Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Locale support -*- C++ -*-
  2.  
  3. // Copyright (C) 1997-2013 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file bits/locale_facets.tcc
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{locale}
  28.  */
  29.  
  30. #ifndef _LOCALE_FACETS_TCC
  31. #define _LOCALE_FACETS_TCC 1
  32.  
  33. #pragma GCC system_header
  34.  
  35. namespace std _GLIBCXX_VISIBILITY(default)
  36. {
  37. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  38.  
  39.   // Routine to access a cache for the facet.  If the cache didn't
  40.   // exist before, it gets constructed on the fly.
  41.   template<typename _Facet>
  42.     struct __use_cache
  43.     {
  44.       const _Facet*
  45.       operator() (const locale& __loc) const;
  46.     };
  47.  
  48.   // Specializations.
  49.   template<typename _CharT>
  50.     struct __use_cache<__numpunct_cache<_CharT> >
  51.     {
  52.       const __numpunct_cache<_CharT>*
  53.       operator() (const locale& __loc) const
  54.       {
  55.         const size_t __i = numpunct<_CharT>::id._M_id();
  56.         const locale::facet** __caches = __loc._M_impl->_M_caches;
  57.         if (!__caches[__i])
  58.           {
  59.             __numpunct_cache<_CharT>* __tmp = 0;
  60.             __try
  61.               {
  62.                 __tmp = new __numpunct_cache<_CharT>;
  63.                 __tmp->_M_cache(__loc);
  64.               }
  65.             __catch(...)
  66.               {
  67.                 delete __tmp;
  68.                 __throw_exception_again;
  69.               }
  70.             __loc._M_impl->_M_install_cache(__tmp, __i);
  71.           }
  72.         return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
  73.       }
  74.     };
  75.  
  76.   template<typename _CharT>
  77.     void
  78.     __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
  79.     {
  80.       _M_allocated = true;
  81.  
  82.       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
  83.  
  84.       char* __grouping = 0;
  85.       _CharT* __truename = 0;
  86.       _CharT* __falsename = 0;
  87.       __try
  88.         {
  89.           _M_grouping_size = __np.grouping().size();
  90.           __grouping = new char[_M_grouping_size];
  91.           __np.grouping().copy(__grouping, _M_grouping_size);
  92.           _M_grouping = __grouping;
  93.           _M_use_grouping = (_M_grouping_size
  94.                              && static_cast<signed char>(_M_grouping[0]) > 0
  95.                              && (_M_grouping[0]
  96.                                  != __gnu_cxx::__numeric_traits<char>::__max));
  97.  
  98.           _M_truename_size = __np.truename().size();
  99.           __truename = new _CharT[_M_truename_size];
  100.           __np.truename().copy(__truename, _M_truename_size);
  101.           _M_truename = __truename;
  102.  
  103.           _M_falsename_size = __np.falsename().size();
  104.           __falsename = new _CharT[_M_falsename_size];
  105.           __np.falsename().copy(__falsename, _M_falsename_size);
  106.           _M_falsename = __falsename;
  107.  
  108.           _M_decimal_point = __np.decimal_point();
  109.           _M_thousands_sep = __np.thousands_sep();
  110.  
  111.           const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
  112.           __ct.widen(__num_base::_S_atoms_out,
  113.                      __num_base::_S_atoms_out
  114.                      + __num_base::_S_oend, _M_atoms_out);
  115.           __ct.widen(__num_base::_S_atoms_in,
  116.                      __num_base::_S_atoms_in
  117.                      + __num_base::_S_iend, _M_atoms_in);
  118.         }
  119.       __catch(...)
  120.         {
  121.           delete [] __grouping;
  122.           delete [] __truename;
  123.           delete [] __falsename;
  124.           __throw_exception_again;
  125.         }
  126.     }
  127.  
  128.   // Used by both numeric and monetary facets.
  129.   // Check to make sure that the __grouping_tmp string constructed in
  130.   // money_get or num_get matches the canonical grouping for a given
  131.   // locale.
  132.   // __grouping_tmp is parsed L to R
  133.   // 1,222,444 == __grouping_tmp of "\1\3\3"
  134.   // __grouping is parsed R to L
  135.   // 1,222,444 == __grouping of "\3" == "\3\3\3"
  136.   _GLIBCXX_PURE bool
  137.   __verify_grouping(const char* __grouping, size_t __grouping_size,
  138.                     const string& __grouping_tmp) throw ();
  139.  
  140. _GLIBCXX_BEGIN_NAMESPACE_LDBL
  141.  
  142.   template<typename _CharT, typename _InIter>
  143.     _InIter
  144.     num_get<_CharT, _InIter>::
  145.     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
  146.                      ios_base::iostate& __err, string& __xtrc) const
  147.     {
  148.       typedef char_traits<_CharT>                       __traits_type;
  149.       typedef __numpunct_cache<_CharT>                  __cache_type;
  150.       __use_cache<__cache_type> __uc;
  151.       const locale& __loc = __io._M_getloc();
  152.       const __cache_type* __lc = __uc(__loc);
  153.       const _CharT* __lit = __lc->_M_atoms_in;
  154.       char_type __c = char_type();
  155.  
  156.       // True if __beg becomes equal to __end.
  157.       bool __testeof = __beg == __end;
  158.  
  159.       // First check for sign.
  160.       if (!__testeof)
  161.         {
  162.           __c = *__beg;
  163.           const bool __plus = __c == __lit[__num_base::_S_iplus];
  164.           if ((__plus || __c == __lit[__num_base::_S_iminus])
  165.               && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  166.               && !(__c == __lc->_M_decimal_point))
  167.             {
  168.               __xtrc += __plus ? '+' : '-';
  169.               if (++__beg != __end)
  170.                 __c = *__beg;
  171.               else
  172.                 __testeof = true;
  173.             }
  174.         }
  175.  
  176.       // Next, look for leading zeros.
  177.       bool __found_mantissa = false;
  178.       int __sep_pos = 0;
  179.       while (!__testeof)
  180.         {
  181.           if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  182.               || __c == __lc->_M_decimal_point)
  183.             break;
  184.           else if (__c == __lit[__num_base::_S_izero])
  185.             {
  186.               if (!__found_mantissa)
  187.                 {
  188.                   __xtrc += '0';
  189.                   __found_mantissa = true;
  190.                 }
  191.               ++__sep_pos;
  192.  
  193.               if (++__beg != __end)
  194.                 __c = *__beg;
  195.               else
  196.                 __testeof = true;
  197.             }
  198.           else
  199.             break;
  200.         }
  201.  
  202.       // Only need acceptable digits for floating point numbers.
  203.       bool __found_dec = false;
  204.       bool __found_sci = false;
  205.       string __found_grouping;
  206.       if (__lc->_M_use_grouping)
  207.         __found_grouping.reserve(32);
  208.       const char_type* __lit_zero = __lit + __num_base::_S_izero;
  209.  
  210.       if (!__lc->_M_allocated)
  211.         // "C" locale
  212.         while (!__testeof)
  213.           {
  214.             const int __digit = _M_find(__lit_zero, 10, __c);
  215.             if (__digit != -1)
  216.               {
  217.                 __xtrc += '0' + __digit;
  218.                 __found_mantissa = true;
  219.               }
  220.             else if (__c == __lc->_M_decimal_point
  221.                      && !__found_dec && !__found_sci)
  222.               {
  223.                 __xtrc += '.';
  224.                 __found_dec = true;
  225.               }
  226.             else if ((__c == __lit[__num_base::_S_ie]
  227.                       || __c == __lit[__num_base::_S_iE])
  228.                      && !__found_sci && __found_mantissa)
  229.               {
  230.                 // Scientific notation.
  231.                 __xtrc += 'e';
  232.                 __found_sci = true;
  233.                
  234.                 // Remove optional plus or minus sign, if they exist.
  235.                 if (++__beg != __end)
  236.                   {
  237.                     __c = *__beg;
  238.                     const bool __plus = __c == __lit[__num_base::_S_iplus];
  239.                     if (__plus || __c == __lit[__num_base::_S_iminus])
  240.                       __xtrc += __plus ? '+' : '-';
  241.                     else
  242.                       continue;
  243.                   }
  244.                 else
  245.                   {
  246.                     __testeof = true;
  247.                     break;
  248.                   }
  249.               }
  250.             else
  251.               break;
  252.  
  253.             if (++__beg != __end)
  254.               __c = *__beg;
  255.             else
  256.               __testeof = true;
  257.           }
  258.       else
  259.         while (!__testeof)
  260.           {
  261.             // According to 22.2.2.1.2, p8-9, first look for thousands_sep
  262.             // and decimal_point.
  263.             if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  264.               {
  265.                 if (!__found_dec && !__found_sci)
  266.                   {
  267.                     // NB: Thousands separator at the beginning of a string
  268.                     // is a no-no, as is two consecutive thousands separators.
  269.                     if (__sep_pos)
  270.                       {
  271.                         __found_grouping += static_cast<char>(__sep_pos);
  272.                         __sep_pos = 0;
  273.                       }
  274.                     else
  275.                       {
  276.                         // NB: __convert_to_v will not assign __v and will
  277.                         // set the failbit.
  278.                         __xtrc.clear();
  279.                         break;
  280.                       }
  281.                   }
  282.                 else
  283.                   break;
  284.               }
  285.             else if (__c == __lc->_M_decimal_point)
  286.               {
  287.                 if (!__found_dec && !__found_sci)
  288.                   {
  289.                     // If no grouping chars are seen, no grouping check
  290.                     // is applied. Therefore __found_grouping is adjusted
  291.                     // only if decimal_point comes after some thousands_sep.
  292.                     if (__found_grouping.size())
  293.                       __found_grouping += static_cast<char>(__sep_pos);
  294.                     __xtrc += '.';
  295.                     __found_dec = true;
  296.                   }
  297.                 else
  298.                   break;
  299.               }
  300.             else
  301.               {
  302.                 const char_type* __q =
  303.                   __traits_type::find(__lit_zero, 10, __c);
  304.                 if (__q)
  305.                   {
  306.                     __xtrc += '0' + (__q - __lit_zero);
  307.                     __found_mantissa = true;
  308.                     ++__sep_pos;
  309.                   }
  310.                 else if ((__c == __lit[__num_base::_S_ie]
  311.                           || __c == __lit[__num_base::_S_iE])
  312.                          && !__found_sci && __found_mantissa)
  313.                   {
  314.                     // Scientific notation.
  315.                     if (__found_grouping.size() && !__found_dec)
  316.                       __found_grouping += static_cast<char>(__sep_pos);
  317.                     __xtrc += 'e';
  318.                     __found_sci = true;
  319.                    
  320.                     // Remove optional plus or minus sign, if they exist.
  321.                     if (++__beg != __end)
  322.                       {
  323.                         __c = *__beg;
  324.                         const bool __plus = __c == __lit[__num_base::_S_iplus];
  325.                         if ((__plus || __c == __lit[__num_base::_S_iminus])
  326.                             && !(__lc->_M_use_grouping
  327.                                  && __c == __lc->_M_thousands_sep)
  328.                             && !(__c == __lc->_M_decimal_point))
  329.                       __xtrc += __plus ? '+' : '-';
  330.                         else
  331.                           continue;
  332.                       }
  333.                     else
  334.                       {
  335.                         __testeof = true;
  336.                         break;
  337.                       }
  338.                   }
  339.                 else
  340.                   break;
  341.               }
  342.            
  343.             if (++__beg != __end)
  344.               __c = *__beg;
  345.             else
  346.               __testeof = true;
  347.           }
  348.  
  349.       // Digit grouping is checked. If grouping and found_grouping don't
  350.       // match, then get very very upset, and set failbit.
  351.       if (__found_grouping.size())
  352.         {
  353.           // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
  354.           if (!__found_dec && !__found_sci)
  355.             __found_grouping += static_cast<char>(__sep_pos);
  356.  
  357.           if (!std::__verify_grouping(__lc->_M_grouping,
  358.                                       __lc->_M_grouping_size,
  359.                                       __found_grouping))
  360.             __err = ios_base::failbit;
  361.         }
  362.  
  363.       return __beg;
  364.     }
  365.  
  366.   template<typename _CharT, typename _InIter>
  367.     template<typename _ValueT>
  368.       _InIter
  369.       num_get<_CharT, _InIter>::
  370.       _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
  371.                      ios_base::iostate& __err, _ValueT& __v) const
  372.       {
  373.         typedef char_traits<_CharT>                          __traits_type;
  374.         using __gnu_cxx::__add_unsigned;
  375.         typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
  376.         typedef __numpunct_cache<_CharT>                     __cache_type;
  377.         __use_cache<__cache_type> __uc;
  378.         const locale& __loc = __io._M_getloc();
  379.         const __cache_type* __lc = __uc(__loc);
  380.         const _CharT* __lit = __lc->_M_atoms_in;
  381.         char_type __c = char_type();
  382.  
  383.         // NB: Iff __basefield == 0, __base can change based on contents.
  384.         const ios_base::fmtflags __basefield = __io.flags()
  385.                                                & ios_base::basefield;
  386.         const bool __oct = __basefield == ios_base::oct;
  387.         int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
  388.  
  389.         // True if __beg becomes equal to __end.
  390.         bool __testeof = __beg == __end;
  391.  
  392.         // First check for sign.
  393.         bool __negative = false;
  394.         if (!__testeof)
  395.           {
  396.             __c = *__beg;
  397.             __negative = __c == __lit[__num_base::_S_iminus];
  398.             if ((__negative || __c == __lit[__num_base::_S_iplus])
  399.                 && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  400.                 && !(__c == __lc->_M_decimal_point))
  401.               {
  402.                 if (++__beg != __end)
  403.                   __c = *__beg;
  404.                 else
  405.                   __testeof = true;
  406.               }
  407.           }
  408.  
  409.         // Next, look for leading zeros and check required digits
  410.         // for base formats.
  411.         bool __found_zero = false;
  412.         int __sep_pos = 0;
  413.         while (!__testeof)
  414.           {
  415.             if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  416.                 || __c == __lc->_M_decimal_point)
  417.               break;
  418.             else if (__c == __lit[__num_base::_S_izero]
  419.                      && (!__found_zero || __base == 10))
  420.               {
  421.                 __found_zero = true;
  422.                 ++__sep_pos;
  423.                 if (__basefield == 0)
  424.                   __base = 8;
  425.                 if (__base == 8)
  426.                   __sep_pos = 0;
  427.               }
  428.             else if (__found_zero
  429.                      && (__c == __lit[__num_base::_S_ix]
  430.                          || __c == __lit[__num_base::_S_iX]))
  431.               {
  432.                 if (__basefield == 0)
  433.                   __base = 16;
  434.                 if (__base == 16)
  435.                   {
  436.                     __found_zero = false;
  437.                     __sep_pos = 0;
  438.                   }
  439.                 else
  440.                   break;
  441.               }
  442.             else
  443.               break;
  444.  
  445.             if (++__beg != __end)
  446.               {
  447.                 __c = *__beg;
  448.                 if (!__found_zero)
  449.                   break;
  450.               }
  451.             else
  452.               __testeof = true;
  453.           }
  454.        
  455.         // At this point, base is determined. If not hex, only allow
  456.         // base digits as valid input.
  457.         const size_t __len = (__base == 16 ? __num_base::_S_iend
  458.                               - __num_base::_S_izero : __base);
  459.  
  460.         // Extract.
  461.         string __found_grouping;
  462.         if (__lc->_M_use_grouping)
  463.           __found_grouping.reserve(32);
  464.         bool __testfail = false;
  465.         bool __testoverflow = false;
  466.         const __unsigned_type __max =
  467.           (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
  468.           ? -__gnu_cxx::__numeric_traits<_ValueT>::__min
  469.           : __gnu_cxx::__numeric_traits<_ValueT>::__max;
  470.         const __unsigned_type __smax = __max / __base;
  471.         __unsigned_type __result = 0;
  472.         int __digit = 0;
  473.         const char_type* __lit_zero = __lit + __num_base::_S_izero;
  474.  
  475.         if (!__lc->_M_allocated)
  476.           // "C" locale
  477.           while (!__testeof)
  478.             {
  479.               __digit = _M_find(__lit_zero, __len, __c);
  480.               if (__digit == -1)
  481.                 break;
  482.              
  483.               if (__result > __smax)
  484.                 __testoverflow = true;
  485.               else
  486.                 {
  487.                   __result *= __base;
  488.                   __testoverflow |= __result > __max - __digit;
  489.                   __result += __digit;
  490.                   ++__sep_pos;
  491.                 }
  492.              
  493.               if (++__beg != __end)
  494.                 __c = *__beg;
  495.               else
  496.                 __testeof = true;
  497.             }
  498.         else
  499.           while (!__testeof)
  500.             {
  501.               // According to 22.2.2.1.2, p8-9, first look for thousands_sep
  502.               // and decimal_point.
  503.               if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
  504.                 {
  505.                   // NB: Thousands separator at the beginning of a string
  506.                   // is a no-no, as is two consecutive thousands separators.
  507.                   if (__sep_pos)
  508.                     {
  509.                       __found_grouping += static_cast<char>(__sep_pos);
  510.                       __sep_pos = 0;
  511.                     }
  512.                   else
  513.                     {
  514.                       __testfail = true;
  515.                       break;
  516.                     }
  517.                 }
  518.               else if (__c == __lc->_M_decimal_point)
  519.                 break;
  520.               else
  521.                 {
  522.                   const char_type* __q =
  523.                     __traits_type::find(__lit_zero, __len, __c);
  524.                   if (!__q)
  525.                     break;
  526.                  
  527.                   __digit = __q - __lit_zero;
  528.                   if (__digit > 15)
  529.                     __digit -= 6;
  530.                   if (__result > __smax)
  531.                     __testoverflow = true;
  532.                   else
  533.                     {
  534.                       __result *= __base;
  535.                       __testoverflow |= __result > __max - __digit;
  536.                       __result += __digit;
  537.                       ++__sep_pos;
  538.                     }
  539.                 }
  540.              
  541.               if (++__beg != __end)
  542.                 __c = *__beg;
  543.               else
  544.                 __testeof = true;
  545.             }
  546.        
  547.         // Digit grouping is checked. If grouping and found_grouping don't
  548.         // match, then get very very upset, and set failbit.
  549.         if (__found_grouping.size())
  550.           {
  551.             // Add the ending grouping.
  552.             __found_grouping += static_cast<char>(__sep_pos);
  553.  
  554.             if (!std::__verify_grouping(__lc->_M_grouping,
  555.                                         __lc->_M_grouping_size,
  556.                                         __found_grouping))
  557.               __err = ios_base::failbit;
  558.           }
  559.  
  560.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  561.         // 23. Num_get overflow result.
  562.         if ((!__sep_pos && !__found_zero && !__found_grouping.size())
  563.             || __testfail)
  564.           {
  565.             __v = 0;
  566.             __err = ios_base::failbit;
  567.           }
  568.         else if (__testoverflow)
  569.           {
  570.             if (__negative
  571.                 && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
  572.               __v = __gnu_cxx::__numeric_traits<_ValueT>::__min;
  573.             else
  574.               __v = __gnu_cxx::__numeric_traits<_ValueT>::__max;
  575.             __err = ios_base::failbit;
  576.           }
  577.         else
  578.           __v = __negative ? -__result : __result;
  579.  
  580.         if (__testeof)
  581.           __err |= ios_base::eofbit;
  582.         return __beg;
  583.       }
  584.  
  585.   // _GLIBCXX_RESOLVE_LIB_DEFECTS
  586.   // 17.  Bad bool parsing
  587.   template<typename _CharT, typename _InIter>
  588.     _InIter
  589.     num_get<_CharT, _InIter>::
  590.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  591.            ios_base::iostate& __err, bool& __v) const
  592.     {
  593.       if (!(__io.flags() & ios_base::boolalpha))
  594.         {
  595.           // Parse bool values as long.
  596.           // NB: We can't just call do_get(long) here, as it might
  597.           // refer to a derived class.
  598.           long __l = -1;
  599.           __beg = _M_extract_int(__beg, __end, __io, __err, __l);
  600.           if (__l == 0 || __l == 1)
  601.             __v = bool(__l);
  602.           else
  603.             {
  604.               // _GLIBCXX_RESOLVE_LIB_DEFECTS
  605.               // 23. Num_get overflow result.
  606.               __v = true;
  607.               __err = ios_base::failbit;
  608.               if (__beg == __end)
  609.                 __err |= ios_base::eofbit;
  610.             }
  611.         }
  612.       else
  613.         {
  614.           // Parse bool values as alphanumeric.
  615.           typedef __numpunct_cache<_CharT>  __cache_type;
  616.           __use_cache<__cache_type> __uc;
  617.           const locale& __loc = __io._M_getloc();
  618.           const __cache_type* __lc = __uc(__loc);
  619.  
  620.           bool __testf = true;
  621.           bool __testt = true;
  622.           bool __donef = __lc->_M_falsename_size == 0;
  623.           bool __donet = __lc->_M_truename_size == 0;
  624.           bool __testeof = false;
  625.           size_t __n = 0;
  626.           while (!__donef || !__donet)
  627.             {
  628.               if (__beg == __end)
  629.                 {
  630.                   __testeof = true;
  631.                   break;
  632.                 }
  633.  
  634.               const char_type __c = *__beg;
  635.  
  636.               if (!__donef)
  637.                 __testf = __c == __lc->_M_falsename[__n];
  638.  
  639.               if (!__testf && __donet)
  640.                 break;
  641.  
  642.               if (!__donet)
  643.                 __testt = __c == __lc->_M_truename[__n];
  644.  
  645.               if (!__testt && __donef)
  646.                 break;
  647.  
  648.               if (!__testt && !__testf)
  649.                 break;
  650.  
  651.               ++__n;
  652.               ++__beg;
  653.  
  654.               __donef = !__testf || __n >= __lc->_M_falsename_size;
  655.               __donet = !__testt || __n >= __lc->_M_truename_size;
  656.             }
  657.           if (__testf && __n == __lc->_M_falsename_size && __n)
  658.             {
  659.               __v = false;
  660.               if (__testt && __n == __lc->_M_truename_size)
  661.                 __err = ios_base::failbit;
  662.               else
  663.                 __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
  664.             }
  665.           else if (__testt && __n == __lc->_M_truename_size && __n)
  666.             {
  667.               __v = true;
  668.               __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
  669.             }
  670.           else
  671.             {
  672.               // _GLIBCXX_RESOLVE_LIB_DEFECTS
  673.               // 23. Num_get overflow result.
  674.               __v = false;
  675.               __err = ios_base::failbit;
  676.               if (__testeof)
  677.                 __err |= ios_base::eofbit;
  678.             }
  679.         }
  680.       return __beg;
  681.     }
  682.  
  683.   template<typename _CharT, typename _InIter>
  684.     _InIter
  685.     num_get<_CharT, _InIter>::
  686.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  687.            ios_base::iostate& __err, float& __v) const
  688.     {
  689.       string __xtrc;
  690.       __xtrc.reserve(32);
  691.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  692.       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  693.       if (__beg == __end)
  694.         __err |= ios_base::eofbit;
  695.       return __beg;
  696.     }
  697.  
  698.   template<typename _CharT, typename _InIter>
  699.     _InIter
  700.     num_get<_CharT, _InIter>::
  701.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  702.            ios_base::iostate& __err, double& __v) const
  703.     {
  704.       string __xtrc;
  705.       __xtrc.reserve(32);
  706.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  707.       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  708.       if (__beg == __end)
  709.         __err |= ios_base::eofbit;
  710.       return __beg;
  711.     }
  712.  
  713. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
  714.   template<typename _CharT, typename _InIter>
  715.     _InIter
  716.     num_get<_CharT, _InIter>::
  717.     __do_get(iter_type __beg, iter_type __end, ios_base& __io,
  718.              ios_base::iostate& __err, double& __v) const
  719.     {
  720.       string __xtrc;
  721.       __xtrc.reserve(32);
  722.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  723.       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  724.       if (__beg == __end)
  725.         __err |= ios_base::eofbit;
  726.       return __beg;
  727.     }
  728. #endif
  729.  
  730.   template<typename _CharT, typename _InIter>
  731.     _InIter
  732.     num_get<_CharT, _InIter>::
  733.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  734.            ios_base::iostate& __err, long double& __v) const
  735.     {
  736.       string __xtrc;
  737.       __xtrc.reserve(32);
  738.       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
  739.       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
  740.       if (__beg == __end)
  741.         __err |= ios_base::eofbit;
  742.       return __beg;
  743.     }
  744.  
  745.   template<typename _CharT, typename _InIter>
  746.     _InIter
  747.     num_get<_CharT, _InIter>::
  748.     do_get(iter_type __beg, iter_type __end, ios_base& __io,
  749.            ios_base::iostate& __err, void*& __v) const
  750.     {
  751.       // Prepare for hex formatted input.
  752.       typedef ios_base::fmtflags        fmtflags;
  753.       const fmtflags __fmt = __io.flags();
  754.       __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
  755.  
  756.       typedef __gnu_cxx::__conditional_type<(sizeof(void*)
  757.                                              <= sizeof(unsigned long)),
  758.         unsigned long, unsigned long long>::__type _UIntPtrType;      
  759.  
  760.       _UIntPtrType __ul;
  761.       __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
  762.  
  763.       // Reset from hex formatted input.
  764.       __io.flags(__fmt);
  765.  
  766.       __v = reinterpret_cast<void*>(__ul);
  767.       return __beg;
  768.     }
  769.  
  770.   // For use by integer and floating-point types after they have been
  771.   // converted into a char_type string.
  772.   template<typename _CharT, typename _OutIter>
  773.     void
  774.     num_put<_CharT, _OutIter>::
  775.     _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
  776.            _CharT* __new, const _CharT* __cs, int& __len) const
  777.     {
  778.       // [22.2.2.2.2] Stage 3.
  779.       // If necessary, pad.
  780.       __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new,
  781.                                                   __cs, __w, __len);
  782.       __len = static_cast<int>(__w);
  783.     }
  784.  
  785. _GLIBCXX_END_NAMESPACE_LDBL
  786.  
  787.   template<typename _CharT, typename _ValueT>
  788.     int
  789.     __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
  790.                   ios_base::fmtflags __flags, bool __dec)
  791.     {
  792.       _CharT* __buf = __bufend;
  793.       if (__builtin_expect(__dec, true))
  794.         {
  795.           // Decimal.
  796.           do
  797.             {
  798.               *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
  799.               __v /= 10;
  800.             }
  801.           while (__v != 0);
  802.         }
  803.       else if ((__flags & ios_base::basefield) == ios_base::oct)
  804.         {
  805.           // Octal.
  806.           do
  807.             {
  808.               *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
  809.               __v >>= 3;
  810.             }
  811.           while (__v != 0);
  812.         }
  813.       else
  814.         {
  815.           // Hex.
  816.           const bool __uppercase = __flags & ios_base::uppercase;
  817.           const int __case_offset = __uppercase ? __num_base::_S_oudigits
  818.                                                 : __num_base::_S_odigits;
  819.           do
  820.             {
  821.               *--__buf = __lit[(__v & 0xf) + __case_offset];
  822.               __v >>= 4;
  823.             }
  824.           while (__v != 0);
  825.         }
  826.       return __bufend - __buf;
  827.     }
  828.  
  829. _GLIBCXX_BEGIN_NAMESPACE_LDBL
  830.  
  831.   template<typename _CharT, typename _OutIter>
  832.     void
  833.     num_put<_CharT, _OutIter>::
  834.     _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
  835.                  ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
  836.     {
  837.       _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
  838.                                         __grouping_size, __cs, __cs + __len);
  839.       __len = __p - __new;
  840.     }
  841.  
  842.   template<typename _CharT, typename _OutIter>
  843.     template<typename _ValueT>
  844.       _OutIter
  845.       num_put<_CharT, _OutIter>::
  846.       _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
  847.                     _ValueT __v) const
  848.       {
  849.         using __gnu_cxx::__add_unsigned;
  850.         typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
  851.         typedef __numpunct_cache<_CharT>                     __cache_type;
  852.         __use_cache<__cache_type> __uc;
  853.         const locale& __loc = __io._M_getloc();
  854.         const __cache_type* __lc = __uc(__loc);
  855.         const _CharT* __lit = __lc->_M_atoms_out;
  856.         const ios_base::fmtflags __flags = __io.flags();
  857.  
  858.         // Long enough to hold hex, dec, and octal representations.
  859.         const int __ilen = 5 * sizeof(_ValueT);
  860.         _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  861.                                                              * __ilen));
  862.  
  863.         // [22.2.2.2.2] Stage 1, numeric conversion to character.
  864.         // Result is returned right-justified in the buffer.
  865.         const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
  866.         const bool __dec = (__basefield != ios_base::oct
  867.                             && __basefield != ios_base::hex);
  868.         const __unsigned_type __u = ((__v > 0 || !__dec)
  869.                                      ? __unsigned_type(__v)
  870.                                      : -__unsigned_type(__v));
  871.         int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec);
  872.         __cs += __ilen - __len;
  873.  
  874.         // Add grouping, if necessary.
  875.         if (__lc->_M_use_grouping)
  876.           {
  877.             // Grouping can add (almost) as many separators as the number
  878.             // of digits + space is reserved for numeric base or sign.
  879.             _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  880.                                                                   * (__len + 1)
  881.                                                                   * 2));
  882.             _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
  883.                          __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
  884.             __cs = __cs2 + 2;
  885.           }
  886.  
  887.         // Complete Stage 1, prepend numeric base or sign.
  888.         if (__builtin_expect(__dec, true))
  889.           {
  890.             // Decimal.
  891.             if (__v >= 0)
  892.               {
  893.                 if (bool(__flags & ios_base::showpos)
  894.                     && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
  895.                   *--__cs = __lit[__num_base::_S_oplus], ++__len;
  896.               }
  897.             else
  898.               *--__cs = __lit[__num_base::_S_ominus], ++__len;
  899.           }
  900.         else if (bool(__flags & ios_base::showbase) && __v)
  901.           {
  902.             if (__basefield == ios_base::oct)
  903.               *--__cs = __lit[__num_base::_S_odigits], ++__len;
  904.             else
  905.               {
  906.                 // 'x' or 'X'
  907.                 const bool __uppercase = __flags & ios_base::uppercase;
  908.                 *--__cs = __lit[__num_base::_S_ox + __uppercase];
  909.                 // '0'
  910.                 *--__cs = __lit[__num_base::_S_odigits];
  911.                 __len += 2;
  912.               }
  913.           }
  914.  
  915.         // Pad.
  916.         const streamsize __w = __io.width();
  917.         if (__w > static_cast<streamsize>(__len))
  918.           {
  919.             _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  920.                                                                   * __w));
  921.             _M_pad(__fill, __w, __io, __cs3, __cs, __len);
  922.             __cs = __cs3;
  923.           }
  924.         __io.width(0);
  925.  
  926.         // [22.2.2.2.2] Stage 4.
  927.         // Write resulting, fully-formatted string to output iterator.
  928.         return std::__write(__s, __cs, __len);
  929.       }
  930.  
  931.   template<typename _CharT, typename _OutIter>
  932.     void
  933.     num_put<_CharT, _OutIter>::
  934.     _M_group_float(const char* __grouping, size_t __grouping_size,
  935.                    _CharT __sep, const _CharT* __p, _CharT* __new,
  936.                    _CharT* __cs, int& __len) const
  937.     {
  938.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  939.       // 282. What types does numpunct grouping refer to?
  940.       // Add grouping, if necessary.
  941.       const int __declen = __p ? __p - __cs : __len;
  942.       _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
  943.                                          __grouping_size,
  944.                                          __cs, __cs + __declen);
  945.  
  946.       // Tack on decimal part.
  947.       int __newlen = __p2 - __new;
  948.       if (__p)
  949.         {
  950.           char_traits<_CharT>::copy(__p2, __p, __len - __declen);
  951.           __newlen += __len - __declen;
  952.         }
  953.       __len = __newlen;
  954.     }
  955.  
  956.   // The following code uses vsnprintf (or vsprintf(), when
  957.   // _GLIBCXX_USE_C99 is not defined) to convert floating point values
  958.   // for insertion into a stream.  An optimization would be to replace
  959.   // them with code that works directly on a wide buffer and then use
  960.   // __pad to do the padding.  It would be good to replace them anyway
  961.   // to gain back the efficiency that C++ provides by knowing up front
  962.   // the type of the values to insert.  Also, sprintf is dangerous
  963.   // since may lead to accidental buffer overruns.  This
  964.   // implementation follows the C++ standard fairly directly as
  965.   // outlined in 22.2.2.2 [lib.locale.num.put]
  966.   template<typename _CharT, typename _OutIter>
  967.     template<typename _ValueT>
  968.       _OutIter
  969.       num_put<_CharT, _OutIter>::
  970.       _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
  971.                        _ValueT __v) const
  972.       {
  973.         typedef __numpunct_cache<_CharT>                __cache_type;
  974.         __use_cache<__cache_type> __uc;
  975.         const locale& __loc = __io._M_getloc();
  976.         const __cache_type* __lc = __uc(__loc);
  977.  
  978.         // Use default precision if out of range.
  979.         const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision();
  980.  
  981.         const int __max_digits =
  982.           __gnu_cxx::__numeric_traits<_ValueT>::__digits10;
  983.  
  984.         // [22.2.2.2.2] Stage 1, numeric conversion to character.
  985.         int __len;
  986.         // Long enough for the max format spec.
  987.         char __fbuf[16];
  988.         __num_base::_S_format_float(__io, __fbuf, __mod);
  989.  
  990. #ifdef _GLIBCXX_USE_C99
  991.         // First try a buffer perhaps big enough (most probably sufficient
  992.         // for non-ios_base::fixed outputs)
  993.         int __cs_size = __max_digits * 3;
  994.         char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  995.         __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  996.                                       __fbuf, __prec, __v);
  997.  
  998.         // If the buffer was not large enough, try again with the correct size.
  999.         if (__len >= __cs_size)
  1000.           {
  1001.             __cs_size = __len + 1;
  1002.             __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1003.             __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
  1004.                                           __fbuf, __prec, __v);
  1005.           }
  1006. #else
  1007.         // Consider the possibility of long ios_base::fixed outputs
  1008.         const bool __fixed = __io.flags() & ios_base::fixed;
  1009.         const int __max_exp =
  1010.           __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10;
  1011.  
  1012.         // The size of the output string is computed as follows.
  1013.         // ios_base::fixed outputs may need up to __max_exp + 1 chars
  1014.         // for the integer part + __prec chars for the fractional part
  1015.         // + 3 chars for sign, decimal point, '\0'. On the other hand,
  1016.         // for non-fixed outputs __max_digits * 2 + __prec chars are
  1017.         // largely sufficient.
  1018.         const int __cs_size = __fixed ? __max_exp + __prec + 4
  1019.                                       : __max_digits * 2 + __prec;
  1020.         char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
  1021.         __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf,
  1022.                                       __prec, __v);
  1023. #endif
  1024.  
  1025.         // [22.2.2.2.2] Stage 2, convert to char_type, using correct
  1026.         // numpunct.decimal_point() values for '.' and adding grouping.
  1027.         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1028.        
  1029.         _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  1030.                                                              * __len));
  1031.         __ctype.widen(__cs, __cs + __len, __ws);
  1032.        
  1033.         // Replace decimal point.
  1034.         _CharT* __wp = 0;
  1035.         const char* __p = char_traits<char>::find(__cs, __len, '.');
  1036.         if (__p)
  1037.           {
  1038.             __wp = __ws + (__p - __cs);
  1039.             *__wp = __lc->_M_decimal_point;
  1040.           }
  1041.        
  1042.         // Add grouping, if necessary.
  1043.         // N.B. Make sure to not group things like 2e20, i.e., no decimal
  1044.         // point, scientific notation.
  1045.         if (__lc->_M_use_grouping
  1046.             && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
  1047.                                       && __cs[1] >= '0' && __cs[2] >= '0')))
  1048.           {
  1049.             // Grouping can add (almost) as many separators as the
  1050.             // number of digits, but no more.
  1051.             _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  1052.                                                                   * __len * 2));
  1053.            
  1054.             streamsize __off = 0;
  1055.             if (__cs[0] == '-' || __cs[0] == '+')
  1056.               {
  1057.                 __off = 1;
  1058.                 __ws2[0] = __ws[0];
  1059.                 __len -= 1;
  1060.               }
  1061.            
  1062.             _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
  1063.                            __lc->_M_thousands_sep, __wp, __ws2 + __off,
  1064.                            __ws + __off, __len);
  1065.             __len += __off;
  1066.            
  1067.             __ws = __ws2;
  1068.           }
  1069.  
  1070.         // Pad.
  1071.         const streamsize __w = __io.width();
  1072.         if (__w > static_cast<streamsize>(__len))
  1073.           {
  1074.             _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  1075.                                                                   * __w));
  1076.             _M_pad(__fill, __w, __io, __ws3, __ws, __len);
  1077.             __ws = __ws3;
  1078.           }
  1079.         __io.width(0);
  1080.        
  1081.         // [22.2.2.2.2] Stage 4.
  1082.         // Write resulting, fully-formatted string to output iterator.
  1083.         return std::__write(__s, __ws, __len);
  1084.       }
  1085.  
  1086.   template<typename _CharT, typename _OutIter>
  1087.     _OutIter
  1088.     num_put<_CharT, _OutIter>::
  1089.     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
  1090.     {
  1091.       const ios_base::fmtflags __flags = __io.flags();
  1092.       if ((__flags & ios_base::boolalpha) == 0)
  1093.         {
  1094.           const long __l = __v;
  1095.           __s = _M_insert_int(__s, __io, __fill, __l);
  1096.         }
  1097.       else
  1098.         {
  1099.           typedef __numpunct_cache<_CharT>              __cache_type;
  1100.           __use_cache<__cache_type> __uc;
  1101.           const locale& __loc = __io._M_getloc();
  1102.           const __cache_type* __lc = __uc(__loc);
  1103.  
  1104.           const _CharT* __name = __v ? __lc->_M_truename
  1105.                                      : __lc->_M_falsename;
  1106.           int __len = __v ? __lc->_M_truename_size
  1107.                           : __lc->_M_falsename_size;
  1108.  
  1109.           const streamsize __w = __io.width();
  1110.           if (__w > static_cast<streamsize>(__len))
  1111.             {
  1112.               const streamsize __plen = __w - __len;
  1113.               _CharT* __ps
  1114.                 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
  1115.                                                         * __plen));
  1116.  
  1117.               char_traits<_CharT>::assign(__ps, __plen, __fill);
  1118.               __io.width(0);
  1119.  
  1120.               if ((__flags & ios_base::adjustfield) == ios_base::left)
  1121.                 {
  1122.                   __s = std::__write(__s, __name, __len);
  1123.                   __s = std::__write(__s, __ps, __plen);
  1124.                 }
  1125.               else
  1126.                 {
  1127.                   __s = std::__write(__s, __ps, __plen);
  1128.                   __s = std::__write(__s, __name, __len);
  1129.                 }
  1130.               return __s;
  1131.             }
  1132.           __io.width(0);
  1133.           __s = std::__write(__s, __name, __len);
  1134.         }
  1135.       return __s;
  1136.     }
  1137.  
  1138.   template<typename _CharT, typename _OutIter>
  1139.     _OutIter
  1140.     num_put<_CharT, _OutIter>::
  1141.     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
  1142.     { return _M_insert_float(__s, __io, __fill, char(), __v); }
  1143.  
  1144. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
  1145.   template<typename _CharT, typename _OutIter>
  1146.     _OutIter
  1147.     num_put<_CharT, _OutIter>::
  1148.     __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
  1149.     { return _M_insert_float(__s, __io, __fill, char(), __v); }
  1150. #endif
  1151.  
  1152.   template<typename _CharT, typename _OutIter>
  1153.     _OutIter
  1154.     num_put<_CharT, _OutIter>::
  1155.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  1156.            long double __v) const
  1157.     { return _M_insert_float(__s, __io, __fill, 'L', __v); }
  1158.  
  1159.   template<typename _CharT, typename _OutIter>
  1160.     _OutIter
  1161.     num_put<_CharT, _OutIter>::
  1162.     do_put(iter_type __s, ios_base& __io, char_type __fill,
  1163.            const void* __v) const
  1164.     {
  1165.       const ios_base::fmtflags __flags = __io.flags();
  1166.       const ios_base::fmtflags __fmt = ~(ios_base::basefield
  1167.                                          | ios_base::uppercase);
  1168.       __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
  1169.  
  1170.       typedef __gnu_cxx::__conditional_type<(sizeof(const void*)
  1171.                                              <= sizeof(unsigned long)),
  1172.         unsigned long, unsigned long long>::__type _UIntPtrType;      
  1173.  
  1174.       __s = _M_insert_int(__s, __io, __fill,
  1175.                           reinterpret_cast<_UIntPtrType>(__v));
  1176.       __io.flags(__flags);
  1177.       return __s;
  1178.     }
  1179.  
  1180. _GLIBCXX_END_NAMESPACE_LDBL
  1181.  
  1182.   // Construct correctly padded string, as per 22.2.2.2.2
  1183.   // Assumes
  1184.   // __newlen > __oldlen
  1185.   // __news is allocated for __newlen size
  1186.  
  1187.   // NB: Of the two parameters, _CharT can be deduced from the
  1188.   // function arguments. The other (_Traits) has to be explicitly specified.
  1189.   template<typename _CharT, typename _Traits>
  1190.     void
  1191.     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
  1192.                                    _CharT* __news, const _CharT* __olds,
  1193.                                    streamsize __newlen, streamsize __oldlen)
  1194.     {
  1195.       const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
  1196.       const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
  1197.  
  1198.       // Padding last.
  1199.       if (__adjust == ios_base::left)
  1200.         {
  1201.           _Traits::copy(__news, __olds, __oldlen);
  1202.           _Traits::assign(__news + __oldlen, __plen, __fill);
  1203.           return;
  1204.         }
  1205.  
  1206.       size_t __mod = 0;
  1207.       if (__adjust == ios_base::internal)
  1208.         {
  1209.           // Pad after the sign, if there is one.
  1210.           // Pad after 0[xX], if there is one.
  1211.           // Who came up with these rules, anyway? Jeeze.
  1212.           const locale& __loc = __io._M_getloc();
  1213.           const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
  1214.  
  1215.           if (__ctype.widen('-') == __olds[0]
  1216.               || __ctype.widen('+') == __olds[0])
  1217.             {
  1218.               __news[0] = __olds[0];
  1219.               __mod = 1;
  1220.               ++__news;
  1221.             }
  1222.           else if (__ctype.widen('0') == __olds[0]
  1223.                    && __oldlen > 1
  1224.                    && (__ctype.widen('x') == __olds[1]
  1225.                        || __ctype.widen('X') == __olds[1]))
  1226.             {
  1227.               __news[0] = __olds[0];
  1228.               __news[1] = __olds[1];
  1229.               __mod = 2;
  1230.               __news += 2;
  1231.             }
  1232.           // else Padding first.
  1233.         }
  1234.       _Traits::assign(__news, __plen, __fill);
  1235.       _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod);
  1236.     }
  1237.  
  1238.   template<typename _CharT>
  1239.     _CharT*
  1240.     __add_grouping(_CharT* __s, _CharT __sep,
  1241.                    const char* __gbeg, size_t __gsize,
  1242.                    const _CharT* __first, const _CharT* __last)
  1243.     {
  1244.       size_t __idx = 0;
  1245.       size_t __ctr = 0;
  1246.  
  1247.       while (__last - __first > __gbeg[__idx]
  1248.              && static_cast<signed char>(__gbeg[__idx]) > 0
  1249.              && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max)
  1250.         {
  1251.           __last -= __gbeg[__idx];
  1252.           __idx < __gsize - 1 ? ++__idx : ++__ctr;
  1253.         }
  1254.  
  1255.       while (__first != __last)
  1256.         *__s++ = *__first++;
  1257.  
  1258.       while (__ctr--)
  1259.         {
  1260.           *__s++ = __sep;        
  1261.           for (char __i = __gbeg[__idx]; __i > 0; --__i)
  1262.             *__s++ = *__first++;
  1263.         }
  1264.  
  1265.       while (__idx--)
  1266.         {
  1267.           *__s++ = __sep;        
  1268.           for (char __i = __gbeg[__idx]; __i > 0; --__i)
  1269.             *__s++ = *__first++;
  1270.         }
  1271.  
  1272.       return __s;
  1273.     }
  1274.  
  1275.   // Inhibit implicit instantiations for required instantiations,
  1276.   // which are defined via explicit instantiations elsewhere.
  1277. #if _GLIBCXX_EXTERN_TEMPLATE
  1278.   extern template class numpunct<char>;
  1279.   extern template class numpunct_byname<char>;
  1280.   extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>;
  1281.   extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>;
  1282.   extern template class ctype_byname<char>;
  1283.  
  1284.   extern template
  1285.     const ctype<char>&
  1286.     use_facet<ctype<char> >(const locale&);
  1287.  
  1288.   extern template
  1289.     const numpunct<char>&
  1290.     use_facet<numpunct<char> >(const locale&);
  1291.  
  1292.   extern template
  1293.     const num_put<char>&
  1294.     use_facet<num_put<char> >(const locale&);
  1295.  
  1296.   extern template
  1297.     const num_get<char>&
  1298.     use_facet<num_get<char> >(const locale&);
  1299.  
  1300.   extern template
  1301.     bool
  1302.     has_facet<ctype<char> >(const locale&);
  1303.  
  1304.   extern template
  1305.     bool
  1306.     has_facet<numpunct<char> >(const locale&);
  1307.  
  1308.   extern template
  1309.     bool
  1310.     has_facet<num_put<char> >(const locale&);
  1311.  
  1312.   extern template
  1313.     bool
  1314.     has_facet<num_get<char> >(const locale&);
  1315.  
  1316. #ifdef _GLIBCXX_USE_WCHAR_T
  1317.   extern template class numpunct<wchar_t>;
  1318.   extern template class numpunct_byname<wchar_t>;
  1319.   extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>;
  1320.   extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>;
  1321.   extern template class ctype_byname<wchar_t>;
  1322.  
  1323.   extern template
  1324.     const ctype<wchar_t>&
  1325.     use_facet<ctype<wchar_t> >(const locale&);
  1326.  
  1327.   extern template
  1328.     const numpunct<wchar_t>&
  1329.     use_facet<numpunct<wchar_t> >(const locale&);
  1330.  
  1331.   extern template
  1332.     const num_put<wchar_t>&
  1333.     use_facet<num_put<wchar_t> >(const locale&);
  1334.  
  1335.   extern template
  1336.     const num_get<wchar_t>&
  1337.     use_facet<num_get<wchar_t> >(const locale&);
  1338.  
  1339.  extern template
  1340.     bool
  1341.     has_facet<ctype<wchar_t> >(const locale&);
  1342.  
  1343.   extern template
  1344.     bool
  1345.     has_facet<numpunct<wchar_t> >(const locale&);
  1346.  
  1347.   extern template
  1348.     bool
  1349.     has_facet<num_put<wchar_t> >(const locale&);
  1350.  
  1351.   extern template
  1352.     bool
  1353.     has_facet<num_get<wchar_t> >(const locale&);
  1354. #endif
  1355. #endif
  1356.  
  1357. _GLIBCXX_END_NAMESPACE_VERSION
  1358. } // namespace
  1359.  
  1360. #endif
  1361.