1    	// Locale support -*- C++ -*-
2    	
3    	// Copyright (C) 2007-2013 Free Software Foundation, Inc.
4    	//
5    	// This file is part of the GNU ISO C++ Library.  This library is free
6    	// software; you can redistribute it and/or modify it under the
7    	// terms of the GNU General Public License as published by the
8    	// Free Software Foundation; either version 3, or (at your option)
9    	// any later version.
10   	
11   	// This library is distributed in the hope that it will be useful,
12   	// but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   	// GNU General Public License for more details.
15   	
16   	// Under Section 7 of GPL version 3, you are granted additional
17   	// permissions described in the GCC Runtime Library Exception, version
18   	// 3.1, as published by the Free Software Foundation.
19   	
20   	// You should have received a copy of the GNU General Public License and
21   	// a copy of the GCC Runtime Library Exception along with this program;
22   	// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   	// <http://www.gnu.org/licenses/>.
24   	
25   	/** @file bits/locale_facets_nonio.tcc
26   	 *  This is an internal header file, included by other library headers.
27   	 *  Do not attempt to use it directly. @headername{locale}
28   	 */
29   	
30   	#ifndef _LOCALE_FACETS_NONIO_TCC
31   	#define _LOCALE_FACETS_NONIO_TCC 1
32   	
33   	#pragma GCC system_header
34   	
35   	namespace std _GLIBCXX_VISIBILITY(default)
36   	{
37   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
38   	
39   	  template<typename _CharT, bool _Intl>
40   	    struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
41   	    {
42   	      const __moneypunct_cache<_CharT, _Intl>*
43   	      operator() (const locale& __loc) const
44   	      {
45   		const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
46   		const locale::facet** __caches = __loc._M_impl->_M_caches;
47   		if (!__caches[__i])
48   		  {
49   		    __moneypunct_cache<_CharT, _Intl>* __tmp = 0;
50   		    __try
51   		      {
52   			__tmp = new __moneypunct_cache<_CharT, _Intl>;
53   			__tmp->_M_cache(__loc);
54   		      }
55   		    __catch(...)
56   		      {
57   			delete __tmp;
58   			__throw_exception_again;
59   		      }
60   		    __loc._M_impl->_M_install_cache(__tmp, __i);
61   		  }
62   		return static_cast<
63   		  const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
64   	      }
65   	    };
66   	
67   	  template<typename _CharT, bool _Intl>
68   	    void
69   	    __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
70   	    {
71   	      _M_allocated = true;
72   	
73   	      const moneypunct<_CharT, _Intl>& __mp =
74   		use_facet<moneypunct<_CharT, _Intl> >(__loc);
75   	
76   	      _M_decimal_point = __mp.decimal_point();
77   	      _M_thousands_sep = __mp.thousands_sep();
78   	      _M_frac_digits = __mp.frac_digits();
79   	
80   	      char* __grouping = 0;
81   	      _CharT* __curr_symbol = 0;
82   	      _CharT* __positive_sign = 0;
83   	      _CharT* __negative_sign = 0;     
84   	      __try
85   		{
86   		  _M_grouping_size = __mp.grouping().size();
87   		  __grouping = new char[_M_grouping_size];
88   		  __mp.grouping().copy(__grouping, _M_grouping_size);
89   		  _M_grouping = __grouping;
90   		  _M_use_grouping = (_M_grouping_size
91   				     && static_cast<signed char>(_M_grouping[0]) > 0
92   				     && (_M_grouping[0]
93   					 != __gnu_cxx::__numeric_traits<char>::__max));
94   	
95   		  _M_curr_symbol_size = __mp.curr_symbol().size();
96   		  __curr_symbol = new _CharT[_M_curr_symbol_size];
97   		  __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
98   		  _M_curr_symbol = __curr_symbol;
99   	
100  		  _M_positive_sign_size = __mp.positive_sign().size();
101  		  __positive_sign = new _CharT[_M_positive_sign_size];
102  		  __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
103  		  _M_positive_sign = __positive_sign;
104  	
105  		  _M_negative_sign_size = __mp.negative_sign().size();
106  		  __negative_sign = new _CharT[_M_negative_sign_size];
107  		  __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
108  		  _M_negative_sign = __negative_sign;
109  	
110  		  _M_pos_format = __mp.pos_format();
111  		  _M_neg_format = __mp.neg_format();
112  	
113  		  const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
114  		  __ct.widen(money_base::_S_atoms,
115  			     money_base::_S_atoms + money_base::_S_end, _M_atoms);
116  		}
117  	      __catch(...)
118  		{
119  		  delete [] __grouping;
120  		  delete [] __curr_symbol;
121  		  delete [] __positive_sign;
122  		  delete [] __negative_sign;
123  		  __throw_exception_again;
124  		}
125  	    }
126  	
127  	_GLIBCXX_BEGIN_NAMESPACE_LDBL
128  	
129  	  template<typename _CharT, typename _InIter>
130  	    template<bool _Intl>
131  	      _InIter
132  	      money_get<_CharT, _InIter>::
133  	      _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
134  			 ios_base::iostate& __err, string& __units) const
135  	      {
136  		typedef char_traits<_CharT>			  __traits_type;
137  		typedef typename string_type::size_type	          size_type;	
138  		typedef money_base::part			  part;
139  		typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
140  		
141  		const locale& __loc = __io._M_getloc();
142  		const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
143  	
144  		__use_cache<__cache_type> __uc;
145  		const __cache_type* __lc = __uc(__loc);
146  		const char_type* __lit = __lc->_M_atoms;
147  	
148  		// Deduced sign.
149  		bool __negative = false;
150  		// Sign size.
151  		size_type __sign_size = 0;
152  		// True if sign is mandatory.
153  		const bool __mandatory_sign = (__lc->_M_positive_sign_size
154  					       && __lc->_M_negative_sign_size);
155  		// String of grouping info from thousands_sep plucked from __units.
156  		string __grouping_tmp;
157  		if (__lc->_M_use_grouping)
158  		  __grouping_tmp.reserve(32);
159  		// Last position before the decimal point.
160  		int __last_pos = 0;
161  		// Separator positions, then, possibly, fractional digits.
162  		int __n = 0;
163  		// If input iterator is in a valid state.
164  		bool __testvalid = true;
165  		// Flag marking when a decimal point is found.
166  		bool __testdecfound = false;
167  	
168  		// The tentative returned string is stored here.
169  		string __res;
170  		__res.reserve(32);
171  	
172  		const char_type* __lit_zero = __lit + money_base::_S_zero;
173  		const money_base::pattern __p = __lc->_M_neg_format;
174  		for (int __i = 0; __i < 4 && __testvalid; ++__i)
175  		  {
176  		    const part __which = static_cast<part>(__p.field[__i]);
177  		    switch (__which)
178  		      {
179  		      case money_base::symbol:
180  			// According to 22.2.6.1.2, p2, symbol is required
181  			// if (__io.flags() & ios_base::showbase), otherwise
182  			// is optional and consumed only if other characters
183  			// are needed to complete the format.
184  			if (__io.flags() & ios_base::showbase || __sign_size > 1
185  			    || __i == 0
186  			    || (__i == 1 && (__mandatory_sign
187  					     || (static_cast<part>(__p.field[0])
188  						 == money_base::sign)
189  					     || (static_cast<part>(__p.field[2])
190  						 == money_base::space)))
191  			    || (__i == 2 && ((static_cast<part>(__p.field[3])
192  					      == money_base::value)
193  					     || (__mandatory_sign
194  						 && (static_cast<part>(__p.field[3])
195  						     == money_base::sign)))))
196  			  {
197  			    const size_type __len = __lc->_M_curr_symbol_size;
198  			    size_type __j = 0;
199  			    for (; __beg != __end && __j < __len
200  				   && *__beg == __lc->_M_curr_symbol[__j];
201  				 ++__beg, ++__j);
202  			    if (__j != __len
203  				&& (__j || __io.flags() & ios_base::showbase))
204  			      __testvalid = false;
205  			  }
206  			break;
207  		      case money_base::sign:
208  			// Sign might not exist, or be more than one character long.
209  			if (__lc->_M_positive_sign_size && __beg != __end
210  			    && *__beg == __lc->_M_positive_sign[0])
211  			  {
212  			    __sign_size = __lc->_M_positive_sign_size;
213  			    ++__beg;
214  			  }
215  			else if (__lc->_M_negative_sign_size && __beg != __end
216  				 && *__beg == __lc->_M_negative_sign[0])
217  			  {
218  			    __negative = true;
219  			    __sign_size = __lc->_M_negative_sign_size;
220  			    ++__beg;
221  			  }
222  			else if (__lc->_M_positive_sign_size
223  				 && !__lc->_M_negative_sign_size)
224  			  // "... if no sign is detected, the result is given the sign
225  			  // that corresponds to the source of the empty string"
226  			  __negative = true;
227  			else if (__mandatory_sign)
228  			  __testvalid = false;
229  			break;
230  		      case money_base::value:
231  			// Extract digits, remove and stash away the
232  			// grouping of found thousands separators.
233  			for (; __beg != __end; ++__beg)
234  			  {
235  			    const char_type __c = *__beg;
236  			    const char_type* __q = __traits_type::find(__lit_zero, 
237  								       10, __c);
238  			    if (__q != 0)
239  			      {
240  				__res += money_base::_S_atoms[__q - __lit];
241  				++__n;
242  			      }
243  			    else if (__c == __lc->_M_decimal_point 
244  				     && !__testdecfound)
245  			      {
246  				if (__lc->_M_frac_digits <= 0)
247  				  break;
248  	
249  				__last_pos = __n;
250  				__n = 0;
251  				__testdecfound = true;
252  			      }
253  			    else if (__lc->_M_use_grouping
254  				     && __c == __lc->_M_thousands_sep
255  				     && !__testdecfound)
256  			      {
257  				if (__n)
258  				  {
259  				    // Mark position for later analysis.
260  				    __grouping_tmp += static_cast<char>(__n);
261  				    __n = 0;
262  				  }
263  				else
264  				  {
265  				    __testvalid = false;
266  				    break;
267  				  }
268  			      }
269  			    else
270  			      break;
271  			  }
272  			if (__res.empty())
273  			  __testvalid = false;
274  			break;
275  		      case money_base::space:
276  			// At least one space is required.
277  			if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
278  			  ++__beg;
279  			else
280  			  __testvalid = false;
281  		      case money_base::none:
282  			// Only if not at the end of the pattern.
283  			if (__i != 3)
284  			  for (; __beg != __end
285  				 && __ctype.is(ctype_base::space, *__beg); ++__beg);
286  			break;
287  		      }
288  		  }
289  	
290  		// Need to get the rest of the sign characters, if they exist.
291  		if (__sign_size > 1 && __testvalid)
292  		  {
293  		    const char_type* __sign = __negative ? __lc->_M_negative_sign
294  		                                         : __lc->_M_positive_sign;
295  		    size_type __i = 1;
296  		    for (; __beg != __end && __i < __sign_size
297  			   && *__beg == __sign[__i]; ++__beg, ++__i);
298  		    
299  		    if (__i != __sign_size)
300  		      __testvalid = false;
301  		  }
302  	
303  		if (__testvalid)
304  		  {
305  		    // Strip leading zeros.
306  		    if (__res.size() > 1)
307  		      {
308  			const size_type __first = __res.find_first_not_of('0');
309  			const bool __only_zeros = __first == string::npos;
310  			if (__first)
311  			  __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
312  		      }
313  	
314  		    // 22.2.6.1.2, p4
315  		    if (__negative && __res[0] != '0')
316  		      __res.insert(__res.begin(), '-');
317  		    
318  		    // Test for grouping fidelity.
319  		    if (__grouping_tmp.size())
320  		      {
321  			// Add the ending grouping.
322  			__grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
323  							                   : __n);
324  			if (!std::__verify_grouping(__lc->_M_grouping,
325  						    __lc->_M_grouping_size,
326  						    __grouping_tmp))
327  			  __err |= ios_base::failbit;
328  		      }
329  		    
330  		    // Iff not enough digits were supplied after the decimal-point.
331  		    if (__testdecfound && __n != __lc->_M_frac_digits)
332  		      __testvalid = false;
333  		  }
334  	
335  		// Iff valid sequence is not recognized.
336  		if (!__testvalid)
337  		  __err |= ios_base::failbit;
338  		else
339  		  __units.swap(__res);
340  		
341  		// Iff no more characters are available.
342  		if (__beg == __end)
343  		  __err |= ios_base::eofbit;
344  		return __beg;
345  	      }
346  	
347  	#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
348  	  template<typename _CharT, typename _InIter>
349  	    _InIter
350  	    money_get<_CharT, _InIter>::
351  	    __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
352  		     ios_base::iostate& __err, double& __units) const
353  	    {
354  	      string __str;
355  	      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
356  	                     : _M_extract<false>(__beg, __end, __io, __err, __str);
357  	      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
358  	      return __beg;
359  	    }
360  	#endif
361  	
362  	  template<typename _CharT, typename _InIter>
363  	    _InIter
364  	    money_get<_CharT, _InIter>::
365  	    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
366  		   ios_base::iostate& __err, long double& __units) const
367  	    {
368  	      string __str;
369  	      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
370  		             : _M_extract<false>(__beg, __end, __io, __err, __str);
371  	      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
372  	      return __beg;
373  	    }
374  	
375  	  template<typename _CharT, typename _InIter>
376  	    _InIter
377  	    money_get<_CharT, _InIter>::
378  	    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
379  		   ios_base::iostate& __err, string_type& __digits) const
380  	    {
381  	      typedef typename string::size_type                  size_type;
382  	
383  	      const locale& __loc = __io._M_getloc();
384  	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
385  	
386  	      string __str;
387  	      __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
388  		             : _M_extract<false>(__beg, __end, __io, __err, __str);
389  	      const size_type __len = __str.size();
390  	      if (__len)
391  		{
392  		  __digits.resize(__len);
393  		  __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]);
394  		}
395  	      return __beg;
396  	    }
397  	
398  	  template<typename _CharT, typename _OutIter>
399  	    template<bool _Intl>
400  	      _OutIter
401  	      money_put<_CharT, _OutIter>::
402  	      _M_insert(iter_type __s, ios_base& __io, char_type __fill,
403  			const string_type& __digits) const
404  	      {
405  		typedef typename string_type::size_type	          size_type;
406  		typedef money_base::part                          part;
407  		typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
408  	      
409  		const locale& __loc = __io._M_getloc();
410  		const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
411  	
412  		__use_cache<__cache_type> __uc;
413  		const __cache_type* __lc = __uc(__loc);
414  		const char_type* __lit = __lc->_M_atoms;
415  	
416  		// Determine if negative or positive formats are to be used, and
417  		// discard leading negative_sign if it is present.
418  		const char_type* __beg = __digits.data();
419  	
420  		money_base::pattern __p;
421  		const char_type* __sign;
422  		size_type __sign_size;
423  		if (!(*__beg == __lit[money_base::_S_minus]))
424  		  {
425  		    __p = __lc->_M_pos_format;
426  		    __sign = __lc->_M_positive_sign;
427  		    __sign_size = __lc->_M_positive_sign_size;
428  		  }
429  		else
430  		  {
431  		    __p = __lc->_M_neg_format;
432  		    __sign = __lc->_M_negative_sign;
433  		    __sign_size = __lc->_M_negative_sign_size;
434  		    if (__digits.size())
435  		      ++__beg;
436  		  }
437  	       
438  		// Look for valid numbers in the ctype facet within input digits.
439  		size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
440  						   __beg + __digits.size()) - __beg;
441  		if (__len)
442  		  {
443  		    // Assume valid input, and attempt to format.
444  		    // Break down input numbers into base components, as follows:
445  		    //   final_value = grouped units + (decimal point) + (digits)
446  		    string_type __value;
447  		    __value.reserve(2 * __len);
448  	
449  		    // Add thousands separators to non-decimal digits, per
450  		    // grouping rules.
451  		    long __paddec = __len - __lc->_M_frac_digits;
452  		    if (__paddec > 0)
453  	  	      {
454  			if (__lc->_M_frac_digits < 0)
455  			  __paddec = __len;
456  	  		if (__lc->_M_grouping_size)
457  	  		  {
458  			    __value.assign(2 * __paddec, char_type());
459  	 		    _CharT* __vend = 
460  			      std::__add_grouping(&__value[0], __lc->_M_thousands_sep,
461  						  __lc->_M_grouping,
462  						  __lc->_M_grouping_size,
463  						  __beg, __beg + __paddec);
464  			    __value.erase(__vend - &__value[0]);
465  	  		  }
466  	  		else
467  			  __value.assign(__beg, __paddec);
468  		      }
469  	
470  		    // Deal with decimal point, decimal digits.
471  		    if (__lc->_M_frac_digits > 0)
472  		      {
473  			__value += __lc->_M_decimal_point;
474  			if (__paddec >= 0)
475  			  __value.append(__beg + __paddec, __lc->_M_frac_digits);
476  			else
477  			  {
478  			    // Have to pad zeros in the decimal position.
479  			    __value.append(-__paddec, __lit[money_base::_S_zero]);
480  			    __value.append(__beg, __len);
481  			  }
482  	  	      }
483  	  
484  		    // Calculate length of resulting string.
485  		    const ios_base::fmtflags __f = __io.flags() 
486  		                                   & ios_base::adjustfield;
487  		    __len = __value.size() + __sign_size;
488  		    __len += ((__io.flags() & ios_base::showbase)
489  			      ? __lc->_M_curr_symbol_size : 0);
490  	
491  		    string_type __res;
492  		    __res.reserve(2 * __len);
493  		    
494  		    const size_type __width = static_cast<size_type>(__io.width());  
495  		    const bool __testipad = (__f == ios_base::internal
496  					     && __len < __width);
497  		    // Fit formatted digits into the required pattern.
498  		    for (int __i = 0; __i < 4; ++__i)
499  		      {
500  			const part __which = static_cast<part>(__p.field[__i]);
501  			switch (__which)
502  			  {
503  			  case money_base::symbol:
504  			    if (__io.flags() & ios_base::showbase)
505  			      __res.append(__lc->_M_curr_symbol,
506  					   __lc->_M_curr_symbol_size);
507  			    break;
508  			  case money_base::sign:
509  			    // Sign might not exist, or be more than one
510  			    // character long. In that case, add in the rest
511  			    // below.
512  			    if (__sign_size)
513  			      __res += __sign[0];
514  			    break;
515  			  case money_base::value:
516  			    __res += __value;
517  			    break;
518  			  case money_base::space:
519  			    // At least one space is required, but if internal
520  			    // formatting is required, an arbitrary number of
521  			    // fill spaces will be necessary.
522  			    if (__testipad)
523  			      __res.append(__width - __len, __fill);
524  			    else
525  			      __res += __fill;
526  			    break;
527  			  case money_base::none:
528  			    if (__testipad)
529  			      __res.append(__width - __len, __fill);
530  			    break;
531  			  }
532  		      }
533  		    
534  		    // Special case of multi-part sign parts.
535  		    if (__sign_size > 1)
536  		      __res.append(__sign + 1, __sign_size - 1);
537  		    
538  		    // Pad, if still necessary.
539  		    __len = __res.size();
540  		    if (__width > __len)
541  		      {
542  			if (__f == ios_base::left)
543  			  // After.
544  			  __res.append(__width - __len, __fill);
545  			else
546  			  // Before.
547  			  __res.insert(0, __width - __len, __fill);
548  			__len = __width;
549  		      }
550  		    
551  		    // Write resulting, fully-formatted string to output iterator.
552  		    __s = std::__write(__s, __res.data(), __len);
553  		  }
554  		__io.width(0);
555  		return __s;    
556  	      }
557  	
558  	#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
559  	  template<typename _CharT, typename _OutIter>
560  	    _OutIter
561  	    money_put<_CharT, _OutIter>::
562  	    __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
563  		     double __units) const
564  	    { return this->do_put(__s, __intl, __io, __fill, (long double) __units); }
565  	#endif
566  	
567  	  template<typename _CharT, typename _OutIter>
568  	    _OutIter
569  	    money_put<_CharT, _OutIter>::
570  	    do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
571  		   long double __units) const
572  	    {
573  	      const locale __loc = __io.getloc();
574  	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
575  	#ifdef _GLIBCXX_USE_C99
576  	      // First try a buffer perhaps big enough.
577  	      int __cs_size = 64;
578  	      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
579  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
580  	      // 328. Bad sprintf format modifier in money_put<>::do_put()
581  	      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
582  						"%.*Lf", 0, __units);
583  	      // If the buffer was not large enough, try again with the correct size.
584  	      if (__len >= __cs_size)
585  		{
586  		  __cs_size = __len + 1;
587  		  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
588  		  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
589  						"%.*Lf", 0, __units);
590  		}
591  	#else
592  	      // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
593  	      const int __cs_size =
594  		__gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
595  	      char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
596  	      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 
597  						0, __units);
598  	#endif
599  	      string_type __digits(__len, char_type());
600  	      __ctype.widen(__cs, __cs + __len, &__digits[0]);
601  	      return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
602  		            : _M_insert<false>(__s, __io, __fill, __digits);
603  	    }
604  	
605  	  template<typename _CharT, typename _OutIter>
606  	    _OutIter
607  	    money_put<_CharT, _OutIter>::
608  	    do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
609  		   const string_type& __digits) const
610  	    { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
611  		            : _M_insert<false>(__s, __io, __fill, __digits); }
612  	
613  	_GLIBCXX_END_NAMESPACE_LDBL
614  	
615  	  // NB: Not especially useful. Without an ios_base object or some
616  	  // kind of locale reference, we are left clawing at the air where
617  	  // the side of the mountain used to be...
618  	  template<typename _CharT, typename _InIter>
619  	    time_base::dateorder
620  	    time_get<_CharT, _InIter>::do_date_order() const
621  	    { return time_base::no_order; }
622  	
623  	  // Expand a strftime format string and parse it.  E.g., do_get_date() may
624  	  // pass %m/%d/%Y => extracted characters.
625  	  template<typename _CharT, typename _InIter>
626  	    _InIter
627  	    time_get<_CharT, _InIter>::
628  	    _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
629  				  ios_base::iostate& __err, tm* __tm,
630  				  const _CharT* __format) const
631  	    {
632  	      const locale& __loc = __io._M_getloc();
633  	      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
634  	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
635  	      const size_t __len = char_traits<_CharT>::length(__format);
636  	
637  	      ios_base::iostate __tmperr = ios_base::goodbit;
638  	      size_t __i = 0;
639  	      for (; __beg != __end && __i < __len && !__tmperr; ++__i)
640  		{
641  		  if (__ctype.narrow(__format[__i], 0) == '%')
642  		    {
643  		      // Verify valid formatting code, attempt to extract.
644  		      char __c = __ctype.narrow(__format[++__i], 0);
645  		      int __mem = 0;
646  		      if (__c == 'E' || __c == 'O')
647  			__c = __ctype.narrow(__format[++__i], 0);
648  		      switch (__c)
649  			{
650  			  const char* __cs;
651  			  _CharT __wcs[10];
652  			case 'a':
653  			  // Abbreviated weekday name [tm_wday]
654  			  const char_type*  __days1[7];
655  			  __tp._M_days_abbreviated(__days1);
656  			  __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
657  						  7, __io, __tmperr);
658  			  break;
659  			case 'A':
660  			  // Weekday name [tm_wday].
661  			  const char_type*  __days2[7];
662  			  __tp._M_days(__days2);
663  			  __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
664  						  7, __io, __tmperr);
665  			  break;
666  			case 'h':
667  			case 'b':
668  			  // Abbreviated month name [tm_mon]
669  			  const char_type*  __months1[12];
670  			  __tp._M_months_abbreviated(__months1);
671  			  __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 
672  						  __months1, 12, __io, __tmperr);
673  			  break;
674  			case 'B':
675  			  // Month name [tm_mon].
676  			  const char_type*  __months2[12];
677  			  __tp._M_months(__months2);
678  			  __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 
679  						  __months2, 12, __io, __tmperr);
680  			  break;
681  			case 'c':
682  			  // Default time and date representation.
683  			  const char_type*  __dt[2];
684  			  __tp._M_date_time_formats(__dt);
685  			  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
686  							__tm, __dt[0]);
687  			  break;
688  			case 'd':
689  			  // Day [01, 31]. [tm_mday]
690  			  __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
691  						 __io, __tmperr);
692  			  break;
693  			case 'e':
694  			  // Day [1, 31], with single digits preceded by
695  			  // space. [tm_mday]
696  			  if (__ctype.is(ctype_base::space, *__beg))
697  			    __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
698  						   1, __io, __tmperr);
699  			  else
700  			    __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
701  						   2, __io, __tmperr);
702  			  break;
703  			case 'D':
704  			  // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
705  			  __cs = "%m/%d/%y";
706  			  __ctype.widen(__cs, __cs + 9, __wcs);
707  			  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
708  							__tm, __wcs);
709  			  break;
710  			case 'H':
711  			  // Hour [00, 23]. [tm_hour]
712  			  __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
713  						 __io, __tmperr);
714  			  break;
715  			case 'I':
716  			  // Hour [01, 12]. [tm_hour]
717  			  __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
718  						 __io, __tmperr);
719  			  break;
720  			case 'm':
721  			  // Month [01, 12]. [tm_mon]
722  			  __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 
723  						 __io, __tmperr);
724  			  if (!__tmperr)
725  			    __tm->tm_mon = __mem - 1;
726  			  break;
727  			case 'M':
728  			  // Minute [00, 59]. [tm_min]
729  			  __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
730  						 __io, __tmperr);
731  			  break;
732  			case 'n':
733  			  if (__ctype.narrow(*__beg, 0) == '\n')
734  			    ++__beg;
735  			  else
736  			    __tmperr |= ios_base::failbit;
737  			  break;
738  			case 'R':
739  			  // Equivalent to (%H:%M).
740  			  __cs = "%H:%M";
741  			  __ctype.widen(__cs, __cs + 6, __wcs);
742  			  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
743  							__tm, __wcs);
744  			  break;
745  			case 'S':
746  			  // Seconds. [tm_sec]
747  			  // [00, 60] in C99 (one leap-second), [00, 61] in C89.
748  	#ifdef _GLIBCXX_USE_C99
749  			  __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
750  	#else
751  			  __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
752  	#endif
753  						 __io, __tmperr);
754  			  break;
755  			case 't':
756  			  if (__ctype.narrow(*__beg, 0) == '\t')
757  			    ++__beg;
758  			  else
759  			    __tmperr |= ios_base::failbit;
760  			  break;
761  			case 'T':
762  			  // Equivalent to (%H:%M:%S).
763  			  __cs = "%H:%M:%S";
764  			  __ctype.widen(__cs, __cs + 9, __wcs);
765  			  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
766  							__tm, __wcs);
767  			  break;
768  			case 'x':
769  			  // Locale's date.
770  			  const char_type*  __dates[2];
771  			  __tp._M_date_formats(__dates);
772  			  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
773  							__tm, __dates[0]);
774  			  break;
775  			case 'X':
776  			  // Locale's time.
777  			  const char_type*  __times[2];
778  			  __tp._M_time_formats(__times);
779  			  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
780  							__tm, __times[0]);
781  			  break;
782  			case 'y':
783  			case 'C': // C99
784  			  // Two digit year.
785  			case 'Y':
786  			  // Year [1900).
787  			  // NB: We parse either two digits, implicitly years since
788  			  // 1900, or 4 digits, full year.  In both cases we can 
789  			  // reconstruct [tm_year].  See also libstdc++/26701.
790  			  __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
791  						 __io, __tmperr);
792  			  if (!__tmperr)
793  			    __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900;
794  			  break;
795  			case 'Z':
796  			  // Timezone info.
797  			  if (__ctype.is(ctype_base::upper, *__beg))
798  			    {
799  			      int __tmp;
800  			      __beg = _M_extract_name(__beg, __end, __tmp,
801  					       __timepunct_cache<_CharT>::_S_timezones,
802  						      14, __io, __tmperr);
803  	
804  			      // GMT requires special effort.
805  			      if (__beg != __end && !__tmperr && __tmp == 0
806  				  && (*__beg == __ctype.widen('-')
807  				      || *__beg == __ctype.widen('+')))
808  				{
809  				  __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
810  							 __io, __tmperr);
811  				  __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
812  							 __io, __tmperr);
813  				}
814  			    }
815  			  else
816  			    __tmperr |= ios_base::failbit;
817  			  break;
818  			default:
819  			  // Not recognized.
820  			  __tmperr |= ios_base::failbit;
821  			}
822  		    }
823  		  else
824  		    {
825  		      // Verify format and input match, extract and discard.
826  		      if (__format[__i] == *__beg)
827  			++__beg;
828  		      else
829  			__tmperr |= ios_base::failbit;
830  		    }
831  		}
832  	
833  	      if (__tmperr || __i != __len)
834  		__err |= ios_base::failbit;
835  	  
836  	      return __beg;
837  	    }
838  	
839  	  template<typename _CharT, typename _InIter>
840  	    _InIter
841  	    time_get<_CharT, _InIter>::
842  	    _M_extract_num(iter_type __beg, iter_type __end, int& __member,
843  			   int __min, int __max, size_t __len,
844  			   ios_base& __io, ios_base::iostate& __err) const
845  	    {
846  	      const locale& __loc = __io._M_getloc();
847  	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
848  	
849  	      // As-is works for __len = 1, 2, 4, the values actually used.
850  	      int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
851  	
852  	      ++__min;
853  	      size_t __i = 0;
854  	      int __value = 0;
855  	      for (; __beg != __end && __i < __len; ++__beg, ++__i)
856  		{
857  		  const char __c = __ctype.narrow(*__beg, '*');
858  		  if (__c >= '0' && __c <= '9')
859  		    {
860  		      __value = __value * 10 + (__c - '0');
861  		      const int __valuec = __value * __mult;
862  		      if (__valuec > __max || __valuec + __mult < __min)
863  			break;
864  		      __mult /= 10;
865  		    }
866  		  else
867  		    break;
868  		}
869  	      if (__i == __len)
870  		__member = __value;
871  	      // Special encoding for do_get_year, 'y', and 'Y' above.
872  	      else if (__len == 4 && __i == 2)
873  		__member = __value - 100;
874  	      else
875  		__err |= ios_base::failbit;
876  	
877  	      return __beg;
878  	    }
879  	
880  	  // Assumptions:
881  	  // All elements in __names are unique.
882  	  template<typename _CharT, typename _InIter>
883  	    _InIter
884  	    time_get<_CharT, _InIter>::
885  	    _M_extract_name(iter_type __beg, iter_type __end, int& __member,
886  			    const _CharT** __names, size_t __indexlen,
887  			    ios_base& __io, ios_base::iostate& __err) const
888  	    {
889  	      typedef char_traits<_CharT>		__traits_type;
890  	      const locale& __loc = __io._M_getloc();
891  	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
892  	
893  	      int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
894  								  * __indexlen));
895  	      size_t __nmatches = 0;
896  	      size_t __pos = 0;
897  	      bool __testvalid = true;
898  	      const char_type* __name;
899  	
900  	      // Look for initial matches.
901  	      // NB: Some of the locale data is in the form of all lowercase
902  	      // names, and some is in the form of initially-capitalized
903  	      // names. Look for both.
904  	      if (__beg != __end)
905  		{
906  		  const char_type __c = *__beg;
907  		  for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
908  		    if (__c == __names[__i1][0]
909  			|| __c == __ctype.toupper(__names[__i1][0]))
910  		      __matches[__nmatches++] = __i1;
911  		}
912  	
913  	      while (__nmatches > 1)
914  		{
915  		  // Find smallest matching string.
916  		  size_t __minlen = __traits_type::length(__names[__matches[0]]);
917  		  for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
918  		    __minlen = std::min(__minlen,
919  				      __traits_type::length(__names[__matches[__i2]]));
920  		  ++__beg, ++__pos;
921  		  if (__pos < __minlen && __beg != __end)
922  		    for (size_t __i3 = 0; __i3 < __nmatches;)
923  		      {
924  			__name = __names[__matches[__i3]];
925  			if (!(__name[__pos] == *__beg))
926  			  __matches[__i3] = __matches[--__nmatches];
927  			else
928  			  ++__i3;
929  		      }
930  		  else
931  		    break;
932  		}
933  	
934  	      if (__nmatches == 1)
935  		{
936  		  // Make sure found name is completely extracted.
937  		  ++__beg, ++__pos;
938  		  __name = __names[__matches[0]];
939  		  const size_t __len = __traits_type::length(__name);
940  		  while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
941  		    ++__beg, ++__pos;
942  	
943  		  if (__len == __pos)
944  		    __member = __matches[0];
945  		  else
946  		    __testvalid = false;
947  		}
948  	      else
949  		__testvalid = false;
950  	      if (!__testvalid)
951  		__err |= ios_base::failbit;
952  	
953  	      return __beg;
954  	    }
955  	
956  	  template<typename _CharT, typename _InIter>
957  	    _InIter
958  	    time_get<_CharT, _InIter>::
959  	    _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
960  				     const _CharT** __names, size_t __indexlen,
961  				     ios_base& __io, ios_base::iostate& __err) const
962  	    {
963  	      typedef char_traits<_CharT>		__traits_type;
964  	      const locale& __loc = __io._M_getloc();
965  	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
966  	
967  	      int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int)
968  								  * __indexlen));
969  	      size_t __nmatches = 0;
970  	      size_t* __matches_lengths = 0;
971  	      size_t __pos = 0;
972  	
973  	      if (__beg != __end)
974  		{
975  		  const char_type __c = *__beg;
976  		  for (size_t __i = 0; __i < 2 * __indexlen; ++__i)
977  		    if (__c == __names[__i][0]
978  			|| __c == __ctype.toupper(__names[__i][0]))
979  		      __matches[__nmatches++] = __i;
980  		}
981  	
982  	      if (__nmatches)
983  		{
984  		  ++__beg, ++__pos;
985  	
986  		  __matches_lengths
987  		    = static_cast<size_t*>(__builtin_alloca(sizeof(size_t)
988  							    * __nmatches));
989  		  for (size_t __i = 0; __i < __nmatches; ++__i)
990  		    __matches_lengths[__i]
991  		      = __traits_type::length(__names[__matches[__i]]);
992  		}
993  	
994  	      for (; __beg != __end; ++__beg, ++__pos)
995  		{
996  		  size_t __nskipped = 0;
997  		  const char_type __c = *__beg;
998  		  for (size_t __i = 0; __i < __nmatches;)
999  		    {
1000 		      const char_type* __name = __names[__matches[__i]];
1001 		      if (__pos >= __matches_lengths[__i])
1002 			++__nskipped, ++__i;
1003 		      else if (!(__name[__pos] == __c))
1004 			{
1005 			  --__nmatches;
1006 			  __matches[__i] = __matches[__nmatches];
1007 			  __matches_lengths[__i] = __matches_lengths[__nmatches];
1008 			}
1009 		      else
1010 			++__i;
1011 		    }
1012 		  if (__nskipped == __nmatches)
1013 		    break;
1014 		}
1015 	
1016 	      if ((__nmatches == 1 && __matches_lengths[0] == __pos)
1017 		  || (__nmatches == 2 && (__matches_lengths[0] == __pos
1018 					  || __matches_lengths[1] == __pos)))
1019 		__member = (__matches[0] >= __indexlen
1020 			    ? __matches[0] - __indexlen : __matches[0]);
1021 	      else
1022 		__err |= ios_base::failbit;
1023 	
1024 	      return __beg;
1025 	    }
1026 	
1027 	  template<typename _CharT, typename _InIter>
1028 	    _InIter
1029 	    time_get<_CharT, _InIter>::
1030 	    do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1031 			ios_base::iostate& __err, tm* __tm) const
1032 	    {
1033 	      const locale& __loc = __io._M_getloc();
1034 	      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1035 	      const char_type*  __times[2];
1036 	      __tp._M_time_formats(__times);
1037 	      __beg = _M_extract_via_format(__beg, __end, __io, __err, 
1038 					    __tm, __times[0]);
1039 	      if (__beg == __end)
1040 		__err |= ios_base::eofbit;
1041 	      return __beg;
1042 	    }
1043 	
1044 	  template<typename _CharT, typename _InIter>
1045 	    _InIter
1046 	    time_get<_CharT, _InIter>::
1047 	    do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1048 			ios_base::iostate& __err, tm* __tm) const
1049 	    {
1050 	      const locale& __loc = __io._M_getloc();
1051 	      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1052 	      const char_type*  __dates[2];
1053 	      __tp._M_date_formats(__dates);
1054 	      __beg = _M_extract_via_format(__beg, __end, __io, __err, 
1055 					    __tm, __dates[0]);
1056 	      if (__beg == __end)
1057 		__err |= ios_base::eofbit;
1058 	      return __beg;
1059 	    }
1060 	
1061 	  template<typename _CharT, typename _InIter>
1062 	    _InIter
1063 	    time_get<_CharT, _InIter>::
1064 	    do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
1065 			   ios_base::iostate& __err, tm* __tm) const
1066 	    {
1067 	      typedef char_traits<_CharT>		__traits_type;
1068 	      const locale& __loc = __io._M_getloc();
1069 	      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1070 	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1071 	      const char_type* __days[14];
1072 	      __tp._M_days_abbreviated(__days);
1073 	      __tp._M_days(__days + 7);
1074 	      int __tmpwday;
1075 	      ios_base::iostate __tmperr = ios_base::goodbit;
1076 	
1077 	      __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7,
1078 					       __io, __tmperr);
1079 	      if (!__tmperr)
1080 		__tm->tm_wday = __tmpwday;
1081 	      else
1082 		__err |= ios_base::failbit;
1083 	
1084 	      if (__beg == __end)
1085 		__err |= ios_base::eofbit;
1086 	      return __beg;
1087 	     }
1088 	
1089 	  template<typename _CharT, typename _InIter>
1090 	    _InIter
1091 	    time_get<_CharT, _InIter>::
1092 	    do_get_monthname(iter_type __beg, iter_type __end,
1093 	                     ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1094 	    {
1095 	      typedef char_traits<_CharT>		__traits_type;
1096 	      const locale& __loc = __io._M_getloc();
1097 	      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1098 	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1099 	      const char_type*  __months[24];
1100 	      __tp._M_months_abbreviated(__months);
1101 	      __tp._M_months(__months + 12);
1102 	      int __tmpmon;
1103 	      ios_base::iostate __tmperr = ios_base::goodbit;
1104 	
1105 	      __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12,
1106 					       __io, __tmperr);
1107 	      if (!__tmperr)
1108 		__tm->tm_mon = __tmpmon;
1109 	      else
1110 		__err |= ios_base::failbit;
1111 	
1112 	      if (__beg == __end)
1113 		__err |= ios_base::eofbit;
1114 	      return __beg;
1115 	    }
1116 	
1117 	  template<typename _CharT, typename _InIter>
1118 	    _InIter
1119 	    time_get<_CharT, _InIter>::
1120 	    do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
1121 			ios_base::iostate& __err, tm* __tm) const
1122 	    {
1123 	      const locale& __loc = __io._M_getloc();
1124 	      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1125 	      int __tmpyear;
1126 	      ios_base::iostate __tmperr = ios_base::goodbit;
1127 	
1128 	      __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4,
1129 				     __io, __tmperr);
1130 	      if (!__tmperr)
1131 		__tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900;
1132 	      else
1133 		__err |= ios_base::failbit;
1134 	
1135 	      if (__beg == __end)
1136 		__err |= ios_base::eofbit;
1137 	      return __beg;
1138 	    }
1139 	
1140 	  template<typename _CharT, typename _OutIter>
1141 	    _OutIter
1142 	    time_put<_CharT, _OutIter>::
1143 	    put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
1144 		const _CharT* __beg, const _CharT* __end) const
1145 	    {
1146 	      const locale& __loc = __io._M_getloc();
1147 	      ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1148 	      for (; __beg != __end; ++__beg)
1149 		if (__ctype.narrow(*__beg, 0) != '%')
1150 		  {
1151 		    *__s = *__beg;
1152 		    ++__s;
1153 		  }
1154 		else if (++__beg != __end)
1155 		  {
1156 		    char __format;
1157 		    char __mod = 0;
1158 		    const char __c = __ctype.narrow(*__beg, 0);
1159 		    if (__c != 'E' && __c != 'O')
1160 		      __format = __c;
1161 		    else if (++__beg != __end)
1162 		      {
1163 			__mod = __c;
1164 			__format = __ctype.narrow(*__beg, 0);
1165 		      }
1166 		    else
1167 		      break;
1168 		    __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
1169 		  }
1170 		else
1171 		  break;
1172 	      return __s;
1173 	    }
1174 	
1175 	  template<typename _CharT, typename _OutIter>
1176 	    _OutIter
1177 	    time_put<_CharT, _OutIter>::
1178 	    do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1179 		   char __format, char __mod) const
1180 	    {
1181 	      const locale& __loc = __io._M_getloc();
1182 	      ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1183 	      __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1184 	
1185 	      // NB: This size is arbitrary. Should this be a data member,
1186 	      // initialized at construction?
1187 	      const size_t __maxlen = 128;
1188 	      char_type __res[__maxlen];
1189 	
1190 	      // NB: In IEE 1003.1-200x, and perhaps other locale models, it
1191 	      // is possible that the format character will be longer than one
1192 	      // character. Possibilities include 'E' or 'O' followed by a
1193 	      // format character: if __mod is not the default argument, assume
1194 	      // it's a valid modifier.
1195 	      char_type __fmt[4];
1196 	      __fmt[0] = __ctype.widen('%');
1197 	      if (!__mod)
1198 		{
1199 		  __fmt[1] = __format;
1200 		  __fmt[2] = char_type();
1201 		}
1202 	      else
1203 		{
1204 		  __fmt[1] = __mod;
1205 		  __fmt[2] = __format;
1206 		  __fmt[3] = char_type();
1207 		}
1208 	
1209 	      __tp._M_put(__res, __maxlen, __fmt, __tm);
1210 	
1211 	      // Write resulting, fully-formatted string to output iterator.
1212 	      return std::__write(__s, __res, char_traits<char_type>::length(__res));
1213 	    }
1214 	
1215 	
1216 	  // Inhibit implicit instantiations for required instantiations,
1217 	  // which are defined via explicit instantiations elsewhere.
1218 	#if _GLIBCXX_EXTERN_TEMPLATE
1219 	  extern template class moneypunct<char, false>;
1220 	  extern template class moneypunct<char, true>;
1221 	  extern template class moneypunct_byname<char, false>;
1222 	  extern template class moneypunct_byname<char, true>;
1223 	  extern template class _GLIBCXX_NAMESPACE_LDBL money_get<char>;
1224 	  extern template class _GLIBCXX_NAMESPACE_LDBL money_put<char>;
1225 	  extern template class __timepunct<char>;
1226 	  extern template class time_put<char>;
1227 	  extern template class time_put_byname<char>;
1228 	  extern template class time_get<char>;
1229 	  extern template class time_get_byname<char>;
1230 	  extern template class messages<char>;
1231 	  extern template class messages_byname<char>;
1232 	
1233 	  extern template
1234 	    const moneypunct<char, true>&
1235 	    use_facet<moneypunct<char, true> >(const locale&);
1236 	
1237 	  extern template
1238 	    const moneypunct<char, false>&
1239 	    use_facet<moneypunct<char, false> >(const locale&);
1240 	
1241 	  extern template
1242 	    const money_put<char>&
1243 	    use_facet<money_put<char> >(const locale&);
1244 	
1245 	  extern template
1246 	    const money_get<char>&
1247 	    use_facet<money_get<char> >(const locale&);
1248 	
1249 	  extern template
1250 	    const __timepunct<char>&
1251 	    use_facet<__timepunct<char> >(const locale&);
1252 	
1253 	  extern template
1254 	    const time_put<char>&
1255 	    use_facet<time_put<char> >(const locale&);
1256 	
1257 	  extern template
1258 	    const time_get<char>&
1259 	    use_facet<time_get<char> >(const locale&);
1260 	
1261 	  extern template
1262 	    const messages<char>&
1263 	    use_facet<messages<char> >(const locale&);
1264 	
1265 	  extern template
1266 	    bool
1267 	    has_facet<moneypunct<char> >(const locale&);
1268 	
1269 	  extern template
1270 	    bool
1271 	    has_facet<money_put<char> >(const locale&);
1272 	
1273 	  extern template
1274 	    bool
1275 	    has_facet<money_get<char> >(const locale&);
1276 	
1277 	  extern template
1278 	    bool
1279 	    has_facet<__timepunct<char> >(const locale&);
1280 	
1281 	  extern template
1282 	    bool
1283 	    has_facet<time_put<char> >(const locale&);
1284 	
1285 	  extern template
1286 	    bool
1287 	    has_facet<time_get<char> >(const locale&);
1288 	
1289 	  extern template
1290 	    bool
1291 	    has_facet<messages<char> >(const locale&);
1292 	
1293 	#ifdef _GLIBCXX_USE_WCHAR_T
1294 	  extern template class moneypunct<wchar_t, false>;
1295 	  extern template class moneypunct<wchar_t, true>;
1296 	  extern template class moneypunct_byname<wchar_t, false>;
1297 	  extern template class moneypunct_byname<wchar_t, true>;
1298 	  extern template class _GLIBCXX_NAMESPACE_LDBL money_get<wchar_t>;
1299 	  extern template class _GLIBCXX_NAMESPACE_LDBL money_put<wchar_t>;
1300 	  extern template class __timepunct<wchar_t>;
1301 	  extern template class time_put<wchar_t>;
1302 	  extern template class time_put_byname<wchar_t>;
1303 	  extern template class time_get<wchar_t>;
1304 	  extern template class time_get_byname<wchar_t>;
1305 	  extern template class messages<wchar_t>;
1306 	  extern template class messages_byname<wchar_t>;
1307 	
1308 	  extern template
1309 	    const moneypunct<wchar_t, true>&
1310 	    use_facet<moneypunct<wchar_t, true> >(const locale&);
1311 	
1312 	  extern template
1313 	    const moneypunct<wchar_t, false>&
1314 	    use_facet<moneypunct<wchar_t, false> >(const locale&);
1315 	
1316 	  extern template
1317 	    const money_put<wchar_t>&
1318 	    use_facet<money_put<wchar_t> >(const locale&);
1319 	
1320 	  extern template
1321 	    const money_get<wchar_t>&
1322 	    use_facet<money_get<wchar_t> >(const locale&);
1323 	
1324 	  extern template
1325 	    const __timepunct<wchar_t>&
1326 	    use_facet<__timepunct<wchar_t> >(const locale&);
1327 	
1328 	  extern template
1329 	    const time_put<wchar_t>&
1330 	    use_facet<time_put<wchar_t> >(const locale&);
1331 	
1332 	  extern template
1333 	    const time_get<wchar_t>&
1334 	    use_facet<time_get<wchar_t> >(const locale&);
1335 	
1336 	  extern template
1337 	    const messages<wchar_t>&
1338 	    use_facet<messages<wchar_t> >(const locale&);
1339 	
1340 	  extern template
1341 	    bool
1342 	    has_facet<moneypunct<wchar_t> >(const locale&);
1343 	
1344 	  extern template
1345 	    bool
1346 	    has_facet<money_put<wchar_t> >(const locale&);
1347 	
1348 	  extern template
1349 	    bool
1350 	    has_facet<money_get<wchar_t> >(const locale&);
1351 	
1352 	  extern template
1353 	    bool
1354 	    has_facet<__timepunct<wchar_t> >(const locale&);
1355 	
1356 	  extern template
1357 	    bool
1358 	    has_facet<time_put<wchar_t> >(const locale&);
1359 	
1360 	  extern template
1361 	    bool
1362 	    has_facet<time_get<wchar_t> >(const locale&);
1363 	
1364 	  extern template
1365 	    bool
1366 	    has_facet<messages<wchar_t> >(const locale&);
1367 	#endif
1368 	#endif
1369 	
1370 	_GLIBCXX_END_NAMESPACE_VERSION
1371 	} // namespace std
1372 	
1373 	#endif
1374