103a78d15Sespie // Locale support -*- C++ -*-
203a78d15Sespie 
319731d4fSespie // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
403a78d15Sespie // Free Software Foundation, Inc.
503a78d15Sespie //
603a78d15Sespie // This file is part of the GNU ISO C++ Library.  This library is free
703a78d15Sespie // software; you can redistribute it and/or modify it under the
803a78d15Sespie // terms of the GNU General Public License as published by the
903a78d15Sespie // Free Software Foundation; either version 2, or (at your option)
1003a78d15Sespie // any later version.
1103a78d15Sespie 
1203a78d15Sespie // This library is distributed in the hope that it will be useful,
1303a78d15Sespie // but WITHOUT ANY WARRANTY; without even the implied warranty of
1403a78d15Sespie // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1503a78d15Sespie // GNU General Public License for more details.
1603a78d15Sespie 
1703a78d15Sespie // You should have received a copy of the GNU General Public License along
1803a78d15Sespie // with this library; see the file COPYING.  If not, write to the Free
1903a78d15Sespie // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
2003a78d15Sespie // USA.
2103a78d15Sespie 
2203a78d15Sespie // As a special exception, you may use this file as part of a free software
2303a78d15Sespie // library without restriction.  Specifically, if other files instantiate
2403a78d15Sespie // templates or use macros or inline functions from this file, or you compile
2503a78d15Sespie // this file and link it with other files to produce an executable, this
2603a78d15Sespie // file does not by itself cause the resulting executable to be covered by
2703a78d15Sespie // the GNU General Public License.  This exception does not however
2803a78d15Sespie // invalidate any other reasons why the executable file might be covered by
2903a78d15Sespie // the GNU General Public License.
3003a78d15Sespie 
3103a78d15Sespie // Warning: this file is not meant for user inclusion. Use <locale>.
3203a78d15Sespie 
3303a78d15Sespie #ifndef _CPP_BITS_LOCFACETS_TCC
3403a78d15Sespie #define _CPP_BITS_LOCFACETS_TCC 1
3503a78d15Sespie 
3603a78d15Sespie #pragma GCC system_header
3703a78d15Sespie 
3803a78d15Sespie #include <cerrno>
3903a78d15Sespie #include <clocale>   		// For localeconv
4003a78d15Sespie #include <cstdlib>   		// For strof, strtold
4103a78d15Sespie #include <cctype>    		// For isspace
4203a78d15Sespie #include <limits>    		// For numeric_limits
4303a78d15Sespie #include <typeinfo>  		// For bad_cast.
4403a78d15Sespie #include <bits/streambuf_iterator.h>
4503a78d15Sespie 
4603a78d15Sespie namespace std
4703a78d15Sespie {
4803a78d15Sespie   template<typename _Facet>
4903a78d15Sespie     locale
combine(const locale & __other) const5003a78d15Sespie     locale::combine(const locale& __other) const
5103a78d15Sespie     {
5203a78d15Sespie       _Impl* __tmp = new _Impl(*_M_impl, 1);
5319731d4fSespie       try
5419731d4fSespie 	{
5503a78d15Sespie 	  __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
5619731d4fSespie 	}
5719731d4fSespie       catch(...)
5819731d4fSespie 	{
5919731d4fSespie 	  __tmp->_M_remove_reference();
6019731d4fSespie 	  __throw_exception_again;
6119731d4fSespie 	}
6203a78d15Sespie       return locale(__tmp);
6303a78d15Sespie     }
6403a78d15Sespie 
6503a78d15Sespie   template<typename _CharT, typename _Traits, typename _Alloc>
6603a78d15Sespie     bool
operator ()(const basic_string<_CharT,_Traits,_Alloc> & __s1,const basic_string<_CharT,_Traits,_Alloc> & __s2) const6703a78d15Sespie     locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
6803a78d15Sespie                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
6903a78d15Sespie     {
7003a78d15Sespie       typedef std::collate<_CharT> __collate_type;
7103a78d15Sespie       const __collate_type& __collate = use_facet<__collate_type>(*this);
7203a78d15Sespie       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
7303a78d15Sespie 				__s2.data(), __s2.data() + __s2.length()) < 0);
7403a78d15Sespie     }
7503a78d15Sespie 
7603a78d15Sespie   template<typename _Facet>
7703a78d15Sespie     const _Facet&
use_facet(const locale & __loc)7803a78d15Sespie     use_facet(const locale& __loc)
7903a78d15Sespie     {
8003a78d15Sespie       size_t __i = _Facet::id._M_id();
8103a78d15Sespie       locale::facet** __facets = __loc._M_impl->_M_facets;
8203a78d15Sespie       if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
8303a78d15Sespie         __throw_bad_cast();
8403a78d15Sespie       return static_cast<const _Facet&>(*__facets[__i]);
8503a78d15Sespie     }
8603a78d15Sespie 
8703a78d15Sespie   template<typename _Facet>
8803a78d15Sespie     bool
has_facet(const locale & __loc)8903a78d15Sespie     has_facet(const locale& __loc) throw()
9003a78d15Sespie     {
9103a78d15Sespie       size_t __i = _Facet::id._M_id();
9203a78d15Sespie       locale::facet** __facets = __loc._M_impl->_M_facets;
9303a78d15Sespie       return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
9403a78d15Sespie     }
9503a78d15Sespie 
9603a78d15Sespie   // Routine to access a cache for the locale.  If the cache didn't
9703a78d15Sespie   // exist before, it gets constructed on the fly.
9803a78d15Sespie   template<typename _Facet>
9903a78d15Sespie     inline const __locale_cache<_Facet>&
__use_cache(const locale & __loc)10003a78d15Sespie     __use_cache(const locale& __loc)
10103a78d15Sespie     {
10203a78d15Sespie       size_t __i = _Facet::id._M_id();
10303a78d15Sespie       if (__builtin_expect(__i >= __loc._M_impl->_M_facets_size,false))
10403a78d15Sespie 	__throw_bad_cast();
10503a78d15Sespie       __locale_cache_base* __cache = __loc._M_impl->_M_get_cache(__i);
10603a78d15Sespie       if (__builtin_expect(!__cache, false))
10703a78d15Sespie 	{
10803a78d15Sespie 	  __cache = new __locale_cache<_Facet>(__loc);
10903a78d15Sespie 	  __loc._M_impl->_M_install_cache(__cache, __i);
11003a78d15Sespie 	}
11103a78d15Sespie       return static_cast<const __locale_cache<_Facet>&>(*__cache);
11203a78d15Sespie     }
11303a78d15Sespie 
11403a78d15Sespie   // Stage 1: Determine a conversion specifier.
11503a78d15Sespie   template<typename _CharT, typename _InIter>
11603a78d15Sespie     _InIter
11703a78d15Sespie     num_get<_CharT, _InIter>::
_M_extract_float(_InIter __beg,_InIter __end,ios_base & __io,ios_base::iostate & __err,string & __xtrc) const11803a78d15Sespie     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
11903a78d15Sespie 		     ios_base::iostate& __err, string& __xtrc) const
12003a78d15Sespie     {
12103a78d15Sespie       typedef char_traits<_CharT>		__traits_type;
12203a78d15Sespie       const locale __loc = __io.getloc();
12303a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
12403a78d15Sespie       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
12503a78d15Sespie 
12603a78d15Sespie       // First check for sign.
12703a78d15Sespie       const char_type __plus = __ctype.widen('+');
12803a78d15Sespie       const char_type __minus = __ctype.widen('-');
12903a78d15Sespie       int __pos = 0;
13003a78d15Sespie       char_type  __c = *__beg;
13103a78d15Sespie       if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
13203a78d15Sespie 	  && __beg != __end)
13303a78d15Sespie 	{
13403a78d15Sespie 	  __xtrc += __ctype.narrow(__c, char());
13503a78d15Sespie 	  ++__pos;
13603a78d15Sespie 	  __c = *(++__beg);
13703a78d15Sespie 	}
13803a78d15Sespie 
13903a78d15Sespie       // Next, strip leading zeros.
14003a78d15Sespie       const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]);
14103a78d15Sespie       bool __found_zero = false;
14203a78d15Sespie       while (__traits_type::eq(__c, __zero) && __beg != __end)
14303a78d15Sespie 	{
14403a78d15Sespie 	  __c = *(++__beg);
14503a78d15Sespie 	  __found_zero = true;
14603a78d15Sespie 	}
14703a78d15Sespie       if (__found_zero)
14803a78d15Sespie 	{
14903a78d15Sespie 	  __xtrc += _S_atoms_in[_M_zero];
15003a78d15Sespie 	  ++__pos;
15103a78d15Sespie 	}
15203a78d15Sespie 
15303a78d15Sespie       // Only need acceptable digits for floating point numbers.
15403a78d15Sespie       const size_t __len = _M_E - _M_zero + 1;
15503a78d15Sespie       char_type  __watoms[__len];
15603a78d15Sespie       __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms);
15703a78d15Sespie       bool __found_dec = false;
15803a78d15Sespie       bool __found_sci = false;
15903a78d15Sespie       const char_type __dec = __np.decimal_point();
16003a78d15Sespie 
16103a78d15Sespie       string __found_grouping;
16203a78d15Sespie       const string __grouping = __np.grouping();
16303a78d15Sespie       bool __check_grouping = __grouping.size();
16403a78d15Sespie       int __sep_pos = 0;
16503a78d15Sespie       const char_type __sep = __np.thousands_sep();
16603a78d15Sespie 
16703a78d15Sespie       while (__beg != __end)
16803a78d15Sespie         {
16903a78d15Sespie 	  // Only look in digits.
17003a78d15Sespie           const char_type* __p = __traits_type::find(__watoms, 10,  __c);
17103a78d15Sespie 
17203a78d15Sespie           // NB: strchr returns true for __c == 0x0
17303a78d15Sespie           if (__p && !__traits_type::eq(__c, char_type()))
17403a78d15Sespie 	    {
17503a78d15Sespie 	      // Try first for acceptable digit; record it if found.
17603a78d15Sespie 	      ++__pos;
17703a78d15Sespie 	      __xtrc += _S_atoms_in[__p - __watoms];
17803a78d15Sespie 	      ++__sep_pos;
17903a78d15Sespie 	      __c = *(++__beg);
18003a78d15Sespie 	    }
18103a78d15Sespie           else if (__traits_type::eq(__c, __sep)
18203a78d15Sespie 		   && __check_grouping && !__found_dec)
18303a78d15Sespie 	    {
18403a78d15Sespie               // NB: Thousands separator at the beginning of a string
18503a78d15Sespie               // is a no-no, as is two consecutive thousands separators.
18603a78d15Sespie               if (__sep_pos)
18703a78d15Sespie                 {
18803a78d15Sespie                   __found_grouping += static_cast<char>(__sep_pos);
18903a78d15Sespie                   __sep_pos = 0;
19003a78d15Sespie 		  __c = *(++__beg);
19103a78d15Sespie                 }
19203a78d15Sespie               else
19303a78d15Sespie 		{
19403a78d15Sespie 		  __err |= ios_base::failbit;
19503a78d15Sespie 		  break;
19603a78d15Sespie 		}
19703a78d15Sespie             }
19803a78d15Sespie 	  else if (__traits_type::eq(__c, __dec) && !__found_dec)
19903a78d15Sespie 	    {
20003a78d15Sespie 	      // According to the standard, if no grouping chars are seen,
20103a78d15Sespie 	      // no grouping check is applied. Therefore __found_grouping
20203a78d15Sespie 	      // must be adjusted only if __dec comes after some __sep.
20303a78d15Sespie 	      if (__found_grouping.size())
20403a78d15Sespie 		__found_grouping += static_cast<char>(__sep_pos);
20503a78d15Sespie 	      ++__pos;
20603a78d15Sespie 	      __xtrc += '.';
20703a78d15Sespie 	      __c = *(++__beg);
20803a78d15Sespie 	      __found_dec = true;
20903a78d15Sespie 	    }
21003a78d15Sespie 	  else if ((__traits_type::eq(__c, __watoms[_M_e])
21103a78d15Sespie 		    || __traits_type::eq(__c, __watoms[_M_E]))
21203a78d15Sespie 		   && !__found_sci && __pos)
21303a78d15Sespie 	    {
21403a78d15Sespie 	      // Scientific notation.
21503a78d15Sespie 	      ++__pos;
21603a78d15Sespie 	      __xtrc += __ctype.narrow(__c, char());
21703a78d15Sespie 	      __c = *(++__beg);
21803a78d15Sespie 
21903a78d15Sespie 	      // Remove optional plus or minus sign, if they exist.
22003a78d15Sespie 	      if (__traits_type::eq(__c, __plus)
22103a78d15Sespie 		  || __traits_type::eq(__c, __minus))
22203a78d15Sespie 		{
22303a78d15Sespie 		  ++__pos;
22403a78d15Sespie 		  __xtrc += __ctype.narrow(__c, char());
22503a78d15Sespie 		  __c = *(++__beg);
22603a78d15Sespie 		}
22703a78d15Sespie 	      __found_sci = true;
22803a78d15Sespie 	    }
22903a78d15Sespie 	  else
23003a78d15Sespie 	    // Not a valid input item.
23103a78d15Sespie 	    break;
23203a78d15Sespie         }
23303a78d15Sespie 
23403a78d15Sespie       // Digit grouping is checked. If grouping and found_grouping don't
23503a78d15Sespie       // match, then get very very upset, and set failbit.
23603a78d15Sespie       if (__check_grouping && __found_grouping.size())
23703a78d15Sespie         {
23803a78d15Sespie           // Add the ending grouping if a decimal wasn't found.
23903a78d15Sespie 	  if (!__found_dec)
24003a78d15Sespie 	    __found_grouping += static_cast<char>(__sep_pos);
24103a78d15Sespie           if (!__verify_grouping(__grouping, __found_grouping))
24203a78d15Sespie 	    __err |= ios_base::failbit;
24303a78d15Sespie         }
24403a78d15Sespie 
24503a78d15Sespie       // Finish up
24603a78d15Sespie       __xtrc += char();
24703a78d15Sespie       if (__beg == __end)
24803a78d15Sespie         __err |= ios_base::eofbit;
24903a78d15Sespie       return __beg;
25003a78d15Sespie     }
25103a78d15Sespie 
25203a78d15Sespie   // Stage 1: Determine a conversion specifier.
25303a78d15Sespie   template<typename _CharT, typename _InIter>
25403a78d15Sespie     _InIter
25503a78d15Sespie     num_get<_CharT, _InIter>::
_M_extract_int(_InIter __beg,_InIter __end,ios_base & __io,ios_base::iostate & __err,string & __xtrc,int & __base) const25603a78d15Sespie     _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
25703a78d15Sespie 		   ios_base::iostate& __err, string& __xtrc, int& __base) const
25803a78d15Sespie     {
25903a78d15Sespie       typedef char_traits<_CharT>		__traits_type;
26003a78d15Sespie       const locale __loc = __io.getloc();
26103a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
26203a78d15Sespie       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
26303a78d15Sespie 
26403a78d15Sespie       // NB: Iff __basefield == 0, this can change based on contents.
26503a78d15Sespie       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
26603a78d15Sespie       if (__basefield == ios_base::oct)
26703a78d15Sespie         __base = 8;
26803a78d15Sespie       else if (__basefield == ios_base::hex)
26903a78d15Sespie         __base = 16;
27003a78d15Sespie       else
27103a78d15Sespie 	__base = 10;
27203a78d15Sespie 
27303a78d15Sespie       // First check for sign.
27403a78d15Sespie       int __pos = 0;
27503a78d15Sespie       char_type  __c = *__beg;
27603a78d15Sespie       const char_type __plus = __ctype.widen('+');
27703a78d15Sespie       const char_type __minus = __ctype.widen('-');
27803a78d15Sespie 
27903a78d15Sespie       if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
28003a78d15Sespie 	  && __beg != __end)
28103a78d15Sespie 	{
28203a78d15Sespie 	  __xtrc += __ctype.narrow(__c, char());
28303a78d15Sespie 	  ++__pos;
28403a78d15Sespie 	  __c = *(++__beg);
28503a78d15Sespie 	}
28603a78d15Sespie 
28703a78d15Sespie       // Next, strip leading zeros and check required digits for base formats.
28803a78d15Sespie       const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]);
28903a78d15Sespie       const char_type __x = __ctype.widen('x');
29003a78d15Sespie       const char_type __X = __ctype.widen('X');
29103a78d15Sespie       if (__base == 10)
29203a78d15Sespie 	{
29303a78d15Sespie 	  bool __found_zero = false;
29403a78d15Sespie 	  while (__traits_type::eq(__c, __zero) && __beg != __end)
29503a78d15Sespie 	    {
29603a78d15Sespie 	      __c = *(++__beg);
29703a78d15Sespie 	      __found_zero = true;
29803a78d15Sespie 	    }
29903a78d15Sespie 	  if (__found_zero)
30003a78d15Sespie 	    {
30103a78d15Sespie 	      __xtrc += _S_atoms_in[_M_zero];
30203a78d15Sespie 	      ++__pos;
30303a78d15Sespie 	      if (__basefield == 0)
30403a78d15Sespie 		{
30503a78d15Sespie 		  if ((__traits_type::eq(__c, __x)
30603a78d15Sespie 		       || __traits_type::eq(__c, __X))
30703a78d15Sespie 		      && __beg != __end)
30803a78d15Sespie 		    {
30903a78d15Sespie 		      __xtrc += __ctype.narrow(__c, char());
31003a78d15Sespie 		      ++__pos;
31103a78d15Sespie 		      __c = *(++__beg);
31203a78d15Sespie 		      __base = 16;
31303a78d15Sespie 		    }
31403a78d15Sespie 		  else
31503a78d15Sespie 		    __base = 8;
31603a78d15Sespie 		}
31703a78d15Sespie 	    }
31803a78d15Sespie 	}
31903a78d15Sespie       else if (__base == 16)
32003a78d15Sespie 	{
32103a78d15Sespie 	  if (__traits_type::eq(__c, __zero) && __beg != __end)
32203a78d15Sespie 	    {
32303a78d15Sespie 	      __xtrc += _S_atoms_in[_M_zero];
32403a78d15Sespie 	      ++__pos;
32503a78d15Sespie 	      __c = *(++__beg);
32603a78d15Sespie 	      if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X))
32703a78d15Sespie 		  && __beg != __end)
32803a78d15Sespie 		{
32903a78d15Sespie 		  __xtrc += __ctype.narrow(__c, char());
33003a78d15Sespie 		  ++__pos;
33103a78d15Sespie 		  __c = *(++__beg);
33203a78d15Sespie 		}
33303a78d15Sespie 	    }
33403a78d15Sespie 	}
33503a78d15Sespie 
33603a78d15Sespie       // At this point, base is determined. If not hex, only allow
33703a78d15Sespie       // base digits as valid input.
33803a78d15Sespie       size_t __len;
33903a78d15Sespie       if (__base == 16)
34003a78d15Sespie 	__len = _M_size;
34103a78d15Sespie       else
34203a78d15Sespie 	__len = __base;
34303a78d15Sespie 
34403a78d15Sespie       // Extract.
34503a78d15Sespie       char_type __watoms[_M_size];
34603a78d15Sespie       __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms);
34703a78d15Sespie       string __found_grouping;
34803a78d15Sespie       const string __grouping = __np.grouping();
34903a78d15Sespie       bool __check_grouping = __grouping.size();
35003a78d15Sespie       int __sep_pos = 0;
35103a78d15Sespie       const char_type __sep = __np.thousands_sep();
35203a78d15Sespie       while (__beg != __end)
35303a78d15Sespie         {
35403a78d15Sespie           const char_type* __p = __traits_type::find(__watoms, __len,  __c);
35503a78d15Sespie 
35603a78d15Sespie           // NB: strchr returns true for __c == 0x0
35703a78d15Sespie           if (__p && !__traits_type::eq(__c, char_type()))
35803a78d15Sespie 	    {
35903a78d15Sespie 	      // Try first for acceptable digit; record it if found.
36003a78d15Sespie 	      __xtrc += _S_atoms_in[__p - __watoms];
36103a78d15Sespie 	      ++__pos;
36203a78d15Sespie 	      ++__sep_pos;
36303a78d15Sespie 	      __c = *(++__beg);
36403a78d15Sespie 	    }
36503a78d15Sespie           else if (__traits_type::eq(__c, __sep) && __check_grouping)
36603a78d15Sespie 	    {
36703a78d15Sespie               // NB: Thousands separator at the beginning of a string
36803a78d15Sespie               // is a no-no, as is two consecutive thousands separators.
36903a78d15Sespie               if (__sep_pos)
37003a78d15Sespie                 {
37103a78d15Sespie                   __found_grouping += static_cast<char>(__sep_pos);
37203a78d15Sespie                   __sep_pos = 0;
37303a78d15Sespie 		  __c = *(++__beg);
37403a78d15Sespie                 }
37503a78d15Sespie               else
37603a78d15Sespie 		{
37703a78d15Sespie 		  __err |= ios_base::failbit;
37803a78d15Sespie 		  break;
37903a78d15Sespie 		}
38003a78d15Sespie             }
38103a78d15Sespie 	  else
38203a78d15Sespie 	    // Not a valid input item.
38303a78d15Sespie 	    break;
38403a78d15Sespie         }
38503a78d15Sespie 
38603a78d15Sespie       // Digit grouping is checked. If grouping and found_grouping don't
38703a78d15Sespie       // match, then get very very upset, and set failbit.
38803a78d15Sespie       if (__check_grouping && __found_grouping.size())
38903a78d15Sespie         {
39003a78d15Sespie           // Add the ending grouping.
39103a78d15Sespie           __found_grouping += static_cast<char>(__sep_pos);
39203a78d15Sespie           if (!__verify_grouping(__grouping, __found_grouping))
39303a78d15Sespie 	    __err |= ios_base::failbit;
39403a78d15Sespie         }
39503a78d15Sespie 
39603a78d15Sespie       // Finish up.
39703a78d15Sespie       __xtrc += char();
39803a78d15Sespie       if (__beg == __end)
39903a78d15Sespie         __err |= ios_base::eofbit;
40003a78d15Sespie       return __beg;
40103a78d15Sespie     }
40203a78d15Sespie 
40303a78d15Sespie #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
40403a78d15Sespie   //17.  Bad bool parsing
40503a78d15Sespie   template<typename _CharT, typename _InIter>
40603a78d15Sespie     _InIter
40703a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,bool & __v) const40803a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
40903a78d15Sespie            ios_base::iostate& __err, bool& __v) const
41003a78d15Sespie     {
41103a78d15Sespie       // Parse bool values as unsigned long
41203a78d15Sespie       if (!(__io.flags() & ios_base::boolalpha))
41303a78d15Sespie         {
41403a78d15Sespie           // NB: We can't just call do_get(long) here, as it might
41503a78d15Sespie           // refer to a derived class.
41603a78d15Sespie           string __xtrc;
41703a78d15Sespie           int __base;
41803a78d15Sespie           __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
41903a78d15Sespie 
42003a78d15Sespie 	  unsigned long __ul;
42103a78d15Sespie 	  __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
42203a78d15Sespie 	  if (!(__err & ios_base::failbit) && __ul <= 1)
42303a78d15Sespie 	    __v = __ul;
42403a78d15Sespie 	  else
42503a78d15Sespie             __err |= ios_base::failbit;
42603a78d15Sespie         }
42703a78d15Sespie 
42803a78d15Sespie       // Parse bool values as alphanumeric
42903a78d15Sespie       else
43003a78d15Sespie         {
43103a78d15Sespie 	  typedef char_traits<_CharT>	      	__traits_type;
43203a78d15Sespie 	  typedef basic_string<_CharT>   	__string_type;
43303a78d15Sespie 
43403a78d15Sespie           locale __loc = __io.getloc();
43503a78d15Sespie 	  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
43603a78d15Sespie 	  const __string_type __true = __np.truename();
43703a78d15Sespie 	  const __string_type __false = __np.falsename();
43803a78d15Sespie           const char_type* __trues = __true.c_str();
43903a78d15Sespie           const char_type* __falses = __false.c_str();
44003a78d15Sespie           const size_t __truen =  __true.size() - 1;
44103a78d15Sespie           const size_t __falsen =  __false.size() - 1;
44203a78d15Sespie 
44303a78d15Sespie           for (size_t __n = 0; __beg != __end; ++__n)
44403a78d15Sespie             {
44503a78d15Sespie               char_type __c = *__beg++;
44603a78d15Sespie               bool __testf = __n <= __falsen
44703a78d15Sespie 		             ? __traits_type::eq(__c, __falses[__n]) : false;
44803a78d15Sespie               bool __testt = __n <= __truen
44903a78d15Sespie 		             ? __traits_type::eq(__c, __trues[__n]) : false;
45003a78d15Sespie               if (!(__testf || __testt))
45103a78d15Sespie                 {
45203a78d15Sespie                   __err |= ios_base::failbit;
45303a78d15Sespie                   break;
45403a78d15Sespie                 }
45503a78d15Sespie               else if (__testf && __n == __falsen)
45603a78d15Sespie                 {
45703a78d15Sespie                   __v = 0;
45803a78d15Sespie                   break;
45903a78d15Sespie                 }
46003a78d15Sespie               else if (__testt && __n == __truen)
46103a78d15Sespie                 {
46203a78d15Sespie                   __v = 1;
46303a78d15Sespie                   break;
46403a78d15Sespie                 }
46503a78d15Sespie             }
46603a78d15Sespie           if (__beg == __end)
46703a78d15Sespie             __err |= ios_base::eofbit;
46803a78d15Sespie         }
46903a78d15Sespie       return __beg;
47003a78d15Sespie     }
47103a78d15Sespie #endif
47203a78d15Sespie 
47303a78d15Sespie   template<typename _CharT, typename _InIter>
47403a78d15Sespie     _InIter
47503a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,long & __v) const47603a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
47703a78d15Sespie            ios_base::iostate& __err, long& __v) const
47803a78d15Sespie     {
47903a78d15Sespie       string __xtrc;
48003a78d15Sespie       int __base;
48103a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
48203a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
48303a78d15Sespie       return __beg;
48403a78d15Sespie     }
48503a78d15Sespie 
48603a78d15Sespie   template<typename _CharT, typename _InIter>
48703a78d15Sespie     _InIter
48803a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,unsigned short & __v) const48903a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
49003a78d15Sespie            ios_base::iostate& __err, unsigned short& __v) const
49103a78d15Sespie     {
49203a78d15Sespie       string __xtrc;
49303a78d15Sespie       int __base;
49403a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
49503a78d15Sespie       unsigned long __ul;
49603a78d15Sespie       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
49703a78d15Sespie       if (!(__err & ios_base::failbit)
49803a78d15Sespie 	  && __ul <= numeric_limits<unsigned short>::max())
49903a78d15Sespie 	__v = static_cast<unsigned short>(__ul);
50003a78d15Sespie       else
50103a78d15Sespie 	__err |= ios_base::failbit;
50203a78d15Sespie       return __beg;
50303a78d15Sespie     }
50403a78d15Sespie 
50503a78d15Sespie   template<typename _CharT, typename _InIter>
50603a78d15Sespie     _InIter
50703a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,unsigned int & __v) const50803a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
50903a78d15Sespie            ios_base::iostate& __err, unsigned int& __v) const
51003a78d15Sespie     {
51103a78d15Sespie       string __xtrc;
51203a78d15Sespie       int __base;
51303a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
51403a78d15Sespie       unsigned long __ul;
51503a78d15Sespie       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
51603a78d15Sespie       if (!(__err & ios_base::failbit)
51703a78d15Sespie 	  && __ul <= numeric_limits<unsigned int>::max())
51803a78d15Sespie 	__v = static_cast<unsigned int>(__ul);
51903a78d15Sespie       else
52003a78d15Sespie 	__err |= ios_base::failbit;
52103a78d15Sespie       return __beg;
52203a78d15Sespie     }
52303a78d15Sespie 
52403a78d15Sespie   template<typename _CharT, typename _InIter>
52503a78d15Sespie     _InIter
52603a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,unsigned long & __v) const52703a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
52803a78d15Sespie            ios_base::iostate& __err, unsigned long& __v) const
52903a78d15Sespie     {
53003a78d15Sespie       string __xtrc;
53103a78d15Sespie       int __base;
53203a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
53303a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
53403a78d15Sespie       return __beg;
53503a78d15Sespie     }
53603a78d15Sespie 
53703a78d15Sespie #ifdef _GLIBCPP_USE_LONG_LONG
53803a78d15Sespie   template<typename _CharT, typename _InIter>
53903a78d15Sespie     _InIter
54003a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,long long & __v) const54103a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
54203a78d15Sespie            ios_base::iostate& __err, long long& __v) const
54303a78d15Sespie     {
54403a78d15Sespie       string __xtrc;
54503a78d15Sespie       int __base;
54603a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
54703a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
54803a78d15Sespie       return __beg;
54903a78d15Sespie     }
55003a78d15Sespie 
55103a78d15Sespie   template<typename _CharT, typename _InIter>
55203a78d15Sespie     _InIter
55303a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,unsigned long long & __v) const55403a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
55503a78d15Sespie            ios_base::iostate& __err, unsigned long long& __v) const
55603a78d15Sespie     {
55703a78d15Sespie       string __xtrc;
55803a78d15Sespie       int __base;
55903a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
56003a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
56103a78d15Sespie       return __beg;
56203a78d15Sespie     }
56303a78d15Sespie #endif
56403a78d15Sespie 
56503a78d15Sespie   template<typename _CharT, typename _InIter>
56603a78d15Sespie     _InIter
56703a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,float & __v) const56803a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
56903a78d15Sespie 	   ios_base::iostate& __err, float& __v) const
57003a78d15Sespie     {
57103a78d15Sespie       string __xtrc;
57203a78d15Sespie       __xtrc.reserve(32);
57303a78d15Sespie       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
57403a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
57503a78d15Sespie       return __beg;
57603a78d15Sespie     }
57703a78d15Sespie 
57803a78d15Sespie   template<typename _CharT, typename _InIter>
57903a78d15Sespie     _InIter
58003a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,double & __v) const58103a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
58203a78d15Sespie            ios_base::iostate& __err, double& __v) const
58303a78d15Sespie     {
58403a78d15Sespie       string __xtrc;
58503a78d15Sespie       __xtrc.reserve(32);
58603a78d15Sespie       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
58703a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
58803a78d15Sespie       return __beg;
58903a78d15Sespie     }
59003a78d15Sespie 
59103a78d15Sespie   template<typename _CharT, typename _InIter>
59203a78d15Sespie     _InIter
59303a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,long double & __v) const59403a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
59503a78d15Sespie            ios_base::iostate& __err, long double& __v) const
59603a78d15Sespie     {
59703a78d15Sespie       string __xtrc;
59803a78d15Sespie       __xtrc.reserve(32);
59903a78d15Sespie       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
60003a78d15Sespie       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
60103a78d15Sespie       return __beg;
60203a78d15Sespie     }
60303a78d15Sespie 
60403a78d15Sespie   template<typename _CharT, typename _InIter>
60503a78d15Sespie     _InIter
60603a78d15Sespie     num_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,void * & __v) const60703a78d15Sespie     do_get(iter_type __beg, iter_type __end, ios_base& __io,
60803a78d15Sespie            ios_base::iostate& __err, void*& __v) const
60903a78d15Sespie     {
61003a78d15Sespie       // Prepare for hex formatted input
61103a78d15Sespie       typedef ios_base::fmtflags        fmtflags;
61203a78d15Sespie       fmtflags __fmt = __io.flags();
61303a78d15Sespie       fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
61403a78d15Sespie                              | ios_base::uppercase | ios_base::internal);
61503a78d15Sespie       __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
61603a78d15Sespie 
61703a78d15Sespie       string __xtrc;
61803a78d15Sespie       int __base;
61903a78d15Sespie       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
62003a78d15Sespie 
62103a78d15Sespie       // Reset from hex formatted input
62203a78d15Sespie       __io.flags(__fmt);
62303a78d15Sespie 
62403a78d15Sespie       unsigned long __ul;
62503a78d15Sespie       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
62603a78d15Sespie       if (!(__err & ios_base::failbit))
62703a78d15Sespie 	__v = reinterpret_cast<void*>(__ul);
62803a78d15Sespie       else
62903a78d15Sespie 	__err |= ios_base::failbit;
63003a78d15Sespie       return __beg;
63103a78d15Sespie     }
63203a78d15Sespie 
63303a78d15Sespie   // For use by integer and floating-point types after they have been
63403a78d15Sespie   // converted into a char_type string.
63503a78d15Sespie   template<typename _CharT, typename _OutIter>
63603a78d15Sespie     void
63703a78d15Sespie     num_put<_CharT, _OutIter>::
_M_pad(_CharT __fill,streamsize __w,ios_base & __io,_CharT * __new,const _CharT * __cs,int & __len) const63803a78d15Sespie     _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
63903a78d15Sespie 	   _CharT* __new, const _CharT* __cs, int& __len) const
64003a78d15Sespie     {
64103a78d15Sespie       // [22.2.2.2.2] Stage 3.
64203a78d15Sespie       // If necessary, pad.
64303a78d15Sespie       __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs,
64403a78d15Sespie 						  __w, __len, true);
64503a78d15Sespie       __len = static_cast<int>(__w);
64603a78d15Sespie     }
64703a78d15Sespie 
64803a78d15Sespie   // Forwarding functions to peel signed from unsigned integer types.
64903a78d15Sespie   template<typename _CharT>
65003a78d15Sespie     inline int
__int_to_char(_CharT * __out,const int __size,long __v,const _CharT * __lit,ios_base::fmtflags __flags)65103a78d15Sespie     __int_to_char(_CharT* __out, const int __size, long __v,
65203a78d15Sespie 		       const _CharT* __lit, ios_base::fmtflags __flags)
65303a78d15Sespie     {
65403a78d15Sespie       unsigned long __ul = static_cast<unsigned long>(__v);
65503a78d15Sespie       bool __neg = false;
65603a78d15Sespie       if (__v < 0)
65703a78d15Sespie 	{
65803a78d15Sespie 	  __ul = -__ul;
65903a78d15Sespie 	  __neg = true;
66003a78d15Sespie 	}
66103a78d15Sespie       return __int_to_char(__out, __size, __ul, __lit, __flags, __neg);
66203a78d15Sespie     }
66303a78d15Sespie 
66403a78d15Sespie   template<typename _CharT>
66503a78d15Sespie     inline int
__int_to_char(_CharT * __out,const int __size,unsigned long __v,const _CharT * __lit,ios_base::fmtflags __flags)66603a78d15Sespie     __int_to_char(_CharT* __out, const int __size, unsigned long __v,
66703a78d15Sespie 		       const _CharT* __lit, ios_base::fmtflags __flags)
66803a78d15Sespie     { return __int_to_char(__out, __size, __v, __lit, __flags, false); }
66903a78d15Sespie 
67003a78d15Sespie #ifdef _GLIBCPP_USE_LONG_LONG
67103a78d15Sespie   template<typename _CharT>
67203a78d15Sespie     inline int
__int_to_char(_CharT * __out,const int __size,long long __v,const _CharT * __lit,ios_base::fmtflags __flags)67303a78d15Sespie     __int_to_char(_CharT* __out, const int __size, long long __v,
67403a78d15Sespie 		       const _CharT* __lit, ios_base::fmtflags __flags)
67503a78d15Sespie     {
67603a78d15Sespie       unsigned long long __ull = static_cast<unsigned long long>(__v);
67703a78d15Sespie       bool __neg = false;
67803a78d15Sespie       if (__v < 0)
67903a78d15Sespie 	{
68003a78d15Sespie 	  __ull = -__ull;
68103a78d15Sespie 	  __neg = true;
68203a78d15Sespie 	}
68303a78d15Sespie       return __int_to_char(__out, __size, __ull, __lit, __flags, __neg);
68403a78d15Sespie     }
68503a78d15Sespie 
68603a78d15Sespie   template<typename _CharT>
68703a78d15Sespie     inline int
__int_to_char(_CharT * __out,const int __size,unsigned long long __v,const _CharT * __lit,ios_base::fmtflags __flags)68803a78d15Sespie     __int_to_char(_CharT* __out, const int __size, unsigned long long __v,
68903a78d15Sespie 		       const _CharT* __lit, ios_base::fmtflags __flags)
69003a78d15Sespie     { return __int_to_char(__out, __size, __v, __lit, __flags, false); }
69103a78d15Sespie #endif
69203a78d15Sespie 
69303a78d15Sespie   template<typename _CharT, typename _ValueT>
69403a78d15Sespie     int
__int_to_char(_CharT * __out,const int __size,_ValueT __v,const _CharT * __lit,ios_base::fmtflags __flags,bool __neg)69503a78d15Sespie     __int_to_char(_CharT* __out, const int __size, _ValueT __v,
69603a78d15Sespie 		  const _CharT* __lit, ios_base::fmtflags __flags, bool __neg)
69703a78d15Sespie     {
69803a78d15Sespie       // Don't write base if already 0.
69903a78d15Sespie       const bool __showbase = (__flags & ios_base::showbase) && __v;
70003a78d15Sespie       const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
70103a78d15Sespie       _CharT* __buf = __out + __size - 1;
70203a78d15Sespie       _CharT* __bufend = __out + __size;
70303a78d15Sespie 
70403a78d15Sespie       if (__builtin_expect(__basefield != ios_base::oct &&
70503a78d15Sespie 			   __basefield != ios_base::hex, true))
70603a78d15Sespie 	{
70703a78d15Sespie 	  // Decimal.
70803a78d15Sespie 	  do
70903a78d15Sespie 	    {
71003a78d15Sespie 	      *__buf-- = __lit[(__v % 10) + __num_base::_S_digits];
71103a78d15Sespie 	      __v /= 10;
71203a78d15Sespie 	    }
71303a78d15Sespie 	  while (__v != 0);
71403a78d15Sespie 	  if (__neg)
71503a78d15Sespie 	    *__buf-- = __lit[__num_base::_S_minus];
71603a78d15Sespie 	  else if (__flags & ios_base::showpos)
71703a78d15Sespie 	    *__buf-- = __lit[__num_base::_S_plus];
71803a78d15Sespie 	}
71903a78d15Sespie       else if (__basefield == ios_base::oct)
72003a78d15Sespie 	{
72103a78d15Sespie 	  // Octal.
72203a78d15Sespie 	  do
72303a78d15Sespie 	    {
72403a78d15Sespie 	      *__buf-- = __lit[(__v & 0x7) + __num_base::_S_digits];
72503a78d15Sespie 	      __v >>= 3;
72603a78d15Sespie 	    }
72703a78d15Sespie 	  while (__v != 0);
72803a78d15Sespie 	  if (__showbase)
72903a78d15Sespie 	    *__buf-- = __lit[__num_base::_S_digits];
73003a78d15Sespie 	}
73103a78d15Sespie       else
73203a78d15Sespie 	{
73303a78d15Sespie 	  // Hex.
73403a78d15Sespie 	  const bool __uppercase = __flags & ios_base::uppercase;
73503a78d15Sespie 	  int __case_offset = __uppercase
73603a78d15Sespie 	                      ? __num_base::_S_udigits : __num_base::_S_digits;
73703a78d15Sespie 	  do
73803a78d15Sespie 	    {
73903a78d15Sespie 	      *__buf-- = __lit[(__v & 0xf) + __case_offset];
74003a78d15Sespie 	      __v >>= 4;
74103a78d15Sespie 	    }
74203a78d15Sespie 	  while (__v != 0);
74303a78d15Sespie 	  if (__showbase)
74403a78d15Sespie 	    {
74503a78d15Sespie 	      // 'x' or 'X'
74603a78d15Sespie 	      *__buf-- = __lit[__num_base::_S_x + __uppercase];
74703a78d15Sespie 	      // '0'
74803a78d15Sespie 	      *__buf-- = __lit[__num_base::_S_digits];
74903a78d15Sespie 	    }
75003a78d15Sespie 	}
75103a78d15Sespie       int __ret = __bufend - __buf - 1;
75203a78d15Sespie       return __ret;
75303a78d15Sespie     }
75403a78d15Sespie 
75503a78d15Sespie   template<typename _CharT, typename _OutIter>
75603a78d15Sespie     void
75703a78d15Sespie     num_put<_CharT, _OutIter>::
_M_group_int(const string & __grouping,_CharT __sep,ios_base & __io,_CharT * __new,_CharT * __cs,int & __len) const75803a78d15Sespie     _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io,
75903a78d15Sespie 		 _CharT* __new, _CharT* __cs, int& __len) const
76003a78d15Sespie     {
76103a78d15Sespie       // By itself __add_grouping cannot deal correctly with __ws when
76203a78d15Sespie       // ios::showbase is set and ios_base::oct || ios_base::hex.
76303a78d15Sespie       // Therefore we take care "by hand" of the initial 0, 0x or 0X.
76403a78d15Sespie       // However, remember that the latter do not occur if the number
76503a78d15Sespie       // printed is '0' (__len == 1).
76603a78d15Sespie       streamsize __off = 0;
76703a78d15Sespie       const ios_base::fmtflags __basefield = __io.flags()
76803a78d15Sespie 	                                     & ios_base::basefield;
76903a78d15Sespie       if ((__io.flags() & ios_base::showbase) && __len > 1)
77003a78d15Sespie 	if (__basefield == ios_base::oct)
77103a78d15Sespie 	  {
77203a78d15Sespie 	    __off = 1;
77303a78d15Sespie 	    *__new = *__cs;
77403a78d15Sespie 	  }
77503a78d15Sespie 	else if (__basefield == ios_base::hex)
77603a78d15Sespie 	  {
77703a78d15Sespie 	    __off = 2;
77803a78d15Sespie 	    *__new = *__cs;
77903a78d15Sespie 	    *(__new + 1) = *(__cs + 1);
78003a78d15Sespie 	  }
78103a78d15Sespie       _CharT* __p;
78203a78d15Sespie       __p = __add_grouping(__new + __off, __sep,
78303a78d15Sespie 			   __grouping.c_str(),
78403a78d15Sespie 			   __grouping.c_str() + __grouping.size(),
78503a78d15Sespie 			   __cs + __off, __cs + __len);
78603a78d15Sespie       __len = __p - __new;
78703a78d15Sespie     }
78803a78d15Sespie 
78903a78d15Sespie   template<typename _CharT, typename _OutIter>
79003a78d15Sespie     template<typename _ValueT>
79103a78d15Sespie       _OutIter
79203a78d15Sespie       num_put<_CharT, _OutIter>::
_M_convert_int(_OutIter __s,ios_base & __io,_CharT __fill,_ValueT __v) const79303a78d15Sespie       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill,
79403a78d15Sespie 		     _ValueT __v) const
79503a78d15Sespie       {
79603a78d15Sespie 	typedef numpunct<_CharT>  __facet_type;
79703a78d15Sespie 	typedef __locale_cache<numpunct<_CharT> > __cache_type;
79803a78d15Sespie  	const locale& __loc = __io._M_getloc();
79903a78d15Sespie 	const __cache_type& __lc = __use_cache<__facet_type>(__loc);
80003a78d15Sespie 	const _CharT* __lit = __lc._M_atoms_out;
80103a78d15Sespie 
80203a78d15Sespie 	// Long enough to hold hex, dec, and octal representations.
80303a78d15Sespie 	int __ilen = 4 * sizeof(_ValueT);
80403a78d15Sespie 	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
80503a78d15Sespie 							     * __ilen));
80603a78d15Sespie 	// [22.2.2.2.2] Stage 1, numeric conversion to character.
80703a78d15Sespie 	// Result is returned right-justified in the buffer.
80803a78d15Sespie 	int __len;
80903a78d15Sespie 	__len = __int_to_char(&__cs[0], __ilen, __v, __lit, __io.flags());
81003a78d15Sespie 	__cs = __cs + __ilen - __len;
81103a78d15Sespie 
81203a78d15Sespie 	// Add grouping, if necessary.
81303a78d15Sespie 	_CharT* __cs2;
81403a78d15Sespie 	if (__lc._M_use_grouping)
81503a78d15Sespie 	  {
81603a78d15Sespie 	    // Grouping can add (almost) as many separators as the
81703a78d15Sespie 	    // number of digits, but no more.
81803a78d15Sespie 	    __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
81903a78d15Sespie 							  * __len * 2));
82003a78d15Sespie 	    _M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io,
82103a78d15Sespie 			 __cs2, __cs, __len);
82203a78d15Sespie 	    __cs = __cs2;
82303a78d15Sespie 	  }
82403a78d15Sespie 
82503a78d15Sespie 	// Pad.
82603a78d15Sespie 	_CharT* __cs3;
82703a78d15Sespie 	streamsize __w = __io.width();
82803a78d15Sespie 	if (__w > static_cast<streamsize>(__len))
82903a78d15Sespie 	  {
83003a78d15Sespie 	    __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
83103a78d15Sespie 							  * __w));
83203a78d15Sespie 	    _M_pad(__fill, __w, __io, __cs3, __cs, __len);
83303a78d15Sespie 	    __cs = __cs3;
83403a78d15Sespie 	  }
83503a78d15Sespie 	__io.width(0);
83603a78d15Sespie 
83703a78d15Sespie 	// [22.2.2.2.2] Stage 4.
83803a78d15Sespie 	// Write resulting, fully-formatted string to output iterator.
83903a78d15Sespie 	return __write(__s, __cs, __len);
84003a78d15Sespie       }
84103a78d15Sespie 
84203a78d15Sespie   template<typename _CharT, typename _OutIter>
84303a78d15Sespie     void
84403a78d15Sespie     num_put<_CharT, _OutIter>::
_M_group_float(const string & __grouping,_CharT __sep,const _CharT * __p,_CharT * __new,_CharT * __cs,int & __len) const84503a78d15Sespie     _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p,
84603a78d15Sespie 		   _CharT* __new, _CharT* __cs, int& __len) const
84703a78d15Sespie     {
84803a78d15Sespie #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
84903a78d15Sespie       //282. What types does numpunct grouping refer to?
85003a78d15Sespie       // Add grouping, if necessary.
85103a78d15Sespie       _CharT* __p2;
85203a78d15Sespie       int __declen = __p ? __p - __cs : __len;
85303a78d15Sespie       __p2 = __add_grouping(__new, __sep,
85403a78d15Sespie 			    __grouping.c_str(),
85503a78d15Sespie 			    __grouping.c_str() + __grouping.size(),
85603a78d15Sespie 			    __cs, __cs + __declen);
85703a78d15Sespie 
85803a78d15Sespie       // Tack on decimal part.
85903a78d15Sespie       int __newlen = __p2 - __new;
86003a78d15Sespie       if (__p)
86103a78d15Sespie 	{
86203a78d15Sespie 	  char_traits<_CharT>::copy(__p2, __p, __len - __declen);
86303a78d15Sespie 	  __newlen += __len - __declen;
86403a78d15Sespie 	}
86503a78d15Sespie       __len = __newlen;
86603a78d15Sespie #endif
86703a78d15Sespie     }
86803a78d15Sespie 
86903a78d15Sespie   // The following code uses snprintf (or sprintf(), when
87003a78d15Sespie   // _GLIBCPP_USE_C99 is not defined) to convert floating point values
87103a78d15Sespie   // for insertion into a stream.  An optimization would be to replace
87203a78d15Sespie   // them with code that works directly on a wide buffer and then use
87303a78d15Sespie   // __pad to do the padding.  It would be good to replace them anyway
87403a78d15Sespie   // to gain back the efficiency that C++ provides by knowing up front
87503a78d15Sespie   // the type of the values to insert.  Also, sprintf is dangerous
87603a78d15Sespie   // since may lead to accidental buffer overruns.  This
87703a78d15Sespie   // implementation follows the C++ standard fairly directly as
87803a78d15Sespie   // outlined in 22.2.2.2 [lib.locale.num.put]
87903a78d15Sespie   template<typename _CharT, typename _OutIter>
88003a78d15Sespie     template<typename _ValueT>
88103a78d15Sespie       _OutIter
88203a78d15Sespie       num_put<_CharT, _OutIter>::
_M_convert_float(_OutIter __s,ios_base & __io,_CharT __fill,char __mod,_ValueT __v) const88303a78d15Sespie       _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
88403a78d15Sespie 		       _ValueT __v) const
88503a78d15Sespie       {
88603a78d15Sespie 	// Use default precision if out of range.
88703a78d15Sespie 	streamsize __prec = __io.precision();
88819731d4fSespie 	if (__prec < static_cast<streamsize>(0))
88903a78d15Sespie 	  __prec = static_cast<streamsize>(6);
89003a78d15Sespie 
89119731d4fSespie 	const int __max_digits = numeric_limits<_ValueT>::digits10;
89219731d4fSespie 
89303a78d15Sespie 	typedef numpunct<_CharT>  __facet_type;
89403a78d15Sespie 	typedef __locale_cache<numpunct<_CharT> > __cache_type;
89503a78d15Sespie 	const locale __loc = __io._M_getloc();
89603a78d15Sespie 	const __cache_type& __lc = __use_cache<__facet_type>(__loc);
89703a78d15Sespie 
89803a78d15Sespie 	// [22.2.2.2.2] Stage 1, numeric conversion to character.
89903a78d15Sespie 	int __len;
90003a78d15Sespie 	// Long enough for the max format spec.
90103a78d15Sespie 	char __fbuf[16];
90203a78d15Sespie 
90301d8d202Skettenis #if defined _GLIBCPP_USE_C99 || defined _GLIBCPP_USE_C99_SNPRINTF
90419731d4fSespie 	// First try a buffer perhaps big enough (most probably sufficient
90503a78d15Sespie 	// for non-ios_base::fixed outputs)
90603a78d15Sespie 	int __cs_size = __max_digits * 3;
90703a78d15Sespie 	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
90803a78d15Sespie 
90903a78d15Sespie 	_S_format_float(__io, __fbuf, __mod, __prec);
91003a78d15Sespie 	__len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
91103a78d15Sespie 				 _S_c_locale, __prec);
91203a78d15Sespie 
91303a78d15Sespie 	// If the buffer was not large enough, try again with the correct size.
91403a78d15Sespie 	if (__len >= __cs_size)
91503a78d15Sespie 	  {
91603a78d15Sespie 	    __cs_size = __len + 1;
91703a78d15Sespie 	    __cs = static_cast<char*>(__builtin_alloca(__cs_size));
91803a78d15Sespie 	    __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
91903a78d15Sespie 				     _S_c_locale, __prec);
92003a78d15Sespie 	  }
92103a78d15Sespie #else
92203a78d15Sespie 	// Consider the possibility of long ios_base::fixed outputs
92303a78d15Sespie 	const bool __fixed = __io.flags() & ios_base::fixed;
92403a78d15Sespie 	const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
92503a78d15Sespie 
92603a78d15Sespie 	// ios_base::fixed outputs may need up to __max_exp + 1 chars
92719731d4fSespie 	// for the integer part + __prec chars for the fractional part
92819731d4fSespie 	// + 3 chars for sign, decimal point, '\0'. On the other hand,
92919731d4fSespie 	// for non-fixed outputs __max_digits * 2 chars + __prec are
93019731d4fSespie 	// largely sufficient.
93119731d4fSespie 	const int __cs_size = __fixed ? __max_exp + __prec + 4
93219731d4fSespie 	                              : __max_digits * 2 + __prec;
93303a78d15Sespie 	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
93403a78d15Sespie 
93503a78d15Sespie 	_S_format_float(__io, __fbuf, __mod, __prec);
93603a78d15Sespie 	__len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
93703a78d15Sespie #endif
93803a78d15Sespie 
93903a78d15Sespie       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
94003a78d15Sespie       // numpunct.decimal_point() values for '.' and adding grouping.
94103a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
94203a78d15Sespie 
94303a78d15Sespie       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
94403a78d15Sespie 							   * __len));
94503a78d15Sespie       __ctype.widen(__cs, __cs + __len, __ws);
94603a78d15Sespie 
94703a78d15Sespie       // Replace decimal point.
94803a78d15Sespie       const _CharT __cdec = __ctype.widen('.');
94903a78d15Sespie       const _CharT __dec = __lc._M_decimal_point;
95003a78d15Sespie       const _CharT* __p;
95103a78d15Sespie       if (__p = char_traits<_CharT>::find(__ws, __len, __cdec))
95203a78d15Sespie 	__ws[__p - __ws] = __dec;
95303a78d15Sespie 
95403a78d15Sespie       // Add grouping, if necessary.
95503a78d15Sespie       _CharT* __ws2;
95603a78d15Sespie       if (__lc._M_use_grouping)
95703a78d15Sespie 	{
95803a78d15Sespie 	    // Grouping can add (almost) as many separators as the
95903a78d15Sespie 	    // number of digits, but no more.
96003a78d15Sespie 	    __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
96103a78d15Sespie 							  * __len * 2));
96203a78d15Sespie 	    _M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p,
96303a78d15Sespie 			   __ws2, __ws, __len);
96403a78d15Sespie 	    __ws = __ws2;
96503a78d15Sespie 	}
96603a78d15Sespie 
96703a78d15Sespie       // Pad.
96803a78d15Sespie       _CharT* __ws3;
96903a78d15Sespie       streamsize __w = __io.width();
97003a78d15Sespie       if (__w > static_cast<streamsize>(__len))
97103a78d15Sespie 	{
97203a78d15Sespie 	  __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
97303a78d15Sespie 	  _M_pad(__fill, __w, __io, __ws3, __ws, __len);
97403a78d15Sespie 	  __ws = __ws3;
97503a78d15Sespie 	}
97603a78d15Sespie       __io.width(0);
97703a78d15Sespie 
97803a78d15Sespie       // [22.2.2.2.2] Stage 4.
97903a78d15Sespie       // Write resulting, fully-formatted string to output iterator.
98003a78d15Sespie       return __write(__s, __ws, __len);
98103a78d15Sespie       }
98203a78d15Sespie 
98303a78d15Sespie   template<typename _CharT, typename _OutIter>
98403a78d15Sespie     _OutIter
98503a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,bool __v) const98603a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
98703a78d15Sespie     {
98803a78d15Sespie       ios_base::fmtflags __flags = __io.flags();
98903a78d15Sespie       if ((__flags & ios_base::boolalpha) == 0)
99003a78d15Sespie         {
99103a78d15Sespie           unsigned long __uv = __v;
99203a78d15Sespie           __s = _M_convert_int(__s, __io, __fill, __uv);
99303a78d15Sespie         }
99403a78d15Sespie       else
99503a78d15Sespie         {
99603a78d15Sespie 	  typedef numpunct<_CharT>  __facet_type;
99703a78d15Sespie 	  typedef __locale_cache<numpunct<_CharT> > __cache_type;
99803a78d15Sespie 	  const locale __loc = __io._M_getloc();
99903a78d15Sespie 	  const __cache_type& __lc = __use_cache<__facet_type>(__loc);
100003a78d15Sespie 
100103a78d15Sespie 	  typedef basic_string<_CharT> 	__string_type;
100203a78d15Sespie 	  __string_type __name;
100303a78d15Sespie           if (__v)
100403a78d15Sespie 	    __name = __lc._M_truename;
100503a78d15Sespie           else
100603a78d15Sespie 	    __name = __lc._M_falsename;
100703a78d15Sespie 
100803a78d15Sespie 	  const _CharT* __cs = __name.c_str();
100903a78d15Sespie 	  int __len = __name.size();
101003a78d15Sespie 	  _CharT* __cs3;
101103a78d15Sespie 	  streamsize __w = __io.width();
101203a78d15Sespie 	  if (__w > static_cast<streamsize>(__len))
101303a78d15Sespie 	    {
101403a78d15Sespie 	      __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
101503a78d15Sespie 							    * __w));
101603a78d15Sespie 	      _M_pad(__fill, __w, __io, __cs3, __cs, __len);
101703a78d15Sespie 	      __cs = __cs3;
101803a78d15Sespie 	    }
101903a78d15Sespie 	  __io.width(0);
102003a78d15Sespie 	  __s = __write(__s, __cs, __len);
102103a78d15Sespie 	}
102203a78d15Sespie       return __s;
102303a78d15Sespie     }
102403a78d15Sespie 
102503a78d15Sespie   template<typename _CharT, typename _OutIter>
102603a78d15Sespie     _OutIter
102703a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,long __v) const102803a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
102903a78d15Sespie     { return _M_convert_int(__s, __io, __fill, __v); }
103003a78d15Sespie 
103103a78d15Sespie   template<typename _CharT, typename _OutIter>
103203a78d15Sespie     _OutIter
103303a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,unsigned long __v) const103403a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill,
103503a78d15Sespie            unsigned long __v) const
103603a78d15Sespie     { return _M_convert_int(__s, __io, __fill, __v); }
103703a78d15Sespie 
103803a78d15Sespie #ifdef _GLIBCPP_USE_LONG_LONG
103903a78d15Sespie   template<typename _CharT, typename _OutIter>
104003a78d15Sespie     _OutIter
104103a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __b,char_type __fill,long long __v) const104203a78d15Sespie     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
104303a78d15Sespie     { return _M_convert_int(__s, __b, __fill, __v); }
104403a78d15Sespie 
104503a78d15Sespie   template<typename _CharT, typename _OutIter>
104603a78d15Sespie     _OutIter
104703a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,unsigned long long __v) const104803a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill,
104903a78d15Sespie            unsigned long long __v) const
105003a78d15Sespie     { return _M_convert_int(__s, __io, __fill, __v); }
105103a78d15Sespie #endif
105203a78d15Sespie 
105303a78d15Sespie   template<typename _CharT, typename _OutIter>
105403a78d15Sespie     _OutIter
105503a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,double __v) const105603a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
105703a78d15Sespie     { return _M_convert_float(__s, __io, __fill, char(), __v); }
105803a78d15Sespie 
105903a78d15Sespie   template<typename _CharT, typename _OutIter>
106003a78d15Sespie     _OutIter
106103a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,long double __v) const106203a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill,
106303a78d15Sespie 	   long double __v) const
106403a78d15Sespie     { return _M_convert_float(__s, __io, __fill, 'L', __v); }
106503a78d15Sespie 
106603a78d15Sespie   template<typename _CharT, typename _OutIter>
106703a78d15Sespie     _OutIter
106803a78d15Sespie     num_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type __fill,const void * __v) const106903a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type __fill,
107003a78d15Sespie            const void* __v) const
107103a78d15Sespie     {
107203a78d15Sespie       ios_base::fmtflags __flags = __io.flags();
107303a78d15Sespie       ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
107403a78d15Sespie 				   | ios_base::uppercase | ios_base::internal);
107503a78d15Sespie       __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
107603a78d15Sespie       try
107703a78d15Sespie 	{
107803a78d15Sespie 	  __s = _M_convert_int(__s, __io, __fill,
107903a78d15Sespie 			       reinterpret_cast<unsigned long>(__v));
108003a78d15Sespie 	  __io.flags(__flags);
108103a78d15Sespie 	}
108203a78d15Sespie       catch (...)
108303a78d15Sespie 	{
108403a78d15Sespie 	  __io.flags(__flags);
108503a78d15Sespie 	  __throw_exception_again;
108603a78d15Sespie 	}
108703a78d15Sespie       return __s;
108803a78d15Sespie     }
108903a78d15Sespie 
109003a78d15Sespie 
109103a78d15Sespie   template<typename _CharT, typename _InIter>
109203a78d15Sespie     _InIter
109303a78d15Sespie     money_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,bool __intl,ios_base & __io,ios_base::iostate & __err,long double & __units) const109403a78d15Sespie     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
109503a78d15Sespie 	   ios_base::iostate& __err, long double& __units) const
109603a78d15Sespie     {
109703a78d15Sespie       string_type __str;
109803a78d15Sespie       __beg = this->do_get(__beg, __end, __intl, __io, __err, __str);
109903a78d15Sespie 
110019731d4fSespie       const int __cs_size = __str.size() + 1;
110119731d4fSespie       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
110203a78d15Sespie       const locale __loc = __io.getloc();
110303a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
110403a78d15Sespie       const _CharT* __wcs = __str.c_str();
110519731d4fSespie       __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs);
110603a78d15Sespie       __convert_to_v(__cs, __units, __err, _S_c_locale);
110703a78d15Sespie       return __beg;
110803a78d15Sespie     }
110903a78d15Sespie 
111003a78d15Sespie   template<typename _CharT, typename _InIter>
111103a78d15Sespie     _InIter
111203a78d15Sespie     money_get<_CharT, _InIter>::
do_get(iter_type __beg,iter_type __end,bool __intl,ios_base & __io,ios_base::iostate & __err,string_type & __units) const111303a78d15Sespie     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
111403a78d15Sespie 	   ios_base::iostate& __err, string_type& __units) const
111503a78d15Sespie     {
111603a78d15Sespie       // These contortions are quite unfortunate.
111703a78d15Sespie       typedef moneypunct<_CharT, true> 		__money_true;
111803a78d15Sespie       typedef moneypunct<_CharT, false> 	__money_false;
111903a78d15Sespie       typedef money_base::part 			part;
112003a78d15Sespie       typedef typename string_type::size_type 	size_type;
112103a78d15Sespie 
112203a78d15Sespie       const locale __loc = __io.getloc();
112303a78d15Sespie       const __money_true& __mpt = use_facet<__money_true>(__loc);
112403a78d15Sespie       const __money_false& __mpf = use_facet<__money_false>(__loc);
112503a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
112603a78d15Sespie 
112703a78d15Sespie       const money_base::pattern __p = __intl ? __mpt.neg_format()
112803a78d15Sespie 					     : __mpf.neg_format();
112903a78d15Sespie 
113003a78d15Sespie       const string_type __pos_sign =__intl ? __mpt.positive_sign()
113103a78d15Sespie 					   : __mpf.positive_sign();
113203a78d15Sespie       const string_type __neg_sign =__intl ? __mpt.negative_sign()
113303a78d15Sespie 					   : __mpf.negative_sign();
113403a78d15Sespie       const char_type __d = __intl ? __mpt.decimal_point()
113503a78d15Sespie   	    	       		   : __mpf.decimal_point();
113603a78d15Sespie       const char_type __sep = __intl ? __mpt.thousands_sep()
113703a78d15Sespie 		    		     : __mpf.thousands_sep();
113803a78d15Sespie 
113903a78d15Sespie       const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
114003a78d15Sespie 
114103a78d15Sespie       // Set to deduced positive or negative sign, depending.
114203a78d15Sespie       string_type __sign;
114303a78d15Sespie       // String of grouping info from thousands_sep plucked from __units.
114403a78d15Sespie       string __grouping_tmp;
114503a78d15Sespie       // Marker for thousands_sep position.
114603a78d15Sespie       int __sep_pos = 0;
114703a78d15Sespie       // If input iterator is in a valid state.
114803a78d15Sespie       bool __testvalid = true;
114903a78d15Sespie       // Flag marking when a decimal point is found.
115003a78d15Sespie       bool __testdecfound = false;
115103a78d15Sespie 
115203a78d15Sespie       // The tentative returned string is stored here.
115303a78d15Sespie       string_type __temp_units;
115403a78d15Sespie 
115503a78d15Sespie       char_type __c = *__beg;
115603a78d15Sespie       char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
115703a78d15Sespie       for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
115803a78d15Sespie 	{
115903a78d15Sespie 	  part __which = static_cast<part>(__p.field[__i]);
116003a78d15Sespie 	  switch (__which)
116103a78d15Sespie 		{
116203a78d15Sespie 		case money_base::symbol:
116303a78d15Sespie 		  if (__io.flags() & ios_base::showbase
116403a78d15Sespie 		      || __i < 2 || __sign.size() > 1
116503a78d15Sespie 		      || ((static_cast<part>(__p.field[3]) != money_base::none)
116603a78d15Sespie 			  && __i == 2))
116703a78d15Sespie 		    {
116803a78d15Sespie 		      // According to 22.2.6.1.2.2, symbol is required
116903a78d15Sespie 		      // if (__io.flags() & ios_base::showbase),
117003a78d15Sespie 		      // otherwise is optional and consumed only if
117103a78d15Sespie 		      // other characters are needed to complete the
117203a78d15Sespie 		      // format.
117303a78d15Sespie 		      const string_type __symbol = __intl ? __mpt.curr_symbol()
117403a78d15Sespie 						    	 : __mpf.curr_symbol();
117503a78d15Sespie 		      size_type __len = __symbol.size();
117603a78d15Sespie 		      size_type __j = 0;
117703a78d15Sespie 		      while (__beg != __end
117803a78d15Sespie 			     && __j < __len && __symbol[__j] == __c)
117903a78d15Sespie 			{
118003a78d15Sespie 			  __c = *(++__beg);
118103a78d15Sespie 			  ++__j;
118203a78d15Sespie 			}
118303a78d15Sespie 		      // When (__io.flags() & ios_base::showbase)
118403a78d15Sespie 		      // symbol is required.
118503a78d15Sespie 		      if (__j != __len && (__io.flags() & ios_base::showbase))
118603a78d15Sespie 			__testvalid = false;
118703a78d15Sespie 		    }
118803a78d15Sespie 		  break;
118903a78d15Sespie 		case money_base::sign:
119003a78d15Sespie 		  // Sign might not exist, or be more than one character long.
119103a78d15Sespie 		  if (__pos_sign.size() && __neg_sign.size())
119203a78d15Sespie 		  {
119303a78d15Sespie 		    // Sign is mandatory.
119403a78d15Sespie 		    if (__c == __pos_sign[0])
119503a78d15Sespie 		      {
119603a78d15Sespie 			__sign = __pos_sign;
119703a78d15Sespie 			__c = *(++__beg);
119803a78d15Sespie 		      }
119903a78d15Sespie 		    else if (__c == __neg_sign[0])
120003a78d15Sespie 		      {
120103a78d15Sespie 			__sign = __neg_sign;
120203a78d15Sespie 			__c = *(++__beg);
120303a78d15Sespie 		      }
120403a78d15Sespie 		    else
120503a78d15Sespie 		      __testvalid = false;
120603a78d15Sespie 		  }
120703a78d15Sespie 		  else if (__pos_sign.size() && __c == __pos_sign[0])
120803a78d15Sespie 		    {
120903a78d15Sespie 		      __sign = __pos_sign;
121003a78d15Sespie 		      __c = *(++__beg);
121103a78d15Sespie 		    }
121203a78d15Sespie 		  else if (__neg_sign.size() && __c == __neg_sign[0])
121303a78d15Sespie 		    {
121403a78d15Sespie 		      __sign = __neg_sign;
121503a78d15Sespie 		      __c = *(++__beg);
121603a78d15Sespie 		    }
121703a78d15Sespie 		  break;
121803a78d15Sespie 		case money_base::value:
121903a78d15Sespie 		  // Extract digits, remove and stash away the
122003a78d15Sespie 		  // grouping of found thousands separators.
122103a78d15Sespie 		  while (__beg != __end
122203a78d15Sespie 			 && (__ctype.is(ctype_base::digit, __c)
122303a78d15Sespie 			     || (__c == __d && !__testdecfound)
122403a78d15Sespie 			     || __c == __sep))
122503a78d15Sespie 		    {
122603a78d15Sespie 		      if (__c == __d)
122703a78d15Sespie 			{
122803a78d15Sespie 			  __grouping_tmp += static_cast<char>(__sep_pos);
122903a78d15Sespie 			  __sep_pos = 0;
123003a78d15Sespie 			  __testdecfound = true;
123103a78d15Sespie 			}
123203a78d15Sespie 		      else if (__c == __sep)
123303a78d15Sespie 			{
123403a78d15Sespie 			  if (__grouping.size())
123503a78d15Sespie 			    {
123603a78d15Sespie 			      // Mark position for later analysis.
123703a78d15Sespie 			      __grouping_tmp += static_cast<char>(__sep_pos);
123803a78d15Sespie 			      __sep_pos = 0;
123903a78d15Sespie 			    }
124003a78d15Sespie 			  else
124103a78d15Sespie 			    {
124203a78d15Sespie 			      __testvalid = false;
124303a78d15Sespie 			      break;
124403a78d15Sespie 			    }
124503a78d15Sespie 			}
124603a78d15Sespie 		      else
124703a78d15Sespie 			{
124803a78d15Sespie 			  __temp_units += __c;
124903a78d15Sespie 			  ++__sep_pos;
125003a78d15Sespie 			}
125103a78d15Sespie 		      __c = *(++__beg);
125203a78d15Sespie 		    }
125303a78d15Sespie 		  break;
125403a78d15Sespie 		case money_base::space:
125503a78d15Sespie 		case money_base::none:
125603a78d15Sespie 		  // Only if not at the end of the pattern.
125703a78d15Sespie 		  if (__i != 3)
125803a78d15Sespie 		    while (__beg != __end
125903a78d15Sespie 			   && __ctype.is(ctype_base::space, __c))
126003a78d15Sespie 		      __c = *(++__beg);
126103a78d15Sespie 		  break;
126203a78d15Sespie 		}
126303a78d15Sespie 	}
126403a78d15Sespie 
126503a78d15Sespie       // Need to get the rest of the sign characters, if they exist.
126603a78d15Sespie       if (__sign.size() > 1)
126703a78d15Sespie 	{
126803a78d15Sespie 	  size_type __len = __sign.size();
126903a78d15Sespie 	  size_type __i = 1;
127003a78d15Sespie 	  for (; __c != __eof && __i < __len; ++__i)
127103a78d15Sespie 	    while (__beg != __end && __c != __sign[__i])
127203a78d15Sespie 	      __c = *(++__beg);
127303a78d15Sespie 
127403a78d15Sespie 	  if (__i != __len)
127503a78d15Sespie 	    __testvalid = false;
127603a78d15Sespie 	}
127703a78d15Sespie 
127803a78d15Sespie       // Strip leading zeros.
127903a78d15Sespie       while (__temp_units.size() > 1 && __temp_units[0] == __ctype.widen('0'))
128003a78d15Sespie 	__temp_units.erase(__temp_units.begin());
128103a78d15Sespie 
128203a78d15Sespie       if (__sign.size() && __sign == __neg_sign)
128303a78d15Sespie 	__temp_units.insert(__temp_units.begin(), __ctype.widen('-'));
128403a78d15Sespie 
128503a78d15Sespie       // Test for grouping fidelity.
128603a78d15Sespie       if (__grouping.size() && __grouping_tmp.size())
128703a78d15Sespie 	{
128803a78d15Sespie 	  if (!__verify_grouping(__grouping, __grouping_tmp))
128903a78d15Sespie 	    __testvalid = false;
129003a78d15Sespie 	}
129103a78d15Sespie 
129203a78d15Sespie       // Iff no more characters are available.
129303a78d15Sespie       if (__c == __eof)
129403a78d15Sespie 	__err |= ios_base::eofbit;
129503a78d15Sespie 
129603a78d15Sespie       // Iff valid sequence is not recognized.
129703a78d15Sespie       if (!__testvalid || !__temp_units.size())
129803a78d15Sespie 	__err |= ios_base::failbit;
129903a78d15Sespie       else
130003a78d15Sespie 	// Use the "swap trick" to copy __temp_units into __units.
130103a78d15Sespie 	__temp_units.swap(__units);
130203a78d15Sespie 
130303a78d15Sespie       return __beg;
130403a78d15Sespie     }
130503a78d15Sespie 
130603a78d15Sespie   template<typename _CharT, typename _OutIter>
130703a78d15Sespie     _OutIter
130803a78d15Sespie     money_put<_CharT, _OutIter>::
do_put(iter_type __s,bool __intl,ios_base & __io,char_type __fill,long double __units) const130903a78d15Sespie     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
131003a78d15Sespie 	   long double __units) const
131103a78d15Sespie     {
131203a78d15Sespie       const locale __loc = __io.getloc();
131303a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
131401d8d202Skettenis #if defined _GLIBCPP_USE_C99 || defined _GLIBCPP_USE_C99_SNPRINTF
131503a78d15Sespie       // First try a buffer perhaps big enough.
131603a78d15Sespie       int __cs_size = 64;
131703a78d15Sespie       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
131819731d4fSespie       // _GLIBCXX_RESOLVE_LIB_DEFECTS
131919731d4fSespie       // 328. Bad sprintf format modifier in money_put<>::do_put()
132019731d4fSespie       int __len = __convert_from_v(__cs, __cs_size, "%.0Lf", __units,
132103a78d15Sespie 				   _S_c_locale);
132203a78d15Sespie       // If the buffer was not large enough, try again with the correct size.
132303a78d15Sespie       if (__len >= __cs_size)
132403a78d15Sespie 	{
132503a78d15Sespie 	  __cs_size = __len + 1;
132603a78d15Sespie 	  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
132719731d4fSespie 	  __len = __convert_from_v(__cs, __cs_size, "%.0Lf", __units,
132803a78d15Sespie 				   _S_c_locale);
132903a78d15Sespie 	}
133003a78d15Sespie #else
133119731d4fSespie       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
133219731d4fSespie       const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
133303a78d15Sespie       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
133419731d4fSespie       int __len = __convert_from_v(__cs, 0, "%.0Lf", __units, _S_c_locale);
133503a78d15Sespie #endif
133603a78d15Sespie       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
133703a78d15Sespie 							   * __cs_size));
133803a78d15Sespie       __ctype.widen(__cs, __cs + __len, __ws);
133919731d4fSespie       const string_type __digits(__ws, __len);
134003a78d15Sespie       return this->do_put(__s, __intl, __io, __fill, __digits);
134103a78d15Sespie     }
134203a78d15Sespie 
134303a78d15Sespie   template<typename _CharT, typename _OutIter>
134403a78d15Sespie     _OutIter
134503a78d15Sespie     money_put<_CharT, _OutIter>::
do_put(iter_type __s,bool __intl,ios_base & __io,char_type __fill,const string_type & __digits) const134603a78d15Sespie     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
134703a78d15Sespie 	   const string_type& __digits) const
134803a78d15Sespie     {
134903a78d15Sespie       typedef typename string_type::size_type 	size_type;
135003a78d15Sespie       typedef money_base::part 			part;
135103a78d15Sespie 
135203a78d15Sespie       const locale __loc = __io.getloc();
135303a78d15Sespie       const size_type __width = static_cast<size_type>(__io.width());
135403a78d15Sespie 
135503a78d15Sespie       // These contortions are quite unfortunate.
135603a78d15Sespie       typedef moneypunct<_CharT, true> __money_true;
135703a78d15Sespie       typedef moneypunct<_CharT, false> __money_false;
135803a78d15Sespie       const __money_true& __mpt = use_facet<__money_true>(__loc);
135903a78d15Sespie       const __money_false& __mpf = use_facet<__money_false>(__loc);
136003a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
136103a78d15Sespie 
136203a78d15Sespie       // Determine if negative or positive formats are to be used, and
136303a78d15Sespie       // discard leading negative_sign if it is present.
136403a78d15Sespie       const char_type* __beg = __digits.data();
136503a78d15Sespie       const char_type* __end = __beg + __digits.size();
136603a78d15Sespie       money_base::pattern __p;
136703a78d15Sespie       string_type __sign;
136803a78d15Sespie       if (*__beg != __ctype.widen('-'))
136903a78d15Sespie 	{
137003a78d15Sespie 	  __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
137103a78d15Sespie 	  __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
137203a78d15Sespie 	}
137303a78d15Sespie       else
137403a78d15Sespie 	{
137503a78d15Sespie 	  __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
137603a78d15Sespie 	  __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
137703a78d15Sespie 	  ++__beg;
137803a78d15Sespie 	}
137903a78d15Sespie 
138003a78d15Sespie       // Look for valid numbers in the current ctype facet within input digits.
138103a78d15Sespie       __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
138203a78d15Sespie       if (__beg != __end)
138303a78d15Sespie 	{
138403a78d15Sespie 	  // Assume valid input, and attempt to format.
138503a78d15Sespie 	  // Break down input numbers into base components, as follows:
138603a78d15Sespie 	  //   final_value = grouped units + (decimal point) + (digits)
138703a78d15Sespie 	  string_type __res;
138803a78d15Sespie 	  string_type __value;
138903a78d15Sespie 	  const string_type __symbol = __intl ? __mpt.curr_symbol()
139003a78d15Sespie 	    				      : __mpf.curr_symbol();
139103a78d15Sespie 
139203a78d15Sespie 	  // Deal with decimal point, decimal digits.
139303a78d15Sespie 	  const int __frac = __intl ? __mpt.frac_digits()
139403a78d15Sespie 	    			    : __mpf.frac_digits();
139503a78d15Sespie 	  if (__frac > 0)
139603a78d15Sespie 	    {
139703a78d15Sespie 	      const char_type __d = __intl ? __mpt.decimal_point()
139803a78d15Sespie 					   : __mpf.decimal_point();
139903a78d15Sespie 	      if (__end - __beg >= __frac)
140003a78d15Sespie 		{
140103a78d15Sespie 		  __value = string_type(__end - __frac, __end);
140203a78d15Sespie 		  __value.insert(__value.begin(), __d);
140303a78d15Sespie 		  __end -= __frac;
140403a78d15Sespie 		}
140503a78d15Sespie 	      else
140603a78d15Sespie 		{
140703a78d15Sespie 		  // Have to pad zeros in the decimal position.
140803a78d15Sespie 		  __value = string_type(__beg, __end);
140903a78d15Sespie 		  int __paddec = __frac - (__end - __beg);
141003a78d15Sespie 		  char_type __zero = __ctype.widen('0');
141103a78d15Sespie 		  __value.insert(__value.begin(), __paddec, __zero);
141203a78d15Sespie 		  __value.insert(__value.begin(), __d);
141303a78d15Sespie 		  __beg = __end;
141403a78d15Sespie 		}
141503a78d15Sespie 	    }
141603a78d15Sespie 
141703a78d15Sespie 	  // Add thousands separators to non-decimal digits, per
141803a78d15Sespie 	  // grouping rules.
141903a78d15Sespie 	  if (__beg != __end)
142003a78d15Sespie 	    {
142103a78d15Sespie 	      const string __grouping = __intl ? __mpt.grouping()
142203a78d15Sespie 					       : __mpf.grouping();
142303a78d15Sespie 	      if (__grouping.size())
142403a78d15Sespie 		{
142503a78d15Sespie 		  const char_type __sep = __intl ? __mpt.thousands_sep()
142603a78d15Sespie 		    			         : __mpf.thousands_sep();
142703a78d15Sespie 		  const char* __gbeg = __grouping.c_str();
142803a78d15Sespie 		  const char* __gend = __gbeg + __grouping.size();
142903a78d15Sespie 		  const int __n = (__end - __beg) * 2;
143003a78d15Sespie 		  _CharT* __ws2 =
143103a78d15Sespie        	          static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
143203a78d15Sespie 		  _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
143303a78d15Sespie 						    __gend, __beg, __end);
143403a78d15Sespie 		  __value.insert(0, __ws2, __ws_end - __ws2);
143503a78d15Sespie 		}
143603a78d15Sespie 	      else
143703a78d15Sespie 		__value.insert(0, string_type(__beg, __end));
143803a78d15Sespie 	    }
143903a78d15Sespie 
144003a78d15Sespie 	  // Calculate length of resulting string.
144103a78d15Sespie 	  ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
144203a78d15Sespie 	  size_type __len = __value.size() + __sign.size();
144303a78d15Sespie 	  __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
144403a78d15Sespie 	  bool __testipad = __f == ios_base::internal && __len < __width;
144503a78d15Sespie 
144603a78d15Sespie 	  // Fit formatted digits into the required pattern.
144703a78d15Sespie 	  for (int __i = 0; __i < 4; ++__i)
144803a78d15Sespie 	    {
144903a78d15Sespie 	      part __which = static_cast<part>(__p.field[__i]);
145003a78d15Sespie 	      switch (__which)
145103a78d15Sespie 		{
145203a78d15Sespie 		case money_base::symbol:
145303a78d15Sespie 		  if (__io.flags() & ios_base::showbase)
145403a78d15Sespie 		    __res += __symbol;
145503a78d15Sespie 		  break;
145603a78d15Sespie 		case money_base::sign:
145703a78d15Sespie 		  // Sign might not exist, or be more than one
145803a78d15Sespie 		  // charater long. In that case, add in the rest
145903a78d15Sespie 		  // below.
146003a78d15Sespie 		  if (__sign.size())
146103a78d15Sespie 		    __res += __sign[0];
146203a78d15Sespie 		  break;
146303a78d15Sespie 		case money_base::value:
146403a78d15Sespie 		  __res += __value;
146503a78d15Sespie 		  break;
146603a78d15Sespie 		case money_base::space:
146703a78d15Sespie 		  // At least one space is required, but if internal
146803a78d15Sespie 		  // formatting is required, an arbitrary number of
146903a78d15Sespie 		  // fill spaces will be necessary.
147003a78d15Sespie 		  if (__testipad)
147103a78d15Sespie 		    __res += string_type(__width - __len, __fill);
147203a78d15Sespie 		  else
147303a78d15Sespie 		    __res += __ctype.widen(__fill);
147403a78d15Sespie 		  break;
147503a78d15Sespie 		case money_base::none:
147603a78d15Sespie 		  if (__testipad)
147703a78d15Sespie 		    __res += string_type(__width - __len, __fill);
147803a78d15Sespie 		  break;
147903a78d15Sespie 		}
148003a78d15Sespie 	    }
148103a78d15Sespie 
148203a78d15Sespie 	  // Special case of multi-part sign parts.
148303a78d15Sespie 	  if (__sign.size() > 1)
148403a78d15Sespie 	    __res += string_type(__sign.begin() + 1, __sign.end());
148503a78d15Sespie 
148603a78d15Sespie 	  // Pad, if still necessary.
148703a78d15Sespie 	  __len = __res.size();
148803a78d15Sespie 	  if (__width > __len)
148903a78d15Sespie 	    {
149003a78d15Sespie 	      if (__f == ios_base::left)
149103a78d15Sespie 		// After.
149203a78d15Sespie 		__res.append(__width - __len, __fill);
149303a78d15Sespie 	      else
149403a78d15Sespie 		// Before.
149503a78d15Sespie 		__res.insert(0, string_type(__width - __len, __fill));
149603a78d15Sespie 	      __len = __width;
149703a78d15Sespie 	    }
149803a78d15Sespie 
149903a78d15Sespie 	  // Write resulting, fully-formatted string to output iterator.
150003a78d15Sespie 	  __s = __write(__s, __res.c_str(), __len);
150103a78d15Sespie 	}
150203a78d15Sespie       __io.width(0);
150303a78d15Sespie       return __s;
150403a78d15Sespie     }
150503a78d15Sespie 
150603a78d15Sespie 
150703a78d15Sespie   // NB: Not especially useful. Without an ios_base object or some
150803a78d15Sespie   // kind of locale reference, we are left clawing at the air where
150903a78d15Sespie   // the side of the mountain used to be...
151003a78d15Sespie   template<typename _CharT, typename _InIter>
151103a78d15Sespie     time_base::dateorder
do_date_order() const151203a78d15Sespie     time_get<_CharT, _InIter>::do_date_order() const
151303a78d15Sespie     { return time_base::no_order; }
151403a78d15Sespie 
151503a78d15Sespie   template<typename _CharT, typename _InIter>
151603a78d15Sespie     void
151703a78d15Sespie     time_get<_CharT, _InIter>::
_M_extract_via_format(iter_type & __beg,iter_type & __end,ios_base & __io,ios_base::iostate & __err,tm * __tm,const _CharT * __format) const151803a78d15Sespie     _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
151903a78d15Sespie 			  ios_base::iostate& __err, tm* __tm,
152003a78d15Sespie 			  const _CharT* __format) const
152103a78d15Sespie     {
152203a78d15Sespie       locale __loc = __io.getloc();
152303a78d15Sespie       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
152403a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
152503a78d15Sespie       size_t __len = char_traits<_CharT>::length(__format);
152603a78d15Sespie 
152703a78d15Sespie       for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
152803a78d15Sespie 	{
152903a78d15Sespie 	  char __c = __format[__i];
153003a78d15Sespie 	  if (__c == '%')
153103a78d15Sespie 	    {
153203a78d15Sespie 	      // Verify valid formatting code, attempt to extract.
153303a78d15Sespie 	      __c = __format[++__i];
153403a78d15Sespie 	      char __mod = 0;
153503a78d15Sespie 	      int __mem = 0;
153603a78d15Sespie 	      if (__c == 'E' || __c == 'O')
153703a78d15Sespie 		{
153803a78d15Sespie 		  __mod = __c;
153903a78d15Sespie 		  __c = __format[++__i];
154003a78d15Sespie 		}
154103a78d15Sespie 	      switch (__c)
154203a78d15Sespie 		{
154303a78d15Sespie 		  const char* __cs;
154403a78d15Sespie 		  _CharT __wcs[10];
154503a78d15Sespie 		case 'a':
154603a78d15Sespie 		  // Abbreviated weekday name [tm_wday]
154703a78d15Sespie 		  const char_type*  __days1[7];
154803a78d15Sespie 		  __tp._M_days_abbreviated(__days1);
154903a78d15Sespie 		  _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
155003a78d15Sespie 				  __err);
155103a78d15Sespie 		  break;
155203a78d15Sespie 		case 'A':
155303a78d15Sespie 		  // Weekday name [tm_wday].
155403a78d15Sespie 		  const char_type*  __days2[7];
155503a78d15Sespie 		  __tp._M_days(__days2);
155603a78d15Sespie 		  _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
155703a78d15Sespie 				  __err);
155803a78d15Sespie 		  break;
155903a78d15Sespie 		case 'h':
156003a78d15Sespie 		case 'b':
156103a78d15Sespie 		  // Abbreviated month name [tm_mon]
156203a78d15Sespie 		  const char_type*  __months1[12];
156303a78d15Sespie 		  __tp._M_months_abbreviated(__months1);
156403a78d15Sespie 		  _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
156503a78d15Sespie 				  __err);
156603a78d15Sespie 		  break;
156703a78d15Sespie 		case 'B':
156803a78d15Sespie 		  // Month name [tm_mon].
156903a78d15Sespie 		  const char_type*  __months2[12];
157003a78d15Sespie 		  __tp._M_months(__months2);
157103a78d15Sespie 		  _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
157203a78d15Sespie 				  __err);
157303a78d15Sespie 		  break;
157403a78d15Sespie 		case 'c':
157503a78d15Sespie 		  // Default time and date representation.
157603a78d15Sespie 		  const char_type*  __dt[2];
157703a78d15Sespie 		  __tp._M_date_time_formats(__dt);
157803a78d15Sespie 		  _M_extract_via_format(__beg, __end, __io, __err, __tm,
157903a78d15Sespie 					__dt[0]);
158003a78d15Sespie 		  break;
158103a78d15Sespie 		case 'd':
158203a78d15Sespie 		  // Day [01, 31]. [tm_mday]
158303a78d15Sespie 		  _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
158403a78d15Sespie 				 __ctype, __err);
158503a78d15Sespie 		  break;
158603a78d15Sespie 		case 'D':
158703a78d15Sespie 		  // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
158803a78d15Sespie 		  __cs = "%m/%d/%y";
158903a78d15Sespie 		  __ctype.widen(__cs, __cs + 9, __wcs);
159003a78d15Sespie 		  _M_extract_via_format(__beg, __end, __io, __err, __tm,
159103a78d15Sespie 					__wcs);
159203a78d15Sespie 		  break;
159303a78d15Sespie 		case 'H':
159403a78d15Sespie 		  // Hour [00, 23]. [tm_hour]
159503a78d15Sespie 		  _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
159603a78d15Sespie 				 __ctype, __err);
159703a78d15Sespie 		  break;
159803a78d15Sespie 		case 'I':
159903a78d15Sespie 		  // Hour [01, 12]. [tm_hour]
160003a78d15Sespie 		  _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
160103a78d15Sespie 				 __ctype, __err);
160203a78d15Sespie 		  break;
160303a78d15Sespie 		case 'm':
160403a78d15Sespie 		  // Month [01, 12]. [tm_mon]
160503a78d15Sespie 		  _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype,
160603a78d15Sespie 				 __err);
160703a78d15Sespie 		  if (!__err)
160803a78d15Sespie 		    __tm->tm_mon = __mem - 1;
160903a78d15Sespie 		  break;
161003a78d15Sespie 		case 'M':
161103a78d15Sespie 		  // Minute [00, 59]. [tm_min]
161203a78d15Sespie 		  _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
161303a78d15Sespie 				 __ctype, __err);
161403a78d15Sespie 		  break;
161503a78d15Sespie 		case 'n':
161603a78d15Sespie 		  if (__ctype.narrow(*__beg, 0) == '\n')
161703a78d15Sespie 		    ++__beg;
161803a78d15Sespie 		  else
161903a78d15Sespie 		    __err |= ios_base::failbit;
162003a78d15Sespie 		  break;
162103a78d15Sespie 		case 'R':
162203a78d15Sespie 		  // Equivalent to (%H:%M).
162303a78d15Sespie 		  __cs = "%H:%M";
162403a78d15Sespie 		  __ctype.widen(__cs, __cs + 6, __wcs);
162503a78d15Sespie 		  _M_extract_via_format(__beg, __end, __io, __err, __tm,
162603a78d15Sespie 					__wcs);
162703a78d15Sespie 		  break;
162803a78d15Sespie 		case 'S':
162903a78d15Sespie 		  // Seconds.
163003a78d15Sespie 		  _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
163103a78d15Sespie 				 __ctype, __err);
163203a78d15Sespie 		  break;
163303a78d15Sespie 		case 't':
163403a78d15Sespie 		  if (__ctype.narrow(*__beg, 0) == '\t')
163503a78d15Sespie 		    ++__beg;
163603a78d15Sespie 		  else
163703a78d15Sespie 		__err |= ios_base::failbit;
163803a78d15Sespie 		  break;
163903a78d15Sespie 		case 'T':
164003a78d15Sespie 		  // Equivalent to (%H:%M:%S).
164103a78d15Sespie 		  __cs = "%H:%M:%S";
164203a78d15Sespie 		  __ctype.widen(__cs, __cs + 9, __wcs);
164303a78d15Sespie 		  _M_extract_via_format(__beg, __end, __io, __err, __tm,
164403a78d15Sespie 					__wcs);
164503a78d15Sespie 		  break;
164603a78d15Sespie 		case 'x':
164703a78d15Sespie 		  // Locale's date.
164803a78d15Sespie 		  const char_type*  __dates[2];
164903a78d15Sespie 		  __tp._M_date_formats(__dates);
165003a78d15Sespie 		  _M_extract_via_format(__beg, __end, __io, __err, __tm,
165103a78d15Sespie 					__dates[0]);
165203a78d15Sespie 		  break;
165303a78d15Sespie 		case 'X':
165403a78d15Sespie 		  // Locale's time.
165503a78d15Sespie 		  const char_type*  __times[2];
165603a78d15Sespie 		  __tp._M_time_formats(__times);
165703a78d15Sespie 		  _M_extract_via_format(__beg, __end, __io, __err, __tm,
165803a78d15Sespie 					__times[0]);
165903a78d15Sespie 		  break;
166003a78d15Sespie 		case 'y':
166103a78d15Sespie 		  // Two digit year. [tm_year]
166203a78d15Sespie 		  _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
166303a78d15Sespie 				 __ctype, __err);
166403a78d15Sespie 		  break;
166503a78d15Sespie 		case 'Y':
166603a78d15Sespie 		  // Year [1900). [tm_year]
166703a78d15Sespie 		  _M_extract_num(__beg, __end, __mem, 0,
166803a78d15Sespie 				 numeric_limits<int>::max(), 4,
166903a78d15Sespie 				 __ctype, __err);
167003a78d15Sespie 		  if (!__err)
167103a78d15Sespie 		    __tm->tm_year = __mem - 1900;
167203a78d15Sespie 		  break;
167303a78d15Sespie 		case 'Z':
167403a78d15Sespie 		  // Timezone info.
167503a78d15Sespie 		  if (__ctype.is(ctype_base::upper, *__beg))
167603a78d15Sespie 		    {
167703a78d15Sespie 		      int __tmp;
167803a78d15Sespie 		      _M_extract_name(__beg, __end, __tmp,
167903a78d15Sespie 				      __timepunct<_CharT>::_S_timezones,
168003a78d15Sespie 				      14, __err);
168103a78d15Sespie 
168203a78d15Sespie 		      // GMT requires special effort.
168303a78d15Sespie 		      char_type __c = *__beg;
168403a78d15Sespie 		      if (!__err && __tmp == 0
168503a78d15Sespie 			  && (__c == __ctype.widen('-')
168603a78d15Sespie 			      || __c == __ctype.widen('+')))
168703a78d15Sespie 			{
168803a78d15Sespie 			  _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
168903a78d15Sespie 					  __ctype, __err);
169003a78d15Sespie 			  _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
169103a78d15Sespie 					  __ctype, __err);
169203a78d15Sespie 			}
169303a78d15Sespie 			  }
169403a78d15Sespie 		      else
169503a78d15Sespie 			__err |= ios_base::failbit;
169603a78d15Sespie 		      break;
169703a78d15Sespie 		    default:
169803a78d15Sespie 		      // Not recognized.
169903a78d15Sespie 		      __err |= ios_base::failbit;
170003a78d15Sespie 		    }
170103a78d15Sespie 		}
170203a78d15Sespie 	      else
170303a78d15Sespie 		{
170403a78d15Sespie 		  // Verify format and input match, extract and discard.
170503a78d15Sespie 		  if (__c == __ctype.narrow(*__beg, 0))
170603a78d15Sespie 		    ++__beg;
170703a78d15Sespie 		  else
170803a78d15Sespie 		    __err |= ios_base::failbit;
170903a78d15Sespie 		}
171003a78d15Sespie 	}
171103a78d15Sespie     }
171203a78d15Sespie 
171303a78d15Sespie   template<typename _CharT, typename _InIter>
171403a78d15Sespie     void
171503a78d15Sespie     time_get<_CharT, _InIter>::
_M_extract_num(iter_type & __beg,iter_type & __end,int & __member,int __min,int __max,size_t __len,const ctype<_CharT> & __ctype,ios_base::iostate & __err) const171603a78d15Sespie     _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
171703a78d15Sespie 		   int __min, int __max, size_t __len,
171803a78d15Sespie 		   const ctype<_CharT>& __ctype,
171903a78d15Sespie 		   ios_base::iostate& __err) const
172003a78d15Sespie     {
172103a78d15Sespie       size_t __i = 0;
172203a78d15Sespie       string __digits;
172303a78d15Sespie       bool __testvalid = true;
172403a78d15Sespie       char_type __c = *__beg;
172503a78d15Sespie       while (__beg != __end && __i < __len
172603a78d15Sespie 	     && __ctype.is(ctype_base::digit, __c))
172703a78d15Sespie 	{
172803a78d15Sespie 	  __digits += __ctype.narrow(__c, 0);
172903a78d15Sespie 	  __c = *(++__beg);
173003a78d15Sespie 	  ++__i;
173103a78d15Sespie 	}
173203a78d15Sespie       if (__i == __len)
173303a78d15Sespie 	{
173403a78d15Sespie 	  int __value = atoi(__digits.c_str());
173503a78d15Sespie 	  if (__min <= __value && __value <= __max)
173603a78d15Sespie 	    __member = __value;
173703a78d15Sespie 	  else
173803a78d15Sespie 	    __testvalid = false;
173903a78d15Sespie 	}
174003a78d15Sespie       else
174103a78d15Sespie 	__testvalid = false;
174203a78d15Sespie       if (!__testvalid)
174303a78d15Sespie 	__err |= ios_base::failbit;
174403a78d15Sespie     }
174503a78d15Sespie 
174603a78d15Sespie   // Assumptions:
174703a78d15Sespie   // All elements in __names are unique.
174803a78d15Sespie   template<typename _CharT, typename _InIter>
174903a78d15Sespie     void
175003a78d15Sespie     time_get<_CharT, _InIter>::
_M_extract_name(iter_type & __beg,iter_type & __end,int & __member,const _CharT ** __names,size_t __indexlen,ios_base::iostate & __err) const175103a78d15Sespie     _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
175203a78d15Sespie 		    const _CharT** __names, size_t __indexlen,
175303a78d15Sespie 		    ios_base::iostate& __err) const
175403a78d15Sespie     {
175503a78d15Sespie       typedef char_traits<_CharT> 		__traits_type;
175603a78d15Sespie       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
175703a78d15Sespie 							  * __indexlen));
175803a78d15Sespie       size_t __nmatches = 0;
175903a78d15Sespie       size_t __pos = 0;
176003a78d15Sespie       bool __testvalid = true;
176103a78d15Sespie       const char_type* __name;
176203a78d15Sespie 
176303a78d15Sespie       char_type __c = *__beg;
176403a78d15Sespie       // Look for initial matches.
176503a78d15Sespie       for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
176603a78d15Sespie 	if (__c == __names[__i1][0])
176703a78d15Sespie 	  __matches[__nmatches++] = __i1;
176803a78d15Sespie 
176903a78d15Sespie       while (__nmatches > 1)
177003a78d15Sespie 	{
177103a78d15Sespie 	  // Find smallest matching string.
177203a78d15Sespie 	  size_t __minlen = 10;
177303a78d15Sespie 	  for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
177403a78d15Sespie 	    __minlen = min(__minlen,
177503a78d15Sespie 			   __traits_type::length(__names[__matches[__i2]]));
177603a78d15Sespie 
177703a78d15Sespie 	  if (__pos < __minlen && __beg != __end)
177803a78d15Sespie 	    {
177903a78d15Sespie 	      ++__pos;
178003a78d15Sespie 	      __c = *(++__beg);
178103a78d15Sespie 	      for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
178203a78d15Sespie 		{
178303a78d15Sespie 		  __name = __names[__matches[__i3]];
178403a78d15Sespie 		  if (__name[__pos] != __c)
178503a78d15Sespie 		    __matches[__i3] = __matches[--__nmatches];
178603a78d15Sespie 		}
178703a78d15Sespie 	    }
178803a78d15Sespie 	  else
178903a78d15Sespie 	    break;
179003a78d15Sespie 	}
179103a78d15Sespie 
179203a78d15Sespie       if (__nmatches == 1)
179303a78d15Sespie 	{
179403a78d15Sespie 	  // Make sure found name is completely extracted.
179503a78d15Sespie 	  __name = __names[__matches[0]];
179603a78d15Sespie 	  const size_t __len = __traits_type::length(__name);
179703a78d15Sespie 	  while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
179803a78d15Sespie 	    ++__beg, ++__pos;
179903a78d15Sespie 
180003a78d15Sespie 	  if (__len == __pos)
180103a78d15Sespie 	    __member = __matches[0];
180203a78d15Sespie 	  else
180303a78d15Sespie 	    __testvalid = false;
180403a78d15Sespie 	}
180503a78d15Sespie       else
180603a78d15Sespie 	__testvalid = false;
180703a78d15Sespie       if (!__testvalid)
180803a78d15Sespie 	__err |= ios_base::failbit;
180903a78d15Sespie     }
181003a78d15Sespie 
181103a78d15Sespie   template<typename _CharT, typename _InIter>
181203a78d15Sespie     _InIter
181303a78d15Sespie     time_get<_CharT, _InIter>::
do_get_time(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const181403a78d15Sespie     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
181503a78d15Sespie 		ios_base::iostate& __err, tm* __tm) const
181603a78d15Sespie     {
181703a78d15Sespie       _CharT __wcs[3];
181803a78d15Sespie       const char* __cs = "%X";
181903a78d15Sespie       locale __loc = __io.getloc();
182003a78d15Sespie       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
182103a78d15Sespie       __ctype.widen(__cs, __cs + 3, __wcs);
182203a78d15Sespie       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
182303a78d15Sespie       if (__beg == __end)
182403a78d15Sespie 	__err |= ios_base::eofbit;
182503a78d15Sespie       return __beg;
182603a78d15Sespie     }
182703a78d15Sespie 
182803a78d15Sespie   template<typename _CharT, typename _InIter>
182903a78d15Sespie     _InIter
183003a78d15Sespie     time_get<_CharT, _InIter>::
do_get_date(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const183103a78d15Sespie     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
183203a78d15Sespie 		ios_base::iostate& __err, tm* __tm) const
183303a78d15Sespie     {
183403a78d15Sespie       _CharT __wcs[3];
183503a78d15Sespie       const char* __cs = "%x";
183603a78d15Sespie       locale __loc = __io.getloc();
183703a78d15Sespie       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
183803a78d15Sespie       __ctype.widen(__cs, __cs + 3, __wcs);
183903a78d15Sespie       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
184003a78d15Sespie       if (__beg == __end)
184103a78d15Sespie 	__err |= ios_base::eofbit;
184203a78d15Sespie       return __beg;
184303a78d15Sespie     }
184403a78d15Sespie 
184503a78d15Sespie   template<typename _CharT, typename _InIter>
184603a78d15Sespie     _InIter
184703a78d15Sespie     time_get<_CharT, _InIter>::
do_get_weekday(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const184803a78d15Sespie     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
184903a78d15Sespie 		   ios_base::iostate& __err, tm* __tm) const
185003a78d15Sespie     {
185103a78d15Sespie       typedef char_traits<_CharT> 		__traits_type;
185203a78d15Sespie       locale __loc = __io.getloc();
185303a78d15Sespie       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
185403a78d15Sespie       const char_type*  __days[7];
185503a78d15Sespie       __tp._M_days_abbreviated(__days);
185603a78d15Sespie       int __tmpwday;
185703a78d15Sespie       _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
185803a78d15Sespie 
185903a78d15Sespie       // Check to see if non-abbreviated name exists, and extract.
186003a78d15Sespie       // NB: Assumes both _M_days and _M_days_abbreviated organized in
186103a78d15Sespie       // exact same order, first to last, such that the resulting
186203a78d15Sespie       // __days array with the same index points to a day, and that
186303a78d15Sespie       // day's abbreviated form.
186403a78d15Sespie       // NB: Also assumes that an abbreviated name is a subset of the name.
186503a78d15Sespie       if (!__err)
186603a78d15Sespie 	{
186703a78d15Sespie 	  size_t __pos = __traits_type::length(__days[__tmpwday]);
186803a78d15Sespie 	  __tp._M_days(__days);
186903a78d15Sespie 	  const char_type* __name = __days[__tmpwday];
187003a78d15Sespie 	  if (__name[__pos] == *__beg)
187103a78d15Sespie 	    {
187203a78d15Sespie 	      // Extract the rest of it.
187303a78d15Sespie 	      const size_t __len = __traits_type::length(__name);
187403a78d15Sespie 	      while (__pos < __len && __beg != __end
187503a78d15Sespie 		     && __name[__pos] == *__beg)
187603a78d15Sespie 		++__beg, ++__pos;
187703a78d15Sespie 	      if (__len != __pos)
187803a78d15Sespie 		__err |= ios_base::failbit;
187903a78d15Sespie 	    }
188003a78d15Sespie 	  if (!__err)
188103a78d15Sespie 	    __tm->tm_wday = __tmpwday;
188203a78d15Sespie 	}
188303a78d15Sespie       if (__beg == __end)
188403a78d15Sespie 	__err |= ios_base::eofbit;
188503a78d15Sespie       return __beg;
188603a78d15Sespie      }
188703a78d15Sespie 
188803a78d15Sespie   template<typename _CharT, typename _InIter>
188903a78d15Sespie     _InIter
189003a78d15Sespie     time_get<_CharT, _InIter>::
do_get_monthname(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const189103a78d15Sespie     do_get_monthname(iter_type __beg, iter_type __end,
189203a78d15Sespie                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
189303a78d15Sespie     {
189403a78d15Sespie       typedef char_traits<_CharT> 		__traits_type;
189503a78d15Sespie       locale __loc = __io.getloc();
189603a78d15Sespie       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
189703a78d15Sespie       const char_type*  __months[12];
189803a78d15Sespie       __tp._M_months_abbreviated(__months);
189903a78d15Sespie       int __tmpmon;
190003a78d15Sespie       _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
190103a78d15Sespie 
190203a78d15Sespie       // Check to see if non-abbreviated name exists, and extract.
190303a78d15Sespie       // NB: Assumes both _M_months and _M_months_abbreviated organized in
190403a78d15Sespie       // exact same order, first to last, such that the resulting
190503a78d15Sespie       // __months array with the same index points to a month, and that
190603a78d15Sespie       // month's abbreviated form.
190703a78d15Sespie       // NB: Also assumes that an abbreviated name is a subset of the name.
190803a78d15Sespie       if (!__err)
190903a78d15Sespie 	{
191003a78d15Sespie 	  size_t __pos = __traits_type::length(__months[__tmpmon]);
191103a78d15Sespie 	  __tp._M_months(__months);
191203a78d15Sespie 	  const char_type* __name = __months[__tmpmon];
191303a78d15Sespie 	  if (__name[__pos] == *__beg)
191403a78d15Sespie 	    {
191503a78d15Sespie 	      // Extract the rest of it.
191603a78d15Sespie 	      const size_t __len = __traits_type::length(__name);
191703a78d15Sespie 	      while (__pos < __len && __beg != __end
191803a78d15Sespie 		     && __name[__pos] == *__beg)
191903a78d15Sespie 		++__beg, ++__pos;
192003a78d15Sespie 	      if (__len != __pos)
192103a78d15Sespie 		__err |= ios_base::failbit;
192203a78d15Sespie 	    }
192303a78d15Sespie 	  if (!__err)
192403a78d15Sespie 	    __tm->tm_mon = __tmpmon;
192503a78d15Sespie 	}
192603a78d15Sespie 
192703a78d15Sespie       if (__beg == __end)
192803a78d15Sespie 	__err |= ios_base::eofbit;
192903a78d15Sespie       return __beg;
193003a78d15Sespie     }
193103a78d15Sespie 
193203a78d15Sespie   template<typename _CharT, typename _InIter>
193303a78d15Sespie     _InIter
193403a78d15Sespie     time_get<_CharT, _InIter>::
do_get_year(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const193503a78d15Sespie     do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
193603a78d15Sespie 		ios_base::iostate& __err, tm* __tm) const
193703a78d15Sespie     {
193803a78d15Sespie       locale __loc = __io.getloc();
193903a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
194003a78d15Sespie 
194103a78d15Sespie       char_type __c = *__beg;
194203a78d15Sespie       size_t __i = 0;
194303a78d15Sespie       string __digits;
194403a78d15Sespie       while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
194503a78d15Sespie 	{
194603a78d15Sespie 	  __digits += __ctype.narrow(__c, 0);
194703a78d15Sespie 	  __c = *(++__beg);
194803a78d15Sespie 	  ++__i;
194903a78d15Sespie 	}
195003a78d15Sespie       if (__i == 2 || __i == 4)
195103a78d15Sespie 	{
195203a78d15Sespie 	  long __l;
195303a78d15Sespie 	  __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
195403a78d15Sespie 	  if (!(__err & ios_base::failbit) && __l <= INT_MAX)
195503a78d15Sespie 	    {
195603a78d15Sespie 	      __l = __i == 2 ? __l : __l - 1900;
195703a78d15Sespie 	      __tm->tm_year = static_cast<int>(__l);
195803a78d15Sespie 	    }
195903a78d15Sespie 	}
196003a78d15Sespie       else
196103a78d15Sespie 	__err |= ios_base::failbit;
196203a78d15Sespie       if (__beg == __end)
196303a78d15Sespie 	__err |= ios_base::eofbit;
196403a78d15Sespie       return __beg;
196503a78d15Sespie     }
196603a78d15Sespie 
196703a78d15Sespie   template<typename _CharT, typename _OutIter>
196803a78d15Sespie     _OutIter
196903a78d15Sespie     time_put<_CharT, _OutIter>::
put(iter_type __s,ios_base & __io,char_type,const tm * __tm,const _CharT * __beg,const _CharT * __end) const197003a78d15Sespie     put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
197103a78d15Sespie 	const _CharT* __beg, const _CharT* __end) const
197203a78d15Sespie     {
197303a78d15Sespie       locale __loc = __io.getloc();
197403a78d15Sespie       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
197503a78d15Sespie       while (__beg != __end)
197603a78d15Sespie 	{
197703a78d15Sespie 	  char __c = __ctype.narrow(*__beg, 0);
197803a78d15Sespie 	  ++__beg;
197903a78d15Sespie 	  if (__c == '%')
198003a78d15Sespie 	    {
198103a78d15Sespie 	      char __format;
198203a78d15Sespie 	      char __mod = 0;
198303a78d15Sespie 	      size_t __len = 1;
198403a78d15Sespie 	      __c = __ctype.narrow(*__beg, 0);
198503a78d15Sespie 	      ++__beg;
198603a78d15Sespie 	      if (__c == 'E' || __c == 'O')
198703a78d15Sespie 		{
198803a78d15Sespie 		  __mod = __c;
198903a78d15Sespie 		  __format = __ctype.narrow(*__beg, 0);
199003a78d15Sespie 		  ++__beg;
199103a78d15Sespie 		}
199203a78d15Sespie 	      else
199303a78d15Sespie 		__format = __c;
199403a78d15Sespie 	      __s = this->do_put(__s, __io, _CharT(), __tm, __format, __mod);
199503a78d15Sespie 	    }
199603a78d15Sespie 	  else
199703a78d15Sespie 	    {
199803a78d15Sespie 	      *__s = __c;
199903a78d15Sespie 	      ++__s;
200003a78d15Sespie 	    }
200103a78d15Sespie 	}
200203a78d15Sespie       return __s;
200303a78d15Sespie     }
200403a78d15Sespie 
200503a78d15Sespie   template<typename _CharT, typename _OutIter>
200603a78d15Sespie     _OutIter
200703a78d15Sespie     time_put<_CharT, _OutIter>::
do_put(iter_type __s,ios_base & __io,char_type,const tm * __tm,char __format,char __mod) const200803a78d15Sespie     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
200903a78d15Sespie 	   char __format, char __mod) const
201003a78d15Sespie     {
201103a78d15Sespie       locale __loc = __io.getloc();
201203a78d15Sespie       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
201303a78d15Sespie       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
201403a78d15Sespie 
201503a78d15Sespie       // NB: This size is arbitrary. Should this be a data member,
201603a78d15Sespie       // initialized at construction?
201703a78d15Sespie       const size_t __maxlen = 64;
201803a78d15Sespie       char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
201903a78d15Sespie 
202003a78d15Sespie       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
202103a78d15Sespie       // is possible that the format character will be longer than one
202203a78d15Sespie       // character. Possibilities include 'E' or 'O' followed by a
202303a78d15Sespie       // format character: if __mod is not the default argument, assume
202403a78d15Sespie       // it's a valid modifier.
202503a78d15Sespie       char_type __fmt[4];
202603a78d15Sespie       __fmt[0] = __ctype.widen('%');
202703a78d15Sespie       if (!__mod)
202803a78d15Sespie 	{
202903a78d15Sespie 	  __fmt[1] = __format;
203003a78d15Sespie 	  __fmt[2] = char_type();
203103a78d15Sespie 	}
203203a78d15Sespie       else
203303a78d15Sespie 	{
203403a78d15Sespie 	  __fmt[1] = __mod;
203503a78d15Sespie 	  __fmt[2] = __format;
203603a78d15Sespie 	  __fmt[3] = char_type();
203703a78d15Sespie 	}
203803a78d15Sespie 
203903a78d15Sespie       __tp._M_put(__res, __maxlen, __fmt, __tm);
204003a78d15Sespie 
204103a78d15Sespie       // Write resulting, fully-formatted string to output iterator.
204203a78d15Sespie       return __write(__s, __res, char_traits<char_type>::length(__res));
204303a78d15Sespie     }
204403a78d15Sespie 
204503a78d15Sespie 
204603a78d15Sespie   // Generic version does nothing.
204703a78d15Sespie   template<typename _CharT>
204803a78d15Sespie     int
_M_compare(const _CharT *,const _CharT *) const204903a78d15Sespie     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
205003a78d15Sespie     { return 0; }
205103a78d15Sespie 
205203a78d15Sespie   // Generic version does nothing.
205303a78d15Sespie   template<typename _CharT>
205403a78d15Sespie     size_t
_M_transform(_CharT *,const _CharT *,size_t) const205503a78d15Sespie     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
205603a78d15Sespie     { return 0; }
205703a78d15Sespie 
205803a78d15Sespie   template<typename _CharT>
205903a78d15Sespie     int
206003a78d15Sespie     collate<_CharT>::
do_compare(const _CharT * __lo1,const _CharT * __hi1,const _CharT * __lo2,const _CharT * __hi2) const206103a78d15Sespie     do_compare(const _CharT* __lo1, const _CharT* __hi1,
206203a78d15Sespie 	       const _CharT* __lo2, const _CharT* __hi2) const
206303a78d15Sespie     {
206403a78d15Sespie       // strcoll assumes zero-terminated strings so we make a copy
206503a78d15Sespie       // and then put a zero at the end.
206603a78d15Sespie       const string_type __one(__lo1, __hi1);
206703a78d15Sespie       const string_type __two(__lo2, __hi2);
206803a78d15Sespie 
206903a78d15Sespie       const _CharT* __p = __one.c_str();
207003a78d15Sespie       const _CharT* __pend = __one.c_str() + __one.length();
207103a78d15Sespie       const _CharT* __q = __two.c_str();
207203a78d15Sespie       const _CharT* __qend = __two.c_str() + __two.length();
207303a78d15Sespie 
207403a78d15Sespie       // strcoll stops when it sees a nul character so we break
207503a78d15Sespie       // the strings into zero-terminated substrings and pass those
207603a78d15Sespie       // to strcoll.
207703a78d15Sespie       for (;;)
207803a78d15Sespie 	{
207903a78d15Sespie 	  int __res = _M_compare(__p, __q);
208003a78d15Sespie 	  if (__res)
208103a78d15Sespie 	    return __res;
208203a78d15Sespie 
208303a78d15Sespie 	  __p += char_traits<_CharT>::length(__p);
208403a78d15Sespie 	  __q += char_traits<_CharT>::length(__q);
208503a78d15Sespie 	  if (__p == __pend && __q == __qend)
208603a78d15Sespie 	    return 0;
208703a78d15Sespie 	  else if (__p == __pend)
208803a78d15Sespie 	    return -1;
208903a78d15Sespie 	  else if (__q == __qend)
209003a78d15Sespie 	    return 1;
209103a78d15Sespie 
209203a78d15Sespie 	  __p++;
209303a78d15Sespie 	  __q++;
209403a78d15Sespie 	}
209503a78d15Sespie     }
209603a78d15Sespie 
209703a78d15Sespie  template<typename _CharT>
209803a78d15Sespie     typename collate<_CharT>::string_type
209903a78d15Sespie     collate<_CharT>::
do_transform(const _CharT * __lo,const _CharT * __hi) const210003a78d15Sespie     do_transform(const _CharT* __lo, const _CharT* __hi) const
210103a78d15Sespie     {
210203a78d15Sespie       // strxfrm assumes zero-terminated strings so we make a copy
210303a78d15Sespie       string_type __str(__lo, __hi);
210403a78d15Sespie 
210503a78d15Sespie       const _CharT* __p = __str.c_str();
210603a78d15Sespie       const _CharT* __pend = __str.c_str() + __str.length();
210703a78d15Sespie 
210803a78d15Sespie       size_t __len = (__hi - __lo) * 2;
210903a78d15Sespie 
211003a78d15Sespie       string_type __ret;
211103a78d15Sespie 
211203a78d15Sespie       // strxfrm stops when it sees a nul character so we break
211303a78d15Sespie       // the string into zero-terminated substrings and pass those
211403a78d15Sespie       // to strxfrm.
211503a78d15Sespie       for (;;)
211603a78d15Sespie 	{
211703a78d15Sespie 	  // First try a buffer perhaps big enough.
211803a78d15Sespie 	  _CharT* __c =
211903a78d15Sespie 	    static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
212003a78d15Sespie 	  size_t __res = _M_transform(__c, __p, __len);
212103a78d15Sespie 	  // If the buffer was not large enough, try again with the
212203a78d15Sespie 	  // correct size.
212303a78d15Sespie 	  if (__res >= __len)
212403a78d15Sespie 	    {
212503a78d15Sespie 	      __len = __res + 1;
212603a78d15Sespie 	      __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
212703a78d15Sespie 							  * __len));
212803a78d15Sespie 	      __res = _M_transform(__c, __p, __res + 1);
212903a78d15Sespie 	    }
213003a78d15Sespie 
213103a78d15Sespie 	  __ret.append(__c, __res);
213203a78d15Sespie 	  __p += char_traits<_CharT>::length(__p);
213303a78d15Sespie 	  if (__p == __pend)
213403a78d15Sespie 	    return __ret;
213503a78d15Sespie 
213603a78d15Sespie 	  __p++;
213703a78d15Sespie 	  __ret.push_back(_CharT());
213803a78d15Sespie 	}
213903a78d15Sespie     }
214003a78d15Sespie 
214103a78d15Sespie  template<typename _CharT>
214203a78d15Sespie     long
214303a78d15Sespie     collate<_CharT>::
do_hash(const _CharT * __lo,const _CharT * __hi) const214403a78d15Sespie     do_hash(const _CharT* __lo, const _CharT* __hi) const
214503a78d15Sespie     {
214603a78d15Sespie       unsigned long __val = 0;
214703a78d15Sespie       for (; __lo < __hi; ++__lo)
214803a78d15Sespie 	__val = *__lo + ((__val << 7) |
214903a78d15Sespie 		       (__val >> (numeric_limits<unsigned long>::digits - 7)));
215003a78d15Sespie       return static_cast<long>(__val);
215103a78d15Sespie     }
215203a78d15Sespie 
215303a78d15Sespie   // Construct correctly padded string, as per 22.2.2.2.2
215403a78d15Sespie   // Assumes
215503a78d15Sespie   // __newlen > __oldlen
215603a78d15Sespie   // __news is allocated for __newlen size
215703a78d15Sespie   // Used by both num_put and ostream inserters: if __num,
215803a78d15Sespie   // internal-adjusted objects are padded according to the rules below
215903a78d15Sespie   // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
216003a78d15Sespie   // ones are.
216103a78d15Sespie 
216203a78d15Sespie   // NB: Of the two parameters, _CharT can be deduced from the
216303a78d15Sespie   // function arguments. The other (_Traits) has to be explicitly specified.
216403a78d15Sespie   template<typename _CharT, typename _Traits>
216503a78d15Sespie     void
_S_pad(ios_base & __io,_CharT __fill,_CharT * __news,const _CharT * __olds,const streamsize __newlen,const streamsize __oldlen,const bool __num)216603a78d15Sespie     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
216703a78d15Sespie 				   _CharT* __news, const _CharT* __olds,
216803a78d15Sespie 				   const streamsize __newlen,
216903a78d15Sespie 				   const streamsize __oldlen, const bool __num)
217003a78d15Sespie     {
217119731d4fSespie       const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
217219731d4fSespie       const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
217303a78d15Sespie 
217419731d4fSespie       // Padding last.
217503a78d15Sespie       if (__adjust == ios_base::left)
217603a78d15Sespie 	{
217719731d4fSespie 	  _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen);
217819731d4fSespie 	  _Traits::assign(__news + __oldlen, __plen, __fill);
217919731d4fSespie 	  return;
218003a78d15Sespie 	}
218119731d4fSespie 
218219731d4fSespie       size_t __mod = 0;
218319731d4fSespie       if (__adjust == ios_base::internal && __num)
218403a78d15Sespie 	{
218503a78d15Sespie 	  // Pad after the sign, if there is one.
218603a78d15Sespie 	  // Pad after 0[xX], if there is one.
218703a78d15Sespie 	  // Who came up with these rules, anyway? Jeeze.
218819731d4fSespie           const locale& __loc = __io.getloc();
218903a78d15Sespie 	  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
219003a78d15Sespie 	  const _CharT __minus = __ctype.widen('-');
219103a78d15Sespie 	  const _CharT __plus = __ctype.widen('+');
219219731d4fSespie 	  const bool __testsign = _Traits::eq(__olds[0], __minus)
219303a78d15Sespie 	                          || _Traits::eq(__olds[0], __plus);
219403a78d15Sespie 
219519731d4fSespie 	  const bool __testhex = (_Traits::eq(__ctype.widen('0'), __olds[0])
219619731d4fSespie 				  && __oldlen > 1
219703a78d15Sespie 				  && (_Traits::eq(__ctype.widen('x'), __olds[1])
219819731d4fSespie 				      || _Traits::eq(__ctype.widen('X'),
219919731d4fSespie 						     __olds[1])));
220003a78d15Sespie 	  if (__testhex)
220103a78d15Sespie 	    {
220203a78d15Sespie 	      __news[0] = __olds[0];
220303a78d15Sespie 	      __news[1] = __olds[1];
220419731d4fSespie 	      __mod = 2;
220503a78d15Sespie 	      __news += 2;
220603a78d15Sespie 	    }
220703a78d15Sespie 	  else if (__testsign)
220803a78d15Sespie 	    {
220919731d4fSespie 	      __news[0] = __olds[0];
221019731d4fSespie 	      __mod = 1;
221103a78d15Sespie 	      ++__news;
221203a78d15Sespie 	    }
221319731d4fSespie 	  // else Padding first.
221403a78d15Sespie 	}
221519731d4fSespie       _Traits::assign(__news, __plen, __fill);
221619731d4fSespie       _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod),
221719731d4fSespie 		    __oldlen - __mod);
221803a78d15Sespie     }
221903a78d15Sespie 
222003a78d15Sespie   template<typename _CharT>
222103a78d15Sespie     bool
__verify_grouping(const basic_string<_CharT> & __grouping,basic_string<_CharT> & __grouping_tmp)222203a78d15Sespie     __verify_grouping(const basic_string<_CharT>& __grouping,
222303a78d15Sespie 		      basic_string<_CharT>& __grouping_tmp)
222403a78d15Sespie     {
222519731d4fSespie       const size_t __n = __grouping_tmp.size() - 1;
222619731d4fSespie       const size_t __min = std::min(__n, __grouping.size() - 1);
222719731d4fSespie       size_t __i = __n;
222803a78d15Sespie       bool __test = true;
222903a78d15Sespie 
223003a78d15Sespie       // Parsed number groupings have to match the
223103a78d15Sespie       // numpunct::grouping string exactly, starting at the
223203a78d15Sespie       // right-most point of the parsed sequence of elements ...
223319731d4fSespie       for (size_t __j = 0; __j < __min && __test; --__i, ++__j)
223419731d4fSespie 	__test = __grouping_tmp[__i] == __grouping[__j];
223519731d4fSespie       for (; __i && __test; --__i)
223619731d4fSespie 	__test = __grouping_tmp[__i] == __grouping[__min];
223703a78d15Sespie       // ... but the last parsed grouping can be <= numpunct
223803a78d15Sespie       // grouping.
223919731d4fSespie       __test &= __grouping_tmp[0] <= __grouping[__min];
224003a78d15Sespie       return __test;
224103a78d15Sespie     }
224203a78d15Sespie 
224303a78d15Sespie   template<typename _CharT>
224403a78d15Sespie     _CharT*
__add_grouping(_CharT * __s,_CharT __sep,const char * __gbeg,const char * __gend,const _CharT * __first,const _CharT * __last)224503a78d15Sespie     __add_grouping(_CharT* __s, _CharT __sep,
224603a78d15Sespie 		   const char* __gbeg, const char* __gend,
224703a78d15Sespie 		   const _CharT* __first, const _CharT* __last)
224803a78d15Sespie     {
224903a78d15Sespie       if (__last - __first > *__gbeg)
225003a78d15Sespie         {
225103a78d15Sespie           __s = __add_grouping(__s,  __sep,
225203a78d15Sespie 			       (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
225303a78d15Sespie 			       __gend, __first, __last - *__gbeg);
225403a78d15Sespie           __first = __last - *__gbeg;
225503a78d15Sespie           *__s++ = __sep;
225603a78d15Sespie         }
225703a78d15Sespie       do
225803a78d15Sespie 	*__s++ = *__first++;
225903a78d15Sespie       while (__first != __last);
226003a78d15Sespie       return __s;
226103a78d15Sespie     }
226203a78d15Sespie 
226303a78d15Sespie #if 1
226403a78d15Sespie       // XXX GLIBCXX_ABI Deprecated, compatibility only.
226503a78d15Sespie   template<typename _CharT, typename _OutIter>
226603a78d15Sespie     template<typename _ValueT>
226703a78d15Sespie       _OutIter
226803a78d15Sespie       num_put<_CharT, _OutIter>::
_M_convert_int(_OutIter __s,ios_base & __io,_CharT __fill,char __mod,char __modl,_ValueT __v) const226903a78d15Sespie       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
227003a78d15Sespie 		     char __modl, _ValueT __v) const
227103a78d15Sespie       {
227203a78d15Sespie 	// [22.2.2.2.2] Stage 1, numeric conversion to character.
227303a78d15Sespie 
227403a78d15Sespie 	// Long enough for the max format spec.
227503a78d15Sespie 	char __fbuf[16];
227603a78d15Sespie 	_S_format_int(__io, __fbuf, __mod, __modl);
227701d8d202Skettenis #if defined _GLIBCPP_USE_C99 || defined _GLIBCPP_USE_C99_SNPRINTF
227803a78d15Sespie 	// First try a buffer perhaps big enough.
227903a78d15Sespie 	int __cs_size = 64;
228003a78d15Sespie 	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
228103a78d15Sespie 	int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
228203a78d15Sespie 				     _S_c_locale);
228303a78d15Sespie 	// If the buffer was not large enough, try again with the correct size.
228403a78d15Sespie 	if (__len >= __cs_size)
228503a78d15Sespie 	  {
228603a78d15Sespie 	    __cs_size = __len + 1;
228703a78d15Sespie 	    __cs = static_cast<char*>(__builtin_alloca(__cs_size));
228803a78d15Sespie 	    __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
228903a78d15Sespie 				     _S_c_locale);
229003a78d15Sespie 	  }
229103a78d15Sespie #else
229203a78d15Sespie 	// Leave room for "+/-," "0x," and commas. This size is
229303a78d15Sespie 	// arbitrary, but should be largely sufficient.
229403a78d15Sespie 	char __cs[128];
229503a78d15Sespie 	int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
229603a78d15Sespie #endif
229703a78d15Sespie 	return _M_widen_int(__s, __io, __fill, __cs, __len);
229803a78d15Sespie       }
229903a78d15Sespie 
230003a78d15Sespie   template<typename _CharT, typename _OutIter>
230103a78d15Sespie     _OutIter
230203a78d15Sespie     num_put<_CharT, _OutIter>::
_M_widen_float(_OutIter __s,ios_base & __io,_CharT __fill,char * __cs,int __len) const230303a78d15Sespie     _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
230403a78d15Sespie 		   int __len) const
230503a78d15Sespie     {
230603a78d15Sespie       typedef char_traits<_CharT> 		__traits_type;
230703a78d15Sespie       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
230803a78d15Sespie       // numpunct.decimal_point() values for '.' and adding grouping.
230903a78d15Sespie       const locale __loc = __io.getloc();
231003a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
231103a78d15Sespie       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
231203a78d15Sespie 							   * __len));
231303a78d15Sespie       // Grouping can add (almost) as many separators as the number of
231403a78d15Sespie       // digits, but no more.
231503a78d15Sespie       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
231603a78d15Sespie 			 				    * __len * 2));
231703a78d15Sespie       __ctype.widen(__cs, __cs + __len, __ws);
231803a78d15Sespie 
231903a78d15Sespie       // Replace decimal point.
232003a78d15Sespie       const _CharT* __p;
232103a78d15Sespie       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
232203a78d15Sespie       if (__p = __traits_type::find(__ws, __len, __ctype.widen('.')))
232303a78d15Sespie 	__ws[__p - __ws] = __np.decimal_point();
232403a78d15Sespie 
232503a78d15Sespie #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
232603a78d15Sespie //282. What types does numpunct grouping refer to?
232703a78d15Sespie       // Add grouping, if necessary.
232803a78d15Sespie       const string __grouping = __np.grouping();
232903a78d15Sespie       if (__grouping.size())
233003a78d15Sespie 	{
233103a78d15Sespie 	  _CharT* __p2;
233203a78d15Sespie 	  int __declen = __p ? __p - __ws : __len;
233303a78d15Sespie 	  __p2 = __add_grouping(__ws2, __np.thousands_sep(),
233403a78d15Sespie 				__grouping.c_str(),
233503a78d15Sespie 				__grouping.c_str() + __grouping.size(),
233603a78d15Sespie 				__ws, __ws + __declen);
233703a78d15Sespie 	  int __newlen = __p2 - __ws2;
233803a78d15Sespie 
233903a78d15Sespie 	  // Tack on decimal part.
234003a78d15Sespie 	  if (__p)
234103a78d15Sespie 	    {
234203a78d15Sespie 	      __traits_type::copy(__p2, __p, __len - __declen);
234303a78d15Sespie 	      __newlen += __len - __declen;
234403a78d15Sespie 	    }
234503a78d15Sespie 
234603a78d15Sespie 	  // Switch strings, establish correct new length.
234703a78d15Sespie 	  __ws = __ws2;
234803a78d15Sespie 	  __len = __newlen;
234903a78d15Sespie 	}
235003a78d15Sespie #endif
235103a78d15Sespie       return _M_insert(__s, __io, __fill, __ws, __len);
235203a78d15Sespie     }
235303a78d15Sespie 
235403a78d15Sespie   template<typename _CharT, typename _OutIter>
235503a78d15Sespie     _OutIter
235603a78d15Sespie     num_put<_CharT, _OutIter>::
_M_widen_int(_OutIter __s,ios_base & __io,_CharT __fill,char * __cs,int __len) const235703a78d15Sespie     _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
235803a78d15Sespie 		 int __len) const
235903a78d15Sespie     {
236003a78d15Sespie       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
236103a78d15Sespie       // numpunct.decimal_point() values for '.' and adding grouping.
236203a78d15Sespie       const locale __loc = __io.getloc();
236303a78d15Sespie       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
236403a78d15Sespie       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
236503a78d15Sespie 							   * __len));
236603a78d15Sespie       // Grouping can add (almost) as many separators as the number of
236703a78d15Sespie       // digits, but no more.
236803a78d15Sespie       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
236903a78d15Sespie 							    * __len * 2));
237003a78d15Sespie       __ctype.widen(__cs, __cs + __len, __ws);
237103a78d15Sespie 
237203a78d15Sespie       // Add grouping, if necessary.
237303a78d15Sespie       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
237403a78d15Sespie       const string __grouping = __np.grouping();
237503a78d15Sespie       if (__grouping.size())
237603a78d15Sespie 	{
237703a78d15Sespie 	  // By itself __add_grouping cannot deal correctly with __ws when
237803a78d15Sespie 	  // ios::showbase is set and ios_base::oct || ios_base::hex.
237903a78d15Sespie 	  // Therefore we take care "by hand" of the initial 0, 0x or 0X.
238003a78d15Sespie 	  // However, remember that the latter do not occur if the number
238103a78d15Sespie 	  // printed is '0' (__len == 1).
238203a78d15Sespie 	  streamsize __off = 0;
238303a78d15Sespie 	  const ios_base::fmtflags __basefield = __io.flags()
238403a78d15Sespie 	    					 & ios_base::basefield;
238503a78d15Sespie 	  if ((__io.flags() & ios_base::showbase) && __len > 1)
238603a78d15Sespie 	    if (__basefield == ios_base::oct)
238703a78d15Sespie 	      {
238803a78d15Sespie 		__off = 1;
238903a78d15Sespie 		*__ws2 = *__ws;
239003a78d15Sespie 	      }
239103a78d15Sespie 	    else if (__basefield == ios_base::hex)
239203a78d15Sespie 	      {
239303a78d15Sespie 		__off = 2;
239403a78d15Sespie 		*__ws2 = *__ws;
239503a78d15Sespie 		*(__ws2 + 1) = *(__ws + 1);
239603a78d15Sespie 	      }
239703a78d15Sespie 	  _CharT* __p;
239803a78d15Sespie 	  __p = __add_grouping(__ws2 + __off, __np.thousands_sep(),
239903a78d15Sespie 			       __grouping.c_str(),
240003a78d15Sespie 			       __grouping.c_str() + __grouping.size(),
240103a78d15Sespie 			       __ws + __off, __ws + __len);
240203a78d15Sespie 	  __len = __p - __ws2;
240303a78d15Sespie 	  // Switch strings.
240403a78d15Sespie 	  __ws = __ws2;
240503a78d15Sespie 	}
240603a78d15Sespie       return _M_insert(__s, __io, __fill, __ws, __len);
240703a78d15Sespie     }
240803a78d15Sespie 
240903a78d15Sespie   // For use by integer and floating-point types after they have been
241003a78d15Sespie   // converted into a char_type string.
241103a78d15Sespie   template<typename _CharT, typename _OutIter>
241203a78d15Sespie     _OutIter
241303a78d15Sespie     num_put<_CharT, _OutIter>::
_M_insert(_OutIter __s,ios_base & __io,_CharT __fill,const _CharT * __ws,int __len) const241403a78d15Sespie     _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
241503a78d15Sespie 	      int __len) const
241603a78d15Sespie     {
241703a78d15Sespie       typedef char_traits<_CharT> 		__traits_type;
241803a78d15Sespie       // [22.2.2.2.2] Stage 3.
241903a78d15Sespie       // If necessary, pad.
242003a78d15Sespie       streamsize __w = __io.width();
242103a78d15Sespie       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
242203a78d15Sespie 							    * __w));
242303a78d15Sespie       if (__w > static_cast<streamsize>(__len))
242403a78d15Sespie 	{
242503a78d15Sespie 	  __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws,
242603a78d15Sespie 					       __w, __len, true);
242703a78d15Sespie 	  __len = static_cast<int>(__w);
242803a78d15Sespie 	  // Switch strings.
242903a78d15Sespie 	  __ws = __ws2;
243003a78d15Sespie 	}
243103a78d15Sespie       __io.width(0);
243203a78d15Sespie 
243303a78d15Sespie       // [22.2.2.2.2] Stage 4.
243403a78d15Sespie       // Write resulting, fully-formatted string to output iterator.
243503a78d15Sespie       return __write(__s, __ws, __len);
243603a78d15Sespie     }
243703a78d15Sespie #endif
243803a78d15Sespie 
243903a78d15Sespie   template<typename _CharT>
__locale_cache(const locale & __loc)244003a78d15Sespie     __locale_cache<numpunct<_CharT> >::__locale_cache(const locale& __loc)
244103a78d15Sespie       : _M_truename(0), _M_falsename(0), _M_use_grouping(false),
244203a78d15Sespie 	_M_grouping(0)
244303a78d15Sespie     {
244403a78d15Sespie       if (has_facet<numpunct<_CharT> >(__loc))
244503a78d15Sespie 	{
244603a78d15Sespie 	  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
244703a78d15Sespie 	  _M_decimal_point = __np.decimal_point();
244803a78d15Sespie 	  _M_thousands_sep = __np.thousands_sep();
244903a78d15Sespie 
245003a78d15Sespie 	  string_type __false = __np.falsename();
245103a78d15Sespie 	  _CharT* __falsename = new _CharT[__false.length() + 1];
245203a78d15Sespie 	  __false.copy(__falsename, __false.length());
245303a78d15Sespie 	  __falsename[__false.length()] = _CharT();
245403a78d15Sespie 	  _M_falsename = __falsename;
245503a78d15Sespie 
245603a78d15Sespie 	  string_type __true = __np.truename();
245703a78d15Sespie 	  _CharT* __truename = new _CharT[__true.length() + 1];
245803a78d15Sespie 	  __true.copy(__truename, __true.length());
245903a78d15Sespie 	  __truename[__true.length()] = _CharT();
246003a78d15Sespie 	  _M_truename = __truename;
246103a78d15Sespie 
246203a78d15Sespie 	  string __grouping = __np.grouping();
246303a78d15Sespie 	  char* __group = new char[__grouping.length() + 1];
246403a78d15Sespie 	  __grouping.copy(__group, __grouping.length());
246503a78d15Sespie 	  __group[__grouping.length()] = 0;
246603a78d15Sespie 	  _M_grouping = __group;
246703a78d15Sespie 
246803a78d15Sespie 	  _M_use_grouping = __grouping.length() != 0
246903a78d15Sespie 	    && __grouping.data()[0] != 0;
247003a78d15Sespie 	}
247103a78d15Sespie 
247203a78d15Sespie       if (has_facet<ctype<_CharT> >(__loc))
247303a78d15Sespie 	{
247403a78d15Sespie 	  const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
247503a78d15Sespie 	  __ct.widen(__num_base::_S_atoms_out,
247603a78d15Sespie 		     __num_base::_S_atoms_out + __num_base::_S_end,
247703a78d15Sespie 		     _M_atoms_out);
247803a78d15Sespie 	}
247903a78d15Sespie     }
248003a78d15Sespie 
248103a78d15Sespie   // Static locale cache initialization.  Only instantiated with char
248203a78d15Sespie   // and wchar_t, so no need to check has_facet.
248303a78d15Sespie   template<typename _CharT>
248403a78d15Sespie     __locale_cache<numpunct<_CharT> >::
__locale_cache(const locale & __loc,bool)248503a78d15Sespie     __locale_cache(const locale& __loc, bool)
248603a78d15Sespie     {
248703a78d15Sespie       // Grab pointers to numpunct static strings
248803a78d15Sespie       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
248903a78d15Sespie       _M_thousands_sep = __np._M_thousands_sep;
249003a78d15Sespie       _M_decimal_point = __np._M_decimal_point;
249103a78d15Sespie       _M_falsename = __np._M_falsename;
249203a78d15Sespie       _M_truename = __np._M_truename;
249303a78d15Sespie       _M_grouping = __np._M_grouping;
249403a78d15Sespie       _M_use_grouping = false;
249503a78d15Sespie 
249603a78d15Sespie       const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
249703a78d15Sespie       __ct.widen(__num_base::_S_atoms_out,
249803a78d15Sespie 		 __num_base::_S_atoms_out + __num_base::_S_end,
249903a78d15Sespie 		 _M_atoms_out);
250003a78d15Sespie     }
250103a78d15Sespie 
250203a78d15Sespie   // Inhibit implicit instantiations for required instantiations,
250303a78d15Sespie   // which are defined via explicit instantiations elsewhere.
250403a78d15Sespie   // NB: This syntax is a GNU extension.
250503a78d15Sespie #if _GLIBCPP_EXTERN_TEMPLATE
250603a78d15Sespie   extern template class moneypunct<char, false>;
250703a78d15Sespie   extern template class moneypunct<char, true>;
250803a78d15Sespie   extern template class moneypunct_byname<char, false>;
250903a78d15Sespie   extern template class moneypunct_byname<char, true>;
251003a78d15Sespie   extern template class money_get<char>;
251103a78d15Sespie   extern template class money_put<char>;
251203a78d15Sespie   extern template class numpunct<char>;
251303a78d15Sespie   extern template class numpunct_byname<char>;
251403a78d15Sespie   extern template class num_get<char>;
251503a78d15Sespie   extern template class num_put<char>;
251603a78d15Sespie   extern template class __timepunct<char>;
251703a78d15Sespie   extern template class time_put<char>;
251803a78d15Sespie   extern template class time_put_byname<char>;
251903a78d15Sespie   extern template class time_get<char>;
252003a78d15Sespie   extern template class time_get_byname<char>;
252103a78d15Sespie   extern template class messages<char>;
252203a78d15Sespie   extern template class messages_byname<char>;
252303a78d15Sespie   extern template class ctype_byname<char>;
252403a78d15Sespie   extern template class codecvt_byname<char, char, mbstate_t>;
252503a78d15Sespie   extern template class collate<char>;
252603a78d15Sespie   extern template class collate_byname<char>;
252703a78d15Sespie 
252803a78d15Sespie   extern template
252903a78d15Sespie     const codecvt<char, char, mbstate_t>&
253003a78d15Sespie     use_facet<codecvt<char, char, mbstate_t> >(const locale&);
253103a78d15Sespie 
253203a78d15Sespie   extern template
253303a78d15Sespie     const collate<char>&
253403a78d15Sespie     use_facet<collate<char> >(const locale&);
253503a78d15Sespie 
253603a78d15Sespie   extern template
253703a78d15Sespie     const numpunct<char>&
253803a78d15Sespie     use_facet<numpunct<char> >(const locale&);
253903a78d15Sespie 
254003a78d15Sespie   extern template
254103a78d15Sespie     const num_put<char>&
254203a78d15Sespie     use_facet<num_put<char> >(const locale&);
254303a78d15Sespie 
254403a78d15Sespie   extern template
254503a78d15Sespie     const num_get<char>&
254603a78d15Sespie     use_facet<num_get<char> >(const locale&);
254703a78d15Sespie 
254803a78d15Sespie   extern template
254903a78d15Sespie     const moneypunct<char, true>&
255003a78d15Sespie     use_facet<moneypunct<char, true> >(const locale&);
255103a78d15Sespie 
255203a78d15Sespie   extern template
255303a78d15Sespie     const moneypunct<char, false>&
255403a78d15Sespie     use_facet<moneypunct<char, false> >(const locale&);
255503a78d15Sespie 
255603a78d15Sespie   extern template
255703a78d15Sespie     const money_put<char>&
255803a78d15Sespie     use_facet<money_put<char> >(const locale&);
255903a78d15Sespie 
256003a78d15Sespie   extern template
256103a78d15Sespie     const money_get<char>&
256203a78d15Sespie     use_facet<money_get<char> >(const locale&);
256303a78d15Sespie 
256403a78d15Sespie   extern template
256503a78d15Sespie     const __timepunct<char>&
256603a78d15Sespie     use_facet<__timepunct<char> >(const locale&);
256703a78d15Sespie 
256803a78d15Sespie   extern template
256903a78d15Sespie     const time_put<char>&
257003a78d15Sespie     use_facet<time_put<char> >(const locale&);
257103a78d15Sespie 
257203a78d15Sespie   extern template
257303a78d15Sespie     const time_get<char>&
257403a78d15Sespie     use_facet<time_get<char> >(const locale&);
257503a78d15Sespie 
257603a78d15Sespie   extern template
257703a78d15Sespie     const messages<char>&
257803a78d15Sespie     use_facet<messages<char> >(const locale&);
257903a78d15Sespie 
258003a78d15Sespie   extern template
258103a78d15Sespie     bool
258203a78d15Sespie     has_facet<ctype<char> >(const locale&);
258303a78d15Sespie 
258403a78d15Sespie   extern template
258503a78d15Sespie     bool
258603a78d15Sespie     has_facet<codecvt<char, char, mbstate_t> >(const locale&);
258703a78d15Sespie 
258803a78d15Sespie   extern template
258903a78d15Sespie     bool
259003a78d15Sespie     has_facet<collate<char> >(const locale&);
259103a78d15Sespie 
259203a78d15Sespie   extern template
259303a78d15Sespie     bool
259403a78d15Sespie     has_facet<numpunct<char> >(const locale&);
259503a78d15Sespie 
259603a78d15Sespie   extern template
259703a78d15Sespie     bool
259803a78d15Sespie     has_facet<num_put<char> >(const locale&);
259903a78d15Sespie 
260003a78d15Sespie   extern template
260103a78d15Sespie     bool
260203a78d15Sespie     has_facet<num_get<char> >(const locale&);
260303a78d15Sespie 
260403a78d15Sespie   extern template
260503a78d15Sespie     bool
260603a78d15Sespie     has_facet<moneypunct<char> >(const locale&);
260703a78d15Sespie 
260803a78d15Sespie   extern template
260903a78d15Sespie     bool
261003a78d15Sespie     has_facet<money_put<char> >(const locale&);
261103a78d15Sespie 
261203a78d15Sespie   extern template
261303a78d15Sespie     bool
261403a78d15Sespie     has_facet<money_get<char> >(const locale&);
261503a78d15Sespie 
261603a78d15Sespie   extern template
261703a78d15Sespie     bool
261803a78d15Sespie     has_facet<__timepunct<char> >(const locale&);
261903a78d15Sespie 
262003a78d15Sespie   extern template
262103a78d15Sespie     bool
262203a78d15Sespie     has_facet<time_put<char> >(const locale&);
262303a78d15Sespie 
262403a78d15Sespie   extern template
262503a78d15Sespie     bool
262603a78d15Sespie     has_facet<time_get<char> >(const locale&);
262703a78d15Sespie 
262803a78d15Sespie   extern template
262903a78d15Sespie     bool
263003a78d15Sespie     has_facet<messages<char> >(const locale&);
263103a78d15Sespie 
2632*c2fb3212Sespie #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
263303a78d15Sespie   extern template class moneypunct<wchar_t, false>;
263403a78d15Sespie   extern template class moneypunct<wchar_t, true>;
263503a78d15Sespie   extern template class moneypunct_byname<wchar_t, false>;
263603a78d15Sespie   extern template class moneypunct_byname<wchar_t, true>;
263703a78d15Sespie   extern template class money_get<wchar_t>;
263803a78d15Sespie   extern template class money_put<wchar_t>;
263903a78d15Sespie   extern template class numpunct<wchar_t>;
264003a78d15Sespie   extern template class numpunct_byname<wchar_t>;
264103a78d15Sespie   extern template class num_get<wchar_t>;
264203a78d15Sespie   extern template class num_put<wchar_t>;
264303a78d15Sespie   extern template class __timepunct<wchar_t>;
264403a78d15Sespie   extern template class time_put<wchar_t>;
264503a78d15Sespie   extern template class time_put_byname<wchar_t>;
264603a78d15Sespie   extern template class time_get<wchar_t>;
264703a78d15Sespie   extern template class time_get_byname<wchar_t>;
264803a78d15Sespie   extern template class messages<wchar_t>;
264903a78d15Sespie   extern template class messages_byname<wchar_t>;
265003a78d15Sespie   extern template class ctype_byname<wchar_t>;
265103a78d15Sespie   extern template class codecvt_byname<wchar_t, char, mbstate_t>;
265203a78d15Sespie   extern template class collate<wchar_t>;
265303a78d15Sespie   extern template class collate_byname<wchar_t>;
265403a78d15Sespie 
265503a78d15Sespie   extern template
265603a78d15Sespie     const codecvt<wchar_t, char, mbstate_t>&
265703a78d15Sespie     use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
265803a78d15Sespie 
265903a78d15Sespie   extern template
266003a78d15Sespie     const collate<wchar_t>&
266103a78d15Sespie     use_facet<collate<wchar_t> >(const locale&);
266203a78d15Sespie 
266303a78d15Sespie   extern template
266403a78d15Sespie     const numpunct<wchar_t>&
266503a78d15Sespie     use_facet<numpunct<wchar_t> >(const locale&);
266603a78d15Sespie 
266703a78d15Sespie   extern template
266803a78d15Sespie     const num_put<wchar_t>&
266903a78d15Sespie     use_facet<num_put<wchar_t> >(const locale&);
267003a78d15Sespie 
267103a78d15Sespie   extern template
267203a78d15Sespie     const num_get<wchar_t>&
267303a78d15Sespie     use_facet<num_get<wchar_t> >(const locale&);
267403a78d15Sespie 
267503a78d15Sespie   extern template
267603a78d15Sespie     const moneypunct<wchar_t, true>&
267703a78d15Sespie     use_facet<moneypunct<wchar_t, true> >(const locale&);
267803a78d15Sespie 
267903a78d15Sespie   extern template
268003a78d15Sespie     const moneypunct<wchar_t, false>&
268103a78d15Sespie     use_facet<moneypunct<wchar_t, false> >(const locale&);
268203a78d15Sespie 
268303a78d15Sespie   extern template
268403a78d15Sespie     const money_put<wchar_t>&
268503a78d15Sespie     use_facet<money_put<wchar_t> >(const locale&);
268603a78d15Sespie 
268703a78d15Sespie   extern template
268803a78d15Sespie     const money_get<wchar_t>&
268903a78d15Sespie     use_facet<money_get<wchar_t> >(const locale&);
269003a78d15Sespie 
269103a78d15Sespie   extern template
269203a78d15Sespie     const __timepunct<wchar_t>&
269303a78d15Sespie     use_facet<__timepunct<wchar_t> >(const locale&);
269403a78d15Sespie 
269503a78d15Sespie   extern template
269603a78d15Sespie     const time_put<wchar_t>&
269703a78d15Sespie     use_facet<time_put<wchar_t> >(const locale&);
269803a78d15Sespie 
269903a78d15Sespie   extern template
270003a78d15Sespie     const time_get<wchar_t>&
270103a78d15Sespie     use_facet<time_get<wchar_t> >(const locale&);
270203a78d15Sespie 
270303a78d15Sespie   extern template
270403a78d15Sespie     const messages<wchar_t>&
270503a78d15Sespie     use_facet<messages<wchar_t> >(const locale&);
270603a78d15Sespie 
270703a78d15Sespie  extern template
270803a78d15Sespie     bool
270903a78d15Sespie     has_facet<ctype<wchar_t> >(const locale&);
271003a78d15Sespie 
271103a78d15Sespie   extern template
271203a78d15Sespie     bool
271303a78d15Sespie     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
271403a78d15Sespie 
271503a78d15Sespie   extern template
271603a78d15Sespie     bool
271703a78d15Sespie     has_facet<collate<wchar_t> >(const locale&);
271803a78d15Sespie 
271903a78d15Sespie   extern template
272003a78d15Sespie     bool
272103a78d15Sespie     has_facet<numpunct<wchar_t> >(const locale&);
272203a78d15Sespie 
272303a78d15Sespie   extern template
272403a78d15Sespie     bool
272503a78d15Sespie     has_facet<num_put<wchar_t> >(const locale&);
272603a78d15Sespie 
272703a78d15Sespie   extern template
272803a78d15Sespie     bool
272903a78d15Sespie     has_facet<num_get<wchar_t> >(const locale&);
273003a78d15Sespie 
273103a78d15Sespie   extern template
273203a78d15Sespie     bool
273303a78d15Sespie     has_facet<moneypunct<wchar_t> >(const locale&);
273403a78d15Sespie 
273503a78d15Sespie   extern template
273603a78d15Sespie     bool
273703a78d15Sespie     has_facet<money_put<wchar_t> >(const locale&);
273803a78d15Sespie 
273903a78d15Sespie   extern template
274003a78d15Sespie     bool
274103a78d15Sespie     has_facet<money_get<wchar_t> >(const locale&);
274203a78d15Sespie 
274303a78d15Sespie   extern template
274403a78d15Sespie     bool
274503a78d15Sespie     has_facet<__timepunct<wchar_t> >(const locale&);
274603a78d15Sespie 
274703a78d15Sespie   extern template
274803a78d15Sespie     bool
274903a78d15Sespie     has_facet<time_put<wchar_t> >(const locale&);
275003a78d15Sespie 
275103a78d15Sespie   extern template
275203a78d15Sespie     bool
275303a78d15Sespie     has_facet<time_get<wchar_t> >(const locale&);
275403a78d15Sespie 
275503a78d15Sespie   extern template
275603a78d15Sespie     bool
275703a78d15Sespie     has_facet<messages<wchar_t> >(const locale&);
275803a78d15Sespie #endif
275903a78d15Sespie #endif
276003a78d15Sespie } // namespace std
276103a78d15Sespie 
276203a78d15Sespie #endif
2763