Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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