OSDN Git Service

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