home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 14 / hacker14.iso / programacao / cwin / c.exe / $INSTDIR / include / c++ / bits / locale_facets.tcc < prev    next >
Encoding:
Text File  |  2003-12-15  |  76.8 KB  |  2,495 lines

  1. // Locale support -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
  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. // Warning: this file is not meant for user inclusion. Use <locale>.
  32.  
  33. #ifndef _CPP_BITS_LOCFACETS_TCC
  34. #define _CPP_BITS_LOCFACETS_TCC 1
  35.  
  36. #pragma GCC system_header
  37.  
  38. #include <cerrno>
  39. #include <clocale>   // For localeconv
  40. #include <cstdlib>   // For strof, strtold
  41. #include <cmath>     // For ceil
  42. #include <cctype>    // For isspace
  43. #include <limits>    // For numeric_limits
  44. #include <bits/streambuf_iterator.h>
  45. #include <typeinfo>  // For bad_cast.
  46.  
  47. namespace std
  48. {
  49.   template<typename _Facet>
  50.     locale
  51.     locale::combine(const locale& __other) const
  52.     {
  53.       _Impl* __tmp = new _Impl(*_M_impl, 1);
  54.       __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
  55.       return locale(__tmp);
  56.     }
  57.  
  58.   template<typename _CharT, typename _Traits, typename _Alloc>
  59.     bool
  60.     locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
  61.                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
  62.     {
  63.       typedef std::collate<_CharT> __collate_type;
  64.       const __collate_type& __collate = use_facet<__collate_type>(*this);
  65.       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
  66.                 __s2.data(), __s2.data() + __s2.length()) < 0);
  67.     }
  68.  
  69.   template<typename _Facet>
  70.     const _Facet&
  71.     use_facet(const locale& __loc)
  72.     {
  73.       size_t __i = _Facet::id._M_id();
  74.       locale::facet** __facets = __loc._M_impl->_M_facets;
  75.       if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
  76.         __throw_bad_cast();
  77.       return static_cast<const _Facet&>(*__facets[__i]);
  78.     }
  79.  
  80.   template<typename _Facet>
  81.     bool
  82.     has_facet(const locale& __loc) throw()
  83.     {
  84.       size_t __i = _Facet::id._M_id();
  85.       locale::facet** __facets = __loc._M_impl->_M_facets;
  86.       return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
  87.     }
  88.  
  89.  
  90.   // Stage 1: Determine a conversion specifier.
  91.   template<typename _CharT, typename _InIter>
  92.     _InIter
  93.     num_get<_CharT, _InIter>::
  94.     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
  95.              ios_base::iostate& __err, string& __xtrc) const
  96.     {
  97.       typedef char_traits<_CharT>        __traits_type;
  98.       const locale __loc = __io.getloc();
  99.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  100.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  101.  
  102.       // First check for sign.
  103.       const char_type __plus = __ctype.widen('+');
  104.       const char_type __minus = __ctype.widen('-');
  105.       int __pos = 0;
  106.       char_type  __c = *__beg;
  107.       if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
  108.       && __beg != __end)
  109.     {
  110.       __xtrc += __ctype.narrow(__c, char());
  111.       ++__pos;
  112.       __c = *(++__beg);
  113.     }
  114.  
  115.       // Next, strip leading zeros.
  116.       const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
  117.       bool __found_zero = false;
  118.       while (__traits_type::eq(__c, __zero) && __beg != __end)
  119.     {
  120.       __c = *(++__beg);
  121.       __found_zero = true;
  122.     }
  123.       if (__found_zero)
  124.     {
  125.       __xtrc += _S_atoms[_M_zero];
  126.       ++__pos;
  127.     }
  128.  
  129.       // Only need acceptable digits for floating point numbers.
  130.       const size_t __len = _M_E - _M_zero + 1;
  131.       char_type  __watoms[__len];
  132.       __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
  133.       bool __found_dec = false;
  134.       bool __found_sci = false;
  135.       const char_type __dec = __np.decimal_point();
  136.  
  137.       string __found_grouping;
  138.       const string __grouping = __np.grouping();
  139.       bool __check_grouping = __grouping.size();
  140.       int __sep_pos = 0;
  141.       const char_type __sep = __np.thousands_sep();
  142.  
  143.       while (__beg != __end)
  144.         {
  145.       // Only look in digits.
  146.           const char_type* __p = __traits_type::find(__watoms, 10,  __c);
  147.  
  148.           // NB: strchr returns true for __c == 0x0
  149.           if (__p && !__traits_type::eq(__c, char_type()))
  150.         {
  151.           // Try first for acceptable digit; record it if found.
  152.           ++__pos;
  153.           __xtrc += _S_atoms[__p - __watoms];
  154.           ++__sep_pos;
  155.           __c = *(++__beg);
  156.         }
  157.           else if (__traits_type::eq(__c, __sep) 
  158.            && __check_grouping && !__found_dec)
  159.         {
  160.               // NB: Thousands separator at the beginning of a string
  161.               // is a no-no, as is two consecutive thousands separators.
  162.               if (__sep_pos)
  163.                 {
  164.                   __found_grouping += static_cast<char>(__sep_pos);
  165.                   __sep_pos = 0;
  166.           __c = *(++__beg);
  167.                 }
  168.               else
  169.         {
  170.           __err |= ios_base::failbit;
  171.           break;
  172.         }
  173.             }
  174.       else if (__traits_type::eq(__c, __dec) && !__found_dec)
  175.         {
  176.           // According to the standard, if no grouping chars are seen,
  177.           // no grouping check is applied. Therefore __found_grouping
  178.           // must be adjusted only if __dec comes after some __sep.
  179.           if (__found_grouping.size())
  180.         __found_grouping += static_cast<char>(__sep_pos);
  181.           ++__pos;
  182.           __xtrc += '.';
  183.           __c = *(++__beg);
  184.           __found_dec = true;
  185.         }
  186.       else if ((__traits_type::eq(__c, __watoms[_M_e]) 
  187.             || __traits_type::eq(__c, __watoms[_M_E])) 
  188.            && !__found_sci && __pos)
  189.         {
  190.           // Scientific notation.
  191.           ++__pos;
  192.           __xtrc += __ctype.narrow(__c, char());
  193.           __c = *(++__beg);
  194.  
  195.           // Remove optional plus or minus sign, if they exist.
  196.           if (__traits_type::eq(__c, __plus) 
  197.           || __traits_type::eq(__c, __minus))
  198.         {
  199.           ++__pos;
  200.           __xtrc += __ctype.narrow(__c, char());
  201.           __c = *(++__beg);
  202.         }
  203.           __found_sci = true;
  204.         }
  205.       else
  206.         // Not a valid input item.
  207.         break;
  208.         }
  209.  
  210.       // Digit grouping is checked. If grouping and found_grouping don't
  211.       // match, then get very very upset, and set failbit.
  212.       if (__check_grouping && __found_grouping.size())
  213.         {
  214.           // Add the ending grouping if a decimal wasn't found.
  215.       if (!__found_dec)
  216.         __found_grouping += static_cast<char>(__sep_pos);
  217.           if (!__verify_grouping(__grouping, __found_grouping))
  218.         __err |= ios_base::failbit;
  219.         }
  220.  
  221.       // Finish up
  222.       __xtrc += char();
  223.       if (__beg == __end)
  224.         __err |= ios_base::eofbit;
  225.       return __beg;
  226.     }
  227.  
  228.   // Stage 1: Determine a conversion specifier.
  229.   template<typename _CharT, typename _InIter>
  230.     _InIter
  231.     num_get<_CharT, _InIter>::
  232.     _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
  233.            ios_base::iostate& __err, string& __xtrc, int& __base) const
  234.     {
  235.       typedef char_traits<_CharT>        __traits_type;
  236.       const locale __loc = __io.getloc();
  237.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  238.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  239.  
  240.       // NB: Iff __basefield == 0, this can change based on contents.
  241.       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
  242.       if (__basefield == ios_base::oct)
  243.         __base = 8;
  244.       else if (__basefield == ios_base::hex)
  245.         __base = 16;
  246.       else
  247.     __base = 10;
  248.  
  249.       // First check for sign.
  250.       int __pos = 0;
  251.       char_type  __c = *__beg;
  252.       const char_type __plus = __ctype.widen('+');
  253.       const char_type __minus = __ctype.widen('-');
  254.  
  255.       if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
  256.       && __beg != __end)
  257.     {
  258.       __xtrc += __ctype.narrow(__c, char());
  259.       ++__pos;
  260.       __c = *(++__beg);
  261.     }
  262.  
  263.       // Next, strip leading zeros and check required digits for base formats.
  264.       const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
  265.       const char_type __x = __ctype.widen('x');
  266.       const char_type __X = __ctype.widen('X');
  267.       if (__base == 10)
  268.     {
  269.       bool __found_zero = false;
  270.       while (__traits_type::eq(__c, __zero) && __beg != __end)
  271.         {
  272.           __c = *(++__beg);
  273.           __found_zero = true;
  274.         }
  275.       if (__found_zero)
  276.         {
  277.           __xtrc += _S_atoms[_M_zero];
  278.           ++__pos;
  279.           if (__basefield == 0)
  280.         {          
  281.           if ((__traits_type::eq(__c, __x) 
  282.                || __traits_type::eq(__c, __X))
  283.               && __beg != __end)
  284.             {
  285.               __xtrc += __ctype.narrow(__c, char());
  286.               ++__pos;
  287.               __c = *(++__beg);
  288.               __base = 16;
  289.             }
  290.           else 
  291.             __base = 8;
  292.         }
  293.         }
  294.     }
  295.       else if (__base == 16)
  296.     {
  297.       if (__traits_type::eq(__c, __zero) && __beg != __end)
  298.         {
  299.           __xtrc += _S_atoms[_M_zero];
  300.           ++__pos;
  301.           __c = *(++__beg); 
  302.           if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X))
  303.           && __beg != __end)
  304.         {
  305.           __xtrc += __ctype.narrow(__c, char());
  306.           ++__pos;
  307.           __c = *(++__beg);
  308.         }
  309.         }
  310.     }
  311.  
  312.       // At this point, base is determined. If not hex, only allow
  313.       // base digits as valid input.
  314.       size_t __len;
  315.       if (__base == 16)
  316.     __len = _M_size;
  317.       else
  318.     __len = __base;
  319.  
  320.       // Extract.
  321.       char_type __watoms[_M_size];
  322.       __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
  323.       string __found_grouping;
  324.       const string __grouping = __np.grouping();
  325.       bool __check_grouping = __grouping.size();
  326.       int __sep_pos = 0;
  327.       const char_type __sep = __np.thousands_sep();
  328.       while (__beg != __end)
  329.         {
  330.           const char_type* __p = __traits_type::find(__watoms, __len,  __c);
  331.  
  332.           // NB: strchr returns true for __c == 0x0
  333.           if (__p && !__traits_type::eq(__c, char_type()))
  334.         {
  335.           // Try first for acceptable digit; record it if found.
  336.           __xtrc += _S_atoms[__p - __watoms];
  337.           ++__pos;
  338.           ++__sep_pos;
  339.           __c = *(++__beg);
  340.         }
  341.           else if (__traits_type::eq(__c, __sep) && __check_grouping)
  342.         {
  343.               // NB: Thousands separator at the beginning of a string
  344.               // is a no-no, as is two consecutive thousands separators.
  345.               if (__sep_pos)
  346.                 {
  347.                   __found_grouping += static_cast<char>(__sep_pos);
  348.                   __sep_pos = 0;
  349.           __c = *(++__beg);
  350.                 }
  351.               else
  352.         {
  353.           __err |= ios_base::failbit;
  354.           break;
  355.         }
  356.             }
  357.       else
  358.         // Not a valid input item.
  359.         break;
  360.         }
  361.  
  362.       // Digit grouping is checked. If grouping and found_grouping don't
  363.       // match, then get very very upset, and set failbit.
  364.       if (__check_grouping && __found_grouping.size())
  365.         {
  366.           // Add the ending grouping.
  367.           __found_grouping += static_cast<char>(__sep_pos);
  368.           if (!__verify_grouping(__grouping, __found_grouping))
  369.         __err |= ios_base::failbit;
  370.         }
  371.  
  372.       // Finish up.
  373.       __xtrc += char();
  374.       if (__beg == __end)
  375.         __err |= ios_base::eofbit;
  376.       return __beg;
  377.     }
  378.  
  379. #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
  380.   //17.  Bad bool parsing
  381.   template<typename _CharT, typename _InIter>
  382.     _InIter
  383.     num_get<_CharT, _InIter>::
  384.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  385.            ios_base::iostate& __err, bool& __v) const
  386.     {
  387.       // Parse bool values as unsigned long
  388.       if (!(__io.flags() & ios_base::boolalpha))
  389.         {
  390.           // NB: We can't just call do_get(long) here, as it might
  391.           // refer to a derived class.
  392.           string __xtrc;
  393.           int __base;
  394.           __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  395.  
  396.       unsigned long __ul; 
  397.       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
  398.       if (!(__err & ios_base::failbit) && __ul <= 1)
  399.         __v = __ul;
  400.       else 
  401.             __err |= ios_base::failbit;
  402.         }
  403.  
  404.       // Parse bool values as alphanumeric
  405.       else
  406.         {
  407.       typedef char_traits<_CharT>              __traits_type;
  408.       typedef basic_string<_CharT>       __string_type;
  409.  
  410.           locale __loc = __io.getloc();
  411.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
  412.       const __string_type __true = __np.truename();
  413.       const __string_type __false = __np.falsename();
  414.           const char_type* __trues = __true.c_str();
  415.           const char_type* __falses = __false.c_str();
  416.           const size_t __truen =  __true.size() - 1;
  417.           const size_t __falsen =  __false.size() - 1;
  418.  
  419.           for (size_t __n = 0; __beg != __end; ++__n)
  420.             {
  421.               char_type __c = *__beg++;
  422.               bool __testf = __n <= __falsen 
  423.                      ? __traits_type::eq(__c, __falses[__n]) : false;
  424.               bool __testt = __n <= __truen 
  425.                      ? __traits_type::eq(__c, __trues[__n]) : false;
  426.               if (!(__testf || __testt))
  427.                 {
  428.                   __err |= ios_base::failbit;
  429.                   break;
  430.                 }
  431.               else if (__testf && __n == __falsen)
  432.                 {
  433.                   __v = 0;
  434.                   break;
  435.                 }
  436.               else if (__testt && __n == __truen)
  437.                 {
  438.                   __v = 1;
  439.                   break;
  440.                 }
  441.             }
  442.           if (__beg == __end)
  443.             __err |= ios_base::eofbit;
  444.         }
  445.       return __beg;
  446.     }
  447. #endif
  448.  
  449.   template<typename _CharT, typename _InIter>
  450.     _InIter
  451.     num_get<_CharT, _InIter>::
  452.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  453.            ios_base::iostate& __err, long& __v) const
  454.     {
  455.       string __xtrc;
  456.       int __base;
  457.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  458.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
  459.       return __beg;
  460.     }
  461.  
  462.   template<typename _CharT, typename _InIter>
  463.     _InIter
  464.     num_get<_CharT, _InIter>::
  465.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  466.            ios_base::iostate& __err, unsigned short& __v) const
  467.     {
  468.       string __xtrc;
  469.       int __base;
  470.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  471.       unsigned long __ul;
  472.       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
  473.       if (!(__err & ios_base::failbit) 
  474.       && __ul <= numeric_limits<unsigned short>::max())
  475.     __v = static_cast<unsigned short>(__ul);
  476.       else 
  477.     __err |= ios_base::failbit;
  478.       return __beg;
  479.     }
  480.  
  481.   template<typename _CharT, typename _InIter>
  482.     _InIter
  483.     num_get<_CharT, _InIter>::
  484.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  485.            ios_base::iostate& __err, unsigned int& __v) const
  486.     {
  487.       string __xtrc;
  488.       int __base;
  489.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  490.       unsigned long __ul;
  491.       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
  492.       if (!(__err & ios_base::failbit) 
  493.       && __ul <= numeric_limits<unsigned int>::max())
  494.     __v = static_cast<unsigned int>(__ul);
  495.       else 
  496.     __err |= ios_base::failbit;
  497.       return __beg;
  498.     }
  499.  
  500.   template<typename _CharT, typename _InIter>
  501.     _InIter
  502.     num_get<_CharT, _InIter>::
  503.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  504.            ios_base::iostate& __err, unsigned long& __v) const
  505.     {
  506.       string __xtrc;
  507.       int __base;
  508.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  509.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
  510.       return __beg;
  511.     }
  512.  
  513. #ifdef _GLIBCPP_USE_LONG_LONG
  514.   template<typename _CharT, typename _InIter>
  515.     _InIter
  516.     num_get<_CharT, _InIter>::
  517.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  518.            ios_base::iostate& __err, long long& __v) const
  519.     {
  520.       string __xtrc;
  521.       int __base;
  522.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  523.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
  524.       return __beg;
  525.     }
  526.  
  527.   template<typename _CharT, typename _InIter>
  528.     _InIter
  529.     num_get<_CharT, _InIter>::
  530.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  531.            ios_base::iostate& __err, unsigned long long& __v) const
  532.     {
  533.       string __xtrc;
  534.       int __base;
  535.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  536.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
  537.       return __beg;
  538.     }
  539. #endif
  540.  
  541.   template<typename _CharT, typename _InIter>
  542.     _InIter
  543.     num_get<_CharT, _InIter>::
  544.     do_get(iter_type __beg, iter_type __end, ios_base& __io, 
  545.        ios_base::iostate& __err, float& __v) const
  546.     {
  547.       string __xtrc;
  548.       __xtrc.reserve(32);
  549.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  550.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
  551.       return __beg;
  552.     }
  553.  
  554.   template<typename _CharT, typename _InIter>
  555.     _InIter
  556.     num_get<_CharT, _InIter>::
  557.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  558.            ios_base::iostate& __err, double& __v) const
  559.     {
  560.       string __xtrc;
  561.       __xtrc.reserve(32);
  562.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  563.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
  564.       return __beg;
  565.     }
  566.  
  567.   template<typename _CharT, typename _InIter>
  568.     _InIter
  569.     num_get<_CharT, _InIter>::
  570.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  571.            ios_base::iostate& __err, long double& __v) const
  572.     {
  573.       string __xtrc;
  574.       __xtrc.reserve(32);
  575.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  576. #ifdef  _GLIBCPP_NO_LONG_DOUBLE_IO
  577.       double __vd;
  578.       __convert_to_v(__xtrc.c_str(), __vd, __err, _S_c_locale);
  579.       __v = static_cast<long double>(__vd);    
  580. #else
  581.       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
  582. #endif
  583.       return __beg;
  584.     }
  585.  
  586.   template<typename _CharT, typename _InIter>
  587.     _InIter
  588.     num_get<_CharT, _InIter>::
  589.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  590.            ios_base::iostate& __err, void*& __v) const
  591.     {
  592.       // Prepare for hex formatted input
  593.       typedef ios_base::fmtflags        fmtflags;
  594.       fmtflags __fmt = __io.flags();
  595.       fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
  596.                              | ios_base::uppercase | ios_base::internal);
  597.       __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
  598.  
  599.       string __xtrc;
  600.       int __base;
  601.       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
  602.  
  603.       // Reset from hex formatted input
  604.       __io.flags(__fmt);
  605.  
  606.       unsigned long __ul;
  607.       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
  608.       if (!(__err & ios_base::failbit))
  609.     __v = reinterpret_cast<void*>(__ul);
  610.       else 
  611.     __err |= ios_base::failbit;
  612.       return __beg;
  613.     }
  614.  
  615.   // The following code uses snprintf (or sprintf(), when _GLIBCPP_USE_C99
  616.   // is not defined) to convert floating point values for insertion into a
  617.   // stream.  An optimization would be to replace them with code that works
  618.   // directly on a wide buffer and then use __pad to do the padding.
  619.   // It would be good to replace them anyway to gain back the efficiency
  620.   // that C++ provides by knowing up front the type of the values to insert.
  621.   // Also, sprintf is dangerous since may lead to accidental buffer overruns.
  622.   // This implementation follows the C++ standard fairly directly as
  623.   // outlined in 22.2.2.2 [lib.locale.num.put]
  624.   template<typename _CharT, typename _OutIter>
  625.     template<typename _ValueT>
  626.       _OutIter
  627.       num_put<_CharT, _OutIter>::
  628.       _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
  629.                _ValueT __v) const
  630.       {
  631.     // Note: digits10 is rounded down.  We need to add 1 to ensure
  632.     // we get the full available precision.
  633.     const int __max_digits = numeric_limits<_ValueT>::digits10 + 1;
  634.     streamsize __prec = __io.precision();
  635.  
  636.     if (__prec > static_cast<streamsize>(__max_digits))
  637.       __prec = static_cast<streamsize>(__max_digits);
  638.  
  639.     // Long enough for the max format spec.
  640.     char __fbuf[16];
  641.  
  642.     // [22.2.2.2.2] Stage 1, numeric conversion to character.
  643.     int __len;
  644. #ifdef _GLIBCPP_USE_C99
  645.     // First try a buffer perhaps big enough (for sure sufficient for
  646.     // non-ios_base::fixed outputs)
  647.     int __cs_size = __max_digits * 3;
  648.     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  649.  
  650.     const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
  651.     if (__fp)
  652.       __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
  653.                    _S_c_locale, __prec);
  654.     else
  655.       __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
  656.  
  657.     // If the buffer was not large enough, try again with the correct size.
  658.     if (__len >= __cs_size)
  659.       {
  660.         __cs_size = __len + 1; 
  661.         __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  662.         if (__fp)
  663.           __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
  664.                        _S_c_locale, __prec);
  665.         else
  666.           __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
  667.                        _S_c_locale);
  668.       }
  669. #else
  670.     // Consider the possibility of long ios_base::fixed outputs
  671.     const bool __fixed = __io.flags() & ios_base::fixed;
  672.     const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
  673.     // ios_base::fixed outputs may need up to __max_exp+1 chars
  674.     // for the integer part + up to __max_digits chars for the
  675.     // fractional part + 3 chars for sign, decimal point, '\0'. On
  676.     // the other hand, for non-fixed outputs __max_digits*3 chars
  677.     // are largely sufficient.
  678.     const int __cs_size = __fixed ? __max_exp + __max_digits + 4 
  679.                                   : __max_digits * 3;
  680.     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  681.  
  682.     if (_S_format_float(__io, __fbuf, __mod, __prec))
  683.       __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
  684.     else
  685.       __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
  686. #endif
  687.     return _M_widen_float(__s, __io, __fill, __cs, __len);
  688.       }
  689.  
  690.   template<typename _CharT, typename _OutIter>
  691.     template<typename _ValueT>
  692.       _OutIter
  693.       num_put<_CharT, _OutIter>::
  694.       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
  695.              char __modl, _ValueT __v) const
  696.       {
  697.     // [22.2.2.2.2] Stage 1, numeric conversion to character.
  698.  
  699.     // Long enough for the max format spec.
  700.     char __fbuf[16];
  701.     _S_format_int(__io, __fbuf, __mod, __modl);
  702. #ifdef _GLIBCPP_USE_C99
  703.     // First try a buffer perhaps big enough.
  704.     int __cs_size = 64;
  705.     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  706.     int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
  707.                      _S_c_locale);
  708.     // If the buffer was not large enough, try again with the correct size.
  709.     if (__len >= __cs_size)
  710.       {
  711.         __cs_size = __len + 1;
  712.         __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  713.         __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
  714.                      _S_c_locale);
  715.       }
  716. #else
  717.     // Leave room for "+/-," "0x," and commas. This size is
  718.     // arbitrary, but should be largely sufficient.
  719.     char __cs[128];
  720.     int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
  721. #endif
  722.     return _M_widen_int(__s, __io, __fill, __cs, __len);
  723.       }
  724.  
  725.   template<typename _CharT, typename _OutIter>
  726.     _OutIter
  727.     num_put<_CharT, _OutIter>::
  728.     _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
  729.            int __len) const
  730.     {
  731.       typedef char_traits<_CharT>         __traits_type;
  732.       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
  733.       // numpunct.decimal_point() values for '.' and adding grouping.
  734.       const locale __loc = __io.getloc();
  735.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  736.       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  737.                                * __len));
  738.       // Grouping can add (almost) as many separators as the number of
  739.       // digits, but no more.
  740.       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  741.                                  * __len * 2));
  742.       __ctype.widen(__cs, __cs + __len, __ws);
  743.       
  744.       // Replace decimal point.
  745.       const _CharT* __p;
  746.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  747.       if (__p = __traits_type::find(__ws, __len, __ctype.widen('.')))
  748.     __ws[__p - __ws] = __np.decimal_point();
  749.  
  750. #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
  751. //282. What types does numpunct grouping refer to?
  752.       // Add grouping, if necessary. 
  753.       const string __grouping = __np.grouping();
  754.       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
  755.       if (__grouping.size())
  756.     {
  757.       _CharT* __p2;
  758.       int __declen = __p ? __p - __ws : __len;
  759.       __p2 = __add_grouping(__ws2, __np.thousands_sep(), 
  760.                 __grouping.c_str(),
  761.                 __grouping.c_str() + __grouping.size(),
  762.                 __ws, __ws + __declen);
  763.       int __newlen = __p2 - __ws2;
  764.     
  765.       // Tack on decimal part.
  766.       if (__p)
  767.         {
  768.           __traits_type::copy(__p2, __p, __len - __declen);
  769.           __newlen += __len - __declen;
  770.         }    
  771.  
  772.       // Switch strings, establish correct new length.
  773.       __ws = __ws2;
  774.       __len = __newlen;
  775.     }
  776. #endif
  777.       return _M_insert(__s, __io, __fill, __ws, __len);
  778.     }
  779.  
  780.   template<typename _CharT, typename _OutIter>
  781.     _OutIter
  782.     num_put<_CharT, _OutIter>::
  783.     _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
  784.          int __len) const
  785.     {
  786.       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
  787.       // numpunct.decimal_point() values for '.' and adding grouping.
  788.       const locale __loc = __io.getloc();
  789.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  790.       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  791.                                * __len));
  792.       // Grouping can add (almost) as many separators as the number of
  793.       // digits, but no more.
  794.       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  795.                                 * __len * 2));
  796.       __ctype.widen(__cs, __cs + __len, __ws);
  797.  
  798.       // Add grouping, if necessary. 
  799.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  800.       const string __grouping = __np.grouping();
  801.       const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
  802.       if (__grouping.size())
  803.     {
  804.       // By itself __add_grouping cannot deal correctly with __ws when
  805.       // ios::showbase is set and ios_base::oct || ios_base::hex.
  806.       // Therefore we take care "by hand" of the initial 0, 0x or 0X.
  807.       streamsize __off = 0;
  808.       if (__io.flags() & ios_base::showbase)
  809.         if (__basefield == ios_base::oct)
  810.           {
  811.         __off = 1;
  812.         *__ws2 = *__ws;
  813.           }
  814.         else if (__basefield == ios_base::hex)
  815.           {
  816.         __off = 2;
  817.         *__ws2 = *__ws;
  818.         *(__ws2 + 1) = *(__ws + 1);
  819.           }
  820.       _CharT* __p;
  821.       __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), 
  822.                    __grouping.c_str(),
  823.                    __grouping.c_str() + __grouping.size(),
  824.                    __ws + __off, __ws + __len);
  825.       __len = __p - __ws2;
  826.       // Switch strings.
  827.       __ws = __ws2;
  828.     }
  829.       return _M_insert(__s, __io, __fill, __ws, __len);
  830.     }
  831.  
  832.   // For use by integer and floating-point types after they have been
  833.   // converted into a char_type string.
  834.   template<typename _CharT, typename _OutIter>
  835.     _OutIter
  836.     num_put<_CharT, _OutIter>::
  837.     _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, 
  838.           int __len) const
  839.     {
  840.       typedef char_traits<_CharT>         __traits_type;
  841.       // [22.2.2.2.2] Stage 3.
  842.       streamsize __w = __io.width();
  843.       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
  844.                                 * __w));
  845.       if (__w > static_cast<streamsize>(__len))
  846.     {
  847.       __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws, 
  848.                            __w, __len, true);
  849.       __len = static_cast<int>(__w);
  850.       // Switch strings.
  851.       __ws = __ws2;
  852.     }
  853.       __io.width(0);
  854.  
  855.       // [22.2.2.2.2] Stage 4.
  856.       // Write resulting, fully-formatted string to output iterator.
  857.       for (int __j = 0; __j < __len; ++__j, ++__s)
  858.     *__s = __ws[__j];
  859.       return __s;
  860.     }
  861.  
  862.   template<typename _CharT, typename _OutIter>
  863.     _OutIter
  864.     num_put<_CharT, _OutIter>::
  865.     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
  866.     {
  867.       ios_base::fmtflags __flags = __io.flags();
  868.       if ((__flags & ios_base::boolalpha) == 0)
  869.         {
  870.           unsigned long __uv = __v;
  871.           __s = _M_convert_int(__s, __io, __fill, 'u', char(), __uv);
  872.         }
  873.       else
  874.         {
  875.       typedef basic_string<_CharT> __string_type;
  876.           locale __loc = __io.getloc();
  877.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
  878.       __string_type __name;
  879.           if (__v)
  880.         __name = __np.truename();
  881.           else
  882.         __name = __np.falsename();
  883.       __s = _M_insert(__s, __io, __fill, __name.c_str(), __name.size()); 
  884.     }
  885.       return __s;
  886.     }
  887.  
  888.   template<typename _CharT, typename _OutIter>
  889.     _OutIter
  890.     num_put<_CharT, _OutIter>::
  891.     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
  892.     { return _M_convert_int(__s, __io, __fill, 'd', char(), __v); }
  893.  
  894.   template<typename _CharT, typename _OutIter>
  895.     _OutIter
  896.     num_put<_CharT, _OutIter>::
  897.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  898.            unsigned long __v) const
  899.     { return _M_convert_int(__s, __io, __fill, 'u', char(), __v); }
  900.  
  901. #ifdef _GLIBCPP_USE_LONG_LONG
  902.   template<typename _CharT, typename _OutIter>
  903.     _OutIter
  904.     num_put<_CharT, _OutIter>::
  905.     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
  906.     { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
  907.  
  908.   template<typename _CharT, typename _OutIter>
  909.     _OutIter
  910.     num_put<_CharT, _OutIter>::
  911.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  912.            unsigned long long __v) const
  913.     { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
  914. #endif
  915.  
  916.   template<typename _CharT, typename _OutIter>
  917.     _OutIter
  918.     num_put<_CharT, _OutIter>::
  919.     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
  920.     { return _M_convert_float(__s, __io, __fill, char(), __v); }
  921.  
  922.   template<typename _CharT, typename _OutIter>
  923.     _OutIter
  924.     num_put<_CharT, _OutIter>::
  925.     do_put(iter_type __s, ios_base& __io, char_type __fill, 
  926.        long double __v) const
  927.     {
  928. #ifdef  _GLIBCPP_NO_LONG_DOUBLE_IO
  929.       return _M_convert_float(__s, __io, __fill, char_type(),
  930.                   static_cast<double>(__v));
  931. #else
  932.       return _M_convert_float(__s, __io, __fill, 'L', __v);
  933. #endif
  934.    }
  935.  
  936.   template<typename _CharT, typename _OutIter>
  937.     _OutIter
  938.     num_put<_CharT, _OutIter>::
  939.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  940.            const void* __v) const
  941.     {
  942.       ios_base::fmtflags __flags = __io.flags();
  943.       ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
  944.                    | ios_base::uppercase | ios_base::internal);
  945.       __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
  946.       try 
  947.     {
  948.       __s = _M_convert_int(__s, __io, __fill, 'u', char(),
  949.                    reinterpret_cast<unsigned long>(__v));
  950.       __io.flags(__flags);
  951.     }
  952.       catch (...) 
  953.     {
  954.       __io.flags(__flags);
  955.       __throw_exception_again;
  956.     }
  957.       return __s;
  958.     }
  959.  
  960. #ifdef  _GLIBCPP_NO_LONG_DOUBLE_IO
  961.   template<typename _CharT, typename _InIter>
  962.     _InIter
  963.     money_get<_CharT, _InIter>::
  964.     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
  965.        ios_base::iostate& __err, long double& __units) const
  966.     { 
  967.       string_type __str;
  968.       __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); 
  969.       double __dunits;
  970.     
  971.       const int __n = numeric_limits<double>::digits10;
  972.       char* __cs = static_cast<char*>(__builtin_alloca(__n));
  973.       const locale __loc = __io.getloc();
  974.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  975.       const _CharT* __wcs = __str.c_str();
  976.       __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
  977.       __convert_to_v(__cs, __dunits, __err, _S_c_locale);
  978.       __units = static_cast<long double>(__dunits);    
  979.       return __beg;
  980.     }
  981.  
  982. #else //  _GLIBCPP_NO_LONG_DOUBLE_IO
  983.   template<typename _CharT, typename _InIter>
  984.     _InIter
  985.     money_get<_CharT, _InIter>::
  986.     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
  987.        ios_base::iostate& __err, long double& __units) const
  988.     { 
  989.       string_type __str;
  990.       __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); 
  991.  
  992.       const int __n = numeric_limits<long double>::digits10;
  993.       char* __cs = static_cast<char*>(__builtin_alloca(__n));
  994.       const locale __loc = __io.getloc();
  995.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  996.       const _CharT* __wcs = __str.c_str();
  997.       __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
  998.       __convert_to_v(__cs, __units, __err, _S_c_locale);
  999.       return __beg;
  1000.     }
  1001. #endif //  _GLIBCPP_NO_LONG_DOUBLE_IO
  1002.  
  1003.   template<typename _CharT, typename _InIter>
  1004.     _InIter
  1005.     money_get<_CharT, _InIter>::
  1006.     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
  1007.        ios_base::iostate& __err, string_type& __units) const
  1008.     { 
  1009.       // These contortions are quite unfortunate.
  1010.       typedef moneypunct<_CharT, true>         __money_true;
  1011.       typedef moneypunct<_CharT, false>     __money_false;
  1012.       typedef money_base::part             part;
  1013.       typedef typename string_type::size_type     size_type;
  1014.  
  1015.       const locale __loc = __io.getloc();
  1016.       const __money_true& __mpt = use_facet<__money_true>(__loc); 
  1017.       const __money_false& __mpf = use_facet<__money_false>(__loc); 
  1018.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  1019.  
  1020.       const money_base::pattern __p = __intl ? __mpt.neg_format() 
  1021.                          : __mpf.neg_format();
  1022.  
  1023.       const string_type __pos_sign =__intl ? __mpt.positive_sign() 
  1024.                        : __mpf.positive_sign();
  1025.       const string_type __neg_sign =__intl ? __mpt.negative_sign() 
  1026.                        : __mpf.negative_sign();
  1027.       const char_type __d = __intl ? __mpt.decimal_point() 
  1028.                                 : __mpf.decimal_point();
  1029.       const char_type __sep = __intl ? __mpt.thousands_sep() 
  1030.                          : __mpf.thousands_sep();
  1031.  
  1032.       const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
  1033.  
  1034.       // Set to deduced positive or negative sign, depending.
  1035.       string_type __sign;
  1036.       // String of grouping info from thousands_sep plucked from __units.
  1037.       string __grouping_tmp; 
  1038.       // Marker for thousands_sep position.
  1039.       int __sep_pos = 0;
  1040.       // If input iterator is in a valid state.
  1041.       bool __testvalid = true;
  1042.       // Flag marking when a decimal point is found.
  1043.       bool __testdecfound = false; 
  1044.  
  1045.       // The tentative returned string is stored here.
  1046.       string_type __temp_units;
  1047.  
  1048.       char_type __c = *__beg;
  1049.       char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
  1050.       for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
  1051.     {
  1052.       part __which = static_cast<part>(__p.field[__i]);
  1053.       switch (__which)
  1054.         {
  1055.         case money_base::symbol:
  1056.           if (__io.flags() & ios_base::showbase 
  1057.               || __i < 2 || __sign.size() > 1
  1058.               || ((static_cast<part>(__p.field[3]) != money_base::none)
  1059.               && __i == 2)) 
  1060.             {
  1061.               // According to 22.2.6.1.2.2, symbol is required
  1062.               // if (__io.flags() & ios_base::showbase),
  1063.               // otherwise is optional and consumed only if
  1064.               // other characters are needed to complete the
  1065.               // format.
  1066.               const string_type __symbol = __intl ? __mpt.curr_symbol()
  1067.                                  : __mpf.curr_symbol();
  1068.               size_type __len = __symbol.size();
  1069.               size_type __j = 0;
  1070.               while (__beg != __end 
  1071.                  && __j < __len && __symbol[__j] == __c)
  1072.             {
  1073.               __c = *(++__beg);
  1074.               ++__j;
  1075.             }
  1076.               // When (__io.flags() & ios_base::showbase)
  1077.               // symbol is required.
  1078.               if (__j != __len && (__io.flags() & ios_base::showbase))
  1079.             __testvalid = false;
  1080.             }
  1081.           break;
  1082.         case money_base::sign:            
  1083.           // Sign might not exist, or be more than one character long. 
  1084.           if (__pos_sign.size() && __neg_sign.size())
  1085.           {
  1086.             // Sign is mandatory.
  1087.             if (__c == __pos_sign[0])
  1088.               {
  1089.             __sign = __pos_sign;
  1090.             __c = *(++__beg);
  1091.               }
  1092.             else if (__c == __neg_sign[0])
  1093.               {
  1094.             __sign = __neg_sign;
  1095.             __c = *(++__beg);
  1096.               }
  1097.             else
  1098.               __testvalid = false;
  1099.           }
  1100.           else if (__pos_sign.size() && __c == __pos_sign[0])
  1101.             {
  1102.               __sign = __pos_sign;
  1103.               __c = *(++__beg);
  1104.             }
  1105.           else if (__neg_sign.size() && __c == __neg_sign[0])
  1106.             {
  1107.               __sign = __neg_sign;
  1108.               __c = *(++__beg);
  1109.             }
  1110.           break;
  1111.         case money_base::value:
  1112.           // Extract digits, remove and stash away the
  1113.           // grouping of found thousands separators.
  1114.           while (__beg != __end 
  1115.              && (__ctype.is(ctype_base::digit, __c) 
  1116.                  || (__c == __d && !__testdecfound)
  1117.                  || __c == __sep))
  1118.             {
  1119.               if (__c == __d)
  1120.             {
  1121.               __grouping_tmp += static_cast<char>(__sep_pos);
  1122.               __sep_pos = 0;
  1123.               __testdecfound = true;
  1124.             }
  1125.               else if (__c == __sep)
  1126.             {
  1127.               if (__grouping.size())
  1128.                 {
  1129.                   // Mark position for later analysis.
  1130.                   __grouping_tmp += static_cast<char>(__sep_pos);
  1131.                   __sep_pos = 0;
  1132.                 }
  1133.               else
  1134.                 {
  1135.                   __testvalid = false;
  1136.                   break;
  1137.                 }
  1138.             }
  1139.               else
  1140.             {
  1141.               __temp_units += __c;
  1142.               ++__sep_pos;
  1143.             }
  1144.               __c = *(++__beg);
  1145.             }
  1146.           break;
  1147.         case money_base::space:
  1148.         case money_base::none:
  1149.           // Only if not at the end of the pattern.
  1150.           if (__i != 3)
  1151.             while (__beg != __end 
  1152.                && __ctype.is(ctype_base::space, __c))
  1153.               __c = *(++__beg);
  1154.           break;
  1155.         }
  1156.     }
  1157.  
  1158.       // Need to get the rest of the sign characters, if they exist.
  1159.       if (__sign.size() > 1)
  1160.     {
  1161.       size_type __len = __sign.size();
  1162.       size_type __i = 1;
  1163.       for (; __c != __eof && __i < __len; ++__i)
  1164.         while (__beg != __end && __c != __sign[__i])
  1165.           __c = *(++__beg);
  1166.       
  1167.       if (__i != __len)
  1168.         __testvalid = false;
  1169.     }
  1170.  
  1171.       // Strip leading zeros.
  1172.       while (__temp_units[0] == __ctype.widen('0'))
  1173.     __temp_units.erase(__temp_units.begin());
  1174.  
  1175.       if (__sign.size() && __sign == __neg_sign)
  1176.     __temp_units.insert(__temp_units.begin(), __ctype.widen('-'));
  1177.  
  1178.       // Test for grouping fidelity.
  1179.       if (__grouping.size() && __grouping_tmp.size())
  1180.     {
  1181.       if (!__verify_grouping(__grouping, __grouping_tmp))
  1182.         __testvalid = false;
  1183.     }
  1184.  
  1185.       // Iff no more characters are available.      
  1186.       if (__c == __eof)
  1187.     __err |= ios_base::eofbit;
  1188.  
  1189.       // Iff valid sequence is not recognized.
  1190.       if (!__testvalid || !__temp_units.size())
  1191.     __err |= ios_base::failbit;
  1192.       else
  1193.     // Use the "swap trick" to copy __temp_units into __units.
  1194.     __temp_units.swap(__units);
  1195.  
  1196.       return __beg; 
  1197.     }
  1198.  
  1199. #ifdef  _GLIBCPP_NO_LONG_DOUBLE_IO
  1200.   template<typename _CharT, typename _OutIter>
  1201.     _OutIter
  1202.     money_put<_CharT, _OutIter>::
  1203.     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  1204.        long double __units) const
  1205.     { 
  1206.       const locale __loc = __io.getloc();
  1207.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1208.       double __dunits = static_cast<double>(__units);    
  1209. #ifdef _GLIBCPP_USE_C99
  1210.       // First try a buffer perhaps big enough.
  1211.       int __cs_size = 64;
  1212.       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1213.       int __len = __convert_from_v(__cs, __cs_size, "%.01f", __dunits, 
  1214.                    _S_c_locale);
  1215.       // If the buffer was not large enough, try again with the correct size.
  1216.       if (__len >= __cs_size)
  1217.     {
  1218.       __cs_size = __len + 1;
  1219.       __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1220.       __len = __convert_from_v(__cs, __cs_size, "%.01f", __dunits, 
  1221.                    _S_c_locale);
  1222.     }
  1223. #else
  1224.       // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
  1225.       // decimal digit, '\0'. 
  1226.       const int __cs_size = numeric_limits<double>::max_exponent10 + 5;
  1227.       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1228.       int __len = __convert_from_v(__cs, 0, "%.01f", __dunits, _S_c_locale);
  1229. #endif
  1230.       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size));
  1231.       __ctype.widen(__cs, __cs + __len, __ws);
  1232.       string_type __digits(__ws);
  1233.       return this->do_put(__s, __intl, __io, __fill, __digits); 
  1234.     }
  1235. #else  //  _GLIBCPP_NO_LONG_DOUBLE_IO
  1236.   template<typename _CharT, typename _OutIter>
  1237.     _OutIter
  1238.     money_put<_CharT, _OutIter>::
  1239.     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  1240.        long double __units) const
  1241.     { 
  1242.       const locale __loc = __io.getloc();
  1243.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1244. #ifdef _GLIBCPP_USE_C99
  1245.       // First try a buffer perhaps big enough.
  1246.       int __cs_size = 64;
  1247.       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1248.       int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
  1249.                    _S_c_locale);
  1250.       // If the buffer was not large enough, try again with the correct size.
  1251.       if (__len >= __cs_size)
  1252.     {
  1253.       __cs_size = __len + 1;
  1254.       __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1255.       __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
  1256.                    _S_c_locale);
  1257.     }
  1258. #else
  1259.       // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
  1260.       // decimal digit, '\0'. 
  1261.       const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
  1262.       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1263.       int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
  1264. #endif
  1265.       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size));
  1266.       __ctype.widen(__cs, __cs + __len, __ws);
  1267.       string_type __digits(__ws);
  1268.       return this->do_put(__s, __intl, __io, __fill, __digits); 
  1269.     }
  1270. #endif //  _GLIBCPP_NO_LONG_DOUBLE_IO
  1271.  
  1272.   template<typename _CharT, typename _OutIter>
  1273.     _OutIter
  1274.     money_put<_CharT, _OutIter>::
  1275.     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
  1276.        const string_type& __digits) const
  1277.     { 
  1278.       typedef typename string_type::size_type     size_type;
  1279.       typedef money_base::part             part;
  1280.  
  1281.       const locale __loc = __io.getloc();
  1282.       const size_type __width = static_cast<size_type>(__io.width());
  1283.  
  1284.       // These contortions are quite unfortunate.
  1285.       typedef moneypunct<_CharT, true> __money_true;
  1286.       typedef moneypunct<_CharT, false> __money_false;
  1287.       const __money_true& __mpt = use_facet<__money_true>(__loc); 
  1288.       const __money_false& __mpf = use_facet<__money_false>(__loc); 
  1289.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  1290.  
  1291.       // Determine if negative or positive formats are to be used, and
  1292.       // discard leading negative_sign if it is present.
  1293.       const char_type* __beg = __digits.data();
  1294.       const char_type* __end = __beg + __digits.size();
  1295.       money_base::pattern __p;
  1296.       string_type __sign;
  1297.       if (*__beg != __ctype.widen('-'))
  1298.     {
  1299.       __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
  1300.       __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
  1301.     }
  1302.       else
  1303.     {
  1304.       __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
  1305.       __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
  1306.       ++__beg;
  1307.     }
  1308.       
  1309.       // Look for valid numbers in the current ctype facet within input digits.
  1310.       __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
  1311.       if (__beg != __end)
  1312.     {
  1313.       // Assume valid input, and attempt to format.
  1314.       // Break down input numbers into base components, as follows:
  1315.       //   final_value = grouped units + (decimal point) + (digits)
  1316.       string_type __res;
  1317.       string_type __value;
  1318.       const string_type __symbol = __intl ? __mpt.curr_symbol() 
  1319.                               : __mpf.curr_symbol();
  1320.  
  1321.       // Deal with decimal point, decimal digits.
  1322.       const int __frac = __intl ? __mpt.frac_digits() 
  1323.                         : __mpf.frac_digits();
  1324.       if (__frac > 0)
  1325.         {
  1326.           const char_type __d = __intl ? __mpt.decimal_point() 
  1327.                        : __mpf.decimal_point();
  1328.           if (__end - __beg >= __frac)
  1329.         {
  1330.           __value = string_type(__end - __frac, __end);
  1331.           __value.insert(__value.begin(), __d);
  1332.           __end -= __frac;
  1333.         }
  1334.           else
  1335.         {
  1336.           // Have to pad zeros in the decimal position.
  1337.           __value = string_type(__beg, __end);
  1338.           int __paddec = __frac - (__end - __beg);
  1339.           char_type __zero = __ctype.widen('0');
  1340.           __value.insert(__value.begin(), __paddec, __zero);
  1341.           __value.insert(__value.begin(), __d);
  1342.           __beg = __end;
  1343.         }
  1344.         }
  1345.  
  1346.       // Add thousands separators to non-decimal digits, per
  1347.       // grouping rules.
  1348.       if (__beg != __end)
  1349.         {
  1350.           const string __grouping = __intl ? __mpt.grouping() 
  1351.                            : __mpf.grouping();
  1352.           if (__grouping.size())
  1353.         {
  1354.           const char_type __sep = __intl ? __mpt.thousands_sep() 
  1355.                                  : __mpf.thousands_sep();
  1356.           const char* __gbeg = __grouping.c_str();
  1357.           const char* __gend = __gbeg + __grouping.size();
  1358.           const int __n = (__end - __beg) * 2;
  1359.           _CharT* __ws2 =
  1360.             static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
  1361.           _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
  1362.                             __gend, __beg, __end);
  1363.           __value.insert(0, __ws2, __ws_end - __ws2);
  1364.         }
  1365.           else
  1366.         __value.insert(0, string_type(__beg, __end));
  1367.         }
  1368.  
  1369.       // Calculate length of resulting string.
  1370.       ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
  1371.       size_type __len = __value.size() + __sign.size();
  1372.       __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
  1373.       bool __testipad = __f == ios_base::internal && __len < __width;
  1374.  
  1375.       // Fit formatted digits into the required pattern.
  1376.       for (int __i = 0; __i < 4; ++__i)
  1377.         {
  1378.           part __which = static_cast<part>(__p.field[__i]);
  1379.           switch (__which)
  1380.         {
  1381.         case money_base::symbol:
  1382.           if (__io.flags() & ios_base::showbase)
  1383.             __res += __symbol;
  1384.           break;
  1385.         case money_base::sign:            
  1386.           // Sign might not exist, or be more than one
  1387.           // charater long. In that case, add in the rest
  1388.           // below.
  1389.           if (__sign.size())
  1390.             __res += __sign[0];
  1391.           break;
  1392.         case money_base::value:
  1393.           __res += __value;
  1394.           break;
  1395.         case money_base::space:
  1396.           // At least one space is required, but if internal
  1397.           // formatting is required, an arbitrary number of
  1398.           // fill spaces will be necessary.
  1399.           if (__testipad)
  1400.             __res += string_type(__width - __len, __fill);
  1401.           else
  1402.             __res += __ctype.widen(__fill);
  1403.           break;
  1404.         case money_base::none:
  1405.           if (__testipad)
  1406.             __res += string_type(__width - __len, __fill);
  1407.           break;
  1408.         }
  1409.         }
  1410.  
  1411.       // Special case of multi-part sign parts.
  1412.       if (__sign.size() > 1)
  1413.         __res += string_type(__sign.begin() + 1, __sign.end());
  1414.  
  1415.       // Pad, if still necessary.
  1416.       __len = __res.size();
  1417.       if (__width > __len)
  1418.         {
  1419.           if (__f == ios_base::left)
  1420.         // After.
  1421.         __res.append(__width - __len, __fill);
  1422.           else
  1423.         // Before.
  1424.         __res.insert(0, string_type(__width - __len, __fill));
  1425.           __len = __width;
  1426.         }
  1427.  
  1428.       // Write resulting, fully-formatted string to output iterator.
  1429.       for (size_type __j = 0; __j < __len; ++__j, ++__s)
  1430.         *__s = __res[__j];
  1431.     }
  1432.       __io.width(0);
  1433.       return __s; 
  1434.     }
  1435.  
  1436.  
  1437.   // NB: Not especially useful. Without an ios_base object or some
  1438.   // kind of locale reference, we are left clawing at the air where
  1439.   // the side of the mountain used to be...
  1440.   template<typename _CharT, typename _InIter>
  1441.     time_base::dateorder
  1442.     time_get<_CharT, _InIter>::do_date_order() const
  1443.     { return time_base::no_order; }
  1444.  
  1445.   template<typename _CharT, typename _InIter>
  1446.     void
  1447.     time_get<_CharT, _InIter>::
  1448.     _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
  1449.               ios_base::iostate& __err, tm* __tm, 
  1450.               const _CharT* __format) const
  1451.     {  
  1452.       locale __loc = __io.getloc();
  1453.       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1454.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  1455.       size_t __len = char_traits<_CharT>::length(__format);
  1456.  
  1457.       for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
  1458.     {
  1459.       char __c = __format[__i];
  1460.       if (__c == '%')
  1461.         {
  1462.           // Verify valid formatting code, attempt to extract.
  1463.           __c = __format[++__i];
  1464.           char __mod = 0;
  1465.           int __mem = 0; 
  1466.           if (__c == 'E' || __c == 'O')
  1467.         {
  1468.           __mod = __c;
  1469.           __c = __format[++__i];
  1470.         }
  1471.           switch (__c)
  1472.         {
  1473.           const char* __cs;
  1474.           _CharT __wcs[10];
  1475.         case 'a':
  1476.           // Abbreviated weekday name [tm_wday]
  1477.           const char_type*  __days1[7];
  1478.           __tp._M_days_abbreviated(__days1);
  1479.           _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, 
  1480.                   __err);
  1481.           break;
  1482.         case 'A':
  1483.           // Weekday name [tm_wday].
  1484.           const char_type*  __days2[7];
  1485.           __tp._M_days(__days2);
  1486.           _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, 
  1487.                   __err);
  1488.           break;
  1489.         case 'h':
  1490.         case 'b':
  1491.           // Abbreviated month name [tm_mon]
  1492.           const char_type*  __months1[12];
  1493.           __tp._M_months_abbreviated(__months1);
  1494.           _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, 
  1495.                   __err);
  1496.           break;
  1497.         case 'B':
  1498.           // Month name [tm_mon].
  1499.           const char_type*  __months2[12];
  1500.           __tp._M_months(__months2);
  1501.           _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, 
  1502.                   __err);
  1503.           break;
  1504.         case 'c':
  1505.           // Default time and date representation.
  1506.           const char_type*  __dt[2];
  1507.           __tp._M_date_time_formats(__dt);
  1508.           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
  1509.                     __dt[0]);
  1510.           break;
  1511.         case 'd':
  1512.           // Day [01, 31]. [tm_mday]
  1513.           _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 
  1514.                  __ctype, __err);
  1515.           break;
  1516.         case 'D':
  1517.           // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
  1518.           __cs = "%m/%d/%y";
  1519.           __ctype.widen(__cs, __cs + 9, __wcs);
  1520.           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
  1521.                     __wcs);
  1522.           break;
  1523.         case 'H':
  1524.           // Hour [00, 23]. [tm_hour]
  1525.           _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
  1526.                  __ctype, __err);
  1527.           break;
  1528.         case 'I':
  1529.           // Hour [01, 12]. [tm_hour]
  1530.           _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, 
  1531.                  __ctype, __err);
  1532.           break;
  1533.         case 'm':
  1534.           // Month [01, 12]. [tm_mon]
  1535.           _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype, 
  1536.                  __err);
  1537.           if (!__err)
  1538.             __tm->tm_mon = __mem - 1;
  1539.           break;
  1540.         case 'M':
  1541.           // Minute [00, 59]. [tm_min]
  1542.           _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
  1543.                  __ctype, __err);
  1544.           break;
  1545.         case 'n':
  1546.           if (__ctype.narrow(*__beg, 0) == '\n')
  1547.             ++__beg;
  1548.           else
  1549.             __err |= ios_base::failbit;
  1550.           break;
  1551.         case 'R':
  1552.           // Equivalent to (%H:%M).
  1553.           __cs = "%H:%M";
  1554.           __ctype.widen(__cs, __cs + 6, __wcs);
  1555.           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
  1556.                     __wcs);
  1557.           break;
  1558.         case 'S':
  1559.           // Seconds.
  1560.           _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
  1561.                  __ctype, __err);
  1562.           break;
  1563.         case 't':
  1564.           if (__ctype.narrow(*__beg, 0) == '\t')
  1565.             ++__beg;
  1566.           else
  1567.         __err |= ios_base::failbit;
  1568.           break;
  1569.         case 'T':
  1570.           // Equivalent to (%H:%M:%S).
  1571.           __cs = "%H:%M:%S";
  1572.           __ctype.widen(__cs, __cs + 9, __wcs);
  1573.           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
  1574.                     __wcs);
  1575.           break;
  1576.         case 'x':
  1577.           // Locale's date.
  1578.           const char_type*  __dates[2];
  1579.           __tp._M_date_formats(__dates);
  1580.           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
  1581.                     __dates[0]);
  1582.           break;
  1583.         case 'X':
  1584.           // Locale's time.
  1585.           const char_type*  __times[2];
  1586.           __tp._M_time_formats(__times);
  1587.           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
  1588.                     __times[0]);
  1589.           break;
  1590.         case 'y':
  1591.           // Two digit year. [tm_year]
  1592.           _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, 
  1593.                  __ctype, __err);
  1594.           break;
  1595.         case 'Y':
  1596.           // Year [1900). [tm_year]
  1597.           _M_extract_num(__beg, __end, __mem, 0, 
  1598.                  numeric_limits<int>::max(), 4, 
  1599.                  __ctype, __err);
  1600.           if (!__err)
  1601.             __tm->tm_year = __mem - 1900;
  1602.           break;
  1603.         case 'Z':
  1604.           // Timezone info.
  1605.           if (__ctype.is(ctype_base::upper, *__beg))
  1606.             {
  1607.               int __tmp;
  1608.               _M_extract_name(__beg, __end, __tmp, 
  1609.                       __timepunct<_CharT>::_S_timezones, 
  1610.                       14, __err);
  1611.               
  1612.               // GMT requires special effort.
  1613.               char_type __c = *__beg;
  1614.               if (!__err && __tmp == 0 
  1615.               && (__c == __ctype.widen('-') 
  1616.                   || __c == __ctype.widen('+')))
  1617.             {
  1618.               _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
  1619.                       __ctype, __err);
  1620.               _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
  1621.                       __ctype, __err);
  1622.             }        
  1623.               }
  1624.               else
  1625.             __err |= ios_base::failbit;
  1626.               break;
  1627.             default:
  1628.               // Not recognized.
  1629.               __err |= ios_base::failbit;
  1630.             }
  1631.         }
  1632.           else
  1633.         {
  1634.           // Verify format and input match, extract and discard.
  1635.           if (__c == __ctype.narrow(*__beg, 0))
  1636.             ++__beg;
  1637.           else
  1638.             __err |= ios_base::failbit;
  1639.         }
  1640.     }
  1641.     }
  1642.  
  1643.   template<typename _CharT, typename _InIter>
  1644.     void
  1645.     time_get<_CharT, _InIter>::
  1646.     _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
  1647.            int __min, int __max, size_t __len, 
  1648.            const ctype<_CharT>& __ctype, 
  1649.            ios_base::iostate& __err) const
  1650.     {
  1651.       size_t __i = 0;
  1652.       string __digits;
  1653.       bool __testvalid = true;
  1654.       char_type __c = *__beg;
  1655.       while (__beg != __end && __i < __len 
  1656.          && __ctype.is(ctype_base::digit, __c)) 
  1657.     {
  1658.       __digits += __ctype.narrow(__c, 0);
  1659.       __c = *(++__beg);
  1660.       ++__i;
  1661.     }
  1662.       if (__i == __len)
  1663.     {
  1664.       int __value = atoi(__digits.c_str());
  1665.       if (__min <= __value && __value <= __max)
  1666.         __member = __value;
  1667.       else
  1668.         __testvalid = false;
  1669.     }
  1670.       else
  1671.     __testvalid = false;
  1672.       if (!__testvalid)
  1673.     __err |= ios_base::failbit;
  1674.     }
  1675.  
  1676.   // Assumptions:
  1677.   // All elements in __names are unique.
  1678.   template<typename _CharT, typename _InIter>
  1679.     void
  1680.     time_get<_CharT, _InIter>::
  1681.     _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
  1682.             const _CharT** __names, size_t __indexlen, 
  1683.             ios_base::iostate& __err) const
  1684.     {
  1685.       typedef char_traits<_CharT>         __traits_type;
  1686.       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
  1687.       size_t __nmatches = 0;
  1688.       size_t __pos = 0;
  1689.       bool __testvalid = true;
  1690.       const char_type* __name;
  1691.  
  1692.       char_type __c = *__beg;
  1693.       // Look for initial matches.
  1694.       for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
  1695.     if (__c == __names[__i1][0])
  1696.       __matches[__nmatches++] = __i1;
  1697.       
  1698.       while(__nmatches > 1)
  1699.     {
  1700.       // Find smallest matching string.
  1701.       size_t __minlen = 10;
  1702.       for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
  1703.         __minlen = min(__minlen, 
  1704.                __traits_type::length(__names[__matches[__i2]]));
  1705.       
  1706.       if (__pos < __minlen && __beg != __end)
  1707.         {
  1708.           ++__pos;
  1709.           __c = *(++__beg);
  1710.           for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
  1711.         {
  1712.           __name = __names[__matches[__i3]];
  1713.           if (__name[__pos] != __c)
  1714.             __matches[__i3] = __matches[--__nmatches];
  1715.         }
  1716.         }
  1717.       else
  1718.         break;
  1719.     }
  1720.  
  1721.       if (__nmatches == 1)
  1722.     {
  1723.       // Make sure found name is completely extracted.
  1724.       __name = __names[__matches[0]];
  1725.       const size_t __len = __traits_type::length(__name);
  1726.       while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
  1727.         ++__beg, ++__pos;
  1728.  
  1729.       if (__len == __pos)
  1730.         __member = __matches[0];
  1731.       else
  1732.         __testvalid = false;
  1733.     }
  1734.       else
  1735.     __testvalid = false;
  1736.       if (!__testvalid)
  1737.     __err |= ios_base::failbit;
  1738.     }
  1739.  
  1740.   template<typename _CharT, typename _InIter>
  1741.     _InIter
  1742.     time_get<_CharT, _InIter>::
  1743.     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
  1744.         ios_base::iostate& __err, tm* __tm) const
  1745.     {
  1746.       _CharT __wcs[3];
  1747.       const char* __cs = "%X";
  1748.       locale __loc = __io.getloc();
  1749.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1750.       __ctype.widen(__cs, __cs + 3, __wcs);
  1751.       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
  1752.       if (__beg == __end)
  1753.     __err |= ios_base::eofbit;
  1754.       return __beg;
  1755.     }
  1756.  
  1757.   template<typename _CharT, typename _InIter>
  1758.     _InIter
  1759.     time_get<_CharT, _InIter>::
  1760.     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
  1761.         ios_base::iostate& __err, tm* __tm) const
  1762.     {
  1763.       _CharT __wcs[3];
  1764.       const char* __cs = "%x";
  1765.       locale __loc = __io.getloc();
  1766.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1767.       __ctype.widen(__cs, __cs + 3, __wcs);
  1768.       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
  1769.       if (__beg == __end)
  1770.     __err |= ios_base::eofbit;
  1771.       return __beg;
  1772.     }
  1773.  
  1774.   template<typename _CharT, typename _InIter>
  1775.     _InIter
  1776.     time_get<_CharT, _InIter>::
  1777.     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 
  1778.            ios_base::iostate& __err, tm* __tm) const
  1779.     {
  1780.       typedef char_traits<_CharT>         __traits_type;
  1781.       locale __loc = __io.getloc();
  1782.       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1783.       const char_type*  __days[7];
  1784.       __tp._M_days_abbreviated(__days);
  1785.       int __tmpwday;
  1786.       _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
  1787.  
  1788.       // Check to see if non-abbreviated name exists, and extract.
  1789.       // NB: Assumes both _M_days and _M_days_abbreviated organized in
  1790.       // exact same order, first to last, such that the resulting
  1791.       // __days array with the same index points to a day, and that
  1792.       // day's abbreviated form.
  1793.       // NB: Also assumes that an abbreviated name is a subset of the name. 
  1794.       if (!__err)
  1795.     {
  1796.       size_t __pos = __traits_type::length(__days[__tmpwday]);
  1797.       __tp._M_days(__days);
  1798.       const char_type* __name = __days[__tmpwday];
  1799.       if (__name[__pos] == *__beg)
  1800.         {
  1801.           // Extract the rest of it.
  1802.           const size_t __len = __traits_type::length(__name);
  1803.           while (__pos < __len && __beg != __end 
  1804.              && __name[__pos] == *__beg)
  1805.         ++__beg, ++__pos;
  1806.           if (__len != __pos)
  1807.         __err |= ios_base::failbit;
  1808.         }
  1809.       if (!__err)
  1810.         __tm->tm_wday = __tmpwday;
  1811.     }
  1812.       if (__beg == __end)
  1813.     __err |= ios_base::eofbit;
  1814.       return __beg;
  1815.      }
  1816.  
  1817.   template<typename _CharT, typename _InIter>
  1818.     _InIter
  1819.     time_get<_CharT, _InIter>::
  1820.     do_get_monthname(iter_type __beg, iter_type __end,
  1821.                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
  1822.     {
  1823.       typedef char_traits<_CharT>         __traits_type;
  1824.       locale __loc = __io.getloc();
  1825.       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1826.       const char_type*  __months[12];
  1827.       __tp._M_months_abbreviated(__months);
  1828.       int __tmpmon;
  1829.       _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
  1830.  
  1831.       // Check to see if non-abbreviated name exists, and extract.
  1832.       // NB: Assumes both _M_months and _M_months_abbreviated organized in
  1833.       // exact same order, first to last, such that the resulting
  1834.       // __months array with the same index points to a month, and that
  1835.       // month's abbreviated form.
  1836.       // NB: Also assumes that an abbreviated name is a subset of the name. 
  1837.       if (!__err)
  1838.     {
  1839.       size_t __pos = __traits_type::length(__months[__tmpmon]);
  1840.       __tp._M_months(__months);
  1841.       const char_type* __name = __months[__tmpmon];
  1842.       if (__name[__pos] == *__beg)
  1843.         {
  1844.           // Extract the rest of it.
  1845.           const size_t __len = __traits_type::length(__name);
  1846.           while (__pos < __len && __beg != __end 
  1847.              && __name[__pos] == *__beg)
  1848.         ++__beg, ++__pos;
  1849.           if (__len != __pos)
  1850.         __err |= ios_base::failbit;
  1851.         }
  1852.       if (!__err)
  1853.         __tm->tm_mon = __tmpmon;
  1854.     }
  1855.  
  1856.       if (__beg == __end)
  1857.     __err |= ios_base::eofbit;
  1858.       return __beg;
  1859.     }
  1860.  
  1861.   template<typename _CharT, typename _InIter>
  1862.     _InIter
  1863.     time_get<_CharT, _InIter>::
  1864.     do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 
  1865.         ios_base::iostate& __err, tm* __tm) const
  1866.     {
  1867.       locale __loc = __io.getloc();
  1868.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  1869.  
  1870.       char_type __c = *__beg;
  1871.       size_t __i = 0;
  1872.       string __digits;
  1873.       while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
  1874.     {
  1875.       __digits += __ctype.narrow(__c, 0);
  1876.       __c = *(++__beg);
  1877.       ++__i;
  1878.     }
  1879.       if (__i == 2 || __i == 4)
  1880.     {
  1881.       long __l;
  1882.       __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
  1883.       if (!(__err & ios_base::failbit) && __l <= INT_MAX)
  1884.         {
  1885.           __l = __i == 2 ? __l : __l - 1900; 
  1886.           __tm->tm_year = static_cast<int>(__l);
  1887.         }
  1888.     }
  1889.       else
  1890.     __err |= ios_base::failbit;
  1891.       if (__beg == __end)
  1892.     __err |= ios_base::eofbit;
  1893.       return __beg;
  1894.     }
  1895.  
  1896.   template<typename _CharT, typename _OutIter>
  1897.     _OutIter
  1898.     time_put<_CharT, _OutIter>::
  1899.     put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
  1900.     const _CharT* __beg, const _CharT* __end) const
  1901.     {
  1902.       locale __loc = __io.getloc();
  1903.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1904.       while (__beg != __end)
  1905.     {
  1906.       char __c = __ctype.narrow(*__beg, 0);
  1907.       ++__beg;
  1908.       if (__c == '%')
  1909.         {
  1910.           char __format;
  1911.           char __mod = 0;
  1912.           size_t __len = 1; 
  1913.           __c = __ctype.narrow(*__beg, 0);
  1914.           ++__beg;
  1915.           if (__c == 'E' || __c == 'O')
  1916.         {
  1917.           __mod = __c;
  1918.           __format = __ctype.narrow(*__beg, 0);
  1919.           ++__beg;
  1920.         }
  1921.           else
  1922.         __format = __c;
  1923.           __s = this->do_put(__s, __io, char_type(), __tm, __format, 
  1924.                  __mod);
  1925.         }
  1926.       else
  1927.         {
  1928.           *__s = __c;
  1929.           ++__s;
  1930.         }
  1931.     }
  1932.       return __s;
  1933.     }
  1934.  
  1935.   template<typename _CharT, typename _OutIter>
  1936.     _OutIter
  1937.     time_put<_CharT, _OutIter>::
  1938.     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
  1939.        char __format, char __mod) const
  1940.     { 
  1941.       locale __loc = __io.getloc();
  1942.       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
  1943.       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
  1944.  
  1945.       // NB: This size is arbitrary. Should this be a data member,
  1946.       // initialized at construction?
  1947.       const size_t __maxlen = 64;
  1948.       char_type* __res =
  1949.     static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
  1950.  
  1951.       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
  1952.       // is possible that the format character will be longer than one
  1953.       // character. Possibilities include 'E' or 'O' followed by a
  1954.       // format character: if __mod is not the default argument, assume
  1955.       // it's a valid modifier.
  1956.       char_type __fmt[4];
  1957.       __fmt[0] = __ctype.widen('%'); 
  1958.       if (!__mod)
  1959.     {
  1960.       __fmt[1] = __format;
  1961.       __fmt[2] = char_type();
  1962.     }
  1963.       else
  1964.     {
  1965.       __fmt[1] = __mod;
  1966.       __fmt[2] = __format;
  1967.       __fmt[3] = char_type();
  1968.     }
  1969.  
  1970.       __tp._M_put(__res, __maxlen, __fmt, __tm);
  1971.  
  1972.       // Write resulting, fully-formatted string to output iterator.
  1973.       size_t __len = char_traits<char_type>::length(__res);
  1974.       for (size_t __i = 0; __i < __len; ++__i, ++__s)
  1975.     *__s = __res[__i];
  1976.       return __s;
  1977.     }
  1978.  
  1979.  
  1980.   // Generic version does nothing.
  1981.   template<typename _CharT>
  1982.     int
  1983.     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
  1984.     { return 0; }
  1985.  
  1986.   // Generic version does nothing.
  1987.   template<typename _CharT>
  1988.     size_t
  1989.     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
  1990.     { return 0; }
  1991.  
  1992.   template<typename _CharT>
  1993.     int
  1994.     collate<_CharT>::
  1995.     do_compare(const _CharT* __lo1, const _CharT* __hi1, 
  1996.            const _CharT* __lo2, const _CharT* __hi2) const
  1997.     { 
  1998.       const string_type __one(__lo1, __hi1);
  1999.       const string_type __two(__lo2, __hi2);
  2000.       return _M_compare(__one.c_str(), __two.c_str());
  2001.     }
  2002.  
  2003.  template<typename _CharT>
  2004.     typename collate<_CharT>::string_type
  2005.     collate<_CharT>::
  2006.     do_transform(const _CharT* __lo, const _CharT* __hi) const
  2007.     {
  2008.       size_t __len = (__hi - __lo) * 2;
  2009.       // First try a buffer perhaps big enough.
  2010.       _CharT* __c =
  2011.     static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
  2012.       size_t __res = _M_transform(__c, __lo, __len);
  2013.       // If the buffer was not large enough, try again with the correct size.
  2014.       if (__res >= __len)
  2015.     {
  2016.       __c =
  2017.         static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1)));
  2018.       _M_transform(__c, __lo, __res + 1);
  2019.     }
  2020.       return string_type(__c);
  2021.     }
  2022.  
  2023.  template<typename _CharT>
  2024.     long
  2025.     collate<_CharT>::
  2026.     do_hash(const _CharT* __lo, const _CharT* __hi) const
  2027.     { 
  2028.       unsigned long __val = 0;
  2029.       for (; __lo < __hi; ++__lo)
  2030.     __val = *__lo + ((__val << 7) | 
  2031.                (__val >> (numeric_limits<unsigned long>::digits - 7)));
  2032.       return static_cast<long>(__val);
  2033.     }
  2034.  
  2035.   // Convert string to numeric value of type _Tv and store results.  
  2036.   // NB: This is specialized for all required types, there is no
  2037.   // generic definition.
  2038.   template<typename _Tv>
  2039.     void
  2040.     __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, 
  2041.            const __c_locale& __cloc, int __base = 10);
  2042.  
  2043.   // Convert numeric value of type _Tv to string and return length of string.
  2044.   // If snprintf is available use it, otherwise fall back to the unsafe sprintf
  2045.   // which, in general, can be dangerous and should be avoided.
  2046. #ifdef _GLIBCPP_USE_C99
  2047.   template<typename _Tv>
  2048.     int
  2049.     __convert_from_v(char* __out, const int __size, const char* __fmt,
  2050.              _Tv __v, const __c_locale&, int __prec = -1)
  2051.     {
  2052.       int __ret;
  2053.       char* __old = strdup(setlocale(LC_ALL, NULL));
  2054.       setlocale(LC_ALL, "C");
  2055.       if (__prec >= 0)
  2056.         __ret = snprintf(__out, __size, __fmt, __prec, __v);
  2057.       else
  2058.         __ret = snprintf(__out, __size, __fmt, __v);
  2059.       setlocale(LC_ALL, __old);
  2060.       free(__old);
  2061.       return __ret;
  2062.     }
  2063. #else
  2064.   template<typename _Tv>
  2065.     int
  2066.     __convert_from_v(char* __out, const int, const char* __fmt, _Tv __v,
  2067.              const __c_locale&, int __prec = -1)
  2068.     {
  2069.       int __ret;
  2070.       char* __old = strdup(setlocale(LC_ALL, NULL));
  2071.       setlocale(LC_ALL, "C");
  2072.       if (__prec >= 0)
  2073.         __ret = sprintf(__out, __fmt, __prec, __v);
  2074.       else
  2075.         __ret = sprintf(__out, __fmt, __v);
  2076.       setlocale(LC_ALL, __old);
  2077.       free(__old);
  2078.       return __ret;
  2079.     }
  2080. #endif
  2081.  
  2082.  
  2083.   // Construct correctly padded string, as per 22.2.2.2.2
  2084.   // Assumes 
  2085.   // __newlen > __oldlen
  2086.   // __news is allocated for __newlen size
  2087.   // Used by both num_put and ostream inserters: if __num,
  2088.   // internal-adjusted objects are padded according to the rules below
  2089.   // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
  2090.   // ones are.
  2091.  
  2092.   // NB: Of the two parameters, _CharT can be deduced from the
  2093.   // function arguments. The other (_Traits) has to be explicitly specified.
  2094.   template<typename _CharT, typename _Traits>
  2095.     struct __pad
  2096.     {
  2097.       static void
  2098.       _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, 
  2099.          const _CharT* __olds, const streamsize __newlen, 
  2100.          const streamsize __oldlen, const bool __num);
  2101.     };
  2102.  
  2103.   template<typename _CharT, typename _Traits>
  2104.     void 
  2105.     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, 
  2106.                    _CharT* __news, const _CharT* __olds, 
  2107.                    const streamsize __newlen, 
  2108.                    const streamsize __oldlen, const bool __num)
  2109.     {
  2110.       size_t __plen = static_cast<size_t>(__newlen - __oldlen);
  2111.       _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen));
  2112.       _Traits::assign(__pads, __plen, __fill); 
  2113.  
  2114.       _CharT* __beg;
  2115.       _CharT* __end;
  2116.       size_t __mod = 0;
  2117.       size_t __beglen; //either __plen or __oldlen
  2118.       ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
  2119.  
  2120.       if (__adjust == ios_base::left)
  2121.     {
  2122.       // Padding last.
  2123.       __beg = const_cast<_CharT*>(__olds);
  2124.       __beglen = __oldlen;
  2125.       __end = __pads;
  2126.     }
  2127.       else if (__adjust == ios_base::internal && __num)
  2128.     {
  2129.       // Pad after the sign, if there is one.
  2130.       // Pad after 0[xX], if there is one.
  2131.       // Who came up with these rules, anyway? Jeeze.
  2132.           locale __loc = __io.getloc();
  2133.       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
  2134.       const _CharT __minus = __ctype.widen('-');
  2135.       const _CharT __plus = __ctype.widen('+');
  2136.       bool __testsign = _Traits::eq(__olds[0], __minus)
  2137.                     || _Traits::eq(__olds[0], __plus);
  2138.  
  2139.       bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0]) 
  2140.                    && (_Traits::eq(__ctype.widen('x'), __olds[1]) 
  2141.                    || _Traits::eq(__ctype.widen('X'), __olds[1]));
  2142.       if (__testhex)
  2143.         {
  2144.           __news[0] = __olds[0]; 
  2145.           __news[1] = __olds[1];
  2146.           __mod += 2;
  2147.           __news += 2;
  2148.           __beg = __pads;
  2149.           __beglen = __plen;
  2150.           __end = const_cast<_CharT*>(__olds + __mod);
  2151.         }
  2152.       else if (__testsign)
  2153.         {
  2154.           _Traits::eq((__news[0] = __olds[0]), __plus) ? __plus : __minus;
  2155.           ++__mod;
  2156.           ++__news;
  2157.           __beg = __pads;
  2158.           __beglen = __plen;
  2159.           __end = const_cast<_CharT*>(__olds + __mod);
  2160.         }
  2161.       else
  2162.         {
  2163.           // Padding first.
  2164.           __beg = __pads;
  2165.           __beglen = __plen;
  2166.           __end = const_cast<_CharT*>(__olds);
  2167.         }
  2168.     }
  2169.       else
  2170.     {
  2171.       // Padding first.
  2172.       __beg = __pads;
  2173.       __beglen = __plen;
  2174.       __end = const_cast<_CharT*>(__olds);
  2175.     }
  2176.       _Traits::copy(__news, __beg, __beglen);
  2177.       _Traits::copy(__news + __beglen, __end, 
  2178.               __newlen - __beglen - __mod);
  2179.     }
  2180.  
  2181.   // Used by both numeric and monetary facets.
  2182.   // Check to make sure that the __grouping_tmp string constructed in
  2183.   // money_get or num_get matches the canonical grouping for a given
  2184.   // locale.
  2185.   // __grouping_tmp is parsed L to R
  2186.   // 1,222,444 == __grouping_tmp of "/1/3/3"
  2187.   // __grouping is parsed R to L
  2188.   // 1,222,444 == __grouping of "/3" == "/3/3/3"
  2189.   template<typename _CharT>
  2190.     bool
  2191.     __verify_grouping(const basic_string<_CharT>& __grouping, 
  2192.               basic_string<_CharT>& __grouping_tmp)
  2193.     {         
  2194.       int __i = 0;
  2195.       int __j = 0;
  2196.       const int __len = __grouping.size();
  2197.       const int __n = __grouping_tmp.size();
  2198.       bool __test = true;
  2199.       
  2200.       // Parsed number groupings have to match the
  2201.       // numpunct::grouping string exactly, starting at the
  2202.       // right-most point of the parsed sequence of elements ...
  2203.       while (__test && __i < __n - 1)
  2204.     for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
  2205.       __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
  2206.       // ... but the last parsed grouping can be <= numpunct
  2207.       // grouping.
  2208.       __j == __len ? __j = 0 : __j;
  2209.       __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
  2210.       return __test;
  2211.     }
  2212.  
  2213.   // Used by both numeric and monetary facets.
  2214.   // Inserts "group separator" characters into an array of characters.
  2215.   // It's recursive, one iteration per group.  It moves the characters
  2216.   // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
  2217.   // only with __gbeg != __gend.
  2218.   template<typename _CharT>
  2219.     _CharT*
  2220.     __add_grouping(_CharT* __s, _CharT __sep,  
  2221.            const char* __gbeg, const char* __gend, 
  2222.            const _CharT* __first, const _CharT* __last)
  2223.     {
  2224.       if (__last - __first > *__gbeg)
  2225.         {
  2226.           __s = __add_grouping(__s,  __sep, 
  2227.                    (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
  2228.                    __gend, __first, __last - *__gbeg);
  2229.           __first = __last - *__gbeg;
  2230.           *__s++ = __sep;
  2231.         }
  2232.       do
  2233.     *__s++ = *__first++;
  2234.       while (__first != __last);
  2235.       return __s;
  2236.     }
  2237.  
  2238.   // Inhibit implicit instantiations for required instantiations,
  2239.   // which are defined via explicit instantiations elsewhere.  
  2240.   // NB: This syntax is a GNU extension.
  2241.   extern template class moneypunct<char, false>;
  2242.   extern template class moneypunct<char, true>;
  2243.   extern template class moneypunct_byname<char, false>;
  2244.   extern template class moneypunct_byname<char, true>;
  2245.   extern template class money_get<char>;
  2246.   extern template class money_put<char>;
  2247.   extern template class moneypunct<wchar_t, false>;
  2248.   extern template class moneypunct<wchar_t, true>;
  2249.   extern template class moneypunct_byname<wchar_t, false>;
  2250.   extern template class moneypunct_byname<wchar_t, true>;
  2251.   extern template class money_get<wchar_t>;
  2252.   extern template class money_put<wchar_t>;
  2253.   extern template class numpunct<char>;
  2254.   extern template class numpunct_byname<char>;
  2255.   extern template class num_get<char>;
  2256.   extern template class num_put<char>; 
  2257.   extern template class numpunct<wchar_t>;
  2258.   extern template class numpunct_byname<wchar_t>;
  2259.   extern template class num_get<wchar_t>;
  2260.   extern template class num_put<wchar_t>;
  2261.   extern template class __timepunct<char>;
  2262.   extern template class time_put<char>;
  2263.   extern template class time_put_byname<char>;
  2264.   extern template class time_get<char>;
  2265.   extern template class time_get_byname<char>;
  2266.   extern template class __timepunct<wchar_t>;
  2267.   extern template class time_put<wchar_t>;
  2268.   extern template class time_put_byname<wchar_t>;
  2269.   extern template class time_get<wchar_t>;
  2270.   extern template class time_get_byname<wchar_t>;
  2271.   extern template class messages<char>;
  2272.   extern template class messages_byname<char>;
  2273.   extern template class messages<wchar_t>;
  2274.   extern template class messages_byname<wchar_t>;
  2275.   extern template class ctype_byname<char>;
  2276.   extern template class ctype_byname<wchar_t>;
  2277.   extern template class codecvt_byname<char, char, mbstate_t>;
  2278.   extern template class codecvt_byname<wchar_t, char, mbstate_t>;
  2279.   extern template class collate<char>;
  2280.   extern template class collate_byname<char>;
  2281.   extern template class collate<wchar_t>;
  2282.   extern template class collate_byname<wchar_t>;
  2283.  
  2284.   extern template
  2285.     const codecvt<char, char, mbstate_t>& 
  2286.     use_facet<codecvt<char, char, mbstate_t> >(const locale&);
  2287.  
  2288.   extern template
  2289.     const collate<char>& 
  2290.     use_facet<collate<char> >(const locale&);
  2291.  
  2292.   extern template
  2293.     const numpunct<char>& 
  2294.     use_facet<numpunct<char> >(const locale&);
  2295.  
  2296.   extern template 
  2297.     const num_put<char>& 
  2298.     use_facet<num_put<char> >(const locale&);
  2299.  
  2300.   extern template 
  2301.     const num_get<char>& 
  2302.     use_facet<num_get<char> >(const locale&);
  2303.  
  2304.   extern template
  2305.     const moneypunct<char, true>& 
  2306.     use_facet<moneypunct<char, true> >(const locale&);
  2307.  
  2308.   extern template
  2309.     const moneypunct<char, false>& 
  2310.     use_facet<moneypunct<char, false> >(const locale&);
  2311.  
  2312.   extern template 
  2313.     const money_put<char>& 
  2314.     use_facet<money_put<char> >(const locale&);
  2315.  
  2316.   extern template 
  2317.     const money_get<char>& 
  2318.     use_facet<money_get<char> >(const locale&);
  2319.  
  2320.   extern template
  2321.     const __timepunct<char>& 
  2322.     use_facet<__timepunct<char> >(const locale&);
  2323.  
  2324.   extern template 
  2325.     const time_put<char>& 
  2326.     use_facet<time_put<char> >(const locale&);
  2327.  
  2328.   extern template 
  2329.     const time_get<char>& 
  2330.     use_facet<time_get<char> >(const locale&);
  2331.  
  2332.   extern template 
  2333.     const messages<char>& 
  2334.     use_facet<messages<char> >(const locale&);
  2335.  
  2336.   extern template
  2337.     const codecvt<wchar_t, char, mbstate_t>& 
  2338.     use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
  2339.  
  2340.   extern template
  2341.     const collate<wchar_t>& 
  2342.     use_facet<collate<wchar_t> >(const locale&);
  2343.  
  2344.   extern template
  2345.     const numpunct<wchar_t>& 
  2346.     use_facet<numpunct<wchar_t> >(const locale&);
  2347.  
  2348.   extern template 
  2349.     const num_put<wchar_t>& 
  2350.     use_facet<num_put<wchar_t> >(const locale&);
  2351.  
  2352.   extern template 
  2353.     const num_get<wchar_t>& 
  2354.     use_facet<num_get<wchar_t> >(const locale&);
  2355.  
  2356.   extern template
  2357.     const moneypunct<wchar_t, true>& 
  2358.     use_facet<moneypunct<wchar_t, true> >(const locale&);
  2359.  
  2360.   extern template
  2361.     const moneypunct<wchar_t, false>& 
  2362.     use_facet<moneypunct<wchar_t, false> >(const locale&);
  2363.  
  2364.   extern template 
  2365.     const money_put<wchar_t>& 
  2366.     use_facet<money_put<wchar_t> >(const locale&);
  2367.  
  2368.   extern template 
  2369.     const money_get<wchar_t>& 
  2370.     use_facet<money_get<wchar_t> >(const locale&);
  2371.  
  2372.   extern template
  2373.     const __timepunct<wchar_t>& 
  2374.     use_facet<__timepunct<wchar_t> >(const locale&);
  2375.  
  2376.   extern template 
  2377.     const time_put<wchar_t>& 
  2378.     use_facet<time_put<wchar_t> >(const locale&);
  2379.  
  2380.   extern template 
  2381.     const time_get<wchar_t>& 
  2382.     use_facet<time_get<wchar_t> >(const locale&);
  2383.  
  2384.   extern template 
  2385.     const messages<wchar_t>& 
  2386.     use_facet<messages<wchar_t> >(const locale&);
  2387.  
  2388.  
  2389.   extern template 
  2390.     bool
  2391.     has_facet<ctype<char> >(const locale&);
  2392.  
  2393.   extern template 
  2394.     bool
  2395.     has_facet<codecvt<char, char, mbstate_t> >(const locale&);
  2396.  
  2397.   extern template 
  2398.     bool
  2399.     has_facet<collate<char> >(const locale&);
  2400.  
  2401.   extern template 
  2402.     bool
  2403.     has_facet<numpunct<char> >(const locale&);
  2404.  
  2405.   extern template 
  2406.     bool
  2407.     has_facet<num_put<char> >(const locale&);
  2408.  
  2409.   extern template 
  2410.     bool
  2411.     has_facet<num_get<char> >(const locale&);
  2412.  
  2413.   extern template 
  2414.     bool
  2415.     has_facet<moneypunct<char> >(const locale&);
  2416.  
  2417.   extern template 
  2418.     bool
  2419.     has_facet<money_put<char> >(const locale&);
  2420.  
  2421.   extern template 
  2422.     bool
  2423.     has_facet<money_get<char> >(const locale&);
  2424.  
  2425.   extern template 
  2426.     bool
  2427.     has_facet<__timepunct<char> >(const locale&);
  2428.  
  2429.   extern template 
  2430.     bool
  2431.     has_facet<time_put<char> >(const locale&);
  2432.  
  2433.   extern template 
  2434.     bool
  2435.     has_facet<time_get<char> >(const locale&);
  2436.  
  2437.   extern template 
  2438.     bool
  2439.     has_facet<messages<char> >(const locale&);
  2440.  
  2441.  extern template 
  2442.     bool
  2443.     has_facet<ctype<wchar_t> >(const locale&);
  2444.  
  2445.   extern template 
  2446.     bool
  2447.     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
  2448.  
  2449.   extern template 
  2450.     bool
  2451.     has_facet<collate<wchar_t> >(const locale&);
  2452.  
  2453.   extern template 
  2454.     bool
  2455.     has_facet<numpunct<wchar_t> >(const locale&);
  2456.  
  2457.   extern template 
  2458.     bool
  2459.     has_facet<num_put<wchar_t> >(const locale&);
  2460.  
  2461.   extern template 
  2462.     bool
  2463.     has_facet<num_get<wchar_t> >(const locale&);
  2464.  
  2465.   extern template 
  2466.     bool
  2467.     has_facet<moneypunct<wchar_t> >(const locale&);
  2468.  
  2469.   extern template 
  2470.     bool
  2471.     has_facet<money_put<wchar_t> >(const locale&);
  2472.  
  2473.   extern template 
  2474.     bool
  2475.     has_facet<money_get<wchar_t> >(const locale&);
  2476.  
  2477.   extern template 
  2478.     bool
  2479.     has_facet<__timepunct<wchar_t> >(const locale&);
  2480.  
  2481.   extern template 
  2482.     bool
  2483.     has_facet<time_put<wchar_t> >(const locale&);
  2484.  
  2485.   extern template 
  2486.     bool
  2487.     has_facet<time_get<wchar_t> >(const locale&);
  2488.  
  2489.   extern template 
  2490.     bool
  2491.     has_facet<messages<wchar_t> >(const locale&);
  2492. } // namespace std
  2493.  
  2494. #endif
  2495.