home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / locale_facets.h < prev    next >
C/C++ Source or Header  |  2005-01-29  |  157KB  |  4,563 lines

  1. // Locale support -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
  4. // Free Software Foundation, Inc.
  5. //
  6. // This file is part of the GNU ISO C++ Library.  This library is free
  7. // software; you can redistribute it and/or modify it under the
  8. // terms of the GNU General Public License as published by the
  9. // Free Software Foundation; either version 2, or (at your option)
  10. // any later version.
  11.  
  12. // This library is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16.  
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING.  If not, write to the Free
  19. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20. // USA.
  21.  
  22. // As a special exception, you may use this file as part of a free software
  23. // library without restriction.  Specifically, if other files instantiate
  24. // templates or use macros or inline functions from this file, or you compile
  25. // this file and link it with other files to produce an executable, this
  26. // file does not by itself cause the resulting executable to be covered by
  27. // the GNU General Public License.  This exception does not however
  28. // invalidate any other reasons why the executable file might be covered by
  29. // the GNU General Public License.
  30.  
  31. //
  32. // ISO C++ 14882: 22.1  Locales
  33. //
  34.  
  35. /** @file locale_facets.h
  36.  *  This is an internal header file, included by other library headers.
  37.  *  You should not attempt to use it directly.
  38.  */
  39.  
  40. #ifndef _LOCALE_FACETS_H
  41. #define _LOCALE_FACETS_H 1
  42.  
  43. #pragma GCC system_header
  44.  
  45. #include <ctime>    // For struct tm
  46. #include <cwctype>    // For wctype_t
  47. #include <iosfwd>
  48. #include <bits/ios_base.h>  // For ios_base, ios_base::iostate
  49. #include <streambuf>
  50.  
  51. namespace std
  52. {
  53.   // NB: Don't instantiate required wchar_t facets if no wchar_t support.
  54. #ifdef _GLIBCXX_USE_WCHAR_T
  55. # define  _GLIBCXX_NUM_FACETS 28
  56. #else
  57. # define  _GLIBCXX_NUM_FACETS 14
  58. #endif
  59.  
  60.   // Convert string to numeric value of type _Tv and store results.
  61.   // NB: This is specialized for all required types, there is no
  62.   // generic definition.
  63.   template<typename _Tv>
  64.     void
  65.     __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
  66.            const __c_locale& __cloc);
  67.  
  68.   // Explicit specializations for required types.
  69.   template<>
  70.     void
  71.     __convert_to_v(const char*, float&, ios_base::iostate&,
  72.            const __c_locale&);
  73.  
  74.   template<>
  75.     void
  76.     __convert_to_v(const char*, double&, ios_base::iostate&,
  77.            const __c_locale&);
  78.  
  79.   template<>
  80.     void
  81.     __convert_to_v(const char*, long double&, ios_base::iostate&,
  82.            const __c_locale&);
  83.  
  84.   // NB: __pad is a struct, rather than a function, so it can be
  85.   // partially-specialized.
  86.   template<typename _CharT, typename _Traits>
  87.     struct __pad
  88.     {
  89.       static void
  90.       _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
  91.          const _CharT* __olds, const streamsize __newlen,
  92.          const streamsize __oldlen, const bool __num);
  93.     };
  94.  
  95.   // Used by both numeric and monetary facets.
  96.   // Inserts "group separator" characters into an array of characters.
  97.   // It's recursive, one iteration per group.  It moves the characters
  98.   // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
  99.   // only with __glen != 0.
  100.   template<typename _CharT>
  101.     _CharT*
  102.     __add_grouping(_CharT* __s, _CharT __sep,
  103.            const char* __gbeg, size_t __gsize,
  104.            const _CharT* __first, const _CharT* __last);
  105.  
  106.   // This template permits specializing facet output code for
  107.   // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
  108.   // significantly more efficient than incrementing iterators.
  109.   template<typename _CharT>
  110.     inline
  111.     ostreambuf_iterator<_CharT>
  112.     __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
  113.     {
  114.       __s._M_put(__ws, __len);
  115.       return __s;
  116.     }
  117.  
  118.   // This is the unspecialized form of the template.
  119.   template<typename _CharT, typename _OutIter>
  120.     inline
  121.     _OutIter
  122.     __write(_OutIter __s, const _CharT* __ws, int __len)
  123.     {
  124.       for (int __j = 0; __j < __len; __j++, ++__s)
  125.     *__s = __ws[__j];
  126.       return __s;
  127.     }
  128.  
  129.  
  130.   // 22.2.1.1  Template class ctype
  131.   // Include host and configuration specific ctype enums for ctype_base.
  132.   #include <bits/ctype_base.h>
  133.  
  134.   // Common base for ctype<_CharT>.
  135.   /**
  136.    *  @brief  Common base for ctype facet
  137.    *
  138.    *  This template class provides implementations of the public functions
  139.    *  that forward to the protected virtual functions.
  140.    *
  141.    *  This template also provides abtract stubs for the protected virtual
  142.    *  functions.
  143.   */
  144.   template<typename _CharT>
  145.     class __ctype_abstract_base : public locale::facet, public ctype_base
  146.     {
  147.     public:
  148.       // Types:
  149.       /// Typedef for the template parameter
  150.       typedef _CharT char_type;
  151.  
  152.       /**
  153.        *  @brief  Test char_type classification.
  154.        *
  155.        *  This function finds a mask M for @a c and compares it to mask @a m.
  156.        *  It does so by returning the value of ctype<char_type>::do_is().
  157.        *
  158.        *  @param c  The char_type to compare the mask of.
  159.        *  @param m  The mask to compare against.
  160.        *  @return  (M & m) != 0.
  161.       */
  162.       bool
  163.       is(mask __m, char_type __c) const
  164.       { return this->do_is(__m, __c); }
  165.  
  166.       /**
  167.        *  @brief  Return a mask array.
  168.        *
  169.        *  This function finds the mask for each char_type in the range [lo,hi)
  170.        *  and successively writes it to vec.  vec must have as many elements
  171.        *  as the char array.  It does so by returning the value of
  172.        *  ctype<char_type>::do_is().
  173.        *
  174.        *  @param lo  Pointer to start of range.
  175.        *  @param hi  Pointer to end of range.
  176.        *  @param vec  Pointer to an array of mask storage.
  177.        *  @return  @a hi.
  178.       */
  179.       const char_type*
  180.       is(const char_type *__lo, const char_type *__hi, mask *__vec) const
  181.       { return this->do_is(__lo, __hi, __vec); }
  182.  
  183.       /**
  184.        *  @brief  Find char_type matching a mask
  185.        *
  186.        *  This function searches for and returns the first char_type c in
  187.        *  [lo,hi) for which is(m,c) is true.  It does so by returning
  188.        *  ctype<char_type>::do_scan_is().
  189.        *
  190.        *  @param m  The mask to compare against.
  191.        *  @param lo  Pointer to start of range.
  192.        *  @param hi  Pointer to end of range.
  193.        *  @return  Pointer to matching char_type if found, else @a hi.
  194.       */
  195.       const char_type*
  196.       scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
  197.       { return this->do_scan_is(__m, __lo, __hi); }
  198.  
  199.       /**
  200.        *  @brief  Find char_type not matching a mask
  201.        *
  202.        *  This function searches for and returns the first char_type c in
  203.        *  [lo,hi) for which is(m,c) is false.  It does so by returning
  204.        *  ctype<char_type>::do_scan_not().
  205.        *
  206.        *  @param m  The mask to compare against.
  207.        *  @param lo  Pointer to first char in range.
  208.        *  @param hi  Pointer to end of range.
  209.        *  @return  Pointer to non-matching char if found, else @a hi.
  210.       */
  211.       const char_type*
  212.       scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
  213.       { return this->do_scan_not(__m, __lo, __hi); }
  214.  
  215.       /**
  216.        *  @brief  Convert to uppercase.
  217.        *
  218.        *  This function converts the argument to uppercase if possible.
  219.        *  If not possible (for example, '2'), returns the argument.  It does
  220.        *  so by returning ctype<char_type>::do_toupper().
  221.        *
  222.        *  @param c  The char_type to convert.
  223.        *  @return  The uppercase char_type if convertible, else @a c.
  224.       */
  225.       char_type
  226.       toupper(char_type __c) const
  227.       { return this->do_toupper(__c); }
  228.  
  229.       /**
  230.        *  @brief  Convert array to uppercase.
  231.        *
  232.        *  This function converts each char_type in the range [lo,hi) to
  233.        *  uppercase if possible.  Other elements remain untouched.  It does so
  234.        *  by returning ctype<char_type>:: do_toupper(lo, hi).
  235.        *
  236.        *  @param lo  Pointer to start of range.
  237.        *  @param hi  Pointer to end of range.
  238.        *  @return  @a hi.
  239.       */
  240.       const char_type*
  241.       toupper(char_type *__lo, const char_type* __hi) const
  242.       { return this->do_toupper(__lo, __hi); }
  243.  
  244.       /**
  245.        *  @brief  Convert to lowercase.
  246.        *
  247.        *  This function converts the argument to lowercase if possible.  If
  248.        *  not possible (for example, '2'), returns the argument.  It does so
  249.        *  by returning ctype<char_type>::do_tolower(c).
  250.        *
  251.        *  @param c  The char_type to convert.
  252.        *  @return  The lowercase char_type if convertible, else @a c.
  253.       */
  254.       char_type
  255.       tolower(char_type __c) const
  256.       { return this->do_tolower(__c); }
  257.  
  258.       /**
  259.        *  @brief  Convert array to lowercase.
  260.        *
  261.        *  This function converts each char_type in the range [lo,hi) to
  262.        *  lowercase if possible.  Other elements remain untouched.  It does so
  263.        *  by returning ctype<char_type>:: do_tolower(lo, hi).
  264.        *
  265.        *  @param lo  Pointer to start of range.
  266.        *  @param hi  Pointer to end of range.
  267.        *  @return  @a hi.
  268.       */
  269.       const char_type*
  270.       tolower(char_type* __lo, const char_type* __hi) const
  271.       { return this->do_tolower(__lo, __hi); }
  272.  
  273.       /**
  274.        *  @brief  Widen char to char_type
  275.        *
  276.        *  This function converts the char argument to char_type using the
  277.        *  simplest reasonable transformation.  It does so by returning
  278.        *  ctype<char_type>::do_widen(c).
  279.        *
  280.        *  Note: this is not what you want for codepage conversions.  See
  281.        *  codecvt for that.
  282.        *
  283.        *  @param c  The char to convert.
  284.        *  @return  The converted char_type.
  285.       */
  286.       char_type
  287.       widen(char __c) const
  288.       { return this->do_widen(__c); }
  289.  
  290.       /**
  291.        *  @brief  Widen array to char_type
  292.        *
  293.        *  This function converts each char in the input to char_type using the
  294.        *  simplest reasonable transformation.  It does so by returning
  295.        *  ctype<char_type>::do_widen(c).
  296.        *
  297.        *  Note: this is not what you want for codepage conversions.  See
  298.        *  codecvt for that.
  299.        *
  300.        *  @param lo  Pointer to start of range.
  301.        *  @param hi  Pointer to end of range.
  302.        *  @param to  Pointer to the destination array.
  303.        *  @return  @a hi.
  304.       */
  305.       const char*
  306.       widen(const char* __lo, const char* __hi, char_type* __to) const
  307.       { return this->do_widen(__lo, __hi, __to); }
  308.  
  309.       /**
  310.        *  @brief  Narrow char_type to char
  311.        *
  312.        *  This function converts the char_type to char using the simplest
  313.        *  reasonable transformation.  If the conversion fails, dfault is
  314.        *  returned instead.  It does so by returning
  315.        *  ctype<char_type>::do_narrow(c).
  316.        *
  317.        *  Note: this is not what you want for codepage conversions.  See
  318.        *  codecvt for that.
  319.        *
  320.        *  @param c  The char_type to convert.
  321.        *  @param dfault  Char to return if conversion fails.
  322.        *  @return  The converted char.
  323.       */
  324.       char
  325.       narrow(char_type __c, char __dfault) const
  326.       { return this->do_narrow(__c, __dfault); }
  327.  
  328.       /**
  329.        *  @brief  Narrow array to char array
  330.        *
  331.        *  This function converts each char_type in the input to char using the
  332.        *  simplest reasonable transformation and writes the results to the
  333.        *  destination array.  For any char_type in the input that cannot be
  334.        *  converted, @a dfault is used instead.  It does so by returning
  335.        *  ctype<char_type>::do_narrow(lo, hi, dfault, to).
  336.        *
  337.        *  Note: this is not what you want for codepage conversions.  See
  338.        *  codecvt for that.
  339.        *
  340.        *  @param lo  Pointer to start of range.
  341.        *  @param hi  Pointer to end of range.
  342.        *  @param dfault  Char to use if conversion fails.
  343.        *  @param to  Pointer to the destination array.
  344.        *  @return  @a hi.
  345.       */
  346.       const char_type*
  347.       narrow(const char_type* __lo, const char_type* __hi,
  348.           char __dfault, char *__to) const
  349.       { return this->do_narrow(__lo, __hi, __dfault, __to); }
  350.  
  351.     protected:
  352.       explicit
  353.       __ctype_abstract_base(size_t __refs = 0): facet(__refs) { }
  354.  
  355.       virtual
  356.       ~__ctype_abstract_base() { }
  357.  
  358.       /**
  359.        *  @brief  Test char_type classification.
  360.        *
  361.        *  This function finds a mask M for @a c and compares it to mask @a m.
  362.        *
  363.        *  do_is() is a hook for a derived facet to change the behavior of
  364.        *  classifying.  do_is() must always return the same result for the
  365.        *  same input.
  366.        *
  367.        *  @param c  The char_type to find the mask of.
  368.        *  @param m  The mask to compare against.
  369.        *  @return  (M & m) != 0.
  370.       */
  371.       virtual bool
  372.       do_is(mask __m, char_type __c) const = 0;
  373.  
  374.       /**
  375.        *  @brief  Return a mask array.
  376.        *
  377.        *  This function finds the mask for each char_type in the range [lo,hi)
  378.        *  and successively writes it to vec.  vec must have as many elements
  379.        *  as the input.
  380.        *
  381.        *  do_is() is a hook for a derived facet to change the behavior of
  382.        *  classifying.  do_is() must always return the same result for the
  383.        *  same input.
  384.        *
  385.        *  @param lo  Pointer to start of range.
  386.        *  @param hi  Pointer to end of range.
  387.        *  @param vec  Pointer to an array of mask storage.
  388.        *  @return  @a hi.
  389.       */
  390.       virtual const char_type*
  391.       do_is(const char_type* __lo, const char_type* __hi,
  392.         mask* __vec) const = 0;
  393.  
  394.       /**
  395.        *  @brief  Find char_type matching mask
  396.        *
  397.        *  This function searches for and returns the first char_type c in
  398.        *  [lo,hi) for which is(m,c) is true.
  399.        *
  400.        *  do_scan_is() is a hook for a derived facet to change the behavior of
  401.        *  match searching.  do_is() must always return the same result for the
  402.        *  same input.
  403.        *
  404.        *  @param m  The mask to compare against.
  405.        *  @param lo  Pointer to start of range.
  406.        *  @param hi  Pointer to end of range.
  407.        *  @return  Pointer to a matching char_type if found, else @a hi.
  408.       */
  409.       virtual const char_type*
  410.       do_scan_is(mask __m, const char_type* __lo,
  411.          const char_type* __hi) const = 0;
  412.  
  413.       /**
  414.        *  @brief  Find char_type not matching mask
  415.        *
  416.        *  This function searches for and returns a pointer to the first
  417.        *  char_type c of [lo,hi) for which is(m,c) is false.
  418.        *
  419.        *  do_scan_is() is a hook for a derived facet to change the behavior of
  420.        *  match searching.  do_is() must always return the same result for the
  421.        *  same input.
  422.        *
  423.        *  @param m  The mask to compare against.
  424.        *  @param lo  Pointer to start of range.
  425.        *  @param hi  Pointer to end of range.
  426.        *  @return  Pointer to a non-matching char_type if found, else @a hi.
  427.       */
  428.       virtual const char_type*
  429.       do_scan_not(mask __m, const char_type* __lo,
  430.           const char_type* __hi) const = 0;
  431.  
  432.       /**
  433.        *  @brief  Convert to uppercase.
  434.        *
  435.        *  This virtual function converts the char_type argument to uppercase
  436.        *  if possible.  If not possible (for example, '2'), returns the
  437.        *  argument.
  438.        *
  439.        *  do_toupper() is a hook for a derived facet to change the behavior of
  440.        *  uppercasing.  do_toupper() must always return the same result for
  441.        *  the same input.
  442.        *
  443.        *  @param c  The char_type to convert.
  444.        *  @return  The uppercase char_type if convertible, else @a c.
  445.       */
  446.       virtual char_type
  447.       do_toupper(char_type) const = 0;
  448.  
  449.       /**
  450.        *  @brief  Convert array to uppercase.
  451.        *
  452.        *  This virtual function converts each char_type in the range [lo,hi)
  453.        *  to uppercase if possible.  Other elements remain untouched.
  454.        *
  455.        *  do_toupper() is a hook for a derived facet to change the behavior of
  456.        *  uppercasing.  do_toupper() must always return the same result for
  457.        *  the same input.
  458.        *
  459.        *  @param lo  Pointer to start of range.
  460.        *  @param hi  Pointer to end of range.
  461.        *  @return  @a hi.
  462.       */
  463.       virtual const char_type*
  464.       do_toupper(char_type* __lo, const char_type* __hi) const = 0;
  465.  
  466.       /**
  467.        *  @brief  Convert to lowercase.
  468.        *
  469.        *  This virtual function converts the argument to lowercase if
  470.        *  possible.  If not possible (for example, '2'), returns the argument.
  471.        *
  472.        *  do_tolower() is a hook for a derived facet to change the behavior of
  473.        *  lowercasing.  do_tolower() must always return the same result for
  474.        *  the same input.
  475.        *
  476.        *  @param c  The char_type to convert.
  477.        *  @return  The lowercase char_type if convertible, else @a c.
  478.       */
  479.       virtual char_type
  480.       do_tolower(char_type) const = 0;
  481.  
  482.       /**
  483.        *  @brief  Convert array to lowercase.
  484.        *
  485.        *  This virtual function converts each char_type in the range [lo,hi)
  486.        *  to lowercase if possible.  Other elements remain untouched.
  487.        *
  488.        *  do_tolower() is a hook for a derived facet to change the behavior of
  489.        *  lowercasing.  do_tolower() must always return the same result for
  490.        *  the same input.
  491.        *
  492.        *  @param lo  Pointer to start of range.
  493.        *  @param hi  Pointer to end of range.
  494.        *  @return  @a hi.
  495.       */
  496.       virtual const char_type*
  497.       do_tolower(char_type* __lo, const char_type* __hi) const = 0;
  498.  
  499.       /**
  500.        *  @brief  Widen char
  501.        *
  502.        *  This virtual function converts the char to char_type using the
  503.        *  simplest reasonable transformation.
  504.        *
  505.        *  do_widen() is a hook for a derived facet to change the behavior of
  506.        *  widening.  do_widen() must always return the same result for the
  507.        *  same input.
  508.        *
  509.        *  Note: this is not what you want for codepage conversions.  See
  510.        *  codecvt for that.
  511.        *
  512.        *  @param c  The char to convert.
  513.        *  @return  The converted char_type
  514.       */
  515.       virtual char_type
  516.       do_widen(char) const = 0;
  517.  
  518.       /**
  519.        *  @brief  Widen char array
  520.        *
  521.        *  This function converts each char in the input to char_type using the
  522.        *  simplest reasonable transformation.
  523.        *
  524.        *  do_widen() is a hook for a derived facet to change the behavior of
  525.        *  widening.  do_widen() must always return the same result for the
  526.        *  same input.
  527.        *
  528.        *  Note: this is not what you want for codepage conversions.  See
  529.        *  codecvt for that.
  530.        *
  531.        *  @param lo  Pointer to start range.
  532.        *  @param hi  Pointer to end of range.
  533.        *  @param to  Pointer to the destination array.
  534.        *  @return  @a hi.
  535.       */
  536.       virtual const char*
  537.       do_widen(const char* __lo, const char* __hi,
  538.            char_type* __dest) const = 0;
  539.  
  540.       /**
  541.        *  @brief  Narrow char_type to char
  542.        *
  543.        *  This virtual function converts the argument to char using the
  544.        *  simplest reasonable transformation.  If the conversion fails, dfault
  545.        *  is returned instead.
  546.        *
  547.        *  do_narrow() is a hook for a derived facet to change the behavior of
  548.        *  narrowing.  do_narrow() must always return the same result for the
  549.        *  same input.
  550.        *
  551.        *  Note: this is not what you want for codepage conversions.  See
  552.        *  codecvt for that.
  553.        *
  554.        *  @param c  The char_type to convert.
  555.        *  @param dfault  Char to return if conversion fails.
  556.        *  @return  The converted char.
  557.       */
  558.       virtual char
  559.       do_narrow(char_type, char __dfault) const = 0;
  560.  
  561.       /**
  562.        *  @brief  Narrow char_type array to char
  563.        *
  564.        *  This virtual function converts each char_type in the range [lo,hi) to
  565.        *  char using the simplest reasonable transformation and writes the
  566.        *  results to the destination array.  For any element in the input that
  567.        *  cannot be converted, @a dfault is used instead.
  568.        *
  569.        *  do_narrow() is a hook for a derived facet to change the behavior of
  570.        *  narrowing.  do_narrow() must always return the same result for the
  571.        *  same input.
  572.        *
  573.        *  Note: this is not what you want for codepage conversions.  See
  574.        *  codecvt for that.
  575.        *
  576.        *  @param lo  Pointer to start of range.
  577.        *  @param hi  Pointer to end of range.
  578.        *  @param dfault  Char to use if conversion fails.
  579.        *  @param to  Pointer to the destination array.
  580.        *  @return  @a hi.
  581.       */
  582.       virtual const char_type*
  583.       do_narrow(const char_type* __lo, const char_type* __hi,
  584.         char __dfault, char* __dest) const = 0;
  585.     };
  586.  
  587.   // NB: Generic, mostly useless implementation.
  588.   /**
  589.    *  @brief  Template ctype facet
  590.    *
  591.    *  This template class defines classification and conversion functions for
  592.    *  character sets.  It wraps <cctype> functionality.  Ctype gets used by
  593.    *  streams for many I/O operations.
  594.    *
  595.    *  This template provides the protected virtual functions the developer
  596.    *  will have to replace in a derived class or specialization to make a
  597.    *  working facet.  The public functions that access them are defined in
  598.    *  __ctype_abstract_base, to allow for implementation flexibility.  See
  599.    *  ctype<wchar_t> for an example.  The functions are documented in
  600.    *  __ctype_abstract_base.
  601.    *
  602.    *  Note: implementations are provided for all the protected virtual
  603.    *  functions, but will likely not be useful.
  604.   */
  605.   template<typename _CharT>
  606.     class ctype : public __ctype_abstract_base<_CharT>
  607.     {
  608.     public:
  609.       // Types:
  610.       typedef _CharT            char_type;
  611.       typedef typename __ctype_abstract_base<_CharT>::mask mask;
  612.  
  613.       /// The facet id for ctype<char_type>
  614.       static locale::id            id;
  615.  
  616.       explicit
  617.       ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
  618.  
  619.    protected:
  620.       virtual
  621.       ~ctype();
  622.  
  623.       virtual bool
  624.       do_is(mask __m, char_type __c) const;
  625.  
  626.       virtual const char_type*
  627.       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
  628.  
  629.       virtual const char_type*
  630.       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
  631.  
  632.       virtual const char_type*
  633.       do_scan_not(mask __m, const char_type* __lo,
  634.           const char_type* __hi) const;
  635.  
  636.       virtual char_type
  637.       do_toupper(char_type __c) const;
  638.  
  639.       virtual const char_type*
  640.       do_toupper(char_type* __lo, const char_type* __hi) const;
  641.  
  642.       virtual char_type
  643.       do_tolower(char_type __c) const;
  644.  
  645.       virtual const char_type*
  646.       do_tolower(char_type* __lo, const char_type* __hi) const;
  647.  
  648.       virtual char_type
  649.       do_widen(char __c) const;
  650.  
  651.       virtual const char*
  652.       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
  653.  
  654.       virtual char
  655.       do_narrow(char_type, char __dfault) const;
  656.  
  657.       virtual const char_type*
  658.       do_narrow(const char_type* __lo, const char_type* __hi,
  659.         char __dfault, char* __dest) const;
  660.     };
  661.  
  662.   template<typename _CharT>
  663.     locale::id ctype<_CharT>::id;
  664.  
  665.   // 22.2.1.3  ctype<char> specialization.
  666.   /**
  667.    *  @brief  The ctype<char> specialization.
  668.    *
  669.    *  This class defines classification and conversion functions for
  670.    *  the char type.  It gets used by char streams for many I/O
  671.    *  operations.  The char specialization provides a number of
  672.    *  optimizations as well.
  673.   */
  674.   template<>
  675.     class ctype<char> : public locale::facet, public ctype_base
  676.     {
  677.     public:
  678.       // Types:
  679.       /// Typedef for the template parameter char.
  680.       typedef char        char_type;
  681.  
  682.     protected:
  683.       // Data Members:
  684.       __c_locale        _M_c_locale_ctype;
  685.       bool            _M_del;
  686.       __to_type            _M_toupper;
  687.       __to_type            _M_tolower;
  688.       const mask*        _M_table;
  689.       mutable char        _M_widen_ok;
  690.       mutable char        _M_widen[1 + static_cast<unsigned char>(-1)];
  691.       mutable char        _M_narrow[1 + static_cast<unsigned char>(-1)];
  692.       mutable char        _M_narrow_ok;    // 0 uninitialized, 1 init,
  693.                         // 2 non-consecutive
  694.  
  695.     public:
  696.       /// The facet id for ctype<char>
  697.       static locale::id        id;
  698.       /// The size of the mask table.  It is SCHAR_MAX + 1.
  699.       static const size_t      table_size = 1 + static_cast<unsigned char>(-1);
  700.  
  701.       /**
  702.        *  @brief  Constructor performs initialization.
  703.        *
  704.        *  This is the constructor provided by the standard.
  705.        *
  706.        *  @param table If non-zero, table is used as the per-char mask.
  707.        *               Else classic_table() is used.
  708.        *  @param del   If true, passes ownership of table to this facet.
  709.        *  @param refs  Passed to the base facet class.
  710.       */
  711.       explicit
  712.       ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
  713.  
  714.       /**
  715.        *  @brief  Constructor performs static initialization.
  716.        *
  717.        *  This constructor is used to construct the initial C locale facet.
  718.        *
  719.        *  @param cloc  Handle to C locale data.
  720.        *  @param table If non-zero, table is used as the per-char mask.
  721.        *  @param del   If true, passes ownership of table to this facet.
  722.        *  @param refs  Passed to the base facet class.
  723.       */
  724.       explicit
  725.       ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
  726.         size_t __refs = 0);
  727.  
  728.       /**
  729.        *  @brief  Test char classification.
  730.        *
  731.        *  This function compares the mask table[c] to @a m.
  732.        *
  733.        *  @param c  The char to compare the mask of.
  734.        *  @param m  The mask to compare against.
  735.        *  @return  True if m & table[c] is true, false otherwise.
  736.       */
  737.       inline bool
  738.       is(mask __m, char __c) const;
  739.  
  740.       /**
  741.        *  @brief  Return a mask array.
  742.        *
  743.        *  This function finds the mask for each char in the range [lo, hi) and
  744.        *  successively writes it to vec.  vec must have as many elements as
  745.        *  the char array.
  746.        *
  747.        *  @param lo  Pointer to start of range.
  748.        *  @param hi  Pointer to end of range.
  749.        *  @param vec  Pointer to an array of mask storage.
  750.        *  @return  @a hi.
  751.       */
  752.       inline const char*
  753.       is(const char* __lo, const char* __hi, mask* __vec) const;
  754.  
  755.       /**
  756.        *  @brief  Find char matching a mask
  757.        *
  758.        *  This function searches for and returns the first char in [lo,hi) for
  759.        *  which is(m,char) is true.
  760.        *
  761.        *  @param m  The mask to compare against.
  762.        *  @param lo  Pointer to start of range.
  763.        *  @param hi  Pointer to end of range.
  764.        *  @return  Pointer to a matching char if found, else @a hi.
  765.       */
  766.       inline const char*
  767.       scan_is(mask __m, const char* __lo, const char* __hi) const;
  768.  
  769.       /**
  770.        *  @brief  Find char not matching a mask
  771.        *
  772.        *  This function searches for and returns a pointer to the first char
  773.        *  in [lo,hi) for which is(m,char) is false.
  774.        *
  775.        *  @param m  The mask to compare against.
  776.        *  @param lo  Pointer to start of range.
  777.        *  @param hi  Pointer to end of range.
  778.        *  @return  Pointer to a non-matching char if found, else @a hi.
  779.       */
  780.       inline const char*
  781.       scan_not(mask __m, const char* __lo, const char* __hi) const;
  782.  
  783.       /**
  784.        *  @brief  Convert to uppercase.
  785.        *
  786.        *  This function converts the char argument to uppercase if possible.
  787.        *  If not possible (for example, '2'), returns the argument.
  788.        *
  789.        *  toupper() acts as if it returns ctype<char>::do_toupper(c).
  790.        *  do_toupper() must always return the same result for the same input.
  791.        *
  792.        *  @param c  The char to convert.
  793.        *  @return  The uppercase char if convertible, else @a c.
  794.       */
  795.       char_type
  796.       toupper(char_type __c) const
  797.       { return this->do_toupper(__c); }
  798.  
  799.       /**
  800.        *  @brief  Convert array to uppercase.
  801.        *
  802.        *  This function converts each char in the range [lo,hi) to uppercase
  803.        *  if possible.  Other chars remain untouched.
  804.        *
  805.        *  toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi).
  806.        *  do_toupper() must always return the same result for the same input.
  807.        *
  808.        *  @param lo  Pointer to first char in range.
  809.        *  @param hi  Pointer to end of range.
  810.        *  @return  @a hi.
  811.       */
  812.       const char_type*
  813.       toupper(char_type *__lo, const char_type* __hi) const
  814.       { return this->do_toupper(__lo, __hi); }
  815.  
  816.       /**
  817.        *  @brief  Convert to lowercase.
  818.        *
  819.        *  This function converts the char argument to lowercase if possible.
  820.        *  If not possible (for example, '2'), returns the argument.
  821.        *
  822.        *  tolower() acts as if it returns ctype<char>::do_tolower(c).
  823.        *  do_tolower() must always return the same result for the same input.
  824.        *
  825.        *  @param c  The char to convert.
  826.        *  @return  The lowercase char if convertible, else @a c.
  827.       */
  828.       char_type
  829.       tolower(char_type __c) const
  830.       { return this->do_tolower(__c); }
  831.  
  832.       /**
  833.        *  @brief  Convert array to lowercase.
  834.        *
  835.        *  This function converts each char in the range [lo,hi) to lowercase
  836.        *  if possible.  Other chars remain untouched.
  837.        *
  838.        *  tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi).
  839.        *  do_tolower() must always return the same result for the same input.
  840.        *
  841.        *  @param lo  Pointer to first char in range.
  842.        *  @param hi  Pointer to end of range.
  843.        *  @return  @a hi.
  844.       */
  845.       const char_type*
  846.       tolower(char_type* __lo, const char_type* __hi) const
  847.       { return this->do_tolower(__lo, __hi); }
  848.  
  849.       /**
  850.        *  @brief  Widen char
  851.        *
  852.        *  This function converts the char to char_type using the simplest
  853.        *  reasonable transformation.  For an underived ctype<char> facet, the
  854.        *  argument will be returned unchanged.
  855.        *
  856.        *  This function works as if it returns ctype<char>::do_widen(c).
  857.        *  do_widen() must always return the same result for the same input.
  858.        *
  859.        *  Note: this is not what you want for codepage conversions.  See
  860.        *  codecvt for that.
  861.        *
  862.        *  @param c  The char to convert.
  863.        *  @return  The converted character.
  864.       */
  865.       char_type
  866.       widen(char __c) const
  867.       {
  868.     if (_M_widen_ok) return _M_widen[static_cast<unsigned char>(__c)];
  869.     this->_M_widen_init();
  870.     return this->do_widen(__c);
  871.       }
  872.  
  873.       /**
  874.        *  @brief  Widen char array
  875.        *
  876.        *  This function converts each char in the input to char using the
  877.        *  simplest reasonable transformation.  For an underived ctype<char>
  878.        *  facet, the argument will be copied unchanged.
  879.        *
  880.        *  This function works as if it returns ctype<char>::do_widen(c).
  881.        *  do_widen() must always return the same result for the same input.
  882.        *
  883.        *  Note: this is not what you want for codepage conversions.  See
  884.        *  codecvt for that.
  885.        *
  886.        *  @param lo  Pointer to first char in range.
  887.        *  @param hi  Pointer to end of range.
  888.        *  @param to  Pointer to the destination array.
  889.        *  @return  @a hi.
  890.       */
  891.       const char*
  892.       widen(const char* __lo, const char* __hi, char_type* __to) const
  893.       {
  894.     if (_M_widen_ok == 1)
  895.       {
  896.         memcpy(__to, __lo, __hi - __lo);
  897.         return __hi;
  898.       }
  899.     if (!_M_widen_ok) _M_widen_init();
  900.     return this->do_widen(__lo, __hi, __to);
  901.       }
  902.  
  903.       /**
  904.        *  @brief  Narrow char
  905.        *
  906.        *  This function converts the char to char using the simplest
  907.        *  reasonable transformation.  If the conversion fails, dfault is
  908.        *  returned instead.  For an underived ctype<char> facet, @a c
  909.        *  will be returned unchanged.
  910.        *
  911.        *  This function works as if it returns ctype<char>::do_narrow(c).
  912.        *  do_narrow() must always return the same result for the same input.
  913.        *
  914.        *  Note: this is not what you want for codepage conversions.  See
  915.        *  codecvt for that.
  916.        *
  917.        *  @param c  The char to convert.
  918.        *  @param dfault  Char to return if conversion fails.
  919.        *  @return  The converted character.
  920.       */
  921.       char
  922.       narrow(char_type __c, char __dfault) const
  923.       {
  924.     if (_M_narrow[static_cast<unsigned char>(__c)])
  925.       return _M_narrow[static_cast<unsigned char>(__c)];
  926.     const char __t = do_narrow(__c, __dfault);
  927.     if (__t != __dfault) _M_narrow[static_cast<unsigned char>(__c)] = __t;
  928.     return __t;
  929.       }
  930.  
  931.       /**
  932.        *  @brief  Narrow char array
  933.        *
  934.        *  This function converts each char in the input to char using the
  935.        *  simplest reasonable transformation and writes the results to the
  936.        *  destination array.  For any char in the input that cannot be
  937.        *  converted, @a dfault is used instead.  For an underived ctype<char>
  938.        *  facet, the argument will be copied unchanged.
  939.        *
  940.        *  This function works as if it returns ctype<char>::do_narrow(lo, hi,
  941.        *  dfault, to).  do_narrow() must always return the same result for the
  942.        *  same input.
  943.        *
  944.        *  Note: this is not what you want for codepage conversions.  See
  945.        *  codecvt for that.
  946.        *
  947.        *  @param lo  Pointer to start of range.
  948.        *  @param hi  Pointer to end of range.
  949.        *  @param dfault  Char to use if conversion fails.
  950.        *  @param to  Pointer to the destination array.
  951.        *  @return  @a hi.
  952.       */
  953.       const char_type*
  954.       narrow(const char_type* __lo, const char_type* __hi,
  955.          char __dfault, char *__to) const
  956.       {
  957.     if (__builtin_expect(_M_narrow_ok == 1,true))
  958.       {
  959.         memcpy(__to, __lo, __hi - __lo);
  960.         return __hi;
  961.       }
  962.     if (!_M_narrow_ok)
  963.       _M_narrow_init();
  964.     return this->do_narrow(__lo, __hi, __dfault, __to);
  965.       }
  966.  
  967.     protected:
  968.       /// Returns a pointer to the mask table provided to the constructor, or
  969.       /// the default from classic_table() if none was provided.
  970.       const mask*
  971.       table() const throw()
  972.       { return _M_table; }
  973.  
  974.       /// Returns a pointer to the C locale mask table.
  975.       static const mask*
  976.       classic_table() throw();
  977.  
  978.       /**
  979.        *  @brief  Destructor.
  980.        *
  981.        *  This function deletes table() if @a del was true in the
  982.        *  constructor.
  983.       */
  984.       virtual
  985.       ~ctype();
  986.  
  987.       /**
  988.        *  @brief  Convert to uppercase.
  989.        *
  990.        *  This virtual function converts the char argument to uppercase if
  991.        *  possible.  If not possible (for example, '2'), returns the argument.
  992.        *
  993.        *  do_toupper() is a hook for a derived facet to change the behavior of
  994.        *  uppercasing.  do_toupper() must always return the same result for
  995.        *  the same input.
  996.        *
  997.        *  @param c  The char to convert.
  998.        *  @return  The uppercase char if convertible, else @a c.
  999.       */
  1000.       virtual char_type
  1001.       do_toupper(char_type) const;
  1002.  
  1003.       /**
  1004.        *  @brief  Convert array to uppercase.
  1005.        *
  1006.        *  This virtual function converts each char in the range [lo,hi) to
  1007.        *  uppercase if possible.  Other chars remain untouched.
  1008.        *
  1009.        *  do_toupper() is a hook for a derived facet to change the behavior of
  1010.        *  uppercasing.  do_toupper() must always return the same result for
  1011.        *  the same input.
  1012.        *
  1013.        *  @param lo  Pointer to start of range.
  1014.        *  @param hi  Pointer to end of range.
  1015.        *  @return  @a hi.
  1016.       */
  1017.       virtual const char_type*
  1018.       do_toupper(char_type* __lo, const char_type* __hi) const;
  1019.  
  1020.       /**
  1021.        *  @brief  Convert to lowercase.
  1022.        *
  1023.        *  This virtual function converts the char argument to lowercase if
  1024.        *  possible.  If not possible (for example, '2'), returns the argument.
  1025.        *
  1026.        *  do_tolower() is a hook for a derived facet to change the behavior of
  1027.        *  lowercasing.  do_tolower() must always return the same result for
  1028.        *  the same input.
  1029.        *
  1030.        *  @param c  The char to convert.
  1031.        *  @return  The lowercase char if convertible, else @a c.
  1032.       */
  1033.       virtual char_type
  1034.       do_tolower(char_type) const;
  1035.  
  1036.       /**
  1037.        *  @brief  Convert array to lowercase.
  1038.        *
  1039.        *  This virtual function converts each char in the range [lo,hi) to
  1040.        *  lowercase if possible.  Other chars remain untouched.
  1041.        *
  1042.        *  do_tolower() is a hook for a derived facet to change the behavior of
  1043.        *  lowercasing.  do_tolower() must always return the same result for
  1044.        *  the same input.
  1045.        *
  1046.        *  @param lo  Pointer to first char in range.
  1047.        *  @param hi  Pointer to end of range.
  1048.        *  @return  @a hi.
  1049.       */
  1050.       virtual const char_type*
  1051.       do_tolower(char_type* __lo, const char_type* __hi) const;
  1052.  
  1053.       /**
  1054.        *  @brief  Widen char
  1055.        *
  1056.        *  This virtual function converts the char to char using the simplest
  1057.        *  reasonable transformation.  For an underived ctype<char> facet, the
  1058.        *  argument will be returned unchanged.
  1059.        *
  1060.        *  do_widen() is a hook for a derived facet to change the behavior of
  1061.        *  widening.  do_widen() must always return the same result for the
  1062.        *  same input.
  1063.        *
  1064.        *  Note: this is not what you want for codepage conversions.  See
  1065.        *  codecvt for that.
  1066.        *
  1067.        *  @param c  The char to convert.
  1068.        *  @return  The converted character.
  1069.       */
  1070.       virtual char_type
  1071.       do_widen(char __c) const
  1072.       { return __c; }
  1073.  
  1074.       /**
  1075.        *  @brief  Widen char array
  1076.        *
  1077.        *  This function converts each char in the range [lo,hi) to char using
  1078.        *  the simplest reasonable transformation.  For an underived
  1079.        *  ctype<char> facet, the argument will be copied unchanged.
  1080.        *
  1081.        *  do_widen() is a hook for a derived facet to change the behavior of
  1082.        *  widening.  do_widen() must always return the same result for the
  1083.        *  same input.
  1084.        *
  1085.        *  Note: this is not what you want for codepage conversions.  See
  1086.        *  codecvt for that.
  1087.        *
  1088.        *  @param lo  Pointer to start of range.
  1089.        *  @param hi  Pointer to end of range.
  1090.        *  @param to  Pointer to the destination array.
  1091.        *  @return  @a hi.
  1092.       */
  1093.       virtual const char*
  1094.       do_widen(const char* __lo, const char* __hi, char_type* __dest) const
  1095.       {
  1096.     memcpy(__dest, __lo, __hi - __lo);
  1097.     return __hi;
  1098.       }
  1099.  
  1100.       /**
  1101.        *  @brief  Narrow char
  1102.        *
  1103.        *  This virtual function converts the char to char using the simplest
  1104.        *  reasonable transformation.  If the conversion fails, dfault is
  1105.        *  returned instead.  For an underived ctype<char> facet, @a c will be
  1106.        *  returned unchanged.
  1107.        *
  1108.        *  do_narrow() is a hook for a derived facet to change the behavior of
  1109.        *  narrowing.  do_narrow() must always return the same result for the
  1110.        *  same input.
  1111.        *
  1112.        *  Note: this is not what you want for codepage conversions.  See
  1113.        *  codecvt for that.
  1114.        *
  1115.        *  @param c  The char to convert.
  1116.        *  @param dfault  Char to return if conversion fails.
  1117.        *  @return  The converted char.
  1118.       */
  1119.       virtual char
  1120.       do_narrow(char_type __c, char) const
  1121.       { return __c; }
  1122.  
  1123.       /**
  1124.        *  @brief  Narrow char array to char array
  1125.        *
  1126.        *  This virtual function converts each char in the range [lo,hi) to
  1127.        *  char using the simplest reasonable transformation and writes the
  1128.        *  results to the destination array.  For any char in the input that
  1129.        *  cannot be converted, @a dfault is used instead.  For an underived
  1130.        *  ctype<char> facet, the argument will be copied unchanged.
  1131.        *
  1132.        *  do_narrow() is a hook for a derived facet to change the behavior of
  1133.        *  narrowing.  do_narrow() must always return the same result for the
  1134.        *  same input.
  1135.        *
  1136.        *  Note: this is not what you want for codepage conversions.  See
  1137.        *  codecvt for that.
  1138.        *
  1139.        *  @param lo  Pointer to start of range.
  1140.        *  @param hi  Pointer to end of range.
  1141.        *  @param dfault  Char to use if conversion fails.
  1142.        *  @param to  Pointer to the destination array.
  1143.        *  @return  @a hi.
  1144.       */
  1145.       virtual const char_type*
  1146.       do_narrow(const char_type* __lo, const char_type* __hi,
  1147.         char, char* __dest) const
  1148.       {
  1149.     memcpy(__dest, __lo, __hi - __lo);
  1150.     return __hi;
  1151.       }
  1152.  
  1153.     private:
  1154.  
  1155.       void _M_widen_init() const
  1156.       {
  1157.     char __tmp[sizeof(_M_widen)];
  1158.     for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
  1159.       __tmp[__i] = __i;
  1160.     do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
  1161.  
  1162.     _M_widen_ok = 1;
  1163.     // Set _M_widen_ok to 2 if memcpy can't be used.
  1164.     for (size_t __j = 0; __j < sizeof(_M_widen); ++__j)
  1165.       if (__tmp[__j] != _M_widen[__j])
  1166.         {
  1167.           _M_widen_ok = 2;
  1168.           break;
  1169.         }
  1170.       }
  1171.  
  1172.       // Fill in the narrowing cache and flag whether all values are
  1173.       // valid or not.  _M_narrow_ok is set to 1 if the whole table is
  1174.       // narrowed, 2 if only some values could be narrowed.
  1175.       void _M_narrow_init() const
  1176.       {
  1177.     char __tmp[sizeof(_M_narrow)];
  1178.     for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
  1179.       __tmp[__i] = __i;
  1180.     do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
  1181.  
  1182.     // Check if any default values were created.  Do this by
  1183.     // renarrowing with a different default value and comparing.
  1184.     bool __consecutive = true;
  1185.     for (size_t __j = 0; __j < sizeof(_M_narrow); ++__j)
  1186.       if (!_M_narrow[__j])
  1187.         {
  1188.           char __c;
  1189.           do_narrow(__tmp + __j, __tmp + __j + 1, 1, &__c);
  1190.           if (__c == 1)
  1191.         {
  1192.           __consecutive = false;
  1193.           break;
  1194.         }
  1195.         }
  1196.     _M_narrow_ok = __consecutive ? 1 : 2;
  1197.       }
  1198.     };
  1199.  
  1200.   template<>
  1201.     const ctype<char>&
  1202.     use_facet<ctype<char> >(const locale& __loc);
  1203.  
  1204. #ifdef _GLIBCXX_USE_WCHAR_T
  1205.   // 22.2.1.3  ctype<wchar_t> specialization
  1206.   /**
  1207.    *  @brief  The ctype<wchar_t> specialization.
  1208.    *
  1209.    *  This class defines classification and conversion functions for the
  1210.    *  wchar_t type.  It gets used by wchar_t streams for many I/O operations.
  1211.    *  The wchar_t specialization provides a number of optimizations as well.
  1212.    *
  1213.    *  ctype<wchar_t> inherits its public methods from
  1214.    *  __ctype_abstract_base<wchar_t>.
  1215.   */
  1216.   template<>
  1217.     class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
  1218.     {
  1219.     public:
  1220.       // Types:
  1221.       /// Typedef for the template parameter wchar_t.
  1222.       typedef wchar_t        char_type;
  1223.       typedef wctype_t        __wmask_type;
  1224.  
  1225.     protected:
  1226.       __c_locale        _M_c_locale_ctype;
  1227.  
  1228.       // Pre-computed narrowed and widened chars.
  1229.       bool                      _M_narrow_ok;
  1230.       char                      _M_narrow[128];
  1231.       wint_t                    _M_widen[1 + static_cast<unsigned char>(-1)];
  1232.  
  1233.       // Pre-computed elements for do_is.
  1234.       mask                      _M_bit[16];
  1235.       __wmask_type              _M_wmask[16];
  1236.  
  1237.     public:
  1238.       // Data Members:
  1239.       /// The facet id for ctype<wchar_t>
  1240.       static locale::id        id;
  1241.  
  1242.       /**
  1243.        *  @brief  Constructor performs initialization.
  1244.        *
  1245.        *  This is the constructor provided by the standard.
  1246.        *
  1247.        *  @param refs  Passed to the base facet class.
  1248.       */
  1249.       explicit
  1250.       ctype(size_t __refs = 0);
  1251.  
  1252.       /**
  1253.        *  @brief  Constructor performs static initialization.
  1254.        *
  1255.        *  This constructor is used to construct the initial C locale facet.
  1256.        *
  1257.        *  @param cloc  Handle to C locale data.
  1258.        *  @param refs  Passed to the base facet class.
  1259.       */
  1260.       explicit
  1261.       ctype(__c_locale __cloc, size_t __refs = 0);
  1262.  
  1263.     protected:
  1264.       __wmask_type
  1265.       _M_convert_to_wmask(const mask __m) const;
  1266.  
  1267.       /// Destructor
  1268.       virtual
  1269.       ~ctype();
  1270.  
  1271.       /**
  1272.        *  @brief  Test wchar_t classification.
  1273.        *
  1274.        *  This function finds a mask M for @a c and compares it to mask @a m.
  1275.        *
  1276.        *  do_is() is a hook for a derived facet to change the behavior of
  1277.        *  classifying.  do_is() must always return the same result for the
  1278.        *  same input.
  1279.        *
  1280.        *  @param c  The wchar_t to find the mask of.
  1281.        *  @param m  The mask to compare against.
  1282.        *  @return  (M & m) != 0.
  1283.       */
  1284.       virtual bool
  1285.       do_is(mask __m, char_type __c) const;
  1286.  
  1287.       /**
  1288.        *  @brief  Return a mask array.
  1289.        *
  1290.        *  This function finds the mask for each wchar_t in the range [lo,hi)
  1291.        *  and successively writes it to vec.  vec must have as many elements
  1292.        *  as the input.
  1293.        *
  1294.        *  do_is() is a hook for a derived facet to change the behavior of
  1295.        *  classifying.  do_is() must always return the same result for the
  1296.        *  same input.
  1297.        *
  1298.        *  @param lo  Pointer to start of range.
  1299.        *  @param hi  Pointer to end of range.
  1300.        *  @param vec  Pointer to an array of mask storage.
  1301.        *  @return  @a hi.
  1302.       */
  1303.       virtual const char_type*
  1304.       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
  1305.  
  1306.       /**
  1307.        *  @brief  Find wchar_t matching mask
  1308.        *
  1309.        *  This function searches for and returns the first wchar_t c in
  1310.        *  [lo,hi) for which is(m,c) is true.
  1311.        *
  1312.        *  do_scan_is() is a hook for a derived facet to change the behavior of
  1313.        *  match searching.  do_is() must always return the same result for the
  1314.        *  same input.
  1315.        *
  1316.        *  @param m  The mask to compare against.
  1317.        *  @param lo  Pointer to start of range.
  1318.        *  @param hi  Pointer to end of range.
  1319.        *  @return  Pointer to a matching wchar_t if found, else @a hi.
  1320.       */
  1321.       virtual const char_type*
  1322.       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
  1323.  
  1324.       /**
  1325.        *  @brief  Find wchar_t not matching mask
  1326.        *
  1327.        *  This function searches for and returns a pointer to the first
  1328.        *  wchar_t c of [lo,hi) for which is(m,c) is false.
  1329.        *
  1330.        *  do_scan_is() is a hook for a derived facet to change the behavior of
  1331.        *  match searching.  do_is() must always return the same result for the
  1332.        *  same input.
  1333.        *
  1334.        *  @param m  The mask to compare against.
  1335.        *  @param lo  Pointer to start of range.
  1336.        *  @param hi  Pointer to end of range.
  1337.        *  @return  Pointer to a non-matching wchar_t if found, else @a hi.
  1338.       */
  1339.       virtual const char_type*
  1340.       do_scan_not(mask __m, const char_type* __lo,
  1341.           const char_type* __hi) const;
  1342.  
  1343.       /**
  1344.        *  @brief  Convert to uppercase.
  1345.        *
  1346.        *  This virtual function converts the wchar_t argument to uppercase if
  1347.        *  possible.  If not possible (for example, '2'), returns the argument.
  1348.        *
  1349.        *  do_toupper() is a hook for a derived facet to change the behavior of
  1350.        *  uppercasing.  do_toupper() must always return the same result for
  1351.        *  the same input.
  1352.        *
  1353.        *  @param c  The wchar_t to convert.
  1354.        *  @return  The uppercase wchar_t if convertible, else @a c.
  1355.       */
  1356.       virtual char_type
  1357.       do_toupper(char_type) const;
  1358.  
  1359.       /**
  1360.        *  @brief  Convert array to uppercase.
  1361.        *
  1362.        *  This virtual function converts each wchar_t in the range [lo,hi) to
  1363.        *  uppercase if possible.  Other elements remain untouched.
  1364.        *
  1365.        *  do_toupper() is a hook for a derived facet to change the behavior of
  1366.        *  uppercasing.  do_toupper() must always return the same result for
  1367.        *  the same input.
  1368.        *
  1369.        *  @param lo  Pointer to start of range.
  1370.        *  @param hi  Pointer to end of range.
  1371.        *  @return  @a hi.
  1372.       */
  1373.       virtual const char_type*
  1374.       do_toupper(char_type* __lo, const char_type* __hi) const;
  1375.  
  1376.       /**
  1377.        *  @brief  Convert to lowercase.
  1378.        *
  1379.        *  This virtual function converts the argument to lowercase if
  1380.        *  possible.  If not possible (for example, '2'), returns the argument.
  1381.        *
  1382.        *  do_tolower() is a hook for a derived facet to change the behavior of
  1383.        *  lowercasing.  do_tolower() must always return the same result for
  1384.        *  the same input.
  1385.        *
  1386.        *  @param c  The wchar_t to convert.
  1387.        *  @return  The lowercase wchar_t if convertible, else @a c.
  1388.       */
  1389.       virtual char_type
  1390.       do_tolower(char_type) const;
  1391.  
  1392.       /**
  1393.        *  @brief  Convert array to lowercase.
  1394.        *
  1395.        *  This virtual function converts each wchar_t in the range [lo,hi) to
  1396.        *  lowercase if possible.  Other elements remain untouched.
  1397.        *
  1398.        *  do_tolower() is a hook for a derived facet to change the behavior of
  1399.        *  lowercasing.  do_tolower() must always return the same result for
  1400.        *  the same input.
  1401.        *
  1402.        *  @param lo  Pointer to start of range.
  1403.        *  @param hi  Pointer to end of range.
  1404.        *  @return  @a hi.
  1405.       */
  1406.       virtual const char_type*
  1407.       do_tolower(char_type* __lo, const char_type* __hi) const;
  1408.  
  1409.       /**
  1410.        *  @brief  Widen char to wchar_t
  1411.        *
  1412.        *  This virtual function converts the char to wchar_t using the
  1413.        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
  1414.        *  facet, the argument will be cast to wchar_t.
  1415.        *
  1416.        *  do_widen() is a hook for a derived facet to change the behavior of
  1417.        *  widening.  do_widen() must always return the same result for the
  1418.        *  same input.
  1419.        *
  1420.        *  Note: this is not what you want for codepage conversions.  See
  1421.        *  codecvt for that.
  1422.        *
  1423.        *  @param c  The char to convert.
  1424.        *  @return  The converted wchar_t.
  1425.       */
  1426.       virtual char_type
  1427.       do_widen(char) const;
  1428.  
  1429.       /**
  1430.        *  @brief  Widen char array to wchar_t array
  1431.        *
  1432.        *  This function converts each char in the input to wchar_t using the
  1433.        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
  1434.        *  facet, the argument will be copied, casting each element to wchar_t.
  1435.        *
  1436.        *  do_widen() is a hook for a derived facet to change the behavior of
  1437.        *  widening.  do_widen() must always return the same result for the
  1438.        *  same input.
  1439.        *
  1440.        *  Note: this is not what you want for codepage conversions.  See
  1441.        *  codecvt for that.
  1442.        *
  1443.        *  @param lo  Pointer to start range.
  1444.        *  @param hi  Pointer to end of range.
  1445.        *  @param to  Pointer to the destination array.
  1446.        *  @return  @a hi.
  1447.       */
  1448.       virtual const char*
  1449.       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
  1450.  
  1451.       /**
  1452.        *  @brief  Narrow wchar_t to char
  1453.        *
  1454.        *  This virtual function converts the argument to char using
  1455.        *  the simplest reasonable transformation.  If the conversion
  1456.        *  fails, dfault is returned instead.  For an underived
  1457.        *  ctype<wchar_t> facet, @a c will be cast to char and
  1458.        *  returned.
  1459.        *
  1460.        *  do_narrow() is a hook for a derived facet to change the
  1461.        *  behavior of narrowing.  do_narrow() must always return the
  1462.        *  same result for the same input.
  1463.        *
  1464.        *  Note: this is not what you want for codepage conversions.  See
  1465.        *  codecvt for that.
  1466.        *
  1467.        *  @param c  The wchar_t to convert.
  1468.        *  @param dfault  Char to return if conversion fails.
  1469.        *  @return  The converted char.
  1470.       */
  1471.       virtual char
  1472.       do_narrow(char_type, char __dfault) const;
  1473.  
  1474.       /**
  1475.        *  @brief  Narrow wchar_t array to char array
  1476.        *
  1477.        *  This virtual function converts each wchar_t in the range [lo,hi) to
  1478.        *  char using the simplest reasonable transformation and writes the
  1479.        *  results to the destination array.  For any wchar_t in the input that
  1480.        *  cannot be converted, @a dfault is used instead.  For an underived
  1481.        *  ctype<wchar_t> facet, the argument will be copied, casting each
  1482.        *  element to char.
  1483.        *
  1484.        *  do_narrow() is a hook for a derived facet to change the behavior of
  1485.        *  narrowing.  do_narrow() must always return the same result for the
  1486.        *  same input.
  1487.        *
  1488.        *  Note: this is not what you want for codepage conversions.  See
  1489.        *  codecvt for that.
  1490.        *
  1491.        *  @param lo  Pointer to start of range.
  1492.        *  @param hi  Pointer to end of range.
  1493.        *  @param dfault  Char to use if conversion fails.
  1494.        *  @param to  Pointer to the destination array.
  1495.        *  @return  @a hi.
  1496.       */
  1497.       virtual const char_type*
  1498.       do_narrow(const char_type* __lo, const char_type* __hi,
  1499.         char __dfault, char* __dest) const;
  1500.  
  1501.       // For use at construction time only.
  1502.       void
  1503.       _M_initialize_ctype();
  1504.     };
  1505.  
  1506.   template<>
  1507.     const ctype<wchar_t>&
  1508.     use_facet<ctype<wchar_t> >(const locale& __loc);
  1509. #endif //_GLIBCXX_USE_WCHAR_T
  1510.  
  1511.   // Include host and configuration specific ctype inlines.
  1512.   #include <bits/ctype_inline.h>
  1513.  
  1514.   // 22.2.1.2  Template class ctype_byname
  1515.   template<typename _CharT>
  1516.     class ctype_byname : public ctype<_CharT>
  1517.     {
  1518.     public:
  1519.       typedef _CharT        char_type;
  1520.  
  1521.       explicit
  1522.       ctype_byname(const char* __s, size_t __refs = 0);
  1523.  
  1524.     protected:
  1525.       virtual
  1526.       ~ctype_byname() { };
  1527.     };
  1528.  
  1529.   // 22.2.1.4  Class ctype_byname specializations.
  1530.   template<>
  1531.     ctype_byname<char>::ctype_byname(const char*, size_t refs);
  1532.  
  1533.   template<>
  1534.     ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
  1535.  
  1536.   // 22.2.1.5  Template class codecvt
  1537.   #include <bits/codecvt.h>
  1538.  
  1539.   // 22.2.2  The numeric category.
  1540.   class __num_base
  1541.   {
  1542.   public:
  1543.     // NB: Code depends on the order of _S_atoms_out elements.
  1544.     // Below are the indices into _S_atoms_out.
  1545.     enum
  1546.       {
  1547.         _S_ominus,
  1548.         _S_oplus,
  1549.         _S_ox,
  1550.         _S_oX,
  1551.         _S_odigits,
  1552.         _S_odigits_end = _S_odigits + 16,
  1553.         _S_oudigits = _S_odigits_end,
  1554.         _S_oudigits_end = _S_oudigits + 16,
  1555.         _S_oe = _S_odigits + 14,  // For scientific notation, 'e'
  1556.         _S_oE = _S_oudigits + 14, // For scientific notation, 'E'
  1557.     _S_oend = _S_oudigits_end
  1558.       };
  1559.  
  1560.     // A list of valid numeric literals for output.  This array
  1561.     // contains chars that will be passed through the current locale's
  1562.     // ctype<_CharT>.widen() and then used to render numbers.
  1563.     // For the standard "C" locale, this is
  1564.     // "-+xX0123456789abcdef0123456789ABCDEF".
  1565.     static const char* _S_atoms_out;
  1566.  
  1567.     // String literal of acceptable (narrow) input, for num_get.
  1568.     // "-+xX0123456789abcdefABCDEF"
  1569.     static const char* _S_atoms_in;
  1570.  
  1571.     enum
  1572.     {
  1573.       _S_iminus,
  1574.       _S_iplus,
  1575.       _S_ix,
  1576.       _S_iX,
  1577.       _S_izero,
  1578.       _S_ie = _S_izero + 14,
  1579.       _S_iE = _S_izero + 20,
  1580.       _S_iend = 26
  1581.     };
  1582.  
  1583.     // num_put
  1584.     // Construct and return valid scanf format for floating point types.
  1585.     static void
  1586.     _S_format_float(const ios_base& __io, char* __fptr, char __mod);
  1587.   };
  1588.  
  1589.   template<typename _CharT>
  1590.     struct __numpunct_cache : public locale::facet
  1591.     {
  1592.       const char*            _M_grouping;
  1593.       size_t                            _M_grouping_size;
  1594.       bool                _M_use_grouping;
  1595.       const _CharT*            _M_truename;
  1596.       size_t                            _M_truename_size;
  1597.       const _CharT*            _M_falsename;
  1598.       size_t                            _M_falsename_size;
  1599.       _CharT                _M_decimal_point;
  1600.       _CharT                _M_thousands_sep;
  1601.  
  1602.       // A list of valid numeric literals for output: in the standard
  1603.       // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
  1604.       // This array contains the chars after having been passed
  1605.       // through the current locale's ctype<_CharT>.widen().
  1606.       _CharT                _M_atoms_out[__num_base::_S_oend];
  1607.  
  1608.       // A list of valid numeric literals for input: in the standard
  1609.       // "C" locale, this is "-+xX0123456789abcdefABCDEF"
  1610.       // This array contains the chars after having been passed
  1611.       // through the current locale's ctype<_CharT>.widen().
  1612.       _CharT                _M_atoms_in[__num_base::_S_iend];
  1613.  
  1614.       bool                _M_allocated;
  1615.  
  1616.       __numpunct_cache(size_t __refs = 0) : facet(__refs),
  1617.       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
  1618.       _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL),
  1619.       _M_falsename_size(0), _M_decimal_point(_CharT()),
  1620.       _M_thousands_sep(_CharT()), _M_allocated(false)
  1621.       { }
  1622.  
  1623.       ~__numpunct_cache();
  1624.  
  1625.       void
  1626.       _M_cache(const locale& __loc);
  1627.  
  1628.     private:
  1629.       __numpunct_cache&
  1630.       operator=(const __numpunct_cache&);
  1631.       
  1632.       explicit
  1633.       __numpunct_cache(const __numpunct_cache&);
  1634.     };
  1635.  
  1636.   template<typename _CharT>
  1637.     __numpunct_cache<_CharT>::~__numpunct_cache()
  1638.     {
  1639.       if (_M_allocated)
  1640.     {
  1641.       delete [] _M_grouping;
  1642.       delete [] _M_truename;
  1643.       delete [] _M_falsename;
  1644.     }
  1645.     }
  1646.  
  1647.   /**
  1648.    *  @brief  Numpunct facet.
  1649.    *
  1650.    *  This facet stores several pieces of information related to printing and
  1651.    *  scanning numbers, such as the decimal point character.  It takes a
  1652.    *  template parameter specifying the char type.  The numpunct facet is
  1653.    *  used by streams for many I/O operations involving numbers.
  1654.    *
  1655.    *  The numpunct template uses protected virtual functions to provide the
  1656.    *  actual results.  The public accessors forward the call to the virtual
  1657.    *  functions.  These virtual functions are hooks for developers to
  1658.    *  implement the behavior they require from a numpunct facet.
  1659.   */
  1660.   template<typename _CharT>
  1661.     class numpunct : public locale::facet
  1662.     {
  1663.     public:
  1664.       // Types:
  1665.       //@{
  1666.       /// Public typedefs
  1667.       typedef _CharT            char_type;
  1668.       typedef basic_string<_CharT>    string_type;
  1669.       //@}
  1670.       typedef __numpunct_cache<_CharT>  __cache_type;
  1671.  
  1672.     protected:
  1673.       __cache_type*            _M_data;
  1674.  
  1675.     public:
  1676.       /// Numpunct facet id.
  1677.       static locale::id            id;
  1678.  
  1679.       /**
  1680.        *  @brief  Numpunct constructor.
  1681.        *
  1682.        *  @param  refs  Refcount to pass to the base class.
  1683.        */
  1684.       explicit
  1685.       numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
  1686.       { _M_initialize_numpunct(); }
  1687.  
  1688.       /**
  1689.        *  @brief  Internal constructor.  Not for general use.
  1690.        *
  1691.        *  This is a constructor for use by the library itself to set up the
  1692.        *  predefined locale facets.
  1693.        *
  1694.        *  @param  cache  __numpunct_cache object.
  1695.        *  @param  refs  Refcount to pass to the base class.
  1696.        */
  1697.       explicit
  1698.       numpunct(__cache_type* __cache, size_t __refs = 0)
  1699.       : facet(__refs), _M_data(__cache)
  1700.       { _M_initialize_numpunct(); }
  1701.  
  1702.       /**
  1703.        *  @brief  Internal constructor.  Not for general use.
  1704.        *
  1705.        *  This is a constructor for use by the library itself to set up new
  1706.        *  locales.
  1707.        *
  1708.        *  @param  cloc  The "C" locale.
  1709.        *  @param  refs  Refcount to pass to the base class.
  1710.        */
  1711.       explicit
  1712.       numpunct(__c_locale __cloc, size_t __refs = 0)
  1713.       : facet(__refs), _M_data(NULL)
  1714.       { _M_initialize_numpunct(__cloc); }
  1715.  
  1716.       /**
  1717.        *  @brief  Return decimal point character.
  1718.        *
  1719.        *  This function returns a char_type to use as a decimal point.  It
  1720.        *  does so by returning returning
  1721.        *  numpunct<char_type>::do_decimal_point().
  1722.        *
  1723.        *  @return  @a char_type representing a decimal point.
  1724.       */
  1725.       char_type
  1726.       decimal_point() const
  1727.       { return this->do_decimal_point(); }
  1728.  
  1729.       /**
  1730.        *  @brief  Return thousands separator character.
  1731.        *
  1732.        *  This function returns a char_type to use as a thousands
  1733.        *  separator.  It does so by returning returning
  1734.        *  numpunct<char_type>::do_thousands_sep().
  1735.        *
  1736.        *  @return  char_type representing a thousands separator.
  1737.       */
  1738.       char_type
  1739.       thousands_sep() const
  1740.       { return this->do_thousands_sep(); }
  1741.  
  1742.       /**
  1743.        *  @brief  Return grouping specification.
  1744.        *
  1745.        *  This function returns a string representing groupings for the
  1746.        *  integer part of a number.  Groupings indicate where thousands
  1747.        *  separators should be inserted in the integer part of a number.
  1748.        *
  1749.        *  Each char in the return string is interpret as an integer
  1750.        *  rather than a character.  These numbers represent the number
  1751.        *  of digits in a group.  The first char in the string
  1752.        *  represents the number of digits in the least significant
  1753.        *  group.  If a char is negative, it indicates an unlimited
  1754.        *  number of digits for the group.  If more chars from the
  1755.        *  string are required to group a number, the last char is used
  1756.        *  repeatedly.
  1757.        *
  1758.        *  For example, if the grouping() returns "\003\002" and is
  1759.        *  applied to the number 123456789, this corresponds to
  1760.        *  12,34,56,789.  Note that if the string was "32", this would
  1761.        *  put more than 50 digits into the least significant group if
  1762.        *  the character set is ASCII.
  1763.        *
  1764.        *  The string is returned by calling
  1765.        *  numpunct<char_type>::do_grouping().
  1766.        *
  1767.        *  @return  string representing grouping specification.
  1768.       */
  1769.       string
  1770.       grouping() const
  1771.       { return this->do_grouping(); }
  1772.  
  1773.       /**
  1774.        *  @brief  Return string representation of bool true.
  1775.        *
  1776.        *  This function returns a string_type containing the text
  1777.        *  representation for true bool variables.  It does so by calling
  1778.        *  numpunct<char_type>::do_truename().
  1779.        *
  1780.        *  @return  string_type representing printed form of true.
  1781.       */
  1782.       string_type
  1783.       truename() const
  1784.       { return this->do_truename(); }
  1785.  
  1786.       /**
  1787.        *  @brief  Return string representation of bool false.
  1788.        *
  1789.        *  This function returns a string_type containing the text
  1790.        *  representation for false bool variables.  It does so by calling
  1791.        *  numpunct<char_type>::do_falsename().
  1792.        *
  1793.        *  @return  string_type representing printed form of false.
  1794.       */
  1795.       string_type
  1796.       falsename() const
  1797.       { return this->do_falsename(); }
  1798.  
  1799.     protected:
  1800.       /// Destructor.
  1801.       virtual
  1802.       ~numpunct();
  1803.  
  1804.       /**
  1805.        *  @brief  Return decimal point character.
  1806.        *
  1807.        *  Returns a char_type to use as a decimal point.  This function is a
  1808.        *  hook for derived classes to change the value returned.
  1809.        *
  1810.        *  @return  @a char_type representing a decimal point.
  1811.       */
  1812.       virtual char_type
  1813.       do_decimal_point() const
  1814.       { return _M_data->_M_decimal_point; }
  1815.  
  1816.       /**
  1817.        *  @brief  Return thousands separator character.
  1818.        *
  1819.        *  Returns a char_type to use as a thousands separator.  This function
  1820.        *  is a hook for derived classes to change the value returned.
  1821.        *
  1822.        *  @return  @a char_type representing a thousands separator.
  1823.       */
  1824.       virtual char_type
  1825.       do_thousands_sep() const
  1826.       { return _M_data->_M_thousands_sep; }
  1827.  
  1828.       /**
  1829.        *  @brief  Return grouping specification.
  1830.        *
  1831.        *  Returns a string representing groupings for the integer part of a
  1832.        *  number.  This function is a hook for derived classes to change the
  1833.        *  value returned.  @see grouping() for details.
  1834.        *
  1835.        *  @return  String representing grouping specification.
  1836.       */
  1837.       virtual string
  1838.       do_grouping() const
  1839.       { return _M_data->_M_grouping; }
  1840.  
  1841.       /**
  1842.        *  @brief  Return string representation of bool true.
  1843.        *
  1844.        *  Returns a string_type containing the text representation for true
  1845.        *  bool variables.  This function is a hook for derived classes to
  1846.        *  change the value returned.
  1847.        *
  1848.        *  @return  string_type representing printed form of true.
  1849.       */
  1850.       virtual string_type
  1851.       do_truename() const
  1852.       { return _M_data->_M_truename; }
  1853.  
  1854.       /**
  1855.        *  @brief  Return string representation of bool false.
  1856.        *
  1857.        *  Returns a string_type containing the text representation for false
  1858.        *  bool variables.  This function is a hook for derived classes to
  1859.        *  change the value returned.
  1860.        *
  1861.        *  @return  string_type representing printed form of false.
  1862.       */
  1863.       virtual string_type
  1864.       do_falsename() const
  1865.       { return _M_data->_M_falsename; }
  1866.  
  1867.       // For use at construction time only.
  1868.       void
  1869.       _M_initialize_numpunct(__c_locale __cloc = NULL);
  1870.     };
  1871.  
  1872.   template<typename _CharT>
  1873.     locale::id numpunct<_CharT>::id;
  1874.  
  1875.   template<>
  1876.     numpunct<char>::~numpunct();
  1877.  
  1878.   template<>
  1879.     void
  1880.     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
  1881.  
  1882. #ifdef _GLIBCXX_USE_WCHAR_T
  1883.   template<>
  1884.     numpunct<wchar_t>::~numpunct();
  1885.  
  1886.   template<>
  1887.     void
  1888.     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
  1889. #endif
  1890.  
  1891.   template<typename _CharT>
  1892.     class numpunct_byname : public numpunct<_CharT>
  1893.     {
  1894.     public:
  1895.       typedef _CharT            char_type;
  1896.       typedef basic_string<_CharT>    string_type;
  1897.  
  1898.       explicit
  1899.       numpunct_byname(const char* __s, size_t __refs = 0)
  1900.       : numpunct<_CharT>(__refs)
  1901.       {
  1902.     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
  1903.       {
  1904.         __c_locale __tmp;
  1905.         this->_S_create_c_locale(__tmp, __s);
  1906.         this->_M_initialize_numpunct(__tmp);
  1907.         this->_S_destroy_c_locale(__tmp);
  1908.       }
  1909.       }
  1910.  
  1911.     protected:
  1912.       virtual
  1913.       ~numpunct_byname() { }
  1914.     };
  1915.  
  1916.   /**
  1917.    *  @brief  Facet for parsing number strings.
  1918.    *
  1919.    *  This facet encapsulates the code to parse and return a number
  1920.    *  from a string.  It is used by the istream numeric extraction
  1921.    *  operators.
  1922.    *
  1923.    *  The num_get template uses protected virtual functions to provide the
  1924.    *  actual results.  The public accessors forward the call to the virtual
  1925.    *  functions.  These virtual functions are hooks for developers to
  1926.    *  implement the behavior they require from the num_get facet.
  1927.   */
  1928.   template<typename _CharT, typename _InIter>
  1929.     class num_get : public locale::facet
  1930.     {
  1931.     public:
  1932.       // Types:
  1933.       //@{
  1934.       /// Public typedefs
  1935.       typedef _CharT            char_type;
  1936.       typedef _InIter            iter_type;
  1937.       //@}
  1938.  
  1939.       /// Numpunct facet id.
  1940.       static locale::id            id;
  1941.  
  1942.       /**
  1943.        *  @brief  Constructor performs initialization.
  1944.        *
  1945.        *  This is the constructor provided by the standard.
  1946.        *
  1947.        *  @param refs  Passed to the base facet class.
  1948.       */
  1949.       explicit
  1950.       num_get(size_t __refs = 0) : facet(__refs) { }
  1951.  
  1952.       /**
  1953.        *  @brief  Numeric parsing.
  1954.        *
  1955.        *  Parses the input stream into the bool @a v.  It does so by calling
  1956.        *  num_put::do_put().
  1957.        *
  1958.        *  If ios_base::boolalpha is set, attempts to read
  1959.        *  ctype<CharT>::truename() or ctype<CharT>::falsename().  Sets
  1960.        *  @a v to true or false if successful.  Sets err to
  1961.        *  ios_base::failbit if reading the string fails.  Sets err to
  1962.        *  ios_base::eofbit if the stream is emptied.
  1963.        *
  1964.        *  If ios_base::boolalpha is not set, proceeds as with reading a long,
  1965.        *  except if the value is 1, sets @a v to true, if the value is 0, sets
  1966.        *  @a v to false, and otherwise set err to ios_base::failbit.
  1967.        *
  1968.        *  @param  in  Start of input stream.
  1969.        *  @param  end  End of input stream.
  1970.        *  @param  io  Source of locale and flags.
  1971.        *  @param  err  Error flags to set.
  1972.        *  @param  v  Value to format and insert.
  1973.        *  @return  Iterator after reading.
  1974.       */
  1975.       iter_type
  1976.       get(iter_type __in, iter_type __end, ios_base& __io,
  1977.       ios_base::iostate& __err, bool& __v) const
  1978.       { return this->do_get(__in, __end, __io, __err, __v); }
  1979.  
  1980.       //@{
  1981.       /**
  1982.        *  @brief  Numeric parsing.
  1983.        *
  1984.        *  Parses the input stream into the integral variable @a v.  It does so
  1985.        *  by calling num_put::do_put().
  1986.        *
  1987.        *  Parsing is affected by the flag settings in @a io.
  1988.        *
  1989.        *  The basic parse is affected by the value of io.flags() &
  1990.        *  ios_base::basefield.  If equal to ios_base::oct, parses like the
  1991.        *  scanf %o specifier.  Else if equal to ios_base::hex, parses like %X
  1992.        *  specifier.  Else if basefield equal to 0, parses like the %i
  1993.        *  specifier.  Otherwise, parses like %d for signed and %u for unsigned
  1994.        *  types.  The matching type length modifier is also used.
  1995.        *
  1996.        *  Digit grouping is intrepreted according to numpunct::grouping() and
  1997.        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
  1998.        *  consistent, sets err to ios_base::failbit.
  1999.        *
  2000.        *  If parsing the string yields a valid value for @a v, @a v is set.
  2001.        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
  2002.        *  Sets err to ios_base::eofbit if the stream is emptied.
  2003.        *
  2004.        *  @param  in  Start of input stream.
  2005.        *  @param  end  End of input stream.
  2006.        *  @param  io  Source of locale and flags.
  2007.        *  @param  err  Error flags to set.
  2008.        *  @param  v  Value to format and insert.
  2009.        *  @return  Iterator after reading.
  2010.       */
  2011.       iter_type
  2012.       get(iter_type __in, iter_type __end, ios_base& __io,
  2013.       ios_base::iostate& __err, long& __v) const
  2014.       { return this->do_get(__in, __end, __io, __err, __v); }
  2015.  
  2016.       iter_type
  2017.       get(iter_type __in, iter_type __end, ios_base& __io,
  2018.       ios_base::iostate& __err, unsigned short& __v) const
  2019.       { return this->do_get(__in, __end, __io, __err, __v); }
  2020.  
  2021.       iter_type
  2022.       get(iter_type __in, iter_type __end, ios_base& __io,
  2023.       ios_base::iostate& __err, unsigned int& __v)   const
  2024.       { return this->do_get(__in, __end, __io, __err, __v); }
  2025.  
  2026.       iter_type
  2027.       get(iter_type __in, iter_type __end, ios_base& __io,
  2028.       ios_base::iostate& __err, unsigned long& __v)  const
  2029.       { return this->do_get(__in, __end, __io, __err, __v); }
  2030.  
  2031. #ifdef _GLIBCXX_USE_LONG_LONG
  2032.       iter_type
  2033.       get(iter_type __in, iter_type __end, ios_base& __io,
  2034.       ios_base::iostate& __err, long long& __v) const
  2035.       { return this->do_get(__in, __end, __io, __err, __v); }
  2036.  
  2037.       iter_type
  2038.       get(iter_type __in, iter_type __end, ios_base& __io,
  2039.       ios_base::iostate& __err, unsigned long long& __v)  const
  2040.       { return this->do_get(__in, __end, __io, __err, __v); }
  2041. #endif
  2042.       //@}
  2043.  
  2044.       //@{
  2045.       /**
  2046.        *  @brief  Numeric parsing.
  2047.        *
  2048.        *  Parses the input stream into the integral variable @a v.  It does so
  2049.        *  by calling num_put::do_put().
  2050.        *
  2051.        *  The input characters are parsed like the scanf %g specifier.  The
  2052.        *  matching type length modifier is also used.
  2053.        *
  2054.        *  The decimal point character used is numpunct::decimal_point().
  2055.        *  Digit grouping is intrepreted according to numpunct::grouping() and
  2056.        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
  2057.        *  consistent, sets err to ios_base::failbit.
  2058.        *
  2059.        *  If parsing the string yields a valid value for @a v, @a v is set.
  2060.        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
  2061.        *  Sets err to ios_base::eofbit if the stream is emptied.
  2062.        *
  2063.        *  @param  in  Start of input stream.
  2064.        *  @param  end  End of input stream.
  2065.        *  @param  io  Source of locale and flags.
  2066.        *  @param  err  Error flags to set.
  2067.        *  @param  v  Value to format and insert.
  2068.        *  @return  Iterator after reading.
  2069.       */
  2070.       iter_type
  2071.       get(iter_type __in, iter_type __end, ios_base& __io,
  2072.       ios_base::iostate& __err, float& __v) const
  2073.       { return this->do_get(__in, __end, __io, __err, __v); }
  2074.  
  2075.       iter_type
  2076.       get(iter_type __in, iter_type __end, ios_base& __io,
  2077.       ios_base::iostate& __err, double& __v) const
  2078.       { return this->do_get(__in, __end, __io, __err, __v); }
  2079.  
  2080.       iter_type
  2081.       get(iter_type __in, iter_type __end, ios_base& __io,
  2082.       ios_base::iostate& __err, long double& __v) const
  2083.       { return this->do_get(__in, __end, __io, __err, __v); }
  2084.       //@}
  2085.  
  2086.       /**
  2087.        *  @brief  Numeric parsing.
  2088.        *
  2089.        *  Parses the input stream into the pointer variable @a v.  It does so
  2090.        *  by calling num_put::do_put().
  2091.        *
  2092.        *  The input characters are parsed like the scanf %p specifier.
  2093.        *
  2094.        *  Digit grouping is intrepreted according to numpunct::grouping() and
  2095.        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
  2096.        *  consistent, sets err to ios_base::failbit.
  2097.        *
  2098.        *  Note that the digit grouping effect for pointers is a bit ambiguous
  2099.        *  in the standard and shouldn't be relied on.  See DR 344.
  2100.        *
  2101.        *  If parsing the string yields a valid value for @a v, @a v is set.
  2102.        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
  2103.        *  Sets err to ios_base::eofbit if the stream is emptied.
  2104.        *
  2105.        *  @param  in  Start of input stream.
  2106.        *  @param  end  End of input stream.
  2107.        *  @param  io  Source of locale and flags.
  2108.        *  @param  err  Error flags to set.
  2109.        *  @param  v  Value to format and insert.
  2110.        *  @return  Iterator after reading.
  2111.       */
  2112.       iter_type
  2113.       get(iter_type __in, iter_type __end, ios_base& __io,
  2114.       ios_base::iostate& __err, void*& __v) const
  2115.       { return this->do_get(__in, __end, __io, __err, __v); }
  2116.  
  2117.     protected:
  2118.       /// Destructor.
  2119.       virtual ~num_get() { }
  2120.  
  2121.       iter_type
  2122.       _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
  2123.                string& __xtrc) const;
  2124.  
  2125.       template<typename _ValueT>
  2126.         iter_type
  2127.         _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
  2128.                _ValueT& __v) const;
  2129.  
  2130.       //@{
  2131.       /**
  2132.        *  @brief  Numeric parsing.
  2133.        *
  2134.        *  Parses the input stream into the variable @a v.  This function is a
  2135.        *  hook for derived classes to change the value returned.  @see get()
  2136.        *  for more details.
  2137.        *
  2138.        *  @param  in  Start of input stream.
  2139.        *  @param  end  End of input stream.
  2140.        *  @param  io  Source of locale and flags.
  2141.        *  @param  err  Error flags to set.
  2142.        *  @param  v  Value to format and insert.
  2143.        *  @return  Iterator after reading.
  2144.       */
  2145.       virtual iter_type
  2146.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
  2147.  
  2148.  
  2149.       virtual iter_type
  2150.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
  2151.  
  2152.       virtual iter_type
  2153.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2154.           unsigned short&) const;
  2155.  
  2156.       virtual iter_type
  2157.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2158.          unsigned int&) const;
  2159.  
  2160.       virtual iter_type
  2161.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2162.          unsigned long&) const;
  2163.  
  2164. #ifdef _GLIBCXX_USE_LONG_LONG
  2165.       virtual iter_type
  2166.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2167.          long long&) const;
  2168.  
  2169.       virtual iter_type
  2170.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2171.          unsigned long long&) const;
  2172. #endif
  2173.  
  2174.       virtual iter_type
  2175.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2176.          float&) const;
  2177.  
  2178.       virtual iter_type
  2179.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2180.          double&) const;
  2181.  
  2182.       virtual iter_type
  2183.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2184.          long double&) const;
  2185.  
  2186.       virtual iter_type
  2187.       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
  2188.          void*&) const;
  2189.       //@}
  2190.     };
  2191.  
  2192.   template<typename _CharT, typename _InIter>
  2193.     locale::id num_get<_CharT, _InIter>::id;
  2194.  
  2195.  
  2196.   /**
  2197.    *  @brief  Facet for converting numbers to strings.
  2198.    *
  2199.    *  This facet encapsulates the code to convert a number to a string.  It is
  2200.    *  used by the ostream numeric insertion operators.
  2201.    *
  2202.    *  The num_put template uses protected virtual functions to provide the
  2203.    *  actual results.  The public accessors forward the call to the virtual
  2204.    *  functions.  These virtual functions are hooks for developers to
  2205.    *  implement the behavior they require from the num_put facet.
  2206.   */
  2207.   template<typename _CharT, typename _OutIter>
  2208.     class num_put : public locale::facet
  2209.     {
  2210.     public:
  2211.       // Types:
  2212.       //@{
  2213.       /// Public typedefs
  2214.       typedef _CharT        char_type;
  2215.       typedef _OutIter        iter_type;
  2216.       //@}
  2217.  
  2218.       /// Numpunct facet id.
  2219.       static locale::id        id;
  2220.  
  2221.       /**
  2222.        *  @brief  Constructor performs initialization.
  2223.        *
  2224.        *  This is the constructor provided by the standard.
  2225.        *
  2226.        *  @param refs  Passed to the base facet class.
  2227.       */
  2228.       explicit
  2229.       num_put(size_t __refs = 0) : facet(__refs) { }
  2230.  
  2231.       /**
  2232.        *  @brief  Numeric formatting.
  2233.        *
  2234.        *  Formats the boolean @a v and inserts it into a stream.  It does so
  2235.        *  by calling num_put::do_put().
  2236.        *
  2237.        *  If ios_base::boolalpha is set, writes ctype<CharT>::truename() or
  2238.        *  ctype<CharT>::falsename().  Otherwise formats @a v as an int.
  2239.        *
  2240.        *  @param  s  Stream to write to.
  2241.        *  @param  io  Source of locale and flags.
  2242.        *  @param  fill  Char_type to use for filling.
  2243.        *  @param  v  Value to format and insert.
  2244.        *  @return  Iterator after writing.
  2245.       */
  2246.       iter_type
  2247.       put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
  2248.       { return this->do_put(__s, __f, __fill, __v); }
  2249.  
  2250.       //@{
  2251.       /**
  2252.        *  @brief  Numeric formatting.
  2253.        *
  2254.        *  Formats the integral value @a v and inserts it into a
  2255.        *  stream.  It does so by calling num_put::do_put().
  2256.        *
  2257.        *  Formatting is affected by the flag settings in @a io.
  2258.        *
  2259.        *  The basic format is affected by the value of io.flags() &
  2260.        *  ios_base::basefield.  If equal to ios_base::oct, formats like the
  2261.        *  printf %o specifier.  Else if equal to ios_base::hex, formats like
  2262.        *  %x or %X with ios_base::uppercase unset or set respectively.
  2263.        *  Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu
  2264.        *  for unsigned values.  Note that if both oct and hex are set, neither
  2265.        *  will take effect.
  2266.        *
  2267.        *  If ios_base::showpos is set, '+' is output before positive values.
  2268.        *  If ios_base::showbase is set, '0' precedes octal values (except 0)
  2269.        *  and '0[xX]' precedes hex values.
  2270.        *
  2271.        *  Thousands separators are inserted according to numpunct::grouping()
  2272.        *  and numpunct::thousands_sep().  The decimal point character used is
  2273.        *  numpunct::decimal_point().
  2274.        *
  2275.        *  If io.width() is non-zero, enough @a fill characters are inserted to
  2276.        *  make the result at least that wide.  If
  2277.        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
  2278.        *  padded at the end.  If ios_base::internal, then padding occurs
  2279.        *  immediately after either a '+' or '-' or after '0x' or '0X'.
  2280.        *  Otherwise, padding occurs at the beginning.
  2281.        *
  2282.        *  @param  s  Stream to write to.
  2283.        *  @param  io  Source of locale and flags.
  2284.        *  @param  fill  Char_type to use for filling.
  2285.        *  @param  v  Value to format and insert.
  2286.        *  @return  Iterator after writing.
  2287.       */
  2288.       iter_type
  2289.       put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
  2290.       { return this->do_put(__s, __f, __fill, __v); }
  2291.  
  2292.       iter_type
  2293.       put(iter_type __s, ios_base& __f, char_type __fill,
  2294.       unsigned long __v) const
  2295.       { return this->do_put(__s, __f, __fill, __v); }
  2296.  
  2297. #ifdef _GLIBCXX_USE_LONG_LONG
  2298.       iter_type
  2299.       put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
  2300.       { return this->do_put(__s, __f, __fill, __v); }
  2301.  
  2302.       iter_type
  2303.       put(iter_type __s, ios_base& __f, char_type __fill,
  2304.       unsigned long long __v) const
  2305.       { return this->do_put(__s, __f, __fill, __v); }
  2306. #endif
  2307.       //@}
  2308.  
  2309.       //@{
  2310.       /**
  2311.        *  @brief  Numeric formatting.
  2312.        *
  2313.        *  Formats the floating point value @a v and inserts it into a stream.
  2314.        *  It does so by calling num_put::do_put().
  2315.        *
  2316.        *  Formatting is affected by the flag settings in @a io.
  2317.        *
  2318.        *  The basic format is affected by the value of io.flags() &
  2319.        *  ios_base::floatfield.  If equal to ios_base::fixed, formats like the
  2320.        *  printf %f specifier.  Else if equal to ios_base::scientific, formats
  2321.        *  like %e or %E with ios_base::uppercase unset or set respectively.
  2322.        *  Otherwise, formats like %g or %G depending on uppercase.  Note that
  2323.        *  if both fixed and scientific are set, the effect will also be like
  2324.        *  %g or %G.
  2325.        *
  2326.        *  The output precision is given by io.precision().  This precision is
  2327.        *  capped at numeric_limits::digits10 + 2 (different for double and
  2328.        *  long double).  The default precision is 6.
  2329.        *
  2330.        *  If ios_base::showpos is set, '+' is output before positive values.
  2331.        *  If ios_base::showpoint is set, a decimal point will always be
  2332.        *  output.
  2333.        *
  2334.        *  Thousands separators are inserted according to numpunct::grouping()
  2335.        *  and numpunct::thousands_sep().  The decimal point character used is
  2336.        *  numpunct::decimal_point().
  2337.        *
  2338.        *  If io.width() is non-zero, enough @a fill characters are inserted to
  2339.        *  make the result at least that wide.  If
  2340.        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
  2341.        *  padded at the end.  If ios_base::internal, then padding occurs
  2342.        *  immediately after either a '+' or '-' or after '0x' or '0X'.
  2343.        *  Otherwise, padding occurs at the beginning.
  2344.        *
  2345.        *  @param  s  Stream to write to.
  2346.        *  @param  io  Source of locale and flags.
  2347.        *  @param  fill  Char_type to use for filling.
  2348.        *  @param  v  Value to format and insert.
  2349.        *  @return  Iterator after writing.
  2350.       */
  2351.       iter_type
  2352.       put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
  2353.       { return this->do_put(__s, __f, __fill, __v); }
  2354.  
  2355.       iter_type
  2356.       put(iter_type __s, ios_base& __f, char_type __fill,
  2357.       long double __v) const
  2358.       { return this->do_put(__s, __f, __fill, __v); }
  2359.       //@}
  2360.  
  2361.       /**
  2362.        *  @brief  Numeric formatting.
  2363.        *
  2364.        *  Formats the pointer value @a v and inserts it into a stream.  It
  2365.        *  does so by calling num_put::do_put().
  2366.        *
  2367.        *  This function formats @a v as an unsigned long with ios_base::hex
  2368.        *  and ios_base::showbase set.
  2369.        *
  2370.        *  @param  s  Stream to write to.
  2371.        *  @param  io  Source of locale and flags.
  2372.        *  @param  fill  Char_type to use for filling.
  2373.        *  @param  v  Value to format and insert.
  2374.        *  @return  Iterator after writing.
  2375.       */
  2376.       iter_type
  2377.       put(iter_type __s, ios_base& __f, char_type __fill,
  2378.       const void* __v) const
  2379.       { return this->do_put(__s, __f, __fill, __v); }
  2380.  
  2381.     protected:
  2382.       template<typename _ValueT>
  2383.         iter_type
  2384.         _M_insert_float(iter_type, ios_base& __io, char_type __fill,
  2385.             char __mod, _ValueT __v) const;
  2386.  
  2387.       void
  2388.       _M_group_float(const char* __grouping, size_t __grouping_size,
  2389.              char_type __sep, const char_type* __p, char_type* __new,
  2390.              char_type* __cs, int& __len) const;
  2391.  
  2392.       template<typename _ValueT>
  2393.         iter_type
  2394.         _M_insert_int(iter_type, ios_base& __io, char_type __fill,
  2395.               _ValueT __v) const;
  2396.  
  2397.       void
  2398.       _M_group_int(const char* __grouping, size_t __grouping_size,
  2399.            char_type __sep, ios_base& __io, char_type* __new,
  2400.            char_type* __cs, int& __len) const;
  2401.  
  2402.       void
  2403.       _M_pad(char_type __fill, streamsize __w, ios_base& __io,
  2404.          char_type* __new, const char_type* __cs, int& __len) const;
  2405.  
  2406.       /// Destructor.
  2407.       virtual
  2408.       ~num_put() { };
  2409.  
  2410.       //@{
  2411.       /**
  2412.        *  @brief  Numeric formatting.
  2413.        *
  2414.        *  These functions do the work of formatting numeric values and
  2415.        *  inserting them into a stream. This function is a hook for derived
  2416.        *  classes to change the value returned.
  2417.        *
  2418.        *  @param  s  Stream to write to.
  2419.        *  @param  io  Source of locale and flags.
  2420.        *  @param  fill  Char_type to use for filling.
  2421.        *  @param  v  Value to format and insert.
  2422.        *  @return  Iterator after writing.
  2423.       */
  2424.       virtual iter_type
  2425.       do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
  2426.  
  2427.       virtual iter_type
  2428.       do_put(iter_type, ios_base&, char_type __fill, long __v) const;
  2429.  
  2430.       virtual iter_type
  2431.       do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
  2432.  
  2433. #ifdef _GLIBCXX_USE_LONG_LONG
  2434.       virtual iter_type
  2435.       do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
  2436.  
  2437.       virtual iter_type
  2438.       do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
  2439. #endif
  2440.  
  2441.       virtual iter_type
  2442.       do_put(iter_type, ios_base&, char_type __fill, double __v) const;
  2443.  
  2444.       virtual iter_type
  2445.       do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
  2446.  
  2447.       virtual iter_type
  2448.       do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
  2449.       //@}
  2450.     };
  2451.  
  2452.   template <typename _CharT, typename _OutIter>
  2453.     locale::id num_put<_CharT, _OutIter>::id;
  2454.  
  2455.  
  2456.   /**
  2457.    *  @brief  Facet for localized string comparison.
  2458.    *
  2459.    *  This facet encapsulates the code to compare strings in a localized
  2460.    *  manner.
  2461.    *
  2462.    *  The collate template uses protected virtual functions to provide
  2463.    *  the actual results.  The public accessors forward the call to
  2464.    *  the virtual functions.  These virtual functions are hooks for
  2465.    *  developers to implement the behavior they require from the
  2466.    *  collate facet.
  2467.   */
  2468.   template<typename _CharT>
  2469.     class collate : public locale::facet
  2470.     {
  2471.     public:
  2472.       // Types:
  2473.       //@{
  2474.       /// Public typedefs
  2475.       typedef _CharT            char_type;
  2476.       typedef basic_string<_CharT>    string_type;
  2477.       //@}
  2478.  
  2479.     protected:
  2480.       // Underlying "C" library locale information saved from
  2481.       // initialization, needed by collate_byname as well.
  2482.       __c_locale            _M_c_locale_collate;
  2483.  
  2484.     public:
  2485.       /// Numpunct facet id.
  2486.       static locale::id            id;
  2487.  
  2488.       /**
  2489.        *  @brief  Constructor performs initialization.
  2490.        *
  2491.        *  This is the constructor provided by the standard.
  2492.        *
  2493.        *  @param refs  Passed to the base facet class.
  2494.       */
  2495.       explicit
  2496.       collate(size_t __refs = 0)
  2497.       : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
  2498.       { }
  2499.  
  2500.       /**
  2501.        *  @brief  Internal constructor. Not for general use.
  2502.        *
  2503.        *  This is a constructor for use by the library itself to set up new
  2504.        *  locales.
  2505.        *
  2506.        *  @param cloc  The "C" locale.
  2507.        *  @param refs  Passed to the base facet class.
  2508.       */
  2509.       explicit
  2510.       collate(__c_locale __cloc, size_t __refs = 0)
  2511.       : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
  2512.       { }
  2513.  
  2514.       /**
  2515.        *  @brief  Compare two strings.
  2516.        *
  2517.        *  This function compares two strings and returns the result by calling
  2518.        *  collate::do_compare().
  2519.        *
  2520.        *  @param lo1  Start of string 1.
  2521.        *  @param hi1  End of string 1.
  2522.        *  @param lo2  Start of string 2.
  2523.        *  @param hi2  End of string 2.
  2524.        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
  2525.       */
  2526.       int
  2527.       compare(const _CharT* __lo1, const _CharT* __hi1,
  2528.           const _CharT* __lo2, const _CharT* __hi2) const
  2529.       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
  2530.  
  2531.       /**
  2532.        *  @brief  Transform string to comparable form.
  2533.        *
  2534.        *  This function is a wrapper for strxfrm functionality.  It takes the
  2535.        *  input string and returns a modified string that can be directly
  2536.        *  compared to other transformed strings.  In the "C" locale, this
  2537.        *  function just returns a copy of the input string.  In some other
  2538.        *  locales, it may replace two chars with one, change a char for
  2539.        *  another, etc.  It does so by returning collate::do_transform().
  2540.        *
  2541.        *  @param lo  Start of string.
  2542.        *  @param hi  End of string.
  2543.        *  @return  Transformed string_type.
  2544.       */
  2545.       string_type
  2546.       transform(const _CharT* __lo, const _CharT* __hi) const
  2547.       { return this->do_transform(__lo, __hi); }
  2548.  
  2549.       /**
  2550.        *  @brief  Return hash of a string.
  2551.        *
  2552.        *  This function computes and returns a hash on the input string.  It
  2553.        *  does so by returning collate::do_hash().
  2554.        *
  2555.        *  @param lo  Start of string.
  2556.        *  @param hi  End of string.
  2557.        *  @return  Hash value.
  2558.       */
  2559.       long
  2560.       hash(const _CharT* __lo, const _CharT* __hi) const
  2561.       { return this->do_hash(__lo, __hi); }
  2562.  
  2563.       // Used to abstract out _CharT bits in virtual member functions, below.
  2564.       int
  2565.       _M_compare(const _CharT*, const _CharT*) const;
  2566.  
  2567.       size_t
  2568.       _M_transform(_CharT*, const _CharT*, size_t) const;
  2569.  
  2570.   protected:
  2571.       /// Destructor.
  2572.       virtual
  2573.       ~collate()
  2574.       { _S_destroy_c_locale(_M_c_locale_collate); }
  2575.  
  2576.       /**
  2577.        *  @brief  Compare two strings.
  2578.        *
  2579.        *  This function is a hook for derived classes to change the value
  2580.        *  returned.  @see compare().
  2581.        *
  2582.        *  @param lo1  Start of string 1.
  2583.        *  @param hi1  End of string 1.
  2584.        *  @param lo2  Start of string 2.
  2585.        *  @param hi2  End of string 2.
  2586.        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
  2587.       */
  2588.       virtual int
  2589.       do_compare(const _CharT* __lo1, const _CharT* __hi1,
  2590.          const _CharT* __lo2, const _CharT* __hi2) const;
  2591.  
  2592.       /**
  2593.        *  @brief  Transform string to comparable form.
  2594.        *
  2595.        *  This function is a hook for derived classes to change the value
  2596.        *  returned.
  2597.        *
  2598.        *  @param lo1  Start of string 1.
  2599.        *  @param hi1  End of string 1.
  2600.        *  @param lo2  Start of string 2.
  2601.        *  @param hi2  End of string 2.
  2602.        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
  2603.       */
  2604.       virtual string_type
  2605.       do_transform(const _CharT* __lo, const _CharT* __hi) const;
  2606.  
  2607.       /**
  2608.        *  @brief  Return hash of a string.
  2609.        *
  2610.        *  This function computes and returns a hash on the input string.  This
  2611.        *  function is a hook for derived classes to change the value returned.
  2612.        *
  2613.        *  @param lo  Start of string.
  2614.        *  @param hi  End of string.
  2615.        *  @return  Hash value.
  2616.       */
  2617.       virtual long
  2618.       do_hash(const _CharT* __lo, const _CharT* __hi) const;
  2619.     };
  2620.  
  2621.   template<typename _CharT>
  2622.     locale::id collate<_CharT>::id;
  2623.  
  2624.   // Specializations.
  2625.   template<>
  2626.     int
  2627.     collate<char>::_M_compare(const char*, const char*) const;
  2628.  
  2629.   template<>
  2630.     size_t
  2631.     collate<char>::_M_transform(char*, const char*, size_t) const;
  2632.  
  2633. #ifdef _GLIBCXX_USE_WCHAR_T
  2634.   template<>
  2635.     int
  2636.     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
  2637.  
  2638.   template<>
  2639.     size_t
  2640.     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
  2641. #endif
  2642.  
  2643.   template<typename _CharT>
  2644.     class collate_byname : public collate<_CharT>
  2645.     {
  2646.     public:
  2647.       //@{
  2648.       /// Public typedefs
  2649.       typedef _CharT               char_type;
  2650.       typedef basic_string<_CharT> string_type;
  2651.       //@}
  2652.  
  2653.       explicit
  2654.       collate_byname(const char* __s, size_t __refs = 0)
  2655.       : collate<_CharT>(__refs)
  2656.       {
  2657.     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
  2658.       {
  2659.         this->_S_destroy_c_locale(this->_M_c_locale_collate);
  2660.         this->_S_create_c_locale(this->_M_c_locale_collate, __s);
  2661.       }
  2662.       }
  2663.  
  2664.     protected:
  2665.       virtual
  2666.       ~collate_byname() { }
  2667.     };
  2668.  
  2669.  
  2670.   /**
  2671.    *  @brief  Time format ordering data.
  2672.    *
  2673.    *  This class provides an enum representing different orderings of day,
  2674.    *  month, and year.
  2675.   */
  2676.   class time_base
  2677.   {
  2678.   public:
  2679.     enum dateorder { no_order, dmy, mdy, ymd, ydm };
  2680.   };
  2681.  
  2682.   template<typename _CharT>
  2683.     struct __timepunct_cache : public locale::facet
  2684.     {
  2685.       // List of all known timezones, with GMT first.
  2686.       static const _CharT*        _S_timezones[14];
  2687.  
  2688.       const _CharT*            _M_date_format;
  2689.       const _CharT*            _M_date_era_format;
  2690.       const _CharT*            _M_time_format;
  2691.       const _CharT*            _M_time_era_format;
  2692.       const _CharT*            _M_date_time_format;
  2693.       const _CharT*            _M_date_time_era_format;
  2694.       const _CharT*            _M_am;
  2695.       const _CharT*            _M_pm;
  2696.       const _CharT*            _M_am_pm_format;
  2697.  
  2698.       // Day names, starting with "C"'s Sunday.
  2699.       const _CharT*            _M_day1;
  2700.       const _CharT*            _M_day2;
  2701.       const _CharT*            _M_day3;
  2702.       const _CharT*            _M_day4;
  2703.       const _CharT*            _M_day5;
  2704.       const _CharT*            _M_day6;
  2705.       const _CharT*            _M_day7;
  2706.  
  2707.       // Abbreviated day names, starting with "C"'s Sun.
  2708.       const _CharT*            _M_aday1;
  2709.       const _CharT*            _M_aday2;
  2710.       const _CharT*            _M_aday3;
  2711.       const _CharT*            _M_aday4;
  2712.       const _CharT*            _M_aday5;
  2713.       const _CharT*            _M_aday6;
  2714.       const _CharT*            _M_aday7;
  2715.  
  2716.       // Month names, starting with "C"'s January.
  2717.       const _CharT*            _M_month01;
  2718.       const _CharT*            _M_month02;
  2719.       const _CharT*            _M_month03;
  2720.       const _CharT*            _M_month04;
  2721.       const _CharT*            _M_month05;
  2722.       const _CharT*            _M_month06;
  2723.       const _CharT*            _M_month07;
  2724.       const _CharT*            _M_month08;
  2725.       const _CharT*            _M_month09;
  2726.       const _CharT*            _M_month10;
  2727.       const _CharT*            _M_month11;
  2728.       const _CharT*            _M_month12;
  2729.  
  2730.       // Abbreviated month names, starting with "C"'s Jan.
  2731.       const _CharT*            _M_amonth01;
  2732.       const _CharT*            _M_amonth02;
  2733.       const _CharT*            _M_amonth03;
  2734.       const _CharT*            _M_amonth04;
  2735.       const _CharT*            _M_amonth05;
  2736.       const _CharT*            _M_amonth06;
  2737.       const _CharT*            _M_amonth07;
  2738.       const _CharT*            _M_amonth08;
  2739.       const _CharT*            _M_amonth09;
  2740.       const _CharT*            _M_amonth10;
  2741.       const _CharT*            _M_amonth11;
  2742.       const _CharT*            _M_amonth12;
  2743.  
  2744.       bool                _M_allocated;
  2745.  
  2746.       __timepunct_cache(size_t __refs = 0) : facet(__refs),
  2747.       _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL),
  2748.       _M_time_era_format(NULL), _M_date_time_format(NULL),
  2749.       _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL),
  2750.       _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL),
  2751.       _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL),
  2752.       _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL),
  2753.       _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL),
  2754.       _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL),
  2755.       _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL),
  2756.       _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL),
  2757.       _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL),
  2758.       _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL),
  2759.       _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL),
  2760.       _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false)
  2761.       { }
  2762.  
  2763.       ~__timepunct_cache();
  2764.  
  2765.       void
  2766.       _M_cache(const locale& __loc);
  2767.  
  2768.     private:
  2769.       __timepunct_cache&
  2770.       operator=(const __timepunct_cache&);
  2771.       
  2772.       explicit
  2773.       __timepunct_cache(const __timepunct_cache&);
  2774.     };
  2775.  
  2776.   template<typename _CharT>
  2777.     __timepunct_cache<_CharT>::~__timepunct_cache()
  2778.     {
  2779.       if (_M_allocated)
  2780.     {
  2781.       // Unused.
  2782.     }
  2783.     }
  2784.  
  2785.   // Specializations.
  2786.   template<>
  2787.     const char*
  2788.     __timepunct_cache<char>::_S_timezones[14];
  2789.  
  2790. #ifdef _GLIBCXX_USE_WCHAR_T
  2791.   template<>
  2792.     const wchar_t*
  2793.     __timepunct_cache<wchar_t>::_S_timezones[14];
  2794. #endif
  2795.  
  2796.   // Generic.
  2797.   template<typename _CharT>
  2798.     const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];
  2799.  
  2800.   template<typename _CharT>
  2801.     class __timepunct : public locale::facet
  2802.     {
  2803.     public:
  2804.       // Types:
  2805.       typedef _CharT            __char_type;
  2806.       typedef basic_string<_CharT>    __string_type;
  2807.       typedef __timepunct_cache<_CharT>    __cache_type;
  2808.  
  2809.     protected:
  2810.       __cache_type*            _M_data;
  2811.       __c_locale            _M_c_locale_timepunct;
  2812.       const char*            _M_name_timepunct;
  2813.  
  2814.     public:
  2815.       /// Numpunct facet id.
  2816.       static locale::id            id;
  2817.  
  2818.       explicit
  2819.       __timepunct(size_t __refs = 0);
  2820.  
  2821.       explicit
  2822.       __timepunct(__cache_type* __cache, size_t __refs = 0);
  2823.  
  2824.       /**
  2825.        *  @brief  Internal constructor. Not for general use.
  2826.        *
  2827.        *  This is a constructor for use by the library itself to set up new
  2828.        *  locales.
  2829.        *
  2830.        *  @param cloc  The "C" locale.
  2831.        *  @param s  The name of a locale.
  2832.        *  @param refs  Passed to the base facet class.
  2833.       */
  2834.       explicit
  2835.       __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
  2836.  
  2837.       void
  2838.       _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
  2839.          const tm* __tm) const;
  2840.  
  2841.       void
  2842.       _M_date_formats(const _CharT** __date) const
  2843.       {
  2844.     // Always have default first.
  2845.     __date[0] = _M_data->_M_date_format;
  2846.     __date[1] = _M_data->_M_date_era_format;
  2847.       }
  2848.  
  2849.       void
  2850.       _M_time_formats(const _CharT** __time) const
  2851.       {
  2852.     // Always have default first.
  2853.     __time[0] = _M_data->_M_time_format;
  2854.     __time[1] = _M_data->_M_time_era_format;
  2855.       }
  2856.  
  2857.       void
  2858.       _M_date_time_formats(const _CharT** __dt) const
  2859.       {
  2860.     // Always have default first.
  2861.     __dt[0] = _M_data->_M_date_time_format;
  2862.     __dt[1] = _M_data->_M_date_time_era_format;
  2863.       }
  2864.  
  2865.       void
  2866.       _M_am_pm_format(const _CharT* __ampm) const
  2867.       { __ampm = _M_data->_M_am_pm_format; }
  2868.  
  2869.       void
  2870.       _M_am_pm(const _CharT** __ampm) const
  2871.       {
  2872.     __ampm[0] = _M_data->_M_am;
  2873.     __ampm[1] = _M_data->_M_pm;
  2874.       }
  2875.  
  2876.       void
  2877.       _M_days(const _CharT** __days) const
  2878.       {
  2879.     __days[0] = _M_data->_M_day1;
  2880.     __days[1] = _M_data->_M_day2;
  2881.     __days[2] = _M_data->_M_day3;
  2882.     __days[3] = _M_data->_M_day4;
  2883.     __days[4] = _M_data->_M_day5;
  2884.     __days[5] = _M_data->_M_day6;
  2885.     __days[6] = _M_data->_M_day7;
  2886.       }
  2887.  
  2888.       void
  2889.       _M_days_abbreviated(const _CharT** __days) const
  2890.       {
  2891.     __days[0] = _M_data->_M_aday1;
  2892.     __days[1] = _M_data->_M_aday2;
  2893.     __days[2] = _M_data->_M_aday3;
  2894.     __days[3] = _M_data->_M_aday4;
  2895.     __days[4] = _M_data->_M_aday5;
  2896.     __days[5] = _M_data->_M_aday6;
  2897.     __days[6] = _M_data->_M_aday7;
  2898.       }
  2899.  
  2900.       void
  2901.       _M_months(const _CharT** __months) const
  2902.       {
  2903.     __months[0] = _M_data->_M_month01;
  2904.     __months[1] = _M_data->_M_month02;
  2905.     __months[2] = _M_data->_M_month03;
  2906.     __months[3] = _M_data->_M_month04;
  2907.     __months[4] = _M_data->_M_month05;
  2908.     __months[5] = _M_data->_M_month06;
  2909.     __months[6] = _M_data->_M_month07;
  2910.     __months[7] = _M_data->_M_month08;
  2911.     __months[8] = _M_data->_M_month09;
  2912.     __months[9] = _M_data->_M_month10;
  2913.     __months[10] = _M_data->_M_month11;
  2914.     __months[11] = _M_data->_M_month12;
  2915.       }
  2916.  
  2917.       void
  2918.       _M_months_abbreviated(const _CharT** __months) const
  2919.       {
  2920.     __months[0] = _M_data->_M_amonth01;
  2921.     __months[1] = _M_data->_M_amonth02;
  2922.     __months[2] = _M_data->_M_amonth03;
  2923.     __months[3] = _M_data->_M_amonth04;
  2924.     __months[4] = _M_data->_M_amonth05;
  2925.     __months[5] = _M_data->_M_amonth06;
  2926.     __months[6] = _M_data->_M_amonth07;
  2927.     __months[7] = _M_data->_M_amonth08;
  2928.     __months[8] = _M_data->_M_amonth09;
  2929.     __months[9] = _M_data->_M_amonth10;
  2930.     __months[10] = _M_data->_M_amonth11;
  2931.     __months[11] = _M_data->_M_amonth12;
  2932.       }
  2933.  
  2934.     protected:
  2935.       virtual
  2936.       ~__timepunct();
  2937.  
  2938.       // For use at construction time only.
  2939.       void
  2940.       _M_initialize_timepunct(__c_locale __cloc = NULL);
  2941.     };
  2942.  
  2943.   template<typename _CharT>
  2944.     locale::id __timepunct<_CharT>::id;
  2945.  
  2946.   // Specializations.
  2947.   template<>
  2948.     void
  2949.     __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
  2950.  
  2951.   template<>
  2952.     void
  2953.     __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
  2954.  
  2955. #ifdef _GLIBCXX_USE_WCHAR_T
  2956.   template<>
  2957.     void
  2958.     __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
  2959.  
  2960.   template<>
  2961.     void
  2962.     __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
  2963.                  const tm*) const;
  2964. #endif
  2965.  
  2966.   // Include host and configuration specific timepunct functions.
  2967.   #include <bits/time_members.h>
  2968.  
  2969.   /**
  2970.    *  @brief  Facet for parsing dates and times.
  2971.    *
  2972.    *  This facet encapsulates the code to parse and return a date or
  2973.    *  time from a string.  It is used by the istream numeric
  2974.    *  extraction operators.
  2975.    *
  2976.    *  The time_get template uses protected virtual functions to provide the
  2977.    *  actual results.  The public accessors forward the call to the virtual
  2978.    *  functions.  These virtual functions are hooks for developers to
  2979.    *  implement the behavior they require from the time_get facet.
  2980.   */
  2981.   template<typename _CharT, typename _InIter>
  2982.     class time_get : public locale::facet, public time_base
  2983.     {
  2984.     public:
  2985.       // Types:
  2986.       //@{
  2987.       /// Public typedefs
  2988.       typedef _CharT            char_type;
  2989.       typedef _InIter            iter_type;
  2990.       //@}
  2991.       typedef basic_string<_CharT>    __string_type;
  2992.  
  2993.       /// Numpunct facet id.
  2994.       static locale::id            id;
  2995.  
  2996.       /**
  2997.        *  @brief  Constructor performs initialization.
  2998.        *
  2999.        *  This is the constructor provided by the standard.
  3000.        *
  3001.        *  @param refs  Passed to the base facet class.
  3002.       */
  3003.       explicit
  3004.       time_get(size_t __refs = 0)
  3005.       : facet (__refs) { }
  3006.  
  3007.       /**
  3008.        *  @brief  Return preferred order of month, day, and year.
  3009.        *
  3010.        *  This function returns an enum from timebase::dateorder giving the
  3011.        *  preferred ordering if the format "x" given to time_put::put() only
  3012.        *  uses month, day, and year.  If the format "x" for the associated
  3013.        *  locale uses other fields, this function returns
  3014.        *  timebase::dateorder::noorder.
  3015.        *
  3016.        *  NOTE: The library always returns noorder at the moment.
  3017.        *
  3018.        *  @return  A member of timebase::dateorder.
  3019.       */
  3020.       dateorder
  3021.       date_order()  const
  3022.       { return this->do_date_order(); }
  3023.  
  3024.       /**
  3025.        *  @brief  Parse input time string.
  3026.        *
  3027.        *  This function parses a time according to the format "x" and puts the
  3028.        *  results into a user-supplied struct tm.  The result is returned by
  3029.        *  calling time_get::do_get_time().
  3030.        *
  3031.        *  If there is a valid time string according to format "x", @a tm will
  3032.        *  be filled in accordingly and the returned iterator will point to the
  3033.        *  first character beyond the time string.  If an error occurs before
  3034.        *  the end, err |= ios_base::failbit.  If parsing reads all the
  3035.        *  characters, err |= ios_base::eofbit.
  3036.        *
  3037.        *  @param  beg  Start of string to parse.
  3038.        *  @param  end  End of string to parse.
  3039.        *  @param  io  Source of the locale.
  3040.        *  @param  err  Error flags to set.
  3041.        *  @param  tm  Pointer to struct tm to fill in.
  3042.        *  @return  Iterator to first char beyond time string.
  3043.       */
  3044.       iter_type
  3045.       get_time(iter_type __beg, iter_type __end, ios_base& __io,
  3046.            ios_base::iostate& __err, tm* __tm)  const
  3047.       { return this->do_get_time(__beg, __end, __io, __err, __tm); }
  3048.  
  3049.       /**
  3050.        *  @brief  Parse input date string.
  3051.        *
  3052.        *  This function parses a date according to the format "X" and puts the
  3053.        *  results into a user-supplied struct tm.  The result is returned by
  3054.        *  calling time_get::do_get_date().
  3055.        *
  3056.        *  If there is a valid date string according to format "X", @a tm will
  3057.        *  be filled in accordingly and the returned iterator will point to the
  3058.        *  first character beyond the date string.  If an error occurs before
  3059.        *  the end, err |= ios_base::failbit.  If parsing reads all the
  3060.        *  characters, err |= ios_base::eofbit.
  3061.        *
  3062.        *  @param  beg  Start of string to parse.
  3063.        *  @param  end  End of string to parse.
  3064.        *  @param  io  Source of the locale.
  3065.        *  @param  err  Error flags to set.
  3066.        *  @param  tm  Pointer to struct tm to fill in.
  3067.        *  @return  Iterator to first char beyond date string.
  3068.       */
  3069.       iter_type
  3070.       get_date(iter_type __beg, iter_type __end, ios_base& __io,
  3071.            ios_base::iostate& __err, tm* __tm)  const
  3072.       { return this->do_get_date(__beg, __end, __io, __err, __tm); }
  3073.  
  3074.       /**
  3075.        *  @brief  Parse input weekday string.
  3076.        *
  3077.        *  This function parses a weekday name and puts the results into a
  3078.        *  user-supplied struct tm.  The result is returned by calling
  3079.        *  time_get::do_get_weekday().
  3080.        *
  3081.        *  Parsing starts by parsing an abbreviated weekday name.  If a valid
  3082.        *  abbreviation is followed by a character that would lead to the full
  3083.        *  weekday name, parsing continues until the full name is found or an
  3084.        *  error occurs.  Otherwise parsing finishes at the end of the
  3085.        *  abbreviated name.
  3086.        *
  3087.        *  If an error occurs before the end, err |= ios_base::failbit.  If
  3088.        *  parsing reads all the characters, err |= ios_base::eofbit.
  3089.        *
  3090.        *  @param  beg  Start of string to parse.
  3091.        *  @param  end  End of string to parse.
  3092.        *  @param  io  Source of the locale.
  3093.        *  @param  err  Error flags to set.
  3094.        *  @param  tm  Pointer to struct tm to fill in.
  3095.        *  @return  Iterator to first char beyond weekday name.
  3096.       */
  3097.       iter_type
  3098.       get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
  3099.           ios_base::iostate& __err, tm* __tm) const
  3100.       { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
  3101.  
  3102.       /**
  3103.        *  @brief  Parse input month string.
  3104.        *
  3105.        *  This function parses a month name and puts the results into a
  3106.        *  user-supplied struct tm.  The result is returned by calling
  3107.        *  time_get::do_get_monthname().
  3108.        *
  3109.        *  Parsing starts by parsing an abbreviated month name.  If a valid
  3110.        *  abbreviation is followed by a character that would lead to the full
  3111.        *  month name, parsing continues until the full name is found or an
  3112.        *  error occurs.  Otherwise parsing finishes at the end of the
  3113.        *  abbreviated name.
  3114.        *
  3115.        *  If an error occurs before the end, err |= ios_base::failbit.  If
  3116.        *  parsing reads all the characters, err |=
  3117.        *  ios_base::eofbit.
  3118.        *
  3119.        *  @param  beg  Start of string to parse.
  3120.        *  @param  end  End of string to parse.
  3121.        *  @param  io  Source of the locale.
  3122.        *  @param  err  Error flags to set.
  3123.        *  @param  tm  Pointer to struct tm to fill in.
  3124.        *  @return  Iterator to first char beyond month name.
  3125.       */
  3126.       iter_type
  3127.       get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
  3128.             ios_base::iostate& __err, tm* __tm) const
  3129.       { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
  3130.  
  3131.       /**
  3132.        *  @brief  Parse input year string.
  3133.        *
  3134.        *  This function reads up to 4 characters to parse a year string and
  3135.        *  puts the results into a user-supplied struct tm.  The result is
  3136.        *  returned by calling time_get::do_get_year().
  3137.        *
  3138.        *  4 consecutive digits are interpreted as a full year.  If there are
  3139.        *  exactly 2 consecutive digits, the library interprets this as the
  3140.        *  number of years since 1900.
  3141.        *
  3142.        *  If an error occurs before the end, err |= ios_base::failbit.  If
  3143.        *  parsing reads all the characters, err |= ios_base::eofbit.
  3144.        *
  3145.        *  @param  beg  Start of string to parse.
  3146.        *  @param  end  End of string to parse.
  3147.        *  @param  io  Source of the locale.
  3148.        *  @param  err  Error flags to set.
  3149.        *  @param  tm  Pointer to struct tm to fill in.
  3150.        *  @return  Iterator to first char beyond year.
  3151.       */
  3152.       iter_type
  3153.       get_year(iter_type __beg, iter_type __end, ios_base& __io,
  3154.            ios_base::iostate& __err, tm* __tm) const
  3155.       { return this->do_get_year(__beg, __end, __io, __err, __tm); }
  3156.  
  3157.     protected:
  3158.       /// Destructor.
  3159.       virtual
  3160.       ~time_get() { }
  3161.  
  3162.       /**
  3163.        *  @brief  Return preferred order of month, day, and year.
  3164.        *
  3165.        *  This function returns an enum from timebase::dateorder giving the
  3166.        *  preferred ordering if the format "x" given to time_put::put() only
  3167.        *  uses month, day, and year.  This function is a hook for derived
  3168.        *  classes to change the value returned.
  3169.        *
  3170.        *  @return  A member of timebase::dateorder.
  3171.       */
  3172.       virtual dateorder
  3173.       do_date_order() const;
  3174.  
  3175.       /**
  3176.        *  @brief  Parse input time string.
  3177.        *
  3178.        *  This function parses a time according to the format "x" and puts the
  3179.        *  results into a user-supplied struct tm.  This function is a hook for
  3180.        *  derived classes to change the value returned.  @see get_time() for
  3181.        *  details.
  3182.        *
  3183.        *  @param  beg  Start of string to parse.
  3184.        *  @param  end  End of string to parse.
  3185.        *  @param  io  Source of the locale.
  3186.        *  @param  err  Error flags to set.
  3187.        *  @param  tm  Pointer to struct tm to fill in.
  3188.        *  @return  Iterator to first char beyond time string.
  3189.       */
  3190.       virtual iter_type
  3191.       do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
  3192.           ios_base::iostate& __err, tm* __tm) const;
  3193.  
  3194.       /**
  3195.        *  @brief  Parse input date string.
  3196.        *
  3197.        *  This function parses a date according to the format "X" and puts the
  3198.        *  results into a user-supplied struct tm.  This function is a hook for
  3199.        *  derived classes to change the value returned.  @see get_date() for
  3200.        *  details.
  3201.        *
  3202.        *  @param  beg  Start of string to parse.
  3203.        *  @param  end  End of string to parse.
  3204.        *  @param  io  Source of the locale.
  3205.        *  @param  err  Error flags to set.
  3206.        *  @param  tm  Pointer to struct tm to fill in.
  3207.        *  @return  Iterator to first char beyond date string.
  3208.       */
  3209.       virtual iter_type
  3210.       do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
  3211.           ios_base::iostate& __err, tm* __tm) const;
  3212.  
  3213.       /**
  3214.        *  @brief  Parse input weekday string.
  3215.        *
  3216.        *  This function parses a weekday name and puts the results into a
  3217.        *  user-supplied struct tm.  This function is a hook for derived
  3218.        *  classes to change the value returned.  @see get_weekday() for
  3219.        *  details.
  3220.        *
  3221.        *  @param  beg  Start of string to parse.
  3222.        *  @param  end  End of string to parse.
  3223.        *  @param  io  Source of the locale.
  3224.        *  @param  err  Error flags to set.
  3225.        *  @param  tm  Pointer to struct tm to fill in.
  3226.        *  @return  Iterator to first char beyond weekday name.
  3227.       */
  3228.       virtual iter_type
  3229.       do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
  3230.              ios_base::iostate& __err, tm* __tm) const;
  3231.  
  3232.       /**
  3233.        *  @brief  Parse input month string.
  3234.        *
  3235.        *  This function parses a month name and puts the results into a
  3236.        *  user-supplied struct tm.  This function is a hook for derived
  3237.        *  classes to change the value returned.  @see get_monthname() for
  3238.        *  details.
  3239.        *
  3240.        *  @param  beg  Start of string to parse.
  3241.        *  @param  end  End of string to parse.
  3242.        *  @param  io  Source of the locale.
  3243.        *  @param  err  Error flags to set.
  3244.        *  @param  tm  Pointer to struct tm to fill in.
  3245.        *  @return  Iterator to first char beyond month name.
  3246.       */
  3247.       virtual iter_type
  3248.       do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
  3249.                ios_base::iostate& __err, tm* __tm) const;
  3250.  
  3251.       /**
  3252.        *  @brief  Parse input year string.
  3253.        *
  3254.        *  This function reads up to 4 characters to parse a year string and
  3255.        *  puts the results into a user-supplied struct tm.  This function is a
  3256.        *  hook for derived classes to change the value returned.  @see
  3257.        *  get_year() for details.
  3258.        *
  3259.        *  @param  beg  Start of string to parse.
  3260.        *  @param  end  End of string to parse.
  3261.        *  @param  io  Source of the locale.
  3262.        *  @param  err  Error flags to set.
  3263.        *  @param  tm  Pointer to struct tm to fill in.
  3264.        *  @return  Iterator to first char beyond year.
  3265.       */
  3266.       virtual iter_type
  3267.       do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
  3268.           ios_base::iostate& __err, tm* __tm) const;
  3269.  
  3270.       // Extract numeric component of length __len.
  3271.       iter_type
  3272.       _M_extract_num(iter_type __beg, iter_type __end, int& __member,
  3273.              int __min, int __max, size_t __len,
  3274.              ios_base& __io, ios_base::iostate& __err) const;
  3275.  
  3276.       // Extract day or month name, or any unique array of string
  3277.       // literals in a const _CharT* array.
  3278.       iter_type
  3279.       _M_extract_name(iter_type __beg, iter_type __end, int& __member,
  3280.               const _CharT** __names, size_t __indexlen,
  3281.               ios_base& __io, ios_base::iostate& __err) const;
  3282.  
  3283.       // Extract on a component-by-component basis, via __format argument.
  3284.       iter_type
  3285.       _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
  3286.                 ios_base::iostate& __err, tm* __tm,
  3287.                 const _CharT* __format) const;
  3288.     };
  3289.  
  3290.   template<typename _CharT, typename _InIter>
  3291.     locale::id time_get<_CharT, _InIter>::id;
  3292.  
  3293.   template<typename _CharT, typename _InIter>
  3294.     class time_get_byname : public time_get<_CharT, _InIter>
  3295.     {
  3296.     public:
  3297.       // Types:
  3298.       typedef _CharT            char_type;
  3299.       typedef _InIter            iter_type;
  3300.  
  3301.       explicit
  3302.       time_get_byname(const char*, size_t __refs = 0)
  3303.       : time_get<_CharT, _InIter>(__refs) { }
  3304.  
  3305.     protected:
  3306.       virtual
  3307.       ~time_get_byname() { }
  3308.     };
  3309.  
  3310.   /**
  3311.    *  @brief  Facet for outputting dates and times.
  3312.    *
  3313.    *  This facet encapsulates the code to format and output dates and times
  3314.    *  according to formats used by strftime().
  3315.    *
  3316.    *  The time_put template uses protected virtual functions to provide the
  3317.    *  actual results.  The public accessors forward the call to the virtual
  3318.    *  functions.  These virtual functions are hooks for developers to
  3319.    *  implement the behavior they require from the time_put facet.
  3320.   */
  3321.   template<typename _CharT, typename _OutIter>
  3322.     class time_put : public locale::facet
  3323.     {
  3324.     public:
  3325.       // Types:
  3326.       //@{
  3327.       /// Public typedefs
  3328.       typedef _CharT            char_type;
  3329.       typedef _OutIter            iter_type;
  3330.       //@}
  3331.  
  3332.       /// Numpunct facet id.
  3333.       static locale::id            id;
  3334.  
  3335.       /**
  3336.        *  @brief  Constructor performs initialization.
  3337.        *
  3338.        *  This is the constructor provided by the standard.
  3339.        *
  3340.        *  @param refs  Passed to the base facet class.
  3341.       */
  3342.       explicit
  3343.       time_put(size_t __refs = 0)
  3344.       : facet(__refs) { }
  3345.  
  3346.       /**
  3347.        *  @brief  Format and output a time or date.
  3348.        *
  3349.        *  This function formats the data in struct tm according to the
  3350.        *  provided format string.  The format string is interpreted as by
  3351.        *  strftime().
  3352.        *
  3353.        *  @param  s  The stream to write to.
  3354.        *  @param  io  Source of locale.
  3355.        *  @param  fill  char_type to use for padding.
  3356.        *  @param  tm  Struct tm with date and time info to format.
  3357.        *  @param  beg  Start of format string.
  3358.        *  @param  end  End of format string.
  3359.        *  @return  Iterator after writing.
  3360.        */
  3361.       iter_type
  3362.       put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
  3363.       const _CharT* __beg, const _CharT* __end) const;
  3364.  
  3365.       /**
  3366.        *  @brief  Format and output a time or date.
  3367.        *
  3368.        *  This function formats the data in struct tm according to the
  3369.        *  provided format char and optional modifier.  The format and modifier
  3370.        *  are interpreted as by strftime().  It does so by returning
  3371.        *  time_put::do_put().
  3372.        *
  3373.        *  @param  s  The stream to write to.
  3374.        *  @param  io  Source of locale.
  3375.        *  @param  fill  char_type to use for padding.
  3376.        *  @param  tm  Struct tm with date and time info to format.
  3377.        *  @param  format  Format char.
  3378.        *  @param  mod  Optional modifier char.
  3379.        *  @return  Iterator after writing.
  3380.        */
  3381.       iter_type
  3382.       put(iter_type __s, ios_base& __io, char_type __fill,
  3383.       const tm* __tm, char __format, char __mod = 0) const
  3384.       { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
  3385.  
  3386.     protected:
  3387.       /// Destructor.
  3388.       virtual
  3389.       ~time_put()
  3390.       { }
  3391.  
  3392.       /**
  3393.        *  @brief  Format and output a time or date.
  3394.        *
  3395.        *  This function formats the data in struct tm according to the
  3396.        *  provided format char and optional modifier.  This function is a hook
  3397.        *  for derived classes to change the value returned.  @see put() for
  3398.        *  more details.
  3399.        *
  3400.        *  @param  s  The stream to write to.
  3401.        *  @param  io  Source of locale.
  3402.        *  @param  fill  char_type to use for padding.
  3403.        *  @param  tm  Struct tm with date and time info to format.
  3404.        *  @param  format  Format char.
  3405.        *  @param  mod  Optional modifier char.
  3406.        *  @return  Iterator after writing.
  3407.        */
  3408.       virtual iter_type
  3409.       do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
  3410.          char __format, char __mod) const;
  3411.     };
  3412.  
  3413.   template<typename _CharT, typename _OutIter>
  3414.     locale::id time_put<_CharT, _OutIter>::id;
  3415.  
  3416.   template<typename _CharT, typename _OutIter>
  3417.     class time_put_byname : public time_put<_CharT, _OutIter>
  3418.     {
  3419.     public:
  3420.       // Types:
  3421.       typedef _CharT            char_type;
  3422.       typedef _OutIter            iter_type;
  3423.  
  3424.       explicit
  3425.       time_put_byname(const char*, size_t __refs = 0)
  3426.       : time_put<_CharT, _OutIter>(__refs)
  3427.       { };
  3428.  
  3429.     protected:
  3430.       virtual
  3431.       ~time_put_byname() { }
  3432.     };
  3433.  
  3434.  
  3435.   /**
  3436.    *  @brief  Money format ordering data.
  3437.    *
  3438.    *  This class contains an ordered array of 4 fields to represent the
  3439.    *  pattern for formatting a money amount.  Each field may contain one entry
  3440.    *  from the part enum.  symbol, sign, and value must be present and the
  3441.    *  remaining field must contain either none or space.  @see
  3442.    *  moneypunct::pos_format() and moneypunct::neg_format() for details of how
  3443.    *  these fields are interpreted.
  3444.   */
  3445.   class money_base
  3446.   {
  3447.   public:
  3448.     enum part { none, space, symbol, sign, value };
  3449.     struct pattern { char field[4]; };
  3450.  
  3451.     static const pattern _S_default_pattern;
  3452.  
  3453.     enum
  3454.     {
  3455.       _S_minus,
  3456.       _S_zero,
  3457.       _S_end = 11
  3458.     };
  3459.  
  3460.     // String literal of acceptable (narrow) input/output, for
  3461.     // money_get/money_put. "-0123456789"
  3462.     static const char* _S_atoms;
  3463.  
  3464.     // Construct and return valid pattern consisting of some combination of:
  3465.     // space none symbol sign value
  3466.     static pattern
  3467.     _S_construct_pattern(char __precedes, char __space, char __posn);
  3468.   };
  3469.  
  3470.   template<typename _CharT, bool _Intl>
  3471.     struct __moneypunct_cache : public locale::facet
  3472.     {
  3473.       const char*            _M_grouping;
  3474.       size_t                            _M_grouping_size;
  3475.       bool                _M_use_grouping;
  3476.       _CharT                _M_decimal_point;
  3477.       _CharT                _M_thousands_sep;
  3478.       const _CharT*            _M_curr_symbol;
  3479.       size_t                            _M_curr_symbol_size;
  3480.       const _CharT*            _M_positive_sign;
  3481.       size_t                            _M_positive_sign_size;
  3482.       const _CharT*            _M_negative_sign;
  3483.       size_t                            _M_negative_sign_size;
  3484.       int                _M_frac_digits;
  3485.       money_base::pattern        _M_pos_format;
  3486.       money_base::pattern            _M_neg_format;
  3487.  
  3488.       // A list of valid numeric literals for input and output: in the standard
  3489.       // "C" locale, this is "-0123456789". This array contains the chars after
  3490.       // having been passed through the current locale's ctype<_CharT>.widen().
  3491.       _CharT                _M_atoms[money_base::_S_end];
  3492.  
  3493.       bool                _M_allocated;
  3494.  
  3495.       __moneypunct_cache(size_t __refs = 0) : facet(__refs),
  3496.       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
  3497.       _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),
  3498.       _M_curr_symbol(NULL), _M_curr_symbol_size(0),
  3499.       _M_positive_sign(NULL), _M_positive_sign_size(0),
  3500.       _M_negative_sign(NULL), _M_negative_sign_size(0),
  3501.       _M_frac_digits(0),
  3502.       _M_pos_format(money_base::pattern()),
  3503.       _M_neg_format(money_base::pattern()), _M_allocated(false)
  3504.       { }
  3505.  
  3506.       ~__moneypunct_cache();
  3507.  
  3508.       void
  3509.       _M_cache(const locale& __loc);
  3510.  
  3511.     private:
  3512.       __moneypunct_cache&
  3513.       operator=(const __moneypunct_cache&);
  3514.       
  3515.       explicit
  3516.       __moneypunct_cache(const __moneypunct_cache&);
  3517.     };
  3518.  
  3519.   template<typename _CharT, bool _Intl>
  3520.     __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache()
  3521.     {
  3522.       if (_M_allocated)
  3523.     {
  3524.       delete [] _M_grouping;
  3525.       delete [] _M_curr_symbol;
  3526.       delete [] _M_positive_sign;
  3527.       delete [] _M_negative_sign;
  3528.     }
  3529.     }
  3530.  
  3531.   /**
  3532.    *  @brief  Facet for formatting data for money amounts.
  3533.    *
  3534.    *  This facet encapsulates the punctuation, grouping and other formatting
  3535.    *  features of money amount string representations.
  3536.   */
  3537.   template<typename _CharT, bool _Intl>
  3538.     class moneypunct : public locale::facet, public money_base
  3539.     {
  3540.     public:
  3541.       // Types:
  3542.       //@{
  3543.       /// Public typedefs
  3544.       typedef _CharT            char_type;
  3545.       typedef basic_string<_CharT>    string_type;
  3546.       //@}
  3547.       typedef __moneypunct_cache<_CharT, _Intl>     __cache_type;
  3548.  
  3549.     private:
  3550.       __cache_type*            _M_data;
  3551.  
  3552.     public:
  3553.       /// This value is provided by the standard, but no reason for its
  3554.       /// existence.
  3555.       static const bool            intl = _Intl;
  3556.       /// Numpunct facet id.
  3557.       static locale::id            id;
  3558.  
  3559.       /**
  3560.        *  @brief  Constructor performs initialization.
  3561.        *
  3562.        *  This is the constructor provided by the standard.
  3563.        *
  3564.        *  @param refs  Passed to the base facet class.
  3565.       */
  3566.       explicit
  3567.       moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
  3568.       { _M_initialize_moneypunct(); }
  3569.  
  3570.       /**
  3571.        *  @brief  Constructor performs initialization.
  3572.        *
  3573.        *  This is an internal constructor.
  3574.        *
  3575.        *  @param cache  Cache for optimization.
  3576.        *  @param refs  Passed to the base facet class.
  3577.       */
  3578.       explicit
  3579.       moneypunct(__cache_type* __cache, size_t __refs = 0)
  3580.       : facet(__refs), _M_data(__cache)
  3581.       { _M_initialize_moneypunct(); }
  3582.  
  3583.       /**
  3584.        *  @brief  Internal constructor. Not for general use.
  3585.        *
  3586.        *  This is a constructor for use by the library itself to set up new
  3587.        *  locales.
  3588.        *
  3589.        *  @param cloc  The "C" locale.
  3590.        *  @param s  The name of a locale.
  3591.        *  @param refs  Passed to the base facet class.
  3592.       */
  3593.       explicit
  3594.       moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
  3595.       : facet(__refs), _M_data(NULL)
  3596.       { _M_initialize_moneypunct(__cloc, __s); }
  3597.  
  3598.       /**
  3599.        *  @brief  Return decimal point character.
  3600.        *
  3601.        *  This function returns a char_type to use as a decimal point.  It
  3602.        *  does so by returning returning
  3603.        *  moneypunct<char_type>::do_decimal_point().
  3604.        *
  3605.        *  @return  @a char_type representing a decimal point.
  3606.       */
  3607.       char_type
  3608.       decimal_point() const
  3609.       { return this->do_decimal_point(); }
  3610.  
  3611.       /**
  3612.        *  @brief  Return thousands separator character.
  3613.        *
  3614.        *  This function returns a char_type to use as a thousands
  3615.        *  separator.  It does so by returning returning
  3616.        *  moneypunct<char_type>::do_thousands_sep().
  3617.        *
  3618.        *  @return  char_type representing a thousands separator.
  3619.       */
  3620.       char_type
  3621.       thousands_sep() const
  3622.       { return this->do_thousands_sep(); }
  3623.  
  3624.       /**
  3625.        *  @brief  Return grouping specification.
  3626.        *
  3627.        *  This function returns a string representing groupings for the
  3628.        *  integer part of an amount.  Groupings indicate where thousands
  3629.        *  separators should be inserted.
  3630.        *
  3631.        *  Each char in the return string is interpret as an integer rather
  3632.        *  than a character.  These numbers represent the number of digits in a
  3633.        *  group.  The first char in the string represents the number of digits
  3634.        *  in the least significant group.  If a char is negative, it indicates
  3635.        *  an unlimited number of digits for the group.  If more chars from the
  3636.        *  string are required to group a number, the last char is used
  3637.        *  repeatedly.
  3638.        *
  3639.        *  For example, if the grouping() returns "\003\002" and is applied to
  3640.        *  the number 123456789, this corresponds to 12,34,56,789.  Note that
  3641.        *  if the string was "32", this would put more than 50 digits into the
  3642.        *  least significant group if the character set is ASCII.
  3643.        *
  3644.        *  The string is returned by calling
  3645.        *  moneypunct<char_type>::do_grouping().
  3646.        *
  3647.        *  @return  string representing grouping specification.
  3648.       */
  3649.       string
  3650.       grouping() const
  3651.       { return this->do_grouping(); }
  3652.  
  3653.       /**
  3654.        *  @brief  Return currency symbol string.
  3655.        *
  3656.        *  This function returns a string_type to use as a currency symbol.  It
  3657.        *  does so by returning returning
  3658.        *  moneypunct<char_type>::do_curr_symbol().
  3659.        *
  3660.        *  @return  @a string_type representing a currency symbol.
  3661.       */
  3662.       string_type
  3663.       curr_symbol() const
  3664.       { return this->do_curr_symbol(); }
  3665.  
  3666.       /**
  3667.        *  @brief  Return positive sign string.
  3668.        *
  3669.        *  This function returns a string_type to use as a sign for positive
  3670.        *  amounts.  It does so by returning returning
  3671.        *  moneypunct<char_type>::do_positive_sign().
  3672.        *
  3673.        *  If the return value contains more than one character, the first
  3674.        *  character appears in the position indicated by pos_format() and the
  3675.        *  remainder appear at the end of the formatted string.
  3676.        *
  3677.        *  @return  @a string_type representing a positive sign.
  3678.       */
  3679.       string_type
  3680.       positive_sign() const
  3681.       { return this->do_positive_sign(); }
  3682.  
  3683.       /**
  3684.        *  @brief  Return negative sign string.
  3685.        *
  3686.        *  This function returns a string_type to use as a sign for negative
  3687.        *  amounts.  It does so by returning returning
  3688.        *  moneypunct<char_type>::do_negative_sign().
  3689.        *
  3690.        *  If the return value contains more than one character, the first
  3691.        *  character appears in the position indicated by neg_format() and the
  3692.        *  remainder appear at the end of the formatted string.
  3693.        *
  3694.        *  @return  @a string_type representing a negative sign.
  3695.       */
  3696.       string_type
  3697.       negative_sign() const
  3698.       { return this->do_negative_sign(); }
  3699.  
  3700.       /**
  3701.        *  @brief  Return number of digits in fraction.
  3702.        *
  3703.        *  This function returns the exact number of digits that make up the
  3704.        *  fractional part of a money amount.  It does so by returning
  3705.        *  returning moneypunct<char_type>::do_frac_digits().
  3706.        *
  3707.        *  The fractional part of a money amount is optional.  But if it is
  3708.        *  present, there must be frac_digits() digits.
  3709.        *
  3710.        *  @return  Number of digits in amount fraction.
  3711.       */
  3712.       int
  3713.       frac_digits() const
  3714.       { return this->do_frac_digits(); }
  3715.  
  3716.       //@{
  3717.       /**
  3718.        *  @brief  Return pattern for money values.
  3719.        *
  3720.        *  This function returns a pattern describing the formatting of a
  3721.        *  positive or negative valued money amount.  It does so by returning
  3722.        *  returning moneypunct<char_type>::do_pos_format() or
  3723.        *  moneypunct<char_type>::do_neg_format().
  3724.        *
  3725.        *  The pattern has 4 fields describing the ordering of symbol, sign,
  3726.        *  value, and none or space.  There must be one of each in the pattern.
  3727.        *  The none and space enums may not appear in the first field and space
  3728.        *  may not appear in the final field.
  3729.        *
  3730.        *  The parts of a money string must appear in the order indicated by
  3731.        *  the fields of the pattern.  The symbol field indicates that the
  3732.        *  value of curr_symbol() may be present.  The sign field indicates
  3733.        *  that the value of positive_sign() or negative_sign() must be
  3734.        *  present.  The value field indicates that the absolute value of the
  3735.        *  money amount is present.  none indicates 0 or more whitespace
  3736.        *  characters, except at the end, where it permits no whitespace.
  3737.        *  space indicates that 1 or more whitespace characters must be
  3738.        *  present.
  3739.        *
  3740.        *  For example, for the US locale and pos_format() pattern
  3741.        *  {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() ==
  3742.        *  '+', and value 10.01, and options set to force the symbol, the
  3743.        *  corresponding string is "$+10.01".
  3744.        *
  3745.        *  @return  Pattern for money values.
  3746.       */
  3747.       pattern
  3748.       pos_format() const
  3749.       { return this->do_pos_format(); }
  3750.  
  3751.       pattern
  3752.       neg_format() const
  3753.       { return this->do_neg_format(); }
  3754.       //@}
  3755.  
  3756.     protected:
  3757.       /// Destructor.
  3758.       virtual
  3759.       ~moneypunct();
  3760.  
  3761.       /**
  3762.        *  @brief  Return decimal point character.
  3763.        *
  3764.        *  Returns a char_type to use as a decimal point.  This function is a
  3765.        *  hook for derived classes to change the value returned.
  3766.        *
  3767.        *  @return  @a char_type representing a decimal point.
  3768.       */
  3769.       virtual char_type
  3770.       do_decimal_point() const
  3771.       { return _M_data->_M_decimal_point; }
  3772.  
  3773.       /**
  3774.        *  @brief  Return thousands separator character.
  3775.        *
  3776.        *  Returns a char_type to use as a thousands separator.  This function
  3777.        *  is a hook for derived classes to change the value returned.
  3778.        *
  3779.        *  @return  @a char_type representing a thousands separator.
  3780.       */
  3781.       virtual char_type
  3782.       do_thousands_sep() const
  3783.       { return _M_data->_M_thousands_sep; }
  3784.  
  3785.       /**
  3786.        *  @brief  Return grouping specification.
  3787.        *
  3788.        *  Returns a string representing groupings for the integer part of a
  3789.        *  number.  This function is a hook for derived classes to change the
  3790.        *  value returned.  @see grouping() for details.
  3791.        *
  3792.        *  @return  String representing grouping specification.
  3793.       */
  3794.       virtual string
  3795.       do_grouping() const
  3796.       { return _M_data->_M_grouping; }
  3797.  
  3798.       /**
  3799.        *  @brief  Return currency symbol string.
  3800.        *
  3801.        *  This function returns a string_type to use as a currency symbol.
  3802.        *  This function is a hook for derived classes to change the value
  3803.        *  returned.  @see curr_symbol() for details.
  3804.        *
  3805.        *  @return  @a string_type representing a currency symbol.
  3806.       */
  3807.       virtual string_type
  3808.       do_curr_symbol()   const
  3809.       { return _M_data->_M_curr_symbol; }
  3810.  
  3811.       /**
  3812.        *  @brief  Return positive sign string.
  3813.        *
  3814.        *  This function returns a string_type to use as a sign for positive
  3815.        *  amounts.  This function is a hook for derived classes to change the
  3816.        *  value returned.  @see positive_sign() for details.
  3817.        *
  3818.        *  @return  @a string_type representing a positive sign.
  3819.       */
  3820.       virtual string_type
  3821.       do_positive_sign() const
  3822.       { return _M_data->_M_positive_sign; }
  3823.  
  3824.       /**
  3825.        *  @brief  Return negative sign string.
  3826.        *
  3827.        *  This function returns a string_type to use as a sign for negative
  3828.        *  amounts.  This function is a hook for derived classes to change the
  3829.        *  value returned.  @see negative_sign() for details.
  3830.        *
  3831.        *  @return  @a string_type representing a negative sign.
  3832.       */
  3833.       virtual string_type
  3834.       do_negative_sign() const
  3835.       { return _M_data->_M_negative_sign; }
  3836.  
  3837.       /**
  3838.        *  @brief  Return number of digits in fraction.
  3839.        *
  3840.        *  This function returns the exact number of digits that make up the
  3841.        *  fractional part of a money amount.  This function is a hook for
  3842.        *  derived classes to change the value returned.  @see frac_digits()
  3843.        *  for details.
  3844.        *
  3845.        *  @return  Number of digits in amount fraction.
  3846.       */
  3847.       virtual int
  3848.       do_frac_digits() const
  3849.       { return _M_data->_M_frac_digits; }
  3850.  
  3851.       /**
  3852.        *  @brief  Return pattern for money values.
  3853.        *
  3854.        *  This function returns a pattern describing the formatting of a
  3855.        *  positive valued money amount.  This function is a hook for derived
  3856.        *  classes to change the value returned.  @see pos_format() for
  3857.        *  details.
  3858.        *
  3859.        *  @return  Pattern for money values.
  3860.       */
  3861.       virtual pattern
  3862.       do_pos_format() const
  3863.       { return _M_data->_M_pos_format; }
  3864.  
  3865.       /**
  3866.        *  @brief  Return pattern for money values.
  3867.        *
  3868.        *  This function returns a pattern describing the formatting of a
  3869.        *  negative valued money amount.  This function is a hook for derived
  3870.        *  classes to change the value returned.  @see neg_format() for
  3871.        *  details.
  3872.        *
  3873.        *  @return  Pattern for money values.
  3874.       */
  3875.       virtual pattern
  3876.       do_neg_format() const
  3877.       { return _M_data->_M_neg_format; }
  3878.  
  3879.       // For use at construction time only.
  3880.        void
  3881.        _M_initialize_moneypunct(__c_locale __cloc = NULL,
  3882.                 const char* __name = NULL);
  3883.     };
  3884.  
  3885.   template<typename _CharT, bool _Intl>
  3886.     locale::id moneypunct<_CharT, _Intl>::id;
  3887.  
  3888.   template<typename _CharT, bool _Intl>
  3889.     const bool moneypunct<_CharT, _Intl>::intl;
  3890.  
  3891.   template<>
  3892.     moneypunct<char, true>::~moneypunct();
  3893.  
  3894.   template<>
  3895.     moneypunct<char, false>::~moneypunct();
  3896.  
  3897.   template<>
  3898.     void
  3899.     moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
  3900.  
  3901.   template<>
  3902.     void
  3903.     moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
  3904.  
  3905. #ifdef _GLIBCXX_USE_WCHAR_T
  3906.   template<>
  3907.     moneypunct<wchar_t, true>::~moneypunct();
  3908.  
  3909.   template<>
  3910.     moneypunct<wchar_t, false>::~moneypunct();
  3911.  
  3912.   template<>
  3913.     void
  3914.     moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
  3915.                             const char*);
  3916.  
  3917.   template<>
  3918.     void
  3919.     moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
  3920.                              const char*);
  3921. #endif
  3922.  
  3923.   template<typename _CharT, bool _Intl>
  3924.     class moneypunct_byname : public moneypunct<_CharT, _Intl>
  3925.     {
  3926.     public:
  3927.       typedef _CharT            char_type;
  3928.       typedef basic_string<_CharT>    string_type;
  3929.  
  3930.       static const bool intl = _Intl;
  3931.  
  3932.       explicit
  3933.       moneypunct_byname(const char* __s, size_t __refs = 0)
  3934.       : moneypunct<_CharT, _Intl>(__refs)
  3935.       {
  3936.     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
  3937.       {
  3938.         __c_locale __tmp;
  3939.         this->_S_create_c_locale(__tmp, __s);
  3940.         this->_M_initialize_moneypunct(__tmp);
  3941.         this->_S_destroy_c_locale(__tmp);
  3942.       }
  3943.       }
  3944.  
  3945.     protected:
  3946.       virtual
  3947.       ~moneypunct_byname() { }
  3948.     };
  3949.  
  3950.   template<typename _CharT, bool _Intl>
  3951.     const bool moneypunct_byname<_CharT, _Intl>::intl;
  3952.  
  3953.   /**
  3954.    *  @brief  Facet for parsing monetary amounts.
  3955.    *
  3956.    *  This facet encapsulates the code to parse and return a monetary
  3957.    *  amount from a string.
  3958.    *
  3959.    *  The money_get template uses protected virtual functions to
  3960.    *  provide the actual results.  The public accessors forward the
  3961.    *  call to the virtual functions.  These virtual functions are
  3962.    *  hooks for developers to implement the behavior they require from
  3963.    *  the money_get facet.
  3964.   */
  3965.   template<typename _CharT, typename _InIter>
  3966.     class money_get : public locale::facet
  3967.     {
  3968.     public:
  3969.       // Types:
  3970.       //@{
  3971.       /// Public typedefs
  3972.       typedef _CharT            char_type;
  3973.       typedef _InIter            iter_type;
  3974.       typedef basic_string<_CharT>    string_type;
  3975.       //@}
  3976.  
  3977.       /// Numpunct facet id.
  3978.       static locale::id            id;
  3979.  
  3980.       /**
  3981.        *  @brief  Constructor performs initialization.
  3982.        *
  3983.        *  This is the constructor provided by the standard.
  3984.        *
  3985.        *  @param refs  Passed to the base facet class.
  3986.       */
  3987.       explicit
  3988.       money_get(size_t __refs = 0) : facet(__refs) { }
  3989.  
  3990.       /**
  3991.        *  @brief  Read and parse a monetary value.
  3992.        *
  3993.        *  This function reads characters from @a s, interprets them as a
  3994.        *  monetary value according to moneypunct and ctype facets retrieved
  3995.        *  from io.getloc(), and returns the result in @a units as an integral
  3996.        *  value moneypunct::frac_digits() * the actual amount.  For example,
  3997.        *  the string $10.01 in a US locale would store 1001 in @a units.
  3998.        *
  3999.        *  Any characters not part of a valid money amount are not consumed.
  4000.        *
  4001.        *  If a money value cannot be parsed from the input stream, sets
  4002.        *  err=(err|io.failbit).  If the stream is consumed before finishing
  4003.        *  parsing,  sets err=(err|io.failbit|io.eofbit).  @a units is
  4004.        *  unchanged if parsing fails.
  4005.        *
  4006.        *  This function works by returning the result of do_get().
  4007.        *
  4008.        *  @param  s  Start of characters to parse.
  4009.        *  @param  end  End of characters to parse.
  4010.        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
  4011.        *  @param  io  Source of facets and io state.
  4012.        *  @param  err  Error field to set if parsing fails.
  4013.        *  @param  units  Place to store result of parsing.
  4014.        *  @return  Iterator referencing first character beyond valid money
  4015.        *       amount.
  4016.        */
  4017.       iter_type
  4018.       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
  4019.       ios_base::iostate& __err, long double& __units) const
  4020.       { return this->do_get(__s, __end, __intl, __io, __err, __units); }
  4021.  
  4022.       /**
  4023.        *  @brief  Read and parse a monetary value.
  4024.        *
  4025.        *  This function reads characters from @a s, interprets them as a
  4026.        *  monetary value according to moneypunct and ctype facets retrieved
  4027.        *  from io.getloc(), and returns the result in @a digits.  For example,
  4028.        *  the string $10.01 in a US locale would store "1001" in @a digits.
  4029.        *
  4030.        *  Any characters not part of a valid money amount are not consumed.
  4031.        *
  4032.        *  If a money value cannot be parsed from the input stream, sets
  4033.        *  err=(err|io.failbit).  If the stream is consumed before finishing
  4034.        *  parsing,  sets err=(err|io.failbit|io.eofbit).
  4035.        *
  4036.        *  This function works by returning the result of do_get().
  4037.        *
  4038.        *  @param  s  Start of characters to parse.
  4039.        *  @param  end  End of characters to parse.
  4040.        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
  4041.        *  @param  io  Source of facets and io state.
  4042.        *  @param  err  Error field to set if parsing fails.
  4043.        *  @param  digits  Place to store result of parsing.
  4044.        *  @return  Iterator referencing first character beyond valid money
  4045.        *       amount.
  4046.        */
  4047.       iter_type
  4048.       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
  4049.       ios_base::iostate& __err, string_type& __digits) const
  4050.       { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
  4051.  
  4052.     protected:
  4053.       /// Destructor.
  4054.       virtual
  4055.       ~money_get() { }
  4056.  
  4057.       /**
  4058.        *  @brief  Read and parse a monetary value.
  4059.        *
  4060.        *  This function reads and parses characters representing a monetary
  4061.        *  value.  This function is a hook for derived classes to change the
  4062.        *  value returned.  @see get() for details.
  4063.        */
  4064.       virtual iter_type
  4065.       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
  4066.          ios_base::iostate& __err, long double& __units) const;
  4067.  
  4068.       /**
  4069.        *  @brief  Read and parse a monetary value.
  4070.        *
  4071.        *  This function reads and parses characters representing a monetary
  4072.        *  value.  This function is a hook for derived classes to change the
  4073.        *  value returned.  @see get() for details.
  4074.        */
  4075.       virtual iter_type
  4076.       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
  4077.          ios_base::iostate& __err, string_type& __digits) const;
  4078.  
  4079.       template<bool _Intl>
  4080.         iter_type
  4081.         _M_extract(iter_type __s, iter_type __end, ios_base& __io,
  4082.            ios_base::iostate& __err, string& __digits) const;     
  4083.     };
  4084.  
  4085.   template<typename _CharT, typename _InIter>
  4086.     locale::id money_get<_CharT, _InIter>::id;
  4087.  
  4088.   /**
  4089.    *  @brief  Facet for outputting monetary amounts.
  4090.    *
  4091.    *  This facet encapsulates the code to format and output a monetary
  4092.    *  amount.
  4093.    *
  4094.    *  The money_put template uses protected virtual functions to
  4095.    *  provide the actual results.  The public accessors forward the
  4096.    *  call to the virtual functions.  These virtual functions are
  4097.    *  hooks for developers to implement the behavior they require from
  4098.    *  the money_put facet.
  4099.   */
  4100.   template<typename _CharT, typename _OutIter>
  4101.     class money_put : public locale::facet
  4102.     {
  4103.     public:
  4104.       //@{
  4105.       /// Public typedefs
  4106.       typedef _CharT            char_type;
  4107.       typedef _OutIter            iter_type;
  4108.       typedef basic_string<_CharT>    string_type;
  4109.       //@}
  4110.  
  4111.       /// Numpunct facet id.
  4112.       static locale::id            id;
  4113.  
  4114.       /**
  4115.        *  @brief  Constructor performs initialization.
  4116.        *
  4117.        *  This is the constructor provided by the standard.
  4118.        *
  4119.        *  @param refs  Passed to the base facet class.
  4120.       */
  4121.       explicit
  4122.       money_put(size_t __refs = 0) : facet(__refs) { }
  4123.  
  4124.       /**
  4125.        *  @brief  Format and output a monetary value.
  4126.        *
  4127.        *  This function formats @a units as a monetary value according to
  4128.        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
  4129.        *  the resulting characters to @a s.  For example, the value 1001 in a
  4130.        *  US locale would write "$10.01" to @a s.
  4131.        *
  4132.        *  This function works by returning the result of do_put().
  4133.        *
  4134.        *  @param  s  The stream to write to.
  4135.        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
  4136.        *  @param  io  Source of facets and io state.
  4137.        *  @param  fill  char_type to use for padding.
  4138.        *  @param  units  Place to store result of parsing.
  4139.        *  @return  Iterator after writing.
  4140.        */
  4141.       iter_type
  4142.       put(iter_type __s, bool __intl, ios_base& __io,
  4143.       char_type __fill, long double __units) const
  4144.       { return this->do_put(__s, __intl, __io, __fill, __units); }
  4145.  
  4146.       /**
  4147.        *  @brief  Format and output a monetary value.
  4148.        *
  4149.        *  This function formats @a digits as a monetary value according to
  4150.        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
  4151.        *  the resulting characters to @a s.  For example, the string "1001" in
  4152.        *  a US locale would write "$10.01" to @a s.
  4153.        *
  4154.        *  This function works by returning the result of do_put().
  4155.        *
  4156.        *  @param  s  The stream to write to.
  4157.        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
  4158.        *  @param  io  Source of facets and io state.
  4159.        *  @param  fill  char_type to use for padding.
  4160.        *  @param  units  Place to store result of parsing.
  4161.        *  @return  Iterator after writing.
  4162.        */
  4163.       iter_type
  4164.       put(iter_type __s, bool __intl, ios_base& __io,
  4165.       char_type __fill, const string_type& __digits) const
  4166.       { return this->do_put(__s, __intl, __io, __fill, __digits); }
  4167.  
  4168.     protected:
  4169.       /// Destructor.
  4170.       virtual
  4171.       ~money_put() { }
  4172.  
  4173.       /**
  4174.        *  @brief  Format and output a monetary value.
  4175.        *
  4176.        *  This function formats @a units as a monetary value according to
  4177.        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
  4178.        *  the resulting characters to @a s.  For example, the value 1001 in a
  4179.        *  US locale would write "$10.01" to @a s.
  4180.        *
  4181.        *  This function is a hook for derived classes to change the value
  4182.        *  returned.  @see put().
  4183.        *
  4184.        *  @param  s  The stream to write to.
  4185.        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
  4186.        *  @param  io  Source of facets and io state.
  4187.        *  @param  fill  char_type to use for padding.
  4188.        *  @param  units  Place to store result of parsing.
  4189.        *  @return  Iterator after writing.
  4190.        */
  4191.       virtual iter_type
  4192.       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  4193.          long double __units) const;
  4194.  
  4195.       /**
  4196.        *  @brief  Format and output a monetary value.
  4197.        *
  4198.        *  This function formats @a digits as a monetary value according to
  4199.        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
  4200.        *  the resulting characters to @a s.  For example, the string "1001" in
  4201.        *  a US locale would write "$10.01" to @a s.
  4202.        *
  4203.        *  This function is a hook for derived classes to change the value
  4204.        *  returned.  @see put().
  4205.        *
  4206.        *  @param  s  The stream to write to.
  4207.        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
  4208.        *  @param  io  Source of facets and io state.
  4209.        *  @param  fill  char_type to use for padding.
  4210.        *  @param  units  Place to store result of parsing.
  4211.        *  @return  Iterator after writing.
  4212.        */
  4213.       virtual iter_type
  4214.       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  4215.          const string_type& __digits) const;
  4216.  
  4217.       template<bool _Intl>
  4218.         iter_type
  4219.         _M_insert(iter_type __s, ios_base& __io, char_type __fill,
  4220.           const string_type& __digits) const;
  4221.     };
  4222.  
  4223.   template<typename _CharT, typename _OutIter>
  4224.     locale::id money_put<_CharT, _OutIter>::id;
  4225.  
  4226.   /**
  4227.    *  @brief  Messages facet base class providing catalog typedef.
  4228.    */
  4229.   struct messages_base
  4230.   {
  4231.     typedef int catalog;
  4232.   };
  4233.  
  4234.   /**
  4235.    *  @brief  Facet for handling message catalogs
  4236.    *
  4237.    *  This facet encapsulates the code to retrieve messages from
  4238.    *  message catalogs.  The only thing defined by the standard for this facet
  4239.    *  is the interface.  All underlying functionality is
  4240.    *  implementation-defined.
  4241.    *
  4242.    *  This library currently implements 3 versions of the message facet.  The
  4243.    *  first version (gnu) is a wrapper around gettext, provided by libintl.
  4244.    *  The second version (ieee) is a wrapper around catgets.  The final
  4245.    *  version (default) does no actual translation.  These implementations are
  4246.    *  only provided for char and wchar_t instantiations.
  4247.    *
  4248.    *  The messages template uses protected virtual functions to
  4249.    *  provide the actual results.  The public accessors forward the
  4250.    *  call to the virtual functions.  These virtual functions are
  4251.    *  hooks for developers to implement the behavior they require from
  4252.    *  the messages facet.
  4253.   */
  4254.   template<typename _CharT>
  4255.     class messages : public locale::facet, public messages_base
  4256.     {
  4257.     public:
  4258.       // Types:
  4259.       //@{
  4260.       /// Public typedefs
  4261.       typedef _CharT            char_type;
  4262.       typedef basic_string<_CharT>    string_type;
  4263.       //@}
  4264.  
  4265.     protected:
  4266.       // Underlying "C" library locale information saved from
  4267.       // initialization, needed by messages_byname as well.
  4268.       __c_locale            _M_c_locale_messages;
  4269.       const char*            _M_name_messages;
  4270.  
  4271.     public:
  4272.       /// Numpunct facet id.
  4273.       static locale::id            id;
  4274.  
  4275.       /**
  4276.        *  @brief  Constructor performs initialization.
  4277.        *
  4278.        *  This is the constructor provided by the standard.
  4279.        *
  4280.        *  @param refs  Passed to the base facet class.
  4281.       */
  4282.       explicit
  4283.       messages(size_t __refs = 0);
  4284.  
  4285.       // Non-standard.
  4286.       /**
  4287.        *  @brief  Internal constructor.  Not for general use.
  4288.        *
  4289.        *  This is a constructor for use by the library itself to set up new
  4290.        *  locales.
  4291.        *
  4292.        *  @param  cloc  The "C" locale.
  4293.        *  @param  s  The name of a locale.
  4294.        *  @param  refs  Refcount to pass to the base class.
  4295.        */
  4296.       explicit
  4297.       messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
  4298.  
  4299.       /*
  4300.        *  @brief  Open a message catalog.
  4301.        *
  4302.        *  This function opens and returns a handle to a message catalog by
  4303.        *  returning do_open(s, loc).
  4304.        *
  4305.        *  @param  s  The catalog to open.
  4306.        *  @param  loc  Locale to use for character set conversions.
  4307.        *  @return  Handle to the catalog or value < 0 if open fails.
  4308.       */
  4309.       catalog
  4310.       open(const basic_string<char>& __s, const locale& __loc) const
  4311.       { return this->do_open(__s, __loc); }
  4312.  
  4313.       // Non-standard and unorthodox, yet effective.
  4314.       /*
  4315.        *  @brief  Open a message catalog.
  4316.        *
  4317.        *  This non-standard function opens and returns a handle to a message
  4318.        *  catalog by returning do_open(s, loc).  The third argument provides a
  4319.        *  message catalog root directory for gnu gettext and is ignored
  4320.        *  otherwise.
  4321.        *
  4322.        *  @param  s  The catalog to open.
  4323.        *  @param  loc  Locale to use for character set conversions.
  4324.        *  @param  dir  Message catalog root directory.
  4325.        *  @return  Handle to the catalog or value < 0 if open fails.
  4326.       */
  4327.       catalog
  4328.       open(const basic_string<char>&, const locale&, const char*) const;
  4329.  
  4330.       /*
  4331.        *  @brief  Look up a string in a message catalog.
  4332.        *
  4333.        *  This function retrieves and returns a message from a catalog by
  4334.        *  returning do_get(c, set, msgid, s).
  4335.        *
  4336.        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
  4337.        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
  4338.        *
  4339.        *  @param  c  The catalog to access.
  4340.        *  @param  set  Implementation-defined.
  4341.        *  @param  msgid  Implementation-defined.
  4342.        *  @param  s  Default return value if retrieval fails.
  4343.        *  @return  Retrieved message or @a s if get fails.
  4344.       */
  4345.       string_type
  4346.       get(catalog __c, int __set, int __msgid, const string_type& __s) const
  4347.       { return this->do_get(__c, __set, __msgid, __s); }
  4348.  
  4349.       /*
  4350.        *  @brief  Close a message catalog.
  4351.        *
  4352.        *  Closes catalog @a c by calling do_close(c).
  4353.        *
  4354.        *  @param  c  The catalog to close.
  4355.       */
  4356.       void
  4357.       close(catalog __c) const
  4358.       { return this->do_close(__c); }
  4359.  
  4360.     protected:
  4361.       /// Destructor.
  4362.       virtual
  4363.       ~messages();
  4364.  
  4365.       /*
  4366.        *  @brief  Open a message catalog.
  4367.        *
  4368.        *  This function opens and returns a handle to a message catalog in an
  4369.        *  implementation-defined manner.  This function is a hook for derived
  4370.        *  classes to change the value returned.
  4371.        *
  4372.        *  @param  s  The catalog to open.
  4373.        *  @param  loc  Locale to use for character set conversions.
  4374.        *  @return  Handle to the opened catalog, value < 0 if open failed.
  4375.       */
  4376.       virtual catalog
  4377.       do_open(const basic_string<char>&, const locale&) const;
  4378.  
  4379.       /*
  4380.        *  @brief  Look up a string in a message catalog.
  4381.        *
  4382.        *  This function retrieves and returns a message from a catalog in an
  4383.        *  implementation-defined manner.  This function is a hook for derived
  4384.        *  classes to change the value returned.
  4385.        *
  4386.        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
  4387.        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
  4388.        *
  4389.        *  @param  c  The catalog to access.
  4390.        *  @param  set  Implementation-defined.
  4391.        *  @param  msgid  Implementation-defined.
  4392.        *  @param  s  Default return value if retrieval fails.
  4393.        *  @return  Retrieved message or @a s if get fails.
  4394.       */
  4395.       virtual string_type
  4396.       do_get(catalog, int, int, const string_type& __dfault) const;
  4397.  
  4398.       /*
  4399.        *  @brief  Close a message catalog.
  4400.        *
  4401.        *  @param  c  The catalog to close.
  4402.       */
  4403.       virtual void
  4404.       do_close(catalog) const;
  4405.  
  4406.       // Returns a locale and codeset-converted string, given a char* message.
  4407.       char*
  4408.       _M_convert_to_char(const string_type& __msg) const
  4409.       {
  4410.     // XXX
  4411.     return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
  4412.       }
  4413.  
  4414.       // Returns a locale and codeset-converted string, given a char* message.
  4415.       string_type
  4416.       _M_convert_from_char(char*) const
  4417.       {
  4418. #if 0
  4419.     // Length of message string without terminating null.
  4420.     size_t __len = char_traits<char>::length(__msg) - 1;
  4421.  
  4422.     // "everybody can easily convert the string using
  4423.     // mbsrtowcs/wcsrtombs or with iconv()"
  4424.  
  4425.     // Convert char* to _CharT in locale used to open catalog.
  4426.     // XXX need additional template parameter on messages class for this..
  4427.     // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
  4428.     typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
  4429.  
  4430.     __codecvt_type::state_type __state;
  4431.     // XXX may need to initialize state.
  4432.     //initialize_state(__state._M_init());
  4433.  
  4434.     char* __from_next;
  4435.     // XXX what size for this string?
  4436.     _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
  4437.     const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
  4438.     __cvt.out(__state, __msg, __msg + __len, __from_next,
  4439.           __to, __to + __len + 1, __to_next);
  4440.     return string_type(__to);
  4441. #endif
  4442. #if 0
  4443.     typedef ctype<_CharT> __ctype_type;
  4444.     // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
  4445.     const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
  4446.     // XXX Again, proper length of converted string an issue here.
  4447.     // For now, assume the converted length is not larger.
  4448.     _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
  4449.     __cvt.widen(__msg, __msg + __len, __dest);
  4450.     return basic_string<_CharT>(__dest);
  4451. #endif
  4452.     return string_type();
  4453.       }
  4454.      };
  4455.  
  4456.   template<typename _CharT>
  4457.     locale::id messages<_CharT>::id;
  4458.  
  4459.   // Specializations for required instantiations.
  4460.   template<>
  4461.     string
  4462.     messages<char>::do_get(catalog, int, int, const string&) const;
  4463.  
  4464. #ifdef _GLIBCXX_USE_WCHAR_T
  4465.   template<>
  4466.     wstring
  4467.     messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
  4468. #endif
  4469.  
  4470.   template<typename _CharT>
  4471.     class messages_byname : public messages<_CharT>
  4472.     {
  4473.     public:
  4474.       typedef _CharT            char_type;
  4475.       typedef basic_string<_CharT>    string_type;
  4476.  
  4477.       explicit
  4478.       messages_byname(const char* __s, size_t __refs = 0);
  4479.  
  4480.     protected:
  4481.       virtual
  4482.       ~messages_byname()
  4483.       { }
  4484.     };
  4485.  
  4486.   // Include host and configuration specific messages functions.
  4487.   #include <bits/messages_members.h>
  4488.  
  4489.  
  4490.   // Subclause convenience interfaces, inlines.
  4491.   // NB: These are inline because, when used in a loop, some compilers
  4492.   // can hoist the body out of the loop; then it's just as fast as the
  4493.   // C is*() function.
  4494.   //@{
  4495.   /// Convenience interface to ctype.is().
  4496.   template<typename _CharT>
  4497.     inline bool
  4498.     isspace(_CharT __c, const locale& __loc)
  4499.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
  4500.  
  4501.   template<typename _CharT>
  4502.     inline bool
  4503.     isprint(_CharT __c, const locale& __loc)
  4504.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
  4505.  
  4506.   template<typename _CharT>
  4507.     inline bool
  4508.     iscntrl(_CharT __c, const locale& __loc)
  4509.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
  4510.  
  4511.   template<typename _CharT>
  4512.     inline bool
  4513.     isupper(_CharT __c, const locale& __loc)
  4514.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
  4515.  
  4516.   template<typename _CharT>
  4517.     inline bool islower(_CharT __c, const locale& __loc)
  4518.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
  4519.  
  4520.   template<typename _CharT>
  4521.     inline bool
  4522.     isalpha(_CharT __c, const locale& __loc)
  4523.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
  4524.  
  4525.   template<typename _CharT>
  4526.     inline bool
  4527.     isdigit(_CharT __c, const locale& __loc)
  4528.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
  4529.  
  4530.   template<typename _CharT>
  4531.     inline bool
  4532.     ispunct(_CharT __c, const locale& __loc)
  4533.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
  4534.  
  4535.   template<typename _CharT>
  4536.     inline bool
  4537.     isxdigit(_CharT __c, const locale& __loc)
  4538.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
  4539.  
  4540.   template<typename _CharT>
  4541.     inline bool
  4542.     isalnum(_CharT __c, const locale& __loc)
  4543.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
  4544.  
  4545.   template<typename _CharT>
  4546.     inline bool
  4547.     isgraph(_CharT __c, const locale& __loc)
  4548.     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
  4549.  
  4550.   template<typename _CharT>
  4551.     inline _CharT
  4552.     toupper(_CharT __c, const locale& __loc)
  4553.     { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
  4554.  
  4555.   template<typename _CharT>
  4556.     inline _CharT
  4557.     tolower(_CharT __c, const locale& __loc)
  4558.     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
  4559.   //@}
  4560. } // namespace std
  4561.  
  4562. #endif
  4563.