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;
219 template<typename _CharT, typename _InIter>
221 num_get<_CharT, _InIter>::
222 _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
223 ios_base::iostate& __err, char* __xtrc, int __max,
226 const locale __loc = __io.getloc();
227 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
228 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
230 // Stage 1: determine a conversion specifier.
231 // NB: Iff __basefield == 0, this can change based on contents.
232 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
233 if (__basefield == ios_base::oct)
235 else if (__basefield == ios_base::hex)
240 // Check first for sign.
242 char_type __c = *__beg;
243 if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
246 __xtrc[__pos++] = __ctype.narrow(__c, char());
250 // Next, strip leading zeros and check required digits for base formats.
251 const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
252 const char_type __x = __ctype.widen('x');
253 const char_type __X = __ctype.widen('X');
256 bool __found_zero = false;
257 while (__c == __zero && __beg != __end)
264 __xtrc[__pos++] = _S_atoms[_M_zero];
265 if (__basefield == 0)
267 if ((__c == __x || __c == __X) && __beg != __end)
269 __xtrc[__pos++] = __ctype.narrow(__c, char());
278 else if (__base == 16)
280 if (__c == __zero && __beg != __end)
282 __xtrc[__pos++] = _S_atoms[_M_zero];
284 if ((__c == __x || __c == __X) && __beg != __end)
286 __xtrc[__pos++] = __ctype.narrow(__c, char());
292 // At this point, base is determined. If not hex, only allow
293 // base digits as valid input.
300 // Figure out the maximum number of digits that can be extracted
301 // for the given type, using the determined base.
304 __max_digits = static_cast<int>(ceil(__max * _S_scale_hex));
305 else if (__base == 8)
306 __max_digits = static_cast<int>(ceil(__max * _S_scale_oct));
308 __max_digits = __max;
310 // Add in what's already been extracted.
311 __max_digits += __pos;
314 char_type __watoms[_M_size];
315 __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
316 string __found_grouping;
317 const string __grouping = __np.grouping();
318 bool __check_grouping = __grouping.size() && __base == 10;
320 const char_type __sep = __np.thousands_sep();
321 while (__beg != __end && __pos <= __max_digits)
323 typedef char_traits<_CharT> __traits_type;
324 const char_type* __p = __traits_type::find(__watoms, __len, __c);
326 // NB: strchr returns true for __c == 0x0
329 // Try first for acceptable digit; record it if found.
330 __xtrc[__pos++] = _S_atoms[__p - __watoms];
334 else if (__c == __sep && __check_grouping)
336 // NB: Thousands separator at the beginning of a string
337 // is a no-no, as is two consecutive thousands separators.
340 __found_grouping += static_cast<char>(__sep_pos);
346 __err |= ios_base::failbit;
351 // Not a valid input item.
355 // If one more than the maximum number of digits is extracted.
356 if (__pos > __max_digits)
357 __err |= ios_base::failbit;
359 // Digit grouping is checked. If grouping and found_grouping don't
360 // match, then get very very upset, and set failbit.
361 if (__check_grouping && __found_grouping.size())
363 // Add the ending grouping.
364 __found_grouping += static_cast<char>(__sep_pos);
365 if (!__verify_grouping(__grouping, __found_grouping))
366 __err |= ios_base::failbit;
370 __xtrc[__pos] = char();
372 __err |= ios_base::eofbit;
376 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
377 //17. Bad bool parsing
378 template<typename _CharT, typename _InIter>
380 num_get<_CharT, _InIter>::
381 do_get(iter_type __beg, iter_type __end, ios_base& __io,
382 ios_base::iostate& __err, bool& __v) const
384 // Parse bool values as long
385 if (!(__io.flags() & ios_base::boolalpha))
387 // NB: We can't just call do_get(long) here, as it might
388 // refer to a derived class.
390 // Stage 1: extract and determine the conversion specifier.
391 // Assuming leading zeros eliminated, thus the size of 32 for
395 // According to 18.2.1.2.9, digits10 is "Number of base 10 digits
396 // that can be represented without change" so we have to add 1 to it
397 // in order to obtain the max number of digits. The same for the
398 // other do_get for integral types below.
399 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
400 numeric_limits<bool>::digits10 + 1, __base);
402 // Stage 2: convert and store results.
405 long __l = strtol(__xtrc, &__sanity, __base);
406 if (!(__err & ios_base::failbit)
408 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
411 __err |= ios_base::failbit;
414 // Parse bool values as alphanumeric
417 locale __loc = __io.getloc();
418 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__loc);
419 const char_type* __true = __np.truename().c_str();
420 const char_type* __false = __np.falsename().c_str();
422 const size_t __truen = __np.truename().size() - 1;
423 const size_t __falsen = __np.falsename().size() - 1;
425 for (size_t __n = 0; __beg != __end; ++__n)
427 char_type __c = *__beg++;
428 bool __testf = __n <= __falsen ? __c == __false[__n] : false;
429 bool __testt = __n <= __truen ? __c == __true[__n] : false;
430 if (!(__testf || __testt))
432 __err |= ios_base::failbit;
435 else if (__testf && __n == __falsen)
440 else if (__testt && __n == __truen)
447 __err |= ios_base::eofbit;
453 template<typename _CharT, typename _InIter>
455 num_get<_CharT, _InIter>::
456 do_get(iter_type __beg, iter_type __end, ios_base& __io,
457 ios_base::iostate& __err, long& __v) const
459 // Stage 1: extract and determine the conversion specifier.
460 // Assuming leading zeros eliminated, thus the size of 32 for
464 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
465 numeric_limits<long>::digits10 + 1, __base);
467 // Stage 2: convert and store results.
470 long __l = strtol(__xtrc, &__sanity, __base);
471 if (!(__err & ios_base::failbit)
472 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
475 __err |= ios_base::failbit;
479 template<typename _CharT, typename _InIter>
481 num_get<_CharT, _InIter>::
482 do_get(iter_type __beg, iter_type __end, ios_base& __io,
483 ios_base::iostate& __err, unsigned short& __v) const
485 // Stage 1: extract and determine the conversion specifier.
486 // Assuming leading zeros eliminated, thus the size of 32 for
490 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
491 numeric_limits<unsigned short>::digits10 + 1,
494 // Stage 2: convert and store results.
497 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
498 if (!(__err & ios_base::failbit)
499 && __sanity != __xtrc && *__sanity == '\0' && errno == 0
500 && __ul <= USHRT_MAX)
501 __v = static_cast<unsigned short>(__ul);
503 __err |= ios_base::failbit;
507 template<typename _CharT, typename _InIter>
509 num_get<_CharT, _InIter>::
510 do_get(iter_type __beg, iter_type __end, ios_base& __io,
511 ios_base::iostate& __err, unsigned int& __v) const
513 // Stage 1: extract and determine the conversion specifier.
514 // Assuming leading zeros eliminated, thus the size of 32 for
518 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
519 numeric_limits<unsigned int>::digits10 + 1,
522 // Stage 2: convert and store results.
525 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
526 if (!(__err & ios_base::failbit)
527 && __sanity != __xtrc && *__sanity == '\0' && errno == 0
529 __v = static_cast<unsigned int>(__ul);
531 __err |= ios_base::failbit;
535 template<typename _CharT, typename _InIter>
537 num_get<_CharT, _InIter>::
538 do_get(iter_type __beg, iter_type __end, ios_base& __io,
539 ios_base::iostate& __err, unsigned long& __v) const
541 // Stage 1: extract and determine the conversion specifier.
542 // Assuming leading zeros eliminated, thus the size of 32 for
546 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
547 numeric_limits<unsigned long>::digits10 + 1,
550 // Stage 2: convert and store results.
553 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
554 if (!(__err & ios_base::failbit)
555 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
558 __err |= ios_base::failbit;
562 #ifdef _GLIBCPP_USE_LONG_LONG
563 template<typename _CharT, typename _InIter>
565 num_get<_CharT, _InIter>::
566 do_get(iter_type __beg, iter_type __end, ios_base& __io,
567 ios_base::iostate& __err, long long& __v) const
569 // Stage 1: extract and determine the conversion specifier.
570 // Assuming leading zeros eliminated, thus the size of 32 for
574 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
575 numeric_limits<long long>::digits10 + 1, __base);
577 // Stage 2: convert and store results.
580 long long __ll = strtoll(__xtrc, &__sanity, __base);
581 if (!(__err & ios_base::failbit)
582 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
585 __err |= ios_base::failbit;
589 template<typename _CharT, typename _InIter>
591 num_get<_CharT, _InIter>::
592 do_get(iter_type __beg, iter_type __end, ios_base& __io,
593 ios_base::iostate& __err, unsigned long long& __v) const
595 // Stage 1: extract and determine the conversion specifier.
596 // Assuming leading zeros eliminated, thus the size of 32 for
600 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
601 numeric_limits<unsigned long long>::digits10 + 1,
604 // Stage 2: convert and store results.
607 unsigned long long __ull = strtoull(__xtrc, &__sanity, __base);
608 if (!(__err & ios_base::failbit)
609 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
612 __err |= ios_base::failbit;
617 template<typename _CharT, typename _InIter>
619 num_get<_CharT, _InIter>::
620 do_get(iter_type __beg, iter_type __end, ios_base& __io,
621 ios_base::iostate& __err, float& __v) const
623 // Stage 1: extract and determine the conversion specifier.
626 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
628 // Stage 2: convert and store results.
631 #ifdef _GLIBCPP_USE_C99
632 float __f = strtof(__xtrc.c_str(), &__sanity);
634 float __f = static_cast<float>(strtod(__xtrc.c_str(), &__sanity));
636 if (!(__err & ios_base::failbit)
637 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
640 __err |= ios_base::failbit;
644 template<typename _CharT, typename _InIter>
646 num_get<_CharT, _InIter>::
647 do_get(iter_type __beg, iter_type __end, ios_base& __io,
648 ios_base::iostate& __err, double& __v) const
650 // Stage 1: extract and determine the conversion specifier.
653 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
655 // Stage 2: convert and store results.
658 double __d = strtod(__xtrc.c_str(), &__sanity);
659 if (!(__err & ios_base::failbit)
660 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
663 __err |= ios_base::failbit;
667 template<typename _CharT, typename _InIter>
669 num_get<_CharT, _InIter>::
670 do_get(iter_type __beg, iter_type __end, ios_base& __io,
671 ios_base::iostate& __err, long double& __v) const
673 // Stage 1: extract and determine the conversion specifier.
676 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
678 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
679 // Stage 2: convert and store results.
682 long double __ld = strtold(__xtrc.c_str(), &__sanity);
683 if (!(__err & ios_base::failbit)
684 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
687 // Stage 2: determine a conversion specifier.
688 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
690 if (__basefield == ios_base::oct)
692 else if (__basefield == ios_base::hex)
694 else if (__basefield == 0)
699 // Stage 3: store results.
700 typedef typename char_traits<_CharT>::int_type int_type;
702 int __p = sscanf(__xtrc.c_str(), __conv, &__ld);
703 if (!(__err & ios_base::failbit) && __p
704 && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
708 __err |= ios_base::failbit;
712 template<typename _CharT, typename _InIter>
714 num_get<_CharT, _InIter>::
715 do_get(iter_type __beg, iter_type __end, ios_base& __io,
716 ios_base::iostate& __err, void*& __v) const
718 // Prepare for hex formatted input
719 typedef ios_base::fmtflags fmtflags;
720 fmtflags __fmt = __io.flags();
721 fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
722 | ios_base::uppercase | ios_base::internal);
723 __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
725 // Stage 1: extract and determine the conversion specifier.
726 // Assuming leading zeros eliminated, thus the size of 32 for
730 __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
731 numeric_limits<unsigned long>::digits10 + 1,
734 // Stage 2: convert and store results.
737 void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base));
738 if (!(__err & ios_base::failbit)
739 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
742 __err |= ios_base::failbit;
744 // Reset from hex formatted input
750 // The following code uses sprintf() to convert floating point
751 // values for insertion into a stream. An optimization would be to
752 // replace sprintf() with code that works directly on a wide buffer
753 // and then use __pad to do the padding. It would be good
754 // to replace sprintf() anyway to avoid accidental buffer overruns
755 // and to gain back the efficiency that C++ provides by knowing up
756 // front the type of the values to insert. This implementation
757 // follows the C++ standard fairly directly as outlined in 22.2.2.2
758 // [lib.locale.num.put]
759 template<typename _CharT, typename _OutIter>
760 template<typename _ValueT>
762 num_put<_CharT, _OutIter>::
763 _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
766 const int __max_digits = numeric_limits<_ValueT>::digits10;
767 streamsize __prec = __io.precision();
768 // Protect against sprintf() buffer overflows.
769 if (__prec > static_cast<streamsize>(__max_digits))
770 __prec = static_cast<streamsize>(__max_digits);
772 // Long enough for the max format spec.
775 // Consider the possibility of long ios_base::fixed outputs
776 const bool __fixed = __io.flags() & ios_base::fixed;
777 const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
778 // ios_base::fixed outputs may need up to __max_exp+1 chars
779 // for the integer part + up to __max_digits chars for the
780 // fractional part + 3 chars for sign, decimal point, '\0'. On
781 // the other hand, for non-fixed outputs __max_digits*3 chars
782 // are largely sufficient.
783 const int __cs_size = __fixed ? __max_exp + __max_digits + 4
785 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
788 // [22.2.2.2.2] Stage 1, numeric conversion to character.
789 if (_S_format_float(__io, __fbuf, __mod, __prec))
790 __len = sprintf(__cs, __fbuf, __prec, __v);
792 __len = sprintf(__cs, __fbuf, __v);
793 return _M_widen_float(__s, __io, __fill, __cs, __len);
796 template<typename _CharT, typename _OutIter>
797 template<typename _ValueT>
799 num_put<_CharT, _OutIter>::
800 _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
801 char __modl, _ValueT __v) const
803 // [22.2.2.2.2] Stage 1, numeric conversion to character.
804 // Leave room for "+/-," "0x," and commas. This size is
805 // arbitrary, but should work.
807 // Long enough for the max format spec.
809 _S_format_int(__io, __fbuf, __mod, __modl);
810 int __len = sprintf(__cs, __fbuf, __v);
811 return _M_widen_int(__s, __io, __fill, __cs, __len);
814 template<typename _CharT, typename _OutIter>
816 num_put<_CharT, _OutIter>::
817 _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
820 // [22.2.2.2.2] Stage 2, convert to char_type, using correct
821 // numpunct.decimal_point() values for '.' and adding grouping.
822 const locale __loc = __io.getloc();
823 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
824 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
826 // Grouping can add (almost) as many separators as the number of
827 // digits, but no more.
828 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
830 __ctype.widen(__cs, __cs + __len, __ws);
832 // Replace decimal point.
834 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
835 if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
836 __ws[__p - __ws] = __np.decimal_point();
838 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
839 //282. What types does numpunct grouping refer to?
840 // Add grouping, if necessary.
841 const string __grouping = __np.grouping();
842 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
843 if (__grouping.size())
846 int __declen = __p ? __p - __ws : __len;
847 __p2 = __add_grouping(__ws2, __np.thousands_sep(),
849 __grouping.c_str() + __grouping.size(),
850 __ws, __ws + __declen);
851 int __newlen = __p2 - __ws2;
853 // Tack on decimal part.
856 char_traits<_CharT>::copy(__p2, __p, __len - __declen);
857 __newlen += __len - __declen;
860 // Switch strings, establish correct new length.
865 return _M_insert(__s, __io, __fill, __ws, __len);
868 template<typename _CharT, typename _OutIter>
870 num_put<_CharT, _OutIter>::
871 _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
874 // [22.2.2.2.2] Stage 2, convert to char_type, using correct
875 // numpunct.decimal_point() values for '.' and adding grouping.
876 const locale __loc = __io.getloc();
877 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
878 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
880 // Grouping can add (almost) as many separators as the number of
881 // digits, but no more.
882 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
884 __ctype.widen(__cs, __cs + __len, __ws);
886 // Add grouping, if necessary.
887 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
888 const string __grouping = __np.grouping();
889 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
890 bool __dec = __basefield != ios_base::oct
891 && __basefield != ios_base::hex;
892 if (__grouping.size() && __dec)
895 __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
896 __grouping.c_str() + __grouping.size(),
902 return _M_insert(__s, __io, __fill, __ws, __len);
905 // For use by integer and floating-point types after they have been
906 // converted into a char_type string.
907 template<typename _CharT, typename _OutIter>
909 num_put<_CharT, _OutIter>::
910 _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
913 // [22.2.2.2.2] Stage 3.
914 streamsize __w = __io.width();
915 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
917 if (__w > static_cast<streamsize>(__len))
919 __pad(__io, __fill, __ws2, __ws, __w, __len, true);
920 __len = static_cast<int>(__w);
926 // [22.2.2.2.2] Stage 4.
927 // Write resulting, fully-formatted string to output iterator.
928 for (int __j = 0; __j < __len; ++__j, ++__s)
933 template<typename _CharT, typename _OutIter>
935 num_put<_CharT, _OutIter>::
936 do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
938 ios_base::fmtflags __flags = __io.flags();
939 if ((__flags & ios_base::boolalpha) == 0)
941 unsigned long __uv = __v;
942 _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
946 locale __loc = __io.getloc();
947 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
948 const char_type* __ws;
952 __ws = __np.truename().c_str();
953 __len = __np.truename().size();
957 __ws = __np.falsename().c_str();
958 __len = __np.falsename().size();
960 _M_insert(__s, __io, __fill, __ws, __len);
965 template<typename _CharT, typename _OutIter>
967 num_put<_CharT, _OutIter>::
968 do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
969 { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
971 template<typename _CharT, typename _OutIter>
973 num_put<_CharT, _OutIter>::
974 do_put(iter_type __s, ios_base& __io, char_type __fill,
975 unsigned long __v) const
976 { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
978 #ifdef _GLIBCPP_USE_LONG_LONG
979 template<typename _CharT, typename _OutIter>
981 num_put<_CharT, _OutIter>::
982 do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
983 { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
985 template<typename _CharT, typename _OutIter>
987 num_put<_CharT, _OutIter>::
988 do_put(iter_type __s, ios_base& __io, char_type __fill,
989 unsigned long long __v) const
990 { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
993 template<typename _CharT, typename _OutIter>
995 num_put<_CharT, _OutIter>::
996 do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
997 { return _M_convert_float(__s, __io, __fill, char_type(), __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 long double __v) const
1004 { return _M_convert_float(__s, __io, __fill, 'L', __v); }
1006 template<typename _CharT, typename _OutIter>
1008 num_put<_CharT, _OutIter>::
1009 do_put(iter_type __s, ios_base& __io, char_type __fill,
1010 const void* __v) const
1012 ios_base::fmtflags __flags = __io.flags();
1013 ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
1014 | ios_base::uppercase | ios_base::internal);
1015 __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
1018 _M_convert_int(__s, __io, __fill, 'u', char_type(),
1019 reinterpret_cast<unsigned long>(__v));
1020 __io.flags(__flags);
1024 __io.flags(__flags);
1025 __throw_exception_again;
1031 template<typename _CharT, typename _InIter>
1033 money_get<_CharT, _InIter>::
1034 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1035 ios_base::iostate& __err, long double& __units) const
1038 __beg = this->do_get(__beg, __end, __intl, __io, __err, __str);
1040 const int __n = numeric_limits<long double>::digits10;
1041 char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1042 const locale __loc = __io.getloc();
1043 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1044 const _CharT* __wcs = __str.c_str();
1045 __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);
1047 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
1050 long double __ld = strtold(__cs, &__sanity);
1051 if (!(__err & ios_base::failbit)
1052 && __sanity != __cs && *__sanity == '\0' && errno == 0)
1055 typedef typename char_traits<_CharT>::int_type int_type;
1057 int __p = sscanf(__cs, "%Lf", &__ld);
1058 if (!(__err & ios_base::failbit)
1059 && __p && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
1065 template<typename _CharT, typename _InIter>
1067 money_get<_CharT, _InIter>::
1068 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1069 ios_base::iostate& __err, string_type& __units) const
1071 // These contortions are quite unfortunate.
1072 typedef moneypunct<_CharT, true> __money_true;
1073 typedef moneypunct<_CharT, false> __money_false;
1074 typedef money_base::part part;
1075 typedef typename string_type::size_type size_type;
1077 const locale __loc = __io.getloc();
1078 const __money_true& __mpt = use_facet<__money_true>(__loc);
1079 const __money_false& __mpf = use_facet<__money_false>(__loc);
1080 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1082 const money_base::pattern __p = __intl ? __mpt.neg_format()
1083 : __mpf.neg_format();
1085 const string_type __pos_sign =__intl ? __mpt.positive_sign()
1086 : __mpf.positive_sign();
1087 const string_type __neg_sign =__intl ? __mpt.negative_sign()
1088 : __mpf.negative_sign();
1089 const char_type __d = __intl ? __mpt.decimal_point()
1090 : __mpf.decimal_point();
1091 const char_type __sep = __intl ? __mpt.thousands_sep()
1092 : __mpf.thousands_sep();
1094 const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
1096 // Set to deduced positive or negative sign, depending.
1098 // String of grouping info from thousands_sep plucked from __units.
1099 string __grouping_tmp;
1100 // Marker for thousands_sep position.
1102 // If input iterator is in a valid state.
1103 bool __testvalid = true;
1104 // Flag marking when a decimal point is found.
1105 bool __testdecfound = false;
1107 char_type __c = *__beg;
1108 char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
1109 for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
1111 part __which = static_cast<part>(__p.field[__i]);
1114 case money_base::symbol:
1115 if (__io.flags() & ios_base::showbase)
1117 // Symbol is required.
1118 const string_type __symbol = __intl ? __mpt.curr_symbol()
1119 : __mpf.curr_symbol();
1120 size_type __len = __symbol.size();
1122 while (__beg != __end
1123 && __i < __len && __symbol[__i] == __c)
1129 __testvalid = false;
1132 case money_base::sign:
1133 // Sign might not exist, or be more than one character long.
1134 if (__pos_sign.size() && __neg_sign.size())
1136 // Sign is mandatory.
1137 if (__c == __pos_sign[0])
1139 __sign = __pos_sign;
1142 else if (__c == __neg_sign[0])
1144 __sign = __neg_sign;
1148 __testvalid = false;
1150 else if (__pos_sign.size() && __c == __pos_sign[0])
1152 __sign = __pos_sign;
1155 else if (__neg_sign.size() && __c == __neg_sign[0])
1157 __sign = __neg_sign;
1161 case money_base::value:
1162 // Extract digits, remove and stash away the
1163 // grouping of found thousands separators.
1164 while (__beg != __end
1165 && (__ctype.is(ctype_base::digit, __c)
1166 || (__c == __d && !__testdecfound)
1171 __grouping_tmp += static_cast<char>(__sep_pos);
1173 __testdecfound = true;
1175 else if (__c == __sep)
1177 if (__grouping.size())
1179 // Mark position for later analysis.
1180 __grouping_tmp += static_cast<char>(__sep_pos);
1185 __testvalid = false;
1197 case money_base::space:
1198 case money_base::none:
1199 // Only if not at the end of the pattern.
1201 while (__beg != __end
1202 && __ctype.is(ctype_base::space, __c))
1208 // Need to get the rest of the sign characters, if they exist.
1209 if (__sign.size() > 1)
1211 size_type __len = __sign.size();
1213 for (; __c != __eof && __i < __len; ++__i)
1214 while (__beg != __end && __c != __sign[__i])
1218 __testvalid = false;
1221 // Strip leading zeros.
1222 while (__units[0] == __ctype.widen('0'))
1223 __units.erase(__units.begin());
1225 if (__sign.size() && __sign == __neg_sign)
1226 __units.insert(__units.begin(), __ctype.widen('-'));
1228 // Test for grouping fidelity.
1229 if (__grouping.size() && __grouping_tmp.size())
1231 if (!__verify_grouping(__grouping, __grouping_tmp))
1232 __testvalid = false;
1235 // Iff no more characters are available.
1237 __err |= ios_base::eofbit;
1239 // Iff valid sequence is not recognized.
1240 if (!__testvalid || !__units.size())
1241 __err |= ios_base::failbit;
1245 template<typename _CharT, typename _OutIter>
1247 money_put<_CharT, _OutIter>::
1248 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1249 long double __units) const
1251 const locale __loc = __io.getloc();
1252 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1253 const int __n = numeric_limits<long double>::digits10;
1254 char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1255 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1256 int __len = sprintf(__cs, "%.01Lf", __units);
1257 __ctype.widen(__cs, __cs + __len, __ws);
1258 string_type __digits(__ws);
1259 return this->do_put(__s, __intl, __io, __fill, __digits);
1262 template<typename _CharT, typename _OutIter>
1264 money_put<_CharT, _OutIter>::
1265 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1266 const string_type& __digits) const
1268 typedef typename string_type::size_type size_type;
1269 typedef money_base::part part;
1271 const locale __loc = __io.getloc();
1272 const size_type __width = static_cast<size_type>(__io.width());
1274 // These contortions are quite unfortunate.
1275 typedef moneypunct<_CharT, true> __money_true;
1276 typedef moneypunct<_CharT, false> __money_false;
1277 const __money_true& __mpt = use_facet<__money_true>(__loc);
1278 const __money_false& __mpf = use_facet<__money_false>(__loc);
1279 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1281 // Determine if negative or positive formats are to be used, and
1282 // discard leading negative_sign if it is present.
1283 const char_type* __beg = __digits.data();
1284 const char_type* __end = __beg + __digits.size();
1285 money_base::pattern __p;
1287 if (*__beg != __ctype.widen('-'))
1289 __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
1290 __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
1294 __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
1295 __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
1299 // Look for valid numbers in the current ctype facet within input digits.
1300 __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
1303 // Assume valid input, and attempt to format.
1304 // Break down input numbers into base components, as follows:
1305 // final_value = grouped units + (decimal point) + (digits)
1307 string_type __value;
1308 const string_type __symbol = __intl ? __mpt.curr_symbol()
1309 : __mpf.curr_symbol();
1311 // Deal with decimal point, decimal digits.
1312 const int __frac = __intl ? __mpt.frac_digits()
1313 : __mpf.frac_digits();
1316 const char_type __d = __intl ? __mpt.decimal_point()
1317 : __mpf.decimal_point();
1318 if (__end - __beg >= __frac)
1320 __value = string_type(__end - __frac, __end);
1321 __value.insert(__value.begin(), __d);
1326 // Have to pad zeros in the decimal position.
1327 __value = string_type(__beg, __end);
1328 int __paddec = __frac - (__end - __beg);
1329 char_type __zero = __ctype.widen('0');
1330 __value.insert(__value.begin(), __paddec, __zero);
1331 __value.insert(__value.begin(), __d);
1336 // Add thousands separators to non-decimal digits, per
1340 const string __grouping = __intl ? __mpt.grouping()
1342 if (__grouping.size())
1344 const char_type __sep = __intl ? __mpt.thousands_sep()
1345 : __mpf.thousands_sep();
1346 const char* __gbeg = __grouping.c_str();
1347 const char* __gend = __gbeg + __grouping.size();
1348 const int __n = numeric_limits<long double>::digits10 * 2;
1349 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1350 _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
1351 __gend, __beg, __end);
1352 __value.insert(0, __ws2, __ws_end - __ws2);
1355 __value.insert(0, string_type(__beg, __end));
1358 // Calculate length of resulting string.
1359 ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
1360 size_type __len = __value.size() + __sign.size();
1361 __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
1362 bool __testipad = __f == ios_base::internal && __len < __width;
1364 // Fit formatted digits into the required pattern.
1365 for (int __i = 0; __i < 4; ++__i)
1367 part __which = static_cast<part>(__p.field[__i]);
1370 case money_base::symbol:
1371 if (__io.flags() & ios_base::showbase)
1374 case money_base::sign:
1375 // Sign might not exist, or be more than one
1376 // charater long. In that case, add in the rest
1381 case money_base::value:
1384 case money_base::space:
1385 // At least one space is required, but if internal
1386 // formatting is required, an arbitrary number of
1387 // fill spaces will be necessary.
1389 __res += string_type(__width - __len, __fill);
1391 __res += __ctype.widen(' ');
1393 case money_base::none:
1395 __res += string_type(__width - __len, __fill);
1400 // Special case of multi-part sign parts.
1401 if (__sign.size() > 1)
1402 __res += string_type(__sign.begin() + 1, __sign.end());
1404 // Pad, if still necessary.
1405 __len = __res.size();
1406 if (__width > __len)
1408 if (__f == ios_base::left)
1410 __res.append(__width - __len, __fill);
1413 __res.insert(0, string_type(__width - __len, __fill));
1417 // Write resulting, fully-formatted string to output iterator.
1418 for (size_type __j = 0; __j < __len; ++__j)
1426 // NB: Not especially useful. Without an ios_base object or some
1427 // kind of locale reference, we are left clawing at the air where
1428 // the side of the mountain used to be...
1429 template<typename _CharT, typename _InIter>
1430 time_base::dateorder
1431 time_get<_CharT, _InIter>::do_date_order() const
1432 { return time_base::no_order; }
1434 template<typename _CharT, typename _InIter>
1436 time_get<_CharT, _InIter>::
1437 _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
1438 ios_base::iostate& __err, tm* __tm,
1439 const _CharT* __format) const
1441 locale __loc = __io.getloc();
1442 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1443 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1444 size_t __len = char_traits<_CharT>::length(__format);
1446 for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
1448 char __c = __format[__i];
1451 // Verify valid formatting code, attempt to extract.
1452 __c = __format[++__i];
1455 if (__c == 'E' || __c == 'O')
1458 __c = __format[++__i];
1465 // Abbreviated weekday name [tm_wday]
1466 const char_type* __days1[7];
1467 __tp._M_days_abbreviated(__days1);
1468 _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
1472 // Weekday name [tm_wday].
1473 const char_type* __days2[7];
1474 __tp._M_days(__days2);
1475 _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
1480 // Abbreviated month name [tm_mon]
1481 const char_type* __months1[12];
1482 __tp._M_months_abbreviated(__months1);
1483 _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
1487 // Month name [tm_mon].
1488 const char_type* __months2[12];
1489 __tp._M_months(__months2);
1490 _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
1494 // Default time and date representation.
1495 const char_type* __dt[2];
1496 __tp._M_date_time_formats(__dt);
1497 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1501 // Day [01, 31]. [tm_mday]
1502 _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
1506 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1508 __ctype.widen(__cs, __cs + 9, __wcs);
1509 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1513 // Hour [00, 23]. [tm_hour]
1514 _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1518 // Hour [01, 12]. [tm_hour]
1519 _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
1523 // Month [01, 12]. [tm_mon]
1524 _M_extract_num(__beg, __end, __mem, 1, 12, 2,
1527 __tm->tm_mon = __mem - 1;
1530 // Minute [00, 59]. [tm_min]
1531 _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1535 if (__ctype.narrow(*__beg, 0) == '\n')
1538 __err |= ios_base::failbit;
1541 // Equivalent to (%H:%M).
1543 __ctype.widen(__cs, __cs + 6, __wcs);
1544 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1549 _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
1553 if (__ctype.narrow(*__beg, 0) == '\t')
1556 __err |= ios_base::failbit;
1559 // Equivalent to (%H:%M:%S).
1561 __ctype.widen(__cs, __cs + 9, __wcs);
1562 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1567 const char_type* __dates[2];
1568 __tp._M_date_formats(__dates);
1569 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1574 const char_type* __times[2];
1575 __tp._M_time_formats(__times);
1576 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1580 // Two digit year. [tm_year]
1581 _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
1585 // Year [1900). [tm_year]
1586 _M_extract_num(__beg, __end, __mem, 0,
1587 numeric_limits<int>::max(), 4,
1590 __tm->tm_year = __mem - 1900;
1594 if (__ctype.is(ctype_base::upper, *__beg))
1597 _M_extract_name(__beg, __end, __tmp,
1598 __timepunct<_CharT>::_S_timezones,
1601 // GMT requires special effort.
1602 char_type __c = *__beg;
1603 if (!__err && __tmp == 0
1604 && (__c == __ctype.widen('-')
1605 || __c == __ctype.widen('+')))
1607 _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1609 _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1614 __err |= ios_base::failbit;
1618 __err |= ios_base::failbit;
1623 // Verify format and input match, extract and discard.
1624 if (__c == __ctype.narrow(*__beg, 0))
1627 __err |= ios_base::failbit;
1632 template<typename _CharT, typename _InIter>
1634 time_get<_CharT, _InIter>::
1635 _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
1636 int __min, int __max, size_t __len,
1637 const ctype<_CharT>& __ctype,
1638 ios_base::iostate& __err) const
1642 bool __testvalid = true;
1643 char_type __c = *__beg;
1644 while (__beg != __end && __i < __len
1645 && __ctype.is(ctype_base::digit, __c))
1647 __digits += __ctype.narrow(__c, 0);
1653 int __value = atoi(__digits.c_str());
1654 if (__min <= __value && __value <= __max)
1657 __testvalid = false;
1660 __testvalid = false;
1662 __err |= ios_base::failbit;
1666 // All elements in __names are unique.
1667 template<typename _CharT, typename _InIter>
1669 time_get<_CharT, _InIter>::
1670 _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
1671 const _CharT** __names, size_t __indexlen,
1672 ios_base::iostate& __err) const
1674 typedef char_traits<char_type> __traits_type;
1675 int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
1676 size_t __nmatches = 0;
1678 bool __testvalid = true;
1679 const char_type* __name;
1681 char_type __c = *__beg;
1682 // Look for initial matches.
1683 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
1684 if (__c == __names[__i1][0])
1685 __matches[__nmatches++] = __i1;
1687 while(__nmatches > 1)
1689 // Find smallest matching string.
1690 size_t __minlen = 10;
1691 for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
1692 __minlen = min(__minlen,
1693 __traits_type::length(__names[__matches[__i2]]));
1695 if (__pos < __minlen && __beg != __end)
1699 for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
1701 __name = __names[__matches[__i3]];
1702 if (__name[__pos] != __c)
1703 __matches[__i3] = __matches[--__nmatches];
1710 if (__nmatches == 1)
1712 // Make sure found name is completely extracted.
1713 __name = __names[__matches[0]];
1714 const size_t __len = __traits_type::length(__name);
1715 while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
1719 __member = __matches[0];
1721 __testvalid = false;
1724 __testvalid = false;
1726 __err |= ios_base::failbit;
1729 template<typename _CharT, typename _InIter>
1731 time_get<_CharT, _InIter>::
1732 do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1733 ios_base::iostate& __err, tm* __tm) const
1736 const char* __cs = "%X";
1737 locale __loc = __io.getloc();
1738 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1739 __ctype.widen(__cs, __cs + 3, __wcs);
1740 _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1742 __err |= ios_base::eofbit;
1746 template<typename _CharT, typename _InIter>
1748 time_get<_CharT, _InIter>::
1749 do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1750 ios_base::iostate& __err, tm* __tm) const
1753 const char* __cs = "%x";
1754 locale __loc = __io.getloc();
1755 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1756 __ctype.widen(__cs, __cs + 3, __wcs);
1757 _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1759 __err |= ios_base::eofbit;
1763 template<typename _CharT, typename _InIter>
1765 time_get<_CharT, _InIter>::
1766 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
1767 ios_base::iostate& __err, tm* __tm) const
1769 typedef char_traits<char_type> __traits_type;
1770 locale __loc = __io.getloc();
1771 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1772 const char_type* __days[7];
1773 __tp._M_days_abbreviated(__days);
1775 _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
1777 // Check to see if non-abbreviated name exists, and extract.
1778 // NB: Assumes both _M_days and _M_days_abbreviated organized in
1779 // exact same order, first to last, such that the resulting
1780 // __days array with the same index points to a day, and that
1781 // day's abbreviated form.
1782 // NB: Also assumes that an abbreviated name is a subset of the name.
1785 size_t __pos = __traits_type::length(__days[__tmpwday]);
1786 __tp._M_days(__days);
1787 const char_type* __name = __days[__tmpwday];
1788 if (__name[__pos] == *__beg)
1790 // Extract the rest of it.
1791 const size_t __len = __traits_type::length(__name);
1792 while (__pos < __len && __beg != __end
1793 && __name[__pos] == *__beg)
1796 __err |= ios_base::failbit;
1799 __tm->tm_wday = __tmpwday;
1802 __err |= ios_base::eofbit;
1806 template<typename _CharT, typename _InIter>
1808 time_get<_CharT, _InIter>::
1809 do_get_monthname(iter_type __beg, iter_type __end,
1810 ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1812 typedef char_traits<char_type> __traits_type;
1813 locale __loc = __io.getloc();
1814 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1815 const char_type* __months[12];
1816 __tp._M_months_abbreviated(__months);
1818 _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
1820 // Check to see if non-abbreviated name exists, and extract.
1821 // NB: Assumes both _M_months and _M_months_abbreviated organized in
1822 // exact same order, first to last, such that the resulting
1823 // __months array with the same index points to a month, and that
1824 // month's abbreviated form.
1825 // NB: Also assumes that an abbreviated name is a subset of the name.
1828 size_t __pos = __traits_type::length(__months[__tmpmon]);
1829 __tp._M_months(__months);
1830 const char_type* __name = __months[__tmpmon];
1831 if (__name[__pos] == *__beg)
1833 // Extract the rest of it.
1834 const size_t __len = __traits_type::length(__name);
1835 while (__pos < __len && __beg != __end
1836 && __name[__pos] == *__beg)
1839 __err |= ios_base::failbit;
1842 __tm->tm_mon = __tmpmon;
1846 __err |= ios_base::eofbit;
1850 template<typename _CharT, typename _InIter>
1852 time_get<_CharT, _InIter>::
1853 do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
1854 ios_base::iostate& __err, tm* __tm) const
1856 locale __loc = __io.getloc();
1857 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1859 char_type __c = *__beg;
1862 while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
1864 __digits += __ctype.narrow(__c, 0);
1868 if (__i == 2 || __i == 4)
1870 int __year = atoi(__digits.c_str());
1871 __year = __i == 2 ? __year : __year - 1900;
1872 __tm->tm_year = __year;
1875 __err |= ios_base::failbit;
1877 __err |= ios_base::eofbit;
1881 template<typename _CharT, typename _OutIter>
1883 time_put<_CharT, _OutIter>::
1884 put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1885 const _CharT* __beg, const _CharT* __end) const
1887 locale __loc = __io.getloc();
1888 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1889 while (__beg != __end)
1891 char __c = __ctype.narrow(*__beg, 0);
1898 __c = __ctype.narrow(*__beg, 0);
1900 if (__c == 'E' || __c == 'O')
1903 __format = __ctype.narrow(*__beg, 0);
1908 this->do_put(__s, __io, char_type(), __tm, __format, __mod);
1916 template<typename _CharT, typename _OutIter>
1918 time_put<_CharT, _OutIter>::
1919 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1920 char __format, char __mod) const
1922 locale __loc = __io.getloc();
1923 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1924 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1926 // NB: This size is arbitrary. Should this be a data member,
1927 // initialized at construction?
1928 const size_t __maxlen = 64;
1929 char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen));
1931 // NB: In IEE 1003.1-200x, and perhaps other locale models, it
1932 // is possible that the format character will be longer than one
1933 // character. Possibilities include 'E' or 'O' followed by a
1934 // format character: if __mod is not the default argument, assume
1935 // it's a valid modifier.
1937 __fmt[0] = __ctype.widen('%');
1940 __fmt[1] = __format;
1941 __fmt[2] = char_type();
1946 __fmt[2] = __format;
1947 __fmt[3] = char_type();
1950 __tp._M_put_helper(__res, __maxlen, __fmt, __tm);
1952 // Write resulting, fully-formatted string to output iterator.
1953 size_t __len = char_traits<char_type>::length(__res);
1954 for (size_t __i = 0; __i < __len; ++__i)
1960 // Generic version does nothing.
1961 template<typename _CharT>
1963 collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const
1966 // Generic version does nothing.
1967 template<typename _CharT>
1969 collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const
1972 template<typename _CharT>
1975 do_compare(const _CharT* __lo1, const _CharT* __hi1,
1976 const _CharT* __lo2, const _CharT* __hi2) const
1978 const string_type __one(__lo1, __hi1);
1979 const string_type __two(__lo2, __hi2);
1980 return _M_compare_helper(__one.c_str(), __two.c_str());
1983 template<typename _CharT>
1984 typename collate<_CharT>::string_type
1986 do_transform(const _CharT* __lo, const _CharT* __hi) const
1988 size_t __len = __hi - __lo;
1989 _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
1990 size_t __res = _M_transform_helper(__c, __lo, __len);
1993 // Try to increment size of translated string.
1994 size_t __len2 = __len * 2;
1995 _CharT* __c2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len2));
1996 __res = _M_transform_helper(__c2, __lo, __len);
1997 // XXX Throw exception if still indeterminate?
1999 return string_type(__c);
2002 template<typename _CharT>
2005 do_hash(const _CharT* __lo, const _CharT* __hi) const
2007 unsigned long __val = 0;
2008 for (; __lo < __hi; ++__lo)
2009 __val = *__lo + ((__val << 7) |
2010 (__val >> (numeric_limits<unsigned long>::digits - 1)));
2011 return static_cast<long>(__val);
2014 // Construct correctly padded string, as per 22.2.2.2.2
2016 // __newlen > __oldlen
2017 // __news is allocated for __newlen size
2018 // Used by both num_put and ostream inserters: if __num,
2019 // internal-adjusted objects are padded according to the rules below
2020 // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
2022 template<typename _CharT, typename _Traits>
2024 __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
2025 const streamsize __newlen, const streamsize __oldlen,
2028 typedef _CharT char_type;
2029 typedef _Traits traits_type;
2030 typedef typename traits_type::int_type int_type;
2032 int_type __plen = static_cast<size_t>(__newlen - __oldlen);
2033 char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
2034 traits_type::assign(__pads, __plen, __fill);
2039 size_t __beglen; //either __plen or __oldlen
2040 ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
2042 if (__adjust == ios_base::left)
2045 __beg = const_cast<char_type*>(__olds);
2046 __beglen = __oldlen;
2049 else if (__adjust == ios_base::internal && __num)
2051 // Pad after the sign, if there is one.
2052 // Pad after 0[xX], if there is one.
2053 // Who came up with these rules, anyway? Jeeze.
2054 locale __loc = __io.getloc();
2055 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2056 const char_type __minus = __ctype.widen('-');
2057 const char_type __plus = __ctype.widen('+');
2058 bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
2059 bool __testhex = __ctype.widen('0') == __olds[0]
2060 && (__ctype.widen('x') == __olds[1]
2061 || __ctype.widen('X') == __olds[1]);
2064 __news[0] = __olds[0];
2065 __news[1] = __olds[1];
2070 __end = const_cast<char_type*>(__olds + __mod);
2072 else if (__testsign)
2074 __news[0] = __olds[0] == __plus ? __plus : __minus;
2079 __end = const_cast<char_type*>(__olds + __mod);
2086 __end = const_cast<char_type*>(__olds);
2094 __end = const_cast<char_type*>(__olds);
2096 traits_type::copy(__news, __beg, __beglen);
2097 traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
2100 // NB: Can't have default argument on non-member template, and
2101 // num_put doesn't have a _Traits template parameter, so this
2102 // forwarding template adds in the default template argument.
2103 template<typename _CharT>
2105 __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
2106 const streamsize __newlen, const streamsize __oldlen,
2109 return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, __olds,
2110 __newlen, __oldlen, __num);
2113 // Used by both numeric and monetary facets.
2114 // Check to make sure that the __grouping_tmp string constructed in
2115 // money_get or num_get matches the canonical grouping for a given
2117 // __grouping_tmp is parsed L to R
2118 // 1,222,444 == __grouping_tmp of "/1/3/3"
2119 // __grouping is parsed R to L
2120 // 1,222,444 == __grouping of "/3" == "/3/3/3"
2121 template<typename _CharT>
2123 __verify_grouping(const basic_string<_CharT>& __grouping,
2124 basic_string<_CharT>& __grouping_tmp)
2128 const int __len = __grouping.size();
2129 const int __n = __grouping_tmp.size();
2132 // Parsed number groupings have to match the
2133 // numpunct::grouping string exactly, starting at the
2134 // right-most point of the parsed sequence of elements ...
2135 while (__test && __i < __n - 1)
2136 for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
2137 __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
2138 // ... but the last parsed grouping can be <= numpunct
2140 __j == __len ? __j = 0 : __j;
2141 __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
2145 // Used by both numeric and monetary facets.
2146 // Inserts "group separator" characters into an array of characters.
2147 // It's recursive, one iteration per group. It moves the characters
2148 // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
2149 // only with __gbeg != __gend.
2150 template<typename _CharT>
2152 __add_grouping(_CharT* __s, _CharT __sep,
2153 const char* __gbeg, const char* __gend,
2154 const _CharT* __first, const _CharT* __last)
2156 if (__last - __first > *__gbeg)
2158 __s = __add_grouping(__s, __sep,
2159 (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
2160 __gend, __first, __last - *__gbeg);
2161 __first = __last - *__gbeg;
2165 *__s++ = *__first++;
2166 while (__first != __last);