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