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