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:
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 via
use_facet<> and has_facet<>,
except that:
- A member operator template
operator()(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 as
isdigit() and isspace(),
so that given a locale object loc
a 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])
.