OSDN Git Service

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