1 // Locale support -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
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 2, or (at your option)
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 // Warning: this file is not meant for user inclusion. Use <locale>.
32 #ifndef _CPP_BITS_LOCFACETS_TCC
33 #define _CPP_BITS_LOCFACETS_TCC 1
36 #include <clocale> // For localeconv
37 #include <cstdlib> // For strof, strtold
38 #include <cmath> // For ceil
39 #include <cctype> // For isspace
40 #include <limits> // For numeric_limits
41 #include <memory> // For auto_ptr
42 #include <bits/streambuf_iterator.h> // For streambuf_iterators
43 #include <typeinfo> // For bad_cast
48 template<typename _Facet>
50 locale::combine(const locale& __other) const
52 _Impl* __tmp = new _Impl(*_M_impl, 1);
53 __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
57 template<typename _CharT, typename _Traits, typename _Alloc>
59 locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
60 const basic_string<_CharT, _Traits, _Alloc>& __s2) const
62 typedef std::collate<_CharT> __collate_type;
63 const __collate_type& __collate = use_facet<__collate_type>(*this);
64 return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
65 __s2.data(), __s2.data() + __s2.length()) < 0);
68 template<typename _Facet>
70 use_facet(const locale& __loc)
72 size_t __i = _Facet::id._M_index;
73 locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
74 const locale::facet* __fp = (*__facet)[__i];
75 if (__fp == 0 || __i >= __facet->size())
77 return static_cast<const _Facet&>(*__fp);
80 template<typename _Facet>
82 has_facet(const locale& __loc) throw()
84 size_t __i = _Facet::id._M_index;
85 locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
86 return (__i < __facet->size() && (*__facet)[__i] != 0);
90 template<typename _CharT, typename _InIter>
92 num_get<_CharT, _InIter>::
93 _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
94 ios_base::iostate& __err, string& __xtrc) const
96 const locale __loc = __io.getloc();
97 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
98 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
100 // Check first for sign.
101 const char_type __plus = __ctype.widen('+');
102 const char_type __minus = __ctype.widen('-');
104 char_type __c = *__beg;
105 if ((__c == __plus || __c == __minus) && __beg != __end)
107 __xtrc += __ctype.narrow(__c, char());
112 // Next, strip leading zeros.
113 const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
114 bool __found_zero = false;
115 while (__c == __zero && __beg != __end)
122 __xtrc += _S_atoms[_M_zero];
126 // Only need acceptable digits for floating point numbers.
127 const size_t __len = _M_E - _M_zero + 1;
128 char_type __watoms[__len];
129 __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
130 bool __found_dec = false;
131 bool __found_sci = false;
132 const char_type __dec = __np.decimal_point();
134 string __found_grouping;
135 const string __grouping = __np.grouping();
136 bool __check_grouping = __grouping.size();
138 const char_type __sep = __np.thousands_sep();
140 while (__beg != __end)
142 // Only look in digits.
143 typedef char_traits<_CharT> __traits_type;
144 const char_type* __p = __traits_type::find(__watoms, 10, __c);
146 // NB: strchr returns true for __c == 0x0
149 // Try first for acceptable digit; record it if found.
151 __xtrc += _S_atoms[__p - __watoms];
155 else if (__c == __sep && __check_grouping && !__found_dec)
157 // NB: Thousands separator at the beginning of a string
158 // is a no-no, as is two consecutive thousands separators.
161 __found_grouping += static_cast<char>(__sep_pos);
167 __err |= ios_base::failbit;
171 else if (__c == __dec && !__found_dec)
173 __found_grouping += static_cast<char>(__sep_pos);
179 else if ((__c == __watoms[_M_e] || __c == __watoms[_M_E])
180 && !__found_sci && __pos)
182 // Scientific notation.
184 __xtrc += __ctype.narrow(__c, char());
187 // Remove optional plus or minus sign, if they exist.
188 if (__c == __plus || __c == __minus)
191 __xtrc += __ctype.narrow(__c, char());
197 // Not a valid input item.
201 // Digit grouping is checked. If grouping and found_grouping don't
202 // match, then get very very upset, and set failbit.
203 if (__check_grouping && __found_grouping.size())
205 // Add the ending grouping if a decimal wasn't found.
207 __found_grouping += static_cast<char>(__sep_pos);
208 if (!__verify_grouping(__grouping, __found_grouping))
209 __err |= ios_base::failbit;
215 __err |= ios_base::eofbit;
218 template<typename _CharT, typename _InIter>
220 num_get<_CharT, _InIter>::
221 _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
222 ios_base::iostate& __err, char* __xtrc, int __max,
225 const locale __loc = __io.getloc();
226 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
227 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
229 // Stage 1: determine a conversion specifier.
230 // NB: Iff __basefield == 0, this can change based on contents.
231 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
232 if (__basefield == ios_base::oct)
234 else if (__basefield == ios_base::hex)
239 // Check first for sign.
241 char_type __c = *__beg;
242 if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
245 __xtrc[__pos++] = __ctype.narrow(__c, char());
249 // Next, strip leading zeros and check required digits for base formats.
250 const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
251 const char_type __x = __ctype.widen('x');
252 const char_type __X = __ctype.widen('X');
255 bool __found_zero = false;
256 while (__c == __zero && __beg != __end)
263 __xtrc[__pos++] = _S_atoms[_M_zero];
264 if (__basefield == 0)
266 if ((__c == __x || __c == __X) && __beg != __end)
268 __xtrc[__pos++] = __ctype.narrow(__c, char());
277 else if (__base == 16)
279 if (__c == __zero && __beg != __end)
281 __xtrc[__pos++] = _S_atoms[_M_zero];
283 if ((__c == __x || __c == __X) && __beg != __end)
285 __xtrc[__pos++] = __ctype.narrow(__c, char());
291 // At this point, base is determined. If not hex, only allow
292 // base digits as valid input.
299 // Figure out the maximum number of digits that can be extracted
300 // for the given type, using the determined base.
303 __max_digits = static_cast<int>(ceil(__max * _S_scale_hex));
304 else if (__base == 8)
305 __max_digits = static_cast<int>(ceil(__max * _S_scale_oct));
307 __max_digits = __max;
309 // Add in what's already been extracted.
310 __max_digits += __pos;
313 char_type __watoms[_M_size];
314 __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
315 string __found_grouping;
316 const string __grouping = __np.grouping();
317 bool __check_grouping = __grouping.size() && __base == 10;
319 const char_type __sep = __np.thousands_sep();
320 while (__beg != __end && __pos <= __max_digits)
322 typedef char_traits<_CharT> __traits_type;
323 const char_type* __p = __traits_type::find(__watoms, __len, __c);
325 // NB: strchr returns true for __c == 0x0
328 // Try first for acceptable digit; record it if found.
329 __xtrc[__pos++] = _S_atoms[__p - __watoms];
333 else if (__c == __sep && __check_grouping)
335 // NB: Thousands separator at the beginning of a string
336 // is a no-no, as is two consecutive thousands separators.
339 __found_grouping += static_cast<char>(__sep_pos);
345 __err |= ios_base::failbit;
350 // Not a valid input item.
354 // If one more than the maximum number of digits is extracted.
355 if (__pos > __max_digits)
356 __err |= ios_base::failbit;
358 // Digit grouping is checked. If grouping and found_grouping don't
359 // match, then get very very upset, and set failbit.
360 if (__check_grouping && __found_grouping.size())
362 // Add the ending grouping.
363 __found_grouping += static_cast<char>(__sep_pos);
364 if (!__verify_grouping(__grouping, __found_grouping))
365 __err |= ios_base::failbit;
369 __xtrc[__pos] = char();
371 __err |= ios_base::eofbit;
374 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
375 //17. Bad bool parsing
376 template<typename _CharT, typename _InIter>
378 num_get<_CharT, _InIter>::
379 do_get(iter_type __beg, iter_type __end, ios_base& __io,
380 ios_base::iostate& __err, bool& __v) const
382 // Parse bool values as long
383 if (!(__io.flags() & ios_base::boolalpha))
385 // NB: We can't just call do_get(long) here, as it might
386 // refer to a derived class.
388 // Stage 1: extract and determine the conversion specifier.
389 // Assuming leading zeros eliminated, thus the size of 32 for
393 // According to 18.2.1.2.9, digits10 is "Number of base 10 digits
394 // that can be represented without change" so we have to add 1 to it
395 // in order to obtain the max number of digits. The same for the
396 // other do_get for integral types below.
397 _M_extract_int(__beg, __end, __io, __err, __xtrc,
398 numeric_limits<bool>::digits10 + 1, __base);
400 // Stage 2: convert and store results.
403 long __l = strtol(__xtrc, &__sanity, __base);
404 if (!(__err & ios_base::failbit)
406 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
409 __err |= ios_base::failbit;
412 // Parse bool values as alphanumeric
415 locale __loc = __io.getloc();
416 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__loc);
417 const char_type* __true = __np.truename().c_str();
418 const char_type* __false = __np.falsename().c_str();
420 const size_t __truen = __np.truename().size() - 1;
421 const size_t __falsen = __np.falsename().size() - 1;
423 for (size_t __n = 0; __beg != __end; ++__n)
425 char_type __c = *__beg++;
426 bool __testf = __n <= __falsen ? __c == __false[__n] : false;
427 bool __testt = __n <= __truen ? __c == __true[__n] : false;
428 if (!(__testf || __testt))
430 __err |= ios_base::failbit;
433 else if (__testf && __n == __falsen)
438 else if (__testt && __n == __truen)
445 __err |= ios_base::eofbit;
451 template<typename _CharT, typename _InIter>
453 num_get<_CharT, _InIter>::
454 do_get(iter_type __beg, iter_type __end, ios_base& __io,
455 ios_base::iostate& __err, long& __v) const
457 // Stage 1: extract and determine the conversion specifier.
458 // Assuming leading zeros eliminated, thus the size of 32 for
462 _M_extract_int(__beg, __end, __io, __err, __xtrc,
463 numeric_limits<long>::digits10 + 1, __base);
465 // Stage 2: convert and store results.
468 long __l = strtol(__xtrc, &__sanity, __base);
469 if (!(__err & ios_base::failbit)
470 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
473 __err |= ios_base::failbit;
477 template<typename _CharT, typename _InIter>
479 num_get<_CharT, _InIter>::
480 do_get(iter_type __beg, iter_type __end, ios_base& __io,
481 ios_base::iostate& __err, unsigned short& __v) const
483 // Stage 1: extract and determine the conversion specifier.
484 // Assuming leading zeros eliminated, thus the size of 32 for
488 _M_extract_int(__beg, __end, __io, __err, __xtrc,
489 numeric_limits<unsigned short>::digits10 + 1, __base);
491 // Stage 2: convert and store results.
494 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
495 if (!(__err & ios_base::failbit)
496 && __sanity != __xtrc && *__sanity == '\0' && errno == 0
497 && __ul <= USHRT_MAX)
498 __v = static_cast<unsigned short>(__ul);
500 __err |= ios_base::failbit;
504 template<typename _CharT, typename _InIter>
506 num_get<_CharT, _InIter>::
507 do_get(iter_type __beg, iter_type __end, ios_base& __io,
508 ios_base::iostate& __err, unsigned int& __v) const
510 // Stage 1: extract and determine the conversion specifier.
511 // Assuming leading zeros eliminated, thus the size of 32 for
515 _M_extract_int(__beg, __end, __io, __err, __xtrc,
516 numeric_limits<unsigned int>::digits10 + 1, __base);
518 // Stage 2: convert and store results.
521 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
522 if (!(__err & ios_base::failbit)
523 && __sanity != __xtrc && *__sanity == '\0' && errno == 0
525 __v = static_cast<unsigned int>(__ul);
527 __err |= ios_base::failbit;
531 template<typename _CharT, typename _InIter>
533 num_get<_CharT, _InIter>::
534 do_get(iter_type __beg, iter_type __end, ios_base& __io,
535 ios_base::iostate& __err, unsigned long& __v) const
537 // Stage 1: extract and determine the conversion specifier.
538 // Assuming leading zeros eliminated, thus the size of 32 for
542 _M_extract_int(__beg, __end, __io, __err, __xtrc,
543 numeric_limits<unsigned long>::digits10 + 1, __base);
545 // Stage 2: convert and store results.
548 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
549 if (!(__err & ios_base::failbit)
550 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
553 __err |= ios_base::failbit;
557 #ifdef _GLIBCPP_USE_LONG_LONG
558 template<typename _CharT, typename _InIter>
560 num_get<_CharT, _InIter>::
561 do_get(iter_type __beg, iter_type __end, ios_base& __io,
562 ios_base::iostate& __err, long long& __v) const
564 // Stage 1: extract and determine the conversion specifier.
565 // Assuming leading zeros eliminated, thus the size of 32 for
569 _M_extract_int(__beg, __end, __io, __err, __xtrc,
570 numeric_limits<long long>::digits10 + 1, __base);
572 // Stage 2: convert and store results.
575 long long __ll = strtoll(__xtrc, &__sanity, __base);
576 if (!(__err & ios_base::failbit)
577 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
580 __err |= ios_base::failbit;
584 template<typename _CharT, typename _InIter>
586 num_get<_CharT, _InIter>::
587 do_get(iter_type __beg, iter_type __end, ios_base& __io,
588 ios_base::iostate& __err, unsigned long long& __v) const
590 // Stage 1: extract and determine the conversion specifier.
591 // Assuming leading zeros eliminated, thus the size of 32 for
595 _M_extract_int(__beg, __end, __io, __err, __xtrc,
596 numeric_limits<unsigned long long>::digits10 + 1, __base);
598 // Stage 2: convert and store results.
601 unsigned long long __ull = strtoull(__xtrc, &__sanity, __base);
602 if (!(__err & ios_base::failbit)
603 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
606 __err |= ios_base::failbit;
611 template<typename _CharT, typename _InIter>
613 num_get<_CharT, _InIter>::
614 do_get(iter_type __beg, iter_type __end, ios_base& __io,
615 ios_base::iostate& __err, float& __v) const
617 // Stage 1: extract and determine the conversion specifier.
620 _M_extract_float(__beg, __end, __io, __err, __xtrc);
622 // Stage 2: convert and store results.
625 #ifdef _GLIBCPP_USE_C99
626 float __f = strtof(__xtrc.c_str(), &__sanity);
628 float __f = static_cast<float>(strtod(__xtrc.c_str(), &__sanity));
630 if (!(__err & ios_base::failbit)
631 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
634 __err |= ios_base::failbit;
638 template<typename _CharT, typename _InIter>
640 num_get<_CharT, _InIter>::
641 do_get(iter_type __beg, iter_type __end, ios_base& __io,
642 ios_base::iostate& __err, double& __v) const
644 // Stage 1: extract and determine the conversion specifier.
647 _M_extract_float(__beg, __end, __io, __err, __xtrc);
649 // Stage 2: convert and store results.
652 double __d = strtod(__xtrc.c_str(), &__sanity);
653 if (!(__err & ios_base::failbit)
654 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
657 __err |= ios_base::failbit;
661 template<typename _CharT, typename _InIter>
663 num_get<_CharT, _InIter>::
664 do_get(iter_type __beg, iter_type __end, ios_base& __io,
665 ios_base::iostate& __err, long double& __v) const
667 // Stage 1: extract and determine the conversion specifier.
670 _M_extract_float(__beg, __end, __io, __err, __xtrc);
672 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
673 // Stage 2: convert and store results.
676 long double __ld = strtold(__xtrc.c_str(), &__sanity);
677 if (!(__err & ios_base::failbit)
678 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
681 // Stage 2: determine a conversion specifier.
682 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
684 if (__basefield == ios_base::oct)
686 else if (__basefield == ios_base::hex)
688 else if (__basefield == 0)
693 // Stage 3: store results.
694 typedef typename char_traits<_CharT>::int_type int_type;
696 int __p = sscanf(__xtrc.c_str(), __conv, &__ld);
697 if (!(__err & ios_base::failbit) && __p
698 && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
702 __err |= ios_base::failbit;
706 template<typename _CharT, typename _InIter>
708 num_get<_CharT, _InIter>::
709 do_get(iter_type __beg, iter_type __end, ios_base& __io,
710 ios_base::iostate& __err, void*& __v) const
712 // Prepare for hex formatted input
713 typedef ios_base::fmtflags fmtflags;
714 fmtflags __fmt = __io.flags();
715 fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
716 | ios_base::uppercase | ios_base::internal);
717 __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
719 // Stage 1: extract and determine the conversion specifier.
720 // Assuming leading zeros eliminated, thus the size of 32 for
724 _M_extract_int(__beg, __end, __io, __err, __xtrc,
725 numeric_limits<unsigned long>::digits10 + 1, __base);
727 // Stage 2: convert and store results.
730 void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base));
731 if (!(__err & ios_base::failbit)
732 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
735 __err |= ios_base::failbit;
737 // Reset from hex formatted input
743 // The following code uses sprintf() to convert floating point
744 // values for insertion into a stream. An optimization would be to
745 // replace sprintf() with code that works directly on a wide buffer
746 // and then use __pad to do the padding. It would be good
747 // to replace sprintf() anyway to avoid accidental buffer overruns
748 // and to gain back the efficiency that C++ provides by knowing up
749 // front the type of the values to insert. This implementation
750 // follows the C++ standard fairly directly as outlined in 22.2.2.2
751 // [lib.locale.num.put]
752 template<typename _CharT, typename _OutIter>
753 template<typename _ValueT>
755 num_put<_CharT, _OutIter>::
756 _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
759 const int __max_digits = numeric_limits<_ValueT>::digits10;
760 streamsize __prec = __io.precision();
761 // Protect against sprintf() buffer overflows.
762 if (__prec > static_cast<streamsize>(__max_digits))
763 __prec = static_cast<streamsize>(__max_digits);
765 // Long enough for the max format spec.
768 // Consider the possibility of long ios_base::fixed outputs
769 const bool __fixed = __io.flags() & ios_base::fixed;
770 const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
771 // ios_base::fixed outputs may need up to __max_exp+1 chars
772 // for the integer part + up to __max_digits chars for the
773 // fractional part + 3 chars for sign, decimal point, '\0'. On
774 // the other hand, for non-fixed outputs __max_digits*3 chars
775 // are largely sufficient.
776 const int __cs_size = __fixed ? __max_exp + __max_digits + 4
778 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
781 // [22.2.2.2.2] Stage 1, numeric conversion to character.
782 if (_S_format_float(__io, __fbuf, __mod, __prec))
783 __len = sprintf(__cs, __fbuf, __prec, __v);
785 __len = sprintf(__cs, __fbuf, __v);
786 return _M_widen_float(__s, __io, __fill, __cs, __len);
789 template<typename _CharT, typename _OutIter>
790 template<typename _ValueT>
792 num_put<_CharT, _OutIter>::
793 _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
794 char __modl, _ValueT __v) const
796 // [22.2.2.2.2] Stage 1, numeric conversion to character.
797 // Leave room for "+/-," "0x," and commas. This size is
798 // arbitrary, but should work.
800 // Long enough for the max format spec.
802 _S_format_int(__io, __fbuf, __mod, __modl);
803 int __len = sprintf(__cs, __fbuf, __v);
804 return _M_widen_int(__s, __io, __fill, __cs, __len);
807 template<typename _CharT, typename _OutIter>
809 num_put<_CharT, _OutIter>::
810 _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
813 // [22.2.2.2.2] Stage 2, convert to char_type, using correct
814 // numpunct.decimal_point() values for '.' and adding grouping.
815 const locale __loc = __io.getloc();
816 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
817 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
819 // Grouping can add (almost) as many separators as the number of
820 // digits, but no more.
821 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
823 __ctype.widen(__cs, __cs + __len, __ws);
825 // Replace decimal point.
827 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
828 if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
829 __ws[__p - __ws] = __np.decimal_point();
831 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
832 //282. What types does numpunct grouping refer to?
833 // Add grouping, if necessary.
834 const string __grouping = __np.grouping();
835 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
836 if (__grouping.size())
839 int __declen = __p ? __p - __ws : __len;
840 __p2 = __add_grouping(__ws2, __np.thousands_sep(),
842 __grouping.c_str() + __grouping.size(),
843 __ws, __ws + __declen);
844 int __newlen = __p2 - __ws2;
846 // Tack on decimal part.
849 char_traits<_CharT>::copy(__p2, __p, __len - __declen);
850 __newlen += __len - __declen;
853 // Switch strings, establish correct new length.
858 return _M_insert(__s, __io, __fill, __ws, __len);
861 template<typename _CharT, typename _OutIter>
863 num_put<_CharT, _OutIter>::
864 _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
867 // [22.2.2.2.2] Stage 2, convert to char_type, using correct
868 // numpunct.decimal_point() values for '.' and adding grouping.
869 const locale __loc = __io.getloc();
870 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
871 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
873 // Grouping can add (almost) as many separators as the number of
874 // digits, but no more.
875 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
877 __ctype.widen(__cs, __cs + __len, __ws);
879 // Add grouping, if necessary.
880 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
881 const string __grouping = __np.grouping();
882 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
883 bool __dec = __basefield != ios_base::oct
884 && __basefield != ios_base::hex;
885 if (__grouping.size() && __dec)
888 __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
889 __grouping.c_str() + __grouping.size(),
895 return _M_insert(__s, __io, __fill, __ws, __len);
898 // For use by integer and floating-point types after they have been
899 // converted into a char_type string.
900 template<typename _CharT, typename _OutIter>
902 num_put<_CharT, _OutIter>::
903 _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
906 // [22.2.2.2.2] Stage 3.
907 streamsize __w = __io.width();
908 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
910 if (__w > static_cast<streamsize>(__len))
912 __pad(__io, __fill, __ws2, __ws, __w, __len, true);
913 __len = static_cast<int>(__w);
919 // [22.2.2.2.2] Stage 4.
920 // Write resulting, fully-formatted string to output iterator.
921 for (int __j = 0; __j < __len; ++__j, ++__s)
926 template<typename _CharT, typename _OutIter>
928 num_put<_CharT, _OutIter>::
929 do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
931 ios_base::fmtflags __flags = __io.flags();
932 if ((__flags & ios_base::boolalpha) == 0)
934 unsigned long __uv = __v;
935 _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
939 locale __loc = __io.getloc();
940 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
941 const char_type* __ws;
945 __ws = __np.truename().c_str();
946 __len = __np.truename().size();
950 __ws = __np.falsename().c_str();
951 __len = __np.falsename().size();
953 _M_insert(__s, __io, __fill, __ws, __len);
958 template<typename _CharT, typename _OutIter>
960 num_put<_CharT, _OutIter>::
961 do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
962 { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
964 template<typename _CharT, typename _OutIter>
966 num_put<_CharT, _OutIter>::
967 do_put(iter_type __s, ios_base& __io, char_type __fill,
968 unsigned long __v) const
969 { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
971 #ifdef _GLIBCPP_USE_LONG_LONG
972 template<typename _CharT, typename _OutIter>
974 num_put<_CharT, _OutIter>::
975 do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
976 { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
978 template<typename _CharT, typename _OutIter>
980 num_put<_CharT, _OutIter>::
981 do_put(iter_type __s, ios_base& __io, char_type __fill,
982 unsigned long long __v) const
983 { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
986 template<typename _CharT, typename _OutIter>
988 num_put<_CharT, _OutIter>::
989 do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
990 { return _M_convert_float(__s, __io, __fill, char_type(), __v); }
992 template<typename _CharT, typename _OutIter>
994 num_put<_CharT, _OutIter>::
995 do_put(iter_type __s, ios_base& __io, char_type __fill,
996 long double __v) const
997 { return _M_convert_float(__s, __io, __fill, 'L', __v); }
999 template<typename _CharT, typename _OutIter>
1001 num_put<_CharT, _OutIter>::
1002 do_put(iter_type __s, ios_base& __io, char_type __fill,
1003 const void* __v) const
1005 ios_base::fmtflags __flags = __io.flags();
1006 ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
1007 | ios_base::uppercase | ios_base::internal);
1008 __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
1011 _M_convert_int(__s, __io, __fill, 'u', char_type(),
1012 reinterpret_cast<unsigned long>(__v));
1013 __io.flags(__flags);
1017 __io.flags(__flags);
1018 __throw_exception_again;
1024 template<typename _CharT, typename _InIter>
1026 money_get<_CharT, _InIter>::
1027 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1028 ios_base::iostate& __err, long double& __units) const
1031 this->do_get(__beg, __end, __intl, __io, __err, __str);
1033 const int __n = numeric_limits<long double>::digits10;
1034 char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1035 const locale __loc = __io.getloc();
1036 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1037 const _CharT* __wcs = __str.c_str();
1038 __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);
1040 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
1043 long double __ld = strtold(__cs, &__sanity);
1044 if (!(__err & ios_base::failbit)
1045 && __sanity != __cs && *__sanity == '\0' && errno == 0)
1048 typedef typename char_traits<_CharT>::int_type int_type;
1050 int __p = sscanf(__cs, "%Lf", &__ld);
1051 if (!(__err & ios_base::failbit)
1052 && __p && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
1058 template<typename _CharT, typename _InIter>
1060 money_get<_CharT, _InIter>::
1061 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1062 ios_base::iostate& __err, string_type& __units) const
1064 // These contortions are quite unfortunate.
1065 typedef moneypunct<_CharT, true> __money_true;
1066 typedef moneypunct<_CharT, false> __money_false;
1067 typedef money_base::part part;
1068 typedef typename string_type::size_type size_type;
1070 const locale __loc = __io.getloc();
1071 const __money_true& __mpt = use_facet<__money_true>(__loc);
1072 const __money_false& __mpf = use_facet<__money_false>(__loc);
1073 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1075 const money_base::pattern __p = __intl ? __mpt.neg_format()
1076 : __mpf.neg_format();
1078 const string_type __pos_sign =__intl ? __mpt.positive_sign()
1079 : __mpf.positive_sign();
1080 const string_type __neg_sign =__intl ? __mpt.negative_sign()
1081 : __mpf.negative_sign();
1082 const char_type __d = __intl ? __mpt.decimal_point()
1083 : __mpf.decimal_point();
1084 const char_type __sep = __intl ? __mpt.thousands_sep()
1085 : __mpf.thousands_sep();
1087 const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
1089 // Set to deduced positive or negative sign, depending.
1091 // String of grouping info from thousands_sep plucked from __units.
1092 string __grouping_tmp;
1093 // Marker for thousands_sep position.
1095 // If input iterator is in a valid state.
1096 bool __testvalid = true;
1097 // Flag marking when a decimal point is found.
1098 bool __testdecfound = false;
1100 char_type __c = *__beg;
1101 char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
1102 for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
1104 part __which = static_cast<part>(__p.field[__i]);
1107 case money_base::symbol:
1108 if (__io.flags() & ios_base::showbase)
1110 // Symbol is required.
1111 const string_type __symbol = __intl ? __mpt.curr_symbol()
1112 : __mpf.curr_symbol();
1113 size_type __len = __symbol.size();
1115 while (__beg != __end
1116 && __i < __len && __symbol[__i] == __c)
1122 __testvalid = false;
1125 case money_base::sign:
1126 // Sign might not exist, or be more than one character long.
1127 if (__pos_sign.size() && __neg_sign.size())
1129 // Sign is mandatory.
1130 if (__c == __pos_sign[0])
1132 __sign = __pos_sign;
1135 else if (__c == __neg_sign[0])
1137 __sign = __neg_sign;
1141 __testvalid = false;
1143 else if (__pos_sign.size() && __c == __pos_sign[0])
1145 __sign = __pos_sign;
1148 else if (__neg_sign.size() && __c == __neg_sign[0])
1150 __sign = __neg_sign;
1154 case money_base::value:
1155 // Extract digits, remove and stash away the
1156 // grouping of found thousands separators.
1157 while (__beg != __end
1158 && (__ctype.is(ctype_base::digit, __c)
1159 || (__c == __d && !__testdecfound)
1164 __grouping_tmp += static_cast<char>(__sep_pos);
1166 __testdecfound = true;
1168 else if (__c == __sep)
1170 if (__grouping.size())
1172 // Mark position for later analysis.
1173 __grouping_tmp += static_cast<char>(__sep_pos);
1178 __testvalid = false;
1190 case money_base::space:
1191 case money_base::none:
1192 // Only if not at the end of the pattern.
1194 while (__beg != __end
1195 && __ctype.is(ctype_base::space, __c))
1201 // Need to get the rest of the sign characters, if they exist.
1202 if (__sign.size() > 1)
1204 size_type __len = __sign.size();
1206 for (; __c != __eof && __i < __len; ++__i)
1207 while (__beg != __end && __c != __sign[__i])
1211 __testvalid = false;
1214 // Strip leading zeros.
1215 while (__units[0] == __ctype.widen('0'))
1216 __units.erase(__units.begin());
1218 if (__sign == __neg_sign)
1219 __units.insert(__units.begin(), __ctype.widen('-'));
1221 // Test for grouping fidelity.
1222 if (__grouping.size() && __grouping_tmp.size())
1224 if (!__verify_grouping(__grouping, __grouping_tmp))
1225 __testvalid = false;
1228 // Iff no more characters are available.
1230 __err |= ios_base::eofbit;
1232 // Iff valid sequence is not recognized.
1233 if (!__testvalid || !__units.size())
1234 __err |= ios_base::failbit;
1238 template<typename _CharT, typename _OutIter>
1240 money_put<_CharT, _OutIter>::
1241 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1242 long double __units) const
1244 const locale __loc = __io.getloc();
1245 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1246 const int __n = numeric_limits<long double>::digits10;
1247 char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1248 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1249 int __len = sprintf(__cs, "%.01Lf", __units);
1250 __ctype.widen(__cs, __cs + __len, __ws);
1251 string_type __digits(__ws);
1252 return this->do_put(__s, __intl, __io, __fill, __digits);
1255 template<typename _CharT, typename _OutIter>
1257 money_put<_CharT, _OutIter>::
1258 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1259 const string_type& __digits) const
1261 typedef typename string_type::size_type size_type;
1262 typedef money_base::part part;
1264 const locale __loc = __io.getloc();
1265 const size_type __width = static_cast<size_type>(__io.width());
1267 // These contortions are quite unfortunate.
1268 typedef moneypunct<_CharT, true> __money_true;
1269 typedef moneypunct<_CharT, false> __money_false;
1270 const __money_true& __mpt = use_facet<__money_true>(__loc);
1271 const __money_false& __mpf = use_facet<__money_false>(__loc);
1272 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1274 // Determine if negative or positive formats are to be used, and
1275 // discard leading negative_sign if it is present.
1276 const char_type* __beg = __digits.data();
1277 const char_type* __end = __beg + __digits.size();
1278 money_base::pattern __p;
1280 if (*__beg != __ctype.widen('-'))
1282 __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
1283 __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
1287 __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
1288 __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
1292 // Look for valid numbers in the current ctype facet within input digits.
1293 __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
1296 // Assume valid input, and attempt to format.
1297 // Break down input numbers into base components, as follows:
1298 // final_value = grouped units + (decimal point) + (digits)
1300 string_type __value;
1301 const string_type __symbol = __intl ? __mpt.curr_symbol()
1302 : __mpf.curr_symbol();
1304 // Deal with decimal point, decimal digits.
1305 const int __frac = __intl ? __mpt.frac_digits()
1306 : __mpf.frac_digits();
1309 const char_type __d = __intl ? __mpt.decimal_point()
1310 : __mpf.decimal_point();
1311 if (__end - __beg >= __frac)
1313 __value = string_type(__end - __frac, __end);
1314 __value.insert(__value.begin(), __d);
1319 // Have to pad zeros in the decimal position.
1320 __value = string_type(__beg, __end);
1321 int __paddec = __frac - (__end - __beg);
1322 char_type __zero = __ctype.widen('0');
1323 __value.insert(__value.begin(), __paddec, __zero);
1324 __value.insert(__value.begin(), __d);
1329 // Add thousands separators to non-decimal digits, per
1333 const string __grouping = __intl ? __mpt.grouping()
1335 if (__grouping.size())
1337 const char_type __sep = __intl ? __mpt.thousands_sep()
1338 : __mpf.thousands_sep();
1339 const char* __gbeg = __grouping.c_str();
1340 const char* __gend = __gbeg + __grouping.size();
1341 const int __n = numeric_limits<long double>::digits10 * 2;
1342 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1343 _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
1344 __gend, __beg, __end);
1345 __value.insert(0, __ws2, __ws_end - __ws2);
1348 __value.insert(0, string_type(__beg, __end));
1351 // Calculate length of resulting string.
1352 ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
1353 size_type __len = __value.size() + __sign.size();
1354 __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
1355 bool __testipad = __f == ios_base::internal && __len < __width;
1357 // Fit formatted digits into the required pattern.
1358 for (int __i = 0; __i < 4; ++__i)
1360 part __which = static_cast<part>(__p.field[__i]);
1363 case money_base::symbol:
1364 if (__io.flags() & ios_base::showbase)
1367 case money_base::sign:
1368 // Sign might not exist, or be more than one
1369 // charater long. In that case, add in the rest
1374 case money_base::value:
1377 case money_base::space:
1378 // At least one space is required, but if internal
1379 // formatting is required, an arbitrary number of
1380 // fill spaces will be necessary.
1382 __res += string_type(__width - __len, __fill);
1384 __res += __ctype.widen(' ');
1386 case money_base::none:
1388 __res += string_type(__width - __len, __fill);
1393 // Special case of multi-part sign parts.
1394 if (__sign.size() > 1)
1395 __res += string_type(__sign.begin() + 1, __sign.end());
1397 // Pad, if still necessary.
1398 __len = __res.size();
1399 if (__width > __len)
1401 if (__f == ios_base::left)
1403 __res.append(__width - __len, __fill);
1406 __res.insert(0, string_type(__width - __len, __fill));
1410 // Write resulting, fully-formatted string to output iterator.
1411 for (size_type __j = 0; __j < __len; ++__j)
1419 // NB: Not especially useful. Without an ios_base object or some
1420 // kind of locale reference, we are left clawing at the air where
1421 // the side of the mountain used to be...
1422 template<typename _CharT, typename _InIter>
1423 time_base::dateorder
1424 time_get<_CharT, _InIter>::do_date_order() const
1425 { return time_base::no_order; }
1427 template<typename _CharT, typename _InIter>
1429 time_get<_CharT, _InIter>::
1430 _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
1431 ios_base::iostate& __err, tm* __tm,
1432 const _CharT* __format) const
1434 locale __loc = __io.getloc();
1435 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1436 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1437 size_t __len = char_traits<_CharT>::length(__format);
1439 for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
1441 char __c = __format[__i];
1444 // Verify valid formatting code, attempt to extract.
1445 __c = __format[++__i];
1448 if (__c == 'E' || __c == 'O')
1451 __c = __format[++__i];
1458 // Abbreviated weekday name [tm_wday]
1459 const char_type* __days1[7];
1460 __tp._M_days_abbreviated(__days1);
1461 _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
1465 // Weekday name [tm_wday].
1466 const char_type* __days2[7];
1467 __tp._M_days(__days2);
1468 _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
1473 // Abbreviated month name [tm_mon]
1474 const char_type* __months1[12];
1475 __tp._M_months_abbreviated(__months1);
1476 _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
1480 // Month name [tm_mon].
1481 const char_type* __months2[12];
1482 __tp._M_months(__months2);
1483 _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
1487 // Default time and date representation.
1488 const char_type* __dt[2];
1489 __tp._M_date_time_formats(__dt);
1490 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1494 // Day [01, 31]. [tm_mday]
1495 _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
1499 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1501 __ctype.widen(__cs, __cs + 9, __wcs);
1502 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1506 // Hour [00, 23]. [tm_hour]
1507 _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1511 // Hour [01, 12]. [tm_hour]
1512 _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
1516 // Month [01, 12]. [tm_mon]
1517 _M_extract_num(__beg, __end, __mem, 1, 12, 2,
1520 __tm->tm_mon = __mem - 1;
1523 // Minute [00, 59]. [tm_min]
1524 _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1528 if (__ctype.narrow(*__beg, 0) == '\n')
1531 __err |= ios_base::failbit;
1534 // Equivalent to (%H:%M).
1536 __ctype.widen(__cs, __cs + 6, __wcs);
1537 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1542 _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
1546 if (__ctype.narrow(*__beg, 0) == '\t')
1549 __err |= ios_base::failbit;
1552 // Equivalent to (%H:%M:%S).
1554 __ctype.widen(__cs, __cs + 9, __wcs);
1555 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1560 const char_type* __dates[2];
1561 __tp._M_date_formats(__dates);
1562 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1567 const char_type* __times[2];
1568 __tp._M_time_formats(__times);
1569 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1573 // Two digit year. [tm_year]
1574 _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
1578 // Year [1900). [tm_year]
1579 _M_extract_num(__beg, __end, __mem, 0,
1580 numeric_limits<int>::max(), 4,
1583 __tm->tm_year = __mem - 1900;
1587 if (__ctype.is(ctype_base::upper, *__beg))
1590 _M_extract_name(__beg, __end, __tmp,
1591 __timepunct<_CharT>::_S_timezones,
1594 // GMT requires special effort.
1595 char_type __c = *__beg;
1596 if (!__err && __tmp == 0
1597 && (__c == __ctype.widen('-')
1598 || __c == __ctype.widen('+')))
1600 _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1602 _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1607 __err |= ios_base::failbit;
1611 __err |= ios_base::failbit;
1616 // Verify format and input match, extract and discard.
1617 if (__c == __ctype.narrow(*__beg, 0))
1620 __err |= ios_base::failbit;
1625 template<typename _CharT, typename _InIter>
1627 time_get<_CharT, _InIter>::
1628 _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
1629 int __min, int __max, size_t __len,
1630 const ctype<_CharT>& __ctype,
1631 ios_base::iostate& __err) const
1635 bool __testvalid = true;
1636 char_type __c = *__beg;
1637 while (__beg != __end && __i < __len
1638 && __ctype.is(ctype_base::digit, __c))
1640 __digits += __ctype.narrow(__c, 0);
1646 int __value = atoi(__digits.c_str());
1647 if (__min <= __value && __value <= __max)
1650 __testvalid = false;
1653 __testvalid = false;
1655 __err |= ios_base::failbit;
1659 // All elements in __names are unique.
1660 template<typename _CharT, typename _InIter>
1662 time_get<_CharT, _InIter>::
1663 _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
1664 const _CharT** __names, size_t __indexlen,
1665 ios_base::iostate& __err) const
1667 typedef char_traits<char_type> __traits_type;
1668 int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
1669 size_t __nmatches = 0;
1671 bool __testvalid = true;
1672 const char_type* __name;
1674 char_type __c = *__beg;
1675 // Look for initial matches.
1676 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
1677 if (__c == __names[__i1][0])
1678 __matches[__nmatches++] = __i1;
1680 while(__nmatches > 1)
1682 // Find smallest matching string.
1683 size_t __minlen = 10;
1684 for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
1685 __minlen = min(__minlen,
1686 __traits_type::length(__names[__matches[__i2]]));
1688 if (__pos < __minlen && __beg != __end)
1692 for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
1694 __name = __names[__matches[__i3]];
1695 if (__name[__pos] != __c)
1696 __matches[__i3] = __matches[--__nmatches];
1703 if (__nmatches == 1)
1705 // Make sure found name is completely extracted.
1706 __name = __names[__matches[0]];
1707 const size_t __len = __traits_type::length(__name);
1708 while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
1712 __member = __matches[0];
1714 __testvalid = false;
1717 __testvalid = false;
1719 __err |= ios_base::failbit;
1722 template<typename _CharT, typename _InIter>
1724 time_get<_CharT, _InIter>::
1725 do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1726 ios_base::iostate& __err, tm* __tm) const
1729 const char* __cs = "%X";
1730 locale __loc = __io.getloc();
1731 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1732 __ctype.widen(__cs, __cs + 3, __wcs);
1733 _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1735 __err |= ios_base::eofbit;
1739 template<typename _CharT, typename _InIter>
1741 time_get<_CharT, _InIter>::
1742 do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1743 ios_base::iostate& __err, tm* __tm) const
1746 const char* __cs = "%x";
1747 locale __loc = __io.getloc();
1748 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1749 __ctype.widen(__cs, __cs + 3, __wcs);
1750 _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1752 __err |= ios_base::eofbit;
1756 template<typename _CharT, typename _InIter>
1758 time_get<_CharT, _InIter>::
1759 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
1760 ios_base::iostate& __err, tm* __tm) const
1762 typedef char_traits<char_type> __traits_type;
1763 locale __loc = __io.getloc();
1764 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1765 const char_type* __days[7];
1766 __tp._M_days_abbreviated(__days);
1768 _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
1770 // Check to see if non-abbreviated name exists, and extract.
1771 // NB: Assumes both _M_days and _M_days_abbreviated organized in
1772 // exact same order, first to last, such that the resulting
1773 // __days array with the same index points to a day, and that
1774 // day's abbreviated form.
1775 // NB: Also assumes that an abbreviated name is a subset of the name.
1778 size_t __pos = __traits_type::length(__days[__tmpwday]);
1779 __tp._M_days(__days);
1780 const char_type* __name = __days[__tmpwday];
1781 if (__name[__pos] == *__beg)
1783 // Extract the rest of it.
1784 const size_t __len = __traits_type::length(__name);
1785 while (__pos < __len && __beg != __end
1786 && __name[__pos] == *__beg)
1789 __err |= ios_base::failbit;
1792 __tm->tm_wday = __tmpwday;
1795 __err |= ios_base::eofbit;
1799 template<typename _CharT, typename _InIter>
1801 time_get<_CharT, _InIter>::
1802 do_get_monthname(iter_type __beg, iter_type __end,
1803 ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1805 typedef char_traits<char_type> __traits_type;
1806 locale __loc = __io.getloc();
1807 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1808 const char_type* __months[12];
1809 __tp._M_months_abbreviated(__months);
1811 _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
1813 // Check to see if non-abbreviated name exists, and extract.
1814 // NB: Assumes both _M_months and _M_months_abbreviated organized in
1815 // exact same order, first to last, such that the resulting
1816 // __months array with the same index points to a month, and that
1817 // month's abbreviated form.
1818 // NB: Also assumes that an abbreviated name is a subset of the name.
1821 size_t __pos = __traits_type::length(__months[__tmpmon]);
1822 __tp._M_months(__months);
1823 const char_type* __name = __months[__tmpmon];
1824 if (__name[__pos] == *__beg)
1826 // Extract the rest of it.
1827 const size_t __len = __traits_type::length(__name);
1828 while (__pos < __len && __beg != __end
1829 && __name[__pos] == *__beg)
1832 __err |= ios_base::failbit;
1835 __tm->tm_mon = __tmpmon;
1839 __err |= ios_base::eofbit;
1843 template<typename _CharT, typename _InIter>
1845 time_get<_CharT, _InIter>::
1846 do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
1847 ios_base::iostate& __err, tm* __tm) const
1849 locale __loc = __io.getloc();
1850 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1852 char_type __c = *__beg;
1855 while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
1857 __digits += __ctype.narrow(__c, 0);
1861 if (__i == 2 || __i == 4)
1863 int __year = atoi(__digits.c_str());
1864 __year = __i == 2 ? __year : __year - 1900;
1865 __tm->tm_year = __year;
1868 __err |= ios_base::failbit;
1870 __err |= ios_base::eofbit;
1874 template<typename _CharT, typename _OutIter>
1876 time_put<_CharT, _OutIter>::
1877 put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1878 const _CharT* __beg, const _CharT* __end) const
1880 locale __loc = __io.getloc();
1881 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1882 while (__beg != __end)
1884 char __c = __ctype.narrow(*__beg, 0);
1891 __c = __ctype.narrow(*__beg, 0);
1893 if (__c == 'E' || __c == 'O')
1896 __format = __ctype.narrow(*__beg, 0);
1901 this->do_put(__s, __io, char_type(), __tm, __format, __mod);
1909 template<typename _CharT, typename _OutIter>
1911 time_put<_CharT, _OutIter>::
1912 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1913 char __format, char __mod) const
1915 locale __loc = __io.getloc();
1916 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1917 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1919 // NB: This size is arbitrary. Should this be a data member,
1920 // initialized at construction?
1921 const size_t __maxlen = 64;
1922 char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen));
1924 // NB: In IEE 1003.1-200x, and perhaps other locale models, it
1925 // is possible that the format character will be longer than one
1926 // character. Possibilities include 'E' or 'O' followed by a
1927 // format character: if __mod is not the default argument, assume
1928 // it's a valid modifier.
1930 __fmt[0] = __ctype.widen('%');
1933 __fmt[1] = __format;
1934 __fmt[2] = char_type();
1939 __fmt[2] = __format;
1940 __fmt[3] = char_type();
1943 __tp._M_put_helper(__res, __maxlen, __fmt, __tm);
1945 // Write resulting, fully-formatted string to output iterator.
1946 size_t __len = char_traits<char_type>::length(__res);
1947 for (size_t __i = 0; __i < __len; ++__i)
1953 // Generic version does nothing.
1954 template<typename _CharT>
1956 collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const
1959 // Generic version does nothing.
1960 template<typename _CharT>
1962 collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const
1965 template<typename _CharT>
1968 do_compare(const _CharT* __lo1, const _CharT* __hi1,
1969 const _CharT* __lo2, const _CharT* __hi2) const
1971 const string_type __one(__lo1, __hi1);
1972 const string_type __two(__lo2, __hi2);
1973 return _M_compare_helper(__one.c_str(), __two.c_str());
1976 template<typename _CharT>
1977 typename collate<_CharT>::string_type
1979 do_transform(const _CharT* __lo, const _CharT* __hi) const
1981 size_t __len = __hi - __lo;
1982 _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
1983 size_t __res = _M_transform_helper(__c, __lo, __len);
1986 // Try to increment size of translated string.
1987 size_t __len2 = __len * 2;
1988 _CharT* __c2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len2));
1989 __res = _M_transform_helper(__c2, __lo, __len);
1990 // XXX Throw exception if still indeterminate?
1992 return string_type(__c);
1995 template<typename _CharT>
1998 do_hash(const _CharT* __lo, const _CharT* __hi) const
2000 unsigned long __val = 0;
2001 for (; __lo < __hi; ++__lo)
2002 __val = *__lo + ((__val << 7) |
2003 (__val >> (numeric_limits<unsigned long>::digits - 1)));
2004 return static_cast<long>(__val);
2007 // Construct correctly padded string, as per 22.2.2.2.2
2009 // __newlen > __oldlen
2010 // __news is allocated for __newlen size
2011 // Used by both num_put and ostream inserters: if __num,
2012 // internal-adjusted objects are padded according to the rules below
2013 // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
2015 template<typename _CharT, typename _Traits>
2017 __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
2018 const streamsize __newlen, const streamsize __oldlen,
2021 typedef _CharT char_type;
2022 typedef _Traits traits_type;
2023 typedef typename traits_type::int_type int_type;
2025 int_type __plen = static_cast<size_t>(__newlen - __oldlen);
2026 char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
2027 traits_type::assign(__pads, __plen, __fill);
2032 size_t __beglen; //either __plen or __oldlen
2033 ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
2035 if (__adjust == ios_base::left)
2038 __beg = const_cast<char_type*>(__olds);
2039 __beglen = __oldlen;
2042 else if (__adjust == ios_base::internal && __num)
2044 // Pad after the sign, if there is one.
2045 // Pad after 0[xX], if there is one.
2046 // Who came up with these rules, anyway? Jeeze.
2047 locale __loc = __io.getloc();
2048 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2049 const char_type __minus = __ctype.widen('-');
2050 const char_type __plus = __ctype.widen('+');
2051 bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
2052 bool __testhex = __ctype.widen('0') == __olds[0]
2053 && (__ctype.widen('x') == __olds[1]
2054 || __ctype.widen('X') == __olds[1]);
2057 __news[0] = __olds[0];
2058 __news[1] = __olds[1];
2063 __end = const_cast<char_type*>(__olds + __mod);
2065 else if (__testsign)
2067 __news[0] = __olds[0] == __plus ? __plus : __minus;
2072 __end = const_cast<char_type*>(__olds + __mod);
2079 __end = const_cast<char_type*>(__olds);
2087 __end = const_cast<char_type*>(__olds);
2089 traits_type::copy(__news, __beg, __beglen);
2090 traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
2093 // NB: Can't have default argument on non-member template, and
2094 // num_put doesn't have a _Traits template parameter, so this
2095 // forwarding template adds in the default template argument.
2096 template<typename _CharT>
2098 __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
2099 const streamsize __newlen, const streamsize __oldlen,
2102 return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, __olds,
2103 __newlen, __oldlen, __num);
2106 // Used by both numeric and monetary facets.
2107 // Check to make sure that the __grouping_tmp string constructed in
2108 // money_get or num_get matches the canonical grouping for a given
2110 // __grouping_tmp is parsed L to R
2111 // 1,222,444 == __grouping_tmp of "/1/3/3"
2112 // __grouping is parsed R to L
2113 // 1,222,444 == __grouping of "/3" == "/3/3/3"
2114 template<typename _CharT>
2116 __verify_grouping(const basic_string<_CharT>& __grouping,
2117 basic_string<_CharT>& __grouping_tmp)
2121 const int __len = __grouping.size();
2122 const int __n = __grouping_tmp.size();
2125 // Parsed number groupings have to match the
2126 // numpunct::grouping string exactly, starting at the
2127 // right-most point of the parsed sequence of elements ...
2128 while (__test && __i < __n - 1)
2129 for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
2130 __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
2131 // ... but the last parsed grouping can be <= numpunct
2133 __j == __len ? __j = 0 : __j;
2134 __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
2138 // Used by both numeric and monetary facets.
2139 // Inserts "group separator" characters into an array of characters.
2140 // It's recursive, one iteration per group. It moves the characters
2141 // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
2142 // only with __gbeg != __gend.
2143 template<typename _CharT>
2145 __add_grouping(_CharT* __s, _CharT __sep,
2146 const char* __gbeg, const char* __gend,
2147 const _CharT* __first, const _CharT* __last)
2149 if (__last - __first > *__gbeg)
2151 __s = __add_grouping(__s, __sep,
2152 (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
2153 __gend, __first, __last - *__gbeg);
2154 __first = __last - *__gbeg;
2158 *__s++ = *__first++;
2159 while (__first != __last);