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
35 #include <bits/std_cerrno.h>
36 #include <bits/std_clocale.h> // For localeconv
37 #include <bits/std_cstdlib.h> // For strof, strtold
38 #include <bits/std_cmath.h> // For ceil
39 #include <bits/std_limits.h> // For numeric_limits
40 #include <bits/std_memory.h> // For auto_ptr
41 #include <bits/streambuf_iterator.h> // For streambuf_iterators
42 #include <bits/std_cctype.h> // For isspace
43 #include <typeinfo> // For bad_cast
44 #include <bits/std_vector.h>
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 _M_extract_int(__beg, __end, __io, __err, __xtrc,
394 numeric_limits<bool>::digits10, __base);
396 // Stage 2: convert and store results.
399 long __l = strtol(__xtrc, &__sanity, __base);
400 if (!(__err & ios_base::failbit)
402 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
405 __err |= ios_base::failbit;
408 // Parse bool values as alphanumeric
411 locale __loc = __io.getloc();
412 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__loc);
413 const char_type* __true = __np.truename().c_str();
414 const char_type* __false = __np.falsename().c_str();
416 const size_t __truen = __np.truename().size() - 1;
417 const size_t __falsen = __np.falsename().size() - 1;
419 for (size_t __n = 0; __beg != __end; ++__n)
421 char_type __c = *__beg++;
422 bool __testf = __n <= __falsen ? __c == __false[__n] : false;
423 bool __testt = __n <= __truen ? __c == __true[__n] : false;
424 if (!(__testf || __testt))
426 __err |= ios_base::failbit;
429 else if (__testf && __n == __falsen)
434 else if (__testt && __n == __truen)
441 __err |= ios_base::eofbit;
447 template<typename _CharT, typename _InIter>
449 num_get<_CharT, _InIter>::
450 do_get(iter_type __beg, iter_type __end, ios_base& __io,
451 ios_base::iostate& __err, long& __v) const
453 // Stage 1: extract and determine the conversion specifier.
454 // Assuming leading zeros eliminated, thus the size of 32 for
458 _M_extract_int(__beg, __end, __io, __err, __xtrc,
459 numeric_limits<long>::digits10, __base);
461 // Stage 2: convert and store results.
464 long __l = strtol(__xtrc, &__sanity, __base);
465 if (!(__err & ios_base::failbit)
466 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
469 __err |= ios_base::failbit;
473 template<typename _CharT, typename _InIter>
475 num_get<_CharT, _InIter>::
476 do_get(iter_type __beg, iter_type __end, ios_base& __io,
477 ios_base::iostate& __err, unsigned short& __v) const
479 // Stage 1: extract and determine the conversion specifier.
480 // Assuming leading zeros eliminated, thus the size of 32 for
484 _M_extract_int(__beg, __end, __io, __err, __xtrc,
485 numeric_limits<unsigned short>::digits10, __base);
487 // Stage 2: convert and store results.
490 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
491 if (!(__err & ios_base::failbit)
492 && __sanity != __xtrc && *__sanity == '\0' && errno == 0
493 && __ul <= USHRT_MAX)
494 __v = static_cast<unsigned short>(__ul);
496 __err |= ios_base::failbit;
500 template<typename _CharT, typename _InIter>
502 num_get<_CharT, _InIter>::
503 do_get(iter_type __beg, iter_type __end, ios_base& __io,
504 ios_base::iostate& __err, unsigned int& __v) const
506 // Stage 1: extract and determine the conversion specifier.
507 // Assuming leading zeros eliminated, thus the size of 32 for
511 _M_extract_int(__beg, __end, __io, __err, __xtrc,
512 numeric_limits<unsigned int>::digits10, __base);
514 // Stage 2: convert and store results.
517 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
518 if (!(__err & ios_base::failbit)
519 && __sanity != __xtrc && *__sanity == '\0' && errno == 0
521 __v = static_cast<unsigned int>(__ul);
523 __err |= ios_base::failbit;
527 template<typename _CharT, typename _InIter>
529 num_get<_CharT, _InIter>::
530 do_get(iter_type __beg, iter_type __end, ios_base& __io,
531 ios_base::iostate& __err, unsigned long& __v) const
533 // Stage 1: extract and determine the conversion specifier.
534 // Assuming leading zeros eliminated, thus the size of 32 for
538 _M_extract_int(__beg, __end, __io, __err, __xtrc,
539 numeric_limits<unsigned long>::digits10, __base);
541 // Stage 2: convert and store results.
544 unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
545 if (!(__err & ios_base::failbit)
546 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
549 __err |= ios_base::failbit;
553 #ifdef _GLIBCPP_USE_LONG_LONG
554 template<typename _CharT, typename _InIter>
556 num_get<_CharT, _InIter>::
557 do_get(iter_type __beg, iter_type __end, ios_base& __io,
558 ios_base::iostate& __err, long long& __v) const
560 // Stage 1: extract and determine the conversion specifier.
561 // Assuming leading zeros eliminated, thus the size of 32 for
565 _M_extract_int(__beg, __end, __io, __err, __xtrc,
566 numeric_limits<long long>::digits10, __base);
568 // Stage 2: convert and store results.
571 long long __ll = strtoll(__xtrc, &__sanity, __base);
572 if (!(__err & ios_base::failbit)
573 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
576 __err |= ios_base::failbit;
580 template<typename _CharT, typename _InIter>
582 num_get<_CharT, _InIter>::
583 do_get(iter_type __beg, iter_type __end, ios_base& __io,
584 ios_base::iostate& __err, unsigned long long& __v) const
586 // Stage 1: extract and determine the conversion specifier.
587 // Assuming leading zeros eliminated, thus the size of 32 for
591 _M_extract_int(__beg, __end, __io, __err, __xtrc,
592 numeric_limits<unsigned long long>::digits10, __base);
594 // Stage 2: convert and store results.
597 unsigned long long __ull = strtoull(__xtrc, &__sanity, __base);
598 if (!(__err & ios_base::failbit)
599 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
602 __err |= ios_base::failbit;
607 template<typename _CharT, typename _InIter>
609 num_get<_CharT, _InIter>::
610 do_get(iter_type __beg, iter_type __end, ios_base& __io,
611 ios_base::iostate& __err, float& __v) const
613 // Stage 1: extract and determine the conversion specifier.
616 _M_extract_float(__beg, __end, __io, __err, __xtrc);
618 // Stage 2: convert and store results.
621 #ifdef _GLIBCPP_USE_C99
622 float __f = strtof(__xtrc.c_str(), &__sanity);
624 float __f = static_cast<float>(strtod(__xtrc.c_str(), &__sanity));
626 if (!(__err & ios_base::failbit)
627 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
630 __err |= ios_base::failbit;
634 template<typename _CharT, typename _InIter>
636 num_get<_CharT, _InIter>::
637 do_get(iter_type __beg, iter_type __end, ios_base& __io,
638 ios_base::iostate& __err, double& __v) const
640 // Stage 1: extract and determine the conversion specifier.
643 _M_extract_float(__beg, __end, __io, __err, __xtrc);
645 // Stage 2: convert and store results.
648 double __d = strtod(__xtrc.c_str(), &__sanity);
649 if (!(__err & ios_base::failbit)
650 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
653 __err |= ios_base::failbit;
657 template<typename _CharT, typename _InIter>
659 num_get<_CharT, _InIter>::
660 do_get(iter_type __beg, iter_type __end, ios_base& __io,
661 ios_base::iostate& __err, long double& __v) const
663 // Stage 1: extract and determine the conversion specifier.
666 _M_extract_float(__beg, __end, __io, __err, __xtrc);
668 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
669 // Stage 2: convert and store results.
672 long double __ld = strtold(__xtrc.c_str(), &__sanity);
673 if (!(__err & ios_base::failbit)
674 && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
677 // Stage 2: determine a conversion specifier.
678 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
680 if (__basefield == ios_base::oct)
682 else if (__basefield == ios_base::hex)
684 else if (__basefield == 0)
689 // Stage 3: store results.
690 typedef typename char_traits<_CharT>::int_type int_type;
692 int __p = sscanf(__xtrc.c_str(), __conv, &__ld);
693 if (!(__err & ios_base::failbit) && __p
694 && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
698 __err |= ios_base::failbit;
702 template<typename _CharT, typename _InIter>
704 num_get<_CharT, _InIter>::
705 do_get(iter_type __beg, iter_type __end, ios_base& __io,
706 ios_base::iostate& __err, void*& __v) const
708 // Prepare for hex formatted input
709 typedef ios_base::fmtflags fmtflags;
710 fmtflags __fmt = __io.flags();
711 fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
712 | ios_base::uppercase | ios_base::internal);
713 __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
715 // Stage 1: extract and determine the conversion specifier.
716 // Assuming leading zeros eliminated, thus the size of 32 for
720 _M_extract_int(__beg, __end, __io, __err, __xtrc,
721 numeric_limits<unsigned long>::digits10, __base);
723 // Stage 2: convert and store results.
726 void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base));
727 if (!(__err & ios_base::failbit)
728 && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
731 __err |= ios_base::failbit;
733 // Reset from hex formatted input
739 // The following code uses sprintf() to convert floating point
740 // values for insertion into a stream. An optimization would be to
741 // replace sprintf() with code that works directly on a wide buffer
742 // and then use __pad to do the padding. It would be good
743 // to replace sprintf() anyway to avoid accidental buffer overruns
744 // and to gain back the efficiency that C++ provides by knowing up
745 // front the type of the values to insert. This implementation
746 // follows the C++ standard fairly directly as outlined in 22.2.2.2
747 // [lib.locale.num.put]
748 template<typename _CharT, typename _OutIter>
749 template<typename _ValueT>
751 num_put<_CharT, _OutIter>::
752 _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
755 const int __max_digits = numeric_limits<_ValueT>::digits10;
756 streamsize __prec = __io.precision();
757 // Protect against sprintf() buffer overflows.
758 if (__prec > static_cast<streamsize>(__max_digits))
759 __prec = static_cast<streamsize>(__max_digits);
761 // Long enough for the max format spec.
764 // Consider the possibility of long ios_base::fixed outputs
765 const bool __fixed = __io.flags() & ios_base::fixed;
766 const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
767 // ios_base::fixed outputs may need up to __max_exp+1 chars
768 // for the integer part + up to __max_digits chars for the
769 // fractional part + 3 chars for sign, decimal point, '\0'. On
770 // the other hand, for non-fixed outputs __max_digits*3 chars
771 // are largely sufficient.
772 const int __cs_size = __fixed ? __max_exp + __max_digits + 4
774 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
777 // [22.2.2.2.2] Stage 1, numeric conversion to character.
778 if (_S_format_float(__io, __fbuf, __mod, __prec))
779 __len = sprintf(__cs, __fbuf, __prec, __v);
781 __len = sprintf(__cs, __fbuf, __v);
782 return _M_widen_float(__s, __io, __fill, __cs, __len);
785 template<typename _CharT, typename _OutIter>
786 template<typename _ValueT>
788 num_put<_CharT, _OutIter>::
789 _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
790 char __modl, _ValueT __v) const
792 // [22.2.2.2.2] Stage 1, numeric conversion to character.
793 // Leave room for "+/-," "0x," and commas. This size is
794 // arbitrary, but should work.
796 // Long enough for the max format spec.
798 _S_format_int(__io, __fbuf, __mod, __modl);
799 int __len = sprintf(__cs, __fbuf, __v);
800 return _M_widen_int(__s, __io, __fill, __cs, __len);
803 template<typename _CharT, typename _OutIter>
805 num_put<_CharT, _OutIter>::
806 _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
809 // [22.2.2.2.2] Stage 2, convert to char_type, using correct
810 // numpunct.decimal_point() values for '.' and adding grouping.
811 const locale __loc = __io.getloc();
812 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
813 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
815 // Grouping can add (almost) as many separators as the number of
816 // digits, but no more.
817 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
819 __ctype.widen(__cs, __cs + __len, __ws);
821 // Replace decimal point.
823 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
824 if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
825 __ws[__p - __ws] = __np.decimal_point();
827 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
828 //282. What types does numpunct grouping refer to?
829 // Add grouping, if necessary.
830 const string __grouping = __np.grouping();
831 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
832 if (__grouping.size())
835 int __declen = __p ? __p - __ws : __len;
836 __p2 = __add_grouping(__ws2, __np.thousands_sep(),
838 __grouping.c_str() + __grouping.size(),
839 __ws, __ws + __declen);
840 int __newlen = __p2 - __ws2;
842 // Tack on decimal part.
845 char_traits<_CharT>::copy(__p2, __p, __len - __declen);
846 __newlen += __len - __declen;
849 // Switch strings, establish correct new length.
854 return _M_insert(__s, __io, __fill, __ws, __len);
857 template<typename _CharT, typename _OutIter>
859 num_put<_CharT, _OutIter>::
860 _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
863 // [22.2.2.2.2] Stage 2, convert to char_type, using correct
864 // numpunct.decimal_point() values for '.' and adding grouping.
865 const locale __loc = __io.getloc();
866 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
867 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
869 // Grouping can add (almost) as many separators as the number of
870 // digits, but no more.
871 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
873 __ctype.widen(__cs, __cs + __len, __ws);
875 // Add grouping, if necessary.
876 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
877 const string __grouping = __np.grouping();
878 ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
879 bool __dec = __basefield != ios_base::oct
880 && __basefield != ios_base::hex;
881 if (__grouping.size() && __dec)
884 __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
885 __grouping.c_str() + __grouping.size(),
891 return _M_insert(__s, __io, __fill, __ws, __len);
894 // For use by integer and floating-point types after they have been
895 // converted into a char_type string.
896 template<typename _CharT, typename _OutIter>
898 num_put<_CharT, _OutIter>::
899 _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
902 // [22.2.2.2.2] Stage 3.
903 streamsize __w = __io.width();
904 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
906 if (__w > static_cast<streamsize>(__len))
908 __pad(__io, __fill, __ws2, __ws, __w, __len, true);
909 __len = static_cast<int>(__w);
915 // [22.2.2.2.2] Stage 4.
916 // Write resulting, fully-formatted string to output iterator.
917 for (int __j = 0; __j < __len; ++__j, ++__s)
922 template<typename _CharT, typename _OutIter>
924 num_put<_CharT, _OutIter>::
925 do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
927 ios_base::fmtflags __flags = __io.flags();
928 if ((__flags & ios_base::boolalpha) == 0)
930 unsigned long __uv = __v;
931 _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
935 locale __loc = __io.getloc();
936 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
937 const char_type* __ws;
941 __ws = __np.truename().c_str();
942 __len = __np.truename().size();
946 __ws = __np.falsename().c_str();
947 __len = __np.falsename().size();
949 _M_insert(__s, __io, __fill, __ws, __len);
954 template<typename _CharT, typename _OutIter>
956 num_put<_CharT, _OutIter>::
957 do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
958 { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
960 template<typename _CharT, typename _OutIter>
962 num_put<_CharT, _OutIter>::
963 do_put(iter_type __s, ios_base& __io, char_type __fill,
964 unsigned long __v) const
965 { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
967 #ifdef _GLIBCPP_USE_LONG_LONG
968 template<typename _CharT, typename _OutIter>
970 num_put<_CharT, _OutIter>::
971 do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
972 { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
974 template<typename _CharT, typename _OutIter>
976 num_put<_CharT, _OutIter>::
977 do_put(iter_type __s, ios_base& __io, char_type __fill,
978 unsigned long long __v) const
979 { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
982 template<typename _CharT, typename _OutIter>
984 num_put<_CharT, _OutIter>::
985 do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
986 { return _M_convert_float(__s, __io, __fill, char_type(), __v); }
988 template<typename _CharT, typename _OutIter>
990 num_put<_CharT, _OutIter>::
991 do_put(iter_type __s, ios_base& __io, char_type __fill,
992 long double __v) const
993 { return _M_convert_float(__s, __io, __fill, 'L', __v); }
995 template<typename _CharT, typename _OutIter>
997 num_put<_CharT, _OutIter>::
998 do_put(iter_type __s, ios_base& __io, char_type __fill,
999 const void* __v) const
1001 ios_base::fmtflags __flags = __io.flags();
1002 ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
1003 | ios_base::uppercase | ios_base::internal);
1004 __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
1007 _M_convert_int(__s, __io, __fill, 'u', char_type(),
1008 reinterpret_cast<unsigned long>(__v));
1009 __io.flags(__flags);
1013 __io.flags(__flags);
1014 __throw_exception_again;
1020 template<typename _CharT, typename _InIter>
1022 money_get<_CharT, _InIter>::
1023 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1024 ios_base::iostate& __err, long double& __units) const
1027 this->do_get(__beg, __end, __intl, __io, __err, __str);
1029 const int __n = numeric_limits<long double>::digits10;
1030 char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1031 const locale __loc = __io.getloc();
1032 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1033 const _CharT* __wcs = __str.c_str();
1034 __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);
1036 #if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
1039 long double __ld = strtold(__cs, &__sanity);
1040 if (!(__err & ios_base::failbit)
1041 && __sanity != __cs && *__sanity == '\0' && errno == 0)
1044 typedef typename char_traits<_CharT>::int_type int_type;
1046 int __p = sscanf(__cs, "%Lf", &__ld);
1047 if (!(__err & ios_base::failbit)
1048 && __p && static_cast<int_type>(__p) != char_traits<_CharT>::eof())
1054 template<typename _CharT, typename _InIter>
1056 money_get<_CharT, _InIter>::
1057 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1058 ios_base::iostate& __err, string_type& __units) const
1060 // These contortions are quite unfortunate.
1061 typedef moneypunct<_CharT, true> __money_true;
1062 typedef moneypunct<_CharT, false> __money_false;
1063 typedef money_base::part part;
1064 typedef typename string_type::size_type size_type;
1066 const locale __loc = __io.getloc();
1067 const __money_true& __mpt = use_facet<__money_true>(__loc);
1068 const __money_false& __mpf = use_facet<__money_false>(__loc);
1069 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1071 const money_base::pattern __p = __intl ? __mpt.neg_format()
1072 : __mpf.neg_format();
1074 const string_type __pos_sign =__intl ? __mpt.positive_sign()
1075 : __mpf.positive_sign();
1076 const string_type __neg_sign =__intl ? __mpt.negative_sign()
1077 : __mpf.negative_sign();
1078 const char_type __d = __intl ? __mpt.decimal_point()
1079 : __mpf.decimal_point();
1080 const char_type __sep = __intl ? __mpt.thousands_sep()
1081 : __mpf.thousands_sep();
1083 const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
1085 // Set to deduced positive or negative sign, depending.
1087 // String of grouping info from thousands_sep plucked from __units.
1088 string __grouping_tmp;
1089 // Marker for thousands_sep position.
1091 // If input iterator is in a valid state.
1092 bool __testvalid = true;
1093 // Flag marking when a decimal point is found.
1094 bool __testdecfound = false;
1096 char_type __c = *__beg;
1097 char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
1098 for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
1100 part __which = static_cast<part>(__p.field[__i]);
1103 case money_base::symbol:
1104 if (__io.flags() & ios_base::showbase)
1106 // Symbol is required.
1107 const string_type __symbol = __intl ? __mpt.curr_symbol()
1108 : __mpf.curr_symbol();
1109 size_type __len = __symbol.size();
1111 while (__beg != __end
1112 && __i < __len && __symbol[__i] == __c)
1118 __testvalid = false;
1121 case money_base::sign:
1122 // Sign might not exist, or be more than one character long.
1123 if (__pos_sign.size() && __neg_sign.size())
1125 // Sign is mandatory.
1126 if (__c == __pos_sign[0])
1128 __sign = __pos_sign;
1131 else if (__c == __neg_sign[0])
1133 __sign = __neg_sign;
1137 __testvalid = false;
1139 else if (__pos_sign.size() && __c == __pos_sign[0])
1141 __sign = __pos_sign;
1144 else if (__neg_sign.size() && __c == __neg_sign[0])
1146 __sign = __neg_sign;
1150 case money_base::value:
1151 // Extract digits, remove and stash away the
1152 // grouping of found thousands separators.
1153 while (__beg != __end
1154 && (__ctype.is(ctype_base::digit, __c)
1155 || (__c == __d && !__testdecfound)
1160 __grouping_tmp += static_cast<char>(__sep_pos);
1162 __testdecfound = true;
1164 else if (__c == __sep)
1166 if (__grouping.size())
1168 // Mark position for later analysis.
1169 __grouping_tmp += static_cast<char>(__sep_pos);
1174 __testvalid = false;
1186 case money_base::space:
1187 case money_base::none:
1188 // Only if not at the end of the pattern.
1190 while (__beg != __end
1191 && __ctype.is(ctype_base::space, __c))
1197 // Need to get the rest of the sign characters, if they exist.
1198 if (__sign.size() > 1)
1200 size_type __len = __sign.size();
1202 for (; __c != __eof && __i < __len; ++__i)
1203 while (__beg != __end && __c != __sign[__i])
1207 __testvalid = false;
1210 // Strip leading zeros.
1211 while (__units[0] == __ctype.widen('0'))
1212 __units.erase(__units.begin());
1214 if (__sign == __neg_sign)
1215 __units.insert(__units.begin(), __ctype.widen('-'));
1217 // Test for grouping fidelity.
1218 if (__grouping.size() && __grouping_tmp.size())
1220 if (!__verify_grouping(__grouping, __grouping_tmp))
1221 __testvalid = false;
1224 // Iff no more characters are available.
1226 __err |= ios_base::eofbit;
1228 // Iff valid sequence is not recognized.
1229 if (!__testvalid || !__units.size())
1230 __err |= ios_base::failbit;
1234 template<typename _CharT, typename _OutIter>
1236 money_put<_CharT, _OutIter>::
1237 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1238 long double __units) const
1240 const locale __loc = __io.getloc();
1241 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1242 const int __n = numeric_limits<long double>::digits10;
1243 char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1244 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1245 int __len = sprintf(__cs, "%.01Lf", __units);
1246 __ctype.widen(__cs, __cs + __len, __ws);
1247 string_type __digits(__ws);
1248 return this->do_put(__s, __intl, __io, __fill, __digits);
1251 template<typename _CharT, typename _OutIter>
1253 money_put<_CharT, _OutIter>::
1254 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1255 const string_type& __digits) const
1257 typedef typename string_type::size_type size_type;
1258 typedef money_base::part part;
1260 const locale __loc = __io.getloc();
1261 const size_type __width = static_cast<size_type>(__io.width());
1263 // These contortions are quite unfortunate.
1264 typedef moneypunct<_CharT, true> __money_true;
1265 typedef moneypunct<_CharT, false> __money_false;
1266 const __money_true& __mpt = use_facet<__money_true>(__loc);
1267 const __money_false& __mpf = use_facet<__money_false>(__loc);
1268 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1270 // Determine if negative or positive formats are to be used, and
1271 // discard leading negative_sign if it is present.
1272 const char_type* __beg = __digits.data();
1273 const char_type* __end = __beg + __digits.size();
1274 money_base::pattern __p;
1276 if (*__beg != __ctype.widen('-'))
1278 __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
1279 __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
1283 __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
1284 __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
1288 // Look for valid numbers in the current ctype facet within input digits.
1289 __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
1292 // Assume valid input, and attempt to format.
1293 // Break down input numbers into base components, as follows:
1294 // final_value = grouped units + (decimal point) + (digits)
1296 string_type __value;
1297 const string_type __symbol = __intl ? __mpt.curr_symbol()
1298 : __mpf.curr_symbol();
1300 // Deal with decimal point, decimal digits.
1301 const int __frac = __intl ? __mpt.frac_digits()
1302 : __mpf.frac_digits();
1305 const char_type __d = __intl ? __mpt.decimal_point()
1306 : __mpf.decimal_point();
1307 if (__end - __beg >= __frac)
1309 __value = string_type(__end - __frac, __end);
1310 __value.insert(__value.begin(), __d);
1315 // Have to pad zeros in the decimal position.
1316 __value = string_type(__beg, __end);
1317 int __paddec = __frac - (__end - __beg);
1318 char_type __zero = __ctype.widen('0');
1319 __value.insert(__value.begin(), __paddec, __zero);
1320 __value.insert(__value.begin(), __d);
1325 // Add thousands separators to non-decimal digits, per
1329 const string __grouping = __intl ? __mpt.grouping()
1331 if (__grouping.size())
1333 const char_type __sep = __intl ? __mpt.thousands_sep()
1334 : __mpf.thousands_sep();
1335 const char* __gbeg = __grouping.c_str();
1336 const char* __gend = __gbeg + __grouping.size();
1337 const int __n = numeric_limits<long double>::digits10 * 2;
1338 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1339 _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
1340 __gend, __beg, __end);
1341 __value.insert(0, __ws2, __ws_end - __ws2);
1344 __value.insert(0, string_type(__beg, __end));
1347 // Calculate length of resulting string.
1348 ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
1349 size_type __len = __value.size() + __sign.size();
1350 __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
1351 bool __testipad = __f == ios_base::internal && __len < __width;
1353 // Fit formatted digits into the required pattern.
1354 for (int __i = 0; __i < 4; ++__i)
1356 part __which = static_cast<part>(__p.field[__i]);
1359 case money_base::symbol:
1360 if (__io.flags() & ios_base::showbase)
1363 case money_base::sign:
1364 // Sign might not exist, or be more than one
1365 // charater long. In that case, add in the rest
1370 case money_base::value:
1373 case money_base::space:
1374 // At least one space is required, but if internal
1375 // formatting is required, an arbitrary number of
1376 // fill spaces will be necessary.
1378 __res += string_type(__width - __len, __fill);
1380 __res += __ctype.widen(' ');
1382 case money_base::none:
1384 __res += string_type(__width - __len, __fill);
1389 // Special case of multi-part sign parts.
1390 if (__sign.size() > 1)
1391 __res += string_type(__sign.begin() + 1, __sign.end());
1393 // Pad, if still necessary.
1394 __len = __res.size();
1395 if (__width > __len)
1397 if (__f == ios_base::left)
1399 __res.append(__width - __len, __fill);
1402 __res.insert(0, string_type(__width - __len, __fill));
1406 // Write resulting, fully-formatted string to output iterator.
1407 for (size_type __j = 0; __j < __len; ++__j)
1415 // NB: Not especially useful. Without an ios_base object or some
1416 // kind of locale reference, we are left clawing at the air where
1417 // the side of the mountain used to be...
1418 template<typename _CharT, typename _InIter>
1419 time_base::dateorder
1420 time_get<_CharT, _InIter>::do_date_order() const
1421 { return time_base::no_order; }
1423 template<typename _CharT, typename _InIter>
1425 time_get<_CharT, _InIter>::
1426 _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
1427 ios_base::iostate& __err, tm* __tm,
1428 const _CharT* __format) const
1430 locale __loc = __io.getloc();
1431 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1432 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1433 size_t __len = char_traits<_CharT>::length(__format);
1435 for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
1437 char __c = __format[__i];
1440 // Verify valid formatting code, attempt to extract.
1441 __c = __format[++__i];
1444 if (__c == 'E' || __c == 'O')
1447 __c = __format[++__i];
1454 // Abbreviated weekday name [tm_wday]
1455 const char_type* __days1[7];
1456 __tp._M_days_abbreviated(__days1);
1457 _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
1461 // Weekday name [tm_wday].
1462 const char_type* __days2[7];
1463 __tp._M_days(__days2);
1464 _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
1469 // Abbreviated month name [tm_mon]
1470 const char_type* __months1[12];
1471 __tp._M_months_abbreviated(__months1);
1472 _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
1476 // Month name [tm_mon].
1477 const char_type* __months2[12];
1478 __tp._M_months(__months2);
1479 _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
1483 // Default time and date representation.
1484 const char_type* __dt[2];
1485 __tp._M_date_time_formats(__dt);
1486 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1490 // Day [01, 31]. [tm_mday]
1491 _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
1495 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1497 __ctype.widen(__cs, __cs + 9, __wcs);
1498 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1502 // Hour [00, 23]. [tm_hour]
1503 _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1507 // Hour [01, 12]. [tm_hour]
1508 _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
1512 // Month [01, 12]. [tm_mon]
1513 _M_extract_num(__beg, __end, __mem, 1, 12, 2,
1516 __tm->tm_mon = __mem - 1;
1519 // Minute [00, 59]. [tm_min]
1520 _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1524 if (__ctype.narrow(*__beg, 0) == '\n')
1527 __err |= ios_base::failbit;
1530 // Equivalent to (%H:%M).
1532 __ctype.widen(__cs, __cs + 6, __wcs);
1533 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1538 _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
1542 if (__ctype.narrow(*__beg, 0) == '\t')
1545 __err |= ios_base::failbit;
1548 // Equivalent to (%H:%M:%S).
1550 __ctype.widen(__cs, __cs + 9, __wcs);
1551 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1556 const char_type* __dates[2];
1557 __tp._M_date_formats(__dates);
1558 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1563 const char_type* __times[2];
1564 __tp._M_time_formats(__times);
1565 _M_extract_via_format(__beg, __end, __io, __err, __tm,
1569 // Two digit year. [tm_year]
1570 _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
1574 // Year [1900). [tm_year]
1575 _M_extract_num(__beg, __end, __mem, 0,
1576 numeric_limits<int>::max(), 4,
1579 __tm->tm_year = __mem - 1900;
1583 if (__ctype.is(ctype_base::upper, *__beg))
1586 _M_extract_name(__beg, __end, __tmp,
1587 __timepunct<_CharT>::_S_timezones,
1590 // GMT requires special effort.
1591 char_type __c = *__beg;
1592 if (!__err && __tmp == 0
1593 && (__c == __ctype.widen('-')
1594 || __c == __ctype.widen('+')))
1596 _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1598 _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1603 __err |= ios_base::failbit;
1607 __err |= ios_base::failbit;
1612 // Verify format and input match, extract and discard.
1613 if (__c == __ctype.narrow(*__beg, 0))
1616 __err |= ios_base::failbit;
1621 template<typename _CharT, typename _InIter>
1623 time_get<_CharT, _InIter>::
1624 _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
1625 int __min, int __max, size_t __len,
1626 const ctype<_CharT>& __ctype,
1627 ios_base::iostate& __err) const
1631 bool __testvalid = true;
1632 char_type __c = *__beg;
1633 while (__beg != __end && __i < __len
1634 && __ctype.is(ctype_base::digit, __c))
1636 __digits += __ctype.narrow(__c, 0);
1642 int __value = atoi(__digits.c_str());
1643 if (__min <= __value && __value <= __max)
1646 __testvalid = false;
1649 __testvalid = false;
1651 __err |= ios_base::failbit;
1655 // All elements in __names are unique.
1656 template<typename _CharT, typename _InIter>
1658 time_get<_CharT, _InIter>::
1659 _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
1660 const _CharT** __names, size_t __indexlen,
1661 ios_base::iostate& __err) const
1663 typedef char_traits<char_type> __traits_type;
1664 int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
1665 size_t __nmatches = 0;
1667 bool __testvalid = true;
1668 const char_type* __name;
1670 char_type __c = *__beg;
1671 // Look for initial matches.
1672 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
1673 if (__c == __names[__i1][0])
1674 __matches[__nmatches++] = __i1;
1676 while(__nmatches > 1)
1678 // Find smallest matching string.
1679 size_t __minlen = 10;
1680 for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
1681 __minlen = min(__minlen,
1682 __traits_type::length(__names[__matches[__i2]]));
1684 if (__pos < __minlen && __beg != __end)
1688 for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
1690 __name = __names[__matches[__i3]];
1691 if (__name[__pos] != __c)
1692 __matches[__i3] = __matches[--__nmatches];
1699 if (__nmatches == 1)
1701 // Make sure found name is completely extracted.
1702 __name = __names[__matches[0]];
1703 const size_t __len = __traits_type::length(__name);
1704 while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
1708 __member = __matches[0];
1710 __testvalid = false;
1713 __testvalid = false;
1715 __err |= ios_base::failbit;
1718 template<typename _CharT, typename _InIter>
1720 time_get<_CharT, _InIter>::
1721 do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1722 ios_base::iostate& __err, tm* __tm) const
1725 const char* __cs = "%X";
1726 locale __loc = __io.getloc();
1727 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1728 __ctype.widen(__cs, __cs + 3, __wcs);
1729 _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1731 __err |= ios_base::eofbit;
1735 template<typename _CharT, typename _InIter>
1737 time_get<_CharT, _InIter>::
1738 do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1739 ios_base::iostate& __err, tm* __tm) const
1742 const char* __cs = "%x";
1743 locale __loc = __io.getloc();
1744 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1745 __ctype.widen(__cs, __cs + 3, __wcs);
1746 _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1748 __err |= ios_base::eofbit;
1752 template<typename _CharT, typename _InIter>
1754 time_get<_CharT, _InIter>::
1755 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
1756 ios_base::iostate& __err, tm* __tm) const
1758 typedef char_traits<char_type> __traits_type;
1759 locale __loc = __io.getloc();
1760 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1761 const char_type* __days[7];
1762 __tp._M_days_abbreviated(__days);
1764 _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
1766 // Check to see if non-abbreviated name exists, and extract.
1767 // NB: Assumes both _M_days and _M_days_abbreviated organized in
1768 // exact same order, first to last, such that the resulting
1769 // __days array with the same index points to a day, and that
1770 // day's abbreviated form.
1771 // NB: Also assumes that an abbreviated name is a subset of the name.
1774 size_t __pos = __traits_type::length(__days[__tmpwday]);
1775 __tp._M_days(__days);
1776 const char_type* __name = __days[__tmpwday];
1777 if (__name[__pos] == *__beg)
1779 // Extract the rest of it.
1780 const size_t __len = __traits_type::length(__name);
1781 while (__pos < __len && __beg != __end
1782 && __name[__pos] == *__beg)
1785 __err |= ios_base::failbit;
1788 __tm->tm_wday = __tmpwday;
1791 __err |= ios_base::eofbit;
1795 template<typename _CharT, typename _InIter>
1797 time_get<_CharT, _InIter>::
1798 do_get_monthname(iter_type __beg, iter_type __end,
1799 ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1801 typedef char_traits<char_type> __traits_type;
1802 locale __loc = __io.getloc();
1803 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1804 const char_type* __months[12];
1805 __tp._M_months_abbreviated(__months);
1807 _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
1809 // Check to see if non-abbreviated name exists, and extract.
1810 // NB: Assumes both _M_months and _M_months_abbreviated organized in
1811 // exact same order, first to last, such that the resulting
1812 // __months array with the same index points to a month, and that
1813 // month's abbreviated form.
1814 // NB: Also assumes that an abbreviated name is a subset of the name.
1817 size_t __pos = __traits_type::length(__months[__tmpmon]);
1818 __tp._M_months(__months);
1819 const char_type* __name = __months[__tmpmon];
1820 if (__name[__pos] == *__beg)
1822 // Extract the rest of it.
1823 const size_t __len = __traits_type::length(__name);
1824 while (__pos < __len && __beg != __end
1825 && __name[__pos] == *__beg)
1828 __err |= ios_base::failbit;
1831 __tm->tm_mon = __tmpmon;
1835 __err |= ios_base::eofbit;
1839 template<typename _CharT, typename _InIter>
1841 time_get<_CharT, _InIter>::
1842 do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
1843 ios_base::iostate& __err, tm* __tm) const
1845 locale __loc = __io.getloc();
1846 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1848 char_type __c = *__beg;
1851 while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
1853 __digits += __ctype.narrow(__c, 0);
1857 if (__i == 2 || __i == 4)
1859 int __year = atoi(__digits.c_str());
1860 __year = __i == 2 ? __year : __year - 1900;
1861 __tm->tm_year = __year;
1864 __err |= ios_base::failbit;
1866 __err |= ios_base::eofbit;
1870 template<typename _CharT, typename _OutIter>
1872 time_put<_CharT, _OutIter>::
1873 put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1874 const _CharT* __beg, const _CharT* __end) const
1876 locale __loc = __io.getloc();
1877 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1878 while (__beg != __end)
1880 char __c = __ctype.narrow(*__beg, 0);
1887 __c = __ctype.narrow(*__beg, 0);
1889 if (__c == 'E' || __c == 'O')
1892 __format = __ctype.narrow(*__beg, 0);
1897 this->do_put(__s, __io, char_type(), __tm, __format, __mod);
1905 template<typename _CharT, typename _OutIter>
1907 time_put<_CharT, _OutIter>::
1908 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1909 char __format, char __mod) const
1911 locale __loc = __io.getloc();
1912 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1913 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1915 // NB: This size is arbitrary. Should this be a data member,
1916 // initialized at construction?
1917 const size_t __maxlen = 64;
1918 char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen));
1920 // NB: In IEE 1003.1-200x, and perhaps other locale models, it
1921 // is possible that the format character will be longer than one
1922 // character. Possibilities include 'E' or 'O' followed by a
1923 // format character: if __mod is not the default argument, assume
1924 // it's a valid modifier.
1926 __fmt[0] = __ctype.widen('%');
1929 __fmt[1] = __format;
1930 __fmt[2] = char_type();
1935 __fmt[2] = __format;
1936 __fmt[3] = char_type();
1939 __tp._M_put_helper(__res, __maxlen, __fmt, __tm);
1941 // Write resulting, fully-formatted string to output iterator.
1942 size_t __len = char_traits<char_type>::length(__res);
1943 for (size_t __i = 0; __i < __len; ++__i)
1949 // Generic version does nothing.
1950 template<typename _CharT>
1952 collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const
1955 // Generic version does nothing.
1956 template<typename _CharT>
1958 collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const
1961 template<typename _CharT>
1964 do_compare(const _CharT* __lo1, const _CharT* __hi1,
1965 const _CharT* __lo2, const _CharT* __hi2) const
1967 const string_type __one(__lo1, __hi1);
1968 const string_type __two(__lo2, __hi2);
1969 return _M_compare_helper(__one.c_str(), __two.c_str());
1972 template<typename _CharT>
1973 collate<_CharT>::string_type
1975 do_transform(const _CharT* __lo, const _CharT* __hi) const
1977 size_t __len = __hi - __lo;
1978 _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
1979 size_t __res = _M_transform_helper(__c, __lo, __len);
1982 // Try to increment size of translated string.
1983 size_t __len2 = __len * 2;
1984 _CharT* __c2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len2));
1985 __res = _M_transform_helper(__c2, __lo, __len);
1986 // XXX Throw exception if still indeterminate?
1988 return string_type(__c);
1991 template<typename _CharT>
1994 do_hash(const _CharT* __lo, const _CharT* __hi) const
1996 unsigned long __val = 0;
1997 for (; __lo < __hi; ++__lo)
1998 __val = *__lo + ((__val << 7) |
1999 (__val >> (numeric_limits<unsigned long>::digits - 1)));
2000 return static_cast<long>(__val);
2003 // Construct correctly padded string, as per 22.2.2.2.2
2005 // __newlen > __oldlen
2006 // __news is allocated for __newlen size
2007 // Used by both num_put and ostream inserters: if __num,
2008 // internal-adjusted objects are padded according to the rules below
2009 // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
2011 template<typename _CharT, typename _Traits>
2013 __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
2014 const streamsize __newlen, const streamsize __oldlen,
2017 typedef _CharT char_type;
2018 typedef _Traits traits_type;
2019 typedef typename traits_type::int_type int_type;
2021 int_type __plen = static_cast<size_t>(__newlen - __oldlen);
2022 char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
2023 traits_type::assign(__pads, __plen, __fill);
2028 size_t __beglen; //either __plen or __oldlen
2029 ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
2031 if (__adjust == ios_base::left)
2034 __beg = const_cast<char_type*>(__olds);
2035 __beglen = __oldlen;
2038 else if (__adjust == ios_base::internal && __num)
2040 // Pad after the sign, if there is one.
2041 // Pad after 0[xX], if there is one.
2042 // Who came up with these rules, anyway? Jeeze.
2043 locale __loc = __io.getloc();
2044 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2045 const char_type __minus = __ctype.widen('-');
2046 const char_type __plus = __ctype.widen('+');
2047 bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
2048 bool __testhex = __ctype.widen('0') == __olds[0]
2049 && (__ctype.widen('x') == __olds[1]
2050 || __ctype.widen('X') == __olds[1]);
2053 __news[0] = __olds[0];
2054 __news[1] = __olds[1];
2059 __end = const_cast<char_type*>(__olds + __mod);
2061 else if (__testsign)
2063 __news[0] = __olds[0] == __plus ? __plus : __minus;
2068 __end = const_cast<char_type*>(__olds + __mod);
2075 __end = const_cast<char_type*>(__olds);
2083 __end = const_cast<char_type*>(__olds);
2085 traits_type::copy(__news, __beg, __beglen);
2086 traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
2089 // NB: Can't have default argument on non-member template, and
2090 // num_put doesn't have a _Traits template parameter, so this
2091 // forwarding template adds in the default template argument.
2092 template<typename _CharT>
2094 __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
2095 const streamsize __newlen, const streamsize __oldlen,
2098 return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, __olds,
2099 __newlen, __oldlen, __num);
2102 // Used by both numeric and monetary facets.
2103 // Check to make sure that the __grouping_tmp string constructed in
2104 // money_get or num_get matches the canonical grouping for a given
2106 // __grouping_tmp is parsed L to R
2107 // 1,222,444 == __grouping_tmp of "/1/3/3"
2108 // __grouping is parsed R to L
2109 // 1,222,444 == __grouping of "/3" == "/3/3/3"
2110 template<typename _CharT>
2112 __verify_grouping(const basic_string<_CharT>& __grouping,
2113 basic_string<_CharT>& __grouping_tmp)
2117 const int __len = __grouping.size();
2118 const int __n = __grouping_tmp.size();
2121 // Parsed number groupings have to match the
2122 // numpunct::grouping string exactly, starting at the
2123 // right-most point of the parsed sequence of elements ...
2124 while (__test && __i < __n - 1)
2125 for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
2126 __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
2127 // ... but the last parsed grouping can be <= numpunct
2129 __j == __len ? __j = 0 : __j;
2130 __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
2134 // Used by both numeric and monetary facets.
2135 // Inserts "group separator" characters into an array of characters.
2136 // It's recursive, one iteration per group. It moves the characters
2137 // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
2138 // only with __gbeg != __gend.
2139 template<typename _CharT>
2141 __add_grouping(_CharT* __s, _CharT __sep,
2142 const char* __gbeg, const char* __gend,
2143 const _CharT* __first, const _CharT* __last)
2145 if (__last - __first > *__gbeg)
2147 __s = __add_grouping(__s, __sep,
2148 (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
2149 __gend, __first, __last - *__gbeg);
2150 __first = __last - *__gbeg;
2154 *__s++ = *__first++;
2155 while (__first != __last);