OSDN Git Service

2004-02-21 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / locale_facets.tcc
1 // Locale support -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 // Warning: this file is not meant for user inclusion. Use <locale>.
32
33 #ifndef _LOCALE_FACETS_TCC
34 #define _LOCALE_FACETS_TCC 1
35
36 #pragma GCC system_header
37
38 #include <limits>               // For numeric_limits
39 #include <typeinfo>             // For bad_cast.
40 #include <bits/streambuf_iterator.h>
41
42 namespace std
43 {
44   template<typename _Facet>
45     locale
46     locale::combine(const locale& __other) const
47     {
48       _Impl* __tmp = new _Impl(*_M_impl, 1);
49       try
50         {
51           __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
52         }
53       catch(...)
54         {
55           __tmp->_M_remove_reference();
56           __throw_exception_again;
57         }
58       return locale(__tmp);
59     }
60
61   template<typename _CharT, typename _Traits, typename _Alloc>
62     bool
63     locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
64                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
65     {
66       typedef std::collate<_CharT> __collate_type;
67       const __collate_type& __collate = use_facet<__collate_type>(*this);
68       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
69                                 __s2.data(), __s2.data() + __s2.length()) < 0);
70     }
71
72   /**
73    *  @brief  Test for the presence of a facet.
74    *
75    *  has_facet tests the locale argument for the presence of the facet type
76    *  provided as the template parameter.  Facets derived from the facet
77    *  parameter will also return true.
78    *
79    *  @param  Facet  The facet type to test the presence of.
80    *  @param  locale  The locale to test.
81    *  @return  true if locale contains a facet of type Facet, else false.
82    *  @throw  std::bad_cast if locale doesn't contain the facet.
83   */
84   template<typename _Facet>
85     inline bool
86     has_facet(const locale& __loc) throw()
87     {
88       const size_t __i = _Facet::id._M_id();
89       const locale::facet** __facets = __loc._M_impl->_M_facets;
90       return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
91     }
92
93   /**
94    *  @brief  Return a facet.
95    *
96    *  use_facet looks for and returns a reference to a facet of type Facet
97    *  where Facet is the template parameter.  If has_facet(locale) is true,
98    *  there is a suitable facet to return.  It throws std::bad_cast if the
99    *  locale doesn't contain a facet of type Facet.
100    *
101    *  @param  Facet  The facet type to access.
102    *  @param  locale  The locale to use.
103    *  @return  Reference to facet of type Facet.
104    *  @throw  std::bad_cast if locale doesn't contain a facet of type Facet.
105   */
106   template<typename _Facet>
107     inline const _Facet&
108     use_facet(const locale& __loc)
109     {
110       const size_t __i = _Facet::id._M_id();
111       const locale::facet** __facets = __loc._M_impl->_M_facets;
112       if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
113         __throw_bad_cast();
114       return static_cast<const _Facet&>(*__facets[__i]);
115     }
116
117   // Routine to access a cache for the facet.  If the cache didn't
118   // exist before, it gets constructed on the fly.
119   template<typename _Facet>
120     struct __use_cache
121     {
122       const _Facet*
123       operator() (const locale& __loc) const;
124     };
125
126   template<typename _CharT>
127     struct __use_cache<__numpunct_cache<_CharT> >
128     {
129       const __numpunct_cache<_CharT>*
130       operator() (const locale& __loc) const
131       {
132         const size_t __i = numpunct<_CharT>::id._M_id();
133         const locale::facet** __caches = __loc._M_impl->_M_caches;
134         if (!__caches[__i])
135           {
136             __numpunct_cache<_CharT>* __tmp = NULL;
137             try
138               {
139                 __tmp = new __numpunct_cache<_CharT>;
140                 __tmp->_M_cache(__loc);
141               }
142             catch(...)
143               {
144                 delete __tmp;
145                 __throw_exception_again;
146               }
147             __loc._M_impl->_M_install_cache(__tmp, __i);
148           }
149         return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
150       }
151     };
152
153   // Used by both numeric and monetary facets.
154   // Check to make sure that the __grouping_tmp string constructed in
155   // money_get or num_get matches the canonical grouping for a given
156   // locale.
157   // __grouping_tmp is parsed L to R
158   // 1,222,444 == __grouping_tmp of "\1\3\3"
159   // __grouping is parsed R to L
160   // 1,222,444 == __grouping of "\3" == "\3\3\3"
161   static bool
162   __verify_grouping(const char* __grouping, size_t __grouping_size,
163                     const string& __grouping_tmp);
164
165   template<typename _CharT, typename _InIter>
166     _InIter
167     num_get<_CharT, _InIter>::
168     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
169                      ios_base::iostate& __err, string& __xtrc) const
170     {
171       typedef char_traits<_CharT>                       __traits_type;
172       typedef typename numpunct<_CharT>::__cache_type   __cache_type;
173       __use_cache<__cache_type> __uc;
174       const locale& __loc = __io._M_getloc();
175       const __cache_type* __lc = __uc(__loc);
176       const _CharT* __lit = __lc->_M_atoms_in;
177
178       // True if a mantissa is found.
179       bool __found_mantissa = false;
180
181       // First check for sign.
182       if (__beg != __end)
183         {
184           const char_type __c = *__beg;
185           const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]);
186           if ((__plus || __traits_type::eq(__c, __lit[_S_iminus]))
187               && !__traits_type::eq(__c, __lc->_M_decimal_point)
188               && (!__lc->_M_use_grouping
189                   || !__traits_type::eq(__c, __lc->_M_thousands_sep)))
190             {
191               __xtrc += __plus ? _S_atoms_in[_S_iplus]
192                                : _S_atoms_in[_S_iminus];
193               ++__beg;
194             }
195         }
196
197       // Next, look for leading zeros.
198       while (__beg != __end)
199         {
200           const char_type __c = *__beg;
201           if (__traits_type::eq(__c, __lc->_M_decimal_point)
202               || (__lc->_M_use_grouping
203                   && __traits_type::eq(__c, __lc->_M_thousands_sep)))
204             break;
205           else if (__traits_type::eq(__c, __lit[_S_izero]))
206             {
207               if (!__found_mantissa)
208                 {
209                   __xtrc += _S_atoms_in[_S_izero];
210                   __found_mantissa = true;
211                 }
212               ++__beg;
213             }
214           else
215             break;
216         }
217
218       // Only need acceptable digits for floating point numbers.
219       bool __found_dec = false;
220       bool __found_sci = false;
221       string __found_grouping;
222       int __sep_pos = 0;
223       bool __e;
224       const char_type* __p;
225       while (__beg != __end)
226         {
227           // According to 22.2.2.1.2, p8-9, first look for thousands_sep
228           // and decimal_point.
229           const char_type __c = *__beg;
230           if (__lc->_M_use_grouping
231               && __traits_type::eq(__c, __lc->_M_thousands_sep))
232             {
233               if (!__found_dec && !__found_sci)
234                 {
235                   // NB: Thousands separator at the beginning of a string
236                   // is a no-no, as is two consecutive thousands separators.
237                   if (__sep_pos)
238                     {
239                       __found_grouping += static_cast<char>(__sep_pos);
240                       __sep_pos = 0;
241                       ++__beg;
242                     }
243                   else
244                     {
245                       __err |= ios_base::failbit;
246                       break;
247                     }
248                 }
249               else
250                 break;
251             }
252           else if (__traits_type::eq(__c, __lc->_M_decimal_point))
253             {
254               if (!__found_dec && !__found_sci)
255                 {
256                   // If no grouping chars are seen, no grouping check
257                   // is applied. Therefore __found_grouping is adjusted
258                   // only if decimal_point comes after some thousands_sep.
259                   if (__found_grouping.size())
260                     __found_grouping += static_cast<char>(__sep_pos);
261                   __xtrc += '.';
262                   __found_dec = true;
263                   ++__beg;
264                 }
265               else
266                 break;
267             }
268           else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
269             {
270               __xtrc += _S_atoms_in[__p - __lit];
271               __found_mantissa = true;
272               ++__sep_pos;
273               ++__beg;
274             }
275           else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
276                     || __traits_type::eq(__c, __lit[_S_iE]))
277                    && __found_mantissa && !__found_sci)
278             {
279               // Scientific notation.
280               __xtrc += __e ? _S_atoms_in[_S_ie] : _S_atoms_in[_S_iE];
281               __found_sci = true;
282
283               // Remove optional plus or minus sign, if they exist.
284               if (++__beg != __end)
285                 {
286                   const bool __plus = __traits_type::eq(*__beg, __lit[_S_iplus]);
287                   if (__plus || __traits_type::eq(*__beg, __lit[_S_iminus]))
288                     {
289                       __xtrc += __plus ? _S_atoms_in[_S_iplus]
290                                        : _S_atoms_in[_S_iminus];
291                       ++__beg;
292                     }
293                 }
294             }
295           else
296             // Not a valid input item.
297             break;
298         }
299
300       // Digit grouping is checked. If grouping and found_grouping don't
301       // match, then get very very upset, and set failbit.
302       if (__found_grouping.size())
303         {
304           // Add the ending grouping if a decimal wasn't found.
305           if (!__found_dec)
306             __found_grouping += static_cast<char>(__sep_pos);
307
308           if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size,
309                                       __found_grouping))
310             __err |= ios_base::failbit;
311         }
312
313       // Finish up.
314       __xtrc += char();
315       if (__beg == __end)
316         __err |= ios_base::eofbit;
317       return __beg;
318     }
319
320   template<typename _CharT, typename _InIter>
321     template<typename _ValueT>
322       _InIter
323       num_get<_CharT, _InIter>::
324       _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
325                      ios_base::iostate& __err, _ValueT& __v) const
326       {
327         typedef char_traits<_CharT>                     __traits_type;
328         typedef typename numpunct<_CharT>::__cache_type __cache_type;
329         __use_cache<__cache_type> __uc;
330         const locale& __loc = __io._M_getloc();
331         const __cache_type* __lc = __uc(__loc);
332         const _CharT* __lit = __lc->_M_atoms_in;
333
334         // NB: Iff __basefield == 0, __base can change based on contents.
335         const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
336         const bool __oct = __basefield == ios_base::oct;
337         int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
338
339         // True if numeric digits are found.
340         bool __found_num = false;
341
342         // First check for sign.
343         bool __negative = false;
344         if (__beg != __end)
345           {
346             const char_type __c = *__beg;
347             if (numeric_limits<_ValueT>::is_signed)
348               __negative = __traits_type::eq(__c, __lit[_S_iminus]);
349             if ((__negative || __traits_type::eq(__c, __lit[_S_iplus]))
350                 && !__traits_type::eq(__c, __lc->_M_decimal_point)
351                 && (!__lc->_M_use_grouping
352                     || !__traits_type::eq(__c, __lc->_M_thousands_sep)))
353               ++__beg;
354           }
355
356         // Next, look for leading zeros and check required digits
357         // for base formats.
358         while (__beg != __end)
359           {
360             const char_type __c = *__beg;
361             if (__traits_type::eq(__c, __lc->_M_decimal_point)
362                 || (__lc->_M_use_grouping
363                     && __traits_type::eq(__c, __lc->_M_thousands_sep)))
364               break;
365             else if (__traits_type::eq(__c, __lit[_S_izero])
366                      && (!__found_num || __base == 10))
367               {
368                 __found_num = true;
369                 ++__beg;
370               }
371             else if (__found_num)
372               {
373                 if (__traits_type::eq(__c, __lit[_S_ix])
374                     || __traits_type::eq(__c, __lit[_S_iX]))
375                   {
376                     if (__basefield == 0)
377                       __base = 16;
378                     if (__base == 16)
379                       {
380                         __found_num = false;
381                         ++__beg;
382                       }
383                   }
384                 else if (__basefield == 0)
385                   __base = 8;
386                 break;
387               }
388             else
389               break;
390           }
391
392         // At this point, base is determined. If not hex, only allow
393         // base digits as valid input.
394         const size_t __len = __base == 16 ? _S_iend : __base;
395
396         // Extract.
397         string __found_grouping;
398         int __sep_pos = 0;
399         bool __overflow = false;
400         _ValueT __result = 0;
401         const char_type* __lit_zero = __lit + _S_izero;
402         const char_type* __p;
403         if (__negative)
404           {
405             const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
406             for (; __beg != __end; ++__beg)
407               {
408                 // According to 22.2.2.1.2, p8-9, first look for thousands_sep
409                 // and decimal_point.
410                 const char_type __c = *__beg;
411                 if (__lc->_M_use_grouping
412                     && __traits_type::eq(__c, __lc->_M_thousands_sep))
413                   {
414                     // NB: Thousands separator at the beginning of a string
415                     // is a no-no, as is two consecutive thousands separators.
416                     if (__sep_pos)
417                       {
418                         __found_grouping += static_cast<char>(__sep_pos);
419                         __sep_pos = 0;
420                       }
421                     else
422                       {
423                         __err |= ios_base::failbit;
424                         break;
425                       }
426                   }
427                 else if (__traits_type::eq(__c, __lc->_M_decimal_point))
428                   break;
429                 else if (__p = __traits_type::find(__lit_zero, __len, __c))
430                   {
431                     int __digit = __p - __lit_zero;
432                     if (__digit > 15)
433                       __digit -= 6;
434                     if (__result < __min)
435                       __overflow = true;
436                     else
437                       {
438                         const _ValueT __new_result = __result * __base - __digit;
439                         __overflow |= __new_result > __result;
440                         __result = __new_result;
441                         ++__sep_pos;
442                         __found_num = true;
443                       }
444                   }
445                 else
446                   // Not a valid input item.
447                   break;
448               }
449           }
450         else
451           {
452             const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
453             for (; __beg != __end; ++__beg)
454               {
455                 const char_type __c = *__beg;
456                 if (__lc->_M_use_grouping
457                     && __traits_type::eq(__c, __lc->_M_thousands_sep))
458                   {
459                     if (__sep_pos)
460                       {
461                         __found_grouping += static_cast<char>(__sep_pos);
462                         __sep_pos = 0;
463                       }
464                     else
465                       {
466                         __err |= ios_base::failbit;
467                         break;
468                       }
469                   }
470                 else if (__traits_type::eq(__c, __lc->_M_decimal_point))
471                   break;
472                 else if (__p = __traits_type::find(__lit_zero, __len, __c))
473                   {
474                     int __digit = __p - __lit_zero;
475                     if (__digit > 15)
476                       __digit -= 6;
477                     if (__result > __max)
478                       __overflow = true;
479                     else
480                       {
481                         const _ValueT __new_result = __result * __base + __digit;
482                         __overflow |= __new_result < __result;
483                         __result = __new_result;
484                         ++__sep_pos;
485                         __found_num = true;
486                       }
487                   }
488                 else
489                   break;
490               }
491           }
492
493         // Digit grouping is checked. If grouping and found_grouping don't
494         // match, then get very very upset, and set failbit.
495         if (__found_grouping.size())
496           {
497             // Add the ending grouping.
498             __found_grouping += static_cast<char>(__sep_pos);
499
500             if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size,
501                                         __found_grouping))
502               __err |= ios_base::failbit;
503           }
504
505         if (!(__err & ios_base::failbit) && !__overflow
506             && __found_num)
507           __v = __result;
508         else
509           __err |= ios_base::failbit;
510
511         if (__beg == __end)
512           __err |= ios_base::eofbit;
513         return __beg;
514       }
515
516   // _GLIBCXX_RESOLVE_LIB_DEFECTS
517   // 17.  Bad bool parsing
518   template<typename _CharT, typename _InIter>
519     _InIter
520     num_get<_CharT, _InIter>::
521     do_get(iter_type __beg, iter_type __end, ios_base& __io,
522            ios_base::iostate& __err, bool& __v) const
523     {
524       if (!(__io.flags() & ios_base::boolalpha))
525         {
526           // Parse bool values as long.
527           // NB: We can't just call do_get(long) here, as it might
528           // refer to a derived class.
529           long __l = -1;
530           __beg = _M_extract_int(__beg, __end, __io, __err, __l);
531           if (__l == 0 || __l == 1)
532             __v = __l;
533           else
534             __err |= ios_base::failbit;
535         }
536       else
537         {
538           // Parse bool values as alphanumeric.
539           typedef char_traits<_CharT>                     __traits_type;
540           typedef typename numpunct<_CharT>::__cache_type __cache_type;
541           __use_cache<__cache_type> __uc;
542           const locale& __loc = __io._M_getloc();
543           const __cache_type* __lc = __uc(__loc);
544
545           bool __testf = true;
546           bool __testt = true;
547           size_t __n;
548           for (__n = 0; __beg != __end; ++__n, ++__beg)
549             {
550               if (__testf)
551                 if (__n < __lc->_M_falsename_size)
552                   __testf = __traits_type::eq(*__beg, __lc->_M_falsename[__n]);
553                 else
554                   break;
555
556               if (__testt)
557                 if (__n < __lc->_M_truename_size)
558                   __testt = __traits_type::eq(*__beg, __lc->_M_truename[__n]);
559                 else
560                   break;
561
562               if (!__testf && !__testt)
563                 break;
564             }
565           if (__testf && __n == __lc->_M_falsename_size)
566             __v = 0;
567           else if (__testt && __n == __lc->_M_truename_size)
568             __v = 1;
569           else
570             __err |= ios_base::failbit;
571
572           if (__beg == __end)
573             __err |= ios_base::eofbit;
574         }
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, long& __v) const
583     { return _M_extract_int(__beg, __end, __io, __err, __v); }
584
585   template<typename _CharT, typename _InIter>
586     _InIter
587     num_get<_CharT, _InIter>::
588     do_get(iter_type __beg, iter_type __end, ios_base& __io,
589            ios_base::iostate& __err, unsigned short& __v) const
590     { return _M_extract_int(__beg, __end, __io, __err, __v); }
591
592   template<typename _CharT, typename _InIter>
593     _InIter
594     num_get<_CharT, _InIter>::
595     do_get(iter_type __beg, iter_type __end, ios_base& __io,
596            ios_base::iostate& __err, unsigned int& __v) const
597     { return _M_extract_int(__beg, __end, __io, __err, __v); }
598
599   template<typename _CharT, typename _InIter>
600     _InIter
601     num_get<_CharT, _InIter>::
602     do_get(iter_type __beg, iter_type __end, ios_base& __io,
603            ios_base::iostate& __err, unsigned long& __v) const
604     { return _M_extract_int(__beg, __end, __io, __err, __v); }
605
606 #ifdef _GLIBCXX_USE_LONG_LONG
607   template<typename _CharT, typename _InIter>
608     _InIter
609     num_get<_CharT, _InIter>::
610     do_get(iter_type __beg, iter_type __end, ios_base& __io,
611            ios_base::iostate& __err, long long& __v) const
612     { return _M_extract_int(__beg, __end, __io, __err, __v); }
613
614   template<typename _CharT, typename _InIter>
615     _InIter
616     num_get<_CharT, _InIter>::
617     do_get(iter_type __beg, iter_type __end, ios_base& __io,
618            ios_base::iostate& __err, unsigned long long& __v) const
619     { return _M_extract_int(__beg, __end, __io, __err, __v); }
620 #endif
621
622   template<typename _CharT, typename _InIter>
623     _InIter
624     num_get<_CharT, _InIter>::
625     do_get(iter_type __beg, iter_type __end, ios_base& __io,
626            ios_base::iostate& __err, float& __v) const
627     {
628       string __xtrc;
629       __xtrc.reserve(32);
630       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
631       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
632       return __beg;
633     }
634
635   template<typename _CharT, typename _InIter>
636     _InIter
637     num_get<_CharT, _InIter>::
638     do_get(iter_type __beg, iter_type __end, ios_base& __io,
639            ios_base::iostate& __err, double& __v) const
640     {
641       string __xtrc;
642       __xtrc.reserve(32);
643       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
644       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
645       return __beg;
646     }
647
648   template<typename _CharT, typename _InIter>
649     _InIter
650     num_get<_CharT, _InIter>::
651     do_get(iter_type __beg, iter_type __end, ios_base& __io,
652            ios_base::iostate& __err, long double& __v) const
653     {
654       string __xtrc;
655       __xtrc.reserve(32);
656       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
657       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
658       return __beg;
659     }
660
661   template<typename _CharT, typename _InIter>
662     _InIter
663     num_get<_CharT, _InIter>::
664     do_get(iter_type __beg, iter_type __end, ios_base& __io,
665            ios_base::iostate& __err, void*& __v) const
666     {
667       // Prepare for hex formatted input.
668       typedef ios_base::fmtflags        fmtflags;
669       const fmtflags __fmt = __io.flags();
670       __io.flags(__fmt & ~ios_base::basefield | ios_base::hex);
671
672       unsigned long __ul;
673       __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
674
675       // Reset from hex formatted input.
676       __io.flags(__fmt);
677
678       if (!(__err & ios_base::failbit))
679         __v = reinterpret_cast<void*>(__ul);
680       else
681         __err |= ios_base::failbit;
682       return __beg;
683     }
684
685   // For use by integer and floating-point types after they have been
686   // converted into a char_type string.
687   template<typename _CharT, typename _OutIter>
688     void
689     num_put<_CharT, _OutIter>::
690     _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
691            _CharT* __new, const _CharT* __cs, int& __len) const
692     {
693       // [22.2.2.2.2] Stage 3.
694       // If necessary, pad.
695       __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs,
696                                                   __w, __len, true);
697       __len = static_cast<int>(__w);
698     }
699
700   // Forwarding functions to peel signed from unsigned integer types.
701   template<typename _CharT>
702     inline int
703     __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit,
704                   ios_base::fmtflags __flags)
705     {
706       unsigned long __ul = static_cast<unsigned long>(__v);
707       bool __neg = false;
708       if (__v < 0)
709         {
710           __ul = -__ul;
711           __neg = true;
712         }
713       return __int_to_char(__bufend, __ul, __lit, __flags, __neg);
714     }
715
716   template<typename _CharT>
717     inline int
718     __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit,
719                   ios_base::fmtflags __flags)
720     { return __int_to_char(__bufend, __v, __lit, __flags, false); }
721
722 #ifdef _GLIBCXX_USE_LONG_LONG
723   template<typename _CharT>
724     inline int
725     __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit,
726                   ios_base::fmtflags __flags)
727     {
728       unsigned long long __ull = static_cast<unsigned long long>(__v);
729       bool __neg = false;
730       if (__v < 0)
731         {
732           __ull = -__ull;
733           __neg = true;
734         }
735       return __int_to_char(__bufend, __ull, __lit, __flags, __neg);
736     }
737
738   template<typename _CharT>
739     inline int
740     __int_to_char(_CharT* __bufend, unsigned long long __v, const _CharT* __lit,
741                   ios_base::fmtflags __flags)
742     { return __int_to_char(__bufend, __v, __lit, __flags, false); }
743 #endif
744
745   template<typename _CharT, typename _ValueT>
746     int
747     __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
748                   ios_base::fmtflags __flags, bool __neg)
749     {
750       // Don't write base if already 0.
751       const bool __showbase = (__flags & ios_base::showbase) && __v;
752       const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
753       _CharT* __buf = __bufend - 1;
754
755       if (__builtin_expect(__basefield != ios_base::oct &&
756                            __basefield != ios_base::hex, true))
757         {
758           // Decimal.
759           do
760             {
761               *__buf-- = __lit[(__v % 10) + __num_base::_S_odigits];
762               __v /= 10;
763             }
764           while (__v != 0);
765           if (__neg)
766             *__buf-- = __lit[__num_base::_S_ominus];
767           else if (__flags & ios_base::showpos)
768             *__buf-- = __lit[__num_base::_S_oplus];
769         }
770       else if (__basefield == ios_base::oct)
771         {
772           // Octal.
773           do
774             {
775               *__buf-- = __lit[(__v & 0x7) + __num_base::_S_odigits];
776               __v >>= 3;
777             }
778           while (__v != 0);
779           if (__showbase)
780             *__buf-- = __lit[__num_base::_S_odigits];
781         }
782       else
783         {
784           // Hex.
785           const bool __uppercase = __flags & ios_base::uppercase;
786           const int __case_offset = __uppercase ? __num_base::_S_oudigits
787                                                 : __num_base::_S_odigits;
788           do
789             {
790               *__buf-- = __lit[(__v & 0xf) + __case_offset];
791               __v >>= 4;
792             }
793           while (__v != 0);
794           if (__showbase)
795             {
796               // 'x' or 'X'
797               *__buf-- = __lit[__num_base::_S_ox + __uppercase];
798               // '0'
799               *__buf-- = __lit[__num_base::_S_odigits];
800             }
801         }
802       return __bufend - __buf - 1;
803     }
804
805   template<typename _CharT, typename _OutIter>
806     void
807     num_put<_CharT, _OutIter>::
808     _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
809                  ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const
810     {
811       // By itself __add_grouping cannot deal correctly with __cs when
812       // ios::showbase is set and ios_base::oct || ios_base::hex.
813       // Therefore we take care "by hand" of the initial 0, 0x or 0X.
814       // However, remember that the latter do not occur if the number
815       // printed is '0' (__len == 1).
816       streamsize __off = 0;
817       const ios_base::fmtflags __basefield = __io.flags()
818                                              & ios_base::basefield;
819       if ((__io.flags() & ios_base::showbase) && __len > 1)
820         if (__basefield == ios_base::oct)
821           {
822             __off = 1;
823             __new[0] = __cs[0];
824           }
825         else if (__basefield == ios_base::hex)
826           {
827             __off = 2;
828             __new[0] = __cs[0];
829             __new[1] = __cs[1];
830           }
831       _CharT* __p;
832       __p = std::__add_grouping(__new + __off, __sep, __grouping,
833                                 __grouping_size, __cs + __off,
834                                 __cs + __len);
835       __len = __p - __new;
836     }
837
838   template<typename _CharT, typename _OutIter>
839     template<typename _ValueT>
840       _OutIter
841       num_put<_CharT, _OutIter>::
842       _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
843                     _ValueT __v) const
844       {
845         typedef typename numpunct<_CharT>::__cache_type __cache_type;
846         __use_cache<__cache_type> __uc;
847         const locale& __loc = __io._M_getloc();
848         const __cache_type* __lc = __uc(__loc);
849         const _CharT* __lit = __lc->_M_atoms_out;
850
851         // Long enough to hold hex, dec, and octal representations.
852         const int __ilen = 4 * sizeof(_ValueT);
853         _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
854                                                              * __ilen));
855
856         // [22.2.2.2.2] Stage 1, numeric conversion to character.
857         // Result is returned right-justified in the buffer.
858         int __len;
859         __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags());
860         __cs += __ilen - __len;
861
862         // Add grouping, if necessary.
863         if (__lc->_M_use_grouping)
864           {
865             // Grouping can add (almost) as many separators as the
866             // number of digits, but no more.
867             _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
868                                                                   * __len * 2));
869             _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
870                          __lc->_M_thousands_sep, __io, __cs2, __cs, __len);
871             __cs = __cs2;
872           }
873
874         // Pad.
875         const streamsize __w = __io.width();
876         if (__w > static_cast<streamsize>(__len))
877           {
878             _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
879                                                                   * __w));
880             _M_pad(__fill, __w, __io, __cs3, __cs, __len);
881             __cs = __cs3;
882           }
883         __io.width(0);
884
885         // [22.2.2.2.2] Stage 4.
886         // Write resulting, fully-formatted string to output iterator.
887         return std::__write(__s, __cs, __len);
888       }
889
890   template<typename _CharT, typename _OutIter>
891     void
892     num_put<_CharT, _OutIter>::
893     _M_group_float(const char* __grouping, size_t __grouping_size, _CharT __sep,
894                    const _CharT* __p, _CharT* __new, _CharT* __cs, int& __len) const
895     {
896       // _GLIBCXX_RESOLVE_LIB_DEFECTS
897       // 282. What types does numpunct grouping refer to?
898       // Add grouping, if necessary.
899       _CharT* __p2;
900       const int __declen = __p ? __p - __cs : __len;
901       __p2 = std::__add_grouping(__new, __sep, __grouping, __grouping_size,
902                                  __cs, __cs + __declen);
903
904       // Tack on decimal part.
905       int __newlen = __p2 - __new;
906       if (__p)
907         {
908           char_traits<_CharT>::copy(__p2, __p, __len - __declen);
909           __newlen += __len - __declen;
910         }
911       __len = __newlen;
912     }
913
914   // The following code uses snprintf (or sprintf(), when
915   // _GLIBCXX_USE_C99 is not defined) to convert floating point values
916   // for insertion into a stream.  An optimization would be to replace
917   // them with code that works directly on a wide buffer and then use
918   // __pad to do the padding.  It would be good to replace them anyway
919   // to gain back the efficiency that C++ provides by knowing up front
920   // the type of the values to insert.  Also, sprintf is dangerous
921   // since may lead to accidental buffer overruns.  This
922   // implementation follows the C++ standard fairly directly as
923   // outlined in 22.2.2.2 [lib.locale.num.put]
924   template<typename _CharT, typename _OutIter>
925     template<typename _ValueT>
926       _OutIter
927       num_put<_CharT, _OutIter>::
928       _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
929                        _ValueT __v) const
930       {
931         typedef typename numpunct<_CharT>::__cache_type __cache_type;
932         __use_cache<__cache_type> __uc;
933         const locale& __loc = __io._M_getloc();
934         const __cache_type* __lc = __uc(__loc);
935
936         // Note: digits10 is rounded down: add 1 to ensure the maximum
937         // available precision.  Then, in general, one more 1 needs to
938         // be added since, when the %{g,G} conversion specifiers are
939         // chosen inside _S_format_float, the precision field is "the
940         // maximum number of significant digits", *not* the "number of
941         // digits to appear after the decimal point", as happens for
942         // %{e,E,f,F} (C99, 7.19.6.1,4).
943         const int __max_digits = numeric_limits<_ValueT>::digits10 + 2;
944
945         // Use default precision if out of range.
946         streamsize __prec = __io.precision();
947         if (__prec > static_cast<streamsize>(__max_digits))
948           __prec = static_cast<streamsize>(__max_digits);
949         else if (__prec < static_cast<streamsize>(0))
950           __prec = static_cast<streamsize>(6);
951
952         // [22.2.2.2.2] Stage 1, numeric conversion to character.
953         int __len;
954         // Long enough for the max format spec.
955         char __fbuf[16];
956
957 #ifdef _GLIBCXX_USE_C99
958         // First try a buffer perhaps big enough (for sure sufficient
959         // for non-ios_base::fixed outputs)
960         int __cs_size = __max_digits * 3;
961         char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
962
963         _S_format_float(__io, __fbuf, __mod);
964         __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
965                                       _S_get_c_locale(), __prec);
966
967         // If the buffer was not large enough, try again with the correct size.
968         if (__len >= __cs_size)
969           {
970             __cs_size = __len + 1;
971             __cs = static_cast<char*>(__builtin_alloca(__cs_size));
972             __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
973                                           _S_get_c_locale(), __prec);
974           }
975 #else
976         // Consider the possibility of long ios_base::fixed outputs
977         const bool __fixed = __io.flags() & ios_base::fixed;
978         const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
979
980         // The size of the output string is computed as follows.
981         // ios_base::fixed outputs may need up to __max_exp+1 chars
982         // for the integer part + up to __max_digits chars for the
983         // fractional part + 3 chars for sign, decimal point, '\0'. On
984         // the other hand, for non-fixed outputs __max_digits*3 chars
985         // are largely sufficient.
986         const int __cs_size = __fixed ? __max_exp + __max_digits + 4
987                                       : __max_digits * 3;
988         char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
989
990         _S_format_float(__io, __fbuf, __mod);
991         __len = std::__convert_from_v(__cs, 0, __fbuf, __v,
992                                       _S_get_c_locale(), __prec);
993 #endif
994
995       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
996       // numpunct.decimal_point() values for '.' and adding grouping.
997       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
998
999       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1000                                                            * __len));
1001       __ctype.widen(__cs, __cs + __len, __ws);
1002
1003       // Replace decimal point.
1004       const _CharT __cdec = __ctype.widen('.');
1005       const _CharT __dec = __lc->_M_decimal_point;
1006       const _CharT* __p;
1007       if (__p = char_traits<_CharT>::find(__ws, __len, __cdec))
1008         __ws[__p - __ws] = __dec;
1009
1010       // Add grouping, if necessary.
1011       if (__lc->_M_use_grouping)
1012         {
1013           // Grouping can add (almost) as many separators as the
1014           // number of digits, but no more.
1015           _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1016                                                                 * __len * 2));
1017           _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
1018                          __lc->_M_thousands_sep, __p, __ws2, __ws, __len);
1019           __ws = __ws2;
1020         }
1021
1022       // Pad.
1023       const streamsize __w = __io.width();
1024       if (__w > static_cast<streamsize>(__len))
1025         {
1026           _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1027                                                                 * __w));
1028           _M_pad(__fill, __w, __io, __ws3, __ws, __len);
1029           __ws = __ws3;
1030         }
1031       __io.width(0);
1032
1033       // [22.2.2.2.2] Stage 4.
1034       // Write resulting, fully-formatted string to output iterator.
1035       return std::__write(__s, __ws, __len);
1036       }
1037
1038   template<typename _CharT, typename _OutIter>
1039     _OutIter
1040     num_put<_CharT, _OutIter>::
1041     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
1042     {
1043       const ios_base::fmtflags __flags = __io.flags();
1044       if ((__flags & ios_base::boolalpha) == 0)
1045         {
1046           unsigned long __uv = __v;
1047           __s = _M_insert_int(__s, __io, __fill, __uv);
1048         }
1049       else
1050         {
1051           typedef typename numpunct<_CharT>::__cache_type __cache_type;
1052           __use_cache<__cache_type> __uc;
1053           const locale& __loc = __io._M_getloc();
1054           const __cache_type* __lc = __uc(__loc);
1055
1056           const _CharT* __name = __v ? __lc->_M_truename
1057                                      : __lc->_M_falsename;
1058           int __len = __v ? __lc->_M_truename_size
1059                           : __lc->_M_falsename_size;
1060
1061           const streamsize __w = __io.width();
1062           if (__w > static_cast<streamsize>(__len))
1063             {
1064               _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1065                                                                    * __w));
1066               _M_pad(__fill, __w, __io, __cs, __name, __len);
1067               __name = __cs;
1068             }
1069           __io.width(0);
1070           __s = std::__write(__s, __name, __len);
1071         }
1072       return __s;
1073     }
1074
1075   template<typename _CharT, typename _OutIter>
1076     _OutIter
1077     num_put<_CharT, _OutIter>::
1078     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
1079     { return _M_insert_int(__s, __io, __fill, __v); }
1080
1081   template<typename _CharT, typename _OutIter>
1082     _OutIter
1083     num_put<_CharT, _OutIter>::
1084     do_put(iter_type __s, ios_base& __io, char_type __fill,
1085            unsigned long __v) const
1086     { return _M_insert_int(__s, __io, __fill, __v); }
1087
1088 #ifdef _GLIBCXX_USE_LONG_LONG
1089   template<typename _CharT, typename _OutIter>
1090     _OutIter
1091     num_put<_CharT, _OutIter>::
1092     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
1093     { return _M_insert_int(__s, __b, __fill, __v); }
1094
1095   template<typename _CharT, typename _OutIter>
1096     _OutIter
1097     num_put<_CharT, _OutIter>::
1098     do_put(iter_type __s, ios_base& __io, char_type __fill,
1099            unsigned long long __v) const
1100     { return _M_insert_int(__s, __io, __fill, __v); }
1101 #endif
1102
1103   template<typename _CharT, typename _OutIter>
1104     _OutIter
1105     num_put<_CharT, _OutIter>::
1106     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1107     { return _M_insert_float(__s, __io, __fill, char(), __v); }
1108
1109   template<typename _CharT, typename _OutIter>
1110     _OutIter
1111     num_put<_CharT, _OutIter>::
1112     do_put(iter_type __s, ios_base& __io, char_type __fill,
1113            long double __v) const
1114     { return _M_insert_float(__s, __io, __fill, 'L', __v); }
1115
1116   template<typename _CharT, typename _OutIter>
1117     _OutIter
1118     num_put<_CharT, _OutIter>::
1119     do_put(iter_type __s, ios_base& __io, char_type __fill,
1120            const void* __v) const
1121     {
1122       const ios_base::fmtflags __flags = __io.flags();
1123       const ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
1124                                          | ios_base::uppercase | ios_base::internal);
1125       __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
1126
1127       __s = _M_insert_int(__s, __io, __fill,
1128                           reinterpret_cast<unsigned long>(__v));
1129       __io.flags(__flags);
1130       return __s;
1131     }
1132
1133   template<typename _CharT, bool _Intl>
1134     struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
1135     {
1136       const __moneypunct_cache<_CharT, _Intl>*
1137       operator() (const locale& __loc) const
1138       {
1139         const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
1140         const locale::facet** __caches = __loc._M_impl->_M_caches;
1141         if (!__caches[__i])
1142           {
1143             __moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
1144             try
1145               {
1146                 __tmp = new __moneypunct_cache<_CharT, _Intl>;
1147                 __tmp->_M_cache(__loc);
1148               }
1149             catch(...)
1150               {
1151                 delete __tmp;
1152                 __throw_exception_again;
1153               }
1154             __loc._M_impl->_M_install_cache(__tmp, __i);
1155           }
1156         return static_cast<
1157           const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
1158       }
1159     };
1160
1161   template<typename _CharT, typename _InIter>
1162     _InIter
1163     money_get<_CharT, _InIter>::
1164     _M_extract(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1165                ios_base::iostate& __err, string_type& __units) const
1166     {
1167       // These contortions are quite unfortunate.
1168       typedef moneypunct<_CharT, true>          __money_true;
1169       typedef moneypunct<_CharT, false>         __money_false;
1170       typedef money_base::part                  part;
1171       typedef typename string_type::size_type   size_type;
1172
1173       const locale __loc = __io.getloc();
1174       const __money_true& __mpt = use_facet<__money_true>(__loc);
1175       const __money_false& __mpf = use_facet<__money_false>(__loc);
1176       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1177
1178       const money_base::pattern __p = __intl ? __mpt.neg_format()
1179                                              : __mpf.neg_format();
1180
1181       const string_type __pos_sign = __intl ? __mpt.positive_sign()
1182                                             : __mpf.positive_sign();
1183       const string_type __neg_sign = __intl ? __mpt.negative_sign()
1184                                             : __mpf.negative_sign();
1185       const char_type __d = __intl ? __mpt.decimal_point()
1186                                    : __mpf.decimal_point();
1187       const char_type __sep = __intl ? __mpt.thousands_sep()
1188                                      : __mpf.thousands_sep();
1189
1190       const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
1191
1192       // Set to deduced positive or negative sign, depending.
1193       string_type __sign;
1194       // String of grouping info from thousands_sep plucked from __units.
1195       string __grouping_tmp;
1196       // Marker for thousands_sep position.
1197       int __sep_pos = 0;
1198       // If input iterator is in a valid state.
1199       bool __testvalid = true;
1200       // Flag marking when a decimal point is found.
1201       bool __testdecfound = false;
1202
1203       // The tentative returned string is stored here.
1204       string_type __tmp_units;
1205
1206       for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
1207         {
1208           char_type __c;
1209           const part __which = static_cast<part>(__p.field[__i]);
1210           switch (__which)
1211             {
1212             case money_base::symbol:
1213               if (__io.flags() & ios_base::showbase
1214                   || __i < 2 || __sign.size() > 1
1215                   || ((static_cast<part>(__p.field[3]) != money_base::none)
1216                       && __i == 2))
1217                 {
1218                   // According to 22.2.6.1.2, p2, symbol is required
1219                   // if (__io.flags() & ios_base::showbase),
1220                   // otherwise is optional and consumed only if
1221                   // other characters are needed to complete the
1222                   // format.
1223                   const string_type __symbol = __intl ? __mpt.curr_symbol()
1224                                                       : __mpf.curr_symbol();
1225                   const size_type __len = __symbol.size();
1226                   size_type __j = 0;
1227                   for (; __beg != __end && __j < __len
1228                          && *__beg == __symbol[__j]; ++__beg, ++__j);
1229                   // When (__io.flags() & ios_base::showbase)
1230                   // symbol is required.
1231                   if (__j != __len && (__io.flags() & ios_base::showbase))
1232                     __testvalid = false;
1233                 }
1234               break;
1235             case money_base::sign:
1236               // Sign might not exist, or be more than one character long.
1237               if (__pos_sign.size() && *__beg == __pos_sign[0])
1238                 {
1239                   __sign = __pos_sign;
1240                   ++__beg;
1241                 }
1242               else if (__neg_sign.size() && *__beg == __neg_sign[0])
1243                 {
1244                   __sign = __neg_sign;
1245                   ++__beg;
1246                 }
1247               else if (__pos_sign.size() && __neg_sign.size())
1248                 {
1249                   // Sign is mandatory.
1250                   __testvalid = false;
1251                 }
1252               break;
1253             case money_base::value:
1254               // Extract digits, remove and stash away the
1255               // grouping of found thousands separators.
1256               for (; __beg != __end; ++__beg)
1257                 if (__ctype.is(ctype_base::digit, __c = *__beg))
1258                   {
1259                     __tmp_units += __c;
1260                     ++__sep_pos;
1261                   }
1262                 else if (__c == __d && !__testdecfound)
1263                   {
1264                     // If no grouping chars are seen, no grouping check
1265                     // is applied. Therefore __grouping_tmp is adjusted
1266                     // only if decimal_point comes after some thousands_sep.
1267                     if (__grouping_tmp.size())
1268                       __grouping_tmp += static_cast<char>(__sep_pos);
1269                     __sep_pos = 0;
1270                     __testdecfound = true;
1271                   }
1272                 else if (__c == __sep && !__testdecfound)
1273                   {
1274                     if (__grouping.size())
1275                       {
1276                         // Mark position for later analysis.
1277                         __grouping_tmp += static_cast<char>(__sep_pos);
1278                         __sep_pos = 0;
1279                       }
1280                     else
1281                       {
1282                         __testvalid = false;
1283                         break;
1284                       }
1285                   }
1286                 else
1287                   break;
1288               break;
1289             case money_base::space:
1290             case money_base::none:
1291               // Only if not at the end of the pattern.
1292               if (__i != 3)
1293                 for (; __beg != __end
1294                        && __ctype.is(ctype_base::space, *__beg); ++__beg);
1295               break;
1296             }
1297         }
1298
1299       // Need to get the rest of the sign characters, if they exist.
1300       if (__sign.size() > 1)
1301         {
1302           const size_type __len = __sign.size();
1303           size_type __i = 1;
1304           for (; __beg != __end && __i < __len
1305                  && *__beg == __sign[__i]; ++__beg, ++__i);
1306
1307           if (__i != __len)
1308             __testvalid = false;
1309         }
1310
1311       if (__testvalid && __tmp_units.size())
1312         {
1313           const char_type __zero = __ctype.widen('0');
1314
1315           // Strip leading zeros.
1316           if (__tmp_units.size() > 1)
1317             {
1318               const size_type __first = __tmp_units.find_first_not_of(__zero);
1319               const bool __only_zeros = __first == string_type::npos;
1320               if (__first)
1321                 __tmp_units.erase(0, __only_zeros ? __tmp_units.size() - 1
1322                                                   : __first);
1323             }
1324
1325           // 22.2.6.1.2, p4
1326           if (__sign.size() && __sign == __neg_sign
1327               && __tmp_units[0] != __zero)
1328             __tmp_units.insert(__tmp_units.begin(), __ctype.widen('-'));
1329
1330           // Test for grouping fidelity.
1331           if (__grouping_tmp.size())
1332             {
1333               // Add the ending grouping if a decimal wasn't found.
1334               if (!__testdecfound)
1335                 __grouping_tmp += static_cast<char>(__sep_pos);
1336
1337               if (!std::__verify_grouping(__grouping.data(),
1338                                           __grouping.size(),
1339                                           __grouping_tmp))
1340                 __testvalid = false;
1341             }
1342
1343           // Iff not enough digits were supplied after the decimal-point.
1344           if (__testdecfound)
1345             {
1346               const int __frac = __intl ? __mpt.frac_digits()
1347                                         : __mpf.frac_digits();
1348               if (__frac > 0 && __sep_pos != __frac)
1349                 __testvalid = false;
1350             }
1351         }
1352       else
1353         __testvalid = false;
1354
1355       // Iff no more characters are available.
1356       if (__beg == __end)
1357         __err |= ios_base::eofbit;
1358
1359       // Iff valid sequence is not recognized.
1360       if (!__testvalid)
1361         __err |= ios_base::failbit;
1362       else
1363         // Use the "swap trick" to copy __tmp_units into __units.
1364         __tmp_units.swap(__units);
1365
1366       return __beg;
1367     }
1368
1369   template<typename _CharT, typename _InIter>
1370     _InIter
1371     money_get<_CharT, _InIter>::
1372     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1373            ios_base::iostate& __err, long double& __units) const
1374     {
1375       string_type __str;
1376       __beg = _M_extract(__beg, __end, __intl, __io, __err, __str);
1377
1378       const int __cs_size = __str.size() + 1;
1379       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1380       const locale __loc = __io.getloc();
1381       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1382       const _CharT* __wcs = __str.c_str();
1383       __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs);
1384       std::__convert_to_v(__cs, __units, __err, _S_get_c_locale());
1385       return __beg;
1386     }
1387
1388   template<typename _CharT, typename _InIter>
1389     _InIter
1390     money_get<_CharT, _InIter>::
1391     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1392            ios_base::iostate& __err, string_type& __units) const
1393     { return _M_extract(__beg, __end, __intl, __io, __err, __units); }
1394
1395   template<typename _CharT, typename _OutIter>
1396     template<bool _Intl>
1397       _OutIter
1398       money_put<_CharT, _OutIter>::
1399       _M_insert(iter_type __s, ios_base& __io, char_type __fill,
1400                 const string_type& __digits) const
1401       {
1402         typedef typename string_type::size_type           size_type;
1403         typedef money_base::part                          part;
1404         typedef moneypunct<_CharT, _Intl>                 __moneypunct_type;
1405         typedef typename __moneypunct_type::__cache_type  __cache_type;
1406       
1407         const locale& __loc = __io._M_getloc();
1408         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1409
1410         __use_cache<__cache_type> __uc;
1411         const __cache_type* __lc = __uc(__loc);
1412         const char_type* __lit = __lc->_M_atoms;
1413
1414         // Determine if negative or positive formats are to be used, and
1415         // discard leading negative_sign if it is present.
1416         const char_type* __beg = __digits.data();
1417         const char_type* __end = __beg + __digits.size();
1418
1419         money_base::pattern __p;
1420         const char_type* __sign;
1421         size_type __sign_size;
1422         if (*__beg != __lit[_S_minus])
1423           {
1424             __p = __lc->_M_pos_format;
1425             __sign = __lc->_M_positive_sign;
1426             __sign_size = __lc->_M_positive_sign_size;
1427           }
1428         else
1429           {
1430             __p = __lc->_M_neg_format;
1431             __sign = __lc->_M_negative_sign;
1432             __sign_size = __lc->_M_negative_sign_size;
1433             ++__beg;
1434           }
1435        
1436         // Look for valid numbers in the ctype facet within input digits.
1437         __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
1438         if (__beg != __end)
1439           {
1440             // Assume valid input, and attempt to format.
1441             // Break down input numbers into base components, as follows:
1442             //   final_value = grouped units + (decimal point) + (digits)
1443             string_type __res;
1444             string_type __value;
1445            
1446             // Deal with decimal point, decimal digits.
1447             if (__lc->_M_frac_digits > 0)
1448               {
1449                 if (__end - __beg >= __lc->_M_frac_digits)
1450                   {
1451                     __value = string_type(__end - __lc->_M_frac_digits, __end);
1452                     __value.insert(__value.begin(), __lc->_M_decimal_point);
1453                     __end -= __lc->_M_frac_digits;
1454                   }
1455                 else
1456                   {
1457                     // Have to pad zeros in the decimal position.
1458                     __value = string_type(__beg, __end);
1459                     const int __paddec = __lc->_M_frac_digits - (__end - __beg);
1460                     __value.insert(__value.begin(), __paddec, __lit[_S_zero]);
1461                     __value.insert(__value.begin(), __lc->_M_decimal_point);
1462                     __beg = __end;
1463                   }
1464               }
1465             
1466             // Add thousands separators to non-decimal digits, per
1467             // grouping rules.
1468             if (__beg != __end)
1469               {
1470                 if (__lc->_M_grouping_size)
1471                   {
1472                     const int __n = (__end - __beg) * 2;
1473                     _CharT* __ws2 =
1474                       static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1475                                                             * __n));
1476                     _CharT* __ws_end =
1477                       std::__add_grouping(__ws2, __lc->_M_thousands_sep,
1478                                           __lc->_M_grouping,
1479                                           __lc->_M_grouping_size,
1480                                           __beg, __end);
1481                     __value.insert(0, __ws2, __ws_end - __ws2);
1482                   }
1483                 else
1484                   __value.insert(0, string_type(__beg, __end));
1485               }
1486             
1487             // Calculate length of resulting string.
1488             const ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
1489             size_type __len = __value.size() + __sign_size;
1490             __len += ((__io.flags() & ios_base::showbase)
1491                       ? __lc->_M_curr_symbol_size : 0);
1492             __res.reserve(__len);
1493             
1494             const size_type __width = static_cast<size_type>(__io.width());       
1495             const bool __testipad = (__f == ios_base::internal
1496                                      && __len < __width);
1497             // Fit formatted digits into the required pattern.
1498             for (int __i = 0; __i < 4; ++__i)
1499               {
1500                 const part __which = static_cast<part>(__p.field[__i]);
1501                 switch (__which)
1502                   {
1503                   case money_base::symbol:
1504                     if (__io.flags() & ios_base::showbase)
1505                       __res.append(__lc->_M_curr_symbol,
1506                                    __lc->_M_curr_symbol_size);
1507                     break;
1508                   case money_base::sign:
1509                     // Sign might not exist, or be more than one
1510                     // charater long. In that case, add in the rest
1511                     // below.
1512                     if (__sign_size)
1513                       __res += __sign[0];
1514                     break;
1515                   case money_base::value:
1516                     __res += __value;
1517                     break;
1518                   case money_base::space:
1519                     // At least one space is required, but if internal
1520                     // formatting is required, an arbitrary number of
1521                     // fill spaces will be necessary.
1522                     if (__testipad)
1523                       __res += string_type(__width - __len, __fill);
1524                     else
1525                       __res += __fill;
1526                     break;
1527                   case money_base::none:
1528                     if (__testipad)
1529                       __res += string_type(__width - __len, __fill);
1530                     break;
1531                   }
1532               }
1533             
1534             // Special case of multi-part sign parts.
1535             if (__sign_size > 1)
1536               __res.append(__sign + 1, __sign_size - 1);
1537             
1538             // Pad, if still necessary.
1539             __len = __res.size();
1540             if (__width > __len)
1541               {
1542                 if (__f == ios_base::left)
1543                   // After.
1544                   __res.append(__width - __len, __fill);
1545                 else
1546                   // Before.
1547                   __res.insert(0, string_type(__width - __len, __fill));
1548                 __len = __width;
1549               }
1550             
1551             // Write resulting, fully-formatted string to output iterator.
1552             __s = std::__write(__s, __res.data(), __len);
1553           }
1554         __io.width(0);
1555         return __s;    
1556       }
1557   
1558   template<typename _CharT, typename _OutIter>
1559     _OutIter
1560     money_put<_CharT, _OutIter>::
1561     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1562            long double __units) const
1563     {
1564       const locale __loc = __io.getloc();
1565       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1566 #ifdef _GLIBCXX_USE_C99
1567       // First try a buffer perhaps big enough.
1568       int __cs_size = 64;
1569       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1570       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1571       // 328. Bad sprintf format modifier in money_put<>::do_put()
1572       int __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units,
1573                                         _S_get_c_locale());
1574       // If the buffer was not large enough, try again with the correct size.
1575       if (__len >= __cs_size)
1576         {
1577           __cs_size = __len + 1;
1578           __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1579           __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units,
1580                                         _S_get_c_locale());
1581         }
1582 #else
1583       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
1584       const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
1585       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1586       int __len = std::__convert_from_v(__cs, 0, "%.0Lf", __units,
1587                                         _S_get_c_locale());
1588 #endif
1589       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1590                                                            * __cs_size));
1591       __ctype.widen(__cs, __cs + __len, __ws);
1592       const string_type __digits(__ws, __len);
1593       return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
1594                     : _M_insert<false>(__s, __io, __fill, __digits);
1595     }
1596
1597   template<typename _CharT, typename _OutIter>
1598     _OutIter
1599     money_put<_CharT, _OutIter>::
1600     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1601            const string_type& __digits) const
1602     { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
1603                     : _M_insert<false>(__s, __io, __fill, __digits); }
1604
1605   // NB: Not especially useful. Without an ios_base object or some
1606   // kind of locale reference, we are left clawing at the air where
1607   // the side of the mountain used to be...
1608   template<typename _CharT, typename _InIter>
1609     time_base::dateorder
1610     time_get<_CharT, _InIter>::do_date_order() const
1611     { return time_base::no_order; }
1612
1613   // Recursively expand a strftime format string and parse it.  Starts w/ %x
1614   // and %X from do_get_time() and do_get_date(), which translate to a more
1615   // specific string, which may contain yet more strings.  I.e. %x => %r =>
1616   // %H:%M:%S => extracted characters.
1617   template<typename _CharT, typename _InIter>
1618     void
1619     time_get<_CharT, _InIter>::
1620     _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
1621                           ios_base::iostate& __err, tm* __tm,
1622                           const _CharT* __format) const
1623     {
1624       const locale __loc = __io.getloc();
1625       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1626       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1627       const size_t __len = char_traits<_CharT>::length(__format);
1628
1629       for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
1630         {
1631           if (__ctype.narrow(__format[__i], 0) == '%')
1632             {
1633               // Verify valid formatting code, attempt to extract.
1634               char __c = __ctype.narrow(__format[++__i], 0);
1635               int __mem = 0;
1636               if (__c == 'E' || __c == 'O')
1637                 __c = __ctype.narrow(__format[++__i], 0);
1638               switch (__c)
1639                 {
1640                   const char* __cs;
1641                   _CharT __wcs[10];
1642                 case 'a':
1643                   // Abbreviated weekday name [tm_wday]
1644                   const char_type*  __days1[7];
1645                   __tp._M_days_abbreviated(__days1);
1646                   _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7,
1647                                   __ctype, __err);
1648                   break;
1649                 case 'A':
1650                   // Weekday name [tm_wday].
1651                   const char_type*  __days2[7];
1652                   __tp._M_days(__days2);
1653                   _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7,
1654                                   __ctype, __err);
1655                   break;
1656                 case 'h':
1657                 case 'b':
1658                   // Abbreviated month name [tm_mon]
1659                   const char_type*  __months1[12];
1660                   __tp._M_months_abbreviated(__months1);
1661                   _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12,
1662                                   __ctype, __err);
1663                   break;
1664                 case 'B':
1665                   // Month name [tm_mon].
1666                   const char_type*  __months2[12];
1667                   __tp._M_months(__months2);
1668                   _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12,
1669                                   __ctype, __err);
1670                   break;
1671                 case 'c':
1672                   // Default time and date representation.
1673                   const char_type*  __dt[2];
1674                   __tp._M_date_time_formats(__dt);
1675                   _M_extract_via_format(__beg, __end, __io, __err, __tm,
1676                                         __dt[0]);
1677                   break;
1678                 case 'd':
1679                   // Day [01, 31]. [tm_mday]
1680                   _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
1681                                  __ctype, __err);
1682                   break;
1683                 case 'e':
1684                   // Day [1, 31], with single digits preceded by
1685                   // space. [tm_mday]
1686                   if (__ctype.is(ctype_base::space, *__beg))
1687                     _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 1,
1688                                    __ctype, __err);
1689                   else
1690                     _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 2,
1691                                    __ctype, __err);
1692                   break;
1693                 case 'D':
1694                   // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1695                   __cs = "%m/%d/%y";
1696                   __ctype.widen(__cs, __cs + 9, __wcs);
1697                   _M_extract_via_format(__beg, __end, __io, __err, __tm,
1698                                         __wcs);
1699                   break;
1700                 case 'H':
1701                   // Hour [00, 23]. [tm_hour]
1702                   _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1703                                  __ctype, __err);
1704                   break;
1705                 case 'I':
1706                   // Hour [01, 12]. [tm_hour]
1707                   _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
1708                                  __ctype, __err);
1709                   break;
1710                 case 'm':
1711                   // Month [01, 12]. [tm_mon]
1712                   _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype,
1713                                  __err);
1714                   if (!__err)
1715                     __tm->tm_mon = __mem - 1;
1716                   break;
1717                 case 'M':
1718                   // Minute [00, 59]. [tm_min]
1719                   _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1720                                  __ctype, __err);
1721                   break;
1722                 case 'n':
1723                   if (__ctype.narrow(*__beg, 0) == '\n')
1724                     ++__beg;
1725                   else
1726                     __err |= ios_base::failbit;
1727                   break;
1728                 case 'R':
1729                   // Equivalent to (%H:%M).
1730                   __cs = "%H:%M";
1731                   __ctype.widen(__cs, __cs + 6, __wcs);
1732                   _M_extract_via_format(__beg, __end, __io, __err, __tm,
1733                                         __wcs);
1734                   break;
1735                 case 'S':
1736                   // Seconds.
1737                   _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
1738                                  __ctype, __err);
1739                   break;
1740                 case 't':
1741                   if (__ctype.narrow(*__beg, 0) == '\t')
1742                     ++__beg;
1743                   else
1744                     __err |= ios_base::failbit;
1745                   break;
1746                 case 'T':
1747                   // Equivalent to (%H:%M:%S).
1748                   __cs = "%H:%M:%S";
1749                   __ctype.widen(__cs, __cs + 9, __wcs);
1750                   _M_extract_via_format(__beg, __end, __io, __err, __tm,
1751                                         __wcs);
1752                   break;
1753                 case 'x':
1754                   // Locale's date.
1755                   const char_type*  __dates[2];
1756                   __tp._M_date_formats(__dates);
1757                   _M_extract_via_format(__beg, __end, __io, __err, __tm,
1758                                         __dates[0]);
1759                   break;
1760                 case 'X':
1761                   // Locale's time.
1762                   const char_type*  __times[2];
1763                   __tp._M_time_formats(__times);
1764                   _M_extract_via_format(__beg, __end, __io, __err, __tm,
1765                                         __times[0]);
1766                   break;
1767                 case 'y':
1768                 case 'C': // C99
1769                   // Two digit year. [tm_year]
1770                   _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
1771                                  __ctype, __err);
1772                   break;
1773                 case 'Y':
1774                   // Year [1900). [tm_year]
1775                   _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
1776                                  __ctype, __err);
1777                   if (!__err)
1778                     __tm->tm_year = __mem - 1900;
1779                   break;
1780                 case 'Z':
1781                   // Timezone info.
1782                   if (__ctype.is(ctype_base::upper, *__beg))
1783                     {
1784                       int __tmp;
1785                       _M_extract_name(__beg, __end, __tmp,
1786                                       __timepunct_cache<_CharT>::_S_timezones,
1787                                       14, __ctype, __err);
1788
1789                       // GMT requires special effort.
1790                       if (__beg != __end && !__err && __tmp == 0
1791                           && (*__beg == __ctype.widen('-')
1792                               || *__beg == __ctype.widen('+')))
1793                         {
1794                           _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1795                                           __ctype, __err);
1796                           _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1797                                           __ctype, __err);
1798                         }
1799                     }
1800                   else
1801                     __err |= ios_base::failbit;
1802                   break;
1803                 default:
1804                   // Not recognized.
1805                   __err |= ios_base::failbit;
1806                 }
1807             }
1808           else
1809             {
1810               // Verify format and input match, extract and discard.
1811               if (__format[__i] == *__beg)
1812                 ++__beg;
1813               else
1814                 __err |= ios_base::failbit;
1815             }
1816         }
1817     }
1818
1819   template<typename _CharT, typename _InIter>
1820     void
1821     time_get<_CharT, _InIter>::
1822     _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
1823                    int __min, int __max, size_t __len,
1824                    const ctype<_CharT>& __ctype,
1825                    ios_base::iostate& __err) const
1826     {
1827       // As-is works for __len = 1, 2, 4, the values actually used.
1828       int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
1829
1830       ++__min;
1831       size_t __i = 0;
1832       int __value = 0;
1833       for (; __beg != __end && __i < __len; ++__beg, ++__i)
1834         {
1835           const char __c = __ctype.narrow(*__beg, '*');
1836           if (__c >= '0' && __c <= '9')
1837             {
1838               __value = __value * 10 + (__c - '0');
1839               const int __valuec = __value * __mult;
1840               if (__valuec > __max || __valuec + __mult < __min)
1841                 break;
1842               __mult /= 10;
1843             }
1844           else
1845             break;
1846         }
1847       if (__i == __len)
1848         __member = __value;
1849       else
1850         __err |= ios_base::failbit;
1851     }
1852
1853   // Assumptions:
1854   // All elements in __names are unique.
1855   template<typename _CharT, typename _InIter>
1856     void
1857     time_get<_CharT, _InIter>::
1858     _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
1859                     const _CharT** __names, size_t __indexlen,
1860                     const ctype<_CharT>& __ctype,
1861                     ios_base::iostate& __err) const
1862     {
1863       typedef char_traits<_CharT>               __traits_type;
1864       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
1865                                                           * __indexlen));
1866       size_t __nmatches = 0;
1867       size_t __pos = 0;
1868       bool __testvalid = true;
1869       const char_type* __name;
1870
1871       // Look for initial matches.
1872       // NB: Some of the locale data is in the form of all lowercase
1873       // names, and some is in the form of initially-capitalized
1874       // names. Look for both.
1875       if (__beg != __end)
1876         {
1877           const char_type __c = *__beg;
1878           for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
1879             if (__c == __names[__i1][0]
1880                 || __c == __ctype.toupper(__names[__i1][0]))
1881               __matches[__nmatches++] = __i1;
1882         }
1883
1884       while (__nmatches > 1)
1885         {
1886           // Find smallest matching string.
1887           size_t __minlen = 10;
1888           for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
1889             __minlen = std::min(__minlen,
1890                                 __traits_type::length(__names[__matches[__i2]]));
1891           ++__beg;
1892           if (__pos < __minlen && __beg != __end)
1893             {
1894               ++__pos;
1895               for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
1896                 {
1897                   __name = __names[__matches[__i3]];
1898                   if (__name[__pos] != *__beg)
1899                     __matches[__i3] = __matches[--__nmatches];
1900                 }
1901             }
1902           else
1903             break;
1904         }
1905
1906       if (__nmatches == 1)
1907         {
1908           // If there was only one match, the first compare is redundant.
1909           if (__pos == 0)
1910             {
1911               ++__pos;
1912               ++__beg;
1913             }
1914
1915           // Make sure found name is completely extracted.
1916           __name = __names[__matches[0]];
1917           const size_t __len = __traits_type::length(__name);
1918           while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
1919             ++__beg, ++__pos;
1920
1921           if (__len == __pos)
1922             __member = __matches[0];
1923           else
1924             __testvalid = false;
1925         }
1926       else
1927         __testvalid = false;
1928       if (!__testvalid)
1929         __err |= ios_base::failbit;
1930     }
1931
1932   template<typename _CharT, typename _InIter>
1933     _InIter
1934     time_get<_CharT, _InIter>::
1935     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1936                 ios_base::iostate& __err, tm* __tm) const
1937     {
1938       _CharT __wcs[3];
1939       const char* __cs = "%X";
1940       const locale __loc = __io.getloc();
1941       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1942       __ctype.widen(__cs, __cs + 3, __wcs);
1943       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1944       if (__beg == __end)
1945         __err |= ios_base::eofbit;
1946       return __beg;
1947     }
1948
1949   template<typename _CharT, typename _InIter>
1950     _InIter
1951     time_get<_CharT, _InIter>::
1952     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1953                 ios_base::iostate& __err, tm* __tm) const
1954     {
1955       _CharT __wcs[3];
1956       const char* __cs = "%x";
1957       const locale __loc = __io.getloc();
1958       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1959       __ctype.widen(__cs, __cs + 3, __wcs);
1960       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
1961       if (__beg == __end)
1962         __err |= ios_base::eofbit;
1963       return __beg;
1964     }
1965
1966   template<typename _CharT, typename _InIter>
1967     _InIter
1968     time_get<_CharT, _InIter>::
1969     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
1970                    ios_base::iostate& __err, tm* __tm) const
1971     {
1972       typedef char_traits<_CharT>               __traits_type;
1973       const locale __loc = __io.getloc();
1974       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1975       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1976       const char_type*  __days[7];
1977       __tp._M_days_abbreviated(__days);
1978       int __tmpwday;
1979       _M_extract_name(__beg, __end, __tmpwday, __days, 7, __ctype, __err);
1980
1981       // Check to see if non-abbreviated name exists, and extract.
1982       // NB: Assumes both _M_days and _M_days_abbreviated organized in
1983       // exact same order, first to last, such that the resulting
1984       // __days array with the same index points to a day, and that
1985       // day's abbreviated form.
1986       // NB: Also assumes that an abbreviated name is a subset of the name.
1987       if (!__err)
1988         {
1989           size_t __pos = __traits_type::length(__days[__tmpwday]);
1990           __tp._M_days(__days);
1991           const char_type* __name = __days[__tmpwday];
1992           if (__name[__pos] == *__beg)
1993             {
1994               // Extract the rest of it.
1995               const size_t __len = __traits_type::length(__name);
1996               while (__pos < __len && __beg != __end
1997                      && __name[__pos] == *__beg)
1998                 ++__beg, ++__pos;
1999               if (__len != __pos)
2000                 __err |= ios_base::failbit;
2001             }
2002           if (!__err)
2003             __tm->tm_wday = __tmpwday;
2004         }
2005       if (__beg == __end)
2006         __err |= ios_base::eofbit;
2007       return __beg;
2008      }
2009
2010   template<typename _CharT, typename _InIter>
2011     _InIter
2012     time_get<_CharT, _InIter>::
2013     do_get_monthname(iter_type __beg, iter_type __end,
2014                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
2015     {
2016       typedef char_traits<_CharT>               __traits_type;
2017       const locale __loc = __io.getloc();
2018       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2019       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2020       const char_type*  __months[12];
2021       __tp._M_months_abbreviated(__months);
2022       int __tmpmon;
2023       _M_extract_name(__beg, __end, __tmpmon, __months, 12, __ctype, __err);
2024
2025       // Check to see if non-abbreviated name exists, and extract.
2026       // NB: Assumes both _M_months and _M_months_abbreviated organized in
2027       // exact same order, first to last, such that the resulting
2028       // __months array with the same index points to a month, and that
2029       // month's abbreviated form.
2030       // NB: Also assumes that an abbreviated name is a subset of the name.
2031       if (!__err)
2032         {
2033           size_t __pos = __traits_type::length(__months[__tmpmon]);
2034           __tp._M_months(__months);
2035           const char_type* __name = __months[__tmpmon];
2036           if (__name[__pos] == *__beg)
2037             {
2038               // Extract the rest of it.
2039               const size_t __len = __traits_type::length(__name);
2040               while (__pos < __len && __beg != __end
2041                      && __name[__pos] == *__beg)
2042                 ++__beg, ++__pos;
2043               if (__len != __pos)
2044                 __err |= ios_base::failbit;
2045             }
2046           if (!__err)
2047             __tm->tm_mon = __tmpmon;
2048         }
2049
2050       if (__beg == __end)
2051         __err |= ios_base::eofbit;
2052       return __beg;
2053     }
2054
2055   template<typename _CharT, typename _InIter>
2056     _InIter
2057     time_get<_CharT, _InIter>::
2058     do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
2059                 ios_base::iostate& __err, tm* __tm) const
2060     {
2061       const locale __loc = __io.getloc();
2062       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2063
2064       size_t __i = 0;
2065       int __value = 0;
2066       for (; __beg != __end && __i < 4; ++__beg, ++__i)
2067         {
2068           const char __c = __ctype.narrow(*__beg, '*');
2069           if (__c >= '0' && __c <= '9')
2070             __value = __value * 10 + (__c - '0');
2071           else
2072             break;
2073         }
2074       if (__i == 2 || __i == 4)
2075         __tm->tm_year = __i == 2 ? __value : __value - 1900;
2076       else
2077         __err |= ios_base::failbit;
2078       if (__beg == __end)
2079         __err |= ios_base::eofbit;
2080       return __beg;
2081     }
2082
2083   template<typename _CharT, typename _OutIter>
2084     _OutIter
2085     time_put<_CharT, _OutIter>::
2086     put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
2087         const _CharT* __beg, const _CharT* __end) const
2088     {
2089       const locale __loc = __io.getloc();
2090       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
2091       for (; __beg != __end; ++__beg)
2092         if (__ctype.narrow(*__beg, 0) != '%')
2093           {
2094             *__s = *__beg;
2095             ++__s;
2096           }
2097         else if (++__beg != __end)
2098           {
2099             char __format;
2100             char __mod = 0;
2101             const char __c = __ctype.narrow(*__beg, 0);
2102             if (__c != 'E' && __c != 'O')
2103               __format = __c;
2104             else if (++__beg != __end)
2105               {
2106                 __mod = __c;
2107                 __format = __ctype.narrow(*__beg, 0);
2108               }
2109             else
2110               break;
2111             __s = this->do_put(__s, __io, __fill, __tm,
2112                                __format, __mod);
2113           }
2114         else
2115           break;
2116       return __s;
2117     }
2118
2119   template<typename _CharT, typename _OutIter>
2120     _OutIter
2121     time_put<_CharT, _OutIter>::
2122     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
2123            char __format, char __mod) const
2124     {
2125       const locale __loc = __io.getloc();
2126       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
2127       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
2128
2129       // NB: This size is arbitrary. Should this be a data member,
2130       // initialized at construction?
2131       const size_t __maxlen = 64;
2132       char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type)
2133                                                                   * __maxlen));
2134
2135       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
2136       // is possible that the format character will be longer than one
2137       // character. Possibilities include 'E' or 'O' followed by a
2138       // format character: if __mod is not the default argument, assume
2139       // it's a valid modifier.
2140       char_type __fmt[4];
2141       __fmt[0] = __ctype.widen('%');
2142       if (!__mod)
2143         {
2144           __fmt[1] = __format;
2145           __fmt[2] = char_type();
2146         }
2147       else
2148         {
2149           __fmt[1] = __mod;
2150           __fmt[2] = __format;
2151           __fmt[3] = char_type();
2152         }
2153
2154       __tp._M_put(__res, __maxlen, __fmt, __tm);
2155
2156       // Write resulting, fully-formatted string to output iterator.
2157       return std::__write(__s, __res, char_traits<char_type>::length(__res));
2158     }
2159
2160
2161   // Generic version does nothing.
2162   template<typename _CharT>
2163     int
2164     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
2165     { return 0; }
2166
2167   // Generic version does nothing.
2168   template<typename _CharT>
2169     size_t
2170     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
2171     { return 0; }
2172
2173   template<typename _CharT>
2174     int
2175     collate<_CharT>::
2176     do_compare(const _CharT* __lo1, const _CharT* __hi1,
2177                const _CharT* __lo2, const _CharT* __hi2) const
2178     {
2179       // strcoll assumes zero-terminated strings so we make a copy
2180       // and then put a zero at the end.
2181       const string_type __one(__lo1, __hi1);
2182       const string_type __two(__lo2, __hi2);
2183
2184       const _CharT* __p = __one.c_str();
2185       const _CharT* __pend = __one.data() + __one.length();
2186       const _CharT* __q = __two.c_str();
2187       const _CharT* __qend = __two.data() + __two.length();
2188
2189       // strcoll stops when it sees a nul character so we break
2190       // the strings into zero-terminated substrings and pass those
2191       // to strcoll.
2192       for (;;)
2193         {
2194           const int __res = _M_compare(__p, __q);
2195           if (__res)
2196             return __res;
2197
2198           __p += char_traits<_CharT>::length(__p);
2199           __q += char_traits<_CharT>::length(__q);
2200           if (__p == __pend && __q == __qend)
2201             return 0;
2202           else if (__p == __pend)
2203             return -1;
2204           else if (__q == __qend)
2205             return 1;
2206
2207           __p++;
2208           __q++;
2209         }
2210     }
2211
2212   template<typename _CharT>
2213     typename collate<_CharT>::string_type
2214     collate<_CharT>::
2215     do_transform(const _CharT* __lo, const _CharT* __hi) const
2216     {
2217       // strxfrm assumes zero-terminated strings so we make a copy
2218       string_type __str(__lo, __hi);
2219
2220       const _CharT* __p = __str.c_str();
2221       const _CharT* __pend = __str.data() + __str.length();
2222
2223       size_t __len = (__hi - __lo) * 2;
2224
2225       string_type __ret;
2226
2227       // strxfrm stops when it sees a nul character so we break
2228       // the string into zero-terminated substrings and pass those
2229       // to strxfrm.
2230       for (;;)
2231         {
2232           // First try a buffer perhaps big enough.
2233           _CharT* __c =
2234             static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
2235           size_t __res = _M_transform(__c, __p, __len);
2236           // If the buffer was not large enough, try again with the
2237           // correct size.
2238           if (__res >= __len)
2239             {
2240               __len = __res + 1;
2241               __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
2242                                                           * __len));
2243               __res = _M_transform(__c, __p, __res + 1);
2244             }
2245
2246           __ret.append(__c, __res);
2247           __p += char_traits<_CharT>::length(__p);
2248           if (__p == __pend)
2249             return __ret;
2250
2251           __p++;
2252           __ret.push_back(_CharT());
2253         }
2254     }
2255
2256   template<typename _CharT>
2257     long
2258     collate<_CharT>::
2259     do_hash(const _CharT* __lo, const _CharT* __hi) const
2260     {
2261       unsigned long __val = 0;
2262       for (; __lo < __hi; ++__lo)
2263         __val = *__lo + ((__val << 7) |
2264                        (__val >> (numeric_limits<unsigned long>::digits - 7)));
2265       return static_cast<long>(__val);
2266     }
2267
2268   // Construct correctly padded string, as per 22.2.2.2.2
2269   // Assumes
2270   // __newlen > __oldlen
2271   // __news is allocated for __newlen size
2272   // Used by both num_put and ostream inserters: if __num,
2273   // internal-adjusted objects are padded according to the rules below
2274   // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
2275   // ones are.
2276
2277   // NB: Of the two parameters, _CharT can be deduced from the
2278   // function arguments. The other (_Traits) has to be explicitly specified.
2279   template<typename _CharT, typename _Traits>
2280     void
2281     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
2282                                    _CharT* __news, const _CharT* __olds,
2283                                    const streamsize __newlen,
2284                                    const streamsize __oldlen, const bool __num)
2285     {
2286       const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
2287       const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
2288
2289       // Padding last.
2290       if (__adjust == ios_base::left)
2291         {
2292           _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen);
2293           _Traits::assign(__news + __oldlen, __plen, __fill);
2294           return;
2295         }
2296
2297       size_t __mod = 0;
2298       if (__adjust == ios_base::internal && __num)
2299         {
2300           // Pad after the sign, if there is one.
2301           // Pad after 0[xX], if there is one.
2302           // Who came up with these rules, anyway? Jeeze.
2303           const locale& __loc = __io._M_getloc();
2304           const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
2305
2306           const bool __testsign = _Traits::eq(__ctype.widen('-'), __olds[0])
2307                                   || _Traits::eq(__ctype.widen('+'), __olds[0]);
2308           const bool __testhex = (_Traits::eq(__ctype.widen('0'), __olds[0])
2309                                   && __oldlen > 1
2310                                   && (_Traits::eq(__ctype.widen('x'), __olds[1])
2311                                       || _Traits::eq(__ctype.widen('X'),
2312                                                      __olds[1])));
2313           if (__testhex)
2314             {
2315               __news[0] = __olds[0];
2316               __news[1] = __olds[1];
2317               __mod = 2;
2318               __news += 2;
2319             }
2320           else if (__testsign)
2321             {
2322               __news[0] = __olds[0];
2323               __mod = 1;
2324               ++__news;
2325             }
2326           // else Padding first.
2327         }
2328       _Traits::assign(__news, __plen, __fill);
2329       _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod),
2330                     __oldlen - __mod);
2331     }
2332
2333   bool
2334   __verify_grouping(const char* __grouping, size_t __grouping_size,
2335                     const string& __grouping_tmp)
2336   {
2337     const size_t __n = __grouping_tmp.size() - 1;
2338     const size_t __min = std::min(__n, __grouping_size - 1);
2339     size_t __i = __n;
2340     bool __test = true;
2341     
2342     // Parsed number groupings have to match the
2343     // numpunct::grouping string exactly, starting at the
2344     // right-most point of the parsed sequence of elements ...
2345     for (size_t __j = 0; __j < __min && __test; --__i, ++__j)
2346       __test = __grouping_tmp[__i] == __grouping[__j];
2347     for (; __i && __test; --__i)
2348       __test = __grouping_tmp[__i] == __grouping[__min];
2349     // ... but the last parsed grouping can be <= numpunct
2350     // grouping.
2351     __test &= __grouping_tmp[0] <= __grouping[__min];
2352     return __test;
2353   }
2354
2355   template<typename _CharT>
2356     _CharT*
2357     __add_grouping(_CharT* __s, _CharT __sep,
2358                    const char* __gbeg, size_t __gsize,
2359                    const _CharT* __first, const _CharT* __last)
2360     {
2361       if (__last - __first > *__gbeg)
2362         {
2363           const bool __bump = __gsize != 1;
2364           __s = std::__add_grouping(__s,  __sep, __gbeg + __bump,
2365                                     __gsize - __bump, __first,
2366                                     __last - *__gbeg);
2367           __first = __last - *__gbeg;
2368           *__s++ = __sep;
2369         }
2370       do
2371         *__s++ = *__first++;
2372       while (__first != __last);
2373       return __s;
2374     }
2375
2376   // Inhibit implicit instantiations for required instantiations,
2377   // which are defined via explicit instantiations elsewhere.
2378   // NB: This syntax is a GNU extension.
2379 #if _GLIBCXX_EXTERN_TEMPLATE
2380   extern template class moneypunct<char, false>;
2381   extern template class moneypunct<char, true>;
2382   extern template class moneypunct_byname<char, false>;
2383   extern template class moneypunct_byname<char, true>;
2384   extern template class money_get<char>;
2385   extern template class money_put<char>;
2386   extern template class numpunct<char>;
2387   extern template class numpunct_byname<char>;
2388   extern template class num_get<char>;
2389   extern template class num_put<char>;
2390   extern template class __timepunct<char>;
2391   extern template class time_put<char>;
2392   extern template class time_put_byname<char>;
2393   extern template class time_get<char>;
2394   extern template class time_get_byname<char>;
2395   extern template class messages<char>;
2396   extern template class messages_byname<char>;
2397   extern template class ctype_byname<char>;
2398   extern template class codecvt_byname<char, char, mbstate_t>;
2399   extern template class collate<char>;
2400   extern template class collate_byname<char>;
2401
2402   extern template
2403     const codecvt<char, char, mbstate_t>&
2404     use_facet<codecvt<char, char, mbstate_t> >(const locale&);
2405
2406   extern template
2407     const collate<char>&
2408     use_facet<collate<char> >(const locale&);
2409
2410   extern template
2411     const numpunct<char>&
2412     use_facet<numpunct<char> >(const locale&);
2413
2414   extern template
2415     const num_put<char>&
2416     use_facet<num_put<char> >(const locale&);
2417
2418   extern template
2419     const num_get<char>&
2420     use_facet<num_get<char> >(const locale&);
2421
2422   extern template
2423     const moneypunct<char, true>&
2424     use_facet<moneypunct<char, true> >(const locale&);
2425
2426   extern template
2427     const moneypunct<char, false>&
2428     use_facet<moneypunct<char, false> >(const locale&);
2429
2430   extern template
2431     const money_put<char>&
2432     use_facet<money_put<char> >(const locale&);
2433
2434   extern template
2435     const money_get<char>&
2436     use_facet<money_get<char> >(const locale&);
2437
2438   extern template
2439     const __timepunct<char>&
2440     use_facet<__timepunct<char> >(const locale&);
2441
2442   extern template
2443     const time_put<char>&
2444     use_facet<time_put<char> >(const locale&);
2445
2446   extern template
2447     const time_get<char>&
2448     use_facet<time_get<char> >(const locale&);
2449
2450   extern template
2451     const messages<char>&
2452     use_facet<messages<char> >(const locale&);
2453
2454   extern template
2455     bool
2456     has_facet<ctype<char> >(const locale&);
2457
2458   extern template
2459     bool
2460     has_facet<codecvt<char, char, mbstate_t> >(const locale&);
2461
2462   extern template
2463     bool
2464     has_facet<collate<char> >(const locale&);
2465
2466   extern template
2467     bool
2468     has_facet<numpunct<char> >(const locale&);
2469
2470   extern template
2471     bool
2472     has_facet<num_put<char> >(const locale&);
2473
2474   extern template
2475     bool
2476     has_facet<num_get<char> >(const locale&);
2477
2478   extern template
2479     bool
2480     has_facet<moneypunct<char> >(const locale&);
2481
2482   extern template
2483     bool
2484     has_facet<money_put<char> >(const locale&);
2485
2486   extern template
2487     bool
2488     has_facet<money_get<char> >(const locale&);
2489
2490   extern template
2491     bool
2492     has_facet<__timepunct<char> >(const locale&);
2493
2494   extern template
2495     bool
2496     has_facet<time_put<char> >(const locale&);
2497
2498   extern template
2499     bool
2500     has_facet<time_get<char> >(const locale&);
2501
2502   extern template
2503     bool
2504     has_facet<messages<char> >(const locale&);
2505
2506 #ifdef _GLIBCXX_USE_WCHAR_T
2507   extern template class moneypunct<wchar_t, false>;
2508   extern template class moneypunct<wchar_t, true>;
2509   extern template class moneypunct_byname<wchar_t, false>;
2510   extern template class moneypunct_byname<wchar_t, true>;
2511   extern template class money_get<wchar_t>;
2512   extern template class money_put<wchar_t>;
2513   extern template class numpunct<wchar_t>;
2514   extern template class numpunct_byname<wchar_t>;
2515   extern template class num_get<wchar_t>;
2516   extern template class num_put<wchar_t>;
2517   extern template class __timepunct<wchar_t>;
2518   extern template class time_put<wchar_t>;
2519   extern template class time_put_byname<wchar_t>;
2520   extern template class time_get<wchar_t>;
2521   extern template class time_get_byname<wchar_t>;
2522   extern template class messages<wchar_t>;
2523   extern template class messages_byname<wchar_t>;
2524   extern template class ctype_byname<wchar_t>;
2525   extern template class codecvt_byname<wchar_t, char, mbstate_t>;
2526   extern template class collate<wchar_t>;
2527   extern template class collate_byname<wchar_t>;
2528
2529   extern template
2530     const codecvt<wchar_t, char, mbstate_t>&
2531     use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
2532
2533   extern template
2534     const collate<wchar_t>&
2535     use_facet<collate<wchar_t> >(const locale&);
2536
2537   extern template
2538     const numpunct<wchar_t>&
2539     use_facet<numpunct<wchar_t> >(const locale&);
2540
2541   extern template
2542     const num_put<wchar_t>&
2543     use_facet<num_put<wchar_t> >(const locale&);
2544
2545   extern template
2546     const num_get<wchar_t>&
2547     use_facet<num_get<wchar_t> >(const locale&);
2548
2549   extern template
2550     const moneypunct<wchar_t, true>&
2551     use_facet<moneypunct<wchar_t, true> >(const locale&);
2552
2553   extern template
2554     const moneypunct<wchar_t, false>&
2555     use_facet<moneypunct<wchar_t, false> >(const locale&);
2556
2557   extern template
2558     const money_put<wchar_t>&
2559     use_facet<money_put<wchar_t> >(const locale&);
2560
2561   extern template
2562     const money_get<wchar_t>&
2563     use_facet<money_get<wchar_t> >(const locale&);
2564
2565   extern template
2566     const __timepunct<wchar_t>&
2567     use_facet<__timepunct<wchar_t> >(const locale&);
2568
2569   extern template
2570     const time_put<wchar_t>&
2571     use_facet<time_put<wchar_t> >(const locale&);
2572
2573   extern template
2574     const time_get<wchar_t>&
2575     use_facet<time_get<wchar_t> >(const locale&);
2576
2577   extern template
2578     const messages<wchar_t>&
2579     use_facet<messages<wchar_t> >(const locale&);
2580
2581  extern template
2582     bool
2583     has_facet<ctype<wchar_t> >(const locale&);
2584
2585   extern template
2586     bool
2587     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
2588
2589   extern template
2590     bool
2591     has_facet<collate<wchar_t> >(const locale&);
2592
2593   extern template
2594     bool
2595     has_facet<numpunct<wchar_t> >(const locale&);
2596
2597   extern template
2598     bool
2599     has_facet<num_put<wchar_t> >(const locale&);
2600
2601   extern template
2602     bool
2603     has_facet<num_get<wchar_t> >(const locale&);
2604
2605   extern template
2606     bool
2607     has_facet<moneypunct<wchar_t> >(const locale&);
2608
2609   extern template
2610     bool
2611     has_facet<money_put<wchar_t> >(const locale&);
2612
2613   extern template
2614     bool
2615     has_facet<money_get<wchar_t> >(const locale&);
2616
2617   extern template
2618     bool
2619     has_facet<__timepunct<wchar_t> >(const locale&);
2620
2621   extern template
2622     bool
2623     has_facet<time_put<wchar_t> >(const locale&);
2624
2625   extern template
2626     bool
2627     has_facet<time_get<wchar_t> >(const locale&);
2628
2629   extern template
2630     bool
2631     has_facet<messages<wchar_t> >(const locale&);
2632 #endif
2633 #endif
2634 } // namespace std
2635
2636 #endif