LCOV - code coverage report
Current view: directory - usr/include/c++/4.2.1/bits - locale_facets.tcc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 12 0 0.0 %
Date: 2012-02-16 Functions: 0 0 -

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

Generated by: LCOV version 1.7