______________________________________________________________________

  22   Localization library                 [lib.localization]

  ______________________________________________________________________

1 This clause describes components that C++ programs may use to encapsu­
  late  (and  therefore be largely independent of) cultural differences.
  The locale facility includes internationalization support for  charac­
  ter  classification  and  collation, numeric and currency punctuation,
  date and time formatting, and message retrieval.

2 The following subclauses describe  components  for  locales,  standard
  facets,  and facilities from the ISO C library, as summarized in Table
  1:

                  Table 1--Localization library summary

          +----------------------------------------------------+
          |               Subclause                  Header(s) |
          +----------------------------------------------------+
          |_lib.locales_ Locales                     <locale>  |
          |_lib.std.facets_ Standard locale facets             |
          +----------------------------------------------------+
          |_lib.c.locales_ C library locales         <clocale> |
          +----------------------------------------------------+

  22.1  Locales                                            [lib.locales]

  Header <locale> synopsis

  #include <limits>
  #include <string>
  #include <iosfwd>
  namespace std {
  // subclause _lib.locale_, locale:
    class locale;
    template <class charT>
      basic_ostream<charT>& operator<<(basic_ostream<charT>& s, const locale& loc);
    template <class charT>
      basic_istream<charT>& operator>>(basic_istream<charT>& s, locale& loc);

  // subclause _lib.locale.convenience_, convenience interfaces:
    template <class charT> bool isspace (charT c, const locale& loc) const;
    template <class charT> bool isprint (charT c, const locale& loc) const;
    template <class charT> bool iscntrl (charT c, const locale& loc) const;
    template <class charT> bool isupper (charT c, const locale& loc) const;
    template <class charT> bool islower (charT c, const locale& loc) const;
    template <class charT> bool isalpha (charT c, const locale& loc) const;
    template <class charT> bool isdigit (charT c, const locale& loc) const;
    template <class charT> bool ispunct (charT c, const locale& loc) const;
    template <class charT> bool isxdigit(charT c, const locale& loc) const;
    template <class charT> bool isalnum (charT c, const locale& loc) const;
    template <class charT> bool isgraph (charT c, const locale& loc) const;
    template <class charT> charT toupper(charT c, const locale& loc) const;
    template <class charT> charT tolower(charT c, const locale& loc) const;
  // subclauses _lib.facet.ctype_ and _lib.facet.ctype.special_, ctype:
    class ctype_base;
    template <class charT> class ctype;
                           class ctype<char>;        // specialization
    template <class charT> class ctype_byname;
                           class ctype_byname<char>; // specialization
  // subclauses _lib.facet.numeric_ and _lib.facet.numpunct_, numeric:
    template <class charT, class InputIterator>  class num_get;
    template <class charT, class OutputIterator> class num_put;
    template <class charT> class numpunct;
    template <class charT> class numpunct_byname;
  // subclause _lib.facet.collate_, collation:
    template <class charT> class collate;
    template <class charT> class collate_byname;
  // subclause _lib.facet.codecvt_, codeset conversion:
    class codecvt_base;
    template <class fromT, class toT, class stateT> class codecvt;
    template <class fromT, class toT, class stateT> class codecvt_byname;
  // subclause _lib.facet.date.time_, date and time:
    class time_base;
    template <class charT, class InputIterator>  class time_get;
    template <class charT, class InputIterator>  class time_get_byname;
    template <class charT, class OutputIterator> class time_put;
    template <class charT, class OutputIterator> class time_put_byname;
  // subclauses _lib.facet.money_ and _lib.facet.moneypunct_, money:
    class money_base;
    template <class charT, class InputIterator>  class money_get;
    template <class charT, class OutputIterator> class money_put;
    template <class charT> class moneypunct;
    template <class charT> class moneypunct_byname;
  // subclause _lib.facet.messages_, message retrieval:
    template <class charT> class messages;
    template <class charT> class messages_byname;
  }

1 The header <locale> defines classes and declares functions that encap­
  sulate and manipulate the information peculiar to a locale.1)
  _________________________
  1)  In  this  subclause, the type name struct tm is an incomplete type
  that is defined in <ctime>.

  22.1.1  Class locale                                      [lib.locale]
  namespace std {
    class locale {
    public:
      class facet;
      class id;
      typedef unsigned category;
      static const category
        collate  = 0x010, ctype    = 0x020,
        monetary = 0x040, numeric  = 0x080,
        time     = 0x100, messages = 0x200, all = 0x3f0;
      locale();
      locale(const locale& other);
      locale(const char* std_name);
      locale(const locale& other, const char* std_name, category);
      template <class Facet>
        locale(const locale& other, Facet* f);
      template <class Facet>
        locale(const locale& other, const locale& one);
      locale(const locale& other, const locale& one, category);
     ~locale();  // non-virtual
      const locale& operator=(const locale& other);
      template <class Facet> const Facet& use()  const;
      template <class Facet> bool         has()  const;
      const basic_string<char>&           name() const;
      bool operator==(const locale& other) const;
      bool operator!=(const locale& other) const;
      template <class charT>
        bool operator()(const basic_string<charT>& s1,
                        const basic_string<charT>& s2) const;
      static       locale  global(const locale&);
      static const locale& classic();
      static const locale  transparent()
    };
  }

1 A locale constructed from a name string (such as ""), or from parts of
  two  named  locales,  or read from a stream, 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 *.

2 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  member  function  templates,
  locale::use<facet>() and locale::has<facet>().

3 For example, the standard iostream operator<< might be implemented as:

    ostream& operator<<(ostream& s, double f)
    {
      locale loc = s.rdloc();
      if (s.opfx()) {
        loc.use< num_put<char> >().put(s, s, loc, f);
        s.osfx();
      }
      return s;
    }
  In the call to l.use<...>(), the type argument chooses a facet, making
  available  all  members  of the named type.  If the named facet is not
  present in a locale (or, failing  that,  in  the  global  locale),  it
  throws  the  standard  exception  bad_cast.  You can check if a locale
  implements a particular  facet  with  the  member  has<...>().   User-
  defined  facets  may be bestowed on a locale, and used the same way as
  standard facets.

4 All locale semantics are accessed via use<>() and  has<>(),  with  one
  exception:  a  member  template  function operator()(basic_string<T>&,
  basic_string<T>&) is provided so that a locale may be used as a predi­
  cate argument to the standard collections, to order strings.  In addi­
  tion, convenient global interfaces are provided for traditional  ctype
  functions  such  as  isdigit()  and  isspace(), so that given a locale
  object loc you can say isspace(c,loc).  These are provided to ease the
  conversion of existing extractors.

5 A  locale  which  does  not  implement a facet delegates to the global
  locale.

6 The effect of imbuing on a stream, or installing as the global locale,
  the  result of static member locale::transparent() (or any locale with
  similar behavior) is undefined.

  22.1.1.1  locale types                              [lib.locale.types]

  22.1.1.1.1  Type locale::category                [lib.locale.category]

  typedef unsigned category;

  Notes:
    Uses values as defined in <clocale>, e.g.  LC_CTYPE.

  22.1.1.1.2  Class locale::facet                     [lib.locale.facet]
  namespace std {
    class locale::facet {
      facet(const facet&);          // not defined
      void operator=(const facet&); // not defined
      void operator&() {}           // not usable
    protected:
      facet(size_t refs = 0);
      virtual ~facet();
    };
  }

1 Base class for locale feature sets.  Any  class  deriving  from  facet
  must declare a static member:
        static std::locale::id id;

2 For some standard facets there is a `` _byname'' class derived from it
  that implements POSIX locale semantics; they are specified by name  in
  the  standard  to  allow users to derive from them.  If there is no ``
  _byname'' version, the base class implements POSIX  semantics  itself,
  sometimes with the help of another facet.

  22.1.1.1.3  Class locale::id                     [lib.locale.ctype.id]
  namespace std {
    class locale::id {
      void operator=(const id&); // not defined
      id(const id&);             // not defined
      void operator&() {}        // not usable
    public:
      id();
    };
  }

1 Identification  of  a  locale  facet  interface,  used as an index for
  lookup.

  22.1.1.2  locale constructors                        [lib.locale.cons]

  locale();

1 Default constructor: the current global locale.
  Effects:
    : imp_(global_ ? global_ : init()) { imp_->add_ref(); }

    locale(const locale& other);

  Effects:
    { imp_ = other.imp_; imp_->add_ref(); }

    const locale& operator=(const locale& other) const;

  Effects:
          if (imp_ != other.imp_) {
            imp_->rem_ref(); imp_ = other.imp_; imp_->add_ref();
          }
  Returns:
    *this

    explicit locale(const char* std_name);

  Effects:
    Constructs a locale using standard C locale names, e.g. "POSIX".

    locale(const locale& other, const char* std_name, category);

  Effects:
    Makes a locale composed of `` byname'' facets, and assigns a name.
    Copies its first argument except for a specified component, which is
    constructed  on  the spot.  If other has a name, the new locale does
    also.

    template <class Facet>
    locale(const locale& other, Facet* f);

2 To accrete or replace facet
  Effects:
    Copies all facets but one from  the  first  argument,  installs  the
    other  argument as the remaining facet.  The resulting locale has no
    name.
        : imp_(new imp(*other.imp_, 1))
        {
          f->add_ref();
          install(f, Facet::id, "*");
        }

    template <class Facet>
      locale(const locale& other, const locale& one);

3 To replace a facet
  Effects:
    Copies all facets but one from the first argument, and the remaining
    facet from the second argument.  The resulting locale has a no name.
        : imp_(new imp(*other.imp_, 1))
        {
          facet* f = (Facet*) one.imp_->vec[Facet::id];  // check derivation
          install(f, Facet::id, merge_names(Facet::id, one.imp_->name_));
        }

    locale(const locale& other, const locale& one, categories);

  Effects:
    Copies all facets from the first argument except those  that  imple­
    ment  the  specified  categories,  which  are copied from the second
    argument.  The resulting locale has a name only if both locale argu­
    ments have names.

  22.1.1.3  locale members                          [lib.locale.members]

  22.1.1.3.1  locale::use                               [lib.locale.use]

  template <class Facet> const Facet& use() const;

  Effects:
          int i = (const id&) Facet::id;    // verify is a locale::id.
          facet* f = (Facet*) 0;            // verify derived from facet.
          return static_cast<const Facet&>(
            (i < imp_->vec_.size() && (f = imp_->vec_[i])) ? *f : delegate(i));
  Returns:
    A  reference  to a facet.  If the  facet requested is not present in
    *this, it returns the facet from the current global locale, if  pre­
    sent there, or throws an exception.
    Its  result  is  guaranteed  by  locale's value semantics to last at
    least as long as the locale it came from.

  22.1.1.3.2  locale::has                               [lib.locale.has]

  template <class Facet> bool has() const;

  Effects:
    Reports whether a locale implements a particular facet.
          facet* null = (Facet*) 0;          // verify derived from facet.
          size_t ix = (const id&) Facet::id; // verify is a locale::id.
  Returns:
    (ix < imp_->vec_.size()) && imp_->vec_[ix];

1 If   (loc.has<facet>()    ||    locale().has<facet>())    is    false,
  loc.use<facet>() would throw an exception.

  22.1.1.3.3  locale::name                             [lib.locale.name]

  const basic_string<char>& name() const;

  Effects:

    { return imp_->name_; }

  22.1.1.4  locale operators                      [lib.locale.operators]

  22.1.1.4.1  locale::operator==                       [lib.locale.op==]

  bool operator==(const locale& other) const;

  Returns:
        (imp_ == other.imp_) ||
        (name() != "*" && name() == other.name())

  22.1.1.4.2  locale::operator!=                       [lib.locale.op!=]

  bool operator!=(const locale& other) const;

  eturns:
    !(*this == other)

  22.1.1.4.3  locale::operator()                       [lib.locale.op()]

  template <class charT>
  bool operator()(const basic_string<charT>& s1,
                  const basic_string<charT>& s2) const;

1 This  template function satisfies requirements for a comparator predi­
  cate template argument (_lib.algorithms_).

  22.1.1.4.4  operator<<                               [lib.locale.op<<]

  template <class charT>
    basic_ostream<charT>&
      operator<<(basic_ostream<charT>& s, const locale& loc)

  Returns:
    s << loc.name() << endl

  22.1.1.4.5  operator>>                               [lib.locale.op>>]

  template <class charT>
    basic_ostream<charT>& operator>>(basic_ostream<charT>& s, locale& loc)

  Effects:
    Read a line, construct a locale, throw exception if cannot.

  22.1.1.5  locale static members                   [lib.locale.statics]

  22.1.1.5.1  locale::global                         [lib.locale.global]

  static locale global(const locale&);

1 Replaces ::setlocale(...).

  22.1.1.5.2  locale::classic                       [lib.locale.classic]

  static const locale& classic();

1 The locale.

  22.1.1.5.3  locale::transparent               [lib.locale.transparent]

  static const locale transparent();

1 Continuously updated global locale.
  Returns:
    locale(new imp(1, 0, true))

  22.1.2  Convenience interfaces                [lib.locale.convenience]

  22.1.2.1  Character classification                [lib.classification]

  22.1.2.1.1  isspace                               [lib.locale.isspace]

  template <class charT> bool isspace(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::space, c).

  22.1.2.1.2  isprint                               [lib.locale.isprint]

  template <class charT> bool isprint(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::print, c).

  22.1.2.1.3  iscntrl                               [lib.locale.iscntrl]

  template <class charT> bool iscntrl(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::cntrl, c).

  22.1.2.1.4  isupper                               [lib.locale.isupper]

  template <class charT> bool isupper(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::upper, c).

  22.1.2.1.5  islower                               [lib.locale.islower]

  template <class charT> bool islower(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::lower, c).

  22.1.2.1.6  isalpha                               [lib.locale.isalpha]

  template <class charT> bool isalpha(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::alpha, c).

  22.1.2.1.7  isdigit                               [lib.locale.isdigit]

  template <class charT> bool isdigit(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::digit, c).

  22.1.2.1.8  ispunct                               [lib.locale.ispunct]

  template <class charT> bool ispunct(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::punct, c).

  22.1.2.1.9  isxdigit                             [lib.locale.isxdigit]

  template <class charT> bool isxdigit(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::xdigit, c).

  22.1.2.1.10  isalnum                              [lib.locale.isalnum]

  template <class charT> bool isalnum(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::alnum, c).

  22.1.2.1.11  isgraph                              [lib.locale.isgraph]

  template <class charT> bool isgraph(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().is(ctype<charT>::graph, c).

  22.1.2.2  Character conversiona                      [lib.conversions]

  22.1.2.2.1  toupper                               [lib.locale.toupper]

  template <class charT> charT toupper(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().toupper(c).

  22.1.2.2.2  tolower                               [lib.locale.tolower]

  template <class charT> charT tolower(charT c, const locale& loc) const;

  Returns:
    loc.use<ctype<charT> >().tolower(c).

  22.2  Standard locale facets                          [lib.std.facets]

  22.2.1  The ctype facet                              [lib.facet.ctype]

  namespace std {
    struct ctype_base {
      enum ctype_mask {
        space=1<<0, print=1<<1, cntrl=1<<2, upper=1<<3, lower=1<<4,
        alpha=1<<5, digit=1<<6, punct=1<<7, xdigit=1<<8,
        alnum=(1<<5)|(1<<6), graph=(1<<7)|(1<<6)|(1<<5)
      };
    };

  +-------                 BEGIN BOX 1                -------+
  ISSUE: should this be in the global namespace?
  +-------                  END BOX 1                 -------+

    ctype_base::ctype_mask
      operator|(ctype_base::ctype_mask a, ctype_base::ctype_mask b);
          { return (ctype_base::ctype_mask)(unsigned(a)|unsigned(b)); }
    template <class charT> class ctype;
    template <class charT> class ctype_byname
  }

  22.2.1.1  Template class ctype                      [lib.locale.ctype]
    template <class charT>
    class ctype : public locale::facet, public ctype_base {
    public:
      typedef charT char_type;
    protected:
      virtual bool         do_is(ctype_mask mask, charT c) const;
      virtual const charT* do_is(const charT* low,
                                 const charT* high, ctype_mask* vec) const;
      virtual const char*  do_scan_is(ctype_mask mask,
                                      const charT* low, const charT* high) const;
      virtual const char*  do_scan_not(ctype_mask mask,
                                       const charT* low, const charT* high) const;
      virtual charT        do_toupper(charT) const;
      virtual const charT* do_toupper(charT* low, const charT* high) const;
      virtual charT        do_tolower(charT) const;
      virtual const charT* do_tolower(charT* low, const charT* high) const;
      virtual charT        do_widen(char) const;
      virtual const char*  do_widen(const char* lo,
                                    const char* hi, charT* dest) const;
      virtual char         do_narrow(charT, char dfault) const;
      virtual const charT* do_narrow(const charT* lo, const charT* hi,
                                     char dfault, char* dest) const;

    public:
      bool         is(ctype_mask mask, charT c) const;
      const charT* is(const charT* low, const charT* high, ctype_mask* vec) const;
      const charT* scan_is(ctype_mask mask, const charT* low,
                           const charT* high) const;
      const charT* scan_not(ctype_mask mask, const charT* low,
                            const charT* high) const;
      charT        toupper(charT) const;
      const charT* toupper(charT* low, const charT* high) const;
      charT        tolower(charT c) const;
      const charT* tolower(charT* low, const charT* high) const;
      charT       widen(char c) const;
      const char* widen(const char* lo, const char* hi, charT* to) const;
      char         narrow(charT c, char dfault) const;
      const charT* narrow(const charT* lo, const charT*,
                          char dfault, char* to) const;
      static locale::id id;
      ctype(size_t refs = 0);
    protected:
     ~ctype();
    };

1 Class ctype encapsulates the C  library  <cctype>  features.   istream
  members are required to use ctype<> for character classing.

  22.2.1.2  ctype members                     [lib.locale.ctype.members]

1 Most of these functions are

  +-------                 BEGIN BOX 2                -------+
  To Be Specified
  +-------                  END BOX 2                 -------+

  22.2.1.2.1  do_is                            [lib.locale.ctype::do.is]

  virtual bool         do_is(ctype_mask mask, charT c) const;
  virtual const charT* do_is(const charT* low,
                             const charT* high, ctype_mask* vec) const;

  22.2.1.2.2  do_scan_is                  [lib.locale.ctype::do.scan.is]

  virtual const char*
    do_scan_is(ctype_mask mask,
               const charT* low, const charT* high) const;

  22.2.1.2.3  do_scan_not                [lib.locale.ctype::do.scan.not]

  virtual const char*
    do_scan_not(ctype_mask mask,
                const charT* low, const charT* high) const;

  22.2.1.2.4  do_toupper                  [lib.locale.ctype::do.toupper]

  virtual charT        do_toupper(charT) const;
  virtual const charT* do_toupper(charT* low, const charT* high) const;

  22.2.1.2.5  do_tolower                  [lib.locale.ctype::do.tolower]

  virtual charT        do_tolower(charT) const;
  virtual const charT* do_tolower(charT* low, const charT* high) const;

  22.2.1.2.6  do_widen                      [lib.locale.ctype::do.widen]

  virtual charT        do_widen(char) const;
  virtual const char*  do_widen(const char* lo,
                                const char* hi, charT* dest) const;

  22.2.1.2.7  do_narrow                    [lib.locale.ctype::do.narrow]

  virtual char         do_narrow(charT, char dfault) const;
  virtual const charT* do_narrow(const charT* lo, const charT* hi,
                                 char dfault, char* dest) const;

  22.2.1.2.8  is                                  [lib.locale.ctype::is]

  bool         is(ctype_mask mask, charT c) const;
  const charT* is(const charT* low, const charT* high, ctype_mask* vec) const;

  Returns:
    do_is(mask,c) or do_is(low,high,vec)

  22.2.1.2.9  scan_is                        [lib.locale.ctype::scan.is]

  const charT* scan_is(ctype_mask mask, const charT* low,
                       const charT* high) const;

  Returns:
    do_scan_is(masklow,high)

  22.2.1.2.10  scan_not                     [lib.locale.ctype::scan.not]

  const charT* scan_not(ctype_mask mask, const charT* low,
                        const charT* high) const;

  Returns:
    do_scan_not(mask,low,high)

  22.2.1.2.11  toupper                       [lib.locale.ctype::toupper]

  charT        toupper(charT) const;
  const charT* toupper(charT* low, const charT* high) const;

  Returns:
    do_toupper(c) or do_toupper(low,high)

  22.2.1.2.12  tolower                       [lib.locale.ctype::tolower]

  charT        tolower(charT c) const;
  const charT* tolower(charT* low, const charT* high) const;

  Returns:
    do_tolower(c) or do_tolower(low,high)

  22.2.1.2.13  widen                           [lib.locale.ctype::widen]

  charT       widen(char c) const;
  const char* widen(const char* lo, const char* hi, charT* to) const;

  Returns:
    do_widen(c) or do_widen(lo,hi,to)

  22.2.1.2.14  narrow                         [lib.locale.ctype::narrow]

  char         narrow(charT c, char dfault) const;
  const charT* narrow(const charT* lo, const charT*,
                      char dfault, char* to) const;

  Returns:
    do_narrow(c,dfault) or do_narrow(lo,hi,dfault,to)

  22.2.1.2.15  ctype constructor                [lib.locale.ctype::cons]

  ctype(size_t refs = 0);

  Effects:
       : locale::facet(refs) {}

  22.2.1.3  Template class ctype_byname        [lib.locale.ctype.byname]

    template <class charT>
    class ctype_byname : public ctype<charT> {
      // this class is specialized by vendors for char and wchar_t.
    protected:
      virtual char        do_toupper(char) const;
      virtual const char* do_toupper(char* low, const char* high) const;
      virtual char        do_tolower(char) const;
      virtual const char* do_tolower(char* low, const char* high) const;
    public:
      ctype_byname(const char*, size_t refs = 0);
    protected:
     ~ctype_byname();
    };
  }

  22.2.2  ctype specializations                [lib.facet.ctype.special]
  namespace std {
    class ctype<char> : public locale::facet, public ctype_base {
    public:
      typedef char char_type;
    protected:
      const ctype_mask* const table_;
      static const ctype_mask
        classic_table_[numeric_limits<unsigned char>::max()+1];
      virtual char        do_toupper(char) const;
      virtual const char* do_toupper(char* low, const char* high) const;
      virtual char        do_tolower(char) const;
      virtual const char* do_tolower(char* low, const char* high) const;
    public:
      bool is(ctype_mask mask, char c) const;
      const char* is(const char* lo, const char* hi,
                     ctype_mask* vec) const;
      const char* scan_is(ctype_mask mask, const char* low,
                          const char* high) const;
      const char* scan_not(ctype_mask mask, const char* low,
                           const char* high) const;
      char        toupper(char c) const;
      const char* toupper(char* low, const char* high) const;
      char        tolower(char c) const;
      const char* tolower(char* low, const char* high) const;
      char  widen(char c) const;
      const char* widen(const char* lo, const char* hi,
                        char* to) const;
      char   narrow(char c, char /*dfault*/) const;
      const char* narrow(const char* lo, const char* hi,
                         char /*dfault*/, char* to) const;
      static locale::id id;
      ctype(const ctype_mask* tab = 0, bool del = false,
            size_t refs = 0);
    protected:
     ~ctype();
    };
  }

1 A specialization ctype<char> is provided, so that the member functions
  on type char may be implemented inline.  Definitions  of  these  func­
  tions  have  been provided for exposition.  Only the char, and not the
  unsigned char and signed char forms, has been provided.  The  special­
  ization  is  specified in the standard (and not left as an implementa­
  tion  detail)  because  it  affects  the  derivation   interface   for
  ctype<char>.

  22.2.3  ctype<char> members             [lib.facet.ctype.char.members]

  22.2.3.1  is                                      [lib.ctype.char::is]

  bool is(ctype_mask mask, char c) const;

  Returns:
    table_[(unsigned char)c] & mask

    const char* is(const char* lo, const char* hi,
     ctype_mask* vec) const;

  Effects:
    while (lo != hi) *vec++ = table_[(unsigned char)*lo++]; return lo;

  22.2.3.2  scan_is                            [lib.ctype.char::scan.is]

  const char* scan_is(ctype_mask mask, const char* low,
  onst char* high) const;

  Effects:
        while (low != high && !(table_[(unsigned char) *low] & mask)) { ++low; }
        return low;

  22.2.3.3  scan_not                          [lib.ctype.char::scan.not]

  const char* scan_not(ctype_mask mask, const char* low,
  const char* high) const;

  Effects:
        while (low != high && (table_[(unsigned char)*low] & mask)) { ++low; }
        return low;

  22.2.3.4  toupper                            [lib.ctype.char::toupper]

  char        toupper(char c) const;
  const char* toupper(char* low, const char* high) const;

  Returns:
    do_toupper(c) or do_toupper(low,high)

  22.2.3.5  tolower                            [lib.ctype.char::tolower]

  char        tolower(char c) const;
  const char* tolower(char* low, const char* high) const;

  Returns:
    do_tolower(c) or do_tolower(low,high)

  22.2.3.6  widen                                [lib.ctype.char::widen]

  char  widen(char c) const;
  const char* widen(const char* lo, const char* hi,
      char* to) const;

  Returns:
    or memcpy(to, lo, hi-lo); return hi

  22.2.3.7  narrow                              [lib.ctype.char::narrow]

  char   narrow(char c, char /*dfault*/) const;
  const char* narrow(const char* lo, const char* hi,
                     char /*dfault*/, char* to) const;

  Returns:
    c or memcpy(to, lo, hi-lo); return hi;

  22.2.3.8  ctype<char>                           [lib.ctype.char::ctor]

  ctype(const ctype_mask* tab = 0, bool del = false,
        size_t refs = 0);

  Effects:
            : locale::facet(refs), table_(tab ? tab : classic_table_),
              delete_it_(tab ? del : false) {}

  22.2.3.9  ctype<char> destructor                [lib.ctype.char::dtor]

  ~ctype();

  Effects:
    if (delete_it_) delete table_;

  22.2.4  The numeric facet                          [lib.facet.numeric]

  22.2.4.1  Template class num_get                  [lib.locale.num.get]
  namespace std {
    template <class charT, class InputIterator = istreambuf_iterator<charT> >
    class num_get : public locale::facet {
    public:
      typedef charT            char_type;
      typedef InputIterator    iter_type;
      typedef basic_ios<charT> ios;

    protected:
      virtual iter_type do_get(iter_type, ios&, const locale&,
                               bool& v) const;
      virtual iter_type do_get(iter_type, ios&, const locale&,
                               long& v) const;
      virtual iter_type do_get(iter_type, ios&, const locale&,
                               unsigned long& v) const;
  //  virtual iter_type do_get(iter_type, ios&, const locale&,
  //                           long long& v) const;
      virtual iter_type do_get(iter_type, ios&, const locale&,
                               double& v) const;
      virtual iter_type do_get(iter_type, ios&, const locale&,
                               long double& v) const;
    public:
      iter_type get(iter_type s, ios& f, const locale&, bool& v)          const;
      iter_type get(iter_type s, ios& f, const locale&, long& v)          const;
      iter_type get(iter_type s, ios& f, const locale&, unsigned long& v) const;
  //  iter_type get(iter_type s, ios& f, const locale&, long long& v)   const;
      iter_type get(iter_type s, ios& f, const locale&, double& v)        const;
      iter_type get(iter_type s, ios& f, const locale&, long double& v)   const;
      static locale::id id;
      num_get(size_t refs = 0);
    protected:
     ~num_get();
    };
  }

1 The  classes  num_get<>  and  num_put<>  handle numeric formatting and
  parsing.  Virtual functions are provided for  several  numeric  types;
  implementations are allowed to delegate conversion of smaller types to
  extractors for larger ones, but are not required  to.   The  functions
  take  a locale argument because their base class implementation refers
  to numpunct features, which identify  preferred  numeric  punctuation.
  Extractors  and  inserters  for the standard iostreams are required to
  call num_get and num_put member functions.  The ios& argument is  used
  both for format control and to report errors.

2 Members  of  num_get  take  a locale argument because they may need to
  refer to the locale's numpunct facet.

  22.2.4.2  Template class num_put                  [lib.locale.num.put]
  namespace std {
    template <class charT, class OutputIterator = ostreambuf_iterator<charT> >
    class num_put : public locale::facet {
    public:
      typedef charT            char_type;
      typedef OutputIterator   iter_type;
      typedef basic_ios<charT> ios;

    protected:
      virtual iter_type do_put(iter_type, ios&, const locale&, bool v) const;
      virtual iter_type do_put(iter_type, ios&, const locale&, long v) const;
      virtual iter_type do_put(iter_type, ios&, const locale&, unsigned long) const;
  //virtual iter_type do_put(iter_type, ios&, const locale&, long long v) const;
      virtual iter_type do_put(iter_type, ios&, const locale&, double v) const;
      virtual iter_type do_put(iter_type, ios&, const locale&, long double v) const;
    public:
      iter_type put(iter_type s, ios& f, const locale& loc,
                    bool v5)          const;
      iter_type put(iter_type s, ios& f, const locale& loc,
                    long v) const;
      iter_type put(iter_type s, ios& f, const locale& loc,
                    unsigned long v) const;
  //  iter_type put(iter_type s, ios& f, const locale& loc,
                    long long v) const;
      iter_type put(iter_type s, ios& f, const locale& loc,
                    double v) const;
      iter_type put(iter_type s, ios& f, const locale& loc,
                    long double v) const;
      static locale::id id;
      num_put(size_t refs = 0);
    protected:
     ~num_put();
    };
  }

1 Members of num_put take a locale argument because  they  may  need  to
  refer  to  the locale's numpunct facet.  The ios& argument is used for
  formatting reference only and error reporting.

  22.2.5  The numeric punctuation facet             [lib.facet.numpunct]

  22.2.5.1  Template class numpunct                [lib.locale.numpunct]
  namespace std {
    template <class charT>
    class numpunct : public locale::facet {
    public:
      typedef charT               char_type;
      typedef basic_string<charT> string;
    protected:
      virtual string       do_decimal_point() const;
      virtual string       do_thousands_sep() const;
      virtual vector<char> do_grouping()      const;
      virtual string       do_truename()      const;  // for bool
      virtual string       do_falsename()     const;  // for bool

    public:
      string decimal_point()   const { return do_decimal_point(); }
      string thousands_sep()   const { return do_thousands_sep(); }
      vector<char>  grouping() const { return do_grouping(); }
      string truename()        const { return do_truename(); }
      string falsename()       const { return do_falsename(); }
      static locale::id id;
      numpunct(size_t refs = 0);
    protected:
     ~numpunct();
    };
  }

1 numpunct<> specifies numeric punctuation.   The  base  class  provides
  classic  numeric  formats,  while the _byname version supports general
  POSIX numeric formatting semantics.

  22.2.5.2  Template class                  [lib.locale.numpunct.byname]
       numpunct_byname
  namespace std {
    template <class charT>
    class numpunct_byname : public numpunct<charT> {
    // this class is specialized by vendors for char and wchar_t.
    protected:
      virtual string       do_decimal_point() const;
      virtual string       do_thousands_sep() const;
      virtual vector<char> do_grouping()      const;
      virtual string       do_truename()      const;  // for bool
      virtual string       do_falsename()     const;  // for bool
    public:
      numpunct_byname(const char*, size_t refs = 0);
    protected:
     ~numpunct_byname();
    };
  }

1 numpunct is used by num_get and num_put facets.

  22.2.6  The collation facet                        [lib.facet.collate]

  22.2.6.1  Template class collate                  [lib.locale.collate]
  namespace std {
    template <class charT>
    class collate : public locale::facet {
    public:
      typedef charT               char_type;
      typedef basic_string<charT> string;
    protected:
      virtual int    do_compare(const char* low1, const char* high1,
                                const char* low2, const char* high2) const;
      virtual string do_transform(const char* low, const char* high) const;
      virtual long   do_hash(     const char* low, const char* high) const;

    public:
      int compare(const char* low1, const char* high1,
                  const char* low2, const char* high2) const;
        { return do_compare(low1, hight1, low2, high2); }
      string transform(const char* low, const char* high) const;
        { return do_transform(low, high); }
      long hash(const char* low, const char* high) const;
        { return do_hash(low, high); }
      static locale::id id;
      collate(size_t refs = 0);
    protected:
     ~collate();
    };
  }

1 The class collate<charT> provides features for use in the collation of
  strings.  A locale member function template, operator(), uses the col­
  late facet to allow a locale to act directly as the predicate argument
  for algorithms.  The base class uses lexicographic ordering.

2 locale.use<collate>() is used for string comparisons.

  22.2.6.2  collate members                 [lib.locale.collate.members]

  22.2.6.2.1  compare                             [lib.collate::compare]

  int compare(const char* low1, const char* high1,
              const char* low2, const char* high2) const;

  Returns:
    do_compare(low1, hight1, low2, high2)

  22.2.6.2.2  transform                         [lib.collate::transform]

  string transform(const char* low, const char* high) const;

  Returns:
    do_transform(low, high)

  22.2.6.2.3  hash                                   [lib.collate::hash]

  long hash(const char* low, const char* high) const;

  Returns:
    do_hash(low, high)

  22.2.6.3  Template class                   [lib.locale.collate.byname]
       collate_byname

  namespace std {
    template <class charT>
    class collate_byname : public collate<charT> {
      // this class is specialized by vendors for char and wchar_t.
    protected:
      virtual int    do_compare(const char* low1, const char* high1,
                                const char* low2, const char* high2) const;
      virtual string do_transform(const char* low, const char* high) const;
      virtual long   do_hash(     const char* low, const char* high) const;
    public:
      collate_byname(const char*);
    protected:
     ~collate_byname();
    };
  //  this template function satisfies requirements for a
  //  comparator predicate template argument:
    template <class charT>
      bool locale::operator()(const basic_string<charT>& s1,
                              const basic_string<charT>& s2);
  }

  22.2.6.4  collate_byname           [lib.locale.collate.byname.members]
       members

  22.2.6.4.1  operator()                         [lib.collate::op.paren]

  bool locale::operator()(const basic_string<charT>& s1,
                          const basic_string<charT>& s2);

  Returns:
        use< collate<charT> >().compare(s1.begin(), s1.end(),
                                        s2.begin(), s2.end()) < 0;

  22.2.7  The codeset conversion facet               [lib.facet.codecvt]

  22.2.7.1  Template class codecvt                  [lib.locale.codecvt]
  namespace std {
    struct codecvt_base {
      enum result { ok, partial, error };
    };
    template <class fromT, class toT, class stateT>
    class codecvt : public locale::facet, public codecvt_base {
    public:
      typedef fromT  from_type;
      typedef toT    to_type;
      typedef stateT state_type;
    protected:
      virtual result do_convert(stateT& state,
        const fromT* from, const fromT* from_end, const fromT*& from_next,
              toT*   to,   toT*         to_limit,       toT*&   to_next) const;

    public:
       result convert(stateT& state,
         const fromT* from, const fromT* from_end, const fromT*& from_next,
                 toT*   to,         toT* to_limit,         toT*& to_next) const;
      static locale::id id;
      codecvt(size_t refs = 0)
    protected:
     ~codecvt() {}
    };
  }

1 The class codecvt<fromT,toT,stateT> is for use  when  converting  from
  one  codeset  to  another,  such  as from wide characters to multibyte
  characters, or between wide character sets such as  Unicode  and  EUC.
  Instances of this facet are typically used in pairs.

2 Its  only  member  function,  convert(),  returns an enumeration value
  which indicates whether it completed the conversion ( ok), ran out  of
  space  in the destination ( partial), or encountered a from_type char­
  acter it could not convert ( error).

3 In all cases it leaves the from_next and to_next pointers pointing one
  beyond the last character successfully converted.

4 The stateT argument selects the pair of codesets being mapped between.
  Base class members are pure virtual.

5 Implementations   are   obliged   to   provide   specializations   for
  <char,wchar_t,mbstate_t> and <wchar_t,char,mbstate_t>.

  22.2.7.2  codecvt members                 [lib.locale.codecvt.members]

  22.2.7.2.1  convert                             [lib.codecvt::convert]

  result convert(stateT& state,
                 const fromT* from, const fromT* from_end,
                 const fromT*& from_next,
                 toT*   to,         toT* to_limit,
                 toT*& to_next) const;

  Returns:
        do_convert(state, from, from_end, from_next,
                   to, to_limit, to_next);

  22.2.7.3  Template class                   [lib.locale.codecvt.byname]
       codecvt_byname

  namespace std {
    template <class fromT, class toT, class stateT>
    class codecvt_byname : public codecvt<fromT, toT, stateT> {
    protected:
      virtual result do_convert(stateT& state,
        const fromT* from, const fromT* from_end, const fromT*& from_next,
              toT*   to,   toT*         to_limit,       toT*&   to_next) const;
    public:
      codecvt_byname(const char*, size_t refs = 0);
    protected:
     ~codecvt_byname();
    };
  }

  22.2.8  The date and time facet                  [lib.facet.date.time]

1 The classes time_get<charT> and time_put<charT> provide date and  time
  formatting  and  parsing.  The time formatting function put() takes an
  extra format argument to accommodate the POSIX strftime()  extensions.
  The ios& argument is used for format control and to report errors.

  22.2.8.1  Template class time_get                [lib.locale.time.get]
  namespace std {
    struct time_base {
      enum dateorder { no_order, dmy, mdy, ymd, ydm };
    };
    template <class charT, class InputIterator = istreambuf_iterator<charT> >
    class time_get : public locale::facet, public time_base {
    public:
      typedef charT            char_type;
      typedef InputIterator    iter_type;
      typedef basic_ios<charT> ios;
    protected:
      virtual dateorder do_date_order()  const;
      virtual iter_type do_get_time(iter_type s, ios&, const locale&, tm* t) const;
      virtual iter_type do_get_date(iter_type s, ios&, const locale&, tm* t) const;
      virtual iter_type do_get_weekday(iter_type s, ios&, const locale&, tm* t)
                      const;
      virtual iter_type do_get_monthname(iter_type s, ios&, const locale&, tm* t)
                      const;
      virtual iter_type do_get_year(iter_type s, ios&, const locale&, tm* t) const;

  22.2.8.2  Template class                  [lib.locale.time.get.byname]
       time_get_byname

  namespace std {
    template <class charT, class InputIterator = istreambuf_iterator<charT> >
    class time_get_byname : public time_get<charT, InputIterator> {
    protected:
      virtual dateorder do_date_order()  const;
      virtual iter_type do_get_time(iter_type s, ios&, const locale&, tm* t) const;
      virtual iter_type do_get_date(iter_type s, ios&, const locale&, tm* t) const;
      virtual iter_type do_get_weekday(iter_type s, ios&, const locale&, tm* t) const;
      virtual iter_type do_get_monthname(iter_type s, ios&, const locale&, tm* t) const;
      virtual iter_type do_get_year(iter_type s, ios&, const locale&, tm* t) const;
    public:
      time_get_byname(const char*, size_t refs = 0);
    protected:
     ~time_get_byname();
    };
  }

  22.2.8.3  Template class time_put                [lib.locale.time.put]
  namespace std {
    template <class charT, class OutputIterator = ostreambuf_iterator<charT> >
    class time_put : public locale::facet {
    public:
      typedef charT            char_type;
      typedef OutputIterator   iter_type;
      typedef basic_ios<charT> ios;
    protected:
      virtual iter_type do_put(iter_type s, ios&, const locale&, const tm* t,
                               char format, char modifier) const;
    public:
      // the following is implemented in terms of other member functions.
      iter_type put(iter_type s, ios& f, struct tm const* tmb,
                    const charT* pattern, const charT* pat_end) const;
      iter_type put(iter_type s, ios& f, const locale& loc, struct tm const* Pt,
                    char format, char modifier = ' ') const;
      static locale::id id;
      time_put(size_t refs = 0);
    protected:
     ~time_put();
    };
  }

  22.2.8.4  Template class                  [lib.locale.time.put.byname]
       time_put_byname

  namespace std {
    template <class charT, class OutputIterator = ostreambuf_iterator<charT> >
    class time_put_byname : public time_put<charT, OutputIterator>
    {
    protected:
      virtual iter_type do_put(iter_type s, ios&, const locale&, const tm* t,
                               char format, char modifier) const;
    public:
      time_put_byname(const char*, size_t refs = 0);
    protected:
     ~time_put_byname();
    };
  }

  22.2.9  The money facet                              [lib.facet.money]

1 These  handle  money  formats.  A template parameter indicates whether
  local or international monetary formats are to be  used.   money_get<>
  and  money_put<>  use  moneypunct<>  features  if appropriate.  money­
  punct<> provides basic format information for money  processing.   The
  ios& argument is used for format control and to report errors.

  22.2.9.1  Template class money_get              [lib.locale.money.get]
  namespace std {
    template <class charT, bool Intl = false,
              class InputIterator = istreambuf_iterator<charT> >
    class money_get : public locale::facet {
      typedef charT               char_type;
      typedef InputIterator       iter_type;
      typedef basic_string<charT> string;
      typedef basic_ios<charT>    ios;
    protected:
      virtual iter_type do_get(iter_type, ios&, const locale&, double& units) const;
      virtual iter_type do_get(iter_type, ios&, const locale&, string& digits) const;
    public:
      iter_type get(iter_type s, ios& f, const locale& loc, double& units
  ) const;
      iter_type get(iter_type s, ios& f, const locale& loc, string& digit
  s) const;
      static const bool intl = Intl;
      static locale::id id;
      money_get(size_t refs = 0);
     protected:
     ~money_get();
    };
  }

  22.2.9.2  Template class money_put              [lib.locale.money.put]

  namespce std {
    template <class charT, bool Intl = false,
              class OutputIterator = ostreambuf_iterator<charT> >
    class money_put : public locale::facet {
    public:
      typedef charT               char_type;
      typedef OutputIterator      iter_type;
      typedef basic_string<charT> string;
      typedef basic_ios<charT>    ios;
    protected:
      virtual iter_type
        do_put(iter_type, ios&, const locale&, double units) const;
      virtual iter_type
        do_put(iter_type, ios&, const locale&, const string& digits) const;
    public:
      iter_type put(iter_type s, ios& f, const locale& loc, double units&) const;
      iter_type put(iter_type s, ios& f, const locale& loc, const string& 6dgts) const;
      static const bool intl = Intl;
      static locale::id id;
      money_put(size_t refs = 0);
    protected:
     ~money_put();
    };
  }

  22.2.10  The money punctuation facet            [lib.facet.moneypunct]

  22.2.10.1  Template class moneypunct           [lib.locale.moneypunct]
  namespace std {
    struct money_base {
      enum part { symbol='$', sign='=', space=' ', value='v', none=0 };
      struct pattern { char field[4]; };
    };
    template <class charT, bool International = false>
    class moneypunct : public locale::facet, public money_base {
    public:
      typedef charT char_type;
      static const bool intl = International;
      typedef basic_string<charT> string;
    protected:
      virtual charT        do_decimal_point() const;
      virtual charT        do_thousands_sep() const;
      virtual vector<char> do_grouping()      const;
      virtual string       do_curr_symbol()   const;
      virtual string       do_positive_sign() const;
      virtual string       do_negative_sign() const;
      virtual int          do_frac_digits()   const;
      virtual pattern      do_pos_format()    const;
      virtual pattern      do_neg_format()    const;

    public:
      charT        decimal_point() const { return do_decimal_point(); }
      charT        thousands_sep() const { return do_thousands_sep(); }
      vector<char> grouping()      const { return do_grouping(); }
      string       curr_symbol()   const { return do_curr_symbol(); };
      string       positive_sign() const { return do_positive_sign; }
      string       negative_sign() const { return do_negative_sign; }
      int          frac_digits()   const { return do_frac_digits(); }
      pattern      pos_format()    const { return do_pos_format(); }
      pattern      neg_format()    const { return do_neg_format(); }
      static locale::id id;
      moneypunct(size_t refs = 0);
    protected:
     ~moneypunct() {}
    };
  }

1 This provides money punctuation, similar to numpunct above.

  22.2.10.2  Template class               [lib.locale.moneypunct.byname]
       moneypunct_byname
  namespace std {
    template <class charT, bool Intl = false>
    class moneypunct_byname : public moneypunct<charT, Intl> {
    protected:
      virtual charT        do_decimal_point() const;
      virtual charT        do_thousands_sep() const;
      virtual vector<char> do_grouping()      const;
      virtual string       do_curr_symbol()   const;
      virtual string       do_positive_sign() const;
      virtual string       do_negative_sign() const;
      virtual int          do_frac_digits()   const;
      virtual pattern      do_pos_format()    const;
      virtual pattern      do_neg_format()    const;
    public:
      moneypunct_byname(const char*, size_t refs = 0);
    protected:
     ~moneypunct_byname();
    };
  }

  22.2.11  The message retrieval facet              [lib.facet.messages]

1 Class messages<charT> implements POSIX message retrieval.2)

  _________________________
  2) It should be flexible enough to retrieve messages from X,  MS  Win­
  dows, or Macintosh resource files as well.

  22.2.11.1  Template class messages               [lib.locale.messages]
  namespace std {
    template <class charT>
    class messages : public locale::facet {
    public:
      typedef charT char_type;
      typedef int   catalog;
      typedef basic_string<charT> string;
    protected:
      virtual catalog do_open(const string&, const locale&) const;
      virtual string  do_get(catalog, int set, int msgid,
                             const string& dfault) const;
      virtual void    do_close(catalog) const;
    public:
      catalog open(const string& fn, const locale& l) const
        { return do_open(fn, l); }
      string get(catalog c, int set, int msgid, const string& dfault) const;
      void close(catalog c) const;
      static locale::id id;
      messages(size_t refs = 0);
    protected:
     ~messages();
    };
  }

  22.2.11.2  Tmessages members             [lib.locale.messages.members]

  22.2.11.3  Template class                 [lib.locale.messages.byname]
       messages_byname
  namespace std {
    template <class charT>
    class messages_byname : public messages<charT> {
    protected:
      virtual catalog do_open(const string&, const locale&) const;
      virtual string  do_get(catalog, int set, int msgid,
                             const string& dfault) const;
      virtual void    do_close(catalog) const;
    public:
      messages_byname(const char*, size_t refs = 0);
    protected:
     ~messages_byname();
    };
  }

  22.2.12  User-defined facets                     [lib.facets.examples]

1 A user-defined facet may be added to a locale and used identically  as
  the  built-in  facets.   To  create a new facet interface users simply
  derive, from locale::facet, a class containing a static member: static
  locale::id id;.  (The locale member function templates verify its type
  and storage class.)

2 For   those   curious   about   the   mechanics:   this    initializa­
  tion/identification  system depends only on the initialization to 0 of
  static objects,  before  static  constructors  are  called.   When  an
  instance  of  a  facet  is  installed  in  a locale, the locale checks
  whether an id has been assigned, and if not, assigns one.  Before this
  occurs,  any attempted use of its interface causes the bad_cast excep­
  tion to be thrown.

3 Here is a program that just calls C functions:

4 In other words, C library localization is unaffected.

5 Traditional global localization is still easy:
    #include <iostream>
    #include <locale>
    int main(int argc, char** argv)
    {
      using namespace std;
      locale::global(locale(""));  // set the global locale
       cin.imbue(locale());        // imbue it on the std streams
      cout.imbue(locale());
      cerr.imbue(locale());
      return MyObject(argc, argv).doit();
    }

6 Greater flexibility is possible:
    #include <iostream>
    #include <locale>
    int main()
    {
      using namespace std;
      cin.imbue(locale(""));  // the user's preferred locale
      cout.imbue(locale::classic());
      double f;
      while (cin >> f) cout << f << endl;
      return (cin.fail() != 0);
    }

7 In a European locale, with input 3.456,78, output  is  3456.78.   This
  can  be  important even for simple programs, which may need to write a
  data file in a fixed format, regardless of a user's preference.

8 For example:

    // file: Date.h
    #include <locale>
       ...
    class Date {
      ...
     public:
      Date(unsigned day, unsigned month, unsigned year);
      std::string asString(const std::locale& = std::locale());
    };
    istream& operator>>(istream& s, Date& d);
    ostream& operator<<(ostream& s, Date d);
    ...

9 This example illustrates two architectural uses of class locale.   The
  first  is as a default argument in Date::asString(), where the default
  is the global (presumably user-preferred) locale.  The  second  is  in
  the  operators  <<  and  >>,  where a locale ``hitchhikes'' on another
  object, in this case a stream, to the point where it is needed.
    // file: Date.C
    #include <Date>
    #include <stringstream>
    std::string Date::asString(const std::locale& l)
    {
      using namespace std;
      stringstream s; s.imbue(l);
      s << *this; return s.data();
    }
    std::istream& operator>>(std::istream& s, Date& d)
    {
      using namespace std;
      if (!s.ipfx(0)) return s;
      locale loc = s.rdloc();
      struct tm t;
      loc.use<time_get<char> >().get_date(s, s, loc, &t);
      if (s) d = Date(t.tm_day, t.tm_mon + 1, t.tm_year + 1900);
      s.isfx();
      return s;
    }

10A locale object may be extended with a new facet simply by  construct­
  ing  it  with  an instance of a class derived from locale::facet.  The
  only member you must define is the static member id, which  identifies
  your  class interface as a new facet.  For example, imagine we want to
  classify Japanese characters:

    // file: jctype.h
    #include <locale>
    namespace My {
      using namespace std;
      class JCtype : public locale::facet {
      public:
        static locale::id id;  // required for use as a new locale facet
        bool is_kanji(wchar_t c);
        JCtype() {}
      protected:
       ~JCtype() {}
      };
    }
    // file: filt.C
    #include <iostream>
    #include <locale>
    #include <jctype> // above
    std::locale::id JCtype::id;  // the static JCtype member declared above.
    int main()
    {
      using namespace std;
      typedef ctype<wchar_t> ctype;
      locale loc(locale(""),       // the user's preferred locale ...
                 new My::JCType);  // and a new feature ...
      wchar_t c = loc.use<ctype>().widen('!');
      if (loc.use<My::JCType>().is_kanji(c))
        cout << "no it isn't!" << endl;
      return 0;
    }

11The new facet is used exactly like the built-in facets.

12Replacing an existing facet is even easier.  Here we do not  define  a
  member id because we are reusing the numpunct<charT> facet interface:
    // my_bool.C
    #include <iostream>
    #include <locale>
    #include <string>
    namespace My {
      using namespace std;
      typedef numpunct_byname<char> numpunct;
      class BoolNames : public numpunct {
        typedef basic_string<char> string;
      protected:
        string do_truename()  { return "Oui Oui!"; }
        string do_falsename() { return "Mais Non!"; }
       ~BoolNames() {}
      public:
        BoolNames(const char* name) : numpunct(name) {}
      };
    }

    int main(int argc, char** argv)
    {
      using namespace std;
      // make the user's preferred locale, except for...
      locale loc(locale(""), new My::BoolNames(""));
      cout.imbue(loc);
      cout << "Any arguments today? " << (argc > 1) << endl;
      return 0;
    }

  22.3  C Library Locales                                [lib.c.locales]

1 Header <clocale> (Table 2):

                    Table 2--Header <clocale> synopsis

            +------------------------------------------------+
            |   Type                   Name(s)               |
            +------------------------------------------------+
            |Macros:                                         |
            |             LC_MONETARY   LC_NUMERIC   LC_TIME |
            +------------------------------------------------+
            |Struct:      lconv                              |
            +------------------------------------------------+
            |Functions:   localeconv    setlocale            |
            +------------------------------------------------+

2 The  contents are the same as the Standard C library.  SEE ALSO: ISO C
  subclause 7.10.4.