OSDN Git Service

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