25 Localization library [localization]

25.3 Locales [locales]

25.3.1 Class locale [locale]

namespace std {
  class locale {
  public:
    // types:
    class facet;
    class id;
    using category = int;
    static const category   // values assigned here are for exposition only
      none     = 0,
      collate  = 0x010, ctype    = 0x020,
      monetary = 0x040, numeric  = 0x080,
      time     = 0x100, messages = 0x200,
      all = collate | ctype | monetary | numeric | time  | messages;

    // construct/copy/destroy:
    locale() noexcept;
    locale(const locale& other) noexcept;
    explicit locale(const char* std_name);
    explicit locale(const string& std_name);
    locale(const locale& other, const char* std_name, category);
    locale(const locale& other, const string& std_name, category);
    template <class Facet> locale(const locale& other, Facet* f);
    locale(const locale& other, const locale& one, category);
    ~locale();                  // not virtual
    const locale& operator=(const locale& other) noexcept;
    template <class Facet> locale combine(const locale& other) const;

    // locale operations:
    basic_string<char>                  name() const;

    bool operator==(const locale& other) const;
    bool operator!=(const locale& other) const;

    template <class charT, class traits, class Allocator>
      bool operator()(const basic_string<charT, traits, Allocator>& s1,
                      const basic_string<charT, traits, Allocator>& s2) const;

    // global locale objects:
    static       locale  global(const locale&);
    static const locale& classic();
  };
}

Класс locale реализует безопасный для типов полиморфный набор фасетов, индексированных фасетами type. Другими словами, фасет выполняет двойную роль: в каком-то смысле это просто интерфейс класса; в то же время, это указатель на набор аспектов локали.

Доступ к фасетам a locale осуществляется через два шаблона функций use_­facet<> и has_­facet<>.

[ Example: Iostream operator<< может быть реализован как:230

template <class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>& s, Date d) {
  typename basic_ostream<charT, traits>::sentry cerberos(s);
  if (cerberos) {
    ios_base::iostate err = ios_base::iostate::goodbit;
    tm tmbuf; d.extract(tmbuf);
    use_facet<time_put<charT, ostreambuf_iterator<charT, traits>> >(
      s.getloc()).put(s, s, s.fill(), err, &tmbuf, 'x');
    s.setstate(err);            // might throw
  }
  return s;
}

end example]

При вызове use_­facet<Facet>(loc)аргумент типа выбирает фасет, делая доступными все члены именованного типа. Если Facet его нет в локали, генерируется стандартное исключение bad_­cast. Программа на C ++ может проверить, реализует ли локаль определенный аспект с шаблоном функции has_­facet<Facet>(). Определяемые пользователем фасеты могут быть установлены в локали и использоваться так же, как и стандартные фасеты ([facets.examples]).

[ Note: Доступ ко всей семантике языкового стандарта осуществляется через use_­facet<> и has_­facet<>, за исключением следующих:

  • Предоставляется шаблон оператора-члена, operator()(const basic_­string<C, T, A>&, const basic_­string<​C, T, A>&) чтобы языковой стандарт можно было использовать в качестве аргумента предиката для стандартных коллекций для сопоставления строк.

  • Для традиционныхctype функций, таких как isdigit() и isspace(), предоставляются удобные глобальные интерфейсы , поэтомуloc программа на C ++ может вызывать объект языкового стандартаisspace(c, loc). (Это упрощает обновление существующих экстракторов ([istream.formatted]).)

end note]

После получения ссылки на фасет из объекта языкового стандарта путем вызова use_­facet<>эта ссылка остается пригодной для использования, а результаты его функций-членов могут кэшироваться и повторно использоваться, если какой-либо объект языкового стандарта ссылается на этот фасет.

При последовательных вызовах функции-члена фасета локали для объекта фасета, установленного в той же локали, возвращаемый результат должен быть идентичным.

locale Построено из имени строки (например , как"POSIX"), или из частей двух названных районов, имеет имя; все остальные этого не делают. Именованные языковые стандарты можно сравнивать на предмет равенства; безымянный языковой стандарт равен только (копиям) самого себя. Для безымянного языкового стандарта locale​::​name() возвращает строку "*".

Независимо от того, существует ли один глобальный объект языкового стандарта для всей программы или один глобальный объект языкового стандарта для каждого потока, определяется реализацией. Реализации должны предоставлять один глобальный объект локали для каждого потока. Если для всей программы существует один глобальный объект локали, реализация на нем не требуетсяavoid data races .

Обратите внимание, что при вызове put потока неявно преобразуется в ostreambuf_­iterator<charT, traits>.

25.3.1.1 locale types [locale.types]

25.3.1.1.1 Type locale​::​category [locale.category]

using category = int;

Valid category значения включают в себяlocale член битовая маска элементы collate, ctype, monetary, numeric, time, и messages, каждый из которых представляет одну категорию локали. Кроме того, locale константа битовой маски элемента none определяется как ноль и не представляет категории. И locale постоянный член битовой маски all определяются таким образом, что выражение

(collate | ctype | monetary | numeric | time | messages | all) == all

есть true, и представляет собой объединение всех категорий. Кроме того, выражение (X | Y), где X и Y каждое представляет одну категорию, представляет собой объединение двух категорий.

locale Функции-члены, ожидающие category аргумента, требуют одного из category значений, определенных выше, или объединения двух или более таких значений. Такое category значение определяет набор категорий локали. Каждая категория языкового стандарта, в свою очередь, определяет набор аспектов языкового стандарта, включая, по крайней мере, те, которые показаны в таблице69.

Таблица69 - аспекты категории языкового стандарта
КатегорияВключает грани
сопоставлять collate<char>,collate<wchar_­t>
ctype ctype<char>,ctype<wchar_­t>
codecvt<char, char, mbstate_­t>
codecvt<char16_­t, char, mbstate_­t>
codecvt<char32_­t, char, mbstate_­t>
codecvt<wchar_­t, char, mbstate_­t>
денежный moneypunct<char>,moneypunct<wchar_­t>
moneypunct<char, true>,moneypunct<wchar_­t, true>
money_­get<char>,money_­get<wchar_­t>
money_­put<char>,money_­put<wchar_­t>
числовой numpunct<char>,numpunct<wchar_­t>
num_­get<char>,num_­get<wchar_­t>
num_­put<char>,num_­put<wchar_­t>
время time_­get<char>,time_­get<wchar_­t>
time_­put<char>,time_­put<wchar_­t>
Сообщения messages<char>,messages<wchar_­t>

Для любой локалиloc , созданной или возвращенной locale​::​classic(), и любого аспекта,Facet показанного в таблице69, has_­facet<Facet>(loc) естьtrue. Каждая locale функция-член, которая принимает locale​::​category аргумент, работает с соответствующим набором аспектов.

Реализация требуется для предоставления этих специализаций для шаблонов аспектов, определенных как члены категории, и для тех, которые показаны в таблице70.

Таблица70 - Необходимые специализации
КатегорияВключает грани
сопоставлять collate_­byname<char>,collate_­byname<wchar_­t>
ctype ctype_­byname<char>,ctype_­byname<wchar_­t>
codecvt_­byname<char, char, mbstate_­t>
codecvt_­byname<char16_­t, char, mbstate_­t>
codecvt_­byname<char32_­t, char, mbstate_­t>
codecvt_­byname<wchar_­t, char, mbstate_­t>
денежный moneypunct_­byname<char, International>
moneypunct_­byname<wchar_­t, International>
money_­get<C, InputIterator>
money_­put<C, OutputIterator>
числовой numpunct_­byname<char>,numpunct_­byname<wchar_­t>
num_­get<C, InputIterator>,num_­put<C, OutputIterator>
время time_­get<char, InputIterator>
time_­get_­byname<char, InputIterator>
time_­get<wchar_­t, InputIterator>
time_­get_­byname<wchar_­t, InputIterator>
time_­put<char, OutputIterator>
time_­put_­byname<char, OutputIterator>
time_­put<wchar_­t, OutputIterator>
time_­put_­byname<wchar_­t, OutputIterator>
Сообщения messages_­byname<char>,messages_­byname<wchar_­t>

Предоставленная реализация членов фасетов num_­get<charT> и num_­put<charT> вызовов use_­facet<F>(l) только для фасетов F типов numpunct<charT> и ctype<charT>, а для локали l значение, полученное путем вызова member getloc() для ios_­base& аргумента этих функций.

В объявлениях фасетов параметр шаблона с именем InputIterator или OutputIterator указывает набор всех возможных специализаций параметров, которые удовлетворяют требованиям итератора ввода или итератора вывода, соответственно ([iterator.requirements]). Параметр шаблона с именем C представляет собой набор типов , содержащихchar,wchar_­tи любых других реализации определенных типов символов , которые удовлетворяют требования , предъявляемые к характеру , на которых любые из компонентов iostream может быть реализованным. Параметр шаблона с именем International представляет собой набор всех возможных специализаций для параметра типа bool.

25.3.1.1.2 Class locale​::​facet [locale.facet]

namespace std {
  class locale::facet {
  protected:
    explicit facet(size_t refs = 0);
    virtual ~facet();
    facet(const facet&) = delete;
    void operator=(const facet&) = delete;
  };
}

Классfacet - это базовый класс для наборов функций локали. Класс - это класс,facet если он является производным от другого аспекта или если он является производным от классаlocale​::​facet и содержит следующее публично доступное объявление:231

static ::std::locale::id id;

Параметры шаблона в этом разделе, которые должны быть фасетами, являются теми, которые указаны Facet в объявлениях. Программа, которая передает тип, который является not фасетом, или тип, который ссылается на фасет с изменяемым атрибутом в качестве (явного или выведенного) параметра шаблона в функцию языкового стандарта, ожидающую фасета, имеет неправильный формат. Фасет с константой является допустимым аргументом шаблона для любой функции локали, которая ожидает параметр шаблона Facet.

refs Аргумент конструктора используется для управления жизненным циклом. Для refs == 0реализации выполняется delete static_­cast<locale​::​facet*>(f) (где f - указатель на фасет), когда последний locale объект, содержащий фасет, уничтожается; ведь refs == 1реализация никогда не разрушает фасет.

Конструкторы всех фасетов, определенных в этом разделе, принимают такой аргумент и передают его конструктору своего facet базового класса. Все конструкторы с одним аргументом, определенные в этом разделе explicit, предотвращают их участие в автоматических преобразованиях.

Для некоторых стандартных аспектов_­bynameпроизводный от него стандартный класс « » реализует семантику виртуальных функций, эквивалентную этому аспекту локали, созданного locale(const char*) с помощью того же имени. Каждый такой аспект предоставляет конструктор, который принимает const char* аргумент, который называет локаль, иrefs аргумент, который передается конструктору базового класса. Каждый такой аспект также предоставляет конструктор, который принимает string аргументstr иrefs аргумент, который имеет тот же эффект, что и вызов первого конструктора с двумя аргументамиstr.c_­str() иrefs. Если нет «_­byname» версии фасета, базовый класс сам реализует именованную семантику локали, ссылаясь на другие фасеты.

Это полный список требований; других требований нет. Таким образом, класс фасета не обязательно должен иметь общедоступный конструктор копирования, присваивание, конструктор по умолчанию, деструктор и т. Д.

25.3.1.1.3 Class locale​::​id [locale.id]

namespace std {
  class locale::id {
  public:
    id();
    void operator=(const id&) = delete;
    id(const id&) = delete;
  };
}

Классlocale​::​id обеспечивает идентификацию интерфейса фасета локали, используемого в качестве индекса для поиска и инкапсуляции инициализации.

[ Note: Поскольку фасеты используются iostreams, потенциально во время работы статических конструкторов их инициализация не может зависеть от запрограммированной статической инициализации. Одна стратегия инициализации заключается locale в инициализации каждогоid члена фасета при первой установке экземпляра фасета в локаль. Это зависит только от нуля статического хранилища перед запуском конструктора ([basic.start.static]). ]end note

25.3.1.2 locale constructors and destructor [locale.cons]

locale() noexcept;

Конструктор по умолчанию: снимок текущего глобального языкового стандарта.

Effects: Создает копию последнего переданного аргумента locale​::​global(locale&), если он был вызван; иначе, результирующие фасеты имеют семантику виртуальных функций, идентичную семантике locale​::​classic(). [ Note: Этот конструктор обычно используется в качестве значения по умолчанию для аргументов функций, которые принимают const locale& аргумент. ] end note

locale(const locale& other) noexcept;

Effects: Создает локаль, являющуюся копиейother.

explicit locale(const char* std_name);

Effects: Создает языковой стандарт с использованием стандартных имен языковых стандартов C, например"POSIX". Результирующий языковой стандарт реализует семантику, связанную с этим именем.

Throws: runtime_­error если аргумент недействителен или имеет значение null.

Remarks: Множество допустимых значений строкового аргумента"C",""и любые реализации определенных значений.

explicit locale(const string& std_name);

Effects: То же, что иlocale(std_­name.c_­str()).

locale(const locale& other, const char* std_name, category);

Effects: Создает локаль как копию, за other исключением аспектов, определенных category аргументом, которые вместо этого реализуют ту же семантику, что и locale(std_­name).

Throws: runtime_­error если аргумент недействителен или имеет значение null.

Remarks: Языковой стандарт имеет имя тогда и только тогда, когда он other имеет имя.

locale(const locale& other, const string& std_name, category cat);

Effects: То же, что иlocale(other, std_­name.c_­str(), cat).

template <class Facet> locale(const locale& other, Facet* f);

Effects: Создает локаль, включающую все фасеты из первого аргумента, кромеFacetфасета типа , и устанавливает второй аргумент как оставшийся фасет. Еслиf имеет значение null, результирующий объект является копиейother.

Remarks: Полученный языковой стандарт не имеет названия.

locale(const locale& other, const locale& one, category cats);

Effects: Создает локаль, включающую все фасеты из первого аргумента, кроме тех, которые реализуют cats, которые вместо этого включены из второго аргумента.

Remarks: Результирующая локаль имеет имя тогда и только тогда, когда у первых двух аргументов есть имена.

const locale& operator=(const locale& other) noexcept;

Effects: Создает копиюother, заменяя текущее значение.

Returns: *this.

~locale();

Не виртуальный деструктор, не вызывающий исключений.

25.3.1.3 locale members [locale.members]

template <class Facet> locale combine(const locale& other) const;

Effects: Создает языковой стандарт, включающий все аспекты из, *this за исключением того одного аспекта, other который идентифицирован Facet.

Returns: Недавно созданный языковой стандарт.

Throws: runtime_­error если has_­facet<Facet>(other) естьfalse.

Remarks: Полученный языковой стандарт не имеет названия.

basic_string<char> name() const;

Returns: Имя *this, если оно есть; в противном случае - строка"*".

25.3.1.4 locale operators [locale.operators]

bool operator==(const locale& other) const;

Returns: true если оба аргумента являются одним и тем же языковым стандартом, или один является копией другого, или каждый имеет имя и имена идентичны; false иначе.

bool operator!=(const locale& other) const;

Returns:!(*this == other).

template <class charT, class traits, class Allocator> bool operator()(const basic_string<charT, traits, Allocator>& s1, const basic_string<charT, traits, Allocator>& s2) const;

Effects: Сравнивает две строки по collate<charT> фасету.

Remarks: Этот шаблон оператора-члена (и, следовательно, locale сам) удовлетворяет требованиям для аргумента (предложение[algorithms]) шаблона предиката компаратора, применяемого к строкам.

Returns:

use_facet<collate<charT>>(*this).compare(s1.data(), s1.data() + s1.size(),
                                         s2.data(), s2.data() + s2.size()) < 0

[ Example: Вектор строк v можно сопоставить в соответствии с правилами сопоставления в локали loc просто с помощью ([alg.sort],[vector]):

std::sort(v.begin(), v.end(), loc);

end example]

25.3.1.5 locale static members [locale.statics]

static locale global(const locale& loc);

Устанавливает глобальный языковой стандарт в качестве аргумента.

Effects: Заставляет будущие вызовы конструктора locale() возвращать копию аргумента. Если аргумент имеет имя, не

setlocale(LC_ALL, loc.name().c_str());

в противном случае влияние на локаль C, если таковая имеется, определяется реализацией. Никакая другая библиотечная функция не locale​::​global() должна влиять на значение, возвращаемое locale(). [ Note: См.[c.locales] Соображенияsetlocale по поводу гонки данных при вызове. ]end note

Returns: Предыдущее значение locale().

static const locale& classic();

Регион"C" .

Returns: Языковой стандарт, реализующий"C" семантику классического языкового стандарта, эквивалентный значениюlocale("C").

Remarks: Этот языковой стандарт, его аспекты и их функции-члены не меняются со временем.

25.3.2 locale globals [locale.global.templates]

template <class Facet> const Facet& use_facet(const locale& loc);

Requires: Facet - это фасетный класс, определение которого содержит публичный статический член, id как определено в[locale.facet].

Returns: Ссылка на соответствующий аспектloc, если таковой имеется.

Throws: bad_­cast если has_­facet<Facet>(loc) есть false.

Remarks: Возвращенная ссылка остается действительной по крайней мере до тех пор, пока существует любая копия loc .

template <class Facet> bool has_facet(const locale& loc) noexcept;

Returns: true если запрошенный фасет присутствует вloc; иначеfalse.

25.3.3 Convenience interfaces [locale.convenience]

25.3.3.1 Character classification [classification]

template <class charT> bool isspace (charT c, const locale& loc); template <class charT> bool isprint (charT c, const locale& loc); template <class charT> bool iscntrl (charT c, const locale& loc); template <class charT> bool isupper (charT c, const locale& loc); template <class charT> bool islower (charT c, const locale& loc); template <class charT> bool isalpha (charT c, const locale& loc); template <class charT> bool isdigit (charT c, const locale& loc); template <class charT> bool ispunct (charT c, const locale& loc); template <class charT> bool isxdigit(charT c, const locale& loc); template <class charT> bool isalnum (charT c, const locale& loc); template <class charT> bool isgraph (charT c, const locale& loc); template <class charT> bool isblank (charT c, const locale& loc);

Каждая из этих функций isF возвращает результат выражения:

use_facet<ctype<charT>>(loc).is(ctype_base::F, c)

гдеF - ctype_­base​::​mask значение, соответствующее этой функции ([category.ctype]).232

При использовании в цикле быстрее кэшировать ctype<> фасет и использовать его напрямую или использовать векторную форму ctype<>​::​is.

25.3.3.2 Conversions [conversions]

25.3.3.2.1 Character conversions [conversions.character]

template <class charT> charT toupper(charT c, const locale& loc);

Returns: use_­facet<ctype<charT>>(loc).toupper(c).

template <class charT> charT tolower(charT c, const locale& loc);

Returns: use_­facet<ctype<charT>>(loc).tolower(c).