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