This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

841
cppdraft/locales.md Normal file
View File

@@ -0,0 +1,841 @@
[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.2Types"), types// [[locale.facet]](#locale.facet "28.3.3.1.2.2Class locale::facet"), class locale::facetclass facet; // [[locale.id]](#locale.id "28.3.3.1.2.3Class locale::id"), class locale::idclass id; // [[locale.category]](#locale.category "28.3.3.1.2.1Type 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.3Constructors 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<class Facet> 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.4Members"), locale operationstemplate<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; // [[locale.statics]](#locale.statics "28.3.3.1.6Static 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<charT, traits>.")
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); // 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<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<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<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.
- [(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.3Formatted 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.10Data 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<charT, traits>[.](#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)<br>**Category** | **Includes facets** |
| --- | --- |
| [🔗](#tab:locale.category.facets-row-2)<br>collate | collate<char>, collate<wchar_t> |
| [🔗](#tab:locale.category.facets-row-3)<br>ctype | ctype<char>, ctype<wchar_t> |
| [🔗](#tab:locale.category.facets-row-4) | codecvt<char, char, mbstate_t> |
| [🔗](#tab:locale.category.facets-row-5) | codecvt<wchar_t, char, mbstate_t> |
| [🔗](#tab:locale.category.facets-row-6)<br>monetary | moneypunct<char>, moneypunct<wchar_t> |
| [🔗](#tab:locale.category.facets-row-7) | moneypunct<char, true>, moneypunct<wchar_t, true> |
| [🔗](#tab:locale.category.facets-row-8) | money_get<char>, money_get<wchar_t> |
| [🔗](#tab:locale.category.facets-row-9) | money_put<char>, money_put<wchar_t> |
| [🔗](#tab:locale.category.facets-row-10)<br>numeric | numpunct<char>, numpunct<wchar_t> |
| [🔗](#tab:locale.category.facets-row-11) | num_get<char>, num_get<wchar_t> |
| [🔗](#tab:locale.category.facets-row-12) | num_put<char>, num_put<wchar_t> |
| [🔗](#tab:locale.category.facets-row-13)<br>time | time_get<char>, time_get<wchar_t> |
| [🔗](#tab:locale.category.facets-row-14) | time_put<char>, time_put<wchar_t> |
| [🔗](#tab:locale.category.facets-row-15)<br>messages | messages<char>, messages<wchar_t> |
[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<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)<br>**Category** | **Includes facets** |
| --- | --- |
| [🔗](#tab:locale.spec-row-2)<br>collate | collate_byname<char>, collate_byname<wchar_t> |
| [🔗](#tab:locale.spec-row-3)<br>ctype | ctype_byname<char>, ctype_byname<wchar_t> |
| [🔗](#tab:locale.spec-row-4) | codecvt_byname<char, char, mbstate_t> |
| [🔗](#tab:locale.spec-row-5) | codecvt_byname<wchar_t, char, mbstate_t> |
| [🔗](#tab:locale.spec-row-6)<br>monetary | moneypunct_byname<char, International> |
| [🔗](#tab:locale.spec-row-7) | moneypunct_byname<wchar_t, International> |
| [🔗](#tab:locale.spec-row-8) | money_get<C, InputIterator> |
| [🔗](#tab:locale.spec-row-9) | money_put<C, OutputIterator> |
| [🔗](#tab:locale.spec-row-10)<br>numeric | numpunct_byname<char>, numpunct_byname<wchar_t> |
| [🔗](#tab:locale.spec-row-11) | num_get<C, InputIterator>, num_put<C, OutputIterator> |
| [🔗](#tab:locale.spec-row-12)<br>time | time_get<char, InputIterator> |
| [🔗](#tab:locale.spec-row-13) | time_get_byname<char, InputIterator> |
| [🔗](#tab:locale.spec-row-14) | time_get<wchar_t, InputIterator> |
| [🔗](#tab:locale.spec-row-15) | time_get_byname<wchar_t, InputIterator> |
| [🔗](#tab:locale.spec-row-16) | time_put<char, OutputIterator> |
| [🔗](#tab:locale.spec-row-17) | time_put_byname<char, OutputIterator> |
| [🔗](#tab:locale.spec-row-18) | time_put<wchar_t, OutputIterator> |
| [🔗](#tab:locale.spec-row-19) | time_put_byname<wchar_t, OutputIterator> |
| [🔗](#tab:locale.spec-row-20)<br>messages | messages_byname<char>, messages_byname<wchar_t> |
[5](#locale.category-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L726)
The provided implementation of members of
facets num_get<charT> and num_put<charT> calls use_facet<F>(l) only for facet F of
types numpunct<charT> and ctype<charT>,
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.3Iterator 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.10character 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.2Class 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<locale::facet*>(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.2Static 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.1Type 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<class Facet> 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<class Facet> 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<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<class charT, class traits, class Allocator>
bool operator()(const basic_string<charT, traits, Allocator>& s1,
const basic_string<charT, traits, Allocator>& 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<charT> facet[.](#locale.operators-2.sentence-1)
[3](#locale.operators-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/text.tex#L1091)
*Returns*: use_facet<std::collate<charT>>(*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 "26Algorithms 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.2Sorting"), [[vector]](vector "23.3.13Class 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.5C 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<class Facet> 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.2Class 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<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<class Facet> 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<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);
`
[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<ctype<charT>>(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.2The ctype category"))[.](#classification-1.sentence-1)[216](#footnote-216 "When used in a loop, it is faster to cache the ctype&lt;> facet and use it directly, or use the vector form of ctype&lt;>::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<class charT> 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<ctype<charT>>(loc).toupper(c)[.](#conversions.character-1.sentence-1)
[🔗](#lib:tolower)
`template<class charT> 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<ctype<charT>>(loc).tolower(c)[.](#conversions.character-2.sentence-1)