libstdc++
locale_facets.tcc
1 // Locale support -*- C++ -*-
2 
3 // Copyright (C) 1997-2013 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.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_TCC
31 #define _LOCALE_FACETS_TCC 1
32 
33 #pragma GCC system_header
34 
35 namespace std _GLIBCXX_VISIBILITY(default)
36 {
37 _GLIBCXX_BEGIN_NAMESPACE_VERSION
38 
39  // Routine to access a cache for the facet. If the cache didn't
40  // exist before, it gets constructed on the fly.
41  template<typename _Facet>
42  struct __use_cache
43  {
44  const _Facet*
45  operator() (const locale& __loc) const;
46  };
47 
48  // Specializations.
49  template<typename _CharT>
50  struct __use_cache<__numpunct_cache<_CharT> >
51  {
52  const __numpunct_cache<_CharT>*
53  operator() (const locale& __loc) const
54  {
55  const size_t __i = numpunct<_CharT>::id._M_id();
56  const locale::facet** __caches = __loc._M_impl->_M_caches;
57  if (!__caches[__i])
58  {
59  __numpunct_cache<_CharT>* __tmp = 0;
60  __try
61  {
62  __tmp = new __numpunct_cache<_CharT>;
63  __tmp->_M_cache(__loc);
64  }
65  __catch(...)
66  {
67  delete __tmp;
68  __throw_exception_again;
69  }
70  __loc._M_impl->_M_install_cache(__tmp, __i);
71  }
72  return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
73  }
74  };
75 
76  template<typename _CharT>
77  void
78  __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
79  {
80  _M_allocated = true;
81 
82  const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
83 
84  char* __grouping = 0;
85  _CharT* __truename = 0;
86  _CharT* __falsename = 0;
87  __try
88  {
89  _M_grouping_size = __np.grouping().size();
90  __grouping = new char[_M_grouping_size];
91  __np.grouping().copy(__grouping, _M_grouping_size);
92  _M_grouping = __grouping;
93  _M_use_grouping = (_M_grouping_size
94  && static_cast<signed char>(_M_grouping[0]) > 0
95  && (_M_grouping[0]
96  != __gnu_cxx::__numeric_traits<char>::__max));
97 
98  _M_truename_size = __np.truename().size();
99  __truename = new _CharT[_M_truename_size];
100  __np.truename().copy(__truename, _M_truename_size);
101  _M_truename = __truename;
102 
103  _M_falsename_size = __np.falsename().size();
104  __falsename = new _CharT[_M_falsename_size];
105  __np.falsename().copy(__falsename, _M_falsename_size);
106  _M_falsename = __falsename;
107 
108  _M_decimal_point = __np.decimal_point();
109  _M_thousands_sep = __np.thousands_sep();
110 
111  const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
112  __ct.widen(__num_base::_S_atoms_out,
113  __num_base::_S_atoms_out
114  + __num_base::_S_oend, _M_atoms_out);
115  __ct.widen(__num_base::_S_atoms_in,
116  __num_base::_S_atoms_in
117  + __num_base::_S_iend, _M_atoms_in);
118  }
119  __catch(...)
120  {
121  delete [] __grouping;
122  delete [] __truename;
123  delete [] __falsename;
124  __throw_exception_again;
125  }
126  }
127 
128  // Used by both numeric and monetary facets.
129  // Check to make sure that the __grouping_tmp string constructed in
130  // money_get or num_get matches the canonical grouping for a given
131  // locale.
132  // __grouping_tmp is parsed L to R
133  // 1,222,444 == __grouping_tmp of "\1\3\3"
134  // __grouping is parsed R to L
135  // 1,222,444 == __grouping of "\3" == "\3\3\3"
136  _GLIBCXX_PURE bool
137  __verify_grouping(const char* __grouping, size_t __grouping_size,
138  const string& __grouping_tmp) throw ();
139 
140 _GLIBCXX_BEGIN_NAMESPACE_LDBL
141 
142  template<typename _CharT, typename _InIter>
143  _InIter
144  num_get<_CharT, _InIter>::
145  _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
146  ios_base::iostate& __err, string& __xtrc) const
147  {
148  typedef char_traits<_CharT> __traits_type;
149  typedef __numpunct_cache<_CharT> __cache_type;
150  __use_cache<__cache_type> __uc;
151  const locale& __loc = __io._M_getloc();
152  const __cache_type* __lc = __uc(__loc);
153  const _CharT* __lit = __lc->_M_atoms_in;
154  char_type __c = char_type();
155 
156  // True if __beg becomes equal to __end.
157  bool __testeof = __beg == __end;
158 
159  // First check for sign.
160  if (!__testeof)
161  {
162  __c = *__beg;
163  const bool __plus = __c == __lit[__num_base::_S_iplus];
164  if ((__plus || __c == __lit[__num_base::_S_iminus])
165  && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
166  && !(__c == __lc->_M_decimal_point))
167  {
168  __xtrc += __plus ? '+' : '-';
169  if (++__beg != __end)
170  __c = *__beg;
171  else
172  __testeof = true;
173  }
174  }
175 
176  // Next, look for leading zeros.
177  bool __found_mantissa = false;
178  int __sep_pos = 0;
179  while (!__testeof)
180  {
181  if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
182  || __c == __lc->_M_decimal_point)
183  break;
184  else if (__c == __lit[__num_base::_S_izero])
185  {
186  if (!__found_mantissa)
187  {
188  __xtrc += '0';
189  __found_mantissa = true;
190  }
191  ++__sep_pos;
192 
193  if (++__beg != __end)
194  __c = *__beg;
195  else
196  __testeof = true;
197  }
198  else
199  break;
200  }
201 
202  // Only need acceptable digits for floating point numbers.
203  bool __found_dec = false;
204  bool __found_sci = false;
205  string __found_grouping;
206  if (__lc->_M_use_grouping)
207  __found_grouping.reserve(32);
208  const char_type* __lit_zero = __lit + __num_base::_S_izero;
209 
210  if (!__lc->_M_allocated)
211  // "C" locale
212  while (!__testeof)
213  {
214  const int __digit = _M_find(__lit_zero, 10, __c);
215  if (__digit != -1)
216  {
217  __xtrc += '0' + __digit;
218  __found_mantissa = true;
219  }
220  else if (__c == __lc->_M_decimal_point
221  && !__found_dec && !__found_sci)
222  {
223  __xtrc += '.';
224  __found_dec = true;
225  }
226  else if ((__c == __lit[__num_base::_S_ie]
227  || __c == __lit[__num_base::_S_iE])
228  && !__found_sci && __found_mantissa)
229  {
230  // Scientific notation.
231  __xtrc += 'e';
232  __found_sci = true;
233 
234  // Remove optional plus or minus sign, if they exist.
235  if (++__beg != __end)
236  {
237  __c = *__beg;
238  const bool __plus = __c == __lit[__num_base::_S_iplus];
239  if (__plus || __c == __lit[__num_base::_S_iminus])
240  __xtrc += __plus ? '+' : '-';
241  else
242  continue;
243  }
244  else
245  {
246  __testeof = true;
247  break;
248  }
249  }
250  else
251  break;
252 
253  if (++__beg != __end)
254  __c = *__beg;
255  else
256  __testeof = true;
257  }
258  else
259  while (!__testeof)
260  {
261  // According to 22.2.2.1.2, p8-9, first look for thousands_sep
262  // and decimal_point.
263  if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
264  {
265  if (!__found_dec && !__found_sci)
266  {
267  // NB: Thousands separator at the beginning of a string
268  // is a no-no, as is two consecutive thousands separators.
269  if (__sep_pos)
270  {
271  __found_grouping += static_cast<char>(__sep_pos);
272  __sep_pos = 0;
273  }
274  else
275  {
276  // NB: __convert_to_v will not assign __v and will
277  // set the failbit.
278  __xtrc.clear();
279  break;
280  }
281  }
282  else
283  break;
284  }
285  else if (__c == __lc->_M_decimal_point)
286  {
287  if (!__found_dec && !__found_sci)
288  {
289  // If no grouping chars are seen, no grouping check
290  // is applied. Therefore __found_grouping is adjusted
291  // only if decimal_point comes after some thousands_sep.
292  if (__found_grouping.size())
293  __found_grouping += static_cast<char>(__sep_pos);
294  __xtrc += '.';
295  __found_dec = true;
296  }
297  else
298  break;
299  }
300  else
301  {
302  const char_type* __q =
303  __traits_type::find(__lit_zero, 10, __c);
304  if (__q)
305  {
306  __xtrc += '0' + (__q - __lit_zero);
307  __found_mantissa = true;
308  ++__sep_pos;
309  }
310  else if ((__c == __lit[__num_base::_S_ie]
311  || __c == __lit[__num_base::_S_iE])
312  && !__found_sci && __found_mantissa)
313  {
314  // Scientific notation.
315  if (__found_grouping.size() && !__found_dec)
316  __found_grouping += static_cast<char>(__sep_pos);
317  __xtrc += 'e';
318  __found_sci = true;
319 
320  // Remove optional plus or minus sign, if they exist.
321  if (++__beg != __end)
322  {
323  __c = *__beg;
324  const bool __plus = __c == __lit[__num_base::_S_iplus];
325  if ((__plus || __c == __lit[__num_base::_S_iminus])
326  && !(__lc->_M_use_grouping
327  && __c == __lc->_M_thousands_sep)
328  && !(__c == __lc->_M_decimal_point))
329  __xtrc += __plus ? '+' : '-';
330  else
331  continue;
332  }
333  else
334  {
335  __testeof = true;
336  break;
337  }
338  }
339  else
340  break;
341  }
342 
343  if (++__beg != __end)
344  __c = *__beg;
345  else
346  __testeof = true;
347  }
348 
349  // Digit grouping is checked. If grouping and found_grouping don't
350  // match, then get very very upset, and set failbit.
351  if (__found_grouping.size())
352  {
353  // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
354  if (!__found_dec && !__found_sci)
355  __found_grouping += static_cast<char>(__sep_pos);
356 
357  if (!std::__verify_grouping(__lc->_M_grouping,
358  __lc->_M_grouping_size,
359  __found_grouping))
360  __err = ios_base::failbit;
361  }
362 
363  return __beg;
364  }
365 
366  template<typename _CharT, typename _InIter>
367  template<typename _ValueT>
368  _InIter
369  num_get<_CharT, _InIter>::
370  _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
371  ios_base::iostate& __err, _ValueT& __v) const
372  {
373  typedef char_traits<_CharT> __traits_type;
374  using __gnu_cxx::__add_unsigned;
375  typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
376  typedef __numpunct_cache<_CharT> __cache_type;
377  __use_cache<__cache_type> __uc;
378  const locale& __loc = __io._M_getloc();
379  const __cache_type* __lc = __uc(__loc);
380  const _CharT* __lit = __lc->_M_atoms_in;
381  char_type __c = char_type();
382 
383  // NB: Iff __basefield == 0, __base can change based on contents.
384  const ios_base::fmtflags __basefield = __io.flags()
385  & ios_base::basefield;
386  const bool __oct = __basefield == ios_base::oct;
387  int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
388 
389  // True if __beg becomes equal to __end.
390  bool __testeof = __beg == __end;
391 
392  // First check for sign.
393  bool __negative = false;
394  if (!__testeof)
395  {
396  __c = *__beg;
397  __negative = __c == __lit[__num_base::_S_iminus];
398  if ((__negative || __c == __lit[__num_base::_S_iplus])
399  && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
400  && !(__c == __lc->_M_decimal_point))
401  {
402  if (++__beg != __end)
403  __c = *__beg;
404  else
405  __testeof = true;
406  }
407  }
408 
409  // Next, look for leading zeros and check required digits
410  // for base formats.
411  bool __found_zero = false;
412  int __sep_pos = 0;
413  while (!__testeof)
414  {
415  if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
416  || __c == __lc->_M_decimal_point)
417  break;
418  else if (__c == __lit[__num_base::_S_izero]
419  && (!__found_zero || __base == 10))
420  {
421  __found_zero = true;
422  ++__sep_pos;
423  if (__basefield == 0)
424  __base = 8;
425  if (__base == 8)
426  __sep_pos = 0;
427  }
428  else if (__found_zero
429  && (__c == __lit[__num_base::_S_ix]
430  || __c == __lit[__num_base::_S_iX]))
431  {
432  if (__basefield == 0)
433  __base = 16;
434  if (__base == 16)
435  {
436  __found_zero = false;
437  __sep_pos = 0;
438  }
439  else
440  break;
441  }
442  else
443  break;
444 
445  if (++__beg != __end)
446  {
447  __c = *__beg;
448  if (!__found_zero)
449  break;
450  }
451  else
452  __testeof = true;
453  }
454 
455  // At this point, base is determined. If not hex, only allow
456  // base digits as valid input.
457  const size_t __len = (__base == 16 ? __num_base::_S_iend
458  - __num_base::_S_izero : __base);
459 
460  // Extract.
461  string __found_grouping;
462  if (__lc->_M_use_grouping)
463  __found_grouping.reserve(32);
464  bool __testfail = false;
465  bool __testoverflow = false;
466  const __unsigned_type __max =
467  (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
468  ? -__gnu_cxx::__numeric_traits<_ValueT>::__min
469  : __gnu_cxx::__numeric_traits<_ValueT>::__max;
470  const __unsigned_type __smax = __max / __base;
471  __unsigned_type __result = 0;
472  int __digit = 0;
473  const char_type* __lit_zero = __lit + __num_base::_S_izero;
474 
475  if (!__lc->_M_allocated)
476  // "C" locale
477  while (!__testeof)
478  {
479  __digit = _M_find(__lit_zero, __len, __c);
480  if (__digit == -1)
481  break;
482 
483  if (__result > __smax)
484  __testoverflow = true;
485  else
486  {
487  __result *= __base;
488  __testoverflow |= __result > __max - __digit;
489  __result += __digit;
490  ++__sep_pos;
491  }
492 
493  if (++__beg != __end)
494  __c = *__beg;
495  else
496  __testeof = true;
497  }
498  else
499  while (!__testeof)
500  {
501  // According to 22.2.2.1.2, p8-9, first look for thousands_sep
502  // and decimal_point.
503  if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
504  {
505  // NB: Thousands separator at the beginning of a string
506  // is a no-no, as is two consecutive thousands separators.
507  if (__sep_pos)
508  {
509  __found_grouping += static_cast<char>(__sep_pos);
510  __sep_pos = 0;
511  }
512  else
513  {
514  __testfail = true;
515  break;
516  }
517  }
518  else if (__c == __lc->_M_decimal_point)
519  break;
520  else
521  {
522  const char_type* __q =
523  __traits_type::find(__lit_zero, __len, __c);
524  if (!__q)
525  break;
526 
527  __digit = __q - __lit_zero;
528  if (__digit > 15)
529  __digit -= 6;
530  if (__result > __smax)
531  __testoverflow = true;
532  else
533  {
534  __result *= __base;
535  __testoverflow |= __result > __max - __digit;
536  __result += __digit;
537  ++__sep_pos;
538  }
539  }
540 
541  if (++__beg != __end)
542  __c = *__beg;
543  else
544  __testeof = true;
545  }
546 
547  // Digit grouping is checked. If grouping and found_grouping don't
548  // match, then get very very upset, and set failbit.
549  if (__found_grouping.size())
550  {
551  // Add the ending grouping.
552  __found_grouping += static_cast<char>(__sep_pos);
553 
554  if (!std::__verify_grouping(__lc->_M_grouping,
555  __lc->_M_grouping_size,
556  __found_grouping))
557  __err = ios_base::failbit;
558  }
559 
560  // _GLIBCXX_RESOLVE_LIB_DEFECTS
561  // 23. Num_get overflow result.
562  if ((!__sep_pos && !__found_zero && !__found_grouping.size())
563  || __testfail)
564  {
565  __v = 0;
566  __err = ios_base::failbit;
567  }
568  else if (__testoverflow)
569  {
570  if (__negative
571  && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
572  __v = __gnu_cxx::__numeric_traits<_ValueT>::__min;
573  else
574  __v = __gnu_cxx::__numeric_traits<_ValueT>::__max;
575  __err = ios_base::failbit;
576  }
577  else
578  __v = __negative ? -__result : __result;
579 
580  if (__testeof)
581  __err |= ios_base::eofbit;
582  return __beg;
583  }
584 
585  // _GLIBCXX_RESOLVE_LIB_DEFECTS
586  // 17. Bad bool parsing
587  template<typename _CharT, typename _InIter>
588  _InIter
589  num_get<_CharT, _InIter>::
590  do_get(iter_type __beg, iter_type __end, ios_base& __io,
591  ios_base::iostate& __err, bool& __v) const
592  {
593  if (!(__io.flags() & ios_base::boolalpha))
594  {
595  // Parse bool values as long.
596  // NB: We can't just call do_get(long) here, as it might
597  // refer to a derived class.
598  long __l = -1;
599  __beg = _M_extract_int(__beg, __end, __io, __err, __l);
600  if (__l == 0 || __l == 1)
601  __v = bool(__l);
602  else
603  {
604  // _GLIBCXX_RESOLVE_LIB_DEFECTS
605  // 23. Num_get overflow result.
606  __v = true;
607  __err = ios_base::failbit;
608  if (__beg == __end)
609  __err |= ios_base::eofbit;
610  }
611  }
612  else
613  {
614  // Parse bool values as alphanumeric.
615  typedef __numpunct_cache<_CharT> __cache_type;
616  __use_cache<__cache_type> __uc;
617  const locale& __loc = __io._M_getloc();
618  const __cache_type* __lc = __uc(__loc);
619 
620  bool __testf = true;
621  bool __testt = true;
622  bool __donef = __lc->_M_falsename_size == 0;
623  bool __donet = __lc->_M_truename_size == 0;
624  bool __testeof = false;
625  size_t __n = 0;
626  while (!__donef || !__donet)
627  {
628  if (__beg == __end)
629  {
630  __testeof = true;
631  break;
632  }
633 
634  const char_type __c = *__beg;
635 
636  if (!__donef)
637  __testf = __c == __lc->_M_falsename[__n];
638 
639  if (!__testf && __donet)
640  break;
641 
642  if (!__donet)
643  __testt = __c == __lc->_M_truename[__n];
644 
645  if (!__testt && __donef)
646  break;
647 
648  if (!__testt && !__testf)
649  break;
650 
651  ++__n;
652  ++__beg;
653 
654  __donef = !__testf || __n >= __lc->_M_falsename_size;
655  __donet = !__testt || __n >= __lc->_M_truename_size;
656  }
657  if (__testf && __n == __lc->_M_falsename_size && __n)
658  {
659  __v = false;
660  if (__testt && __n == __lc->_M_truename_size)
661  __err = ios_base::failbit;
662  else
663  __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
664  }
665  else if (__testt && __n == __lc->_M_truename_size && __n)
666  {
667  __v = true;
668  __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
669  }
670  else
671  {
672  // _GLIBCXX_RESOLVE_LIB_DEFECTS
673  // 23. Num_get overflow result.
674  __v = false;
675  __err = ios_base::failbit;
676  if (__testeof)
677  __err |= ios_base::eofbit;
678  }
679  }
680  return __beg;
681  }
682 
683  template<typename _CharT, typename _InIter>
684  _InIter
685  num_get<_CharT, _InIter>::
686  do_get(iter_type __beg, iter_type __end, ios_base& __io,
687  ios_base::iostate& __err, float& __v) const
688  {
689  string __xtrc;
690  __xtrc.reserve(32);
691  __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
692  std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
693  if (__beg == __end)
694  __err |= ios_base::eofbit;
695  return __beg;
696  }
697 
698  template<typename _CharT, typename _InIter>
699  _InIter
700  num_get<_CharT, _InIter>::
701  do_get(iter_type __beg, iter_type __end, ios_base& __io,
702  ios_base::iostate& __err, double& __v) const
703  {
704  string __xtrc;
705  __xtrc.reserve(32);
706  __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
707  std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
708  if (__beg == __end)
709  __err |= ios_base::eofbit;
710  return __beg;
711  }
712 
713 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
714  template<typename _CharT, typename _InIter>
715  _InIter
716  num_get<_CharT, _InIter>::
717  __do_get(iter_type __beg, iter_type __end, ios_base& __io,
718  ios_base::iostate& __err, double& __v) const
719  {
720  string __xtrc;
721  __xtrc.reserve(32);
722  __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
723  std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
724  if (__beg == __end)
725  __err |= ios_base::eofbit;
726  return __beg;
727  }
728 #endif
729 
730  template<typename _CharT, typename _InIter>
731  _InIter
732  num_get<_CharT, _InIter>::
733  do_get(iter_type __beg, iter_type __end, ios_base& __io,
734  ios_base::iostate& __err, long double& __v) const
735  {
736  string __xtrc;
737  __xtrc.reserve(32);
738  __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
739  std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
740  if (__beg == __end)
741  __err |= ios_base::eofbit;
742  return __beg;
743  }
744 
745  template<typename _CharT, typename _InIter>
746  _InIter
747  num_get<_CharT, _InIter>::
748  do_get(iter_type __beg, iter_type __end, ios_base& __io,
749  ios_base::iostate& __err, void*& __v) const
750  {
751  // Prepare for hex formatted input.
752  typedef ios_base::fmtflags fmtflags;
753  const fmtflags __fmt = __io.flags();
754  __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
755 
756  typedef __gnu_cxx::__conditional_type<(sizeof(void*)
757  <= sizeof(unsigned long)),
758  unsigned long, unsigned long long>::__type _UIntPtrType;
759 
760  _UIntPtrType __ul;
761  __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
762 
763  // Reset from hex formatted input.
764  __io.flags(__fmt);
765 
766  __v = reinterpret_cast<void*>(__ul);
767  return __beg;
768  }
769 
770  // For use by integer and floating-point types after they have been
771  // converted into a char_type string.
772  template<typename _CharT, typename _OutIter>
773  void
774  num_put<_CharT, _OutIter>::
775  _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
776  _CharT* __new, const _CharT* __cs, int& __len) const
777  {
778  // [22.2.2.2.2] Stage 3.
779  // If necessary, pad.
780  __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new,
781  __cs, __w, __len);
782  __len = static_cast<int>(__w);
783  }
784 
785 _GLIBCXX_END_NAMESPACE_LDBL
786 
787  template<typename _CharT, typename _ValueT>
788  int
789  __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
790  ios_base::fmtflags __flags, bool __dec)
791  {
792  _CharT* __buf = __bufend;
793  if (__builtin_expect(__dec, true))
794  {
795  // Decimal.
796  do
797  {
798  *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
799  __v /= 10;
800  }
801  while (__v != 0);
802  }
803  else if ((__flags & ios_base::basefield) == ios_base::oct)
804  {
805  // Octal.
806  do
807  {
808  *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
809  __v >>= 3;
810  }
811  while (__v != 0);
812  }
813  else
814  {
815  // Hex.
816  const bool __uppercase = __flags & ios_base::uppercase;
817  const int __case_offset = __uppercase ? __num_base::_S_oudigits
818  : __num_base::_S_odigits;
819  do
820  {
821  *--__buf = __lit[(__v & 0xf) + __case_offset];
822  __v >>= 4;
823  }
824  while (__v != 0);
825  }
826  return __bufend - __buf;
827  }
828 
829 _GLIBCXX_BEGIN_NAMESPACE_LDBL
830 
831  template<typename _CharT, typename _OutIter>
832  void
833  num_put<_CharT, _OutIter>::
834  _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
835  ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
836  {
837  _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
838  __grouping_size, __cs, __cs + __len);
839  __len = __p - __new;
840  }
841 
842  template<typename _CharT, typename _OutIter>
843  template<typename _ValueT>
844  _OutIter
845  num_put<_CharT, _OutIter>::
846  _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
847  _ValueT __v) const
848  {
849  using __gnu_cxx::__add_unsigned;
850  typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
851  typedef __numpunct_cache<_CharT> __cache_type;
852  __use_cache<__cache_type> __uc;
853  const locale& __loc = __io._M_getloc();
854  const __cache_type* __lc = __uc(__loc);
855  const _CharT* __lit = __lc->_M_atoms_out;
856  const ios_base::fmtflags __flags = __io.flags();
857 
858  // Long enough to hold hex, dec, and octal representations.
859  const int __ilen = 5 * sizeof(_ValueT);
860  _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
861  * __ilen));
862 
863  // [22.2.2.2.2] Stage 1, numeric conversion to character.
864  // Result is returned right-justified in the buffer.
865  const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
866  const bool __dec = (__basefield != ios_base::oct
867  && __basefield != ios_base::hex);
868  const __unsigned_type __u = ((__v > 0 || !__dec)
869  ? __unsigned_type(__v)
870  : -__unsigned_type(__v));
871  int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec);
872  __cs += __ilen - __len;
873 
874  // Add grouping, if necessary.
875  if (__lc->_M_use_grouping)
876  {
877  // Grouping can add (almost) as many separators as the number
878  // of digits + space is reserved for numeric base or sign.
879  _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
880  * (__len + 1)
881  * 2));
882  _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
883  __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
884  __cs = __cs2 + 2;
885  }
886 
887  // Complete Stage 1, prepend numeric base or sign.
888  if (__builtin_expect(__dec, true))
889  {
890  // Decimal.
891  if (__v >= 0)
892  {
893  if (bool(__flags & ios_base::showpos)
894  && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
895  *--__cs = __lit[__num_base::_S_oplus], ++__len;
896  }
897  else
898  *--__cs = __lit[__num_base::_S_ominus], ++__len;
899  }
900  else if (bool(__flags & ios_base::showbase) && __v)
901  {
902  if (__basefield == ios_base::oct)
903  *--__cs = __lit[__num_base::_S_odigits], ++__len;
904  else
905  {
906  // 'x' or 'X'
907  const bool __uppercase = __flags & ios_base::uppercase;
908  *--__cs = __lit[__num_base::_S_ox + __uppercase];
909  // '0'
910  *--__cs = __lit[__num_base::_S_odigits];
911  __len += 2;
912  }
913  }
914 
915  // Pad.
916  const streamsize __w = __io.width();
917  if (__w > static_cast<streamsize>(__len))
918  {
919  _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
920  * __w));
921  _M_pad(__fill, __w, __io, __cs3, __cs, __len);
922  __cs = __cs3;
923  }
924  __io.width(0);
925 
926  // [22.2.2.2.2] Stage 4.
927  // Write resulting, fully-formatted string to output iterator.
928  return std::__write(__s, __cs, __len);
929  }
930 
931  template<typename _CharT, typename _OutIter>
932  void
933  num_put<_CharT, _OutIter>::
934  _M_group_float(const char* __grouping, size_t __grouping_size,
935  _CharT __sep, const _CharT* __p, _CharT* __new,
936  _CharT* __cs, int& __len) const
937  {
938  // _GLIBCXX_RESOLVE_LIB_DEFECTS
939  // 282. What types does numpunct grouping refer to?
940  // Add grouping, if necessary.
941  const int __declen = __p ? __p - __cs : __len;
942  _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
943  __grouping_size,
944  __cs, __cs + __declen);
945 
946  // Tack on decimal part.
947  int __newlen = __p2 - __new;
948  if (__p)
949  {
950  char_traits<_CharT>::copy(__p2, __p, __len - __declen);
951  __newlen += __len - __declen;
952  }
953  __len = __newlen;
954  }
955 
956  // The following code uses vsnprintf (or vsprintf(), when
957  // _GLIBCXX_USE_C99 is not defined) to convert floating point values
958  // for insertion into a stream. An optimization would be to replace
959  // them with code that works directly on a wide buffer and then use
960  // __pad to do the padding. It would be good to replace them anyway
961  // to gain back the efficiency that C++ provides by knowing up front
962  // the type of the values to insert. Also, sprintf is dangerous
963  // since may lead to accidental buffer overruns. This
964  // implementation follows the C++ standard fairly directly as
965  // outlined in 22.2.2.2 [lib.locale.num.put]
966  template<typename _CharT, typename _OutIter>
967  template<typename _ValueT>
968  _OutIter
969  num_put<_CharT, _OutIter>::
970  _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
971  _ValueT __v) const
972  {
973  typedef __numpunct_cache<_CharT> __cache_type;
974  __use_cache<__cache_type> __uc;
975  const locale& __loc = __io._M_getloc();
976  const __cache_type* __lc = __uc(__loc);
977 
978  // Use default precision if out of range.
979  const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision();
980 
981  const int __max_digits =
982  __gnu_cxx::__numeric_traits<_ValueT>::__digits10;
983 
984  // [22.2.2.2.2] Stage 1, numeric conversion to character.
985  int __len;
986  // Long enough for the max format spec.
987  char __fbuf[16];
988  __num_base::_S_format_float(__io, __fbuf, __mod);
989 
990 #ifdef _GLIBCXX_USE_C99
991  // First try a buffer perhaps big enough (most probably sufficient
992  // for non-ios_base::fixed outputs)
993  int __cs_size = __max_digits * 3;
994  char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
995  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
996  __fbuf, __prec, __v);
997 
998  // If the buffer was not large enough, try again with the correct size.
999  if (__len >= __cs_size)
1000  {
1001  __cs_size = __len + 1;
1002  __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1003  __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
1004  __fbuf, __prec, __v);
1005  }
1006 #else
1007  // Consider the possibility of long ios_base::fixed outputs
1008  const bool __fixed = __io.flags() & ios_base::fixed;
1009  const int __max_exp =
1010  __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10;
1011 
1012  // The size of the output string is computed as follows.
1013  // ios_base::fixed outputs may need up to __max_exp + 1 chars
1014  // for the integer part + __prec chars for the fractional part
1015  // + 3 chars for sign, decimal point, '\0'. On the other hand,
1016  // for non-fixed outputs __max_digits * 2 + __prec chars are
1017  // largely sufficient.
1018  const int __cs_size = __fixed ? __max_exp + __prec + 4
1019  : __max_digits * 2 + __prec;
1020  char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1021  __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf,
1022  __prec, __v);
1023 #endif
1024 
1025  // [22.2.2.2.2] Stage 2, convert to char_type, using correct
1026  // numpunct.decimal_point() values for '.' and adding grouping.
1027  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1028 
1029  _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1030  * __len));
1031  __ctype.widen(__cs, __cs + __len, __ws);
1032 
1033  // Replace decimal point.
1034  _CharT* __wp = 0;
1035  const char* __p = char_traits<char>::find(__cs, __len, '.');
1036  if (__p)
1037  {
1038  __wp = __ws + (__p - __cs);
1039  *__wp = __lc->_M_decimal_point;
1040  }
1041 
1042  // Add grouping, if necessary.
1043  // N.B. Make sure to not group things like 2e20, i.e., no decimal
1044  // point, scientific notation.
1045  if (__lc->_M_use_grouping
1046  && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
1047  && __cs[1] >= '0' && __cs[2] >= '0')))
1048  {
1049  // Grouping can add (almost) as many separators as the
1050  // number of digits, but no more.
1051  _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1052  * __len * 2));
1053 
1054  streamsize __off = 0;
1055  if (__cs[0] == '-' || __cs[0] == '+')
1056  {
1057  __off = 1;
1058  __ws2[0] = __ws[0];
1059  __len -= 1;
1060  }
1061 
1062  _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
1063  __lc->_M_thousands_sep, __wp, __ws2 + __off,
1064  __ws + __off, __len);
1065  __len += __off;
1066 
1067  __ws = __ws2;
1068  }
1069 
1070  // Pad.
1071  const streamsize __w = __io.width();
1072  if (__w > static_cast<streamsize>(__len))
1073  {
1074  _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1075  * __w));
1076  _M_pad(__fill, __w, __io, __ws3, __ws, __len);
1077  __ws = __ws3;
1078  }
1079  __io.width(0);
1080 
1081  // [22.2.2.2.2] Stage 4.
1082  // Write resulting, fully-formatted string to output iterator.
1083  return std::__write(__s, __ws, __len);
1084  }
1085 
1086  template<typename _CharT, typename _OutIter>
1087  _OutIter
1088  num_put<_CharT, _OutIter>::
1089  do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
1090  {
1091  const ios_base::fmtflags __flags = __io.flags();
1092  if ((__flags & ios_base::boolalpha) == 0)
1093  {
1094  const long __l = __v;
1095  __s = _M_insert_int(__s, __io, __fill, __l);
1096  }
1097  else
1098  {
1099  typedef __numpunct_cache<_CharT> __cache_type;
1100  __use_cache<__cache_type> __uc;
1101  const locale& __loc = __io._M_getloc();
1102  const __cache_type* __lc = __uc(__loc);
1103 
1104  const _CharT* __name = __v ? __lc->_M_truename
1105  : __lc->_M_falsename;
1106  int __len = __v ? __lc->_M_truename_size
1107  : __lc->_M_falsename_size;
1108 
1109  const streamsize __w = __io.width();
1110  if (__w > static_cast<streamsize>(__len))
1111  {
1112  const streamsize __plen = __w - __len;
1113  _CharT* __ps
1114  = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1115  * __plen));
1116 
1117  char_traits<_CharT>::assign(__ps, __plen, __fill);
1118  __io.width(0);
1119 
1120  if ((__flags & ios_base::adjustfield) == ios_base::left)
1121  {
1122  __s = std::__write(__s, __name, __len);
1123  __s = std::__write(__s, __ps, __plen);
1124  }
1125  else
1126  {
1127  __s = std::__write(__s, __ps, __plen);
1128  __s = std::__write(__s, __name, __len);
1129  }
1130  return __s;
1131  }
1132  __io.width(0);
1133  __s = std::__write(__s, __name, __len);
1134  }
1135  return __s;
1136  }
1137 
1138  template<typename _CharT, typename _OutIter>
1139  _OutIter
1140  num_put<_CharT, _OutIter>::
1141  do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1142  { return _M_insert_float(__s, __io, __fill, char(), __v); }
1143 
1144 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
1145  template<typename _CharT, typename _OutIter>
1146  _OutIter
1147  num_put<_CharT, _OutIter>::
1148  __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1149  { return _M_insert_float(__s, __io, __fill, char(), __v); }
1150 #endif
1151 
1152  template<typename _CharT, typename _OutIter>
1153  _OutIter
1154  num_put<_CharT, _OutIter>::
1155  do_put(iter_type __s, ios_base& __io, char_type __fill,
1156  long double __v) const
1157  { return _M_insert_float(__s, __io, __fill, 'L', __v); }
1158 
1159  template<typename _CharT, typename _OutIter>
1160  _OutIter
1161  num_put<_CharT, _OutIter>::
1162  do_put(iter_type __s, ios_base& __io, char_type __fill,
1163  const void* __v) const
1164  {
1165  const ios_base::fmtflags __flags = __io.flags();
1166  const ios_base::fmtflags __fmt = ~(ios_base::basefield
1167  | ios_base::uppercase);
1168  __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
1169 
1170  typedef __gnu_cxx::__conditional_type<(sizeof(const void*)
1171  <= sizeof(unsigned long)),
1172  unsigned long, unsigned long long>::__type _UIntPtrType;
1173 
1174  __s = _M_insert_int(__s, __io, __fill,
1175  reinterpret_cast<_UIntPtrType>(__v));
1176  __io.flags(__flags);
1177  return __s;
1178  }
1179 
1180 _GLIBCXX_END_NAMESPACE_LDBL
1181 
1182  // Construct correctly padded string, as per 22.2.2.2.2
1183  // Assumes
1184  // __newlen > __oldlen
1185  // __news is allocated for __newlen size
1186 
1187  // NB: Of the two parameters, _CharT can be deduced from the
1188  // function arguments. The other (_Traits) has to be explicitly specified.
1189  template<typename _CharT, typename _Traits>
1190  void
1191  __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
1192  _CharT* __news, const _CharT* __olds,
1193  streamsize __newlen, streamsize __oldlen)
1194  {
1195  const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
1196  const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
1197 
1198  // Padding last.
1199  if (__adjust == ios_base::left)
1200  {
1201  _Traits::copy(__news, __olds, __oldlen);
1202  _Traits::assign(__news + __oldlen, __plen, __fill);
1203  return;
1204  }
1205 
1206  size_t __mod = 0;
1207  if (__adjust == ios_base::internal)
1208  {
1209  // Pad after the sign, if there is one.
1210  // Pad after 0[xX], if there is one.
1211  // Who came up with these rules, anyway? Jeeze.
1212  const locale& __loc = __io._M_getloc();
1213  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1214 
1215  if (__ctype.widen('-') == __olds[0]
1216  || __ctype.widen('+') == __olds[0])
1217  {
1218  __news[0] = __olds[0];
1219  __mod = 1;
1220  ++__news;
1221  }
1222  else if (__ctype.widen('0') == __olds[0]
1223  && __oldlen > 1
1224  && (__ctype.widen('x') == __olds[1]
1225  || __ctype.widen('X') == __olds[1]))
1226  {
1227  __news[0] = __olds[0];
1228  __news[1] = __olds[1];
1229  __mod = 2;
1230  __news += 2;
1231  }
1232  // else Padding first.
1233  }
1234  _Traits::assign(__news, __plen, __fill);
1235  _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod);
1236  }
1237 
1238  template<typename _CharT>
1239  _CharT*
1240  __add_grouping(_CharT* __s, _CharT __sep,
1241  const char* __gbeg, size_t __gsize,
1242  const _CharT* __first, const _CharT* __last)
1243  {
1244  size_t __idx = 0;
1245  size_t __ctr = 0;
1246 
1247  while (__last - __first > __gbeg[__idx]
1248  && static_cast<signed char>(__gbeg[__idx]) > 0
1249  && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max)
1250  {
1251  __last -= __gbeg[__idx];
1252  __idx < __gsize - 1 ? ++__idx : ++__ctr;
1253  }
1254 
1255  while (__first != __last)
1256  *__s++ = *__first++;
1257 
1258  while (__ctr--)
1259  {
1260  *__s++ = __sep;
1261  for (char __i = __gbeg[__idx]; __i > 0; --__i)
1262  *__s++ = *__first++;
1263  }
1264 
1265  while (__idx--)
1266  {
1267  *__s++ = __sep;
1268  for (char __i = __gbeg[__idx]; __i > 0; --__i)
1269  *__s++ = *__first++;
1270  }
1271 
1272  return __s;
1273  }
1274 
1275  // Inhibit implicit instantiations for required instantiations,
1276  // which are defined via explicit instantiations elsewhere.
1277 #if _GLIBCXX_EXTERN_TEMPLATE
1278  extern template class numpunct<char>;
1279  extern template class numpunct_byname<char>;
1280  extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>;
1281  extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>;
1282  extern template class ctype_byname<char>;
1283 
1284  extern template
1285  const ctype<char>&
1286  use_facet<ctype<char> >(const locale&);
1287 
1288  extern template
1289  const numpunct<char>&
1290  use_facet<numpunct<char> >(const locale&);
1291 
1292  extern template
1293  const num_put<char>&
1294  use_facet<num_put<char> >(const locale&);
1295 
1296  extern template
1297  const num_get<char>&
1298  use_facet<num_get<char> >(const locale&);
1299 
1300  extern template
1301  bool
1302  has_facet<ctype<char> >(const locale&);
1303 
1304  extern template
1305  bool
1306  has_facet<numpunct<char> >(const locale&);
1307 
1308  extern template
1309  bool
1310  has_facet<num_put<char> >(const locale&);
1311 
1312  extern template
1313  bool
1314  has_facet<num_get<char> >(const locale&);
1315 
1316 #ifdef _GLIBCXX_USE_WCHAR_T
1317  extern template class numpunct<wchar_t>;
1318  extern template class numpunct_byname<wchar_t>;
1319  extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>;
1320  extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>;
1321  extern template class ctype_byname<wchar_t>;
1322 
1323  extern template
1324  const ctype<wchar_t>&
1325  use_facet<ctype<wchar_t> >(const locale&);
1326 
1327  extern template
1328  const numpunct<wchar_t>&
1329  use_facet<numpunct<wchar_t> >(const locale&);
1330 
1331  extern template
1332  const num_put<wchar_t>&
1333  use_facet<num_put<wchar_t> >(const locale&);
1334 
1335  extern template
1336  const num_get<wchar_t>&
1337  use_facet<num_get<wchar_t> >(const locale&);
1338 
1339  extern template
1340  bool
1341  has_facet<ctype<wchar_t> >(const locale&);
1342 
1343  extern template
1344  bool
1345  has_facet<numpunct<wchar_t> >(const locale&);
1346 
1347  extern template
1348  bool
1349  has_facet<num_put<wchar_t> >(const locale&);
1350 
1351  extern template
1352  bool
1353  has_facet<num_get<wchar_t> >(const locale&);
1354 #endif
1355 #endif
1356 
1357 _GLIBCXX_END_NAMESPACE_VERSION
1358 } // namespace
1359 
1360 #endif