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