locale_facets.tcc revision 169691
1118611Snjl// Locale support -*- C++ -*-
2118611Snjl
3118611Snjl// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4118611Snjl// Free Software Foundation, Inc.
5118611Snjl//
6118611Snjl// This file is part of the GNU ISO C++ Library.  This library is free
7118611Snjl// software; you can redistribute it and/or modify it under the
8118611Snjl// terms of the GNU General Public License as published by the
9118611Snjl// Free Software Foundation; either version 2, or (at your option)
10118611Snjl// any later version.
11118611Snjl
12202771Sjkim// This library is distributed in the hope that it will be useful,
13118611Snjl// but WITHOUT ANY WARRANTY; without even the implied warranty of
14118611Snjl// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15118611Snjl// GNU General Public License for more details.
16118611Snjl
17118611Snjl// You should have received a copy of the GNU General Public License along
18118611Snjl// with this library; see the file COPYING.  If not, write to the Free
19118611Snjl// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20118611Snjl// USA.
21118611Snjl
22118611Snjl// As a special exception, you may use this file as part of a free software
23118611Snjl// library without restriction.  Specifically, if other files instantiate
24118611Snjl// templates or use macros or inline functions from this file, or you compile
25118611Snjl// this file and link it with other files to produce an executable, this
26118611Snjl// file does not by itself cause the resulting executable to be covered by
27118611Snjl// the GNU General Public License.  This exception does not however
28118611Snjl// invalidate any other reasons why the executable file might be covered by
29118611Snjl// the GNU General Public License.
30118611Snjl
31118611Snjl/** @file locale_facets.tcc
32118611Snjl *  This is an internal header file, included by other library headers.
33118611Snjl *  You should not attempt to use it directly.
34118611Snjl */
35118611Snjl
36118611Snjl#ifndef _LOCALE_FACETS_TCC
37118611Snjl#define _LOCALE_FACETS_TCC 1
38118611Snjl
39118611Snjl#pragma GCC system_header
40118611Snjl
41118611Snjl#include <limits>		// For numeric_limits
42118611Snjl#include <typeinfo>		// For bad_cast.
43118611Snjl#include <bits/streambuf_iterator.h>
44118611Snjl#include <ext/type_traits.h>
45118611Snjl
46118611Snjl_GLIBCXX_BEGIN_NAMESPACE(std)
47118611Snjl
48118611Snjl  template<typename _Facet>
49118611Snjl    locale
50118611Snjl    locale::combine(const locale& __other) const
51118611Snjl    {
52118611Snjl      _Impl* __tmp = new _Impl(*_M_impl, 1);
53118611Snjl      try
54118611Snjl	{
55118611Snjl	  __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
56118611Snjl	}
57118611Snjl      catch(...)
58118611Snjl	{
59118611Snjl	  __tmp->_M_remove_reference();
60118611Snjl	  __throw_exception_again;
61118611Snjl	}
62118611Snjl      return locale(__tmp);
63118611Snjl    }
64118611Snjl
65118611Snjl  template<typename _CharT, typename _Traits, typename _Alloc>
66118611Snjl    bool
67118611Snjl    locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
68118611Snjl                       const basic_string<_CharT, _Traits, _Alloc>& __s2) const
69118611Snjl    {
70118611Snjl      typedef std::collate<_CharT> __collate_type;
71118611Snjl      const __collate_type& __collate = use_facet<__collate_type>(*this);
72118611Snjl      return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
73118611Snjl				__s2.data(), __s2.data() + __s2.length()) < 0);
74118611Snjl    }
75118611Snjl
76118611Snjl  /**
77118611Snjl   *  @brief  Test for the presence of a facet.
78118611Snjl   *
79118611Snjl   *  has_facet tests the locale argument for the presence of the facet type
80118611Snjl   *  provided as the template parameter.  Facets derived from the facet
81118611Snjl   *  parameter will also return true.
82118611Snjl   *
83118611Snjl   *  @param  Facet  The facet type to test the presence of.
84118611Snjl   *  @param  locale  The locale to test.
85118611Snjl   *  @return  true if locale contains a facet of type Facet, else false.
86118611Snjl  */
87118611Snjl  template<typename _Facet>
88118611Snjl    inline bool
89118611Snjl    has_facet(const locale& __loc) throw()
90118611Snjl    {
91118611Snjl      const size_t __i = _Facet::id._M_id();
92118611Snjl      const locale::facet** __facets = __loc._M_impl->_M_facets;
93118611Snjl      return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
94118611Snjl    }
95118611Snjl
96118611Snjl  /**
97118611Snjl   *  @brief  Return a facet.
98118611Snjl   *
99118611Snjl   *  use_facet looks for and returns a reference to a facet of type Facet
100118611Snjl   *  where Facet is the template parameter.  If has_facet(locale) is true,
101118611Snjl   *  there is a suitable facet to return.  It throws std::bad_cast if the
102118611Snjl   *  locale doesn't contain a facet of type Facet.
103118611Snjl   *
104118611Snjl   *  @param  Facet  The facet type to access.
105118611Snjl   *  @param  locale  The locale to use.
106118611Snjl   *  @return  Reference to facet of type Facet.
107118611Snjl   *  @throw  std::bad_cast if locale doesn't contain a facet of type Facet.
108118611Snjl  */
109118611Snjl  template<typename _Facet>
110118611Snjl    inline const _Facet&
111118611Snjl    use_facet(const locale& __loc)
112118611Snjl    {
113118611Snjl      const size_t __i = _Facet::id._M_id();
114118611Snjl      const locale::facet** __facets = __loc._M_impl->_M_facets;
115118611Snjl      if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
116118611Snjl        __throw_bad_cast();
117118611Snjl      return static_cast<const _Facet&>(*__facets[__i]);
118151937Sjkim    }
119118611Snjl
120118611Snjl  // Routine to access a cache for the facet.  If the cache didn't
121118611Snjl  // exist before, it gets constructed on the fly.
122118611Snjl  template<typename _Facet>
123151937Sjkim    struct __use_cache
124118611Snjl    {
125151937Sjkim      const _Facet*
126151937Sjkim      operator() (const locale& __loc) const;
127151937Sjkim    };
128151937Sjkim
129151937Sjkim  // Specializations.
130193529Sjkim  template<typename _CharT>
131193529Sjkim    struct __use_cache<__numpunct_cache<_CharT> >
132193529Sjkim    {
133193529Sjkim      const __numpunct_cache<_CharT>*
134193529Sjkim      operator() (const locale& __loc) const
135193529Sjkim      {
136193529Sjkim	const size_t __i = numpunct<_CharT>::id._M_id();
137193529Sjkim	const locale::facet** __caches = __loc._M_impl->_M_caches;
138193529Sjkim	if (!__caches[__i])
139193529Sjkim	  {
140193529Sjkim	    __numpunct_cache<_CharT>* __tmp = NULL;
141193529Sjkim	    try
142193529Sjkim	      {
143193529Sjkim		__tmp = new __numpunct_cache<_CharT>;
144193529Sjkim		__tmp->_M_cache(__loc);
145193529Sjkim	      }
146193529Sjkim	    catch(...)
147193529Sjkim	      {
148193529Sjkim		delete __tmp;
149193529Sjkim		__throw_exception_again;
150118611Snjl	      }
151118611Snjl	    __loc._M_impl->_M_install_cache(__tmp, __i);
152118611Snjl	  }
153118611Snjl	return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
154118611Snjl      }
155118611Snjl    };
156118611Snjl
157118611Snjl  template<typename _CharT, bool _Intl>
158118611Snjl    struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
159118611Snjl    {
160118611Snjl      const __moneypunct_cache<_CharT, _Intl>*
161118611Snjl      operator() (const locale& __loc) const
162118611Snjl      {
163118611Snjl	const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
164151937Sjkim	const locale::facet** __caches = __loc._M_impl->_M_caches;
165118611Snjl	if (!__caches[__i])
166118611Snjl	  {
167118611Snjl	    __moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
168118611Snjl	    try
169118611Snjl	      {
170118611Snjl		__tmp = new __moneypunct_cache<_CharT, _Intl>;
171118611Snjl		__tmp->_M_cache(__loc);
172202771Sjkim	      }
173118611Snjl	    catch(...)
174118611Snjl	      {
175118611Snjl		delete __tmp;
176118611Snjl		__throw_exception_again;
177118611Snjl	      }
178118611Snjl	    __loc._M_impl->_M_install_cache(__tmp, __i);
179118611Snjl	  }
180202771Sjkim	return static_cast<
181202771Sjkim	  const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
182202771Sjkim      }
183202771Sjkim    };
184118611Snjl
185118611Snjl  template<typename _CharT>
186118611Snjl    void
187118611Snjl    __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
188118611Snjl    {
189118611Snjl      _M_allocated = true;
190118611Snjl
191118611Snjl      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
192118611Snjl
193118611Snjl      _M_grouping_size = __np.grouping().size();
194118611Snjl      char* __grouping = new char[_M_grouping_size];
195118611Snjl      __np.grouping().copy(__grouping, _M_grouping_size);
196118611Snjl      _M_grouping = __grouping;
197118611Snjl      _M_use_grouping = (_M_grouping_size
198118611Snjl			 && static_cast<signed char>(__np.grouping()[0]) > 0);
199118611Snjl
200118611Snjl      _M_truename_size = __np.truename().size();
201118611Snjl      _CharT* __truename = new _CharT[_M_truename_size];
202118611Snjl      __np.truename().copy(__truename, _M_truename_size);
203118611Snjl      _M_truename = __truename;
204118611Snjl
205118611Snjl      _M_falsename_size = __np.falsename().size();
206118611Snjl      _CharT* __falsename = new _CharT[_M_falsename_size];
207118611Snjl      __np.falsename().copy(__falsename, _M_falsename_size);
208118611Snjl      _M_falsename = __falsename;
209118611Snjl
210118611Snjl      _M_decimal_point = __np.decimal_point();
211118611Snjl      _M_thousands_sep = __np.thousands_sep();
212118611Snjl
213151937Sjkim      const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
214118611Snjl      __ct.widen(__num_base::_S_atoms_out,
215118611Snjl		 __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
216118611Snjl      __ct.widen(__num_base::_S_atoms_in,
217118611Snjl		 __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
218118611Snjl    }
219118611Snjl
220118611Snjl  template<typename _CharT, bool _Intl>
221118611Snjl    void
222118611Snjl    __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
223118611Snjl    {
224118611Snjl      _M_allocated = true;
225118611Snjl
226118611Snjl      const moneypunct<_CharT, _Intl>& __mp =
227118611Snjl	use_facet<moneypunct<_CharT, _Intl> >(__loc);
228118611Snjl
229118611Snjl      _M_grouping_size = __mp.grouping().size();
230118611Snjl      char* __grouping = new char[_M_grouping_size];
231118611Snjl      __mp.grouping().copy(__grouping, _M_grouping_size);
232118611Snjl      _M_grouping = __grouping;
233118611Snjl      _M_use_grouping = (_M_grouping_size
234118611Snjl			 && static_cast<signed char>(__mp.grouping()[0]) > 0);
235151937Sjkim      
236151937Sjkim      _M_decimal_point = __mp.decimal_point();
237118611Snjl      _M_thousands_sep = __mp.thousands_sep();
238118611Snjl      _M_frac_digits = __mp.frac_digits();
239118611Snjl      
240118611Snjl      _M_curr_symbol_size = __mp.curr_symbol().size();
241118611Snjl      _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
242118611Snjl      __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
243118611Snjl      _M_curr_symbol = __curr_symbol;
244118611Snjl      
245118611Snjl      _M_positive_sign_size = __mp.positive_sign().size();
246193529Sjkim      _CharT* __positive_sign = new _CharT[_M_positive_sign_size];
247193529Sjkim      __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
248193529Sjkim      _M_positive_sign = __positive_sign;
249193529Sjkim
250193529Sjkim      _M_negative_sign_size = __mp.negative_sign().size();
251151937Sjkim      _CharT* __negative_sign = new _CharT[_M_negative_sign_size];
252151937Sjkim      __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
253151937Sjkim      _M_negative_sign = __negative_sign;
254151937Sjkim      
255118611Snjl      _M_pos_format = __mp.pos_format();
256118611Snjl      _M_neg_format = __mp.neg_format();
257118611Snjl
258118611Snjl      const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
259118611Snjl      __ct.widen(money_base::_S_atoms,
260118611Snjl		 money_base::_S_atoms + money_base::_S_end, _M_atoms);
261118611Snjl    }
262118611Snjl
263118611Snjl
264118611Snjl  // Used by both numeric and monetary facets.
265118611Snjl  // Check to make sure that the __grouping_tmp string constructed in
266118611Snjl  // money_get or num_get matches the canonical grouping for a given
267118611Snjl  // locale.
268118611Snjl  // __grouping_tmp is parsed L to R
269118611Snjl  // 1,222,444 == __grouping_tmp of "\1\3\3"
270118611Snjl  // __grouping is parsed R to L
271118611Snjl  // 1,222,444 == __grouping of "\3" == "\3\3\3"
272118611Snjl  static bool
273118611Snjl  __verify_grouping(const char* __grouping, size_t __grouping_size,
274118611Snjl		    const string& __grouping_tmp);
275118611Snjl
276118611Snjl_GLIBCXX_BEGIN_LDBL_NAMESPACE
277118611Snjl
278118611Snjl  template<typename _CharT, typename _InIter>
279118611Snjl    _InIter
280118611Snjl    num_get<_CharT, _InIter>::
281118611Snjl    _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
282118611Snjl		     ios_base::iostate& __err, string& __xtrc) const
283209746Sjkim    {
284209746Sjkim      typedef char_traits<_CharT>			__traits_type;
285209746Sjkim      typedef __numpunct_cache<_CharT>                  __cache_type;
286118611Snjl      __use_cache<__cache_type> __uc;
287209746Sjkim      const locale& __loc = __io._M_getloc();
288209746Sjkim      const __cache_type* __lc = __uc(__loc);
289209746Sjkim      const _CharT* __lit = __lc->_M_atoms_in;
290209746Sjkim      char_type __c = char_type();
291118611Snjl
292118611Snjl      // True if __beg becomes equal to __end.
293118611Snjl      bool __testeof = __beg == __end;
294118611Snjl
295118611Snjl      // First check for sign.
296118611Snjl      if (!__testeof)
297118611Snjl	{
298118611Snjl	  __c = *__beg;
299118611Snjl	  const bool __plus = __c == __lit[__num_base::_S_iplus];
300118611Snjl	  if ((__plus || __c == __lit[__num_base::_S_iminus])
301118611Snjl	      && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
302118611Snjl	      && !(__c == __lc->_M_decimal_point))
303118611Snjl	    {
304118611Snjl	      __xtrc += __plus ? '+' : '-';
305118611Snjl	      if (++__beg != __end)
306118611Snjl		__c = *__beg;
307118611Snjl	      else
308118611Snjl		__testeof = true;
309118611Snjl	    }
310118611Snjl	}
311118611Snjl
312118611Snjl      // Next, look for leading zeros.
313151937Sjkim      bool __found_mantissa = false;
314151937Sjkim      int __sep_pos = 0;
315118611Snjl      while (!__testeof)
316118611Snjl	{
317151937Sjkim	  if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
318193529Sjkim	      || __c == __lc->_M_decimal_point)
319193529Sjkim	    break;
320118611Snjl	  else if (__c == __lit[__num_base::_S_izero])
321118611Snjl	    {
322118611Snjl	      if (!__found_mantissa)
323151937Sjkim		{
324151937Sjkim		  __xtrc += '0';
325118611Snjl		  __found_mantissa = true;
326151937Sjkim		}
327193529Sjkim	      ++__sep_pos;
328193529Sjkim
329118611Snjl	      if (++__beg != __end)
330118611Snjl		__c = *__beg;
331151937Sjkim	      else
332118611Snjl		__testeof = true;
333118611Snjl	    }
334151937Sjkim	  else
335118611Snjl	    break;
336118611Snjl	}
337118611Snjl
338118611Snjl      // Only need acceptable digits for floating point numbers.
339118611Snjl      bool __found_dec = false;
340118611Snjl      bool __found_sci = false;
341118611Snjl      string __found_grouping;
342118611Snjl      if (__lc->_M_use_grouping)
343118611Snjl	__found_grouping.reserve(32);
344118611Snjl      const char_type* __lit_zero = __lit + __num_base::_S_izero;
345118611Snjl
346118611Snjl      if (!__lc->_M_allocated)
347118611Snjl	// "C" locale
348118611Snjl	while (!__testeof)
349118611Snjl	  {
350118611Snjl	    const int __digit = _M_find(__lit_zero, 10, __c);
351118611Snjl	    if (__digit != -1)
352118611Snjl	      {
353118611Snjl		__xtrc += '0' + __digit;
354118611Snjl		__found_mantissa = true;
355118611Snjl	      }
356118611Snjl	    else if (__c == __lc->_M_decimal_point
357118611Snjl		     && !__found_dec && !__found_sci)
358118611Snjl	      {
359118611Snjl		__xtrc += '.';
360118611Snjl		__found_dec = true;
361118611Snjl	      }
362118611Snjl	    else if ((__c == __lit[__num_base::_S_ie] 
363118611Snjl		      || __c == __lit[__num_base::_S_iE])
364118611Snjl		     && !__found_sci && __found_mantissa)
365118611Snjl	      {
366118611Snjl		// Scientific notation.
367118611Snjl		__xtrc += 'e';
368118611Snjl		__found_sci = true;
369118611Snjl		
370118611Snjl		// Remove optional plus or minus sign, if they exist.
371118611Snjl		if (++__beg != __end)
372118611Snjl		  {
373118611Snjl		    __c = *__beg;
374118611Snjl		    const bool __plus = __c == __lit[__num_base::_S_iplus];
375118611Snjl		    if (__plus || __c == __lit[__num_base::_S_iminus])
376118611Snjl		      __xtrc += __plus ? '+' : '-';
377118611Snjl		    else
378118611Snjl		      continue;
379118611Snjl		  }
380118611Snjl		else
381118611Snjl		  {
382118611Snjl		    __testeof = true;
383118611Snjl		    break;
384118611Snjl		  }
385118611Snjl	      }
386118611Snjl	    else
387118611Snjl	      break;
388118611Snjl
389118611Snjl	    if (++__beg != __end)
390118611Snjl	      __c = *__beg;
391118611Snjl	    else
392118611Snjl	      __testeof = true;
393118611Snjl	  }
394118611Snjl      else
395118611Snjl	while (!__testeof)
396118611Snjl	  {
397118611Snjl	    // According to 22.2.2.1.2, p8-9, first look for thousands_sep
398118611Snjl	    // and decimal_point.
399118611Snjl	    if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
400118611Snjl	      {
401118611Snjl		if (!__found_dec && !__found_sci)
402118611Snjl		  {
403118611Snjl		    // NB: Thousands separator at the beginning of a string
404118611Snjl		    // is a no-no, as is two consecutive thousands separators.
405118611Snjl		    if (__sep_pos)
406118611Snjl		      {
407118611Snjl			__found_grouping += static_cast<char>(__sep_pos);
408118611Snjl			__sep_pos = 0;
409118611Snjl		      }
410118611Snjl		    else
411118611Snjl		      {
412118611Snjl			// NB: __convert_to_v will not assign __v and will
413118611Snjl			// set the failbit.
414118611Snjl			__xtrc.clear();
415118611Snjl			break;
416118611Snjl		      }
417151937Sjkim		  }
418118611Snjl		else
419118611Snjl		  break;
420118611Snjl	      }
421118611Snjl	    else if (__c == __lc->_M_decimal_point)
422118611Snjl	      {
423118611Snjl		if (!__found_dec && !__found_sci)
424118611Snjl		  {
425118611Snjl		    // If no grouping chars are seen, no grouping check
426118611Snjl		    // is applied. Therefore __found_grouping is adjusted
427118611Snjl		    // only if decimal_point comes after some thousands_sep.
428118611Snjl		    if (__found_grouping.size())
429118611Snjl		      __found_grouping += static_cast<char>(__sep_pos);
430118611Snjl		    __xtrc += '.';
431118611Snjl		    __found_dec = true;
432118611Snjl		  }
433118611Snjl		else
434118611Snjl		  break;
435118611Snjl	      }
436118611Snjl	    else
437118611Snjl	      {
438118611Snjl		const char_type* __q =
439118611Snjl		  __traits_type::find(__lit_zero, 10, __c);
440118611Snjl		if (__q)
441118611Snjl		  {
442118611Snjl		    __xtrc += '0' + (__q - __lit_zero);
443118611Snjl		    __found_mantissa = true;
444118611Snjl		    ++__sep_pos;
445118611Snjl		  }
446118611Snjl		else if ((__c == __lit[__num_base::_S_ie] 
447118611Snjl			  || __c == __lit[__num_base::_S_iE])
448118611Snjl			 && !__found_sci && __found_mantissa)
449118611Snjl		  {
450118611Snjl		    // Scientific notation.
451118611Snjl		    if (__found_grouping.size() && !__found_dec)
452118611Snjl		      __found_grouping += static_cast<char>(__sep_pos);
453118611Snjl		    __xtrc += 'e';
454118611Snjl		    __found_sci = true;
455118611Snjl		    
456118611Snjl		    // Remove optional plus or minus sign, if they exist.
457118611Snjl		    if (++__beg != __end)
458118611Snjl		      {
459118611Snjl			__c = *__beg;
460118611Snjl			const bool __plus = __c == __lit[__num_base::_S_iplus];
461118611Snjl			if ((__plus || __c == __lit[__num_base::_S_iminus])
462118611Snjl			    && !(__lc->_M_use_grouping
463118611Snjl				 && __c == __lc->_M_thousands_sep)
464118611Snjl			    && !(__c == __lc->_M_decimal_point))
465151937Sjkim		      __xtrc += __plus ? '+' : '-';
466118611Snjl			else
467118611Snjl			  continue;
468118611Snjl		      }
469118611Snjl		    else
470118611Snjl		      {
471118611Snjl			__testeof = true;
472118611Snjl			break;
473118611Snjl		      }
474118611Snjl		  }
475118611Snjl		else
476118611Snjl		  break;
477118611Snjl	      }
478118611Snjl	    
479118611Snjl	    if (++__beg != __end)
480118611Snjl	      __c = *__beg;
481118611Snjl	    else
482118611Snjl	      __testeof = true;
483118611Snjl	  }
484118611Snjl
485118611Snjl      // Digit grouping is checked. If grouping and found_grouping don't
486118611Snjl      // match, then get very very upset, and set failbit.
487118611Snjl      if (__found_grouping.size())
488118611Snjl        {
489118611Snjl          // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
490118611Snjl	  if (!__found_dec && !__found_sci)
491118611Snjl	    __found_grouping += static_cast<char>(__sep_pos);
492118611Snjl
493118611Snjl          if (!std::__verify_grouping(__lc->_M_grouping, 
494118611Snjl				      __lc->_M_grouping_size,
495118611Snjl				      __found_grouping))
496118611Snjl	    __err |= ios_base::failbit;
497118611Snjl        }
498118611Snjl
499118611Snjl      // Finish up.
500118611Snjl      if (__testeof)
501118611Snjl        __err |= ios_base::eofbit;
502118611Snjl      return __beg;
503118611Snjl    }
504118611Snjl
505118611Snjl_GLIBCXX_END_LDBL_NAMESPACE
506118611Snjl
507118611Snjl_GLIBCXX_BEGIN_LDBL_NAMESPACE
508118611Snjl
509118611Snjl  template<typename _CharT, typename _InIter>
510118611Snjl    template<typename _ValueT>
511118611Snjl      _InIter
512118611Snjl      num_get<_CharT, _InIter>::
513118611Snjl      _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
514118611Snjl		     ios_base::iostate& __err, _ValueT& __v) const
515118611Snjl      {
516118611Snjl        typedef char_traits<_CharT>			     __traits_type;
517118611Snjl	using __gnu_cxx::__add_unsigned;
518118611Snjl	typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
519118611Snjl	typedef __numpunct_cache<_CharT>                     __cache_type;
520118611Snjl	__use_cache<__cache_type> __uc;
521118611Snjl	const locale& __loc = __io._M_getloc();
522118611Snjl	const __cache_type* __lc = __uc(__loc);
523118611Snjl	const _CharT* __lit = __lc->_M_atoms_in;
524118611Snjl	char_type __c = char_type();
525118611Snjl
526118611Snjl	// NB: Iff __basefield == 0, __base can change based on contents.
527118611Snjl	const ios_base::fmtflags __basefield = __io.flags()
528118611Snjl	                                       & ios_base::basefield;
529118611Snjl	const bool __oct = __basefield == ios_base::oct;
530118611Snjl	int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
531118611Snjl
532118611Snjl	// True if __beg becomes equal to __end.
533118611Snjl	bool __testeof = __beg == __end;
534118611Snjl
535209746Sjkim	// First check for sign.
536118611Snjl	bool __negative = false;
537118611Snjl	if (!__testeof)
538118611Snjl	  {
539118611Snjl	    __c = *__beg;
540118611Snjl	    if (numeric_limits<_ValueT>::is_signed)
541199337Sjkim	      __negative = __c == __lit[__num_base::_S_iminus];
542118611Snjl	    if ((__negative || __c == __lit[__num_base::_S_iplus])
543118611Snjl		&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
544118611Snjl		&& !(__c == __lc->_M_decimal_point))
545118611Snjl	      {
546118611Snjl		if (++__beg != __end)
547118611Snjl		  __c = *__beg;
548118611Snjl		else
549118611Snjl		  __testeof = true;
550118611Snjl	      }
551118611Snjl	  }
552118611Snjl
553118611Snjl	// Next, look for leading zeros and check required digits
554118611Snjl	// for base formats.
555118611Snjl	bool __found_zero = false;
556118611Snjl	int __sep_pos = 0;
557118611Snjl	while (!__testeof)
558118611Snjl	  {
559118611Snjl	    if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
560118611Snjl		|| __c == __lc->_M_decimal_point)
561118611Snjl	      break;
562118611Snjl	    else if (__c == __lit[__num_base::_S_izero] 
563118611Snjl		     && (!__found_zero || __base == 10))
564118611Snjl	      {
565118611Snjl		__found_zero = true;
566118611Snjl		++__sep_pos;
567118611Snjl		if (__basefield == 0)
568118611Snjl		  __base = 8;
569118611Snjl		if (__base == 8)
570118611Snjl		  __sep_pos = 0;
571118611Snjl	      }
572167802Sjkim	    else if (__found_zero
573167802Sjkim		     && (__c == __lit[__num_base::_S_ix]
574167802Sjkim			 || __c == __lit[__num_base::_S_iX]))
575167802Sjkim	      {
576167802Sjkim		if (__basefield == 0)
577167802Sjkim		  __base = 16;
578167802Sjkim		if (__base == 16)
579167802Sjkim		  {
580167802Sjkim		    __found_zero = false;
581167802Sjkim		    __sep_pos = 0;
582167802Sjkim		  }
583167802Sjkim		else
584167802Sjkim		  break;
585167802Sjkim	      }
586167802Sjkim	    else
587118611Snjl	      break;
588118611Snjl
589118611Snjl	    if (++__beg != __end)
590118611Snjl	      {
591118611Snjl		__c = *__beg;
592118611Snjl		if (!__found_zero)
593118611Snjl		  break;
594118611Snjl	      }
595118611Snjl	    else
596118611Snjl	      __testeof = true;
597118611Snjl	  }
598118611Snjl	
599118611Snjl	// At this point, base is determined. If not hex, only allow
600118611Snjl	// base digits as valid input.
601118611Snjl	const size_t __len = (__base == 16 ? __num_base::_S_iend
602118611Snjl			      - __num_base::_S_izero : __base);
603118611Snjl
604118611Snjl	// Extract.
605118611Snjl	string __found_grouping;
606118611Snjl	if (__lc->_M_use_grouping)
607118611Snjl	  __found_grouping.reserve(32);
608118611Snjl	bool __testfail = false;
609118611Snjl	const __unsigned_type __max = __negative ?
610118611Snjl	  -numeric_limits<_ValueT>::min() : numeric_limits<_ValueT>::max();
611118611Snjl	const __unsigned_type __smax = __max / __base;
612118611Snjl	__unsigned_type __result = 0;
613118611Snjl	int __digit = 0;
614118611Snjl	const char_type* __lit_zero = __lit + __num_base::_S_izero;
615118611Snjl
616118611Snjl	if (!__lc->_M_allocated)
617118611Snjl	  // "C" locale
618118611Snjl	  while (!__testeof)
619118611Snjl	    {
620118611Snjl	      __digit = _M_find(__lit_zero, __len, __c);
621118611Snjl	      if (__digit == -1)
622118611Snjl		break;
623118611Snjl	      
624118611Snjl	      if (__result > __smax)
625118611Snjl		__testfail = true;
626118611Snjl	      else
627118611Snjl		{
628118611Snjl		  __result *= __base;
629118611Snjl		  __testfail |= __result > __max - __digit;
630118611Snjl		  __result += __digit;
631118611Snjl		  ++__sep_pos;
632118611Snjl		}
633118611Snjl	      
634118611Snjl	      if (++__beg != __end)
635118611Snjl		__c = *__beg;
636118611Snjl	      else
637118611Snjl		__testeof = true;
638118611Snjl	    }
639118611Snjl	else
640118611Snjl	  while (!__testeof)
641118611Snjl	    {
642118611Snjl	      // According to 22.2.2.1.2, p8-9, first look for thousands_sep
643118611Snjl	      // and decimal_point.
644118611Snjl	      if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
645118611Snjl		{
646118611Snjl		  // NB: Thousands separator at the beginning of a string
647118611Snjl		  // is a no-no, as is two consecutive thousands separators.
648118611Snjl		  if (__sep_pos)
649118611Snjl		    {
650118611Snjl		      __found_grouping += static_cast<char>(__sep_pos);
651118611Snjl		      __sep_pos = 0;
652118611Snjl		    }
653118611Snjl		  else
654118611Snjl		    {
655118611Snjl		      __testfail = true;
656151937Sjkim		      break;
657118611Snjl		    }
658118611Snjl		}
659151937Sjkim	      else if (__c == __lc->_M_decimal_point)
660151937Sjkim		break;
661118611Snjl	      else
662118611Snjl		{
663118611Snjl		  const char_type* __q =
664118611Snjl		    __traits_type::find(__lit_zero, __len, __c);
665118611Snjl		  if (!__q)
666118611Snjl		    break;
667118611Snjl		  
668118611Snjl		  __digit = __q - __lit_zero;
669118611Snjl		  if (__digit > 15)
670118611Snjl		    __digit -= 6;
671118611Snjl		  if (__result > __smax)
672118611Snjl		    __testfail = true;
673118611Snjl		  else
674118611Snjl		    {
675118611Snjl		      __result *= __base;
676118611Snjl		      __testfail |= __result > __max - __digit;
677118611Snjl		      __result += __digit;
678		      ++__sep_pos;
679		    }
680		}
681	      
682	      if (++__beg != __end)
683		__c = *__beg;
684	      else
685		__testeof = true;
686	    }
687	
688	// Digit grouping is checked. If grouping and found_grouping don't
689	// match, then get very very upset, and set failbit.
690	if (__found_grouping.size())
691	  {
692	    // Add the ending grouping.
693	    __found_grouping += static_cast<char>(__sep_pos);
694
695	    if (!std::__verify_grouping(__lc->_M_grouping,
696					__lc->_M_grouping_size,
697					__found_grouping))
698	      __err |= ios_base::failbit;
699	  }
700
701	if (!__testfail && (__sep_pos || __found_zero 
702			    || __found_grouping.size()))
703	  __v = __negative ? -__result : __result;
704	else
705	  __err |= ios_base::failbit;
706
707	if (__testeof)
708	  __err |= ios_base::eofbit;
709	return __beg;
710      }
711
712  // _GLIBCXX_RESOLVE_LIB_DEFECTS
713  // 17.  Bad bool parsing
714  template<typename _CharT, typename _InIter>
715    _InIter
716    num_get<_CharT, _InIter>::
717    do_get(iter_type __beg, iter_type __end, ios_base& __io,
718           ios_base::iostate& __err, bool& __v) const
719    {
720      if (!(__io.flags() & ios_base::boolalpha))
721        {
722	  // Parse bool values as long.
723          // NB: We can't just call do_get(long) here, as it might
724          // refer to a derived class.
725	  long __l = -1;
726          __beg = _M_extract_int(__beg, __end, __io, __err, __l);
727	  if (__l == 0 || __l == 1)
728	    __v = __l;
729	  else
730            __err |= ios_base::failbit;
731        }
732      else
733        {
734	  // Parse bool values as alphanumeric.
735	  typedef __numpunct_cache<_CharT>              __cache_type;
736	  __use_cache<__cache_type> __uc;
737	  const locale& __loc = __io._M_getloc();
738	  const __cache_type* __lc = __uc(__loc);
739
740	  bool __testf = true;
741	  bool __testt = true;
742	  size_t __n;
743	  bool __testeof = __beg == __end;
744          for (__n = 0; !__testeof; ++__n)
745            {
746	      const char_type __c = *__beg;
747
748	      if (__testf)
749		if (__n < __lc->_M_falsename_size)
750		  __testf = __c == __lc->_M_falsename[__n];
751		else
752		  break;
753
754	      if (__testt)
755		if (__n < __lc->_M_truename_size)
756		  __testt = __c == __lc->_M_truename[__n];
757		else
758		  break;
759
760	      if (!__testf && !__testt)
761		break;
762	      
763	      if (++__beg == __end)
764		__testeof = true;
765            }
766	  if (__testf && __n == __lc->_M_falsename_size)
767	    __v = 0;
768	  else if (__testt && __n == __lc->_M_truename_size)
769	    __v = 1;
770	  else
771	    __err |= ios_base::failbit;
772
773          if (__testeof)
774            __err |= ios_base::eofbit;
775        }
776      return __beg;
777    }
778
779  template<typename _CharT, typename _InIter>
780    _InIter
781    num_get<_CharT, _InIter>::
782    do_get(iter_type __beg, iter_type __end, ios_base& __io,
783           ios_base::iostate& __err, long& __v) const
784    { return _M_extract_int(__beg, __end, __io, __err, __v); }
785
786  template<typename _CharT, typename _InIter>
787    _InIter
788    num_get<_CharT, _InIter>::
789    do_get(iter_type __beg, iter_type __end, ios_base& __io,
790           ios_base::iostate& __err, unsigned short& __v) const
791    { return _M_extract_int(__beg, __end, __io, __err, __v); }
792
793  template<typename _CharT, typename _InIter>
794    _InIter
795    num_get<_CharT, _InIter>::
796    do_get(iter_type __beg, iter_type __end, ios_base& __io,
797           ios_base::iostate& __err, unsigned int& __v) const
798    { return _M_extract_int(__beg, __end, __io, __err, __v); }
799
800  template<typename _CharT, typename _InIter>
801    _InIter
802    num_get<_CharT, _InIter>::
803    do_get(iter_type __beg, iter_type __end, ios_base& __io,
804           ios_base::iostate& __err, unsigned long& __v) const
805    { return _M_extract_int(__beg, __end, __io, __err, __v); }
806
807#ifdef _GLIBCXX_USE_LONG_LONG
808  template<typename _CharT, typename _InIter>
809    _InIter
810    num_get<_CharT, _InIter>::
811    do_get(iter_type __beg, iter_type __end, ios_base& __io,
812           ios_base::iostate& __err, long long& __v) const
813    { return _M_extract_int(__beg, __end, __io, __err, __v); }
814
815  template<typename _CharT, typename _InIter>
816    _InIter
817    num_get<_CharT, _InIter>::
818    do_get(iter_type __beg, iter_type __end, ios_base& __io,
819           ios_base::iostate& __err, unsigned long long& __v) const
820    { return _M_extract_int(__beg, __end, __io, __err, __v); }
821#endif
822
823  template<typename _CharT, typename _InIter>
824    _InIter
825    num_get<_CharT, _InIter>::
826    do_get(iter_type __beg, iter_type __end, ios_base& __io,
827	   ios_base::iostate& __err, float& __v) const
828    {
829      string __xtrc;
830      __xtrc.reserve(32);
831      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
832      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
833      return __beg;
834    }
835
836  template<typename _CharT, typename _InIter>
837    _InIter
838    num_get<_CharT, _InIter>::
839    do_get(iter_type __beg, iter_type __end, ios_base& __io,
840           ios_base::iostate& __err, double& __v) const
841    {
842      string __xtrc;
843      __xtrc.reserve(32);
844      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
845      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
846      return __beg;
847    }
848
849#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
850  template<typename _CharT, typename _InIter>
851    _InIter
852    num_get<_CharT, _InIter>::
853    __do_get(iter_type __beg, iter_type __end, ios_base& __io,
854	     ios_base::iostate& __err, double& __v) const
855    {
856      string __xtrc;
857      __xtrc.reserve(32);
858      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
859      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
860      return __beg;
861    }
862#endif
863
864  template<typename _CharT, typename _InIter>
865    _InIter
866    num_get<_CharT, _InIter>::
867    do_get(iter_type __beg, iter_type __end, ios_base& __io,
868           ios_base::iostate& __err, long double& __v) const
869    {
870      string __xtrc;
871      __xtrc.reserve(32);
872      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
873      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
874      return __beg;
875    }
876
877  template<typename _CharT, typename _InIter>
878    _InIter
879    num_get<_CharT, _InIter>::
880    do_get(iter_type __beg, iter_type __end, ios_base& __io,
881           ios_base::iostate& __err, void*& __v) const
882    {
883      // Prepare for hex formatted input.
884      typedef ios_base::fmtflags        fmtflags;
885      const fmtflags __fmt = __io.flags();
886      __io.flags(__fmt & ~ios_base::basefield | ios_base::hex);
887
888      unsigned long __ul;
889      __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
890
891      // Reset from hex formatted input.
892      __io.flags(__fmt);
893
894      if (!(__err & ios_base::failbit))
895	__v = reinterpret_cast<void*>(__ul);
896      return __beg;
897    }
898
899  // For use by integer and floating-point types after they have been
900  // converted into a char_type string.
901  template<typename _CharT, typename _OutIter>
902    void
903    num_put<_CharT, _OutIter>::
904    _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
905	   _CharT* __new, const _CharT* __cs, int& __len) const
906    {
907      // [22.2.2.2.2] Stage 3.
908      // If necessary, pad.
909      __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs,
910						  __w, __len, true);
911      __len = static_cast<int>(__w);
912    }
913
914_GLIBCXX_END_LDBL_NAMESPACE
915
916  template<typename _CharT, typename _ValueT>
917    int
918    __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
919		  ios_base::fmtflags __flags, bool __dec)
920    {
921      _CharT* __buf = __bufend;
922      if (__builtin_expect(__dec, true))
923	{
924	  // Decimal.
925	  do
926	    {
927	      *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
928	      __v /= 10;
929	    }
930	  while (__v != 0);
931	}
932      else if ((__flags & ios_base::basefield) == ios_base::oct)
933	{
934	  // Octal.
935	  do
936	    {
937	      *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
938	      __v >>= 3;
939	    }
940	  while (__v != 0);
941	}
942      else
943	{
944	  // Hex.
945	  const bool __uppercase = __flags & ios_base::uppercase;
946	  const int __case_offset = __uppercase ? __num_base::_S_oudigits
947	                                        : __num_base::_S_odigits;
948	  do
949	    {
950	      *--__buf = __lit[(__v & 0xf) + __case_offset];
951	      __v >>= 4;
952	    }
953	  while (__v != 0);
954	}
955      return __bufend - __buf;
956    }
957
958_GLIBCXX_BEGIN_LDBL_NAMESPACE
959
960  template<typename _CharT, typename _OutIter>
961    void
962    num_put<_CharT, _OutIter>::
963    _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
964		 ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
965    {
966      _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
967					__grouping_size, __cs, __cs + __len);
968      __len = __p - __new;
969    }
970  
971  template<typename _CharT, typename _OutIter>
972    template<typename _ValueT>
973      _OutIter
974      num_put<_CharT, _OutIter>::
975      _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
976		    _ValueT __v) const
977      {
978	using __gnu_cxx::__add_unsigned;
979	typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
980	typedef __numpunct_cache<_CharT>	             __cache_type;
981	__use_cache<__cache_type> __uc;
982	const locale& __loc = __io._M_getloc();
983	const __cache_type* __lc = __uc(__loc);
984	const _CharT* __lit = __lc->_M_atoms_out;
985	const ios_base::fmtflags __flags = __io.flags();
986
987	// Long enough to hold hex, dec, and octal representations.
988	const int __ilen = 5 * sizeof(_ValueT);
989	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
990							     * __ilen));
991
992	// [22.2.2.2.2] Stage 1, numeric conversion to character.
993	// Result is returned right-justified in the buffer.
994	const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
995	const bool __dec = (__basefield != ios_base::oct
996			    && __basefield != ios_base::hex);
997	const __unsigned_type __u = (__v > 0 || !__dec) ? __v : -__v;
998 	int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec);
999	__cs += __ilen - __len;
1000
1001	// Add grouping, if necessary.
1002	if (__lc->_M_use_grouping)
1003	  {
1004	    // Grouping can add (almost) as many separators as the number
1005	    // of digits + space is reserved for numeric base or sign.
1006	    _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1007								  * (__len + 1)
1008								  * 2));
1009	    _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
1010			 __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
1011	    __cs = __cs2 + 2;
1012	  }
1013
1014	// Complete Stage 1, prepend numeric base or sign.
1015	if (__builtin_expect(__dec, true))
1016	  {
1017	    // Decimal.
1018	    if (__v > 0)
1019	      {
1020		if (__flags & ios_base::showpos
1021		    && numeric_limits<_ValueT>::is_signed)
1022		  *--__cs = __lit[__num_base::_S_oplus], ++__len;
1023	      }
1024	    else if (__v)
1025	      *--__cs = __lit[__num_base::_S_ominus], ++__len;
1026	  }
1027	else if (__flags & ios_base::showbase && __v)
1028	  {
1029	    if (__basefield == ios_base::oct)
1030	      *--__cs = __lit[__num_base::_S_odigits], ++__len;
1031	    else
1032	      {
1033		// 'x' or 'X'
1034		const bool __uppercase = __flags & ios_base::uppercase;
1035		*--__cs = __lit[__num_base::_S_ox + __uppercase];
1036		// '0'
1037		*--__cs = __lit[__num_base::_S_odigits];
1038		__len += 2;
1039	      }
1040	  }
1041
1042	// Pad.
1043	const streamsize __w = __io.width();
1044	if (__w > static_cast<streamsize>(__len))
1045	  {
1046	    _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1047								  * __w));
1048	    _M_pad(__fill, __w, __io, __cs3, __cs, __len);
1049	    __cs = __cs3;
1050	  }
1051	__io.width(0);
1052
1053	// [22.2.2.2.2] Stage 4.
1054	// Write resulting, fully-formatted string to output iterator.
1055	return std::__write(__s, __cs, __len);
1056      }
1057
1058  template<typename _CharT, typename _OutIter>
1059    void
1060    num_put<_CharT, _OutIter>::
1061    _M_group_float(const char* __grouping, size_t __grouping_size,
1062		   _CharT __sep, const _CharT* __p, _CharT* __new,
1063		   _CharT* __cs, int& __len) const
1064    {
1065      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1066      // 282. What types does numpunct grouping refer to?
1067      // Add grouping, if necessary.
1068      const int __declen = __p ? __p - __cs : __len;
1069      _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
1070					 __grouping_size,
1071					 __cs, __cs + __declen);
1072
1073      // Tack on decimal part.
1074      int __newlen = __p2 - __new;
1075      if (__p)
1076	{
1077	  char_traits<_CharT>::copy(__p2, __p, __len - __declen);
1078	  __newlen += __len - __declen;
1079	}
1080      __len = __newlen;
1081    }
1082
1083  // The following code uses vsnprintf (or vsprintf(), when
1084  // _GLIBCXX_USE_C99 is not defined) to convert floating point values
1085  // for insertion into a stream.  An optimization would be to replace
1086  // them with code that works directly on a wide buffer and then use
1087  // __pad to do the padding.  It would be good to replace them anyway
1088  // to gain back the efficiency that C++ provides by knowing up front
1089  // the type of the values to insert.  Also, sprintf is dangerous
1090  // since may lead to accidental buffer overruns.  This
1091  // implementation follows the C++ standard fairly directly as
1092  // outlined in 22.2.2.2 [lib.locale.num.put]
1093  template<typename _CharT, typename _OutIter>
1094    template<typename _ValueT>
1095      _OutIter
1096      num_put<_CharT, _OutIter>::
1097      _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
1098		       _ValueT __v) const
1099      {
1100	typedef __numpunct_cache<_CharT>                __cache_type;
1101	__use_cache<__cache_type> __uc;
1102	const locale& __loc = __io._M_getloc();
1103	const __cache_type* __lc = __uc(__loc);
1104
1105	// Use default precision if out of range.
1106	const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision();
1107
1108	const int __max_digits = numeric_limits<_ValueT>::digits10;
1109
1110	// [22.2.2.2.2] Stage 1, numeric conversion to character.
1111	int __len;
1112	// Long enough for the max format spec.
1113	char __fbuf[16];
1114	__num_base::_S_format_float(__io, __fbuf, __mod);
1115
1116#ifdef _GLIBCXX_USE_C99
1117	// First try a buffer perhaps big enough (most probably sufficient
1118	// for non-ios_base::fixed outputs)
1119	int __cs_size = __max_digits * 3;
1120	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1121	__len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
1122				      __fbuf, __prec, __v);
1123
1124	// If the buffer was not large enough, try again with the correct size.
1125	if (__len >= __cs_size)
1126	  {
1127	    __cs_size = __len + 1;
1128	    __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1129	    __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
1130					  __fbuf, __prec, __v);
1131	  }
1132#else
1133	// Consider the possibility of long ios_base::fixed outputs
1134	const bool __fixed = __io.flags() & ios_base::fixed;
1135	const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
1136
1137	// The size of the output string is computed as follows.
1138	// ios_base::fixed outputs may need up to __max_exp + 1 chars
1139	// for the integer part + __prec chars for the fractional part
1140	// + 3 chars for sign, decimal point, '\0'. On the other hand,
1141	// for non-fixed outputs __max_digits * 2 + __prec chars are
1142	// largely sufficient.
1143	const int __cs_size = __fixed ? __max_exp + __prec + 4
1144	                              : __max_digits * 2 + __prec;
1145	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1146	__len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, 
1147				      __prec, __v);
1148#endif
1149
1150	// [22.2.2.2.2] Stage 2, convert to char_type, using correct
1151	// numpunct.decimal_point() values for '.' and adding grouping.
1152	const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1153	
1154	_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1155							     * __len));
1156	__ctype.widen(__cs, __cs + __len, __ws);
1157	
1158	// Replace decimal point.
1159	_CharT* __wp = 0;
1160	const char* __p = char_traits<char>::find(__cs, __len, '.');
1161	if (__p)
1162	  {
1163	    __wp = __ws + (__p - __cs);
1164	    *__wp = __lc->_M_decimal_point;
1165	  }
1166	
1167	// Add grouping, if necessary.
1168	// N.B. Make sure to not group things like 2e20, i.e., no decimal
1169	// point, scientific notation.
1170	if (__lc->_M_use_grouping
1171	    && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
1172				      && __cs[1] >= '0' && __cs[2] >= '0')))
1173	  {
1174	    // Grouping can add (almost) as many separators as the
1175	    // number of digits, but no more.
1176	    _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1177								  * __len * 2));
1178	    
1179	    streamsize __off = 0;
1180	    if (__cs[0] == '-' || __cs[0] == '+')
1181	      {
1182		__off = 1;
1183		__ws2[0] = __ws[0];
1184		__len -= 1;
1185	      }
1186	    
1187	    _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
1188			   __lc->_M_thousands_sep, __wp, __ws2 + __off,
1189			   __ws + __off, __len);
1190	    __len += __off;
1191	    
1192	    __ws = __ws2;
1193	  }
1194
1195	// Pad.
1196	const streamsize __w = __io.width();
1197	if (__w > static_cast<streamsize>(__len))
1198	  {
1199	    _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1200								  * __w));
1201	    _M_pad(__fill, __w, __io, __ws3, __ws, __len);
1202	    __ws = __ws3;
1203	  }
1204	__io.width(0);
1205	
1206	// [22.2.2.2.2] Stage 4.
1207	// Write resulting, fully-formatted string to output iterator.
1208	return std::__write(__s, __ws, __len);
1209      }
1210  
1211  template<typename _CharT, typename _OutIter>
1212    _OutIter
1213    num_put<_CharT, _OutIter>::
1214    do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
1215    {
1216      const ios_base::fmtflags __flags = __io.flags();
1217      if ((__flags & ios_base::boolalpha) == 0)
1218        {
1219          const long __l = __v;
1220          __s = _M_insert_int(__s, __io, __fill, __l);
1221        }
1222      else
1223        {
1224	  typedef __numpunct_cache<_CharT>              __cache_type;
1225	  __use_cache<__cache_type> __uc;
1226	  const locale& __loc = __io._M_getloc();
1227	  const __cache_type* __lc = __uc(__loc);
1228
1229	  const _CharT* __name = __v ? __lc->_M_truename
1230	                             : __lc->_M_falsename;
1231	  int __len = __v ? __lc->_M_truename_size
1232	                  : __lc->_M_falsename_size;
1233
1234	  const streamsize __w = __io.width();
1235	  if (__w > static_cast<streamsize>(__len))
1236	    {
1237	      _CharT* __cs
1238		= static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1239							* __w));
1240	      _M_pad(__fill, __w, __io, __cs, __name, __len);
1241	      __name = __cs;
1242	    }
1243	  __io.width(0);
1244	  __s = std::__write(__s, __name, __len);
1245	}
1246      return __s;
1247    }
1248
1249  template<typename _CharT, typename _OutIter>
1250    _OutIter
1251    num_put<_CharT, _OutIter>::
1252    do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
1253    { return _M_insert_int(__s, __io, __fill, __v); }
1254
1255  template<typename _CharT, typename _OutIter>
1256    _OutIter
1257    num_put<_CharT, _OutIter>::
1258    do_put(iter_type __s, ios_base& __io, char_type __fill,
1259           unsigned long __v) const
1260    { return _M_insert_int(__s, __io, __fill, __v); }
1261
1262#ifdef _GLIBCXX_USE_LONG_LONG
1263  template<typename _CharT, typename _OutIter>
1264    _OutIter
1265    num_put<_CharT, _OutIter>::
1266    do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const
1267    { return _M_insert_int(__s, __io, __fill, __v); }
1268
1269  template<typename _CharT, typename _OutIter>
1270    _OutIter
1271    num_put<_CharT, _OutIter>::
1272    do_put(iter_type __s, ios_base& __io, char_type __fill,
1273           unsigned long long __v) const
1274    { return _M_insert_int(__s, __io, __fill, __v); }
1275#endif
1276
1277  template<typename _CharT, typename _OutIter>
1278    _OutIter
1279    num_put<_CharT, _OutIter>::
1280    do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1281    { return _M_insert_float(__s, __io, __fill, char(), __v); }
1282
1283#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
1284  template<typename _CharT, typename _OutIter>
1285    _OutIter
1286    num_put<_CharT, _OutIter>::
1287    __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1288    { return _M_insert_float(__s, __io, __fill, char(), __v); }
1289#endif
1290
1291  template<typename _CharT, typename _OutIter>
1292    _OutIter
1293    num_put<_CharT, _OutIter>::
1294    do_put(iter_type __s, ios_base& __io, char_type __fill,
1295	   long double __v) const
1296    { return _M_insert_float(__s, __io, __fill, 'L', __v); }
1297
1298  template<typename _CharT, typename _OutIter>
1299    _OutIter
1300    num_put<_CharT, _OutIter>::
1301    do_put(iter_type __s, ios_base& __io, char_type __fill,
1302           const void* __v) const
1303    {
1304      const ios_base::fmtflags __flags = __io.flags();
1305      const ios_base::fmtflags __fmt = ~(ios_base::basefield
1306					 | ios_base::uppercase
1307					 | ios_base::internal);
1308      __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
1309
1310      __s = _M_insert_int(__s, __io, __fill,
1311			  reinterpret_cast<unsigned long>(__v));
1312      __io.flags(__flags);
1313      return __s;
1314    }
1315
1316  template<typename _CharT, typename _InIter>
1317    template<bool _Intl>
1318      _InIter
1319      money_get<_CharT, _InIter>::
1320      _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
1321		 ios_base::iostate& __err, string& __units) const
1322      {
1323	typedef char_traits<_CharT>			  __traits_type;
1324	typedef typename string_type::size_type	          size_type;	
1325	typedef money_base::part			  part;
1326	typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
1327	
1328	const locale& __loc = __io._M_getloc();
1329	const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1330
1331	__use_cache<__cache_type> __uc;
1332	const __cache_type* __lc = __uc(__loc);
1333	const char_type* __lit = __lc->_M_atoms;
1334
1335	// Deduced sign.
1336	bool __negative = false;
1337	// Sign size.
1338	size_type __sign_size = 0;
1339	// True if sign is mandatory.
1340	const bool __mandatory_sign = (__lc->_M_positive_sign_size
1341				       && __lc->_M_negative_sign_size);
1342	// String of grouping info from thousands_sep plucked from __units.
1343	string __grouping_tmp;
1344	if (__lc->_M_use_grouping)
1345	  __grouping_tmp.reserve(32);
1346	// Last position before the decimal point.
1347	int __last_pos = 0;
1348	// Separator positions, then, possibly, fractional digits.
1349	int __n = 0;
1350	// If input iterator is in a valid state.
1351	bool __testvalid = true;
1352	// Flag marking when a decimal point is found.
1353	bool __testdecfound = false;
1354
1355	// The tentative returned string is stored here.
1356	string __res;
1357	__res.reserve(32);
1358
1359	const char_type* __lit_zero = __lit + money_base::_S_zero;
1360	const money_base::pattern __p = __lc->_M_neg_format;
1361	for (int __i = 0; __i < 4 && __testvalid; ++__i)
1362	  {
1363	    const part __which = static_cast<part>(__p.field[__i]);
1364	    switch (__which)
1365	      {
1366	      case money_base::symbol:
1367		// According to 22.2.6.1.2, p2, symbol is required
1368		// if (__io.flags() & ios_base::showbase), otherwise
1369		// is optional and consumed only if other characters
1370		// are needed to complete the format.
1371		if (__io.flags() & ios_base::showbase || __sign_size > 1
1372		    || __i == 0
1373		    || (__i == 1 && (__mandatory_sign
1374				     || (static_cast<part>(__p.field[0])
1375					 == money_base::sign)
1376				     || (static_cast<part>(__p.field[2])
1377					 == money_base::space)))
1378		    || (__i == 2 && ((static_cast<part>(__p.field[3])
1379				      == money_base::value)
1380				     || __mandatory_sign
1381				     && (static_cast<part>(__p.field[3])
1382					 == money_base::sign))))
1383		  {
1384		    const size_type __len = __lc->_M_curr_symbol_size;
1385		    size_type __j = 0;
1386		    for (; __beg != __end && __j < __len
1387			   && *__beg == __lc->_M_curr_symbol[__j];
1388			 ++__beg, ++__j);
1389		    if (__j != __len
1390			&& (__j || __io.flags() & ios_base::showbase))
1391		      __testvalid = false;
1392		  }
1393		break;
1394	      case money_base::sign:
1395		// Sign might not exist, or be more than one character long.
1396		if (__lc->_M_positive_sign_size && __beg != __end
1397		    && *__beg == __lc->_M_positive_sign[0])
1398		  {
1399		    __sign_size = __lc->_M_positive_sign_size;
1400		    ++__beg;
1401		  }
1402		else if (__lc->_M_negative_sign_size && __beg != __end
1403			 && *__beg == __lc->_M_negative_sign[0])
1404		  {
1405		    __negative = true;
1406		    __sign_size = __lc->_M_negative_sign_size;
1407		    ++__beg;
1408		  }
1409		else if (__lc->_M_positive_sign_size
1410			 && !__lc->_M_negative_sign_size)
1411		  // "... if no sign is detected, the result is given the sign
1412		  // that corresponds to the source of the empty string"
1413		  __negative = true;
1414		else if (__mandatory_sign)
1415		  __testvalid = false;
1416		break;
1417	      case money_base::value:
1418		// Extract digits, remove and stash away the
1419		// grouping of found thousands separators.
1420		for (; __beg != __end; ++__beg)
1421		  {
1422		    const char_type __c = *__beg;
1423		    const char_type* __q = __traits_type::find(__lit_zero, 
1424							       10, __c);
1425		    if (__q != 0)
1426		      {
1427			__res += money_base::_S_atoms[__q - __lit];
1428			++__n;
1429		      }
1430		    else if (__c == __lc->_M_decimal_point 
1431			     && !__testdecfound)
1432		      {
1433			__last_pos = __n;
1434			__n = 0;
1435			__testdecfound = true;
1436		      }
1437		    else if (__lc->_M_use_grouping
1438			     && __c == __lc->_M_thousands_sep
1439			     && !__testdecfound)
1440		      {
1441			if (__n)
1442			  {
1443			    // Mark position for later analysis.
1444			    __grouping_tmp += static_cast<char>(__n);
1445			    __n = 0;
1446			  }
1447			else
1448			  {
1449			    __testvalid = false;
1450			    break;
1451			  }
1452		      }
1453		    else
1454		      break;
1455		  }
1456		if (__res.empty())
1457		  __testvalid = false;
1458		break;
1459	      case money_base::space:
1460		// At least one space is required.
1461		if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
1462		  ++__beg;
1463		else
1464		  __testvalid = false;
1465	      case money_base::none:
1466		// Only if not at the end of the pattern.
1467		if (__i != 3)
1468		  for (; __beg != __end
1469			 && __ctype.is(ctype_base::space, *__beg); ++__beg);
1470		break;
1471	      }
1472	  }
1473
1474	// Need to get the rest of the sign characters, if they exist.
1475	if (__sign_size > 1 && __testvalid)
1476	  {
1477	    const char_type* __sign = __negative ? __lc->_M_negative_sign
1478	                                         : __lc->_M_positive_sign;
1479	    size_type __i = 1;
1480	    for (; __beg != __end && __i < __sign_size
1481		   && *__beg == __sign[__i]; ++__beg, ++__i);
1482	    
1483	    if (__i != __sign_size)
1484	      __testvalid = false;
1485	  }
1486
1487	if (__testvalid)
1488	  {
1489	    // Strip leading zeros.
1490	    if (__res.size() > 1)
1491	      {
1492		const size_type __first = __res.find_first_not_of('0');
1493		const bool __only_zeros = __first == string::npos;
1494		if (__first)
1495		  __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
1496	      }
1497
1498	    // 22.2.6.1.2, p4
1499	    if (__negative && __res[0] != '0')
1500	      __res.insert(__res.begin(), '-');
1501	    
1502	    // Test for grouping fidelity.
1503	    if (__grouping_tmp.size())
1504	      {
1505		// Add the ending grouping.
1506		__grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
1507						                   : __n);
1508		if (!std::__verify_grouping(__lc->_M_grouping,
1509					    __lc->_M_grouping_size,
1510					    __grouping_tmp))
1511		  __err |= ios_base::failbit;
1512	      }
1513	    
1514	    // Iff not enough digits were supplied after the decimal-point.
1515	    if (__testdecfound && __lc->_M_frac_digits > 0
1516		&& __n != __lc->_M_frac_digits)
1517	      __testvalid = false;
1518	  }
1519	
1520	// Iff valid sequence is not recognized.
1521	if (!__testvalid)
1522	  __err |= ios_base::failbit;
1523	else
1524	  __units.swap(__res);
1525	
1526	// Iff no more characters are available.
1527	if (__beg == __end)
1528	  __err |= ios_base::eofbit;
1529	return __beg;
1530      }
1531
1532#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
1533  template<typename _CharT, typename _InIter>
1534    _InIter
1535    money_get<_CharT, _InIter>::
1536    __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1537	     ios_base::iostate& __err, double& __units) const
1538    {
1539      string __str;
1540      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
1541                     : _M_extract<false>(__beg, __end, __io, __err, __str);
1542      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
1543      return __beg;
1544    }
1545#endif
1546
1547  template<typename _CharT, typename _InIter>
1548    _InIter
1549    money_get<_CharT, _InIter>::
1550    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1551	   ios_base::iostate& __err, long double& __units) const
1552    {
1553      string __str;
1554      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
1555	             : _M_extract<false>(__beg, __end, __io, __err, __str);
1556      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
1557      return __beg;
1558    }
1559
1560  template<typename _CharT, typename _InIter>
1561    _InIter
1562    money_get<_CharT, _InIter>::
1563    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1564	   ios_base::iostate& __err, string_type& __digits) const
1565    {
1566      typedef typename string::size_type                  size_type;
1567
1568      const locale& __loc = __io._M_getloc();
1569      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1570
1571      string __str;
1572      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
1573	             : _M_extract<false>(__beg, __end, __io, __err, __str);
1574      const size_type __len = __str.size();
1575      if (__len)
1576	{
1577	  __digits.resize(__len);
1578	  __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]);
1579	}
1580      return __beg;
1581    }
1582
1583  template<typename _CharT, typename _OutIter>
1584    template<bool _Intl>
1585      _OutIter
1586      money_put<_CharT, _OutIter>::
1587      _M_insert(iter_type __s, ios_base& __io, char_type __fill,
1588		const string_type& __digits) const
1589      {
1590	typedef typename string_type::size_type	          size_type;
1591	typedef money_base::part                          part;
1592	typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
1593      
1594	const locale& __loc = __io._M_getloc();
1595	const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1596
1597	__use_cache<__cache_type> __uc;
1598	const __cache_type* __lc = __uc(__loc);
1599	const char_type* __lit = __lc->_M_atoms;
1600
1601	// Determine if negative or positive formats are to be used, and
1602	// discard leading negative_sign if it is present.
1603	const char_type* __beg = __digits.data();
1604
1605	money_base::pattern __p;
1606	const char_type* __sign;
1607	size_type __sign_size;
1608	if (!(*__beg == __lit[money_base::_S_minus]))
1609	  {
1610	    __p = __lc->_M_pos_format;
1611	    __sign = __lc->_M_positive_sign;
1612	    __sign_size = __lc->_M_positive_sign_size;
1613	  }
1614	else
1615	  {
1616	    __p = __lc->_M_neg_format;
1617	    __sign = __lc->_M_negative_sign;
1618	    __sign_size = __lc->_M_negative_sign_size;
1619	    if (__digits.size())
1620	      ++__beg;
1621	  }
1622       
1623	// Look for valid numbers in the ctype facet within input digits.
1624	size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
1625					   __beg + __digits.size()) - __beg;
1626	if (__len)
1627	  {
1628	    // Assume valid input, and attempt to format.
1629	    // Break down input numbers into base components, as follows:
1630	    //   final_value = grouped units + (decimal point) + (digits)
1631	    string_type __value;
1632	    __value.reserve(2 * __len);
1633
1634	    // Add thousands separators to non-decimal digits, per
1635	    // grouping rules.
1636	    long __paddec = __len - __lc->_M_frac_digits;
1637	    if (__paddec > 0)
1638  	      {
1639		if (__lc->_M_frac_digits < 0)
1640		  __paddec = __len;
1641  		if (__lc->_M_grouping_size)
1642  		  {
1643		    __value.assign(2 * __paddec, char_type());
1644 		    _CharT* __vend = 
1645		      std::__add_grouping(&__value[0], __lc->_M_thousands_sep,
1646					  __lc->_M_grouping,
1647					  __lc->_M_grouping_size,
1648					  __beg, __beg + __paddec);
1649		    __value.erase(__vend - &__value[0]);
1650  		  }
1651  		else
1652		  __value.assign(__beg, __paddec);
1653	      }
1654
1655	    // Deal with decimal point, decimal digits.
1656	    if (__lc->_M_frac_digits > 0)
1657	      {
1658		__value += __lc->_M_decimal_point;
1659		if (__paddec >= 0)
1660		  __value.append(__beg + __paddec, __lc->_M_frac_digits);
1661		else
1662		  {
1663		    // Have to pad zeros in the decimal position.
1664		    __value.append(-__paddec, __lit[money_base::_S_zero]);
1665		    __value.append(__beg, __len);
1666		  }
1667  	      }
1668  
1669	    // Calculate length of resulting string.
1670	    const ios_base::fmtflags __f = __io.flags() 
1671	                                   & ios_base::adjustfield;
1672	    __len = __value.size() + __sign_size;
1673	    __len += ((__io.flags() & ios_base::showbase)
1674		      ? __lc->_M_curr_symbol_size : 0);
1675
1676	    string_type __res;
1677	    __res.reserve(2 * __len);
1678	    
1679	    const size_type __width = static_cast<size_type>(__io.width());  
1680	    const bool __testipad = (__f == ios_base::internal
1681				     && __len < __width);
1682	    // Fit formatted digits into the required pattern.
1683	    for (int __i = 0; __i < 4; ++__i)
1684	      {
1685		const part __which = static_cast<part>(__p.field[__i]);
1686		switch (__which)
1687		  {
1688		  case money_base::symbol:
1689		    if (__io.flags() & ios_base::showbase)
1690		      __res.append(__lc->_M_curr_symbol,
1691				   __lc->_M_curr_symbol_size);
1692		    break;
1693		  case money_base::sign:
1694		    // Sign might not exist, or be more than one
1695		    // charater long. In that case, add in the rest
1696		    // below.
1697		    if (__sign_size)
1698		      __res += __sign[0];
1699		    break;
1700		  case money_base::value:
1701		    __res += __value;
1702		    break;
1703		  case money_base::space:
1704		    // At least one space is required, but if internal
1705		    // formatting is required, an arbitrary number of
1706		    // fill spaces will be necessary.
1707		    if (__testipad)
1708		      __res.append(__width - __len, __fill);
1709		    else
1710		      __res += __fill;
1711		    break;
1712		  case money_base::none:
1713		    if (__testipad)
1714		      __res.append(__width - __len, __fill);
1715		    break;
1716		  }
1717	      }
1718	    
1719	    // Special case of multi-part sign parts.
1720	    if (__sign_size > 1)
1721	      __res.append(__sign + 1, __sign_size - 1);
1722	    
1723	    // Pad, if still necessary.
1724	    __len = __res.size();
1725	    if (__width > __len)
1726	      {
1727		if (__f == ios_base::left)
1728		  // After.
1729		  __res.append(__width - __len, __fill);
1730		else
1731		  // Before.
1732		  __res.insert(0, __width - __len, __fill);
1733		__len = __width;
1734	      }
1735	    
1736	    // Write resulting, fully-formatted string to output iterator.
1737	    __s = std::__write(__s, __res.data(), __len);
1738	  }
1739	__io.width(0);
1740	return __s;    
1741      }
1742
1743#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
1744  template<typename _CharT, typename _OutIter>
1745    _OutIter
1746    money_put<_CharT, _OutIter>::
1747    __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1748	     double __units) const
1749    { return this->do_put(__s, __intl, __io, __fill, (long double) __units); }
1750#endif
1751
1752  template<typename _CharT, typename _OutIter>
1753    _OutIter
1754    money_put<_CharT, _OutIter>::
1755    do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1756	   long double __units) const
1757    {
1758      const locale __loc = __io.getloc();
1759      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1760#ifdef _GLIBCXX_USE_C99
1761      // First try a buffer perhaps big enough.
1762      int __cs_size = 64;
1763      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1764      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1765      // 328. Bad sprintf format modifier in money_put<>::do_put()
1766      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
1767					"%.*Lf", 0, __units);
1768      // If the buffer was not large enough, try again with the correct size.
1769      if (__len >= __cs_size)
1770	{
1771	  __cs_size = __len + 1;
1772	  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1773	  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
1774					"%.*Lf", 0, __units);
1775	}
1776#else
1777      // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
1778      const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
1779      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1780      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 
1781					0, __units);
1782#endif
1783      string_type __digits(__len, char_type());
1784      __ctype.widen(__cs, __cs + __len, &__digits[0]);
1785      return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
1786	            : _M_insert<false>(__s, __io, __fill, __digits);
1787    }
1788
1789  template<typename _CharT, typename _OutIter>
1790    _OutIter
1791    money_put<_CharT, _OutIter>::
1792    do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1793	   const string_type& __digits) const
1794    { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
1795	            : _M_insert<false>(__s, __io, __fill, __digits); }
1796
1797_GLIBCXX_END_LDBL_NAMESPACE
1798
1799  // NB: Not especially useful. Without an ios_base object or some
1800  // kind of locale reference, we are left clawing at the air where
1801  // the side of the mountain used to be...
1802  template<typename _CharT, typename _InIter>
1803    time_base::dateorder
1804    time_get<_CharT, _InIter>::do_date_order() const
1805    { return time_base::no_order; }
1806
1807  // Expand a strftime format string and parse it.  E.g., do_get_date() may
1808  // pass %m/%d/%Y => extracted characters.
1809  template<typename _CharT, typename _InIter>
1810    _InIter
1811    time_get<_CharT, _InIter>::
1812    _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
1813			  ios_base::iostate& __err, tm* __tm,
1814			  const _CharT* __format) const
1815    {
1816      const locale& __loc = __io._M_getloc();
1817      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1818      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1819      const size_t __len = char_traits<_CharT>::length(__format);
1820
1821      ios_base::iostate __tmperr = ios_base::goodbit;
1822      for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i)
1823	{
1824	  if (__ctype.narrow(__format[__i], 0) == '%')
1825	    {
1826	      // Verify valid formatting code, attempt to extract.
1827	      char __c = __ctype.narrow(__format[++__i], 0);
1828	      int __mem = 0;
1829	      if (__c == 'E' || __c == 'O')
1830		__c = __ctype.narrow(__format[++__i], 0);
1831	      switch (__c)
1832		{
1833		  const char* __cs;
1834		  _CharT __wcs[10];
1835		case 'a':
1836		  // Abbreviated weekday name [tm_wday]
1837		  const char_type*  __days1[7];
1838		  __tp._M_days_abbreviated(__days1);
1839		  __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
1840					  7, __io, __tmperr);
1841		  break;
1842		case 'A':
1843		  // Weekday name [tm_wday].
1844		  const char_type*  __days2[7];
1845		  __tp._M_days(__days2);
1846		  __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
1847					  7, __io, __tmperr);
1848		  break;
1849		case 'h':
1850		case 'b':
1851		  // Abbreviated month name [tm_mon]
1852		  const char_type*  __months1[12];
1853		  __tp._M_months_abbreviated(__months1);
1854		  __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 
1855					  __months1, 12, __io, __tmperr);
1856		  break;
1857		case 'B':
1858		  // Month name [tm_mon].
1859		  const char_type*  __months2[12];
1860		  __tp._M_months(__months2);
1861		  __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 
1862					  __months2, 12, __io, __tmperr);
1863		  break;
1864		case 'c':
1865		  // Default time and date representation.
1866		  const char_type*  __dt[2];
1867		  __tp._M_date_time_formats(__dt);
1868		  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
1869						__tm, __dt[0]);
1870		  break;
1871		case 'd':
1872		  // Day [01, 31]. [tm_mday]
1873		  __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
1874					 __io, __tmperr);
1875		  break;
1876		case 'e':
1877		  // Day [1, 31], with single digits preceded by
1878		  // space. [tm_mday]
1879		  if (__ctype.is(ctype_base::space, *__beg))
1880		    __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
1881					   1, __io, __tmperr);
1882		  else
1883		    __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
1884					   2, __io, __tmperr);
1885		  break;
1886		case 'D':
1887		  // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1888		  __cs = "%m/%d/%y";
1889		  __ctype.widen(__cs, __cs + 9, __wcs);
1890		  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
1891						__tm, __wcs);
1892		  break;
1893		case 'H':
1894		  // Hour [00, 23]. [tm_hour]
1895		  __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1896					 __io, __tmperr);
1897		  break;
1898		case 'I':
1899		  // Hour [01, 12]. [tm_hour]
1900		  __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
1901					 __io, __tmperr);
1902		  break;
1903		case 'm':
1904		  // Month [01, 12]. [tm_mon]
1905		  __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 
1906					 __io, __tmperr);
1907		  if (!__tmperr)
1908		    __tm->tm_mon = __mem - 1;
1909		  break;
1910		case 'M':
1911		  // Minute [00, 59]. [tm_min]
1912		  __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1913					 __io, __tmperr);
1914		  break;
1915		case 'n':
1916		  if (__ctype.narrow(*__beg, 0) == '\n')
1917		    ++__beg;
1918		  else
1919		    __tmperr |= ios_base::failbit;
1920		  break;
1921		case 'R':
1922		  // Equivalent to (%H:%M).
1923		  __cs = "%H:%M";
1924		  __ctype.widen(__cs, __cs + 6, __wcs);
1925		  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
1926						__tm, __wcs);
1927		  break;
1928		case 'S':
1929		  // Seconds. [tm_sec]
1930		  // [00, 60] in C99 (one leap-second), [00, 61] in C89.
1931#ifdef _GLIBCXX_USE_C99
1932		  __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
1933#else
1934		  __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
1935#endif
1936					 __io, __tmperr);
1937		  break;
1938		case 't':
1939		  if (__ctype.narrow(*__beg, 0) == '\t')
1940		    ++__beg;
1941		  else
1942		    __tmperr |= ios_base::failbit;
1943		  break;
1944		case 'T':
1945		  // Equivalent to (%H:%M:%S).
1946		  __cs = "%H:%M:%S";
1947		  __ctype.widen(__cs, __cs + 9, __wcs);
1948		  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
1949						__tm, __wcs);
1950		  break;
1951		case 'x':
1952		  // Locale's date.
1953		  const char_type*  __dates[2];
1954		  __tp._M_date_formats(__dates);
1955		  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
1956						__tm, __dates[0]);
1957		  break;
1958		case 'X':
1959		  // Locale's time.
1960		  const char_type*  __times[2];
1961		  __tp._M_time_formats(__times);
1962		  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
1963						__tm, __times[0]);
1964		  break;
1965		case 'y':
1966		case 'C': // C99
1967		  // Two digit year. [tm_year]
1968		  __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
1969					 __io, __tmperr);
1970		  break;
1971		case 'Y':
1972		  // Year [1900). [tm_year]
1973		  __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
1974					 __io, __tmperr);
1975		  if (!__tmperr)
1976		    __tm->tm_year = __mem - 1900;
1977		  break;
1978		case 'Z':
1979		  // Timezone info.
1980		  if (__ctype.is(ctype_base::upper, *__beg))
1981		    {
1982		      int __tmp;
1983		      __beg = _M_extract_name(__beg, __end, __tmp,
1984				       __timepunct_cache<_CharT>::_S_timezones,
1985					      14, __io, __tmperr);
1986
1987		      // GMT requires special effort.
1988		      if (__beg != __end && !__tmperr && __tmp == 0
1989			  && (*__beg == __ctype.widen('-')
1990			      || *__beg == __ctype.widen('+')))
1991			{
1992			  __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1993						 __io, __tmperr);
1994			  __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1995						 __io, __tmperr);
1996			}
1997		    }
1998		  else
1999		    __tmperr |= ios_base::failbit;
2000		  break;
2001		default:
2002		  // Not recognized.
2003		  __tmperr |= ios_base::failbit;
2004		}
2005	    }
2006	  else
2007	    {
2008	      // Verify format and input match, extract and discard.
2009	      if (__format[__i] == *__beg)
2010		++__beg;
2011	      else
2012		__tmperr |= ios_base::failbit;
2013	    }
2014	}
2015
2016      if (__tmperr)
2017	__err |= ios_base::failbit;
2018  
2019      return __beg;
2020    }
2021
2022  template<typename _CharT, typename _InIter>
2023    _InIter
2024    time_get<_CharT, _InIter>::
2025    _M_extract_num(iter_type __beg, iter_type __end, int& __member,
2026		   int __min, int __max, size_t __len,
2027		   ios_base& __io, ios_base::iostate& __err) const
2028    {
2029      const locale& __loc = __io._M_getloc();
2030      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2031
2032      // As-is works for __len = 1, 2, 4, the values actually used.
2033      int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
2034
2035      ++__min;
2036      size_t __i = 0;
2037      int __value = 0;
2038      for (; __beg != __end && __i < __len; ++__beg, ++__i)
2039	{
2040	  const char __c = __ctype.narrow(*__beg, '*');
2041	  if (__c >= '0' && __c <= '9')
2042	    {
2043	      __value = __value * 10 + (__c - '0');
2044	      const int __valuec = __value * __mult;
2045	      if (__valuec > __max || __valuec + __mult < __min)
2046		break;
2047	      __mult /= 10;
2048	    }
2049	  else
2050	    break;
2051	}
2052      if (__i == __len)
2053	__member = __value;
2054      else
2055	__err |= ios_base::failbit;
2056
2057      return __beg;
2058    }
2059
2060  // Assumptions:
2061  // All elements in __names are unique.
2062  template<typename _CharT, typename _InIter>
2063    _InIter
2064    time_get<_CharT, _InIter>::
2065    _M_extract_name(iter_type __beg, iter_type __end, int& __member,
2066		    const _CharT** __names, size_t __indexlen,
2067		    ios_base& __io, ios_base::iostate& __err) const
2068    {
2069      typedef char_traits<_CharT>		__traits_type;
2070      const locale& __loc = __io._M_getloc();
2071      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2072
2073      int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
2074							  * __indexlen));
2075      size_t __nmatches = 0;
2076      size_t __pos = 0;
2077      bool __testvalid = true;
2078      const char_type* __name;
2079
2080      // Look for initial matches.
2081      // NB: Some of the locale data is in the form of all lowercase
2082      // names, and some is in the form of initially-capitalized
2083      // names. Look for both.
2084      if (__beg != __end)
2085	{
2086	  const char_type __c = *__beg;
2087	  for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
2088	    if (__c == __names[__i1][0]
2089		|| __c == __ctype.toupper(__names[__i1][0]))
2090	      __matches[__nmatches++] = __i1;
2091	}
2092
2093      while (__nmatches > 1)
2094	{
2095	  // Find smallest matching string.
2096	  size_t __minlen = __traits_type::length(__names[__matches[0]]);
2097	  for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
2098	    __minlen = std::min(__minlen,
2099			      __traits_type::length(__names[__matches[__i2]]));
2100	  ++__beg, ++__pos;
2101	  if (__pos < __minlen && __beg != __end)
2102	    for (size_t __i3 = 0; __i3 < __nmatches;)
2103	      {
2104		__name = __names[__matches[__i3]];
2105		if (!(__name[__pos] == *__beg))
2106		  __matches[__i3] = __matches[--__nmatches];
2107		else
2108		  ++__i3;
2109	      }
2110	  else
2111	    break;
2112	}
2113
2114      if (__nmatches == 1)
2115	{
2116	  // Make sure found name is completely extracted.
2117	  ++__beg, ++__pos;
2118	  __name = __names[__matches[0]];
2119	  const size_t __len = __traits_type::length(__name);
2120	  while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
2121	    ++__beg, ++__pos;
2122
2123	  if (__len == __pos)
2124	    __member = __matches[0];
2125	  else
2126	    __testvalid = false;
2127	}
2128      else
2129	__testvalid = false;
2130      if (!__testvalid)
2131	__err |= ios_base::failbit;
2132
2133      return __beg;
2134    }
2135
2136  template<typename _CharT, typename _InIter>
2137    _InIter
2138    time_get<_CharT, _InIter>::
2139    do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
2140		ios_base::iostate& __err, tm* __tm) const
2141    {
2142      const locale& __loc = __io._M_getloc();
2143      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2144      const char_type*  __times[2];
2145      __tp._M_time_formats(__times);
2146      __beg = _M_extract_via_format(__beg, __end, __io, __err, 
2147				    __tm, __times[0]);
2148      if (__beg == __end)
2149	__err |= ios_base::eofbit;
2150      return __beg;
2151    }
2152
2153  template<typename _CharT, typename _InIter>
2154    _InIter
2155    time_get<_CharT, _InIter>::
2156    do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
2157		ios_base::iostate& __err, tm* __tm) const
2158    {
2159      const locale& __loc = __io._M_getloc();
2160      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2161      const char_type*  __dates[2];
2162      __tp._M_date_formats(__dates);
2163      __beg = _M_extract_via_format(__beg, __end, __io, __err, 
2164				    __tm, __dates[0]);
2165      if (__beg == __end)
2166	__err |= ios_base::eofbit;
2167      return __beg;
2168    }
2169
2170  template<typename _CharT, typename _InIter>
2171    _InIter
2172    time_get<_CharT, _InIter>::
2173    do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
2174		   ios_base::iostate& __err, tm* __tm) const
2175    {
2176      typedef char_traits<_CharT>		__traits_type;
2177      const locale& __loc = __io._M_getloc();
2178      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2179      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2180      const char_type*  __days[7];
2181      __tp._M_days_abbreviated(__days);
2182      int __tmpwday;
2183      ios_base::iostate __tmperr = ios_base::goodbit;
2184      __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7,
2185			      __io, __tmperr);
2186
2187      // Check to see if non-abbreviated name exists, and extract.
2188      // NB: Assumes both _M_days and _M_days_abbreviated organized in
2189      // exact same order, first to last, such that the resulting
2190      // __days array with the same index points to a day, and that
2191      // day's abbreviated form.
2192      // NB: Also assumes that an abbreviated name is a subset of the name.
2193      if (!__tmperr && __beg != __end)
2194	{
2195	  size_t __pos = __traits_type::length(__days[__tmpwday]);
2196	  __tp._M_days(__days);
2197	  const char_type* __name = __days[__tmpwday];
2198	  if (__name[__pos] == *__beg)
2199	    {
2200	      // Extract the rest of it.
2201	      const size_t __len = __traits_type::length(__name);
2202	      while (__pos < __len && __beg != __end
2203		     && __name[__pos] == *__beg)
2204		++__beg, ++__pos;
2205	      if (__len != __pos)
2206		__tmperr |= ios_base::failbit;
2207	    }
2208	}
2209      if (!__tmperr)
2210	__tm->tm_wday = __tmpwday;
2211      else
2212	__err |= ios_base::failbit;
2213
2214      if (__beg == __end)
2215	__err |= ios_base::eofbit;
2216      return __beg;
2217     }
2218
2219  template<typename _CharT, typename _InIter>
2220    _InIter
2221    time_get<_CharT, _InIter>::
2222    do_get_monthname(iter_type __beg, iter_type __end,
2223                     ios_base& __io, ios_base::iostate& __err, tm* __tm) const
2224    {
2225      typedef char_traits<_CharT>		__traits_type;
2226      const locale& __loc = __io._M_getloc();
2227      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2228      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2229      const char_type*  __months[12];
2230      __tp._M_months_abbreviated(__months);
2231      int __tmpmon;
2232      ios_base::iostate __tmperr = ios_base::goodbit;
2233      __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, 
2234			      __io, __tmperr);
2235
2236      // Check to see if non-abbreviated name exists, and extract.
2237      // NB: Assumes both _M_months and _M_months_abbreviated organized in
2238      // exact same order, first to last, such that the resulting
2239      // __months array with the same index points to a month, and that
2240      // month's abbreviated form.
2241      // NB: Also assumes that an abbreviated name is a subset of the name.
2242      if (!__tmperr && __beg != __end)
2243	{
2244	  size_t __pos = __traits_type::length(__months[__tmpmon]);
2245	  __tp._M_months(__months);
2246	  const char_type* __name = __months[__tmpmon];
2247	  if (__name[__pos] == *__beg)
2248	    {
2249	      // Extract the rest of it.
2250	      const size_t __len = __traits_type::length(__name);
2251	      while (__pos < __len && __beg != __end
2252		     && __name[__pos] == *__beg)
2253		++__beg, ++__pos;
2254	      if (__len != __pos)
2255		__tmperr |= ios_base::failbit;
2256	    }
2257	}
2258      if (!__tmperr)
2259	__tm->tm_mon = __tmpmon;
2260      else
2261	__err |= ios_base::failbit;
2262
2263      if (__beg == __end)
2264	__err |= ios_base::eofbit;
2265      return __beg;
2266    }
2267
2268  template<typename _CharT, typename _InIter>
2269    _InIter
2270    time_get<_CharT, _InIter>::
2271    do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
2272		ios_base::iostate& __err, tm* __tm) const
2273    {
2274      const locale& __loc = __io._M_getloc();
2275      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2276
2277      size_t __i = 0;
2278      int __value = 0;
2279      for (; __beg != __end && __i < 4; ++__beg, ++__i)
2280	{
2281	  const char __c = __ctype.narrow(*__beg, '*');
2282	  if (__c >= '0' && __c <= '9')
2283	    __value = __value * 10 + (__c - '0');
2284	  else
2285	    break;
2286	}
2287      if (__i == 2 || __i == 4)
2288	__tm->tm_year = __i == 2 ? __value : __value - 1900;
2289      else
2290	__err |= ios_base::failbit;
2291
2292      if (__beg == __end)
2293	__err |= ios_base::eofbit;
2294      return __beg;
2295    }
2296
2297  template<typename _CharT, typename _OutIter>
2298    _OutIter
2299    time_put<_CharT, _OutIter>::
2300    put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
2301	const _CharT* __beg, const _CharT* __end) const
2302    {
2303      const locale& __loc = __io._M_getloc();
2304      ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
2305      for (; __beg != __end; ++__beg)
2306	if (__ctype.narrow(*__beg, 0) != '%')
2307	  {
2308	    *__s = *__beg;
2309	    ++__s;
2310	  }
2311	else if (++__beg != __end)
2312	  {
2313	    char __format;
2314	    char __mod = 0;
2315	    const char __c = __ctype.narrow(*__beg, 0);
2316	    if (__c != 'E' && __c != 'O')
2317	      __format = __c;
2318	    else if (++__beg != __end)
2319	      {
2320		__mod = __c;
2321		__format = __ctype.narrow(*__beg, 0);
2322	      }
2323	    else
2324	      break;
2325	    __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
2326	  }
2327	else
2328	  break;
2329      return __s;
2330    }
2331
2332  template<typename _CharT, typename _OutIter>
2333    _OutIter
2334    time_put<_CharT, _OutIter>::
2335    do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
2336	   char __format, char __mod) const
2337    {
2338      const locale& __loc = __io._M_getloc();
2339      ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
2340      __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
2341
2342      // NB: This size is arbitrary. Should this be a data member,
2343      // initialized at construction?
2344      const size_t __maxlen = 128;
2345      char_type* __res = 
2346       static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
2347
2348      // NB: In IEE 1003.1-200x, and perhaps other locale models, it
2349      // is possible that the format character will be longer than one
2350      // character. Possibilities include 'E' or 'O' followed by a
2351      // format character: if __mod is not the default argument, assume
2352      // it's a valid modifier.
2353      char_type __fmt[4];
2354      __fmt[0] = __ctype.widen('%');
2355      if (!__mod)
2356	{
2357	  __fmt[1] = __format;
2358	  __fmt[2] = char_type();
2359	}
2360      else
2361	{
2362	  __fmt[1] = __mod;
2363	  __fmt[2] = __format;
2364	  __fmt[3] = char_type();
2365	}
2366
2367      __tp._M_put(__res, __maxlen, __fmt, __tm);
2368
2369      // Write resulting, fully-formatted string to output iterator.
2370      return std::__write(__s, __res, char_traits<char_type>::length(__res));
2371    }
2372
2373  // Generic version does nothing.
2374  template<typename _CharT>
2375    int
2376    collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
2377    { return 0; }
2378
2379  // Generic version does nothing.
2380  template<typename _CharT>
2381    size_t
2382    collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
2383    { return 0; }
2384
2385  template<typename _CharT>
2386    int
2387    collate<_CharT>::
2388    do_compare(const _CharT* __lo1, const _CharT* __hi1,
2389	       const _CharT* __lo2, const _CharT* __hi2) const
2390    {
2391      // strcoll assumes zero-terminated strings so we make a copy
2392      // and then put a zero at the end.
2393      const string_type __one(__lo1, __hi1);
2394      const string_type __two(__lo2, __hi2);
2395
2396      const _CharT* __p = __one.c_str();
2397      const _CharT* __pend = __one.data() + __one.length();
2398      const _CharT* __q = __two.c_str();
2399      const _CharT* __qend = __two.data() + __two.length();
2400
2401      // strcoll stops when it sees a nul character so we break
2402      // the strings into zero-terminated substrings and pass those
2403      // to strcoll.
2404      for (;;)
2405	{
2406	  const int __res = _M_compare(__p, __q);
2407	  if (__res)
2408	    return __res;
2409
2410	  __p += char_traits<_CharT>::length(__p);
2411	  __q += char_traits<_CharT>::length(__q);
2412	  if (__p == __pend && __q == __qend)
2413	    return 0;
2414	  else if (__p == __pend)
2415	    return -1;
2416	  else if (__q == __qend)
2417	    return 1;
2418
2419	  __p++;
2420	  __q++;
2421	}
2422    }
2423
2424  template<typename _CharT>
2425    typename collate<_CharT>::string_type
2426    collate<_CharT>::
2427    do_transform(const _CharT* __lo, const _CharT* __hi) const
2428    {
2429      string_type __ret;
2430
2431      // strxfrm assumes zero-terminated strings so we make a copy
2432      const string_type __str(__lo, __hi);
2433
2434      const _CharT* __p = __str.c_str();
2435      const _CharT* __pend = __str.data() + __str.length();
2436
2437      size_t __len = (__hi - __lo) * 2;
2438
2439      _CharT* __c = new _CharT[__len];
2440
2441      try
2442	{
2443	  // strxfrm stops when it sees a nul character so we break
2444	  // the string into zero-terminated substrings and pass those
2445	  // to strxfrm.
2446	  for (;;)
2447	    {
2448	      // First try a buffer perhaps big enough.
2449	      size_t __res = _M_transform(__c, __p, __len);
2450	      // If the buffer was not large enough, try again with the
2451	      // correct size.
2452	      if (__res >= __len)
2453		{
2454		  __len = __res + 1;
2455		  delete [] __c, __c = 0;
2456		  __c = new _CharT[__len];
2457		  __res = _M_transform(__c, __p, __len);
2458		}
2459
2460	      __ret.append(__c, __res);
2461	      __p += char_traits<_CharT>::length(__p);
2462	      if (__p == __pend)
2463		break;
2464
2465	      __p++;
2466	      __ret.push_back(_CharT());
2467	    }
2468	}
2469      catch(...)
2470	{
2471	  delete [] __c;
2472	  __throw_exception_again;
2473	}
2474
2475      delete [] __c;
2476
2477      return __ret;
2478    }
2479
2480  template<typename _CharT>
2481    long
2482    collate<_CharT>::
2483    do_hash(const _CharT* __lo, const _CharT* __hi) const
2484    {
2485      unsigned long __val = 0;
2486      for (; __lo < __hi; ++__lo)
2487	__val = *__lo + ((__val << 7) |
2488		       (__val >> (numeric_limits<unsigned long>::digits - 7)));
2489      return static_cast<long>(__val);
2490    }
2491
2492  // Construct correctly padded string, as per 22.2.2.2.2
2493  // Assumes
2494  // __newlen > __oldlen
2495  // __news is allocated for __newlen size
2496  // Used by both num_put and ostream inserters: if __num,
2497  // internal-adjusted objects are padded according to the rules below
2498  // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
2499  // ones are.
2500
2501  // NB: Of the two parameters, _CharT can be deduced from the
2502  // function arguments. The other (_Traits) has to be explicitly specified.
2503  template<typename _CharT, typename _Traits>
2504    void
2505    __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
2506				   _CharT* __news, const _CharT* __olds,
2507				   const streamsize __newlen,
2508				   const streamsize __oldlen, const bool __num)
2509    {
2510      const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
2511      const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
2512
2513      // Padding last.
2514      if (__adjust == ios_base::left)
2515	{
2516	  _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen);
2517	  _Traits::assign(__news + __oldlen, __plen, __fill);
2518	  return;
2519	}
2520
2521      size_t __mod = 0;
2522      if (__adjust == ios_base::internal && __num)
2523	{
2524	  // Pad after the sign, if there is one.
2525	  // Pad after 0[xX], if there is one.
2526	  // Who came up with these rules, anyway? Jeeze.
2527          const locale& __loc = __io._M_getloc();
2528	  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2529
2530	  const bool __testsign = (__ctype.widen('-') == __olds[0]
2531				   || __ctype.widen('+') == __olds[0]);
2532	  const bool __testhex = (__ctype.widen('0') == __olds[0]
2533				  && __oldlen > 1
2534				  && (__ctype.widen('x') == __olds[1]
2535				      || __ctype.widen('X') == __olds[1]));
2536	  if (__testhex)
2537	    {
2538	      __news[0] = __olds[0];
2539	      __news[1] = __olds[1];
2540	      __mod = 2;
2541	      __news += 2;
2542	    }
2543	  else if (__testsign)
2544	    {
2545	      __news[0] = __olds[0];
2546	      __mod = 1;
2547	      ++__news;
2548	    }
2549	  // else Padding first.
2550	}
2551      _Traits::assign(__news, __plen, __fill);
2552      _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod),
2553		    __oldlen - __mod);
2554    }
2555
2556  bool
2557  __verify_grouping(const char* __grouping, size_t __grouping_size,
2558		    const string& __grouping_tmp)
2559  {
2560    const size_t __n = __grouping_tmp.size() - 1;
2561    const size_t __min = std::min(__n, size_t(__grouping_size - 1));
2562    size_t __i = __n;
2563    bool __test = true;
2564    
2565    // Parsed number groupings have to match the
2566    // numpunct::grouping string exactly, starting at the
2567    // right-most point of the parsed sequence of elements ...
2568    for (size_t __j = 0; __j < __min && __test; --__i, ++__j)
2569      __test = __grouping_tmp[__i] == __grouping[__j];
2570    for (; __i && __test; --__i)
2571      __test = __grouping_tmp[__i] == __grouping[__min];
2572    // ... but the first parsed grouping can be <= numpunct
2573    // grouping (only do the check if the numpunct char is > 0
2574    // because <= 0 means any size is ok).
2575    if (static_cast<signed char>(__grouping[__min]) > 0)
2576      __test &= __grouping_tmp[0] <= __grouping[__min];
2577    return __test;
2578  }
2579
2580  template<typename _CharT>
2581    _CharT*
2582    __add_grouping(_CharT* __s, _CharT __sep,
2583		   const char* __gbeg, size_t __gsize,
2584		   const _CharT* __first, const _CharT* __last)
2585    {
2586      size_t __idx = 0;
2587      size_t __ctr = 0;
2588
2589      while (__last - __first > __gbeg[__idx]
2590	     && static_cast<signed char>(__gbeg[__idx]) > 0)
2591	{
2592	  __last -= __gbeg[__idx];
2593	  __idx < __gsize - 1 ? ++__idx : ++__ctr;
2594	}
2595
2596      while (__first != __last)
2597	*__s++ = *__first++;
2598
2599      while (__ctr--)
2600	{
2601	  *__s++ = __sep;	  
2602	  for (char __i = __gbeg[__idx]; __i > 0; --__i)
2603	    *__s++ = *__first++;
2604	}
2605
2606      while (__idx--)
2607	{
2608	  *__s++ = __sep;	  
2609	  for (char __i = __gbeg[__idx]; __i > 0; --__i)
2610	    *__s++ = *__first++;
2611	}
2612
2613      return __s;
2614    }
2615
2616  // Inhibit implicit instantiations for required instantiations,
2617  // which are defined via explicit instantiations elsewhere.
2618  // NB: This syntax is a GNU extension.
2619#if _GLIBCXX_EXTERN_TEMPLATE
2620  extern template class moneypunct<char, false>;
2621  extern template class moneypunct<char, true>;
2622  extern template class moneypunct_byname<char, false>;
2623  extern template class moneypunct_byname<char, true>;
2624  extern template class _GLIBCXX_LDBL_NAMESPACE money_get<char>;
2625  extern template class _GLIBCXX_LDBL_NAMESPACE money_put<char>;
2626  extern template class numpunct<char>;
2627  extern template class numpunct_byname<char>;
2628  extern template class _GLIBCXX_LDBL_NAMESPACE num_get<char>;
2629  extern template class _GLIBCXX_LDBL_NAMESPACE num_put<char>;
2630  extern template class __timepunct<char>;
2631  extern template class time_put<char>;
2632  extern template class time_put_byname<char>;
2633  extern template class time_get<char>;
2634  extern template class time_get_byname<char>;
2635  extern template class messages<char>;
2636  extern template class messages_byname<char>;
2637  extern template class ctype_byname<char>;
2638  extern template class codecvt_byname<char, char, mbstate_t>;
2639  extern template class collate<char>;
2640  extern template class collate_byname<char>;
2641
2642  extern template
2643    const codecvt<char, char, mbstate_t>&
2644    use_facet<codecvt<char, char, mbstate_t> >(const locale&);
2645
2646  extern template
2647    const collate<char>&
2648    use_facet<collate<char> >(const locale&);
2649
2650  extern template
2651    const numpunct<char>&
2652    use_facet<numpunct<char> >(const locale&);
2653
2654  extern template
2655    const num_put<char>&
2656    use_facet<num_put<char> >(const locale&);
2657
2658  extern template
2659    const num_get<char>&
2660    use_facet<num_get<char> >(const locale&);
2661
2662  extern template
2663    const moneypunct<char, true>&
2664    use_facet<moneypunct<char, true> >(const locale&);
2665
2666  extern template
2667    const moneypunct<char, false>&
2668    use_facet<moneypunct<char, false> >(const locale&);
2669
2670  extern template
2671    const money_put<char>&
2672    use_facet<money_put<char> >(const locale&);
2673
2674  extern template
2675    const money_get<char>&
2676    use_facet<money_get<char> >(const locale&);
2677
2678  extern template
2679    const __timepunct<char>&
2680    use_facet<__timepunct<char> >(const locale&);
2681
2682  extern template
2683    const time_put<char>&
2684    use_facet<time_put<char> >(const locale&);
2685
2686  extern template
2687    const time_get<char>&
2688    use_facet<time_get<char> >(const locale&);
2689
2690  extern template
2691    const messages<char>&
2692    use_facet<messages<char> >(const locale&);
2693
2694  extern template
2695    bool
2696    has_facet<ctype<char> >(const locale&);
2697
2698  extern template
2699    bool
2700    has_facet<codecvt<char, char, mbstate_t> >(const locale&);
2701
2702  extern template
2703    bool
2704    has_facet<collate<char> >(const locale&);
2705
2706  extern template
2707    bool
2708    has_facet<numpunct<char> >(const locale&);
2709
2710  extern template
2711    bool
2712    has_facet<num_put<char> >(const locale&);
2713
2714  extern template
2715    bool
2716    has_facet<num_get<char> >(const locale&);
2717
2718  extern template
2719    bool
2720    has_facet<moneypunct<char> >(const locale&);
2721
2722  extern template
2723    bool
2724    has_facet<money_put<char> >(const locale&);
2725
2726  extern template
2727    bool
2728    has_facet<money_get<char> >(const locale&);
2729
2730  extern template
2731    bool
2732    has_facet<__timepunct<char> >(const locale&);
2733
2734  extern template
2735    bool
2736    has_facet<time_put<char> >(const locale&);
2737
2738  extern template
2739    bool
2740    has_facet<time_get<char> >(const locale&);
2741
2742  extern template
2743    bool
2744    has_facet<messages<char> >(const locale&);
2745
2746#ifdef _GLIBCXX_USE_WCHAR_T
2747  extern template class moneypunct<wchar_t, false>;
2748  extern template class moneypunct<wchar_t, true>;
2749  extern template class moneypunct_byname<wchar_t, false>;
2750  extern template class moneypunct_byname<wchar_t, true>;
2751  extern template class _GLIBCXX_LDBL_NAMESPACE money_get<wchar_t>;
2752  extern template class _GLIBCXX_LDBL_NAMESPACE money_put<wchar_t>;
2753  extern template class numpunct<wchar_t>;
2754  extern template class numpunct_byname<wchar_t>;
2755  extern template class _GLIBCXX_LDBL_NAMESPACE num_get<wchar_t>;
2756  extern template class _GLIBCXX_LDBL_NAMESPACE num_put<wchar_t>;
2757  extern template class __timepunct<wchar_t>;
2758  extern template class time_put<wchar_t>;
2759  extern template class time_put_byname<wchar_t>;
2760  extern template class time_get<wchar_t>;
2761  extern template class time_get_byname<wchar_t>;
2762  extern template class messages<wchar_t>;
2763  extern template class messages_byname<wchar_t>;
2764  extern template class ctype_byname<wchar_t>;
2765  extern template class codecvt_byname<wchar_t, char, mbstate_t>;
2766  extern template class collate<wchar_t>;
2767  extern template class collate_byname<wchar_t>;
2768
2769  extern template
2770    const codecvt<wchar_t, char, mbstate_t>&
2771    use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
2772
2773  extern template
2774    const collate<wchar_t>&
2775    use_facet<collate<wchar_t> >(const locale&);
2776
2777  extern template
2778    const numpunct<wchar_t>&
2779    use_facet<numpunct<wchar_t> >(const locale&);
2780
2781  extern template
2782    const num_put<wchar_t>&
2783    use_facet<num_put<wchar_t> >(const locale&);
2784
2785  extern template
2786    const num_get<wchar_t>&
2787    use_facet<num_get<wchar_t> >(const locale&);
2788
2789  extern template
2790    const moneypunct<wchar_t, true>&
2791    use_facet<moneypunct<wchar_t, true> >(const locale&);
2792
2793  extern template
2794    const moneypunct<wchar_t, false>&
2795    use_facet<moneypunct<wchar_t, false> >(const locale&);
2796
2797  extern template
2798    const money_put<wchar_t>&
2799    use_facet<money_put<wchar_t> >(const locale&);
2800
2801  extern template
2802    const money_get<wchar_t>&
2803    use_facet<money_get<wchar_t> >(const locale&);
2804
2805  extern template
2806    const __timepunct<wchar_t>&
2807    use_facet<__timepunct<wchar_t> >(const locale&);
2808
2809  extern template
2810    const time_put<wchar_t>&
2811    use_facet<time_put<wchar_t> >(const locale&);
2812
2813  extern template
2814    const time_get<wchar_t>&
2815    use_facet<time_get<wchar_t> >(const locale&);
2816
2817  extern template
2818    const messages<wchar_t>&
2819    use_facet<messages<wchar_t> >(const locale&);
2820
2821 extern template
2822    bool
2823    has_facet<ctype<wchar_t> >(const locale&);
2824
2825  extern template
2826    bool
2827    has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
2828
2829  extern template
2830    bool
2831    has_facet<collate<wchar_t> >(const locale&);
2832
2833  extern template
2834    bool
2835    has_facet<numpunct<wchar_t> >(const locale&);
2836
2837  extern template
2838    bool
2839    has_facet<num_put<wchar_t> >(const locale&);
2840
2841  extern template
2842    bool
2843    has_facet<num_get<wchar_t> >(const locale&);
2844
2845  extern template
2846    bool
2847    has_facet<moneypunct<wchar_t> >(const locale&);
2848
2849  extern template
2850    bool
2851    has_facet<money_put<wchar_t> >(const locale&);
2852
2853  extern template
2854    bool
2855    has_facet<money_get<wchar_t> >(const locale&);
2856
2857  extern template
2858    bool
2859    has_facet<__timepunct<wchar_t> >(const locale&);
2860
2861  extern template
2862    bool
2863    has_facet<time_put<wchar_t> >(const locale&);
2864
2865  extern template
2866    bool
2867    has_facet<time_get<wchar_t> >(const locale&);
2868
2869  extern template
2870    bool
2871    has_facet<messages<wchar_t> >(const locale&);
2872#endif
2873#endif
2874
2875_GLIBCXX_END_NAMESPACE
2876
2877#endif
2878