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