[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<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.4 Members"), 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.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<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](#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[.](#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<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<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)](#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<charT, traits>[.](#footnote-214.sentence-1)
