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