libstdc++
locale_facets_nonio.tcc
Go to the documentation of this file.
1 // Locale support -*- C++ -*-
2 
3 // Copyright (C) 2007-2026 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 #ifdef _GLIBCXX_SYSHDR
34 #pragma GCC system_header
35 #endif
36 
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
40 
41  template<typename _CharT, bool _Intl>
42  struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
43  {
44  const __moneypunct_cache<_CharT, _Intl>*
45  operator() (const locale& __loc) const
46  {
47  const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
48  const locale::facet** __caches = __loc._M_impl->_M_caches;
49  if (!__caches[__i])
50  {
51  __moneypunct_cache<_CharT, _Intl>* __tmp = 0;
52  __try
53  {
54  __tmp = new __moneypunct_cache<_CharT, _Intl>;
55  __tmp->_M_cache(__loc);
56  }
57  __catch(...)
58  {
59  delete __tmp;
60  __throw_exception_again;
61  }
62  __loc._M_impl->_M_install_cache(__tmp, __i);
63  }
64  return static_cast<
65  const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
66  }
67  };
68 
69  template<typename _CharT, bool _Intl>
70  void
71  __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
72  {
73  const moneypunct<_CharT, _Intl>& __mp =
74  use_facet<moneypunct<_CharT, _Intl> >(__loc);
75 
76  struct _Scoped_str
77  {
78  size_t _M_len;
79  _CharT* _M_str;
80 
81  explicit
82  _Scoped_str(const basic_string<_CharT>& __str)
83  : _M_len(__str.size()), _M_str(new _CharT[_M_len])
84  { __str.copy(_M_str, _M_len); }
85 
86  ~_Scoped_str() { delete[] _M_str; }
87 
88  void
89  _M_release(const _CharT*& __p, size_t& __n)
90  {
91  __p = _M_str;
92  __n = _M_len;
93  _M_str = 0;
94  }
95  };
96 
97  _Scoped_str __curr_symbol(__mp.curr_symbol());
98  _Scoped_str __positive_sign(__mp.positive_sign());
99  _Scoped_str __negative_sign(__mp.negative_sign());
100 
101  const string& __g = __mp.grouping();
102  const size_t __g_size = __g.size();
103  char* const __grouping = new char[__g_size];
104  __g.copy(__grouping, __g_size);
105 
106  // All allocations succeeded without throwing, OK to modify *this now.
107 
108  _M_grouping = __grouping;
109  _M_grouping_size = __g_size;
110  _M_use_grouping = (__g_size
111  && static_cast<signed char>(__grouping[0]) > 0
112  && (__grouping[0]
113  != __gnu_cxx::__numeric_traits<char>::__max));
114 
115  _M_decimal_point = __mp.decimal_point();
116  _M_thousands_sep = __mp.thousands_sep();
117 
118  __curr_symbol._M_release(_M_curr_symbol, _M_curr_symbol_size);
119  __positive_sign._M_release(_M_positive_sign, _M_positive_sign_size);
120  __negative_sign._M_release(_M_negative_sign, _M_negative_sign_size);
121 
122  _M_frac_digits = __mp.frac_digits();
123  _M_pos_format = __mp.pos_format();
124  _M_neg_format = __mp.neg_format();
125 
126  const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
127  __ct.widen(money_base::_S_atoms,
128  money_base::_S_atoms + money_base::_S_end, _M_atoms);
129 
130  _M_allocated = true;
131  }
132 
133 _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
134 
135  template<typename _CharT, typename _InIter>
136  template<bool _Intl>
137  _InIter
138  money_get<_CharT, _InIter>::
139  _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
140  ios_base::iostate& __err, string& __units) const
141  {
142  typedef char_traits<_CharT> __traits_type;
143  typedef typename string_type::size_type size_type;
144  typedef money_base::part part;
145  typedef __moneypunct_cache<_CharT, _Intl> __cache_type;
146 
147  const locale& __loc = __io._M_getloc();
148  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
149 
150  __use_cache<__cache_type> __uc;
151  const __cache_type* __lc = __uc(__loc);
152  const char_type* __lit = __lc->_M_atoms;
153 
154  // Deduced sign.
155  bool __negative = false;
156  // Sign size.
157  size_type __sign_size = 0;
158  // True if sign is mandatory.
159  const bool __mandatory_sign = (__lc->_M_positive_sign_size
160  && __lc->_M_negative_sign_size);
161  // String of grouping info from thousands_sep plucked from __units.
162  string __grouping_tmp;
163  if (__lc->_M_use_grouping)
164  __grouping_tmp.reserve(32);
165  // Last position before the decimal point.
166  int __last_pos = 0;
167  // Separator positions, then, possibly, fractional digits.
168  int __n = 0;
169  // If input iterator is in a valid state.
170  bool __testvalid = true;
171  // Flag marking when a decimal point is found.
172  bool __testdecfound = false;
173 
174  // The tentative returned string is stored here.
175  string __res;
176  __res.reserve(32);
177 
178  const char_type* __lit_zero = __lit + money_base::_S_zero;
179  const money_base::pattern __p = __lc->_M_neg_format;
180  for (int __i = 0; __i < 4 && __testvalid; ++__i)
181  {
182  const part __which = static_cast<part>(__p.field[__i]);
183  switch (__which)
184  {
185  case money_base::symbol:
186  // According to 22.2.6.1.2, p2, symbol is required
187  // if (__io.flags() & ios_base::showbase), otherwise
188  // is optional and consumed only if other characters
189  // are needed to complete the format.
190  if (__io.flags() & ios_base::showbase || __sign_size > 1
191  || __i == 0
192  || (__i == 1 && (__mandatory_sign
193  || (static_cast<part>(__p.field[0])
194  == money_base::sign)
195  || (static_cast<part>(__p.field[2])
196  == money_base::space)))
197  || (__i == 2 && ((static_cast<part>(__p.field[3])
198  == money_base::value)
199  || (__mandatory_sign
200  && (static_cast<part>(__p.field[3])
201  == money_base::sign)))))
202  {
203  const size_type __len = __lc->_M_curr_symbol_size;
204  size_type __j = 0;
205  for (; __beg != __end && __j < __len
206  && *__beg == __lc->_M_curr_symbol[__j];
207  ++__beg, (void)++__j);
208  if (__j != __len
209  && (__j || __io.flags() & ios_base::showbase))
210  __testvalid = false;
211  }
212  break;
213  case money_base::sign:
214  // Sign might not exist, or be more than one character long.
215  if (__lc->_M_positive_sign_size && __beg != __end
216  && *__beg == __lc->_M_positive_sign[0])
217  {
218  __sign_size = __lc->_M_positive_sign_size;
219  ++__beg;
220  }
221  else if (__lc->_M_negative_sign_size && __beg != __end
222  && *__beg == __lc->_M_negative_sign[0])
223  {
224  __negative = true;
225  __sign_size = __lc->_M_negative_sign_size;
226  ++__beg;
227  }
228  else if (__lc->_M_positive_sign_size
229  && !__lc->_M_negative_sign_size)
230  // "... if no sign is detected, the result is given the sign
231  // that corresponds to the source of the empty string"
232  __negative = true;
233  else if (__mandatory_sign)
234  __testvalid = false;
235  break;
236  case money_base::value:
237  // Extract digits, remove and stash away the
238  // grouping of found thousands separators.
239  for (; __beg != __end; ++__beg)
240  {
241  const char_type __c = *__beg;
242  const char_type* __q = __traits_type::find(__lit_zero,
243  10, __c);
244  if (__q != 0)
245  {
246  __res += money_base::_S_atoms[__q - __lit];
247  ++__n;
248  }
249  else if (__c == __lc->_M_decimal_point
250  && !__testdecfound)
251  {
252  if (__lc->_M_frac_digits <= 0)
253  break;
254 
255  __last_pos = __n;
256  __n = 0;
257  __testdecfound = true;
258  }
259  else if (__lc->_M_use_grouping
260  && __c == __lc->_M_thousands_sep
261  && !__testdecfound)
262  {
263  if (__n)
264  {
265  // Mark position for later analysis.
266  __grouping_tmp += static_cast<char>(__n);
267  __n = 0;
268  }
269  else
270  {
271  __testvalid = false;
272  break;
273  }
274  }
275  else
276  break;
277  }
278  if (__res.empty())
279  __testvalid = false;
280  break;
281  case money_base::space:
282  // At least one space is required.
283  if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
284  ++__beg;
285  else
286  __testvalid = false;
287  // fallthrough
288  case money_base::none:
289  // Only if not at the end of the pattern.
290  if (__i != 3)
291  for (; __beg != __end
292  && __ctype.is(ctype_base::space, *__beg); ++__beg);
293  break;
294  }
295  }
296 
297  // Need to get the rest of the sign characters, if they exist.
298  if (__sign_size > 1 && __testvalid)
299  {
300  const char_type* __sign = __negative ? __lc->_M_negative_sign
301  : __lc->_M_positive_sign;
302  size_type __i = 1;
303  for (; __beg != __end && __i < __sign_size
304  && *__beg == __sign[__i]; ++__beg, (void)++__i);
305 
306  if (__i != __sign_size)
307  __testvalid = false;
308  }
309 
310  if (__testvalid)
311  {
312  // Strip leading zeros.
313  if (__res.size() > 1)
314  {
315  const size_type __first = __res.find_first_not_of('0');
316  const bool __only_zeros = __first == string::npos;
317  if (__first)
318  __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
319  }
320 
321  // 22.2.6.1.2, p4
322  if (__negative && __res[0] != '0')
323  __res.insert(__res.begin(), '-');
324 
325  // Test for grouping fidelity.
326  if (__grouping_tmp.size())
327  {
328  // Add the ending grouping.
329  __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
330  : __n);
331  if (!std::__verify_grouping(__lc->_M_grouping,
332  __lc->_M_grouping_size,
333  __grouping_tmp))
334  __err |= ios_base::failbit;
335  }
336 
337  // Iff not enough digits were supplied after the decimal-point.
338  if (__testdecfound && __n != __lc->_M_frac_digits)
339  __testvalid = false;
340  }
341 
342  // Iff valid sequence is not recognized.
343  if (!__testvalid)
344  __err |= ios_base::failbit;
345  else
346  __units.swap(__res);
347 
348  // Iff no more characters are available.
349  if (__beg == __end)
350  __err |= ios_base::eofbit;
351  return __beg;
352  }
353 
354 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
355  && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
356  template<typename _CharT, typename _InIter>
357  _InIter
358  money_get<_CharT, _InIter>::
359  __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
360  ios_base::iostate& __err, double& __units) const
361  {
362  string __str;
363  __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
364  : _M_extract<false>(__beg, __end, __io, __err, __str);
365  std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
366  return __beg;
367  }
368 #endif
369 
370  template<typename _CharT, typename _InIter>
371  _InIter
373  do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
374  ios_base::iostate& __err, long double& __units) const
375  {
376  string __str;
377  __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
378  : _M_extract<false>(__beg, __end, __io, __err, __str);
379  std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
380  return __beg;
381  }
382 
383  template<typename _CharT, typename _InIter>
384  _InIter
386  do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
387  ios_base::iostate& __err, string_type& __digits) const
388  {
389  typedef typename string::size_type size_type;
390 
391  const locale& __loc = __io._M_getloc();
392  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
393 
394  string __str;
395  __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
396  : _M_extract<false>(__beg, __end, __io, __err, __str);
397  const size_type __len = __str.size();
398  if (__len)
399  {
400  __digits.resize(__len);
401  __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]);
402  }
403  return __beg;
404  }
405 
406 #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
407  && defined __LONG_DOUBLE_IEEE128__
408  template<typename _CharT, typename _InIter>
409  _InIter
411  __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
412  ios_base::iostate& __err, __ibm128& __units) const
413  {
414  string __str;
415  __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
416  : _M_extract<false>(__beg, __end, __io, __err, __str);
417  std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
418  return __beg;
419  }
420 #endif
421 
422  template<typename _CharT, typename _OutIter>
423  template<bool _Intl>
424  _OutIter
426  _M_insert(iter_type __s, ios_base& __io, char_type __fill,
427  const string_type& __digits) const
428  {
429  typedef typename string_type::size_type size_type;
430  typedef money_base::part part;
431  typedef __moneypunct_cache<_CharT, _Intl> __cache_type;
432 
433  const locale& __loc = __io._M_getloc();
434  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
435 
436  __use_cache<__cache_type> __uc;
437  const __cache_type* __lc = __uc(__loc);
438  const char_type* __lit = __lc->_M_atoms;
439 
440  // Determine if negative or positive formats are to be used, and
441  // discard leading negative_sign if it is present.
442  const char_type* __beg = __digits.data();
443 
444  money_base::pattern __p;
445  const char_type* __sign;
446  size_type __sign_size;
447  if (!(*__beg == __lit[money_base::_S_minus]))
448  {
449  __p = __lc->_M_pos_format;
450  __sign = __lc->_M_positive_sign;
451  __sign_size = __lc->_M_positive_sign_size;
452  }
453  else
454  {
455  __p = __lc->_M_neg_format;
456  __sign = __lc->_M_negative_sign;
457  __sign_size = __lc->_M_negative_sign_size;
458  if (__digits.size())
459  ++__beg;
460  }
461 
462  // Look for valid numbers in the ctype facet within input digits.
463  size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
464  __beg + __digits.size()) - __beg;
465  if (__len)
466  {
467  // Assume valid input, and attempt to format.
468  // Break down input numbers into base components, as follows:
469  // final_value = grouped units + (decimal point) + (digits)
470  string_type __value;
471  __value.reserve(2 * __len);
472 
473  // Add thousands separators to non-decimal digits, per
474  // grouping rules.
475  long __paddec = __len - __lc->_M_frac_digits;
476  if (__paddec > 0)
477  {
478  if (__lc->_M_frac_digits < 0)
479  __paddec = __len;
480  if (__lc->_M_grouping_size)
481  {
482  __value.assign(2 * __paddec, char_type());
483  _CharT* __vend =
484  std::__add_grouping(&__value[0], __lc->_M_thousands_sep,
485  __lc->_M_grouping,
486  __lc->_M_grouping_size,
487  __beg, __beg + __paddec);
488  __value.erase(__vend - &__value[0]);
489  }
490  else
491  __value.assign(__beg, __paddec);
492  }
493 
494  // Deal with decimal point, decimal digits.
495  if (__lc->_M_frac_digits > 0)
496  {
497  __value += __lc->_M_decimal_point;
498  if (__paddec >= 0)
499  __value.append(__beg + __paddec, __lc->_M_frac_digits);
500  else
501  {
502  // Have to pad zeros in the decimal position.
503  __value.append(-__paddec, __lit[money_base::_S_zero]);
504  __value.append(__beg, __len);
505  }
506  }
507 
508  // Calculate length of resulting string.
509  const ios_base::fmtflags __f = __io.flags()
511  __len = __value.size() + __sign_size;
512  __len += ((__io.flags() & ios_base::showbase)
513  ? __lc->_M_curr_symbol_size : 0);
514 
515  string_type __res;
516  __res.reserve(2 * __len);
517 
518  const size_type __width = static_cast<size_type>(__io.width());
519  const bool __testipad = (__f == ios_base::internal
520  && __len < __width);
521  // Fit formatted digits into the required pattern.
522  for (int __i = 0; __i < 4; ++__i)
523  {
524  const part __which = static_cast<part>(__p.field[__i]);
525  switch (__which)
526  {
527  case money_base::symbol:
528  if (__io.flags() & ios_base::showbase)
529  __res.append(__lc->_M_curr_symbol,
530  __lc->_M_curr_symbol_size);
531  break;
532  case money_base::sign:
533  // Sign might not exist, or be more than one
534  // character long. In that case, add in the rest
535  // below.
536  if (__sign_size)
537  __res += __sign[0];
538  break;
539  case money_base::value:
540  __res += __value;
541  break;
542  case money_base::space:
543  // At least one space is required, but if internal
544  // formatting is required, an arbitrary number of
545  // fill spaces will be necessary.
546  if (__testipad)
547  __res.append(__width - __len, __fill);
548  else
549  __res += __fill;
550  break;
551  case money_base::none:
552  if (__testipad)
553  __res.append(__width - __len, __fill);
554  break;
555  }
556  }
557 
558  // Special case of multi-part sign parts.
559  if (__sign_size > 1)
560  __res.append(__sign + 1, __sign_size - 1);
561 
562  // Pad, if still necessary.
563  __len = __res.size();
564  if (__width > __len)
565  {
566  if (__f == ios_base::left)
567  // After.
568  __res.append(__width - __len, __fill);
569  else
570  // Before.
571  __res.insert(0, __width - __len, __fill);
572  __len = __width;
573  }
574 
575  // Write resulting, fully-formatted string to output iterator.
576  __s = std::__write(__s, __res.data(), __len);
577  }
578  __io.width(0);
579  return __s;
580  }
581 
582 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \
583  && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__)
584  template<typename _CharT, typename _OutIter>
585  _OutIter
587  __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
588  double __units) const
589  { return this->do_put(__s, __intl, __io, __fill, (long double) __units); }
590 #endif
591 
592  template<typename _CharT, typename _OutIter>
593  _OutIter
595  do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
596  long double __units) const
597  {
598  const locale __loc = __io.getloc();
599  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
600 #if _GLIBCXX_USE_C99_STDIO
601  // First try a buffer perhaps big enough.
602  int __cs_size = 64;
603  char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
604  // _GLIBCXX_RESOLVE_LIB_DEFECTS
605  // 328. Bad sprintf format modifier in money_put<>::do_put()
606  int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
607  "%.*Lf", 0, __units);
608  // If the buffer was not large enough, try again with the correct size.
609  if (__len >= __cs_size)
610  {
611  __cs_size = __len + 1;
612  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
613  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
614  "%.*Lf", 0, __units);
615  }
616 #else
617  // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
618  const int __cs_size =
619  __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
620  char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
621  int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf",
622  0, __units);
623 #endif
624  string_type __digits(__len, char_type());
625  __ctype.widen(__cs, __cs + __len, &__digits[0]);
626  return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
627  : _M_insert<false>(__s, __io, __fill, __digits);
628  }
629 
630  template<typename _CharT, typename _OutIter>
631  _OutIter
633  do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
634  const string_type& __digits) const
635  { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
636  : _M_insert<false>(__s, __io, __fill, __digits); }
637 
638 #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
639  && defined __LONG_DOUBLE_IEEE128__
640 // The snprintf symbol in glibc that works with __ibm128 format is not visible
641 // when compiling with -mabi=ieeelongdouble so we use this name for it instead.
642 // N.B. we don't use __typeof__(__builtin_snprintf) for the type because that
643 // would inherit __attribute__((format(printf, 3, 4))) and give a warning for
644 // passing __ibm128 to %Lf instead of long double. The warning would be wrong
645 // because long double in this TU is __ieee128 and snprintf expects __ibm128.
646 extern "C" int
647 __glibcxx_snprintfibm128(char*, size_t, const char*, ...) __asm__("snprintf");
648 
649  template<typename _CharT, typename _OutIter>
650  _OutIter
652  __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
653  __ibm128 __units) const
654  {
655  const locale __loc = __io.getloc();
656  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
657  // First try a buffer perhaps big enough.
658  int __cs_size = 64;
659  char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
660  const __c_locale __old = __gnu_cxx::__uselocale(_S_get_c_locale());
661 
662  // _GLIBCXX_RESOLVE_LIB_DEFECTS
663  // 328. Bad sprintf format modifier in money_put<>::do_put()
664  int __len = __glibcxx_snprintfibm128(__cs, __cs_size, "%.*Lf", 0,
665  __units);
666  // If the buffer was not large enough, try again with the correct size.
667  if (__len >= __cs_size)
668  {
669  __cs_size = __len + 1;
670  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
671  __len = __glibcxx_snprintfibm128(__cs, __cs_size, "%.*Lf", 0,
672  __units);
673  }
674  __gnu_cxx::__uselocale(__old);
675  string_type __digits(__len, char_type());
676  __ctype.widen(__cs, __cs + __len, &__digits[0]);
677  return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
678  : _M_insert<false>(__s, __io, __fill, __digits);
679  }
680 #endif
681 
682 _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
683 
684  // NB: Not especially useful. Without an ios_base object or some
685  // kind of locale reference, we are left clawing at the air where
686  // the side of the mountain used to be...
687  template<typename _CharT, typename _InIter>
688  time_base::dateorder
690  { return time_base::no_order; }
691 
692  // Expand a strptime format string and parse it. E.g., do_get_date() may
693  // pass %m/%d/%Y => extracted characters.
694  template<typename _CharT, typename _InIter>
695  _InIter
698  ios_base::iostate& __err, tm* __tm,
699  const _CharT* __format,
700  __time_get_state &__state) const
701  {
702  const locale& __loc = __io._M_getloc();
703  const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
704  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
705  const size_t __len = char_traits<_CharT>::length(__format);
706 
707  ios_base::iostate __tmperr = ios_base::goodbit;
708  size_t __i = 0;
709  for (; __beg != __end && __i < __len && !__tmperr; ++__i)
710  {
711  if (__ctype.narrow(__format[__i], 0) == '%')
712  {
713  // Verify valid formatting code, attempt to extract.
714  char __c = __ctype.narrow(__format[++__i], 0);
715  int __mem = 0;
716  if (__c == 'E' || __c == 'O')
717  __c = __ctype.narrow(__format[++__i], 0);
718  switch (__c)
719  {
720  const char* __cs;
721  _CharT __wcs[10];
722  case 'a':
723  case 'A':
724  // Weekday name (possibly abbreviated) [tm_wday]
725  const char_type* __days[14];
726  __tp._M_days(&__days[0]);
727  __tp._M_days_abbreviated(&__days[7]);
728  __beg = _M_extract_name(__beg, __end, __mem, __days,
729  14, __io, __tmperr);
730  if (!__tmperr)
731  {
732  __tm->tm_wday = __mem % 7;
733  __state._M_have_wday = 1;
734  }
735  break;
736  case 'h':
737  case 'b':
738  case 'B':
739  // Month name (possibly abbreviated) [tm_mon]
740  const char_type* __months[24];
741  __tp._M_months(&__months[0]);
742  __tp._M_months_abbreviated(&__months[12]);
743  __beg = _M_extract_name(__beg, __end, __mem,
744  __months, 24, __io, __tmperr);
745  if (!__tmperr)
746  {
747  __tm->tm_mon = __mem % 12;
748  __state._M_have_mon = 1;
749  __state._M_want_xday = 1;
750  }
751  break;
752  case 'c':
753  // Default time and date representation.
754  const char_type* __dt[2];
755  __tp._M_date_time_formats(__dt);
756  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
757  __tm, __dt[0], __state);
758  if (!__tmperr)
759  __state._M_want_xday = 1;
760  break;
761  case 'C':
762  // Century.
763  __beg = _M_extract_num(__beg, __end, __mem, 0, 99, 2,
764  __io, __tmperr);
765  if (!__tmperr)
766  {
767  __state._M_century = __mem;
768  __state._M_have_century = 1;
769  __state._M_want_xday = 1;
770  }
771  break;
772  case 'd':
773  case 'e':
774  // Day [1, 31]. [tm_mday]
775  if (__ctype.is(ctype_base::space, *__beg))
776  ++__beg;
777  __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2,
778  __io, __tmperr);
779  if (!__tmperr)
780  {
781  __tm->tm_mday = __mem;
782  __state._M_have_mday = 1;
783  __state._M_want_xday = 1;
784  }
785  break;
786  case 'D':
787  // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
788  __cs = "%m/%d/%y";
789  __ctype.widen(__cs, __cs + 9, __wcs);
790  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
791  __tm, __wcs, __state);
792  if (!__tmperr)
793  __state._M_want_xday = 1;
794  break;
795  case 'H':
796  // Hour [00, 23]. [tm_hour]
797  __beg = _M_extract_num(__beg, __end, __mem, 0, 23, 2,
798  __io, __tmperr);
799  if (!__tmperr)
800  {
801  __tm->tm_hour = __mem;
802  __state._M_have_I = 0;
803  }
804  break;
805  case 'I':
806  // Hour [01, 12]. [tm_hour]
807  __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
808  __io, __tmperr);
809  if (!__tmperr)
810  {
811  __tm->tm_hour = __mem % 12;
812  __state._M_have_I = 1;
813  }
814  break;
815  case 'j':
816  // Day number of year.
817  __beg = _M_extract_num(__beg, __end, __mem, 1, 366, 3,
818  __io, __tmperr);
819  if (!__tmperr)
820  {
821  __tm->tm_yday = __mem - 1;
822  __state._M_have_yday = 1;
823  }
824  break;
825  case 'm':
826  // Month [01, 12]. [tm_mon]
827  __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
828  __io, __tmperr);
829  if (!__tmperr)
830  {
831  __tm->tm_mon = __mem - 1;
832  __state._M_have_mon = 1;
833  }
834  break;
835  case 'M':
836  // Minute [00, 59]. [tm_min]
837  __beg = _M_extract_num(__beg, __end, __mem, 0, 59, 2,
838  __io, __tmperr);
839  if (!__tmperr)
840  __tm->tm_min = __mem;
841  break;
842  case 'n':
843  case 't':
844  while (__beg != __end
845  && __ctype.is(ctype_base::space, *__beg))
846  ++__beg;
847  break;
848  case 'p':
849  // Locale's a.m. or p.m.
850  const char_type* __ampm[2];
851  __tp._M_am_pm(&__ampm[0]);
852  if (!__ampm[0][0] || !__ampm[1][0])
853  break;
854  __beg = _M_extract_name(__beg, __end, __mem, __ampm,
855  2, __io, __tmperr);
856  if (!__tmperr && __mem)
857  __state._M_is_pm = 1;
858  break;
859  case 'r':
860  // Locale's 12-hour clock time format (in C %I:%M:%S %p).
861  const char_type* __ampm_format;
862  __tp._M_am_pm_format(&__ampm_format);
863  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
864  __tm, __ampm_format, __state);
865  break;
866  case 'R':
867  // Equivalent to (%H:%M).
868  __cs = "%H:%M";
869  __ctype.widen(__cs, __cs + 6, __wcs);
870  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
871  __tm, __wcs, __state);
872  break;
873  case 'S':
874  // Seconds. [tm_sec]
875  // [00, 60] in C99 (one leap-second), [00, 61] in C89.
876 #if _GLIBCXX_USE_C99
877  __beg = _M_extract_num(__beg, __end, __mem, 0, 60, 2,
878 #else
879  __beg = _M_extract_num(__beg, __end, __mem, 0, 61, 2,
880 #endif
881  __io, __tmperr);
882  if (!__tmperr)
883  __tm->tm_sec = __mem;
884  break;
885  case 'T':
886  // Equivalent to (%H:%M:%S).
887  __cs = "%H:%M:%S";
888  __ctype.widen(__cs, __cs + 9, __wcs);
889  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
890  __tm, __wcs, __state);
891  break;
892  case 'U':
893  // Week number of the year (Sunday as first day of week).
894  __beg = _M_extract_num(__beg, __end, __mem, 0, 53, 2,
895  __io, __tmperr);
896  if (!__tmperr)
897  {
898  __state._M_week_no = __mem;
899  __state._M_have_uweek = 1;
900  }
901  break;
902  case 'w':
903  // Weekday [tm_wday]
904  __beg = _M_extract_num(__beg, __end, __mem, 0, 6, 1,
905  __io, __tmperr);
906  if (!__tmperr)
907  {
908  __tm->tm_wday = __mem;
909  __state._M_have_wday = 1;
910  }
911  break;
912  case 'W':
913  // Week number of the year (Monday as first day of week).
914  __beg = _M_extract_num(__beg, __end, __mem, 0, 53, 2,
915  __io, __tmperr);
916  if (!__tmperr)
917  {
918  __state._M_week_no = __mem;
919  __state._M_have_wweek = 1;
920  }
921  break;
922  case 'x':
923  // Locale's date.
924  const char_type* __dates[2];
925  __tp._M_date_formats(__dates);
926  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
927  __tm, __dates[0], __state);
928  break;
929  case 'X':
930  // Locale's time.
931  const char_type* __times[2];
932  __tp._M_time_formats(__times);
933  __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
934  __tm, __times[0], __state);
935  break;
936  case 'y':
937  // The last 2 digits of year.
938  __beg = _M_extract_num(__beg, __end, __mem, 0, 99, 2,
939  __io, __tmperr);
940  if (!__tmperr)
941  {
942  __state._M_want_century = 1;
943  __state._M_want_xday = 1;
944  // As an extension, if the 2 digits are followed by
945  // 1-2 further digits, treat it like %Y.
946  __c = 0;
947  if (__beg != __end)
948  __c = __ctype.narrow(*__beg, '*');
949  if (__c >= '0' && __c <= '9')
950  {
951  ++__beg;
952  __mem = __mem * 10 + (__c - '0');
953  if (__beg != __end)
954  {
955  __c = __ctype.narrow(*__beg, '*');
956  if (__c >= '0' && __c <= '9')
957  {
958  ++__beg;
959  __mem = __mem * 10 + (__c - '0');
960  }
961  }
962  __mem -= 1900;
963  __state._M_want_century = 0;
964  }
965  // Otherwise, as per POSIX 2008, 00-68 is 2000-2068,
966  // while 69-99 is 1969-1999.
967  else if (__mem < 69)
968  __mem += 100;
969  __tm->tm_year = __mem;
970  }
971  break;
972  case 'Y':
973  // Year.
974  __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
975  __io, __tmperr);
976  if (!__tmperr)
977  {
978  __tm->tm_year = __mem - 1900;
979  __state._M_want_century = 0;
980  __state._M_want_xday = 1;
981  }
982  break;
983  case 'Z':
984  // Timezone info.
985  if (__ctype.is(ctype_base::upper, *__beg))
986  {
987  int __tmp;
988  __beg = _M_extract_name(__beg, __end, __tmp,
989  __timepunct_cache<_CharT>::_S_timezones,
990  14, __io, __tmperr);
991 
992  // GMT requires special effort.
993  if (__beg != __end && !__tmperr && __tmp == 0
994  && (*__beg == __ctype.widen('-')
995  || *__beg == __ctype.widen('+')))
996  {
997  __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
998  __io, __tmperr);
999  __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1000  __io, __tmperr);
1001  }
1002  }
1003  else
1004  __tmperr |= ios_base::failbit;
1005  break;
1006  case '%':
1007  if (*__beg == __ctype.widen('%'))
1008  ++__beg;
1009  else
1010  __tmperr |= ios_base::failbit;
1011  break;
1012  default:
1013  // Not recognized.
1014  __tmperr |= ios_base::failbit;
1015  }
1016  }
1017  else if (__ctype.is(ctype_base::space, __format[__i]))
1018  {
1019  // Skip any whitespace.
1020  while (__beg != __end
1021  && __ctype.is(ctype_base::space, *__beg))
1022  ++__beg;
1023  }
1024  else
1025  {
1026  // Verify format and input match, extract and discard.
1027  // TODO real case-insensitive comparison
1028  if (__ctype.tolower(__format[__i]) == __ctype.tolower(*__beg)
1029  || __ctype.toupper(__format[__i]) == __ctype.toupper(*__beg))
1030  ++__beg;
1031  else
1032  __tmperr |= ios_base::failbit;
1033  }
1034  }
1035 
1036  if (__tmperr || __i != __len)
1037  __err |= ios_base::failbit;
1038 
1039  return __beg;
1040  }
1041 
1042  template<typename _CharT, typename _InIter>
1043  _InIter
1046  ios_base::iostate& __err, tm* __tm,
1047  const _CharT* __format) const
1048  {
1049  __time_get_state __state = __time_get_state();
1050  return _M_extract_via_format(__beg, __end, __io, __err, __tm,
1051  __format, __state);
1052  }
1053 
1054  template<typename _CharT, typename _InIter>
1055  _InIter
1057  _M_extract_num(iter_type __beg, iter_type __end, int& __member,
1058  int __min, int __max, size_t __len,
1059  ios_base& __io, ios_base::iostate& __err) const
1060  {
1061  const locale& __loc = __io._M_getloc();
1062  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1063 
1064  size_t __i = 0;
1065  int __value = 0;
1066  for (; __beg != __end && __i < __len; ++__beg, (void)++__i)
1067  {
1068  const char __c = __ctype.narrow(*__beg, '*');
1069  if (__c >= '0' && __c <= '9')
1070  {
1071  __value = __value * 10 + (__c - '0');
1072  if (__value > __max)
1073  break;
1074  }
1075  else
1076  break;
1077  }
1078  if (__i && __value >= __min && __value <= __max)
1079  __member = __value;
1080  else
1081  __err |= ios_base::failbit;
1082 
1083  return __beg;
1084  }
1085 
1086  // Assumptions:
1087  // All elements in __names are unique, except if __indexlen is
1088  // even __names in the first half could be the same as corresponding
1089  // __names in the second half (May is abbreviated as May). Some __names
1090  // elements could be prefixes of other __names elements.
1091  template<typename _CharT, typename _InIter>
1092  _InIter
1094  _M_extract_name(iter_type __beg, iter_type __end, int& __member,
1095  const _CharT** __names, size_t __indexlen,
1096  ios_base& __io, ios_base::iostate& __err) const
1097  {
1098  typedef char_traits<_CharT> __traits_type;
1099  const locale& __loc = __io._M_getloc();
1100  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1101 
1102  size_t* __matches
1103  = static_cast<size_t*>(__builtin_alloca(2 * sizeof(size_t)
1104  * __indexlen));
1105  size_t* __lengths = __matches + __indexlen;
1106  size_t __nmatches = 0;
1107  size_t __pos = 0;
1108  bool __testvalid = true;
1109  const char_type* __name;
1110  bool __begupdated = false;
1111 
1112  // Look for initial matches.
1113  if (__beg != __end)
1114  {
1115  const char_type __c = *__beg;
1116  // TODO real case-insensitive comparison
1117  const char_type __cl = __ctype.tolower(__c);
1118  const char_type __cu = __ctype.toupper(__c);
1119  for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
1120  if (__cl == __ctype.tolower(__names[__i1][0])
1121  || __cu == __ctype.toupper(__names[__i1][0]))
1122  {
1123  __lengths[__nmatches]
1124  = __traits_type::length(__names[__i1]);
1125  __matches[__nmatches++] = __i1;
1126  }
1127  }
1128 
1129  while (__nmatches > 1)
1130  {
1131  // Find smallest matching string.
1132  size_t __minlen = __lengths[0];
1133  for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
1134  __minlen = std::min(__minlen, __lengths[__i2]);
1135  ++__pos;
1136  ++__beg;
1137  if (__pos == __minlen)
1138  {
1139  // If some match has remaining length of 0,
1140  // need to decide if any match with remaining
1141  // length non-zero matches the next character.
1142  // If so, remove all matches with remaining length
1143  // 0 from consideration, otherwise keep only matches
1144  // with remaining length 0.
1145  bool __match_longer = false;
1146 
1147  if (__beg != __end)
1148  {
1149  // TODO real case-insensitive comparison
1150  const char_type __cl = __ctype.tolower(*__beg);
1151  const char_type __cu = __ctype.toupper(*__beg);
1152  for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
1153  {
1154  __name = __names[__matches[__i3]];
1155  if (__lengths[__i3] > __pos
1156  && (__ctype.tolower(__name[__pos]) == __cl
1157  || __ctype.toupper(__name[__pos]) == __cu))
1158  {
1159  __match_longer = true;
1160  break;
1161  }
1162  }
1163  }
1164  for (size_t __i4 = 0; __i4 < __nmatches;)
1165  if (__match_longer == (__lengths[__i4] == __pos))
1166  {
1167  __matches[__i4] = __matches[--__nmatches];
1168  __lengths[__i4] = __lengths[__nmatches];
1169  }
1170  else
1171  ++__i4;
1172  if (__match_longer)
1173  {
1174  __minlen = __lengths[0];
1175  for (size_t __i5 = 1; __i5 < __nmatches; ++__i5)
1176  __minlen = std::min(__minlen, __lengths[__i5]);
1177  }
1178  else
1179  {
1180  // Deal with May being full as well as abbreviated month
1181  // name. Pick the smaller index.
1182  if (__nmatches == 2 && (__indexlen & 1) == 0)
1183  {
1184  if (__matches[0] < __indexlen / 2)
1185  {
1186  if (__matches[1] == __matches[0] + __indexlen / 2)
1187  __nmatches = 1;
1188  }
1189  else if (__matches[1] == __matches[0] - __indexlen / 2)
1190  {
1191  __matches[0] = __matches[1];
1192  __lengths[0] = __lengths[1];
1193  __nmatches = 1;
1194  }
1195  }
1196  __begupdated = true;
1197  break;
1198  }
1199  }
1200  if (__pos < __minlen && __beg != __end)
1201  {
1202  // TODO real case-insensitive comparison
1203  const char_type __cl = __ctype.tolower(*__beg);
1204  const char_type __cu = __ctype.toupper(*__beg);
1205  for (size_t __i6 = 0; __i6 < __nmatches;)
1206  {
1207  __name = __names[__matches[__i6]];
1208  if (__ctype.tolower(__name[__pos]) != __cl
1209  && __ctype.toupper(__name[__pos]) != __cu)
1210  {
1211  __matches[__i6] = __matches[--__nmatches];
1212  __lengths[__i6] = __lengths[__nmatches];
1213  }
1214  else
1215  ++__i6;
1216  }
1217  }
1218  else
1219  break;
1220  }
1221 
1222  if (__nmatches == 1)
1223  {
1224  // Make sure found name is completely extracted.
1225  if (!__begupdated)
1226  {
1227  ++__beg;
1228  ++__pos;
1229  }
1230  __name = __names[__matches[0]];
1231  const size_t __len = __lengths[0];
1232  while (__pos < __len
1233  && __beg != __end
1234  // TODO real case-insensitive comparison
1235  && (__ctype.tolower(__name[__pos]) == __ctype.tolower(*__beg)
1236  || (__ctype.toupper(__name[__pos])
1237  == __ctype.toupper(*__beg))))
1238  ++__beg, (void)++__pos;
1239 
1240  if (__len == __pos)
1241  __member = __matches[0];
1242  else
1243  __testvalid = false;
1244  }
1245  else
1246  __testvalid = false;
1247  if (!__testvalid)
1248  __err |= ios_base::failbit;
1249 
1250  return __beg;
1251  }
1252 
1253  template<typename _CharT, typename _InIter>
1254  _InIter
1256  _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member,
1257  const _CharT** __names, size_t __indexlen,
1258  ios_base& __io, ios_base::iostate& __err) const
1259  {
1260  typedef char_traits<_CharT> __traits_type;
1261  const locale& __loc = __io._M_getloc();
1262  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1263 
1264  int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int)
1265  * __indexlen));
1266  size_t __nmatches = 0;
1267  size_t* __matches_lengths = 0;
1268  size_t __pos = 0;
1269 
1270  if (__beg != __end)
1271  {
1272  const char_type __c = *__beg;
1273  for (size_t __i = 0; __i < 2 * __indexlen; ++__i)
1274  if (__c == __names[__i][0]
1275  || __c == __ctype.toupper(__names[__i][0]))
1276  __matches[__nmatches++] = __i;
1277  }
1278 
1279  if (__nmatches)
1280  {
1281  ++__beg;
1282  ++__pos;
1283 
1284  __matches_lengths
1285  = static_cast<size_t*>(__builtin_alloca(sizeof(size_t)
1286  * __nmatches));
1287  for (size_t __i = 0; __i < __nmatches; ++__i)
1288  __matches_lengths[__i]
1289  = __traits_type::length(__names[__matches[__i]]);
1290  }
1291 
1292  for (; __beg != __end; ++__beg, (void)++__pos)
1293  {
1294  size_t __nskipped = 0;
1295  const char_type __c = *__beg;
1296  for (size_t __i = 0; __i < __nmatches;)
1297  {
1298  const char_type* __name = __names[__matches[__i]];
1299  if (__pos >= __matches_lengths[__i])
1300  ++__nskipped, ++__i;
1301  else if (!(__name[__pos] == __c))
1302  {
1303  --__nmatches;
1304  __matches[__i] = __matches[__nmatches];
1305  __matches_lengths[__i] = __matches_lengths[__nmatches];
1306  }
1307  else
1308  ++__i;
1309  }
1310  if (__nskipped == __nmatches)
1311  break;
1312  }
1313 
1314  if ((__nmatches == 1 && __matches_lengths[0] == __pos)
1315  || (__nmatches == 2 && (__matches_lengths[0] == __pos
1316  || __matches_lengths[1] == __pos)))
1317  __member = (__matches[0] >= (int)__indexlen
1318  ? __matches[0] - (int)__indexlen : __matches[0]);
1319  else
1320  __err |= ios_base::failbit;
1321 
1322  return __beg;
1323  }
1324 
1325  template<typename _CharT, typename _InIter>
1326  _InIter
1329  ios_base::iostate& __err, tm* __tm) const
1330  {
1331  const locale& __loc = __io._M_getloc();
1332  const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1333  const char_type* __times[2];
1334  __tp._M_time_formats(__times);
1335  __time_get_state __state = __time_get_state();
1336  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1337  __tm, __times[0], __state);
1338  __state._M_finalize_state(__tm);
1339  if (__beg == __end)
1340  __err |= ios_base::eofbit;
1341  return __beg;
1342  }
1343 
1344  template<typename _CharT, typename _InIter>
1345  _InIter
1348  ios_base::iostate& __err, tm* __tm) const
1349  {
1350  const locale& __loc = __io._M_getloc();
1351  const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1352  const char_type* __dates[2];
1353  __tp._M_date_formats(__dates);
1354  __time_get_state __state = __time_get_state();
1355  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1356  __tm, __dates[0], __state);
1357  __state._M_finalize_state(__tm);
1358  if (__beg == __end)
1359  __err |= ios_base::eofbit;
1360  return __beg;
1361  }
1362 
1363  template<typename _CharT, typename _InIter>
1364  _InIter
1367  ios_base::iostate& __err, tm* __tm) const
1368  {
1369  const locale& __loc = __io._M_getloc();
1370  const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1371  const char_type* __days[14];
1372  __tp._M_days_abbreviated(__days);
1373  __tp._M_days(__days + 7);
1374  int __tmpwday;
1375  ios_base::iostate __tmperr = ios_base::goodbit;
1376 
1377  __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7,
1378  __io, __tmperr);
1379  if (!__tmperr)
1380  __tm->tm_wday = __tmpwday;
1381  else
1382  __err |= ios_base::failbit;
1383 
1384  if (__beg == __end)
1385  __err |= ios_base::eofbit;
1386  return __beg;
1387  }
1388 
1389  template<typename _CharT, typename _InIter>
1390  _InIter
1393  ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1394  {
1395  const locale& __loc = __io._M_getloc();
1396  const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1397  const char_type* __months[24];
1398  __tp._M_months_abbreviated(__months);
1399  __tp._M_months(__months + 12);
1400  int __tmpmon;
1401  ios_base::iostate __tmperr = ios_base::goodbit;
1402 
1403  __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12,
1404  __io, __tmperr);
1405  if (!__tmperr)
1406  __tm->tm_mon = __tmpmon;
1407  else
1408  __err |= ios_base::failbit;
1409 
1410  if (__beg == __end)
1411  __err |= ios_base::eofbit;
1412  return __beg;
1413  }
1414 
1415  template<typename _CharT, typename _InIter>
1416  _InIter
1419  ios_base::iostate& __err, tm* __tm) const
1420  {
1421  int __tmpyear;
1422  ios_base::iostate __tmperr = ios_base::goodbit;
1423  const locale& __loc = __io._M_getloc();
1424  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1425 
1426  __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 99, 2,
1427  __io, __tmperr);
1428  if (!__tmperr)
1429  {
1430  char __c = 0;
1431  if (__beg != __end)
1432  __c = __ctype.narrow(*__beg, '*');
1433  // For 1-2 digit year, assume 69-99 is 1969-1999, 0-68 is 2000-2068.
1434  // For 3-4 digit year, use it as year.
1435  // __tm->tm_year needs year - 1900 though.
1436  if (__c >= '0' && __c <= '9')
1437  {
1438  ++__beg;
1439  __tmpyear = __tmpyear * 10 + (__c - '0');
1440  if (__beg != __end)
1441  {
1442  __c = __ctype.narrow(*__beg, '*');
1443  if (__c >= '0' && __c <= '9')
1444  {
1445  ++__beg;
1446  __tmpyear = __tmpyear * 10 + (__c - '0');
1447  }
1448  }
1449  __tmpyear -= 1900;
1450  }
1451  else if (__tmpyear < 69)
1452  __tmpyear += 100;
1453  __tm->tm_year = __tmpyear;
1454  }
1455  else
1456  __err |= ios_base::failbit;
1457 
1458  if (__beg == __end)
1459  __err |= ios_base::eofbit;
1460  return __beg;
1461  }
1462 
1463 #if __cplusplus >= 201103L
1464  template<typename _CharT, typename _InIter>
1465  inline
1466  _InIter
1468  get(iter_type __s, iter_type __end, ios_base& __io,
1469  ios_base::iostate& __err, tm* __tm, const char_type* __fmt,
1470  const char_type* __fmtend) const
1471  {
1472  const locale& __loc = __io._M_getloc();
1473  ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1474  __err = ios_base::goodbit;
1475  bool __use_state = false;
1476 #if __GNUC__ >= 5 && !defined(_GLIBCXX_CLANG)
1477 #pragma GCC diagnostic push
1478 #pragma GCC diagnostic ignored "-Wpmf-conversions"
1479  // Nasty hack. The C++ standard mandates that get invokes the do_get
1480  // virtual method, but unfortunately at least without an ABI change
1481  // for the facets we can't keep state across the different do_get
1482  // calls. So e.g. if __fmt is "%p %I:%M:%S", we can't handle it
1483  // properly, because we first handle the %p am/pm specifier and only
1484  // later the 12-hour format specifier.
1485  if ((void*)(this->*(&time_get::do_get)) == (void*)(&time_get::do_get))
1486  __use_state = true;
1487 #pragma GCC diagnostic pop
1488 #endif
1489  __time_get_state __state = __time_get_state();
1490  while (__fmt != __fmtend &&
1491  __err == ios_base::goodbit)
1492  {
1493  if (__s == __end)
1494  {
1496  break;
1497  }
1498  else if (__ctype.narrow(*__fmt, 0) == '%')
1499  {
1500  const char_type* __fmt_start = __fmt;
1501  char __format;
1502  char __mod = 0;
1503  if (++__fmt == __fmtend)
1504  {
1505  __err = ios_base::failbit;
1506  break;
1507  }
1508  const char __c = __ctype.narrow(*__fmt, 0);
1509  if (__c != 'E' && __c != 'O')
1510  __format = __c;
1511  else if (++__fmt != __fmtend)
1512  {
1513  __mod = __c;
1514  __format = __ctype.narrow(*__fmt, 0);
1515  }
1516  else
1517  {
1518  __err = ios_base::failbit;
1519  break;
1520  }
1521  if (__use_state)
1522  {
1523  char_type __new_fmt[4];
1524  __new_fmt[0] = __fmt_start[0];
1525  __new_fmt[1] = __fmt_start[1];
1526  if (__mod)
1527  {
1528  __new_fmt[2] = __fmt_start[2];
1529  __new_fmt[3] = char_type();
1530  }
1531  else
1532  __new_fmt[2] = char_type();
1533  __s = _M_extract_via_format(__s, __end, __io, __err, __tm,
1534  __new_fmt, __state);
1535  if (__s == __end)
1536  __err |= ios_base::eofbit;
1537  }
1538  else
1539  __s = this->do_get(__s, __end, __io, __err, __tm, __format,
1540  __mod);
1541  ++__fmt;
1542  }
1543  else if (__ctype.is(ctype_base::space, *__fmt))
1544  {
1545  ++__fmt;
1546  while (__fmt != __fmtend &&
1547  __ctype.is(ctype_base::space, *__fmt))
1548  ++__fmt;
1549 
1550  while (__s != __end &&
1551  __ctype.is(ctype_base::space, *__s))
1552  ++__s;
1553  }
1554  // TODO real case-insensitive comparison
1555  else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) ||
1556  __ctype.toupper(*__s) == __ctype.toupper(*__fmt))
1557  {
1558  ++__s;
1559  ++__fmt;
1560  }
1561  else
1562  {
1563  __err = ios_base::failbit;
1564  break;
1565  }
1566  }
1567  if (__use_state)
1568  __state._M_finalize_state(__tm);
1569  return __s;
1570  }
1571 
1572  template<typename _CharT, typename _InIter>
1573  inline
1574  _InIter
1576  do_get(iter_type __beg, iter_type __end, ios_base& __io,
1577  ios_base::iostate& __err, tm* __tm,
1578  char __format, char __mod) const
1579  {
1580  const locale& __loc = __io._M_getloc();
1581  ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1582  __err = ios_base::goodbit;
1583 
1584  char_type __fmt[4];
1585  __fmt[0] = __ctype.widen('%');
1586  if (!__mod)
1587  {
1588  __fmt[1] = __format;
1589  __fmt[2] = char_type();
1590  }
1591  else
1592  {
1593  __fmt[1] = __mod;
1594  __fmt[2] = __format;
1595  __fmt[3] = char_type();
1596  }
1597 
1598  __time_get_state __state = __time_get_state();
1599  __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt,
1600  __state);
1601  __state._M_finalize_state(__tm);
1602  if (__beg == __end)
1603  __err |= ios_base::eofbit;
1604  return __beg;
1605  }
1606 
1607 #endif // __cplusplus >= 201103L
1608 
1609  template<typename _CharT, typename _OutIter>
1610  _OutIter
1612  put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
1613  const _CharT* __beg, const _CharT* __end) const
1614  {
1615  const locale& __loc = __io._M_getloc();
1616  ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1617  for (; __beg != __end; ++__beg)
1618  if (__ctype.narrow(*__beg, 0) != '%')
1619  {
1620  *__s = *__beg;
1621  ++__s;
1622  }
1623  else if (++__beg != __end)
1624  {
1625  char __format;
1626  char __mod = 0;
1627  const char __c = __ctype.narrow(*__beg, 0);
1628  if (__c != 'E' && __c != 'O')
1629  __format = __c;
1630  else if (++__beg != __end)
1631  {
1632  __mod = __c;
1633  __format = __ctype.narrow(*__beg, 0);
1634  }
1635  else
1636  break;
1637  __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
1638  }
1639  else
1640  break;
1641  return __s;
1642  }
1643 
1644  template<typename _CharT, typename _OutIter>
1645  _OutIter
1647  do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1648  char __format, char __mod) const
1649  {
1650  const locale& __loc = __io._M_getloc();
1651  ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1652  __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1653 
1654  // NB: This size is arbitrary. Should this be a data member,
1655  // initialized at construction?
1656  const size_t __maxlen = 128;
1657  char_type __res[__maxlen];
1658 
1659  // NB: In IEEE 1003.1-200x, and perhaps other locale models, it
1660  // is possible that the format character will be longer than one
1661  // character. Possibilities include 'E' or 'O' followed by a
1662  // format character: if __mod is not the default argument, assume
1663  // it's a valid modifier.
1664  char_type __fmt[4];
1665  __fmt[0] = __ctype.widen('%');
1666  if (!__mod)
1667  {
1668  __fmt[1] = __format;
1669  __fmt[2] = char_type();
1670  }
1671  else
1672  {
1673  __fmt[1] = __mod;
1674  __fmt[2] = __format;
1675  __fmt[3] = char_type();
1676  }
1677 
1678  __tp._M_put(__res, __maxlen, __fmt, __tm);
1679 
1680  // Write resulting, fully-formatted string to output iterator.
1681  return std::__write(__s, __res, char_traits<char_type>::length(__res));
1682  }
1683 
1684 
1685  // Inhibit implicit instantiations for required instantiations,
1686  // which are defined via explicit instantiations elsewhere.
1687 #if _GLIBCXX_EXTERN_TEMPLATE
1688 #pragma GCC diagnostic push
1689 #pragma GCC diagnostic ignored "-Wc++11-extensions" // extern template
1690 #pragma GCC diagnostic ignored "-Wlong-long"
1691  extern template class moneypunct<char, false>;
1692  extern template class moneypunct<char, true>;
1693  extern template class moneypunct_byname<char, false>;
1694  extern template class moneypunct_byname<char, true>;
1695  extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<char>;
1696  extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<char>;
1697  extern template class __timepunct<char>;
1698  extern template class time_put<char>;
1699  extern template class time_put_byname<char>;
1700  extern template class time_get<char>;
1701  extern template class time_get_byname<char>;
1702  extern template class messages<char>;
1703  extern template class messages_byname<char>;
1704 
1705  extern template
1706  const moneypunct<char, true>*
1707  __try_use_facet<moneypunct<char, true> >(const locale&) _GLIBCXX_NOTHROW;
1708 
1709  extern template
1711  __try_use_facet<moneypunct<char, false> >(const locale&) _GLIBCXX_NOTHROW;
1712 
1713  extern template
1714  const money_put<char>*
1715  __try_use_facet<money_put<char> >(const locale&) _GLIBCXX_NOTHROW;
1716 
1717  extern template
1718  const money_get<char>*
1719  __try_use_facet<money_get<char> >(const locale&) _GLIBCXX_NOTHROW;
1720 
1721  extern template
1722  const __timepunct<char>*
1723  __try_use_facet<__timepunct<char> >(const locale&) _GLIBCXX_NOTHROW;
1724 
1725  extern template
1726  const time_put<char>*
1727  __try_use_facet<time_put<char> >(const locale&) _GLIBCXX_NOTHROW;
1728 
1729  extern template
1730  const time_get<char>*
1731  __try_use_facet<time_get<char> >(const locale&) _GLIBCXX_NOTHROW;
1732 
1733  extern template
1734  const messages<char>*
1735  __try_use_facet<messages<char> >(const locale&) _GLIBCXX_NOTHROW;
1736 
1737  extern template
1738  const moneypunct<char, true>&
1739  use_facet<moneypunct<char, true> >(const locale&);
1740 
1741  extern template
1743  use_facet<moneypunct<char, false> >(const locale&);
1744 
1745  extern template
1746  const money_put<char>&
1747  use_facet<money_put<char> >(const locale&);
1748 
1749  extern template
1750  const money_get<char>&
1751  use_facet<money_get<char> >(const locale&);
1752 
1753  extern template
1754  const __timepunct<char>&
1755  use_facet<__timepunct<char> >(const locale&);
1756 
1757  extern template
1758  const time_put<char>&
1759  use_facet<time_put<char> >(const locale&);
1760 
1761  extern template
1762  const time_get<char>&
1763  use_facet<time_get<char> >(const locale&);
1764 
1765  extern template
1766  const messages<char>&
1767  use_facet<messages<char> >(const locale&);
1768 
1769  extern template
1770  bool
1771  has_facet<moneypunct<char> >(const locale&);
1772 
1773  extern template
1774  bool
1775  has_facet<money_put<char> >(const locale&);
1776 
1777  extern template
1778  bool
1779  has_facet<money_get<char> >(const locale&);
1780 
1781  extern template
1782  bool
1783  has_facet<__timepunct<char> >(const locale&);
1784 
1785  extern template
1786  bool
1787  has_facet<time_put<char> >(const locale&);
1788 
1789  extern template
1790  bool
1791  has_facet<time_get<char> >(const locale&);
1792 
1793  extern template
1794  bool
1795  has_facet<messages<char> >(const locale&);
1796 
1797 #ifdef _GLIBCXX_USE_WCHAR_T
1798  extern template class moneypunct<wchar_t, false>;
1799  extern template class moneypunct<wchar_t, true>;
1800  extern template class moneypunct_byname<wchar_t, false>;
1801  extern template class moneypunct_byname<wchar_t, true>;
1802  extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<wchar_t>;
1803  extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<wchar_t>;
1804  extern template class __timepunct<wchar_t>;
1805  extern template class time_put<wchar_t>;
1806  extern template class time_put_byname<wchar_t>;
1807  extern template class time_get<wchar_t>;
1808  extern template class time_get_byname<wchar_t>;
1809  extern template class messages<wchar_t>;
1810  extern template class messages_byname<wchar_t>;
1811 
1812  extern template
1814  __try_use_facet<moneypunct<wchar_t, true> >(const locale&) _GLIBCXX_NOTHROW;
1815 
1816  extern template
1817  const moneypunct<wchar_t, false>*
1818  __try_use_facet<moneypunct<wchar_t, false> >(const locale&) _GLIBCXX_NOTHROW;
1819 
1820  extern template
1821  const money_put<wchar_t>*
1822  __try_use_facet<money_put<wchar_t> >(const locale&) _GLIBCXX_NOTHROW;
1823 
1824  extern template
1825  const money_get<wchar_t>*
1826  __try_use_facet<money_get<wchar_t> >(const locale&) _GLIBCXX_NOTHROW;
1827 
1828  extern template
1829  const __timepunct<wchar_t>*
1830  __try_use_facet<__timepunct<wchar_t> >(const locale&) _GLIBCXX_NOTHROW;
1831 
1832  extern template
1833  const time_put<wchar_t>*
1834  __try_use_facet<time_put<wchar_t> >(const locale&) _GLIBCXX_NOTHROW;
1835 
1836  extern template
1837  const time_get<wchar_t>*
1838  __try_use_facet<time_get<wchar_t> >(const locale&) _GLIBCXX_NOTHROW;
1839 
1840  extern template
1841  const messages<wchar_t>*
1842  __try_use_facet<messages<wchar_t> >(const locale&) _GLIBCXX_NOTHROW;
1843 
1844  extern template
1846  use_facet<moneypunct<wchar_t, true> >(const locale&);
1847 
1848  extern template
1849  const moneypunct<wchar_t, false>&
1850  use_facet<moneypunct<wchar_t, false> >(const locale&);
1851 
1852  extern template
1853  const money_put<wchar_t>&
1854  use_facet<money_put<wchar_t> >(const locale&);
1855 
1856  extern template
1857  const money_get<wchar_t>&
1858  use_facet<money_get<wchar_t> >(const locale&);
1859 
1860  extern template
1861  const __timepunct<wchar_t>&
1862  use_facet<__timepunct<wchar_t> >(const locale&);
1863 
1864  extern template
1865  const time_put<wchar_t>&
1866  use_facet<time_put<wchar_t> >(const locale&);
1867 
1868  extern template
1869  const time_get<wchar_t>&
1870  use_facet<time_get<wchar_t> >(const locale&);
1871 
1872  extern template
1873  const messages<wchar_t>&
1874  use_facet<messages<wchar_t> >(const locale&);
1875 
1876  extern template
1877  bool
1878  has_facet<moneypunct<wchar_t> >(const locale&);
1879 
1880  extern template
1881  bool
1882  has_facet<money_put<wchar_t> >(const locale&);
1883 
1884  extern template
1885  bool
1886  has_facet<money_get<wchar_t> >(const locale&);
1887 
1888  extern template
1889  bool
1890  has_facet<__timepunct<wchar_t> >(const locale&);
1891 
1892  extern template
1893  bool
1894  has_facet<time_put<wchar_t> >(const locale&);
1895 
1896  extern template
1897  bool
1898  has_facet<time_get<wchar_t> >(const locale&);
1899 
1900  extern template
1901  bool
1902  has_facet<messages<wchar_t> >(const locale&);
1903 #endif
1904 #pragma GCC diagnostic pop
1905 #endif
1906 
1907 _GLIBCXX_END_NAMESPACE_VERSION
1908 } // namespace std
1909 
1910 #endif
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_year(iter_type __beg, iter_type __end, ios_base &__io, ios_base::iostate &__err, tm *__tm) const
Parse input year string.
_Ios_Iostate iostate
This is a bitmask type.
Definition: ios_base.h:453
_OutIter iter_type
Public typedefs.
static const fmtflags internal
Adds fill characters at a designated internal point in certain generated output, or identical to righ...
Definition: ios_base.h:395
static const iostate eofbit
Indicates that an input operation reached the end of an input sequence.
Definition: ios_base.h:460
size_type size() const noexcept
Returns the number of characters in the string, not including any null-termination.
Definition: cow_string.h:955
void insert(iterator __p, size_type __n, _CharT __c)
Insert multiple characters.
Definition: cow_string.h:1619
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
Definition: range_access.h:274
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.
Primary class template time_get.This facet encapsulates the code to parse and return a date or time f...
const _CharT * data() const noexcept
Return const pointer to contents.
Definition: cow_string.h:2388
char narrow(char_type __c, char __dfault) const
Narrow char_type to char.
bool is(mask __m, char_type __c) const
Test char_type classification.
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.
static const iostate goodbit
Indicates all is well.
Definition: ios_base.h:468
char_type widen(char __c) const
Widen char to char_type.
fmtflags flags() const
Access to format flags.
Definition: ios_base.h:694
const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
Definition: cow_string.h:2376
static const fmtflags showbase
Generates a prefix indicating the numeric base of generated integer output.
Definition: ios_base.h:413
Primary class template money_put.This facet encapsulates the code to format and output a monetary amo...
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.
streamsize width() const
Flags access.
Definition: ios_base.h:789
Primary class template time_put.This facet encapsulates the code to format and output dates and times...
ISO C++ entities toplevel namespace is std.
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.
const char_type * scan_not(mask __m, const char_type *__lo, const char_type *__hi) const
Find char_type not matching a mask.
basic_string & append(const basic_string &__str)
Append a string to this string.
Definition: cow_string.h:3490
Container class for localization functionality.The locale class is first a class wrapper for C librar...
static const size_type npos
Value returned by various member functions when they fail.
Definition: cow_string.h:322
char_type toupper(char_type __c) const
Convert to uppercase.
Primary class template moneypunct.This facet encapsulates the punctuation, grouping and other formatt...
Primary class template ctype facet.This template class defines classification and conversion function...
The base of the I/O class hierarchy.This class defines everything that can be defined about I/O that ...
Definition: ios_base.h:265
static const fmtflags adjustfield
A mask of left|right|internal. Useful for the 2-arg form of setf.
Definition: ios_base.h:433
_CharT char_type
Public typedefs.
char_type tolower(char_type __c) const
Convert to lowercase.
class time_get_byname [22.2.5.2].
_InIter iter_type
Public typedefs.
void resize(size_type __n, _CharT __c)
Resizes the string to the specified number of characters.
Definition: cow_string.h:3818
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.
_OutIter iter_type
Public typedefs.
void reserve(size_type __res_arg)
Attempt to preallocate enough memory for specified number of characters.
Definition: cow_string.h:3670
_CharT char_type
Public typedefs.
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.
static const iostate failbit
Indicates that an input operation failed to read the expected characters, or that an output operation...
Definition: ios_base.h:465
Primary class template messages.This facet encapsulates the code to retrieve messages from message ca...
Primary class template money_get.This facet encapsulates the code to parse and return a monetary amou...
basic_string & erase(size_type __pos=0, size_type __n=npos)
Remove characters.
Definition: cow_string.h:1858
class time_put_byname [22.2.5.4].
static const fmtflags left
Adds fill characters on the right (final positions) of certain generated output. (I.e., the thing you print is flush left.)
Definition: ios_base.h:399
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.
static locale::id id
Numpunct facet id.
Basis for explicit traits specializations.
Definition: char_traits.h:328
locale getloc() const
Locale access.
Definition: ios_base.h:841
basic_string & assign(const basic_string &__str)
Set value to contents of another string.
Definition: cow_string.h:3408
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.
class moneypunct_byname [22.2.6.4].
_CharT char_type
Public typedefs.
class messages_byname [22.2.7.2].
_InIter iter_type
Public typedefs.
_CharT char_type
Public typedefs.
const locale & _M_getloc() const
Locale access.
Definition: ios_base.h:852
virtual dateorder do_date_order() const
Return preferred order of month, day, and year.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
Definition: stl_algobase.h:233
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.