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