[locale.general] # 28 Text processing library [[text]](./#text) ## 28.3 Localization library [[localization]](localization#locale.general) ### 28.3.3 Locales [[locales]](locales#locale.general) #### 28.3.3.1 Class locale [[locale]](locale#general) #### 28.3.3.1.1 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](#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*[.](#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[.](#1.sentence-2) [2](#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<>[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L531) [*Example [1](#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](#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[.](#4.sentence-1) If Facet is not present in a locale, it throws the standard exception bad_cast[.](#4.sentence-2) A C++ program can check if a locale implements a particular facet with the function template has_facet()[.](#4.sentence-3) User-defined facets may be installed in a locale, and used identically as may standard facets[.](#4.sentence-4) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L569) [*Note [1](#note-1)*: All locale semantics are accessed viause_facet<> and has_facet<>, except that: - [(5.1)](#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)](#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"))[.](#5.2.sentence-2)) — *end note*] [6](#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[.](#6.sentence-1) [7](#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[.](#7.sentence-1) [8](#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[.](#8.sentence-1) Named locales may be compared for equality; an unnamed locale is equal only to (copies of) itself[.](#8.sentence-2) For an unnamed locale, locale​::​name() returns the string "*"[.](#8.sentence-3) [9](#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[.](#9.sentence-1) Implementations should provide one global locale object per thread[.](#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"))[.](#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)