home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / locale_facets.tcc < prev    next >
Text File  |  2005-01-29  |  86KB  |  2,794 lines

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