______________________________________________________________________

  22   Localization library                 [lib.localization]

  ______________________________________________________________________

1 This clause describes components that C++ programs may use to encapsu­
  late  (and  therefore be more portable when confronting) cultural dif­
  ferences.  The locale facility includes  internationalization  support
  for  character classification and string collation, numeric, monetary,
  and date/time formatting and parsing, and message retrieval.

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

                  Table 1--Localization library summary

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

  22.1  Locales                                            [lib.locales]

  Header <locale> synopsis

  #include <limits>
  #include <string>
  #include <iosfwd>
  #include <stdexcept>    // for runtime_error
  #include <vector>       // for vector<char>

  namespace std {
  // subclause _lib.locale_, locale:
    class locale;
    template <class charT, class Traits>
      basic_ostream<charT,Traits>&
        operator<<(basic_ostream<charT,Traits>& s, const locale& loc);
    template <class charT, class Traits>
      basic_istream<charT,Traits>&
        operator>>(basic_istream<charT,Traits>& 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.category.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
    class codecvt_base;
    template <class fromT, class toT, class stateT> class codecvt;
    template <class fromT, class toT, class stateT> class codecvt_byname;
  // subclauses _lib.category.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.category.collate_, collation:
    template <class charT> class collate;
    template <class charT> class collate_byname;
  // subclause _lib.category.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.category.monetary_, 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.category.messages_, message retrieval:
    class messages_base;
    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:
    // types:
      class facet;
      class id;
      typedef unsigned category;
      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;
    // construct/copy/destroy:
      locale();
      locale(const locale& other);
      explicit 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);
    // locale operations:
      template <class Facet> const Facet& use()  const;
      template <class Facet> bool         has()  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;
    // global locale objects:
      static       locale  global(const locale&);
      static const locale& classic();
      static       locale  transparent();
    };
  }

1 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.

2 Access to the facets of a locale is via two member function templates,
  locale::use<facet>() and locale::has<facet>().

3 [Example: An iostream operator<< might be  implemented  (and  special­
  ized, for simplicity of exposition) as:

    ostream& operator<<(ostream& s, double f)
    {
      if (s.opfx()) {
        locale loc = s.getloc();
        loc.template use< num_put<char> >().put(s, s, loc, f);
      }
      s.osfx();
      return s;
    }
   --end example]

4 In  the call to loc.template use<Facet>(), the type argument chooses a
  facet, making available all members of the named type. If Facet is not
  present  in  a  locale  (or,  failing  that, in the global locale), it
  throws the standard exception bad_cast.  A C++ program can check if  a
  locale  implements  a  particular  facet with the member has<Facet>().
  User-defined facets may be installed in a locale, and used identically
  as may standard facets (_lib.facets.examples_).

5 All  locale  semantics  are accessed via use<>() and has<>(), with two
  exceptions:

  --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).

  --A    member    operator    template     operator()(basic_string<C>&,
    basic_string<C>&)  is  provided  so  that  a locale may be used as a
    predicate argument to the standard collections, to collate  strings.

6 [Note:  The  purpose  of  this  is  to ease the conversion of existing
  extractors (_lib.istream.formatted_).   --end note]

7 A locale which does not implement a  facet  delegates  to  the  global
  locale  in  effect  at the time that instantiation of use<>() is first
  called on that facet (_lib.locale.statics_).

8 An instance of locale is immutable; once a facet reference is obtained
  from  it,  that  reference  remains usable as long as the locale value
  itself exists.  The effect of imbuing  on  a  stream  (_lib.ios.base_,
  _lib.ios_),  or  installing as the global locale, the result of static
  member locale::transparent() (or any locale with similar behavior)  is
  unspecified.

9 Caching  results  from  calls  to locale facet member functions during
  calls to iostream inserters and extractors, and in streambufs  between
  calls    to    basic_streambuf::imbue,    is    explicitly   supported
  (_lib.streambuf_).2)

  _________________________
  2) This implies that member functions of iostream classes cannot safe­
  ly call imbue() themselves, except as specified elsewhere.

10A  locale  constructed  from  a name string (such as "POSIX"), 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 *".

  22.1.1.1  locale types                              [lib.locale.types]

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

  typedef unsigned category;

1 Valid category values include 0 and the locale member bitmask elements
  collate, ctype, monetary, numeric, time, and messages.   In  addition,
  locale member all is defined such that the expression
    (collate | ctype | monetary | numeric | time | messages) == all
  is true.  Further, the result of applying operators & and | to any two
  valid values is itself valid.

2 locale member functions expecting a category argument require either a
  valid category value or one of the constants LC_CTYPE etc., defined in
  <cctype>.  Such a category value identifies  a  set  of  locale  cate­
  gories.   Each  locale  category,  in turn, identifies a set of locale
  facets, as shown in Table 2:

                     Table 2--Locale Category Facets

     +---------------------------------------------------------------+
     |Category                     Includes Facets                   |
     +---------------------------------------------------------------+
     |collate    collate<char>, collate<wchar_t>                     |
     +---------------------------------------------------------------+
     |ctype      ctype<char>, ctype<wchar_t>                         |
     |           codecvt<char,wchar_t,mbstate_t>,                    |
     |           codecvt<wchar_t,char,mbstate_t>                     |
     +---------------------------------------------------------------+
     |monetary   moneypunct<char>, moneypunct<wchar_t>               |
     |           moneypunct<char,true>, moneypunct<wchar_t,true>,    |
     |           money_get<char,InputIterator>,                      |
     |           money_get<wchar_t,InputIterator>,                   |
     |           money_put<char,OutputIterator>,                     |
     |           money_put<wchar_t,OutputIterator>                   |
     +---------------------------------------------------------------+
     |numeric    numpunct<char>, numpunct<wchar_t>,                  |
     |           num_get<C,InputIterator>, num_put<C,OutputIterator> |
     +---------------------------------------------------------------+
     |time       time_get<char,InputIterator>,                       |
     |           time_put<wchar_t,OutputIterator>,                   |
     |           time_put<char,OutputIterator>,                      |
     |           time_put<wchar_t,OutputIterator>                    |
     +---------------------------------------------------------------+
     |messages   messages<char>, messages<wchar_t>                   |
     +---------------------------------------------------------------+

3 An implementation is only required to provide instantiations  for  the
  facets   identified  as  implementing  a  category.   For  the  facets
  num_get<> and num_put<> the implementation provided must  depend  only
  on the facets numpunct<> and ctype<>, instantiated on the same charac­
  ter type.  Other facets are allowed to depend on any other facet  that
  is part of a standard category.

4 Each  locale  member function which takes a category argument operates
  on the corresponding set of facets.  Those facets represented  with  a
  template parameter InputIterator or OutputIterator indicate the set of
  all possible instantiations on parameters that  satisfy  the  require­
  ments of an Input Iterator or an Output Iterator, respectively.  Those
  facets represented with a template parameter C represent  the  set  of
  all possible instantiations on a parameter that satisfies the require­
  ments for a character on which any of the iostream components  can  be
  instantiated.

5 In  declarations  of  facets,  a  template  formal parameter with name
  InputIterator or OutputIterator indicates that  instantiations  depend
  only  on  the  semantics  specified for an Input Iterator or an Output
  Iterator as defined in _lib.iterator.requirements_.

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

1 Class facet is the base class for locale feature sets.  A class  is  a
  facet  if  it  is  publicly  derived from another facet, or if it is a
  class derived from locale::facet and containing a declaration as  fol­
  lows:
        static ::std::locale::id id;
  Template  parameters  in  this  Clause  which must be facets are those
  named Facet in declarations.  A program that passes a type that is not
  a  facet,  as  an (explicit or deduced) template parameter to a locale
  function expecting a facet, is ill-formed.

2 The refs argument to the constructor is used for lifetime  management.

  --If  (refs  ==  0)  the  facet's lifetime is managed by the locale or
    locales it is incorporated into;

  --if (refs == 1) its lifetime is until explicitly deleted.

3 Constructors of all facets defined in this Clause take such  an  argu­
  ment  and  pass  it  along to their facet base class constructor.  All
  one-argument constructors defined in this clause  are  explicit,  pre­
  venting their participation in automatic conversions.

4 For  some  standard facets a standard _byname" class, derived from it,
  implements the semantics equivalent to that facet of the  locale  con­
  structed by locale(const char*).  Each such facet provides a construc­
  tor that takes a const char* argument, which names the locale,  and  a
  refs  argument,  which  is  passed  to the base class constructor.  If
  there is no _byname" version of a facet,  the  base  class  implements
  such  semantics  itself,  sometimes  with  the  help  of  other facets
  obtained via a locale argument.

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

1 Identification of a locale facet  interface,  used  as  an  index  for
  lookup and to encapsulate initialization.

2 [Note:  Because facets are used by iostreams, potentially while static
  constructors are running, their initialization cannot depend  on  pro­
  grammed static initialization.3)  --end note]

  22.1.1.2  locale constructors and destructor         [lib.locale.cons]

  locale();

1 Default constructor: a snapshot of the current global locale.
  Effects:
    Constructs a locale instance whose value is a snapshot of  the  cur­
    rent  global locale state as set by locale::global(locale&) or the C
    function setlocale().  This constructor  is  commonly  used  as  the
    default  value  for  arguments of functions that take a locale argu­
    ment.

  locale(const locale& other);

  Effects:
    Constructs a locale which is a copy of other.

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

  Effects:
    Creates a copy of other, replacing the current value.
  Returns:
    *this

  explicit locale(const char* std_name);

  Effects:
    Constructs a locale using standard C  locale  names,  e.g.  "POSIX".
    The  resulting  locale implements semantics defined to be associated
    with that name.
  Requires:
    The set of valid string argument values is "C", "", and  any  imple­
    mentation-defined values.

  _________________________
  3)  One  way  to do this is for locale to initialize the id member the
  first time an instance of the facet is installed into a locale.   This
  depends  only  on  static  storage  being zero before constructors run
  (_basic.start.init_).

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

  Effects:
    Constructs a locale as a copy of other except for the facets identi­
    fied by the category argument,  which  instead  implement  the  same
    semantics as locale(std_name).
  Notes:
    The locale has a name if and only if other has a name.

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

  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.
  Notes:
    The resulting locale has no name.

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

  Effects:
    Constructs a locale incorporating all facets from the first argument
    except that identified by Facet, and  that  facet  from  the  second
    argument instead.
  Throws:
    runtime_error if one.template has<Facet>() is false.
  Notes:
    The resulting locale has no name.

  locale(const locale& other, const locale& one, category cats);

  Effects:
    Constructs a locale incorporating all facets from the first argument
    except those that implement cats,  which  are  instead  incorporated
    from the second argument.
  Notes:
    The  resulting  locale has a name if and only if the first two argu­
    ments have names.

  ~locale();

2 A non-virtual destructor.

  22.1.1.3  locale members                          [lib.locale.members]

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

1 Get a reference to a facet of a locale.
  Effects:
    If the requested Facet is not present in *this, but  is  present  in
    the  current  global locale, returns the global locale's instance of
    Facet.  Because locale objects are immutable,  subsequent  calls  to
    use<Facet>()  return  the  same object, regardless of changes to the
    global locale.4)
  Throws:
    bad_cast  if  (this->template  has<Facet>()   ||   locale().template
    has<Facet>()) is false.
  Returns:
    A reference to the requested facet.
  Notes:
    The result is guaranteed by locale's value semantics to last as long
    as the value of *this.

  template <class Facet> bool has() const;

  Returns:
    An indication whether the facet requested is present in  *this.   If
    use<Facet>() has already been called successfully, returns true.
  Notes:
    locale::transparent().template has<Facet>() always returns false.

  basic_string<char>  name() const;

  Returns:
    The name of *this, if it has one; otherwise, the string "*".

  22.1.1.4  locale operators                      [lib.locale.operators]

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

  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  other­
    wise.

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

  Returns:
    The result of the expression: !(*this == other)

  _________________________
  4) The only exception to this rule  is  the  locale  returned  by  lo­
  cale::transparent();  it  always returns the Facet found in the global
  locale at the time of each call.

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

  Effects:
    Compares two strings according to the collate<charT> facet.
  Notes:
    This  member  operator template (and therefore locale itself) satis­
    fies requirements  for  a  comparator  predicate  template  argument
    (_lib.algorithms_) applied to strings.
  Returns:
    The result of the following expression:
      use< collate<charT> >().compare(s1.data(), s1.data()+s1.size(),
                                      s2.data(), s2.data()+s2.size()) < 0;

1 [Example: A vector of strings v can be collated according to collation
  rules in locale loc simply by (_lib.alg.sort_, _lib.vector_):
    std::sort(v.begin(), v.end(), loc);
   --end example]

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

2 The     regular     stream     output     operator     for     locales
  (_lib.ostream.formatted_).
  Effects:
    s << loc.name() << endl.
  Returns:
    The output stream argument s.

  template <class charT, class Traits>
    basic_istream<charT,Traits>&
      operator>>(basic_istream<charT,Traits>& s, loc& loc);

3 The      regular     stream     input     operator     for     locales
  (_lib.istream.formatted_).
  Effects:
    Read a line into a string and construct a locale from it.  If either
    operation     fails,     indicates     a    failure    by    calling
    s.setstate(ios_base::failbit)  (which  may  throw  ios_base::failure
    (_lib.iostate.flags_),  otherwise,  assigns  the  constructed locale
    object into the argument loc.
  Returns:
    s.

  22.1.1.5  locale static members                   [lib.locale.statics]

  static locale global(const locale& loc);

1 Replaces ::setlocale().
  Effects:
    Sets the global locale to its argument.   Subsequent  calls  to  the
    default  constructor, and of other library functions affected by the
    function setlocale(), use the locale loc until the next call to this
    member or setlocale().
  Returns:
    The previous global locale.

  static const locale& classic();

2 The "C" locale.
  Returns:
    A  locale  that implements the classic "C" locale semantics, equiva­
    lent to the value locale("C").
  Notes:
    This locale, its facets, and their member functions, do  not  change
    with time.

  static locale transparent();

3 The continuously updated global locale.
  Returns:
    A  locale  which  implements  semantics that vary dynamically as the
    global locale is changed.
  Notes:
    The effect of imbuing this locale into  an  iostreams  component  is
    unspecified (_lib.ios.members_).

  22.1.2  Convenience interfaces                [lib.locale.convenience]

  22.1.2.1  Character classification                [lib.classification]

  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;

1 Each of these functions isF returns the result of the expression:
    loc.template use< ctype<charT> >().is(ctype<charT>::F, c)
  where  F  is  the  ctype_mask  value  corresponding  to  that function
  (_lib.category.ctype_).

  22.1.2.2  Character conversions                      [lib.conversions]

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

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

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

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

  22.2  Standard locale categories               [lib.locale.categories]

1 Each of the standard categories includes a family of facets.  Some  of
  these implement formatting or parsing, intended for use by standard or
  users' operators << and >>.  Those that take a basic_ios<charT>& argu­
  ment  obey  all  formatting  conventions specified for members of that
  class, including width() and fill() (_lib.ios.base_).

  22.2.1  The ctype category                        [lib.category.ctype]
  namespace std {
    class ctype_base {
    public:
      enum ctype_mask {  // numeric values are for exposition only.
        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=alpha|digit, graph=alnum|punct
      };
    };
  }

1 The type ctype_mask is a bitmask type.

  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;
      explicit ctype(size_t refs = 0);
      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* low, const char* high, charT* to) const;
      char         narrow(charT c, char dfault) const;
      const charT* narrow(const charT* low, const charT*, char dfault,
                          char* to) const;
      static locale::id id;
    protected:
     ~ctype();  // virtual
      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* low, const char* high,
                                    charT* dest) const;
      virtual char         do_narrow(charT, char dfault) const;
      virtual const charT* do_narrow(const charT* low, const charT* high,
                                     char dfault, char* dest) const;
    };

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

2 The base class implementation implements character classing  appropri­
  ate to the implementation's native character set.

  22.2.1.1.1  ctype members                   [lib.locale.ctype.members]

  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)

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

  Returns:
    do_scan_is(mask,low,high)

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

  Returns:
    do_scan_not(mask,low,high)

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

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

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

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

  charT       widen(char c) const;
  const char* widen(const char* low, const char* high, charT* to) const;

  Returns:
    do_widen(c) or do_widen(low,high,to)

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

  Returns:
    do_narrow(c,dfault) or do_narrow(low,high,dfault,to)

  22.2.1.1.2  ctype virtual functions        [lib.locale.ctype.virtuals]

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

  Effects:
    Classifies a character or sequence of characters.  For each argument
    character, identifies a value M of type ctype_mask  The  first  form
    returns  the  result  of the expression (M & mask) != 0.  The second
    form simply places M for all  *p  where  (low<=p  &&  p<high),  into
    vec[p-low].
  Returns:
    The first form returns true if the character has the characteristics
    specified.  The second form returns low.

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

  Effects:
    Locates a character in a buffer that conforms  to  a  classification
    mask.
  Returns:
    The  smallest  pointer  p  in the range [low, high) such that is(*p)
    would return true; otherwise, returns high.

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

  Effects:
    Locates a character in a buffer that fails to conform to a classifi­
    cation mask.
  Returns:
    The  smallest  pointer p, if any, in the range [low, high) such that
    is(*p) would return false; otherwise, returns high.

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

  Effects:
    Converts a character or characters to upper case.
  Effects:
    The second form replaces each character *p in the range [low,  high)
    for  which  a  corresponding  upper-case character exists, with that
    character.
  Returns:
    The first form returns the corresponding upper-case character if  it
    is  known to exist, or its argument if not.  The second form returns
    high.

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

  Effects:
    Converts a character or characters to upper case.
  Effects:
    The second form replaces each character *p in the range [low,  high)
    and for which a corresponding lower-case character exists, with that
    character.
  Returns:
    The first form returns the corresponding lower-case character if  it
    is  known to exist, or its argument if not.  The second form returns
    high.

  charT        do_widen(char c) const;
  const char*  do_widen(const char* low, const char* high,
                        charT* dest) const;

  Effects:
    Applies the simplest reasonable transformation from a char value  or
    sequence  of char values to the corresponding charT value or values.
    The only characters for which unique  transformations  are  required
    are the digits, alphabetic characters, '-', '+', newline, and space.
    For any named ctype category with a ctype<charT> facet ctw and valid
    ctype_mask  value M, however, (is(M, c) || !ctw.is(M, do_widen(c)) )
    is true.5)
    The  second  form  transforms  each  character *p in the range [low,
    high), placing the result in dest[p-low].
  Returns:
    The first form returns  the  transformed  value.   The  second  form
    returns high

  char         do_narrow(charT c, char dfault) const;
  const charT* do_narrow(const charT* low, const charT* high,
                         char dfault, char* dest) const;

  Effects:
    Applies the simplest reasonable transformation from a charT value or
    sequence of charT values to the corresponding char value or  values.
    The  only  characters  for which unique transformations are required
    are the digits, alphabetic characters, '-', '+', newline, and space.
    For  any  named ctype category with a ctype<char> facet ctc however,
    and valid ctype_mask value M, (is(M, c) || !ctc.is(M,  do_narrow(c))
    )  is  true.  In addition, for any digit character c, the expression
    (do_narrow(c)-'0') evaluates to the digit value of the character.

  _________________________
  5) In other words, the transformed character is not a  member  of  any
  character classification that c is not also a member of.

  Effects:
    The second form transforms each character  *p  in  the  range  [low,
    high),  placing the result (or dfault if no simple transformation is
    readly available) in dest[p-low].
  Returns:
    The first form returns the transformed value; or dfault if  no  map­
    ping is readily available.  The second form returns high.

  22.2.1.2  Template class ctype_byname        [lib.locale.ctype.byname]
    template <class charT>
    class ctype_byname : public ctype<charT> {
    public:
      explicit ctype_byname(const char*, size_t refs = 0);
    protected:
     ~ctype_byname();  // virtual
      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;
    };
  }

1 This class is specialized for at least char and wchar_t.

  22.2.1.3  ctype specializations              [lib.facet.ctype.special]
  namespace std {
    class ctype<char> : public locale::facet, public ctype_base {
    public:
      typedef char char_type;
      explicit ctype(const ctype_mask* tab = 0, bool del = false,
                     size_t refs = 0);
      bool is(ctype_mask mask, char c) const;
      const char* is(const char* low, const char* high, 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* low, const char* high, char* to) const;
      char  narrow(char c, char /*dfault*/) const;
      const char* narrow(const char* low, const char* high, char /*dfault*/,
                         char* to) const;
      static locale::id id;
    protected:
      const ctype_mask* const table_;
      static const ctype_mask classic_table_[numeric_limits<unsigned char>::max()+1];

     ~ctype();  // virtual
      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;
    };
    private:
      bool delete_it_              // exposition only
  }

1 A  specialization ctype<char> is provided so that the member functions
  on type char can be implemented inline.6)

  22.2.1.3.1  ctype<char> destructor         [lib.facet.ctype.char.dtor]

  ~ctype();

  Effects:
    if (delete_it_) delete[] table_;

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

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

  Effects:
    Passes  its refs argument to its base class constructor, initializes
    protected member table_ with the tab argument  if  nonzero,  or  the
    static value classic_table_ otherwise, and initializes the protected
    member delete_it_ to (tab && del).

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

  Effects:
    The second form, for all *p in the range [low, high), assigns vec[p-
    low] to table_[(unsigned char)*p].
  Returns:
    The  first  form returns table_[(unsigned char)c] & mask; the second
    form returns low.

  _________________________
  6) Only the char (not unsigned char and signed char) form is provided.
  The  specialization  is  specified in the standard, and not left as an
  implementation detail, because it affects the derivation interface for
  ctype<char>.

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

  Returns:
    The smallest p in the range [low, high) such  that  (table[(unsigned
    char) *p] & mask) == true.

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

  Returns:
    The  smallest  p in the range [low, high) such that (table[(unsigned
    char) *p] & mask) == false.

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

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

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

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

  char  widen(char c) const;
  const char* widen(const char* low, const char* high,
      char* to) const;

  Effects:
    ::memcpy(to, low, high-low)
  Returns:
    c or hi

  char        narrow(char c, char /*dfault*/) const;
  const char* narrow(const char* low, const char* high,
                     char /*dfault*/, char* to) const;

  Effects:
    ::memcpy(to, low, high-low)
  Returns:
    c or high.

  22.2.1.3.3  ctype<char>                [lib.facet.ctype.char.virtuals]
       overridden virtual functions

  22.2.1.4  Template class codecvt                  [lib.locale.codecvt]
  namespace std {
    class codecvt_base {
    public:
      enum result { ok, partial, error, noconv };
    };
    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;
      explicit codecvt(size_t refs = 0)
      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;
    protected:
     ~codecvt();  // virtual
      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;
    };
  }

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 instantiated oppo­
  sitely.

2 The stateT argument selects the pair of codesets being mapped between.

3 Implementations   are   required   to   provide   instantiations   for
  <char,wchar_t,mbstate_t> and <wchar_t,char,mbstate_t>.

  22.2.1.4.1  codecvt members               [lib.locale.codecvt.members]

  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.1.4.2  codecvt virtual              [lib.locale.codecvt.virtuals]
       functions

  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;

  Preconditions:
    (from<=from_end && to<=to_end) well-defined and true; state initial­
    ized, if at the beginning of a sequence, or else equal to the result
    of converting the preceding characters in the sequence.
  Effects:
    Translates  characters  in  the  range  [from,from_end), placing the
    results starting at to.
    Stops when it runs out of characters to translate or  space  to  put
    the  results, or if it encounters a character it cannot convert.  It
    always leaves the from_next and to_next pointers pointing one beyond
    the last character successfully converted.
    If  no translation is needed (returns noconv), sets to_next equal to
    argument to.
  Notes:
    Does not write into *to_limit.  Its operations on state are unspeci­
    fied.
    [Note:  This  argument  can  be used, for example, to maintain shift
    state, to specify conversion options (such as  count  only),  or  to
    identify a cache of seek offsets.   --end note]
  Returns:
    An enumeration value, as summarized in Table 3:

                       Table 3--convert result values

     +-----------------------------------------------------------------+
     | Value                           Meaning                         |
     +-----------------------------------------------------------------+
     |ok        completed the conversion                               |
     |partial   ran out of space in the destination                    |
     |error     encountered a from_type character it could not convert |
     |noconv    no conversion was needed                               |
     +-----------------------------------------------------------------+

  22.2.1.5  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> {
    public:
      explicit codecvt_byname(const char*, size_t refs = 0);
    protected:
     ~codecvt_byname();  // virtual
      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;
    };
  }

  22.2.2  The numeric category                    [lib.category.numeric]

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 extraction of smaller types to
  extractors for larger types, but are not required to do so.

2 The  functions  take a locale argument because their base class imple­
  mentation relies on numpunct<> members to identify all numeric punctu­
  ation preferences, and on ctype<> members to perform character classi­
  fication.

3 Extractor and inserter members of the standard iostreams are  required
  to  use  num_get<>  and  num_put<> member functions for formatting and
  parsing                               (_lib.istream.formatted.reqmts_,
  _lib.ostream.formatted.reqmts_).   The  ios& argument is used both for
  format control, and to  report  errors,  as  described  in  subclauses
  _lib.iostate.flags_ and _lib.fmtflags.state_.

  22.2.2.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;
      explicit num_get(size_t refs = 0);
      iter_type get(iter_type in, iter_type end, ios&,
                    const locale&, bool& v)          const;
      iter_type get(iter_type in, iter_type end, ios& ,
                    const locale&, long& v)          const;
      iter_type get(iter_type in, iter_type end, ios&,
                    const locale&, unsigned long& v) const;
      iter_type get(iter_type in, iter_type end, ios&,
                    const locale&, double& v)        const;
      iter_type get(iter_type in, iter_type end, ios&,
                    const locale&, long double& v)   const;
      static locale::id id;

    protected:
     ~num_get();  // virtual
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               bool& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               unsigned long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               double& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               long double& v) const;
    };
  }

1 The  facet  num_get  is  used  to  parse  numeric values from an input
  sequence such as an istream.

  22.2.2.1.1  num_get members                [lib.facet.num.get.members]

  iter_type get(iter_type in, iter_type end, ios& str
                const locale& loc, bool& val) const;
  iter_type get(iter_type in, iter_type end, ios& str
                const locale& loc, long& val) const;
  iter_type get(iter_type in, iter_type end, ios& str
                const locale& loc, unsigned long& val) const;
  iter_type get(iter_type in, iter_type end, ios& str
                const locale& loc, double& val) const;
  iter_type get(iter_type in, iter_type end, ios& str
                const locale& loc, long double& val) const;

  Returns:
    do_get(in, end, str, loc, val).

  22.2.2.1.2  num_get virtual               [lib.facet.num.get.virtuals]
       functions

  iter_type do_get(iter_type in, iter_type end, ios& str
                   const locale& loc, bool& val) const;
  iter_type do_get(iter_type in, iter_type end, ios& str
                   const locale& loc, long& val) const;
  iter_type do_get(iter_type in, iter_type end, ios& str
                   const locale& loc, unsigned long& val) const;
  iter_type do_get(iter_type in, iter_type end, ios& str
                   const locale& loc, double& val) const;
  iter_type do_get(iter_type in, iter_type end, ios& str
                   const locale& loc, long double& val) const;

  Effects:
    Reads   characters   from   in,   interpreting   them  according  to
    str.flags(), loc.use template< ctype<charT> >, and loc.use template<

    numpunct<charT>  >.   do_get()  ignores  the value of str.rdstate();
    however, indicates failure by calling  str.setstate(failbit)  (which
    may throw ios_base::failure (_lib.iostate.flags_)).
    If  an  error  occurs,  val is unchanged; otherwise it is set to the
    resulting value.
  Notes:
    Digit group separators are optional; if present, digit  grouping  is
    checked after the entire number is read.  When reading a non-numeric
    boolean value, the names are compared exactly.
  Returns:
    An iterator pointing one past the last character consumed as part of
    the converted field.

  22.2.2.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;
      explicit num_put(size_t refs = 0);
      iter_type put(iter_type s, ios& f, const locale& loc, bool v)          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, double v) const;
      iter_type put(iter_type s, ios& f, const locale& loc, long double v) const;
      static locale::id id;
    protected:
     ~num_put();  // virtual
      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&, double v) const;
      virtual iter_type do_put(iter_type, ios&, const locale&, long double v) const;
    };
  }

1 The  facet  num_put  is  used  to format numeric values to a character
  sequence such as an ostream.

  22.2.2.2.1  num_put members                [lib.facet.num.put.members]

  iter_type put(iter_type out, ios& str
                const locale& loc, bool val) const;
  iter_type put(iter_type out, ios& str
                const locale& loc, long val) const;
  iter_type put(iter_type out, ios& str
                const locale& loc, unsigned long val) const;
  iter_type put(iter_type out, ios& str
                const locale& loc, double val) const;
  iter_type put(iter_type out, ios& str
                const locale& loc, long double val) const;

  Returns:
    do_put(out, str, loc, val).

  22.2.2.2.2  num_put virtual               [lib.facet.num.put.virtuals]
       functions

  iter_type do_put(iter_type out, ios& str
                   const locale& loc, bool val) const;
  iter_type do_put(iter_type out, ios& str
                   const locale& loc, long val) const;
  iter_type do_put(iter_type out, ios& str
                   const locale& loc, unsigned long val) const;
  iter_type do_put(iter_type out, ios& str
                   const locale& loc, double val) const;
  iter_type do_put(iter_type out, ios& str
                   const locale& loc, long double val) const;

  Effects:
    Writes  characters  to the sequence out, formatting val according to
    str.flags(), loc.use template< ctype<charT> >, and loc.use template<
    numpunct<charT>  >.   Inserts digit group separators as specified by
    numpunct<charT>::do_grouping.
  Notes:
    do_put() ignores and does not change  the  result  of  str.rdstate()
    (_lib.ios.base_).
  Returns:
    An  iterator pointing immediately after the last character produced.

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

  22.2.3.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;
      explicit numpunct(size_t refs = 0);

      string decimal_point()   const;
      string thousands_sep()   const;
      vector<char>  grouping() const;
      string truename()        const;
      string falsename()       const;
      static locale::id id;
    protected:
     ~numpunct();  // virtual
      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
    };
  }

1 numpunct<> specifies numeric punctuation.   The  base  class  provides
  classic  C" numeric formats, while the _byname" version supports named
  locale (e.g. POSIX, X/Open) numeric formatting semantics.

2 The syntax for number formats is as follows,  where  digit  represents
  the  radix set specified by the fmtflags argument value, whitespace is
  as determined by  the  facet  ctype<charT>  (_lib.locale.ctype_),  and
  thousands-sep  and  decimal-point  are  the  results  of corresponding
  numpunct<charT> members.  Integer values have the format:
    integer   ::= [sign] units
    sign      ::= plusminus [whitespace]
    plusminus ::= '+' | '-'
    units     ::= digits [thousands-sep units]
    digits    ::= digit [digits]
  and floating-point values have:
    floatval ::= [sign] units [decimal-point [digits]] [e [sign] digits] |
                 [sign]        decimal-point  digits   [e [sign] digits]
    e        ::= 'e' | 'E'
  where the number of digits between thousands-seps is as  specified  by
  do_grouping().   For  parsing, if the digits portion contains no thou­
  sands-separators, no grouping constraint is applied.

  22.2.3.1.1  numpunct members              [lib.facet.numpunct.members]

  string decimal_point() const;

  Returns:
    do_decimal_point()

  string thousands_sep() const;

  Returns:
    thousands_sep()

  vector<char> grouping()  const;

  Returns:
    do_grouping()

  string truename()  const;
  string falsename() const;

  Returns:
    do_truename() or do_falsename(), respectively.

  22.2.3.1.2  numpunct virtual             [lib.facet.numpunct.virtuals]
       functions

  string do_decimal_point() const;

  Returns:
    A  basic_string<charT>  for  use as the decimal radix separator.  If
    this is not a one-character string, num_get<charT,InputIterator>  is
    not required to recognize numbers formatted using it.
    The base class implementation returns ".".

  string do_thousands_sep() const;

  Returns:
    A basic_string<charT> for use as the digit group separator.  If this
    is longer than one character,  num_get<charT,InputIterator>  is  not
    required to recognize numbers formatted with it.
    The base class implementation returns the empty string.

  vector<char> do_grouping() const;

  Returns:
    A  vector  vec in which each element vec[i] represents the number of
    digits in the group at position i starting with 0 as  the  rightmost
    group.   If  vec.size() <= i, the number is the same as group (i-1);
    if (i<0 || vec[i]<=0), the size of the digit group is unlimited.
    The base class implementation returns the empty vector.

  string do_truename()  const;
  string do_falsename() const;

  Returns:
    A string representing the name of the boolean value true  or  false,
    respectively.
    In the base class implementation these names are "true" and "false".

  22.2.3.2  Template class                  [lib.locale.numpunct.byname]
       numpunct_byname
  namespace std {
    template <class charT>
    class numpunct_byname : public numpunct<charT> {
      // this class is specialized for char and wchar_t.
    public:
      explicit numpunct_byname(const char*, size_t refs = 0);
    protected:
     ~numpunct_byname();  // virtual
      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
    };
  }

  22.2.4  The collate category                    [lib.category.collate]

  22.2.4.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;
      explicit collate(size_t refs = 0);
      int compare(const charT* low1, const charT* high1,
                  const charT* low2, const charT* high2) const;
      string transform(const charT* low, const charT* high) const;
      long hash(const charT* low, const charT* high) const;
      static locale::id id;
    protected:
     ~collate();  // virtual
      virtual int    do_compare(const charT* low1, const charT* high1,
                                const charT* low2, const charT* high2) const;
      virtual string do_transform(const charT* low, const charT* high) const;
      virtual long   do_hash     (const charT* low, const charT* high) const;
    };
  }

1 The  class  collate<charT>  provides features for use in the collation
  (comparison) and hashing of strings.  A locale  member  function  tem­
  plate,  operator(),  uses  the  collate facet to allow a locale to act
  directly  as  the   predicate   argument   for   standard   algorithms
  (_lib.algorithms_)  and  containers  operating  on  strings.  The base
  class     implementation      applies      lexicographic      ordering
  (_lib.alg.lex.comparison_).

2 Each  function  compares  a  string  of  characters  *p  in  the range
  [low,high).

  22.2.4.1.1  collate members               [lib.locale.collate.members]

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

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

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

  Returns:
    do_transform(low, high)

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

  Returns:
    do_hash(low, high)

  22.2.4.1.2  collate virtual              [lib.locale.collate.virtuals]
       functions

  int do_compare(const charT* low1, const charT* high1,
                 const charT* low2, const charT* high2) const;

  Returns:
    1  if  the first string is greater than the second, -1 if less, zero
    otherwise.

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

  Returns:
    A basic_string<charT> value that,  compared  lexicographically  with
    the result of calling transform() on another string, yields the same
    result as calling compare() on the same two strings.7)

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

  Returns:
    An  integer value equal to the result of calling hash() on any other
    string for which compare() returns 0 (equal)  when  passed  the  two
    strings.
  Notes:
    The probability that the result equals that for another string which
  _________________________
  7) This function is useful when one string is being compared  to  many
  other strings.

    does  not  compare  equal  should   be   very   small,   approaching
    (2.0/numeric_limits<long>::max()) or less for longer strings.

  22.2.4.2  Template class                   [lib.locale.collate.byname]
       collate_byname
  namespace std {
    template <class charT>
    class collate_byname : public collate<charT> {
    public:
      explicit collate_byname(const char*, size_t refs = 0);
    protected:
     ~collate_byname();  // virtual
      virtual int    do_compare(const charT* low1, const charT* high1,
                                const charT* low2, const charT* high2) const;
      virtual string do_transform(const charT* low, const charT* high) const;
      virtual long   do_hash(     const charT* low, const charT* high) const;
    };

  22.2.5  The time category                          [lib.category.time]

1 The         classes         time_get<charT,InputIterator>          and
  time_put<charT,OutputIterator>  provide  date  and time formatting and
  parsing.  The ios& argument is used both for format  control,  and  to
  report  errors,  as  described  in  subclauses _lib.ios::fmtflags_ and
  _lib.ios::iostate_.

  22.2.5.1  Template class time_get                [lib.locale.time.get]
  namespace std {
    class time_base {
    public:
      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;
      explicit time_get(size_t refs = 0);
      dateorder date_order()  const { return do_date_order(); }
      iter_type get_time(iter_type s, iter_type end, ios& f,
                         const locale& loc, tm* t)  const;
      iter_type get_date(iter_type s, iter_type end, ios& f,
                         const locale& loc, tm* t)  const;
      iter_type get_weekday(iter_type s, iter_type end, ios& f,
                            const locale& loc, tm* t) const;
      iter_type get_monthname(iter_type s, iter_type end, ios& f,
                              const locale& loc, tm* t) const;
      iter_type get_year(iter_type s, iter_type end, ios& f,
                         const locale& loc, tm* t\fP) const;
      static locale::id id;

    protected:
     ~time_get();  // virtual
      virtual dateorder do_date_order()  const;
      virtual iter_type do_get_time(iter_type s, iter_type end, ios&,
                                    const locale&, tm* t) const;
      virtual iter_type do_get_date(iter_type s, iter_type end, ios&,
                                    const locale&, tm* t) const;
      virtual iter_type do_get_weekday(iter_type s, iter_type end, 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, iter_type end, ios&,
                                    const locale&, tm* t) const;
    };
  }

1 time_get is used to parse a character sequence, extracting  components
  of  a  time or date into a struct tm record.  Each get member parses a
  format  as  produced  by   a   corresponding   format   specifier   to
  time_put<>::put.   If  the  sequence  being parsed matches the correct
  format, the corresponding members of the struct tm argument are set to
  the  values used to produce the sequence; otherwise either an error is
  reported or unspecified values are assigned.8)

  22.2.5.1.1  time_get members             [lib.locale.time.get.members]

  dateorder date_order() const;

  Returns:
    do_date_order()

  iter_type get_time(iter_type s, iter_type end, ios& str,
                     const locale& loc, tm* t) const;

  Returns:
    do_get_time(s, end, str, loc, t)

  iter_type get_date(iter_type s, iter_type end, ios& str,
                     const locale& loc, tm* t) const;

  Returns:
    do_get_date(s, end, str, loc, t)

  _________________________
  8) In other words, user confirmation is required for reliable  parsing
  of  user-entered dates and times, but machine-generated formats can be
  parsed reliably.  This allows parsers to be  aggressive  about  inter­
  preting user variations on standard formats.

  iter_type get_weekday(iter_type s, iter_type end, ios& str,
                        const locale&loc, tm* t) const;
  iter_type get_monthname(iter_type s, iter_type end, ios& str,
                          const locale& loc, tm* t) const;

  Returns:
    do_get_weekday(s, end, str, loc, t) or do_get_monthname(s, end, str,
    loc, t

  iter_type get_year(iter_type s, iter_type end, ios& str,
                     const locale& loc, tm* t) const;

  Returns:
    do_get_year(s, end, str, loc, t)

  22.2.5.1.2  time_get virtual            [lib.locale.time.get.virtuals]
       functions

  dateorder do_date_order() const;

  Returns:
    An  enumeration  value  indicating the preferred order of components
    for dates composed of day, month, and year.
    Returns no_order if the date format specified by 'X' contains  other
    variable components (e.g Julian day, week number, week day).

  iter_type do_get_time(iter_type s, iter_type end, ios& str, const locale&,
                        tm* t) const;

  Effects:
    Reads  characters  starting at s until it has extracted those struct
    tm members, and remaining format characters,  used  to  produce  the
    format  specified  by 'X', or until it encounters an error or end of
    sequence.
    Indicates an error  by  calling,  str.setstate(failbit),  which  may
    throw ios_base::failure (_lib.iostate.flags_)).
  Returns:
    An  iterator  pointing  immediately beyond the last character recog­
    nized as part of the time, if no error occurred.

  iter_type do_get_date(iter_type s, iter_type end, ios& str, const locale&,
                        tm* t) const;

  Effects:
    Reads characters starting at s until it has extracted  those  struct
    tm  members,  and  remaining  format characters, used to produce the
    format specified by 'x', or until it encounters an error.
    Indicates failure by calling str.setstate(failbit) (which may  throw
    ios_base::failure (_lib.iostate.flags_)).

  Returns:
    An  iterator  pointing  immediately beyond the last character recog­
    nized as part of the date, if no error occurred.

  iter_type do_get_weekday(iter_type s, iter_type end, ios& str,
                           const locale&, tm* t) const;
  iter_type do_get_monthname(iter_type s, iter_type end, ios& str,
                             const locale&, tm* t) const;

  Effects:
    Reads characters starting at s until it has extracted  the  (perhaps
    abbreviated)  name  of a weekday or month.  If it finds an abbrevia­
    tion that is followed by characters that could match a full name, it
    continues  reading until it matches the full name or fails.  It sets
    the appropriate struct tm member accordingly.
    Indicates failure by calling str.setstate(failbit) (which may  throw
    ios_base::failure (_lib.iostate.flags_)).
  Returns:
    An  iterator  pointing  immediately beyond the last character recog­
    nized as part of a valid name.

  iter_type do_get_year(iter_type s, iter_type end, ios& str,
                        const locale&, tm* t) const;

  Effects:
    Reads characters starting at s until it has extracted an unambiguous
    year  identifier.   It is unspecified whether two-digit year numbers
    are accepted, or what century they are assumed to lie in.  Sets  the
    t->tm_year member accordingly.
    Indicates  failure by calling str.setstate(failbit) (which may throw
    ios_base::failure (_lib.iostate.flags_)).
  Returns:
    An iterator pointing immediately beyond the  last  character  recog­
    nized as part of a valid year identifier.

  22.2.5.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> {
    public:
      explicit time_get_byname(const char*, size_t refs = 0);
    protected:
     ~time_get_byname();  // virtual
      virtual dateorder do_date_order()  const;
      virtual iter_type do_get_time(iter_type s, iter_type end, ios&,
                                    const locale&, tm* t) const;
      virtual iter_type do_get_date(iter_type s, iter_type end, ios&,
                                    const locale&, tm* t) const;
      virtual iter_type do_get_weekday(iter_type s, iter_type end, ios&,
                                       const locale&, tm* t) const;
      virtual iter_type do_get_monthname(iter_type s, iter_type end, ios&,
                                         const locale&, tm* t) const;
      virtual iter_type do_get_year(iter_type s, iter_type end, ios&,
                                    const locale&, tm* t) const;
    };
  }

  22.2.5.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;
      explicit time_put(size_t refs = 0);
        // the following is implemented in terms of other member functions.
      iter_type put(iter_type s, ios& f, const locale& loc, const tm* tmb,
                    const charT* pattern, const charT* pat_end) const;
      iter_type put(iter_type s, ios& f, const locale& loc,
                    const tm* t, char format, char modifier = 0) const;
      static locale::id id;
    protected:
     ~time_put();  // virtual
      virtual iter_type do_put(iter_type s, ios&, const locale&, const tm* t,
                               char format, char modifier) const;
    };
  }

  22.2.5.3.1  time_put members             [lib.locale.time.put.members]

  iter_type put(iter_type s, ios&, const locale&, const tm* t,
                const charT* pattern, const charT* pat_end) const;
  iter_type put(iter_type s, ios&, const locale&, const tm* t,
                char format, char modifier = 0) const;

  Effects:
    The first form interprets the characters between pattern and pat_end

    identically  as  strftime(), (though not treating the null character
    as a terminator), calling do_put() repeatedly as needed.
    The second form calls do_put() once, simply passing along its  argu­
    ments.
  Returns:
    An  iterator pointing immediately after the last character produced.

  22.2.5.3.2  time_put virtual            [lib.locale.time.put.virtuals]
       functions

  iter_type do_put(iter_type s, ios&, const locale&, const tm* t,
                   char format, char modifier) const;

  Effects:
    Formats  the  contents  of the parameter t into characters placed on
    the output sequence s.  Formatting is controlled by  the  parameters
    format  and  modifier,  interpreted identically as the format speci­
    fiers in the  string  argument  to  the  standard  library  function
    strftime().9)
  Returns:
    An iterator pointing immediately after the last character  produced.

  22.2.5.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>
    {
    public:
      explicit time_put_byname(const char*, size_t refs = 0);
    protected:
     ~time_put_byname();  // virtual
      virtual iter_type do_put(iter_type s, ios&, const locale&, const tm* t,
                               char format, char modifier) const;
    };
  }

  22.2.6  The monetary category                  [lib.category.monetary]

1 These templates handle monetary formats.  A template  parameter  indi­
  cates  whether local or international monetary formats are to be used.
  money_get<> and money_put<> use moneypunct<> members to determine  all
  formatting  details.   moneypunct<>  provides basic format information
  for money processing.  The ios& argument is used both for format  con­
  trol,   and   to   report   errors,   as   described   in   subclauses
  _lib.ios::fmtflags_ and _lib.ios::iostate_.

  _________________________
  9)  Interpretation of the modifier argument is implementation-defined,
  but should follow POSIX conventions.

  22.2.6.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 {
    public:
      typedef charT               char_type;
      typedef InputIterator       iter_type;
      typedef basic_string<charT> string;
      typedef basic_ios<charT>    ios;
      explicit money_get(size_t refs = 0);
      iter_type get(iter_type s, iter_type end, ios& f,
                    const locale& loc, double& units) const;
      iter_type get(iter_type s, iter_type end, ios& f,
                    const locale& loc, string& digits) const;
      static locale::id id;
    protected:
     ~money_get();  // virtual
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               double& units) const;
      virtual iter_type do_get(iter_type, iter_type, ios&, const locale&,
                               string& digits) const;
    };
  }

  22.2.6.1.1  money_get members           [lib.locale.money.get.members]

  iter_type get(iter_type s, iter_type end, ios& f,
                const locale& loc, double& quant) const;
  iter_type get(s, iter_type end, ios&f,
                const locale& loc, string& quant) const;

  Returns:
    do_get(s, end, f, loc, quant)

  22.2.6.1.2  money_get virtual          [lib.locale.money.get.virtuals]
       functions

  iter_type do_get(iter_type s, iter_type end, ios& str,
                   const locale& loc, double& units) const;
  iter_type do_get(iter_type s, iter_type end, ios& strfP,
                   const locale& loc, string& digits) const;

  Effects:
    Reads  characters  from s until it has constructed a monetary value,
    as specified in str.flags() and the moneypunct<charT> facet of  loc,
    or  until  it  encounters  an  error or runs out of characters.  The
    result is a pure sequence of digits, representing  a  count  of  the
    smallest unit of currency representable.10) Digit  group  separators
  _________________________
  10) For  example, the sequence $1,056.23 in a common U.S. locale would

    are  optional;  if present, digit grouping is checked after all syn­
    tactic elements have been read.  Where space or none appear  in  the
    format  pattern, except at the end, optional whitespace is consumed.
    Sets the argument units or digits from the sequence of digits found.
    units  is  negated,  or  digits  is  preceded by '-', for a negative
    value.
    Indicates failure by calling str.setstate(failbit) (which may  throw
    ios_base::failure (_lib.iostate.flags_)).
    On error, the units or digits argument is unchanged.
  Returns:
    An  iterator  pointing  immediately beyond the last character recog­
    nized as part of a valid monetary quantity.

  22.2.6.2  Template class money_put              [lib.locale.money.put]
  namespace 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;
      explicit money_put(size_t refs = 0);
      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& digits) const;
      static locale::id id;
      static const bool intl = Intl;
    protected:
     ~money_put();  // virtual
      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;
    };
  }

  22.2.6.2.1  money_put members           [lib.locale.money.put.members]

  iter_type put(iter_type s, ios& f, const locale& loc,
                double quant) const;
  iter_type put(iter_type s, ios& f, const locale& loc,
                const string& quant) const;

  Returns:
    do_put(s, f, loc, quant)

  _________________________
  yield, for units, 105623, or for digits, 105623".

  22.2.6.2.2  money_put virtual          [lib.locale.money.put.virtuals]
       functions

  iter_type do_put(iter_type s, ios& str, const locale& loc,
                   double units) const;
  iter_type do_put(iter_type s, ios& str, const locale& loc,
                   const string& digits) const;

  Effects:
    Writes  characters  to  s,  according to the format specified by the
    moneypunct<charT> facet of loc, and str.flags().  Ignores any  frac­
    tional  part  of  units,  or  any  characters  in  digits beyond the
    (optional) leading '-' and immediately subsequent digits.
  Notes:
    The  currency  symbol  is   generated   only   if   (str.flags()   &
    ios::showbase)  is  true.   If  ((str.flags() & ios::adjustfield) ==
    ios::internal) the fill characters are placed where  none  or  space
    appears in the formatting pattern (_lib.money.get.virtuals_).
  Returns:
    An  iterator pointing immediately after the last character produced.

  22.2.6.3  Template class moneypunct            [lib.locale.moneypunct]
  namespace std {
    class money_base {
    public:
      enum part { none, space, symbol, sign, value };
      struct pattern { char field[4]; };
    };

    template <class charT, bool International = false>
    class moneypunct : public locale::facet, public money_base {
    public:
      typedef charT char_type;
      typedef basic_string<charT> string;
      explicit moneypunct(size_t refs = 0);
      charT        decimal_point() const;
      charT        thousands_sep() const;
      vector<char> grouping()      const;
      string       curr_symbol()   const;
      string       positive_sign() const;
      string       negative_sign() const;
      int          frac_digits()   const;
      pattern      pos_format()    const;
      pattern      neg_format()    const;
      static locale::id id;
      static const bool intl = International;

    protected:
     ~moneypunct();  // virtual
      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;
    };
  }

1 This  provides  money  punctuation,  similar   to   numpunct<>   above
  (_lib.locale.numpunct_).  In particular, the value portion of the for­
  mat is:
    value ::= units [decimal-point [digits]] |
              decimal-point digits
  if frac_digits returns a positive value, or just
    value ::= units
  otherwise.  In these forms, the decimal-point and  thousands-separator
  are  as  determined  below  and the number of digits after the decimal
  point is exactly the value returned by frac_digits.

  22.2.6.3.1  moneypunct members         [lib.locale.moneypunct.members]

      charT        decimal_point() const;
      charT        thousands_sep() const;
      vector<char> grouping()      const;
      string       curr_symbol()   const;
      string       positive_sign() const;
      string       negative_sign() const;
      int          frac_digits()   const;
      pattern      pos_format()    const;
      pattern      neg_format()    const;

1 Each of these functions F returns the result  of  calling  the  corre­
  sponding virtual member function do_F().

  22.2.6.3.2  moneypunct virtual        [lib.locale.moneypunct.virtuals]
       functions

  charT do_decimal_point() const;

  Returns:
    The radix separator to use in case do_frac_digits() is greater  than
    zero.11)
  _________________________
  11) In common U.S. locales this is '.'.

  charT do_thousands_sep() const;

  Returns:
    The  digit  group separator to use in case do_grouping() specifies a
    digit grouping pattern.12)

  vector<char> do_grouping() const;

  Returns:
    A    pattern    defined    identically    as    the    result     of
    numpunct<charT>::do_grouping().13)

  string do_curr_symbol() const;

  Returns:
    A string to use as the currency identifier symbol.14)

  string do_positive_sign() const;

  Returns:
    The string to use to indicate a positive monetary value.15)

  string do_negative_sign() const;

  Returns:
    The string to use to indicate a negative monetary value.
  Notes:
    If  it is a one-character string containing '(', it is paired with a
    matching ')'.

  int do_frac_digits() const;

  Returns:
    The number of digits after the decimal radix separator, if any.16)

  pattern do_pos_format() const;
  pattern do_neg_format() const;
  _________________________
  12) In common U.S. locales this is ','.
  13) This is most commonly the vector "{ 3 }"
  14)  For international instantiations (second template parameter true)
  this is always four characters  long,  usually  three  letters  and  a
  space.
  15) This is usually the empty string.
  16) In common U.S. locales, this is 2.

  Returns:
    A pattern, a four-element array specifying the order in  which  syn­
    tactic elements appear in the monetary format.
  Notes:
    In this array each enumeration value symbol, sign, value, and either
    space or none appears exactly once.  none, if present, is not first;
    space,  if  present, is neither first nor last.  Otherwise, the ele­
    ments may appear in any order.  In international instantiations, the
    result is always { symbol, sign, none, value }.17)

  22.2.6.4  Template class                [lib.locale.moneypunct.byname]
       moneypunct_byname
  namespace std {
    template <class charT, bool Intl = false>
    class moneypunct_byname : public moneypunct<charT, Intl> {
    public:
      explicit moneypunct_byname(const char*, size_t refs = 0);
    protected:
     ~moneypunct_byname();  // virtual
      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;
    };
  }

  22.2.7  The message retrieval category         [lib.category.messages]

1 Class  messages<charT>  implements  retrieval  of strings from message
  catalogs.

  22.2.7.1  Template class messages                [lib.locale.messages]
  namespace std {
    class messages_base {
    public:
      typedef THE_POSIX_CATALOG_IDENTIFIER_TYPE catalog;
    };

    template <class charT>
    class messages : public locale::facet, public messages_base {
    public:
      typedef charT char_type;
      typedef int   catalog;
      typedef basic_string<charT> string;
      explicit messages(size_t refs = 0);
  _________________________
  17)  Note  that the international symbol usually contains a space, it­
  self; for example, "USD ".

      catalog open (const basic_string<char>& fn, const locale&) const;
      string  get  (catalog c, int set, int msgid, const string& dfault) const;
      void    close(catalog c) const;
      static locale::id id;
    protected:
     ~messages();  // virtual
      virtual catalog do_open(const basic_string<char>&, const locale&) const;
      virtual string  do_get(catalog, int set, int msgid,
                             const string& dfault) const;
      virtual void    do_close(catalog) const;
    };
  }

  22.2.7.1.1  messages members             [lib.locale.messages.members]

  catalog open(const basic_string<char>& name, const locale& loc) const;

  Returns:
    do_open(name, loc).

  string get(catalog cat, int set, int msgid, const string& dfault) const;

  Returns:
    do_get(cat, set, msgid, dfault).

  void  close(catalog cat) const;

  Effects:
    Calls do_close(cat).

  22.2.7.1.2  messages virtual            [lib.locale.messages.virtuals]
       functions

  catalog do_open(const basic_string<char>& name,
                  const locale& loc) const;

  Returns:
    A  value that may be passed to get() to retrieve a message, from the
    message catalog identified by the string name according to an imple­
    mentation-defined  mapping.   The  result  can  be  used until it is
    passed to close().
    Returns a value less than 0 if no such catalog can be opened.
  Notes:
    The locale argument loc is used for character  set  code  conversion
    when retrieving messages, if needed.

  string do_get(catalog cat, int set, int msgid,
                const string& dfault) const;

  Requires:
    A catalog cat obtained from open() and not yet closed.
  Returns:
    A  message identified by arguments set, msgid, and dfault, according
    to an implementation-defined mapping.  If no  such  message  can  be
    found, returns dfault.

  void do_close(catalog cat) const;

  Requires:
    A catalog cat obtained from open() and not yet closed.
  Effects:
    Releases unspecified resources associated with  cat.
  Notes:
    The limit on such resources, if any, is implementation-defined.

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

  22.2.8  Program-defined facets                   [lib.facets.examples]

1 A C++ program may define facets to be added to a locale and used iden­
  tically  as the built-in facets.  To create a new facet interface, C++
  programs simply derive from locale::facet a class containing a  static
  member: static locale::id id.

2 [Note:  The locale member function templates verify its type and stor­
  age class.   --end note]

3 This initialization/identification system depends only on the initial­
  ization 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 exception to be thrown.

4 [Example: Here is a program that just calls C functions:

    #include <locale>
    extern "C" void c_function();
    int main()
    {
      using namespace std;
      locale::global(locale(""));  // same as setlocale(LC_ALL, "");
      c_function();
      return 0;
    }
  In other words, C library localization is unaffected.   --end example]

5 [Example: 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();
    }
   --end example]

6 [Example: 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);
    }
  In a European locale, with input 3.456,78, output is 3456.78.    --end
  example]

7 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  prefer­
  ence.

8 [Example: Here is an example of the use of locales in a library inter­
  face.

    // 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);
    ...
  This example illustrates two architectural uses of class locale.

9 The first is as a default  argument  in  Date::asString(),  where  the
  default is the global (presumably user-preferred) locale.

10The  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.getloc();
      struct tm t;
      loc.template use<time_get<char> >().get_date(s, s, 0, loc, &t);
      if (s) d = Date(t.tm_day, t.tm_mon + 1, t.tm_year + 1900);
      s.isfx();
      return s;
    }
   --end example]

11A  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  a C++ program must define is the static member id, which
  identifies your class interface as a new facet.

12[Example: Classifying Japanese characters:

    // file: <jctype>
    #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.template use<ctype>().widen('!');
      if (loc.template use<My::JCType>().is_kanji(c))
        cout << "no it isn't!" << endl;
      return 0;
    }

13The new facet is used exactly like the built-in facets.   --end  exam­
  ple]

14[Example:  Replacing 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;
    }
   --end example]

  22.3  C Library Locales                                [lib.c.locales]

1 Header <clocale> (Table 4):

                    Table 4--Header <clocale> synopsis

            +-------------------------------------------------+
            |   Type                    Name(s)               |
            +-------------------------------------------------+
            |Macros:                                          |
            |             LC_ALL        LC_COLLATE   LC_CTYPE |
            |             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.