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;
    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<< might 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
.