OSDN Git Service

2002-01-23 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / locale_facets.tcc
1 // Locale support -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 // Warning: this file is not meant for user inclusion. Use <locale>.
32
33 #ifndef _CPP_BITS_LOCFACETS_TCC
34 #define _CPP_BITS_LOCFACETS_TCC 1
35
36 #include <cerrno>
37 #include <clocale>   // For localeconv
38 #include <cstdlib>   // For strof, strtold
39 #include <cmath>     // For ceil
40 #include <cctype>    // For isspace
41 #include <limits>    // For numeric_limits
42 #include <memory>    // For auto_ptr
43 #include <bits/streambuf_iterator.h>
44 #include <vector>       
45 #include <typeinfo>  // For bad_cast.
46
47 namespace std
48 {
49   template<typename _Facet>
50     locale
51     locale::combine(const locale& __other) const
52     {
53       _Impl* __tmp = new _Impl(*_M_impl, 1);
54       __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
55       return locale(__tmp);
56     }
57
58   template<typename _CharT, typename _Traits, typename _Alloc>
59     bool
60     locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
61                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
62     {
63       typedef std::collate<_CharT> __collate_type;
64       const __collate_type& __collate = use_facet<__collate_type>(*this);
65       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
66                                 __s2.data(), __s2.data() + __s2.length()) < 0);
67     }
68
69   template<typename _Facet>
70     const _Facet&
71     use_facet(const locale& __loc)
72     {
73       size_t __i = _Facet::id._M_index;
74       locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
75       const locale::facet* __fp = (*__facet)[__i]; 
76       if (__fp == 0 || __i >= __facet->size())
77         __throw_bad_cast();
78       return static_cast<const _Facet&>(*__fp);
79     }
80
81   template<typename _Facet>
82     bool
83     has_facet(const locale& __loc) throw()
84     {
85       size_t __i = _Facet::id._M_index;
86       locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
87       return (__i < __facet->size() && (*__facet)[__i] != 0);
88     }
89
90
91   // Stage 1: Determine a conversion specifier.
92   template<typename _CharT, typename _InIter>
93     _InIter
94     num_get<_CharT, _InIter>::
95     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
96                      ios_base::iostate& __err, string& __xtrc) const
97     {
98       const locale __loc = __io.getloc();
99       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
100       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
101
102       // First check for sign.
103       const char_type __plus = __ctype.widen('+');
104       const char_type __minus = __ctype.widen('-');
105       int __pos = 0;
106       char_type  __c = *__beg;
107       if ((__c == __plus || __c == __minus) && __beg != __end)
108         {
109           __xtrc += __ctype.narrow(__c, char());
110           ++__pos;
111           __c = *(++__beg);
112         }
113
114       // Next, strip leading zeros.
115       const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
116       bool __found_zero = false;
117       while (__c == __zero && __beg != __end)
118         {
119           __c = *(++__beg);
120           __found_zero = true;
121         }
122       if (__found_zero)
123         {
124           __xtrc += _S_atoms[_M_zero];
125           ++__pos;
126         }
127
128       // Only need acceptable digits for floating point numbers.
129       const size_t __len = _M_E - _M_zero + 1;
130       char_type  __watoms[__len];
131       __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
132       bool __found_dec = false;
133       bool __found_sci = false;
134       const char_type __dec = __np.decimal_point();
135
136       string __found_grouping;
137       const string __grouping = __np.grouping();
138       bool __check_grouping = __grouping.size();
139       int __sep_pos = 0;
140       const char_type __sep = __np.thousands_sep();
141
142       while (__beg != __end)
143         {
144           // Only look in digits.
145           typedef char_traits<_CharT>   __traits_type;
146           const char_type* __p = __traits_type::find(__watoms, 10,  __c);
147
148           // NB: strchr returns true for __c == 0x0
149           if (__p && __c)
150             {
151               // Try first for acceptable digit; record it if found.
152               ++__pos;
153               __xtrc += _S_atoms[__p - __watoms];
154               ++__sep_pos;
155               __c = *(++__beg);
156             }
157           else if (__c == __sep && __check_grouping && !__found_dec)
158             {
159               // NB: Thousands separator at the beginning of a string
160               // is a no-no, as is two consecutive thousands separators.
161               if (__sep_pos)
162                 {
163                   __found_grouping += static_cast<char>(__sep_pos);
164                   __sep_pos = 0;
165                   __c = *(++__beg);
166                 }
167               else
168                 {
169                   __err |= ios_base::failbit;
170                   break;
171                 }
172             }
173           else if (__c == __dec && !__found_dec)
174             {
175               __found_grouping += static_cast<char>(__sep_pos);
176               ++__pos;
177               __xtrc += '.';
178               __c = *(++__beg);
179               __found_dec = true;
180             }
181           else if ((__c == __watoms[_M_e] || __c == __watoms[_M_E]) 
182                    && !__found_sci && __pos)
183             {
184               // Scientific notation.
185               ++__pos;
186               __xtrc += __ctype.narrow(__c, char());
187               __c = *(++__beg);
188
189               // Remove optional plus or minus sign, if they exist.
190               if (__c == __plus || __c == __minus)
191                 {
192                   ++__pos;
193                   __xtrc += __ctype.narrow(__c, char());
194                   __c = *(++__beg);
195                 }
196               __found_sci = true;
197             }
198           else
199             // Not a valid input item.
200             break;
201         }
202
203       // Digit grouping is checked. If grouping and found_grouping don't
204       // match, then get very very upset, and set failbit.
205       if (__check_grouping && __found_grouping.size())
206         {
207           // Add the ending grouping if a decimal wasn't found.
208           if (!__found_dec)
209             __found_grouping += static_cast<char>(__sep_pos);
210           if (!__verify_grouping(__grouping, __found_grouping))
211             __err |= ios_base::failbit;
212         }
213
214       // Finish up
215       __xtrc += char();
216       if (__beg == __end)
217         __err |= ios_base::eofbit;
218       return __beg;
219     }
220
221   // Stage 1: Determine a conversion specifier.
222   template<typename _CharT, typename _InIter>
223     _InIter
224     num_get<_CharT, _InIter>::
225     _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
226                    ios_base::iostate& __err, string& __xtrc, int& __base) const
227     {
228       const locale __loc = __io.getloc();
229       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
230       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
231  
232       // NB: Iff __basefield == 0, this can change based on contents.
233       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
234       if (__basefield == ios_base::oct)
235         __base = 8;
236       else if (__basefield == ios_base::hex)
237         __base = 16;
238       else
239         __base = 10;
240
241      // First check for sign.
242       int __pos = 0;
243       char_type  __c = *__beg;
244       if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
245           && __beg != __end)
246         {
247           __xtrc += __ctype.narrow(__c, char());
248           ++__pos;
249           __c = *(++__beg);
250         }
251
252       // Next, strip leading zeros and check required digits for base formats.
253       const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
254       const char_type __x = __ctype.widen('x');
255       const char_type __X = __ctype.widen('X');
256       if (__base == 10)
257         {
258           bool __found_zero = false;
259           while (__c == __zero && __beg != __end)
260             {
261               __c = *(++__beg);
262               __found_zero = true;
263             }
264           if (__found_zero)
265             {
266               __xtrc += _S_atoms[_M_zero];
267               ++__pos;
268               if (__basefield == 0)
269                 {             
270                   if ((__c == __x || __c == __X) && __beg != __end)
271                     {
272                       __xtrc += __ctype.narrow(__c, char());
273                       ++__pos;
274                       __c = *(++__beg);
275                       __base = 16;
276                     }
277                   else 
278                     __base = 8;
279                 }
280             }
281         }
282       else if (__base == 16)
283         {
284           if (__c == __zero && __beg != __end)
285             {
286               __xtrc += _S_atoms[_M_zero];
287               ++__pos;
288               __c = *(++__beg); 
289               if  ((__c == __x || __c == __X) && __beg != __end)
290                 {
291                   __xtrc += __ctype.narrow(__c, char());
292                   ++__pos;
293                   __c = *(++__beg);
294                 }
295             }
296         }
297
298       // At this point, base is determined. If not hex, only allow
299       // base digits as valid input.
300       size_t __len;
301       if (__base == 16)
302         __len = _M_size;
303       else
304         __len = __base;
305
306       // Extract.
307       char_type __watoms[_M_size];
308       __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
309       string __found_grouping;
310       const string __grouping = __np.grouping();
311       bool __check_grouping = __grouping.size() && __base == 10;
312       int __sep_pos = 0;
313       const char_type __sep = __np.thousands_sep();
314       while (__beg != __end)
315         {
316           typedef char_traits<_CharT>   __traits_type;
317           const char_type* __p = __traits_type::find(__watoms, __len,  __c);
318
319           // NB: strchr returns true for __c == 0x0
320           if (__p && __c)
321             {
322               // Try first for acceptable digit; record it if found.
323               __xtrc += _S_atoms[__p - __watoms];
324               ++__pos;
325               ++__sep_pos;
326               __c = *(++__beg);
327             }
328           else if (__c == __sep && __check_grouping)
329             {
330               // NB: Thousands separator at the beginning of a string
331               // is a no-no, as is two consecutive thousands separators.
332               if (__sep_pos)
333                 {
334                   __found_grouping += static_cast<char>(__sep_pos);
335                   __sep_pos = 0;
336                   __c = *(++__beg);
337                 }
338               else
339                 {
340                   __err |= ios_base::failbit;
341                   break;
342                 }
343             }
344           else
345             // Not a valid input item.
346             break;
347         }
348
349       // Digit grouping is checked. If grouping and found_grouping don't
350       // match, then get very very upset, and set failbit.
351       if (__check_grouping && __found_grouping.size())
352         {
353           // Add the ending grouping.
354           __found_grouping += static_cast<char>(__sep_pos);
355           if (!__verify_grouping(__grouping, __found_grouping))
356             __err |= ios_base::failbit;
357         }
358
359       // Finish up.
360       __xtrc += char();
361       if (__beg == __end)
362         __err |= ios_base::eofbit;
363       return __beg;
364     }
365
366 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
367   //17.  Bad bool parsing
368   template<typename _CharT, typename _InIter>
369     _InIter
370     num_get<_CharT, _InIter>::
371     do_get(iter_type __beg, iter_type __end, ios_base& __io,
372            ios_base::iostate& __err, bool& __v) const
373     {
374       // Parse bool values as unsigned long
375       if (!(__io.flags() & ios_base::boolalpha))
376         {
377           // NB: We can't just call do_get(long) here, as it might
378           // refer to a derived class.
379           string __xtrc;
380           int __base;
381           // According to 18.2.1.2.9, digits10 is "Number of base 10 digits
382           // that can be represented without change" so we have to add 1 to it
383           // in order to obtain the max number of digits. The same for the
384           // other do_get for integral types below.
385           __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
386
387           unsigned long __ul; 
388           __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
389           if (!(__err & ios_base::failbit) && __ul <= 1)
390             __v = __ul;
391           else 
392             __err |= ios_base::failbit;
393         }
394
395       // Parse bool values as alphanumeric
396       else
397         {
398           locale __loc = __io.getloc();
399           const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
400           const char_type* __true = __np.truename().c_str();
401           const char_type* __false = __np.falsename().c_str();
402
403           const size_t __truen =  __np.truename().size() - 1;
404           const size_t __falsen =  __np.falsename().size() - 1;
405
406           for (size_t __n = 0; __beg != __end; ++__n)
407             {
408               char_type __c = *__beg++;
409               bool __testf = __n <= __falsen ? __c == __false[__n] : false;
410               bool __testt = __n <= __truen ? __c == __true[__n] : false;
411               if (!(__testf || __testt))
412                 {
413                   __err |= ios_base::failbit;
414                   break;
415                 }
416               else if (__testf && __n == __falsen)
417                 {
418                   __v = 0;
419                   break;
420                 }
421               else if (__testt && __n == __truen)
422                 {
423                   __v = 1;
424                   break;
425                 }
426             }
427           if (__beg == __end)
428             __err |= ios_base::eofbit;
429         }
430       return __beg;
431     }
432 #endif
433
434   template<typename _CharT, typename _InIter>
435     _InIter
436     num_get<_CharT, _InIter>::
437     do_get(iter_type __beg, iter_type __end, ios_base& __io,
438            ios_base::iostate& __err, long& __v) const
439     {
440       string __xtrc;
441       int __base;
442       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
443       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
444       return __beg;
445     }
446
447   template<typename _CharT, typename _InIter>
448     _InIter
449     num_get<_CharT, _InIter>::
450     do_get(iter_type __beg, iter_type __end, ios_base& __io,
451            ios_base::iostate& __err, unsigned short& __v) const
452     {
453       string __xtrc;
454       int __base;
455       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
456       unsigned long __ul;
457       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
458       if (!(__err & ios_base::failbit) 
459           && __ul <= numeric_limits<unsigned short>::max())
460         __v = static_cast<unsigned short>(__ul);
461       else 
462         __err |= ios_base::failbit;
463       return __beg;
464     }
465
466   template<typename _CharT, typename _InIter>
467     _InIter
468     num_get<_CharT, _InIter>::
469     do_get(iter_type __beg, iter_type __end, ios_base& __io,
470            ios_base::iostate& __err, unsigned int& __v) const
471     {
472       string __xtrc;
473       int __base;
474       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
475       unsigned long __ul;
476       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
477       if (!(__err & ios_base::failbit) 
478           && __ul <= numeric_limits<unsigned int>::max())
479         __v = static_cast<unsigned int>(__ul);
480       else 
481         __err |= ios_base::failbit;
482       return __beg;
483     }
484
485   template<typename _CharT, typename _InIter>
486     _InIter
487     num_get<_CharT, _InIter>::
488     do_get(iter_type __beg, iter_type __end, ios_base& __io,
489            ios_base::iostate& __err, unsigned long& __v) const
490     {
491       string __xtrc;
492       int __base;
493       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
494       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
495       return __beg;
496     }
497
498 #ifdef _GLIBCPP_USE_LONG_LONG
499   template<typename _CharT, typename _InIter>
500     _InIter
501     num_get<_CharT, _InIter>::
502     do_get(iter_type __beg, iter_type __end, ios_base& __io,
503            ios_base::iostate& __err, long long& __v) const
504     {
505       string __xtrc;
506       int __base;
507       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
508       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
509       return __beg;
510     }
511
512   template<typename _CharT, typename _InIter>
513     _InIter
514     num_get<_CharT, _InIter>::
515     do_get(iter_type __beg, iter_type __end, ios_base& __io,
516            ios_base::iostate& __err, unsigned long long& __v) const
517     {
518       string __xtrc;
519       int __base;
520       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
521       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
522       return __beg;
523     }
524 #endif
525
526   template<typename _CharT, typename _InIter>
527     _InIter
528     num_get<_CharT, _InIter>::
529     do_get(iter_type __beg, iter_type __end, ios_base& __io, 
530            ios_base::iostate& __err, float& __v) const
531     {
532       string __xtrc;
533       __xtrc.reserve(32);
534       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
535       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
536       return __beg;
537     }
538
539   template<typename _CharT, typename _InIter>
540     _InIter
541     num_get<_CharT, _InIter>::
542     do_get(iter_type __beg, iter_type __end, ios_base& __io,
543            ios_base::iostate& __err, double& __v) const
544     {
545       string __xtrc;
546       __xtrc.reserve(32);
547       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
548       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
549       return __beg;
550     }
551
552   template<typename _CharT, typename _InIter>
553     _InIter
554     num_get<_CharT, _InIter>::
555     do_get(iter_type __beg, iter_type __end, ios_base& __io,
556            ios_base::iostate& __err, long double& __v) const
557     {
558       string __xtrc;
559       __xtrc.reserve(32);
560       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
561       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
562       return __beg;
563     }
564
565   template<typename _CharT, typename _InIter>
566     _InIter
567     num_get<_CharT, _InIter>::
568     do_get(iter_type __beg, iter_type __end, ios_base& __io,
569            ios_base::iostate& __err, void*& __v) const
570     {
571       // Prepare for hex formatted input
572       typedef ios_base::fmtflags        fmtflags;
573       fmtflags __fmt = __io.flags();
574       fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
575                              | ios_base::uppercase | ios_base::internal);
576       __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
577
578       string __xtrc;
579       int __base;
580       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
581
582       // Reset from hex formatted input
583       __io.flags(__fmt);
584
585       unsigned long __ul;
586       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
587       if (!(__err & ios_base::failbit))
588         __v = reinterpret_cast<void*>(__ul);
589       else 
590         __err |= ios_base::failbit;
591       return __beg;
592     }
593
594
595   // The following code uses sprintf() to convert floating point
596   // values for insertion into a stream.  An optimization would be to
597   // replace sprintf() with code that works directly on a wide buffer
598   // and then use __pad to do the padding. It would be good
599   // to replace sprintf() anyway to avoid accidental buffer overruns
600   // and to gain back the efficiency that C++ provides by knowing up
601   // front the type of the values to insert. This implementation
602   // follows the C++ standard fairly directly as outlined in 22.2.2.2
603   // [lib.locale.num.put]
604   template<typename _CharT, typename _OutIter>
605     template<typename _ValueT>
606       _OutIter
607       num_put<_CharT, _OutIter>::
608       _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
609                        _ValueT __v) const
610       {
611         const int __max_digits = numeric_limits<_ValueT>::digits10;
612         streamsize __prec = __io.precision();
613         // Protect against sprintf() buffer overflows.
614         if (__prec > static_cast<streamsize>(__max_digits))
615           __prec = static_cast<streamsize>(__max_digits);
616
617         // Long enough for the max format spec.
618         char __fbuf[16];
619
620         // Consider the possibility of long ios_base::fixed outputs
621         const bool __fixed = __io.flags() & ios_base::fixed;
622         const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
623         // ios_base::fixed outputs may need up to __max_exp+1 chars
624         // for the integer part + up to __max_digits chars for the
625         // fractional part + 3 chars for sign, decimal point, '\0'. On
626         // the other hand, for non-fixed outputs __max_digits*3 chars
627         // are largely sufficient.
628         const int __cs_size = __fixed ? __max_exp + __max_digits + 4 
629                                       : __max_digits * 3;
630         char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
631
632         int __len;
633         // [22.2.2.2.2] Stage 1, numeric conversion to character.
634         if (_S_format_float(__io, __fbuf, __mod, __prec))
635           __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale, __prec);
636         else
637           __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
638         return _M_widen_float(__s, __io, __fill, __cs, __len);
639       }
640
641   template<typename _CharT, typename _OutIter>
642     template<typename _ValueT>
643       _OutIter
644       num_put<_CharT, _OutIter>::
645       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
646                      char __modl, _ValueT __v) const
647       {
648         // [22.2.2.2.2] Stage 1, numeric conversion to character.
649         // Leave room for "+/-," "0x," and commas. This size is
650         // arbitrary, but should work.
651         char __cs[64];
652         // Long enough for the max format spec.
653         char __fbuf[16];
654         _S_format_int(__io, __fbuf, __mod, __modl);
655         int __len = __convert_from_v(__cs, __fbuf, __v, _S_c_locale);
656         return _M_widen_int(__s, __io, __fill, __cs, __len);
657       }
658
659   template<typename _CharT, typename _OutIter>
660     _OutIter
661     num_put<_CharT, _OutIter>::
662     _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
663                    int __len) const
664     {
665       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
666       // numpunct.decimal_point() values for '.' and adding grouping.
667       const locale __loc = __io.getloc();
668       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
669       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
670                                                            * __len));
671       // Grouping can add (almost) as many separators as the number of
672       // digits, but no more.
673       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
674                                                             * __len * 2));
675       __ctype.widen(__cs, __cs + __len, __ws);
676       
677       // Replace decimal point.
678       const _CharT* __p;
679       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
680       if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
681         __ws[__p - __ws] = __np.decimal_point();
682
683 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
684 //282. What types does numpunct grouping refer to?
685       // Add grouping, if necessary. 
686       const string __grouping = __np.grouping();
687       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
688       if (__grouping.size())
689         {
690           _CharT* __p2;
691           int __declen = __p ? __p - __ws : __len;
692           __p2 = __add_grouping(__ws2, __np.thousands_sep(), 
693                                 __grouping.c_str(),
694                                 __grouping.c_str() + __grouping.size(),
695                                 __ws, __ws + __declen);
696           int __newlen = __p2 - __ws2;
697         
698           // Tack on decimal part.
699           if (__p)
700             {
701               char_traits<_CharT>::copy(__p2, __p, __len - __declen);
702               __newlen += __len - __declen;
703             }    
704
705           // Switch strings, establish correct new length.
706           __ws = __ws2;
707           __len = __newlen;
708         }
709 #endif
710       return _M_insert(__s, __io, __fill, __ws, __len);
711     }
712
713   template<typename _CharT, typename _OutIter>
714     _OutIter
715     num_put<_CharT, _OutIter>::
716     _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
717                  int __len) const
718     {
719       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
720       // numpunct.decimal_point() values for '.' and adding grouping.
721       const locale __loc = __io.getloc();
722       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
723       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
724                                                            * __len));
725       // Grouping can add (almost) as many separators as the number of
726       // digits, but no more.
727       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
728                                                             * __len * 2));
729       __ctype.widen(__cs, __cs + __len, __ws);
730
731       // Add grouping, if necessary.
732       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
733       const string __grouping = __np.grouping();
734       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
735       bool __dec = __basefield != ios_base::oct 
736                    && __basefield != ios_base::hex;
737       if (__grouping.size() && __dec)
738         {
739           _CharT* __p;
740           __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
741                                __grouping.c_str() + __grouping.size(),
742                                __ws, __ws + __len);
743           __len = __p - __ws2;
744           // Switch strings.
745           __ws = __ws2;
746         }
747       return _M_insert(__s, __io, __fill, __ws, __len);
748     }
749
750   // For use by integer and floating-point types after they have been
751   // converted into a char_type string.
752   template<typename _CharT, typename _OutIter>
753     _OutIter
754     num_put<_CharT, _OutIter>::
755     _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, 
756               int __len) const
757     {
758       // [22.2.2.2.2] Stage 3.
759       streamsize __w = __io.width();
760       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
761                                                             * __w));
762       if (__w > static_cast<streamsize>(__len))
763         {
764           __pad(__io, __fill, __ws2, __ws, __w, __len, true);
765           __len = static_cast<int>(__w);
766           // Switch strings.
767           __ws = __ws2;
768         }
769       __io.width(0);
770
771       // [22.2.2.2.2] Stage 4.
772       // Write resulting, fully-formatted string to output iterator.
773       for (int __j = 0; __j < __len; ++__j, ++__s)
774         *__s = __ws[__j];
775       return __s;
776     }
777
778   template<typename _CharT, typename _OutIter>
779     _OutIter
780     num_put<_CharT, _OutIter>::
781     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
782     {
783       ios_base::fmtflags __flags = __io.flags();
784       if ((__flags & ios_base::boolalpha) == 0)
785         {
786           unsigned long __uv = __v;
787           __s = _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
788         }
789       else
790         {
791           locale __loc = __io.getloc();
792           const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
793           const char_type* __ws;
794           int __len;
795           if (__v)
796             {
797               __ws = __np.truename().c_str();
798               __len = __np.truename().size();
799             }
800           else
801             {
802               __ws = __np.falsename().c_str();
803               __len = __np.falsename().size();
804             }
805           __s = _M_insert(__s, __io, __fill, __ws, __len); 
806         }
807       return __s;
808     }
809
810   template<typename _CharT, typename _OutIter>
811     _OutIter
812     num_put<_CharT, _OutIter>::
813     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
814     { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
815
816   template<typename _CharT, typename _OutIter>
817     _OutIter
818     num_put<_CharT, _OutIter>::
819     do_put(iter_type __s, ios_base& __io, char_type __fill,
820            unsigned long __v) const
821     { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
822
823 #ifdef _GLIBCPP_USE_LONG_LONG
824   template<typename _CharT, typename _OutIter>
825     _OutIter
826     num_put<_CharT, _OutIter>::
827     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
828     { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
829
830   template<typename _CharT, typename _OutIter>
831     _OutIter
832     num_put<_CharT, _OutIter>::
833     do_put(iter_type __s, ios_base& __io, char_type __fill,
834            unsigned long long __v) const
835     { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
836 #endif
837
838   template<typename _CharT, typename _OutIter>
839     _OutIter
840     num_put<_CharT, _OutIter>::
841     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
842     { return _M_convert_float(__s, __io, __fill, char_type(), __v); }
843
844   template<typename _CharT, typename _OutIter>
845     _OutIter
846     num_put<_CharT, _OutIter>::
847     do_put(iter_type __s, ios_base& __io, char_type __fill, 
848            long double __v) const
849     { return _M_convert_float(__s, __io, __fill, 'L', __v); }
850
851   template<typename _CharT, typename _OutIter>
852     _OutIter
853     num_put<_CharT, _OutIter>::
854     do_put(iter_type __s, ios_base& __io, char_type __fill,
855            const void* __v) const
856     {
857       ios_base::fmtflags __flags = __io.flags();
858       ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
859                                    | ios_base::uppercase | ios_base::internal);
860       __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
861       try 
862         {
863           __s = _M_convert_int(__s, __io, __fill, 'u', char_type(),
864                                reinterpret_cast<unsigned long>(__v));
865           __io.flags(__flags);
866         }
867       catch (...) 
868         {
869           __io.flags(__flags);
870           __throw_exception_again;
871         }
872       return __s;
873     }
874
875
876   template<typename _CharT, typename _InIter>
877     _InIter
878     money_get<_CharT, _InIter>::
879     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
880            ios_base::iostate& __err, long double& __units) const
881     { 
882       string_type __str;
883       __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); 
884
885       const int __n = numeric_limits<long double>::digits10;
886       char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
887       const locale __loc = __io.getloc();
888       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
889       const _CharT* __wcs = __str.c_str();
890       __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
891       __convert_to_v(__cs, __units, __err, _S_c_locale);
892       return __beg;
893     }
894
895   template<typename _CharT, typename _InIter>
896     _InIter
897     money_get<_CharT, _InIter>::
898     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
899            ios_base::iostate& __err, string_type& __units) const
900     { 
901       // These contortions are quite unfortunate.
902       typedef moneypunct<_CharT, true>          __money_true;
903       typedef moneypunct<_CharT, false>         __money_false;
904       typedef money_base::part                  part;
905       typedef typename string_type::size_type   size_type;
906
907       const locale __loc = __io.getloc();
908       const __money_true& __mpt = use_facet<__money_true>(__loc); 
909       const __money_false& __mpf = use_facet<__money_false>(__loc); 
910       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
911
912       const money_base::pattern __p = __intl ? __mpt.neg_format() 
913                                              : __mpf.neg_format();
914
915       const string_type __pos_sign =__intl ? __mpt.positive_sign() 
916                                            : __mpf.positive_sign();
917       const string_type __neg_sign =__intl ? __mpt.negative_sign() 
918                                            : __mpf.negative_sign();
919       const char_type __d = __intl ? __mpt.decimal_point() 
920                                    : __mpf.decimal_point();
921       const char_type __sep = __intl ? __mpt.thousands_sep() 
922                                      : __mpf.thousands_sep();
923
924       const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
925
926       // Set to deduced positive or negative sign, depending.
927       string_type __sign;
928       // String of grouping info from thousands_sep plucked from __units.
929       string __grouping_tmp; 
930       // Marker for thousands_sep position.
931       int __sep_pos = 0;
932       // If input iterator is in a valid state.
933       bool __testvalid = true;
934       // Flag marking when a decimal point is found.
935       bool __testdecfound = false; 
936
937       char_type __c = *__beg;
938       char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
939       for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
940         {
941           part __which = static_cast<part>(__p.field[__i]);
942           switch (__which)
943                 {
944                 case money_base::symbol:
945                   if (__io.flags() & ios_base::showbase)
946                     {
947                       // Symbol is required.
948                       const string_type __symbol = __intl ? __mpt.curr_symbol()
949                                                          : __mpf.curr_symbol();
950                       size_type __len = __symbol.size();
951                       size_type __i = 0;
952                       while (__beg != __end 
953                              && __i < __len && __symbol[__i] == __c)
954                         {
955                           __c = *(++__beg);
956                           ++__i;
957                         }
958                       if (__i != __len)
959                         __testvalid = false;
960                     }
961                   break;
962                 case money_base::sign:              
963                   // Sign might not exist, or be more than one character long. 
964                   if (__pos_sign.size() && __neg_sign.size())
965                   {
966                     // Sign is mandatory.
967                     if (__c == __pos_sign[0])
968                       {
969                         __sign = __pos_sign;
970                         __c = *(++__beg);
971                       }
972                     else if (__c == __neg_sign[0])
973                       {
974                         __sign = __neg_sign;
975                         __c = *(++__beg);
976                       }
977                     else
978                       __testvalid = false;
979                   }
980                   else if (__pos_sign.size() && __c == __pos_sign[0])
981                     {
982                       __sign = __pos_sign;
983                       __c = *(++__beg);
984                     }
985                   else if (__neg_sign.size() && __c == __neg_sign[0])
986                     {
987                       __sign = __neg_sign;
988                       __c = *(++__beg);
989                     }
990                   break;
991                 case money_base::value:
992                   // Extract digits, remove and stash away the
993                   // grouping of found thousands separators.
994                   while (__beg != __end 
995                          && (__ctype.is(ctype_base::digit, __c) 
996                              || (__c == __d && !__testdecfound)
997                              || __c == __sep))
998                     {
999                       if (__c == __d)
1000                         {
1001                           __grouping_tmp += static_cast<char>(__sep_pos);
1002                           __sep_pos = 0;
1003                           __testdecfound = true;
1004                         }
1005                       else if (__c == __sep)
1006                         {
1007                           if (__grouping.size())
1008                             {
1009                               // Mark position for later analysis.
1010                               __grouping_tmp += static_cast<char>(__sep_pos);
1011                               __sep_pos = 0;
1012                             }
1013                           else
1014                             {
1015                               __testvalid = false;
1016                               break;
1017                             }
1018                         }
1019                       else
1020                         {
1021                           __units += __c;
1022                           ++__sep_pos;
1023                         }
1024                       __c = *(++__beg);
1025                     }
1026                   break;
1027                 case money_base::space:
1028                 case money_base::none:
1029                   // Only if not at the end of the pattern.
1030                   if (__i != 3)
1031                     while (__beg != __end 
1032                            && __ctype.is(ctype_base::space, __c))
1033                       __c = *(++__beg);
1034                   break;
1035                 }
1036         }
1037
1038       // Need to get the rest of the sign characters, if they exist.
1039       if (__sign.size() > 1)
1040         {
1041           size_type __len = __sign.size();
1042           size_type __i = 1;
1043           for (; __c != __eof && __i < __len; ++__i)
1044             while (__beg != __end && __c != __sign[__i])
1045               __c = *(++__beg);
1046           
1047           if (__i != __len)
1048             __testvalid = false;
1049         }
1050
1051       // Strip leading zeros.
1052       while (__units[0] == __ctype.widen('0'))
1053         __units.erase(__units.begin());
1054
1055       if (__sign.size() && __sign == __neg_sign)
1056         __units.insert(__units.begin(), __ctype.widen('-'));
1057
1058       // Test for grouping fidelity.
1059       if (__grouping.size() && __grouping_tmp.size())
1060         {
1061           if (!__verify_grouping(__grouping, __grouping_tmp))
1062             __testvalid = false;
1063         }
1064
1065       // Iff no more characters are available.      
1066       if (__c == __eof)
1067         __err |= ios_base::eofbit;
1068
1069       // Iff valid sequence is not recognized.
1070       if (!__testvalid || !__units.size())
1071         __err |= ios_base::failbit;
1072       return __beg; 
1073     }
1074
1075   template<typename _CharT, typename _OutIter>
1076     _OutIter
1077     money_put<_CharT, _OutIter>::
1078     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1079            long double __units) const
1080     { 
1081       const locale __loc = __io.getloc();
1082       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
1083       const int __n = numeric_limits<long double>::digits10;
1084       char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
1085       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1086       int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale);
1087       __ctype.widen(__cs, __cs + __len, __ws);
1088       string_type __digits(__ws);
1089       return this->do_put(__s, __intl, __io, __fill, __digits); 
1090     }
1091
1092   template<typename _CharT, typename _OutIter>
1093     _OutIter
1094     money_put<_CharT, _OutIter>::
1095     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1096            const string_type& __digits) const
1097     { 
1098       typedef typename string_type::size_type   size_type;
1099       typedef money_base::part                  part;
1100
1101       const locale __loc = __io.getloc();
1102       const size_type __width = static_cast<size_type>(__io.width());
1103
1104       // These contortions are quite unfortunate.
1105       typedef moneypunct<_CharT, true> __money_true;
1106       typedef moneypunct<_CharT, false> __money_false;
1107       const __money_true& __mpt = use_facet<__money_true>(__loc); 
1108       const __money_false& __mpf = use_facet<__money_false>(__loc); 
1109       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
1110
1111       // Determine if negative or positive formats are to be used, and
1112       // discard leading negative_sign if it is present.
1113       const char_type* __beg = __digits.data();
1114       const char_type* __end = __beg + __digits.size();
1115       money_base::pattern __p;
1116       string_type __sign;
1117       if (*__beg != __ctype.widen('-'))
1118         {
1119           __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
1120           __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
1121         }
1122       else
1123         {
1124           __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
1125           __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
1126           ++__beg;
1127         }
1128       
1129       // Look for valid numbers in the current ctype facet within input digits.
1130       __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
1131       if (__beg != __end)
1132         {
1133           // Assume valid input, and attempt to format.
1134           // Break down input numbers into base components, as follows:
1135           //   final_value = grouped units + (decimal point) + (digits)
1136           string_type __res;
1137           string_type __value;
1138           const string_type __symbol = __intl ? __mpt.curr_symbol() 
1139                                               : __mpf.curr_symbol();
1140
1141           // Deal with decimal point, decimal digits.
1142           const int __frac = __intl ? __mpt.frac_digits() 
1143                                     : __mpf.frac_digits();
1144           if (__frac > 0)
1145             {
1146               const char_type __d = __intl ? __mpt.decimal_point() 
1147                                            : __mpf.decimal_point();
1148               if (__end - __beg >= __frac)
1149                 {
1150                   __value = string_type(__end - __frac, __end);
1151                   __value.insert(__value.begin(), __d);
1152                   __end -= __frac;
1153                 }
1154               else
1155                 {
1156                   // Have to pad zeros in the decimal position.
1157                   __value = string_type(__beg, __end);
1158                   int __paddec = __frac - (__end - __beg);
1159                   char_type __zero = __ctype.widen('0');
1160                   __value.insert(__value.begin(), __paddec, __zero);
1161                   __value.insert(__value.begin(), __d);
1162                   __beg = __end;
1163                 }
1164             }
1165
1166           // Add thousands separators to non-decimal digits, per
1167           // grouping rules.
1168           if (__beg != __end)
1169             {
1170               const string __grouping = __intl ? __mpt.grouping() 
1171                                                : __mpf.grouping();
1172               if (__grouping.size())
1173                 {
1174                   const char_type __sep = __intl ? __mpt.thousands_sep() 
1175                                                  : __mpf.thousands_sep();
1176                   const char* __gbeg = __grouping.c_str();
1177                   const char* __gend = __gbeg + __grouping.size();
1178                   const int __n = numeric_limits<long double>::digits10 * 2;
1179                   _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
1180                   _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
1181                                                     __gend, __beg, __end);
1182                   __value.insert(0, __ws2, __ws_end - __ws2);
1183                 }
1184               else
1185                 __value.insert(0, string_type(__beg, __end));
1186             }
1187
1188           // Calculate length of resulting string.
1189           ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
1190           size_type __len = __value.size() + __sign.size();
1191           __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
1192           bool __testipad = __f == ios_base::internal && __len < __width;
1193
1194           // Fit formatted digits into the required pattern.
1195           for (int __i = 0; __i < 4; ++__i)
1196             {
1197               part __which = static_cast<part>(__p.field[__i]);
1198               switch (__which)
1199                 {
1200                 case money_base::symbol:
1201                   if (__io.flags() & ios_base::showbase)
1202                     __res += __symbol;
1203                   break;
1204                 case money_base::sign:              
1205                   // Sign might not exist, or be more than one
1206                   // charater long. In that case, add in the rest
1207                   // below.
1208                   if (__sign.size())
1209                     __res += __sign[0];
1210                   break;
1211                 case money_base::value:
1212                   __res += __value;
1213                   break;
1214                 case money_base::space:
1215                   // At least one space is required, but if internal
1216                   // formatting is required, an arbitrary number of
1217                   // fill spaces will be necessary.
1218                   if (__testipad)
1219                     __res += string_type(__width - __len, __fill);
1220                   else
1221                     __res += __ctype.widen(' ');
1222                   break;
1223                 case money_base::none:
1224                   if (__testipad)
1225                     __res += string_type(__width - __len, __fill);
1226                   break;
1227                 }
1228             }
1229
1230           // Special case of multi-part sign parts.
1231           if (__sign.size() > 1)
1232             __res += string_type(__sign.begin() + 1, __sign.end());
1233
1234           // Pad, if still necessary.
1235           __len = __res.size();
1236           if (__width > __len)
1237             {
1238               if (__f == ios_base::left)
1239                 // After.
1240                 __res.append(__width - __len, __fill);
1241               else
1242                 // Before.
1243                 __res.insert(0, string_type(__width - __len, __fill));
1244               __len = __width;
1245             }
1246
1247           // Write resulting, fully-formatted string to output iterator.
1248           for (size_type __j = 0; __j < __len; ++__j, ++__s)
1249             *__s = __res[__j];
1250         }
1251       __io.width(0);
1252       return __s; 
1253     }
1254
1255
1256   // NB: Not especially useful. Without an ios_base object or some
1257   // kind of locale reference, we are left clawing at the air where
1258   // the side of the mountain used to be...
1259   template<typename _CharT, typename _InIter>
1260     time_base::dateorder
1261     time_get<_CharT, _InIter>::do_date_order() const
1262     { return time_base::no_order; }
1263
1264   template<typename _CharT, typename _InIter>
1265     void
1266     time_get<_CharT, _InIter>::
1267     _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
1268                           ios_base::iostate& __err, tm* __tm, 
1269                           const _CharT* __format) const
1270     {  
1271       locale __loc = __io.getloc();
1272       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1273       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
1274       size_t __len = char_traits<_CharT>::length(__format);
1275
1276       for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
1277         {
1278           char __c = __format[__i];
1279           if (__c == '%')
1280             {
1281               // Verify valid formatting code, attempt to extract.
1282               __c = __format[++__i];
1283               char __mod = 0;
1284               int __mem = 0; 
1285               if (__c == 'E' || __c == 'O')
1286                 {
1287                   __mod = __c;
1288                   __c = __format[++__i];
1289                 }
1290               switch (__c)
1291                 {
1292                   const char* __cs;
1293                   _CharT __wcs[10];
1294                 case 'a':
1295                   // Abbreviated weekday name [tm_wday]
1296                   const char_type*  __days1[7];
1297                   __tp._M_days_abbreviated(__days1);
1298                   _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, 
1299                                   __err);
1300                   break;
1301                 case 'A':
1302                   // Weekday name [tm_wday].
1303                   const char_type*  __days2[7];
1304                   __tp._M_days(__days2);
1305                   _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, 
1306                                   __err);
1307                   break;
1308                 case 'h':
1309                 case 'b':
1310                   // Abbreviated month name [tm_mon]
1311                   const char_type*  __months1[12];
1312                   __tp._M_months_abbreviated(__months1);
1313                   _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, 
1314                                   __err);
1315                   break;
1316                 case 'B':
1317                   // Month name [tm_mon].
1318                   const char_type*  __months2[12];
1319                   __tp._M_months(__months2);
1320                   _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, 
1321                                   __err);
1322                   break;
1323                 case 'c':
1324                   // Default time and date representation.
1325                   const char_type*  __dt[2];
1326                   __tp._M_date_time_formats(__dt);
1327                   _M_extract_via_format(__beg, __end, __io, __err, __tm, 
1328                                         __dt[0]);
1329                   break;
1330                 case 'd':
1331                   // Day [01, 31]. [tm_mday]
1332                   _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 
1333                                  __ctype, __err);
1334                   break;
1335                 case 'D':
1336                   // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1337                   __cs = "%m/%d/%y";
1338                   __ctype.widen(__cs, __cs + 9, __wcs);
1339                   _M_extract_via_format(__beg, __end, __io, __err, __tm, 
1340                                         __wcs);
1341                   break;
1342                 case 'H':
1343                   // Hour [00, 23]. [tm_hour]
1344                   _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1345                                  __ctype, __err);
1346                   break;
1347                 case 'I':
1348                   // Hour [01, 12]. [tm_hour]
1349                   _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, 
1350                                  __ctype, __err);
1351                   break;
1352                 case 'm':
1353                   // Month [01, 12]. [tm_mon]
1354                   _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype, 
1355                                  __err);
1356                   if (!__err)
1357                     __tm->tm_mon = __mem - 1;
1358                   break;
1359                 case 'M':
1360                   // Minute [00, 59]. [tm_min]
1361                   _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1362                                  __ctype, __err);
1363                   break;
1364                 case 'n':
1365                   if (__ctype.narrow(*__beg, 0) == '\n')
1366                     ++__beg;
1367                   else
1368                     __err |= ios_base::failbit;
1369                   break;
1370                 case 'R':
1371                   // Equivalent to (%H:%M).
1372                   __cs = "%H:%M";
1373                   __ctype.widen(__cs, __cs + 6, __wcs);
1374                   _M_extract_via_format(__beg, __end, __io, __err, __tm, 
1375                                         __wcs);
1376                   break;
1377                 case 'S':
1378                   // Seconds.
1379                   _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
1380                                  __ctype, __err);
1381                   break;
1382                 case 't':
1383                   if (__ctype.narrow(*__beg, 0) == '\t')
1384                     ++__beg;
1385                   else
1386                 __err |= ios_base::failbit;
1387                   break;
1388                 case 'T':
1389                   // Equivalent to (%H:%M:%S).
1390                   __cs = "%H:%M:%S";
1391                   __ctype.widen(__cs, __cs + 9, __wcs);
1392                   _M_extract_via_format(__beg, __end, __io, __err, __tm, 
1393                                         __wcs);
1394                   break;
1395                 case 'x':
1396                   // Locale's date.
1397                   const char_type*  __dates[2];
1398                   __tp._M_date_formats(__dates);
1399                   _M_extract_via_format(__beg, __end, __io, __err, __tm, 
1400                                         __dates[0]);
1401                   break;
1402                 case 'X':
1403                   // Locale's time.
1404                   const char_type*  __times[2];
1405                   __tp._M_time_formats(__times);
1406                   _M_extract_via_format(__beg, __end, __io, __err, __tm, 
1407                                         __times[0]);
1408                   break;
1409                 case 'y':
1410                   // Two digit year. [tm_year]
1411                   _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, 
1412                                  __ctype, __err);
1413                   break;
1414                 case 'Y':
1415                   // Year [1900). [tm_year]
1416                   _M_extract_num(__beg, __end, __mem, 0, 
1417                                  numeric_limits<int>::max(), 4, 
1418                                  __ctype, __err);
1419                   if (!__err)
1420                     __tm->tm_year = __mem - 1900;
1421                   break;
1422                 case 'Z':
1423                   // Timezone info.
1424                   if (__ctype.is(ctype_base::upper, *__beg))
1425                     {
1426                       int __tmp;
1427                       _M_extract_name(__beg, __end, __tmp, 
1428                                       __timepunct<_CharT>::_S_timezones, 
1429                                       14, __err);
1430                       
1431                       // GMT requires special effort.
1432                       char_type __c = *__beg;
1433                       if (!__err && __tmp == 0 
1434                           && (__c == __ctype.widen('-') 
1435                               || __c == __ctype.widen('+')))
1436                         {
1437                           _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1438                                           __ctype, __err);
1439                           _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1440                                           __ctype, __err);
1441                         }           
1442                           }
1443                       else
1444                         __err |= ios_base::failbit;
1445                       break;
1446                     default:
1447                       // Not recognized.
1448                       __err |= ios_base::failbit;
1449                     }
1450                 }
1451               else
1452                 {
1453                   // Verify format and input match, extract and discard.
1454                   if (__c == __ctype.narrow(*__beg, 0))
1455                     ++__beg;
1456                   else
1457                     __err |= ios_base::failbit;
1458                 }
1459         }
1460     }
1461
1462   template<typename _CharT, typename _InIter>
1463     void
1464     time_get<_CharT, _InIter>::
1465     _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
1466                    int __min, int __max, size_t __len, 
1467                    const ctype<_CharT>& __ctype, 
1468                    ios_base::iostate& __err) const
1469     {
1470       size_t __i = 0;
1471       string __digits;
1472       bool __testvalid = true;
1473       char_type __c = *__beg;
1474       while (__beg != __end && __i < __len 
1475              && __ctype.is(ctype_base::digit, __c)) 
1476         {
1477           __digits += __ctype.narrow(__c, 0);
1478           __c = *(++__beg);
1479           ++__i;
1480         }
1481       if (__i == __len)
1482         {
1483           int __value = atoi(__digits.c_str());
1484           if (__min <= __value && __value <= __max)
1485             __member = __value;
1486           else
1487             __testvalid = false;
1488         }
1489       else
1490         __testvalid = false;
1491       if (!__testvalid)
1492         __err |= ios_base::failbit;
1493     }
1494
1495   // Assumptions:
1496   // All elements in __names are unique.
1497   template<typename _CharT, typename _InIter>
1498     void
1499     time_get<_CharT, _InIter>::
1500     _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
1501                     const _CharT** __names, size_t __indexlen, 
1502                     ios_base::iostate& __err) const
1503     {
1504       typedef char_traits<char_type> __traits_type;
1505       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen));
1506       size_t __nmatches = 0;
1507       size_t __pos = 0;
1508       bool __testvalid = true;
1509       const char_type* __name;
1510
1511       char_type __c = *__beg;
1512       // Look for initial matches.
1513       for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
1514         if (__c == __names[__i1][0])
1515           __matches[__nmatches++] = __i1;
1516       
1517       while(__nmatches > 1)
1518         {
1519           // Find smallest matching string.
1520           size_t __minlen = 10;
1521           for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
1522             __minlen = min(__minlen, 
1523                            __traits_type::length(__names[__matches[__i2]]));
1524           
1525           if (__pos < __minlen && __beg != __end)
1526             {
1527               ++__pos;
1528               __c = *(++__beg);
1529               for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
1530                 {
1531                   __name = __names[__matches[__i3]];
1532                   if (__name[__pos] != __c)
1533                     __matches[__i3] = __matches[--__nmatches];
1534                 }
1535             }
1536           else
1537             break;
1538         }
1539
1540       if (__nmatches == 1)
1541         {
1542           // Make sure found name is completely extracted.
1543           __name = __names[__matches[0]];
1544           const size_t __len = __traits_type::length(__name);
1545           while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
1546             ++__beg, ++__pos;
1547
1548           if (__len == __pos)
1549             __member = __matches[0];
1550           else
1551             __testvalid = false;
1552         }
1553       else
1554         __testvalid = false;
1555       if (!__testvalid)
1556         __err |= ios_base::failbit;
1557     }
1558
1559   template<typename _CharT, typename _InIter>
1560     _InIter
1561     time_get<_CharT, _InIter>::
1562     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1563                 ios_base::iostate& __err, tm* __tm) const
1564     {
1565       _CharT __wcs[3];
1566       const char* __cs = "%X";
1567       locale __loc = __io.getloc();
1568       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1569       __ctype.widen(__cs, __cs + 3, __wcs);
1570       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1571       if (__beg == __end)
1572         __err |= ios_base::eofbit;
1573       return __beg;
1574     }
1575
1576   template<typename _CharT, typename _InIter>
1577     _InIter
1578     time_get<_CharT, _InIter>::
1579     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1580                 ios_base::iostate& __err, tm* __tm) const
1581     {
1582       _CharT __wcs[3];
1583       const char* __cs = "%x";
1584       locale __loc = __io.getloc();
1585       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1586       __ctype.widen(__cs, __cs + 3, __wcs);
1587       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1588       if (__beg == __end)
1589         __err |= ios_base::eofbit;
1590       return __beg;
1591     }
1592
1593   template<typename _CharT, typename _InIter>
1594     _InIter
1595     time_get<_CharT, _InIter>::
1596     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 
1597                    ios_base::iostate& __err, tm* __tm) const
1598     {
1599       typedef char_traits<char_type> __traits_type;
1600       locale __loc = __io.getloc();
1601       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1602       const char_type*  __days[7];
1603       __tp._M_days_abbreviated(__days);
1604       int __tmpwday;
1605       _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
1606
1607       // Check to see if non-abbreviated name exists, and extract.
1608       // NB: Assumes both _M_days and _M_days_abbreviated organized in
1609       // exact same order, first to last, such that the resulting
1610       // __days array with the same index points to a day, and that
1611       // day's abbreviated form.
1612       // NB: Also assumes that an abbreviated name is a subset of the name. 
1613       if (!__err)
1614         {
1615           size_t __pos = __traits_type::length(__days[__tmpwday]);
1616           __tp._M_days(__days);
1617           const char_type* __name = __days[__tmpwday];
1618           if (__name[__pos] == *__beg)
1619             {
1620               // Extract the rest of it.
1621               const size_t __len = __traits_type::length(__name);
1622               while (__pos < __len && __beg != __end 
1623                      && __name[__pos] == *__beg)
1624                 ++__beg, ++__pos;
1625               if (__len != __pos)
1626                 __err |= ios_base::failbit;
1627             }
1628           if (!__err)
1629             __tm->tm_wday = __tmpwday;
1630         }
1631       if (__beg == __end)
1632         __err |= ios_base::eofbit;
1633       return __beg;
1634      }
1635
1636   template<typename _CharT, typename _InIter>
1637     _InIter
1638     time_get<_CharT, _InIter>::
1639     do_get_monthname(iter_type __beg, iter_type __end,
1640                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1641     {
1642       typedef char_traits<char_type> __traits_type;
1643       locale __loc = __io.getloc();
1644       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1645       const char_type*  __months[12];
1646       __tp._M_months_abbreviated(__months);
1647       int __tmpmon;
1648       _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
1649
1650       // Check to see if non-abbreviated name exists, and extract.
1651       // NB: Assumes both _M_months and _M_months_abbreviated organized in
1652       // exact same order, first to last, such that the resulting
1653       // __months array with the same index points to a month, and that
1654       // month's abbreviated form.
1655       // NB: Also assumes that an abbreviated name is a subset of the name. 
1656       if (!__err)
1657         {
1658           size_t __pos = __traits_type::length(__months[__tmpmon]);
1659           __tp._M_months(__months);
1660           const char_type* __name = __months[__tmpmon];
1661           if (__name[__pos] == *__beg)
1662             {
1663               // Extract the rest of it.
1664               const size_t __len = __traits_type::length(__name);
1665               while (__pos < __len && __beg != __end 
1666                      && __name[__pos] == *__beg)
1667                 ++__beg, ++__pos;
1668               if (__len != __pos)
1669                 __err |= ios_base::failbit;
1670             }
1671           if (!__err)
1672             __tm->tm_mon = __tmpmon;
1673         }
1674  
1675       if (__beg == __end)
1676         __err |= ios_base::eofbit;
1677       return __beg;
1678     }
1679
1680   template<typename _CharT, typename _InIter>
1681     _InIter
1682     time_get<_CharT, _InIter>::
1683     do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 
1684                 ios_base::iostate& __err, tm* __tm) const
1685     {
1686       locale __loc = __io.getloc();
1687       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
1688
1689       char_type __c = *__beg;
1690       size_t __i = 0;
1691       string __digits;
1692       while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
1693         {
1694           __digits += __ctype.narrow(__c, 0);
1695           __c = *(++__beg);
1696           ++__i;
1697         }
1698       if (__i == 2 || __i == 4)
1699         {
1700           long __l;
1701           __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
1702           if (!(__err & ios_base::failbit) && __l <= INT_MAX)
1703             {
1704               __l = __i == 2 ? __l : __l - 1900; 
1705               __tm->tm_year = static_cast<int>(__l);
1706             }
1707         }
1708       else
1709         __err |= ios_base::failbit;
1710       if (__beg == __end)
1711         __err |= ios_base::eofbit;
1712       return __beg;
1713     }
1714
1715   template<typename _CharT, typename _OutIter>
1716     _OutIter
1717     time_put<_CharT, _OutIter>::
1718     put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
1719         const _CharT* __beg, const _CharT* __end) const
1720     {
1721       locale __loc = __io.getloc();
1722       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1723       while (__beg != __end)
1724         {
1725           char __c = __ctype.narrow(*__beg, 0);
1726           ++__beg;
1727           if (__c == '%')
1728             {
1729               char __format;
1730               char __mod = 0;
1731               size_t __len = 1; 
1732               __c = __ctype.narrow(*__beg, 0);
1733               ++__beg;
1734               if (__c == 'E' || __c == 'O')
1735                 {
1736                   __mod = __c;
1737                   __format = __ctype.narrow(*__beg, 0);
1738                   ++__beg;
1739                 }
1740               else
1741                 __format = __c;
1742               __s = this->do_put(__s, __io, char_type(), __tm, __format, 
1743                                  __mod);
1744             }
1745           else
1746             {
1747               *__s = __c;
1748               ++__s;
1749             }
1750         }
1751       return __s;
1752     }
1753
1754   template<typename _CharT, typename _OutIter>
1755     _OutIter
1756     time_put<_CharT, _OutIter>::
1757     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
1758            char __format, char __mod) const
1759     { 
1760       locale __loc = __io.getloc();
1761       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1762       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1763
1764       // NB: This size is arbitrary. Should this be a data member,
1765       // initialized at construction?
1766       const size_t __maxlen = 64;
1767       char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen));
1768
1769       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
1770       // is possible that the format character will be longer than one
1771       // character. Possibilities include 'E' or 'O' followed by a
1772       // format character: if __mod is not the default argument, assume
1773       // it's a valid modifier.
1774       char_type __fmt[4];
1775       __fmt[0] = __ctype.widen('%'); 
1776       if (!__mod)
1777         {
1778           __fmt[1] = __format;
1779           __fmt[2] = char_type();
1780         }
1781       else
1782         {
1783           __fmt[1] = __mod;
1784           __fmt[2] = __format;
1785           __fmt[3] = char_type();
1786         }
1787
1788       __tp._M_put_helper(__res, __maxlen, __fmt, __tm);
1789
1790       // Write resulting, fully-formatted string to output iterator.
1791       size_t __len = char_traits<char_type>::length(__res);
1792       for (size_t __i = 0; __i < __len; ++__i, ++__s)
1793         *__s = __res[__i];
1794       return __s;
1795     }
1796
1797
1798   // Generic version does nothing.
1799   template<typename _CharT>
1800     int
1801     collate<_CharT>::_M_compare_helper(const _CharT*, const _CharT*) const
1802     { return 0; }
1803
1804   // Generic version does nothing.
1805   template<typename _CharT>
1806     size_t
1807     collate<_CharT>::_M_transform_helper(_CharT*, const _CharT*, size_t) const
1808     { return 0; }
1809
1810   template<typename _CharT>
1811     int
1812     collate<_CharT>::
1813     do_compare(const _CharT* __lo1, const _CharT* __hi1, 
1814                const _CharT* __lo2, const _CharT* __hi2) const
1815     { 
1816       const string_type __one(__lo1, __hi1);
1817       const string_type __two(__lo2, __hi2);
1818       return _M_compare_helper(__one.c_str(), __two.c_str());
1819     }
1820
1821  template<typename _CharT>
1822     typename collate<_CharT>::string_type
1823     collate<_CharT>::
1824     do_transform(const _CharT* __lo, const _CharT* __hi) const
1825     {
1826       size_t __len = __hi - __lo;
1827       _CharT* __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
1828       size_t __res = _M_transform_helper(__c, __lo, __len);
1829       if (__res >= __len)
1830         {
1831           // Try to increment size of translated string.
1832           size_t __len2 = __len * 2;
1833           _CharT* __c2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len2));
1834           __res = _M_transform_helper(__c2, __lo, __len);
1835           // XXX Throw exception if still indeterminate?
1836         }
1837       return string_type(__c);
1838     }
1839
1840  template<typename _CharT>
1841     long
1842     collate<_CharT>::
1843     do_hash(const _CharT* __lo, const _CharT* __hi) const
1844     { 
1845       unsigned long __val = 0;
1846       for (; __lo < __hi; ++__lo)
1847         __val = *__lo + ((__val << 7) | 
1848                        (__val >> (numeric_limits<unsigned long>::digits - 1)));
1849       return static_cast<long>(__val);
1850     }
1851
1852   // Convert string to numeric value of type T and store results.  
1853   // NB: This is specialized for all required types, there is no
1854   // generic definition.
1855   template<typename _T>
1856     void
1857     __convert_to_v(const char* __in, _T& __out, ios_base::iostate& __err, 
1858                    const __c_locale& __cloc, int __base = 10);
1859
1860   // Convert numeric value of type T to string and return length of string.
1861   template<typename _T>
1862     int
1863     __convert_from_v(char* __out, const char* __fmt, _T __v, 
1864                      const __c_locale&, int __prec = -1)
1865     {
1866       int __ret;
1867       const char* __old = setlocale(LC_ALL, "C");
1868       if (__prec >= 0)
1869         __ret = sprintf(__out, __fmt, __prec, __v);
1870       else
1871         __ret = sprintf(__out, __fmt, __v);
1872       setlocale(LC_ALL, __old);
1873       return __ret;
1874     }
1875
1876   // Construct correctly padded string, as per 22.2.2.2.2
1877   // Assumes 
1878   // __newlen > __oldlen
1879   // __news is allocated for __newlen size
1880   // Used by both num_put and ostream inserters: if __num,
1881   // internal-adjusted objects are padded according to the rules below
1882   // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
1883   // ones are.
1884   template<typename _CharT, typename _Traits>
1885     void
1886     __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
1887           const streamsize __newlen, const streamsize __oldlen, 
1888           const bool __num)
1889     {
1890       typedef _CharT    char_type;
1891       typedef _Traits   traits_type;
1892       typedef typename traits_type::int_type int_type;
1893       
1894       int_type __plen = static_cast<size_t>(__newlen - __oldlen); 
1895       char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
1896       traits_type::assign(__pads, __plen, __fill); 
1897
1898       char_type* __beg;
1899       char_type* __end;
1900       size_t __mod = 0;
1901       size_t __beglen; //either __plen or __oldlen
1902       ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
1903
1904       if (__adjust == ios_base::left)
1905         {
1906           // Padding last.
1907           __beg = const_cast<char_type*>(__olds);
1908           __beglen = __oldlen;
1909           __end = __pads;
1910         }
1911       else if (__adjust == ios_base::internal && __num)
1912         {
1913           // Pad after the sign, if there is one.
1914           // Pad after 0[xX], if there is one.
1915           // Who came up with these rules, anyway? Jeeze.
1916           locale __loc = __io.getloc();
1917           const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
1918           const char_type __minus = __ctype.widen('-');
1919           const char_type __plus = __ctype.widen('+');
1920           bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
1921           bool __testhex = __ctype.widen('0') == __olds[0] 
1922                            && (__ctype.widen('x') == __olds[1] 
1923                                || __ctype.widen('X') == __olds[1]);
1924           if (__testhex)
1925             {
1926               __news[0] = __olds[0]; 
1927               __news[1] = __olds[1];
1928               __mod += 2;
1929               __news += 2;
1930               __beg = __pads;
1931               __beglen = __plen;
1932               __end = const_cast<char_type*>(__olds + __mod);
1933             }
1934           else if (__testsign)
1935             {
1936               __news[0] = __olds[0] == __plus ? __plus : __minus;
1937               ++__mod;
1938               ++__news;
1939               __beg = __pads;
1940               __beglen = __plen;
1941               __end = const_cast<char_type*>(__olds + __mod);
1942             }
1943           else
1944             {
1945               // Padding first.
1946               __beg = __pads;
1947               __beglen = __plen;
1948               __end = const_cast<char_type*>(__olds);
1949             }
1950         }
1951       else
1952         {
1953           // Padding first.
1954           __beg = __pads;
1955           __beglen = __plen;
1956           __end = const_cast<char_type*>(__olds);
1957         }
1958       traits_type::copy(__news, __beg, __beglen);
1959       traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
1960     }
1961
1962   // NB: Can't have default argument on non-member template, and
1963   // num_put doesn't have a _Traits template parameter, so this
1964   // forwarding template adds in the default template argument.
1965   template<typename _CharT>
1966     void
1967     __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
1968           const streamsize __newlen, const streamsize __oldlen, 
1969           const bool __num)
1970     { 
1971       return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news, __olds,
1972                                                  __newlen, __oldlen, __num); 
1973     }
1974
1975   // Used by both numeric and monetary facets.
1976   // Check to make sure that the __grouping_tmp string constructed in
1977   // money_get or num_get matches the canonical grouping for a given
1978   // locale.
1979   // __grouping_tmp is parsed L to R
1980   // 1,222,444 == __grouping_tmp of "/1/3/3"
1981   // __grouping is parsed R to L
1982   // 1,222,444 == __grouping of "/3" == "/3/3/3"
1983   template<typename _CharT>
1984     bool
1985     __verify_grouping(const basic_string<_CharT>& __grouping, 
1986                       basic_string<_CharT>& __grouping_tmp)
1987     {         
1988       int __i = 0;
1989       int __j = 0;
1990       const int __len = __grouping.size();
1991       const int __n = __grouping_tmp.size();
1992       bool __test = true;
1993       
1994       // Parsed number groupings have to match the
1995       // numpunct::grouping string exactly, starting at the
1996       // right-most point of the parsed sequence of elements ...
1997       while (__test && __i < __n - 1)
1998         for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
1999           __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
2000       // ... but the last parsed grouping can be <= numpunct
2001       // grouping.
2002       __j == __len ? __j = 0 : __j;
2003       __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
2004       return __test;
2005     }
2006
2007   // Used by both numeric and monetary facets.
2008   // Inserts "group separator" characters into an array of characters.
2009   // It's recursive, one iteration per group.  It moves the characters
2010   // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
2011   // only with __gbeg != __gend.
2012   template<typename _CharT>
2013     _CharT*
2014     __add_grouping(_CharT* __s, _CharT __sep,  
2015                    const char* __gbeg, const char* __gend, 
2016                    const _CharT* __first, const _CharT* __last)
2017     {
2018       if (__last - __first > *__gbeg)
2019         {
2020           __s = __add_grouping(__s,  __sep, 
2021                                (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
2022                                __gend, __first, __last - *__gbeg);
2023           __first = __last - *__gbeg;
2024           *__s++ = __sep;
2025         }
2026       do
2027         *__s++ = *__first++;
2028       while (__first != __last);
2029       return __s;
2030     }
2031 } // namespace std
2032
2033 #endif