[locales] # 28 Text processing library [[text]](./#text) ## 28.3 Localization library [[localization]](localization#locales) ### 28.3.3 Locales [locales] #### [28.3.3.1](#locale) Class locale [[locale]](locale) #### [28.3.3.1.1](#locale.general) General [[locale.general]](locale.general) namespace std {class locale {public:// [[locale.types]](#locale.types "28.3.3.1.2 Types"), types// [[locale.facet]](#locale.facet "28.3.3.1.2.2 Class locale​::​facet"), class locale​::​facetclass facet; // [[locale.id]](#locale.id "28.3.3.1.2.3 Class locale​::​id"), class locale​::​idclass id; // [[locale.category]](#locale.category "28.3.3.1.2.1 Type locale​::​category"), type locale​::​categoryusing 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; // [[locale.cons]](#locale.cons "28.3.3.1.3 Constructors and destructor"), 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 locale(const locale& other, Facet* f); locale(const locale& other, const locale& one, category); ~locale(); // not virtualconst locale& operator=(const locale& other) noexcept; // [[locale.members]](#locale.members "28.3.3.1.4 Members"), locale operationstemplate locale combine(const locale& other) const; string name() const; text_encoding encoding() const; bool operator==(const locale& other) const; templatebool operator()(const basic_string& s1, const basic_string& s2) const; // [[locale.statics]](#locale.statics "28.3.3.1.6 Static members"), global locale objectsstatic locale global(const locale&); static const locale& classic(); };} [1](#locale.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L520) Class locale implements a type-safe polymorphic set of facets, indexed by facet *type*[.](#locale.general-1.sentence-1) In other words, a facet has a dual role: in one sense, it's just a class interface; at the same time, it's an index into a locale's set of facets[.](#locale.general-1.sentence-2) [2](#locale.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L527) Access to the facets of a locale is via two function templates,use_facet<> and has_facet<>[.](#locale.general-2.sentence-1) [3](#locale.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L531) [*Example [1](#locale.general-example-1)*: An iostream operator<< can be implemented as:[214](#footnote-214 "Note that in the call to put, the stream is implicitly converted to an ostreambuf_­iterator.") template basic_ostream&operator<< (basic_ostream& s, Date d) {typename basic_ostream::sentry cerberos(s); if (cerberos) { tm tmbuf; d.extract(tmbuf); bool failed = use_facet>>( s.getloc()).put(s, s, s.fill(), &tmbuf, 'x').failed(); if (failed) s.setstate(s.badbit); // can throw}return s;} — *end example*] [4](#locale.general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L558) In the call to use_facet(loc), the type argument chooses a facet, making available all members of the named type[.](#locale.general-4.sentence-1) If Facet is not present in a locale, it throws the standard exception bad_cast[.](#locale.general-4.sentence-2) A C++ program can check if a locale implements a particular facet with the function template has_facet()[.](#locale.general-4.sentence-3) User-defined facets may be installed in a locale, and used identically as may standard facets[.](#locale.general-4.sentence-4) [5](#locale.general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L569) [*Note [1](#locale.general-note-1)*: All locale semantics are accessed viause_facet<> and has_facet<>, except that: - [(5.1)](#locale.general-5.1) A member operator templateoperator()(const basic_string&, const basic_string&) is provided so that a locale can be used as a predicate argument to the standard collections, to collate strings. - [(5.2)](#locale.general-5.2) Convenient global interfaces are provided for traditional ctype functions such asisdigit() and isspace(), so that given a locale object loc a C++ program can call isspace(c, loc). (This eases upgrading existing extractors ([[istream.formatted]](istream.formatted "31.7.5.3 Formatted input functions"))[.](#locale.general-5.2.sentence-2)) — *end note*] [6](#locale.general-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L593) Once a facet reference is obtained from a locale object by calling use_facet<>, that reference remains usable, and the results from member functions of it may be cached and re-used, as long as some locale object refers to that facet[.](#locale.general-6.sentence-1) [7](#locale.general-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L600) In successive calls to a locale facet member function on a facet object installed in the same locale, the returned result shall be identical[.](#locale.general-7.sentence-1) [8](#locale.general-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L605) A locale constructed from a name string (such as "POSIX"), or from parts of two named locales, has a name; all others do not[.](#locale.general-8.sentence-1) Named locales may be compared for equality; an unnamed locale is equal only to (copies of) itself[.](#locale.general-8.sentence-2) For an unnamed locale, locale​::​name() returns the string "*"[.](#locale.general-8.sentence-3) [9](#locale.general-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L614) Whether there is one global locale object for the entire program or one global locale object per thread is implementation-defined[.](#locale.general-9.sentence-1) Implementations should provide one global locale object per thread[.](#locale.general-9.sentence-2) If there is a single global locale object for the entire program, implementations are not required to avoid data races on it ([[res.on.data.races]](res.on.data.races "16.4.6.10 Data race avoidance"))[.](#locale.general-9.sentence-3) [214)](#footnote-214)[214)](#footnoteref-214) Note that in the call to put, the stream is implicitly converted to an ostreambuf_iterator[.](#footnote-214.sentence-1) #### [28.3.3.1.2](#locale.types) Types [[locale.types]](locale.types) #### [28.3.3.1.2.1](#locale.category) Type locale​::​category [[locale.category]](locale.category) [🔗](#lib:locale,category) `using category = int; ` [1](#locale.category-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L633) *Valid* category values include the locale member bitmask elementscollate,ctype,monetary,numeric,time, andmessages, each of which represents a single locale category[.](#locale.category-1.sentence-1) In addition, locale member bitmask constant none is defined as zero and represents no category[.](#locale.category-1.sentence-2) And locale member bitmask constant all is defined such that the expression(collate | ctype | monetary | numeric | time | messages | all) == all is true, and represents the union of all categories[.](#locale.category-1.sentence-3) Further, the expression (X | Y), where X and Y each represent a single category, represents the union of the two categories[.](#locale.category-1.sentence-4) [2](#locale.category-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L657) locale member functions expecting a category argument require one of the category values defined above, or the union of two or more such values[.](#locale.category-2.sentence-1) Such a category value identifies a set of locale categories[.](#locale.category-2.sentence-2) Each locale category, in turn, identifies a set of locale facets, including at least those shown in Table [91](#tab:locale.category.facets "Table 91: Locale category facets")[.](#locale.category-2.sentence-3) Table [91](#tab:locale.category.facets) — Locale category facets [[tab:locale.category.facets]](./tab:locale.category.facets) | [🔗](#tab:locale.category.facets-row-1)
**Category** | **Includes facets** | | --- | --- | | [🔗](#tab:locale.category.facets-row-2)
collate | collate, collate | | [🔗](#tab:locale.category.facets-row-3)
ctype | ctype, ctype | | [🔗](#tab:locale.category.facets-row-4) | codecvt | | [🔗](#tab:locale.category.facets-row-5) | codecvt | | [🔗](#tab:locale.category.facets-row-6)
monetary | moneypunct, moneypunct | | [🔗](#tab:locale.category.facets-row-7) | moneypunct, moneypunct | | [🔗](#tab:locale.category.facets-row-8) | money_get, money_get | | [🔗](#tab:locale.category.facets-row-9) | money_put, money_put | | [🔗](#tab:locale.category.facets-row-10)
numeric | numpunct, numpunct | | [🔗](#tab:locale.category.facets-row-11) | num_get, num_get | | [🔗](#tab:locale.category.facets-row-12) | num_put, num_put | | [🔗](#tab:locale.category.facets-row-13)
time | time_get, time_get | | [🔗](#tab:locale.category.facets-row-14) | time_put, time_put | | [🔗](#tab:locale.category.facets-row-15)
messages | messages, messages | [3](#locale.category-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L686) For any locale loc either constructed, or returned by locale​::​classic(), and any facet Facet shown in Table [91](#tab:locale.category.facets "Table 91: Locale category facets"),has_facet(loc) is true[.](#locale.category-3.sentence-1) Each locale member function which takes a locale​::​category argument operates on the corresponding set of facets[.](#locale.category-3.sentence-2) [4](#locale.category-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L695) An implementation is required to provide those specializations for facet templates identified as members of a category, and for those shown in Table [92](#tab:locale.spec "Table 92: Required specializations")[.](#locale.category-4.sentence-1) Table [92](#tab:locale.spec) — Required specializations [[tab:locale.spec]](./tab:locale.spec) | [🔗](#tab:locale.spec-row-1)
**Category** | **Includes facets** | | --- | --- | | [🔗](#tab:locale.spec-row-2)
collate | collate_byname, collate_byname | | [🔗](#tab:locale.spec-row-3)
ctype | ctype_byname, ctype_byname | | [🔗](#tab:locale.spec-row-4) | codecvt_byname | | [🔗](#tab:locale.spec-row-5) | codecvt_byname | | [🔗](#tab:locale.spec-row-6)
monetary | moneypunct_byname | | [🔗](#tab:locale.spec-row-7) | moneypunct_byname | | [🔗](#tab:locale.spec-row-8) | money_get | | [🔗](#tab:locale.spec-row-9) | money_put | | [🔗](#tab:locale.spec-row-10)
numeric | numpunct_byname, numpunct_byname | | [🔗](#tab:locale.spec-row-11) | num_get, num_put | | [🔗](#tab:locale.spec-row-12)
time | time_get | | [🔗](#tab:locale.spec-row-13) | time_get_byname | | [🔗](#tab:locale.spec-row-14) | time_get | | [🔗](#tab:locale.spec-row-15) | time_get_byname | | [🔗](#tab:locale.spec-row-16) | time_put | | [🔗](#tab:locale.spec-row-17) | time_put_byname | | [🔗](#tab:locale.spec-row-18) | time_put | | [🔗](#tab:locale.spec-row-19) | time_put_byname | | [🔗](#tab:locale.spec-row-20)
messages | messages_byname, messages_byname | [5](#locale.category-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L726) The provided implementation of members of facets num_get and num_put calls use_facet(l) only for facet F of types numpunct and ctype, and for locale l the value obtained by calling member getloc() on the ios_base& argument to these functions[.](#locale.category-5.sentence-1) [6](#locale.category-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L734) In declarations of facets, a template parameter with name InputIterator or OutputIterator indicates the set of all possible specializations on parameters that meet the*Cpp17InputIterator* requirements or*Cpp17OutputIterator* requirements, respectively ([[iterator.requirements]](iterator.requirements "24.3 Iterator requirements"))[.](#locale.category-6.sentence-1) A template parameter with name C represents the set of types containing char, wchar_t, and any otherimplementation-defined character container types ([[defns.character.container]](defns.character.container "3.10 character container type")) that meet the requirements for a character on which any of the iostream components can be instantiated[.](#locale.category-6.sentence-2) A template parameter with name International represents the set of all possible specializations on a bool parameter[.](#locale.category-6.sentence-3) #### [28.3.3.1.2.2](#locale.facet) Class locale​::​facet [[locale.facet]](locale.facet) [🔗](#lib: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; };} [1](#locale.facet-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L766) Class facet is the base class for locale feature sets[.](#locale.facet-1.sentence-1) A class is a [*facet*](#def:facet "28.3.3.1.2.2 Class locale​::​facet [locale.facet]") if it is publicly derived from another facet, or if it is a class derived from locale​::​facet and contains a publicly accessible declaration as follows:[215](#footnote-215 "This is a complete list of requirements; there are no other requirements. Thus, a facet class need not have a public copy constructor, assignment, default constructor, destructor, etc.")static ::std::locale::id id; [2](#locale.facet-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L781) Template parameters in this Clause which are required to be facets are those named Facet in declarations[.](#locale.facet-2.sentence-1) A program that passes a type that is *not* a facet, or a type that refers to a volatile-qualified facet, as an (explicit or deduced) template parameter to a locale function expecting a facet, is ill-formed[.](#locale.facet-2.sentence-2) A const-qualified facet is a valid template argument to any locale function that expects a Facet template parameter[.](#locale.facet-2.sentence-3) [3](#locale.facet-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L794) The refs argument to the constructor is used for lifetime management[.](#locale.facet-3.sentence-1) For refs == 0, the implementation performs delete static_cast(f) (where f is a pointer to the facet) when the last locale object containing the facet is destroyed; for refs == 1, the implementation never destroys the facet[.](#locale.facet-3.sentence-2) [4](#locale.facet-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L802) Constructors of all facets defined in this Clause take such an argument and pass it along to their facet base class constructor[.](#locale.facet-4.sentence-1) All one-argument constructors defined in this Clause are explicit, preventing their participation in implicit conversions[.](#locale.facet-4.sentence-2) [5](#locale.facet-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L809) For some standard facets a standard “…_byname” class, derived from it, implements the virtual function semantics equivalent to that facet of the locale constructed by locale(const char*) with the same name[.](#locale.facet-5.sentence-1) Each such facet provides a constructor that takes a const char* argument, which names the locale, and a refs argument, which is passed to the base class constructor[.](#locale.facet-5.sentence-2) Each such facet also provides a constructor that takes a string argument str and a refs argument, which has the same effect as calling the first constructor with the two arguments str.c_str() and refs[.](#locale.facet-5.sentence-3) If there is no “…_byname” version of a facet, the base class implements named locale semantics itself by reference to other facets[.](#locale.facet-5.sentence-4) [215)](#footnote-215)[215)](#footnoteref-215) This is a complete list of requirements; there are no other requirements[.](#footnote-215.sentence-1) Thus, a facet class need not have a public copy constructor, assignment, default constructor, destructor, etc[.](#footnote-215.sentence-2) #### [28.3.3.1.2.3](#locale.id) Class locale​::​id [[locale.id]](locale.id) [🔗](#lib:locale,id) namespace std {class locale::id {public: id(); void operator=(const id&) = delete; id(const id&) = delete; };} [1](#locale.id-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L840) The class locale​::​id provides identification of a locale facet interface, used as an index for lookup and to encapsulate initialization[.](#locale.id-1.sentence-1) [2](#locale.id-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L845) [*Note [1](#locale.id-note-1)*: Because facets are used by iostreams, potentially while static constructors are running, their initialization cannot depend on programmed static initialization[.](#locale.id-2.sentence-1) One initialization strategy is for locale to initialize each facet's id member the first time an instance of the facet is installed into a locale[.](#locale.id-2.sentence-2) This depends only on static storage being zero before constructors run ([[basic.start.static]](basic.start.static "6.10.3.2 Static initialization"))[.](#locale.id-2.sentence-3) — *end note*] #### [28.3.3.1.3](#locale.cons) Constructors and destructor [[locale.cons]](locale.cons) [🔗](#lib:locale,constructor) `locale() noexcept; ` [1](#locale.cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L865) *Effects*: Constructs a copy of the argument last passed tolocale​::​global(locale&), if it has been called; else, the resulting facets have virtual function semantics identical to those of locale​::​classic()[.](#locale.cons-1.sentence-1) [*Note [1](#locale.cons-note-1)*: This constructor yields a copy of the current global locale[.](#locale.cons-1.sentence-2) It is commonly used as a default argument for function parameters of type const locale&[.](#locale.cons-1.sentence-3) — *end note*] [🔗](#lib:locale,constructor_) `explicit locale(const char* std_name); ` [2](#locale.cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L885) *Effects*: Constructs a locale using standard C locale names, e.g., "POSIX"[.](#locale.cons-2.sentence-1) The resulting locale implements semantics defined to be associated with that name[.](#locale.cons-2.sentence-2) [3](#locale.cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L891) *Throws*: runtime_error if the argument is not valid, or is null[.](#locale.cons-3.sentence-1) [4](#locale.cons-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L895) *Remarks*: The set of valid string argument values is"C", "", and any implementation-defined values[.](#locale.cons-4.sentence-1) [🔗](#lib:locale,constructor__) `explicit locale(const string& std_name); ` [5](#locale.cons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L907) *Effects*: Equivalent to locale(std_name.c_str())[.](#locale.cons-5.sentence-1) [🔗](#lib:locale,constructor___) `locale(const locale& other, const char* std_name, category cats); ` [6](#locale.cons-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L918) *Preconditions*: cats is a valid category value ([[locale.category]](#locale.category "28.3.3.1.2.1 Type locale​::​category"))[.](#locale.cons-6.sentence-1) [7](#locale.cons-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L922) *Effects*: Constructs a locale as a copy of other except for the facets identified by the category argument, which instead implement the same semantics as locale(std_name)[.](#locale.cons-7.sentence-1) [8](#locale.cons-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L928) *Throws*: runtime_error if the second argument is not valid, or is null[.](#locale.cons-8.sentence-1) [9](#locale.cons-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L932) *Remarks*: The locale has a name if and only if other has a name[.](#locale.cons-9.sentence-1) [🔗](#lib:locale,constructor____) `locale(const locale& other, const string& std_name, category cats); ` [10](#locale.cons-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L943) *Effects*: Equivalent to locale(other, std_name.c_str(), cats)[.](#locale.cons-10.sentence-1) [🔗](#lib:locale,constructor_____) `template locale(const locale& other, Facet* f); ` [11](#locale.cons-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L954) *Effects*: Constructs a locale incorporating all facets from the first argument except that of type Facet, and installs the second argument as the remaining facet[.](#locale.cons-11.sentence-1) If f is null, the resulting object is a copy of other[.](#locale.cons-11.sentence-2) [12](#locale.cons-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L961) *Remarks*: If f is null, the resulting locale has the same name as other[.](#locale.cons-12.sentence-1) Otherwise, the resulting locale has no name[.](#locale.cons-12.sentence-2) [🔗](#lib:locale,constructor______) `locale(const locale& other, const locale& one, category cats); ` [13](#locale.cons-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L974) *Preconditions*: cats is a valid category value[.](#locale.cons-13.sentence-1) [14](#locale.cons-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L978) *Effects*: Constructs a locale incorporating all facets from the first argument except those that implement cats, which are instead incorporated from the second argument[.](#locale.cons-14.sentence-1) [15](#locale.cons-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L984) *Remarks*: If cats is equal to locale​::​none, the resulting locale has a name if and only if the first argument has a name[.](#locale.cons-15.sentence-1) Otherwise, the resulting locale has a name if and only if the first two arguments both have names[.](#locale.cons-15.sentence-2) [🔗](#lib:operator=,locale) `const locale& operator=(const locale& other) noexcept; ` [16](#locale.cons-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L998) *Effects*: Creates a copy of other, replacing the current value[.](#locale.cons-16.sentence-1) [17](#locale.cons-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1002) *Returns*: *this[.](#locale.cons-17.sentence-1) #### [28.3.3.1.4](#locale.members) Members [[locale.members]](locale.members) [🔗](#lib:locale,combine) `template locale combine(const locale& other) const; ` [1](#locale.members-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1015) *Effects*: Constructs a locale incorporating all facets from *this except for that one facet of other that is identified by Facet[.](#locale.members-1.sentence-1) [2](#locale.members-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1020) *Returns*: The newly created locale[.](#locale.members-2.sentence-1) [3](#locale.members-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1024) *Throws*: runtime_error if has_facet(other) is false[.](#locale.members-3.sentence-1) [4](#locale.members-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1028) *Remarks*: The resulting locale has no name[.](#locale.members-4.sentence-1) [🔗](#lib:locale,name) `string name() const; ` [5](#locale.members-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1039) *Returns*: The name of *this, if it has one; otherwise, the string "*"[.](#locale.members-5.sentence-1) [🔗](#lib:locale,encoding) `text_encoding encoding() const; ` [6](#locale.members-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1051) *Mandates*: CHAR_BIT == 8 is true[.](#locale.members-6.sentence-1) [7](#locale.members-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1055) *Returns*: A text_encoding object representing the implementation-defined encoding scheme associated with the locale *this[.](#locale.members-7.sentence-1) #### [28.3.3.1.5](#locale.operators) Operators [[locale.operators]](locale.operators) [🔗](#lib:locale,operator==) `bool operator==(const locale& other) const; ` [1](#locale.operators-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1070) *Returns*: true if both arguments are the same locale, or one is a copy of the other, or each has a name and the names are identical;false otherwise[.](#locale.operators-1.sentence-1) [🔗](#lib:locale,operator()) `template bool operator()(const basic_string& s1, const basic_string& s2) const; ` [2](#locale.operators-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1087) *Effects*: Compares two strings according to the std​::​collate facet[.](#locale.operators-2.sentence-1) [3](#locale.operators-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1091) *Returns*: use_facet>(*this).compare(s1.data(), s1.data() + s1.size(), s2.data(), s2.data() + s2.size()) < 0 [4](#locale.operators-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1098) *Remarks*: This member operator template (and therefore locale itself) meets the requirements for a comparator predicate template argument ([[algorithms]](algorithms "26 Algorithms library")) applied to strings[.](#locale.operators-4.sentence-1) [5](#locale.operators-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1104) [*Example [1](#locale.operators-example-1)*: A vector of strings v can be collated according to collation rules in locale loc simply by ([[alg.sort]](alg.sort "26.8.2 Sorting"), [[vector]](vector "23.3.13 Class template vector")): std::sort(v.begin(), v.end(), loc); — *end example*] #### [28.3.3.1.6](#locale.statics) Static members [[locale.statics]](locale.statics) [🔗](#lib:locale,global) `static locale global(const locale& loc); ` [1](#locale.statics-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1124) *Effects*: Sets the global locale to its argument[.](#locale.statics-1.sentence-1) Causes future calls to the constructor locale() to return a copy of the argument[.](#locale.statics-1.sentence-2) If the argument has a name, doessetlocale(LC_ALL, loc.name().c_str()); otherwise, the effect on the C locale, if any, isimplementation-defined[.](#locale.statics-1.sentence-3) [2](#locale.statics-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1136) *Returns*: The previous value of locale()[.](#locale.statics-2.sentence-1) [3](#locale.statics-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1140) *Remarks*: No library function other than locale​::​global() affects the value returned by locale()[.](#locale.statics-3.sentence-1) [*Note [1](#locale.statics-note-1)*: See [[c.locales]](c.locales "28.3.5 C library locales") for data race considerations when setlocale is invoked[.](#locale.statics-3.sentence-2) — *end note*] [🔗](#lib:locale,classic) `static const locale& classic(); ` [4](#locale.statics-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1156) The "C" locale[.](#locale.statics-4.sentence-1) [5](#locale.statics-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1159) *Returns*: A locale that implements the classic "C" locale semantics, equivalent to the value locale("C")[.](#locale.statics-5.sentence-1) [6](#locale.statics-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1164) *Remarks*: This locale, its facets, and their member functions, do not change with time[.](#locale.statics-6.sentence-1) #### [28.3.3.2](#locale.global.templates) locale globals [[locale.global.templates]](locale.global.templates) [🔗](#lib:locale,use_facet) `template const Facet& use_facet(const locale& loc); ` [1](#locale.global.templates-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1177) *Mandates*: Facet is a facet class whose definition contains the public static member id as defined in [[locale.facet]](#locale.facet "28.3.3.1.2.2 Class locale​::​facet")[.](#locale.global.templates-1.sentence-1) [2](#locale.global.templates-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1183) *Returns*: A reference to the corresponding facet of loc, if present[.](#locale.global.templates-2.sentence-1) [3](#locale.global.templates-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1187) *Throws*: bad_cast if has_facet(loc) is false[.](#locale.global.templates-3.sentence-1) [4](#locale.global.templates-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1191) *Remarks*: The reference returned remains valid at least as long as any copy of loc exists[.](#locale.global.templates-4.sentence-1) [🔗](#lib:locale,has_facet) `template bool has_facet(const locale& loc) noexcept; ` [5](#locale.global.templates-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1203) *Returns*: true if the facet requested is present in loc; otherwise false[.](#locale.global.templates-5.sentence-1) #### [28.3.3.3](#locale.convenience) Convenience interfaces [[locale.convenience]](locale.convenience) #### [28.3.3.3.1](#classification) Character classification [[classification]](classification) [🔗](#lib:isspace) `template bool isspace (charT c, const locale& loc); template bool isprint (charT c, const locale& loc); template bool iscntrl (charT c, const locale& loc); template bool isupper (charT c, const locale& loc); template bool islower (charT c, const locale& loc); template bool isalpha (charT c, const locale& loc); template bool isdigit (charT c, const locale& loc); template bool ispunct (charT c, const locale& loc); template bool isxdigit(charT c, const locale& loc); template bool isalnum (charT c, const locale& loc); template bool isgraph (charT c, const locale& loc); template bool isblank (charT c, const locale& loc); ` [1](#classification-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1240) Each of these functions is*F* returns the result of the expression:use_facet>(loc).is(ctype_base::*F*, c) where *F* is the ctype_base​::​mask value corresponding to that function ([[category.ctype]](category.ctype "28.3.4.2 The ctype category"))[.](#classification-1.sentence-1)[216](#footnote-216 "When used in a loop, it is faster to cache the ctype<> facet and use it directly, or use the vector form of ctype<>​::​is.") [216)](#footnote-216)[216)](#footnoteref-216) When used in a loop, it is faster to cache the ctype<> facet and use it directly, or use the vector form of ctype<>​::​is[.](#footnote-216.sentence-1) #### [28.3.3.3.2](#conversions.character) Character conversions [[conversions.character]](conversions.character) [🔗](#lib:toupper) `template charT toupper(charT c, const locale& loc); ` [1](#conversions.character-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1262) *Returns*: use_facet>(loc).toupper(c)[.](#conversions.character-1.sentence-1) [🔗](#lib:tolower) `template charT tolower(charT c, const locale& loc); ` [2](#conversions.character-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1273) *Returns*: use_facet>(loc).tolower(c)[.](#conversions.character-2.sentence-1)