[locale.general] (original) (raw)
28 Text processing library [text]
28.3 Localization library [localization]
28.3.3 Locales [locales]
28.3.3.1 Class locale [locale]
28.3.3.1.1 General [locale.general]
namespace std { class locale { public: class facet;class id;using category = int;static const category none = 0, collate = 0x010, ctype = 0x020, monetary = 0x040, numeric = 0x080, time = 0x100, messages = 0x200, all = collate | ctype | monetary | numeric | time | messages; 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(); const locale& operator=(const locale& other) noexcept;template<class Facet> locale combine(const locale& other) const; string name() const; text_encoding encoding() 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;static locale global(const locale&);static const locale& classic();};}
Class locale implements a type-safe polymorphic set of facets, indexed by facet type.
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.
Access to the facets of a locale is via two function templates,use_facet<> and has_facet<>.
[Example 1:
An iostream operator<< can be implemented as:215
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) { tm tmbuf; d.extract(tmbuf);bool failed = use_facet<time_put<charT, ostreambuf_iterator<charT, traits>>>( s.getloc()).put(s, s, s.fill(), &tmbuf, 'x').failed();if (failed) s.setstate(s.badbit); } return s;} — _end example_]
In the call to use_facet<Facet>(loc), the type argument chooses a facet, making available all members of the named type.
If Facet is not present in a locale, it throws the standard exception bad_cast.
A C++ program can check if a locale implements a particular facet with the function template has_facet<Facet>().
User-defined facets may be installed in a locale, and used identically as may standard facets.
[Note 1:
All locale semantics are accessed viause_facet<> and has_facet<>, except that:
- A member operator templateoperator()(const basic_string<C, T, A>&, const basic_string<C, T, A>&) is provided so that a locale can be used as a predicate argument to the standard collections, to collate strings.
- Convenient global interfaces are provided for traditional ctype functions such asisdigit() and isspace(), so that given a locale object loca C++ program can call isspace(c, loc).
— _end note_]
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.
In successive calls to a locale facet member function on a facet object installed in the same locale, the returned result shall be identical.
A locale constructed from a name string (such as "POSIX"), or from parts of two named locales, has a name; all others do not.
Named locales may be compared for equality; an unnamed locale is equal only to (copies of) itself.
For an unnamed locale, locale::name() returns the string "*".
Whether there is one global locale object for the entire program or one global locale object per thread is implementation-defined.
Implementations should provide one global locale object per thread.
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]).