Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / libstdc++-v3 / include / bits / locale_facets_nonio.tcc
blobf32ad7fdb1df39bbf3fff465a9b9df2ff6f901f2
1 // Locale support -*- C++ -*-
3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file locale_facets_nonio.tcc
31  *  This is an internal header file, included by other library headers.
32  *  You should not attempt to use it directly.
33  */
35 #ifndef _LOCALE_FACETS_NONIO_TCC
36 #define _LOCALE_FACETS_NONIO_TCC 1
38 #pragma GCC system_header
40 _GLIBCXX_BEGIN_NAMESPACE(std)
42   template<typename _CharT, bool _Intl>
43     struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
44     {
45       const __moneypunct_cache<_CharT, _Intl>*
46       operator() (const locale& __loc) const
47       {
48         const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
49         const locale::facet** __caches = __loc._M_impl->_M_caches;
50         if (!__caches[__i])
51           {
52             __moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
53             __try
54               {
55                 __tmp = new __moneypunct_cache<_CharT, _Intl>;
56                 __tmp->_M_cache(__loc);
57               }
58             __catch(...)
59               {
60                 delete __tmp;
61                 __throw_exception_again;
62               }
63             __loc._M_impl->_M_install_cache(__tmp, __i);
64           }
65         return static_cast<
66           const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
67       }
68     };
70   template<typename _CharT, bool _Intl>
71     void
72     __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
73     {
74       _M_allocated = true;
76       const moneypunct<_CharT, _Intl>& __mp =
77         use_facet<moneypunct<_CharT, _Intl> >(__loc);
79       _M_grouping_size = __mp.grouping().size();
80       char* __grouping = new char[_M_grouping_size];
81       __mp.grouping().copy(__grouping, _M_grouping_size);
82       _M_grouping = __grouping;
83       _M_use_grouping = (_M_grouping_size
84                          && static_cast<signed char>(_M_grouping[0]) > 0
85                          && (_M_grouping[0]
86                              != __gnu_cxx::__numeric_traits<char>::__max));
88       _M_decimal_point = __mp.decimal_point();
89       _M_thousands_sep = __mp.thousands_sep();
90       _M_frac_digits = __mp.frac_digits();
91       
92       _M_curr_symbol_size = __mp.curr_symbol().size();
93       _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
94       __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
95       _M_curr_symbol = __curr_symbol;
96       
97       _M_positive_sign_size = __mp.positive_sign().size();
98       _CharT* __positive_sign = new _CharT[_M_positive_sign_size];
99       __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
100       _M_positive_sign = __positive_sign;
102       _M_negative_sign_size = __mp.negative_sign().size();
103       _CharT* __negative_sign = new _CharT[_M_negative_sign_size];
104       __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
105       _M_negative_sign = __negative_sign;
106       
107       _M_pos_format = __mp.pos_format();
108       _M_neg_format = __mp.neg_format();
110       const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
111       __ct.widen(money_base::_S_atoms,
112                  money_base::_S_atoms + money_base::_S_end, _M_atoms);
113     }
115 _GLIBCXX_BEGIN_LDBL_NAMESPACE
117   template<typename _CharT, typename _InIter>
118     template<bool _Intl>
119       _InIter
120       money_get<_CharT, _InIter>::
121       _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
122                  ios_base::iostate& __err, string& __units) const
123       {
124         typedef char_traits<_CharT>                       __traits_type;
125         typedef typename string_type::size_type           size_type;    
126         typedef money_base::part                          part;
127         typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
128         
129         const locale& __loc = __io._M_getloc();
130         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
132         __use_cache<__cache_type> __uc;
133         const __cache_type* __lc = __uc(__loc);
134         const char_type* __lit = __lc->_M_atoms;
136         // Deduced sign.
137         bool __negative = false;
138         // Sign size.
139         size_type __sign_size = 0;
140         // True if sign is mandatory.
141         const bool __mandatory_sign = (__lc->_M_positive_sign_size
142                                        && __lc->_M_negative_sign_size);
143         // String of grouping info from thousands_sep plucked from __units.
144         string __grouping_tmp;
145         if (__lc->_M_use_grouping)
146           __grouping_tmp.reserve(32);
147         // Last position before the decimal point.
148         int __last_pos = 0;
149         // Separator positions, then, possibly, fractional digits.
150         int __n = 0;
151         // If input iterator is in a valid state.
152         bool __testvalid = true;
153         // Flag marking when a decimal point is found.
154         bool __testdecfound = false;
156         // The tentative returned string is stored here.
157         string __res;
158         __res.reserve(32);
160         const char_type* __lit_zero = __lit + money_base::_S_zero;
161         const money_base::pattern __p = __lc->_M_neg_format;
162         for (int __i = 0; __i < 4 && __testvalid; ++__i)
163           {
164             const part __which = static_cast<part>(__p.field[__i]);
165             switch (__which)
166               {
167               case money_base::symbol:
168                 // According to 22.2.6.1.2, p2, symbol is required
169                 // if (__io.flags() & ios_base::showbase), otherwise
170                 // is optional and consumed only if other characters
171                 // are needed to complete the format.
172                 if (__io.flags() & ios_base::showbase || __sign_size > 1
173                     || __i == 0
174                     || (__i == 1 && (__mandatory_sign
175                                      || (static_cast<part>(__p.field[0])
176                                          == money_base::sign)
177                                      || (static_cast<part>(__p.field[2])
178                                          == money_base::space)))
179                     || (__i == 2 && ((static_cast<part>(__p.field[3])
180                                       == money_base::value)
181                                      || (__mandatory_sign
182                                          && (static_cast<part>(__p.field[3])
183                                              == money_base::sign)))))
184                   {
185                     const size_type __len = __lc->_M_curr_symbol_size;
186                     size_type __j = 0;
187                     for (; __beg != __end && __j < __len
188                            && *__beg == __lc->_M_curr_symbol[__j];
189                          ++__beg, ++__j);
190                     if (__j != __len
191                         && (__j || __io.flags() & ios_base::showbase))
192                       __testvalid = false;
193                   }
194                 break;
195               case money_base::sign:
196                 // Sign might not exist, or be more than one character long.
197                 if (__lc->_M_positive_sign_size && __beg != __end
198                     && *__beg == __lc->_M_positive_sign[0])
199                   {
200                     __sign_size = __lc->_M_positive_sign_size;
201                     ++__beg;
202                   }
203                 else if (__lc->_M_negative_sign_size && __beg != __end
204                          && *__beg == __lc->_M_negative_sign[0])
205                   {
206                     __negative = true;
207                     __sign_size = __lc->_M_negative_sign_size;
208                     ++__beg;
209                   }
210                 else if (__lc->_M_positive_sign_size
211                          && !__lc->_M_negative_sign_size)
212                   // "... if no sign is detected, the result is given the sign
213                   // that corresponds to the source of the empty string"
214                   __negative = true;
215                 else if (__mandatory_sign)
216                   __testvalid = false;
217                 break;
218               case money_base::value:
219                 // Extract digits, remove and stash away the
220                 // grouping of found thousands separators.
221                 for (; __beg != __end; ++__beg)
222                   {
223                     const char_type __c = *__beg;
224                     const char_type* __q = __traits_type::find(__lit_zero, 
225                                                                10, __c);
226                     if (__q != 0)
227                       {
228                         __res += money_base::_S_atoms[__q - __lit];
229                         ++__n;
230                       }
231                     else if (__c == __lc->_M_decimal_point 
232                              && !__testdecfound)
233                       {
234                         if (__lc->_M_frac_digits <= 0)
235                           break;
237                         __last_pos = __n;
238                         __n = 0;
239                         __testdecfound = true;
240                       }
241                     else if (__lc->_M_use_grouping
242                              && __c == __lc->_M_thousands_sep
243                              && !__testdecfound)
244                       {
245                         if (__n)
246                           {
247                             // Mark position for later analysis.
248                             __grouping_tmp += static_cast<char>(__n);
249                             __n = 0;
250                           }
251                         else
252                           {
253                             __testvalid = false;
254                             break;
255                           }
256                       }
257                     else
258                       break;
259                   }
260                 if (__res.empty())
261                   __testvalid = false;
262                 break;
263               case money_base::space:
264                 // At least one space is required.
265                 if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
266                   ++__beg;
267                 else
268                   __testvalid = false;
269               case money_base::none:
270                 // Only if not at the end of the pattern.
271                 if (__i != 3)
272                   for (; __beg != __end
273                          && __ctype.is(ctype_base::space, *__beg); ++__beg);
274                 break;
275               }
276           }
278         // Need to get the rest of the sign characters, if they exist.
279         if (__sign_size > 1 && __testvalid)
280           {
281             const char_type* __sign = __negative ? __lc->_M_negative_sign
282                                                  : __lc->_M_positive_sign;
283             size_type __i = 1;
284             for (; __beg != __end && __i < __sign_size
285                    && *__beg == __sign[__i]; ++__beg, ++__i);
286             
287             if (__i != __sign_size)
288               __testvalid = false;
289           }
291         if (__testvalid)
292           {
293             // Strip leading zeros.
294             if (__res.size() > 1)
295               {
296                 const size_type __first = __res.find_first_not_of('0');
297                 const bool __only_zeros = __first == string::npos;
298                 if (__first)
299                   __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
300               }
302             // 22.2.6.1.2, p4
303             if (__negative && __res[0] != '0')
304               __res.insert(__res.begin(), '-');
305             
306             // Test for grouping fidelity.
307             if (__grouping_tmp.size())
308               {
309                 // Add the ending grouping.
310                 __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
311                                                                    : __n);
312                 if (!std::__verify_grouping(__lc->_M_grouping,
313                                             __lc->_M_grouping_size,
314                                             __grouping_tmp))
315                   __err |= ios_base::failbit;
316               }
317             
318             // Iff not enough digits were supplied after the decimal-point.
319             if (__testdecfound && __n != __lc->_M_frac_digits)
320               __testvalid = false;
321           }
323         // Iff valid sequence is not recognized.
324         if (!__testvalid)
325           __err |= ios_base::failbit;
326         else
327           __units.swap(__res);
328         
329         // Iff no more characters are available.
330         if (__beg == __end)
331           __err |= ios_base::eofbit;
332         return __beg;
333       }
335 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
336   template<typename _CharT, typename _InIter>
337     _InIter
338     money_get<_CharT, _InIter>::
339     __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
340              ios_base::iostate& __err, double& __units) const
341     {
342       string __str;
343       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
344                      : _M_extract<false>(__beg, __end, __io, __err, __str);
345       std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
346       return __beg;
347     }
348 #endif
350   template<typename _CharT, typename _InIter>
351     _InIter
352     money_get<_CharT, _InIter>::
353     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
354            ios_base::iostate& __err, long double& __units) const
355     {
356       string __str;
357       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
358                      : _M_extract<false>(__beg, __end, __io, __err, __str);
359       std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
360       return __beg;
361     }
363   template<typename _CharT, typename _InIter>
364     _InIter
365     money_get<_CharT, _InIter>::
366     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
367            ios_base::iostate& __err, string_type& __digits) const
368     {
369       typedef typename string::size_type                  size_type;
371       const locale& __loc = __io._M_getloc();
372       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
374       string __str;
375       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
376                      : _M_extract<false>(__beg, __end, __io, __err, __str);
377       const size_type __len = __str.size();
378       if (__len)
379         {
380           __digits.resize(__len);
381           __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]);
382         }
383       return __beg;
384     }
386   template<typename _CharT, typename _OutIter>
387     template<bool _Intl>
388       _OutIter
389       money_put<_CharT, _OutIter>::
390       _M_insert(iter_type __s, ios_base& __io, char_type __fill,
391                 const string_type& __digits) const
392       {
393         typedef typename string_type::size_type           size_type;
394         typedef money_base::part                          part;
395         typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
396       
397         const locale& __loc = __io._M_getloc();
398         const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
400         __use_cache<__cache_type> __uc;
401         const __cache_type* __lc = __uc(__loc);
402         const char_type* __lit = __lc->_M_atoms;
404         // Determine if negative or positive formats are to be used, and
405         // discard leading negative_sign if it is present.
406         const char_type* __beg = __digits.data();
408         money_base::pattern __p;
409         const char_type* __sign;
410         size_type __sign_size;
411         if (!(*__beg == __lit[money_base::_S_minus]))
412           {
413             __p = __lc->_M_pos_format;
414             __sign = __lc->_M_positive_sign;
415             __sign_size = __lc->_M_positive_sign_size;
416           }
417         else
418           {
419             __p = __lc->_M_neg_format;
420             __sign = __lc->_M_negative_sign;
421             __sign_size = __lc->_M_negative_sign_size;
422             if (__digits.size())
423               ++__beg;
424           }
425        
426         // Look for valid numbers in the ctype facet within input digits.
427         size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
428                                            __beg + __digits.size()) - __beg;
429         if (__len)
430           {
431             // Assume valid input, and attempt to format.
432             // Break down input numbers into base components, as follows:
433             //   final_value = grouped units + (decimal point) + (digits)
434             string_type __value;
435             __value.reserve(2 * __len);
437             // Add thousands separators to non-decimal digits, per
438             // grouping rules.
439             long __paddec = __len - __lc->_M_frac_digits;
440             if (__paddec > 0)
441               {
442                 if (__lc->_M_frac_digits < 0)
443                   __paddec = __len;
444                 if (__lc->_M_grouping_size)
445                   {
446                     __value.assign(2 * __paddec, char_type());
447                     _CharT* __vend = 
448                       std::__add_grouping(&__value[0], __lc->_M_thousands_sep,
449                                           __lc->_M_grouping,
450                                           __lc->_M_grouping_size,
451                                           __beg, __beg + __paddec);
452                     __value.erase(__vend - &__value[0]);
453                   }
454                 else
455                   __value.assign(__beg, __paddec);
456               }
458             // Deal with decimal point, decimal digits.
459             if (__lc->_M_frac_digits > 0)
460               {
461                 __value += __lc->_M_decimal_point;
462                 if (__paddec >= 0)
463                   __value.append(__beg + __paddec, __lc->_M_frac_digits);
464                 else
465                   {
466                     // Have to pad zeros in the decimal position.
467                     __value.append(-__paddec, __lit[money_base::_S_zero]);
468                     __value.append(__beg, __len);
469                   }
470               }
471   
472             // Calculate length of resulting string.
473             const ios_base::fmtflags __f = __io.flags() 
474                                            & ios_base::adjustfield;
475             __len = __value.size() + __sign_size;
476             __len += ((__io.flags() & ios_base::showbase)
477                       ? __lc->_M_curr_symbol_size : 0);
479             string_type __res;
480             __res.reserve(2 * __len);
481             
482             const size_type __width = static_cast<size_type>(__io.width());  
483             const bool __testipad = (__f == ios_base::internal
484                                      && __len < __width);
485             // Fit formatted digits into the required pattern.
486             for (int __i = 0; __i < 4; ++__i)
487               {
488                 const part __which = static_cast<part>(__p.field[__i]);
489                 switch (__which)
490                   {
491                   case money_base::symbol:
492                     if (__io.flags() & ios_base::showbase)
493                       __res.append(__lc->_M_curr_symbol,
494                                    __lc->_M_curr_symbol_size);
495                     break;
496                   case money_base::sign:
497                     // Sign might not exist, or be more than one
498                     // character long. In that case, add in the rest
499                     // below.
500                     if (__sign_size)
501                       __res += __sign[0];
502                     break;
503                   case money_base::value:
504                     __res += __value;
505                     break;
506                   case money_base::space:
507                     // At least one space is required, but if internal
508                     // formatting is required, an arbitrary number of
509                     // fill spaces will be necessary.
510                     if (__testipad)
511                       __res.append(__width - __len, __fill);
512                     else
513                       __res += __fill;
514                     break;
515                   case money_base::none:
516                     if (__testipad)
517                       __res.append(__width - __len, __fill);
518                     break;
519                   }
520               }
521             
522             // Special case of multi-part sign parts.
523             if (__sign_size > 1)
524               __res.append(__sign + 1, __sign_size - 1);
525             
526             // Pad, if still necessary.
527             __len = __res.size();
528             if (__width > __len)
529               {
530                 if (__f == ios_base::left)
531                   // After.
532                   __res.append(__width - __len, __fill);
533                 else
534                   // Before.
535                   __res.insert(0, __width - __len, __fill);
536                 __len = __width;
537               }
538             
539             // Write resulting, fully-formatted string to output iterator.
540             __s = std::__write(__s, __res.data(), __len);
541           }
542         __io.width(0);
543         return __s;    
544       }
546 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
547   template<typename _CharT, typename _OutIter>
548     _OutIter
549     money_put<_CharT, _OutIter>::
550     __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
551              double __units) const
552     { return this->do_put(__s, __intl, __io, __fill, (long double) __units); }
553 #endif
555   template<typename _CharT, typename _OutIter>
556     _OutIter
557     money_put<_CharT, _OutIter>::
558     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
559            long double __units) const
560     {
561       const locale __loc = __io.getloc();
562       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
563 #ifdef _GLIBCXX_USE_C99
564       // First try a buffer perhaps big enough.
565       int __cs_size = 64;
566       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
567       // _GLIBCXX_RESOLVE_LIB_DEFECTS
568       // 328. Bad sprintf format modifier in money_put<>::do_put()
569       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
570                                         "%.*Lf", 0, __units);
571       // If the buffer was not large enough, try again with the correct size.
572       if (__len >= __cs_size)
573         {
574           __cs_size = __len + 1;
575           __cs = static_cast<char*>(__builtin_alloca(__cs_size));
576           __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
577                                         "%.*Lf", 0, __units);
578         }
579 #else
580       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
581       const int __cs_size =
582         __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
583       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
584       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 
585                                         0, __units);
586 #endif
587       string_type __digits(__len, char_type());
588       __ctype.widen(__cs, __cs + __len, &__digits[0]);
589       return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
590                     : _M_insert<false>(__s, __io, __fill, __digits);
591     }
593   template<typename _CharT, typename _OutIter>
594     _OutIter
595     money_put<_CharT, _OutIter>::
596     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
597            const string_type& __digits) const
598     { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
599                     : _M_insert<false>(__s, __io, __fill, __digits); }
601 _GLIBCXX_END_LDBL_NAMESPACE
603   // NB: Not especially useful. Without an ios_base object or some
604   // kind of locale reference, we are left clawing at the air where
605   // the side of the mountain used to be...
606   template<typename _CharT, typename _InIter>
607     time_base::dateorder
608     time_get<_CharT, _InIter>::do_date_order() const
609     { return time_base::no_order; }
611   // Expand a strftime format string and parse it.  E.g., do_get_date() may
612   // pass %m/%d/%Y => extracted characters.
613   template<typename _CharT, typename _InIter>
614     _InIter
615     time_get<_CharT, _InIter>::
616     _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
617                           ios_base::iostate& __err, tm* __tm,
618                           const _CharT* __format) const
619     {
620       const locale& __loc = __io._M_getloc();
621       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
622       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
623       const size_t __len = char_traits<_CharT>::length(__format);
625       ios_base::iostate __tmperr = ios_base::goodbit;
626       for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i)
627         {
628           if (__ctype.narrow(__format[__i], 0) == '%')
629             {
630               // Verify valid formatting code, attempt to extract.
631               char __c = __ctype.narrow(__format[++__i], 0);
632               int __mem = 0;
633               if (__c == 'E' || __c == 'O')
634                 __c = __ctype.narrow(__format[++__i], 0);
635               switch (__c)
636                 {
637                   const char* __cs;
638                   _CharT __wcs[10];
639                 case 'a':
640                   // Abbreviated weekday name [tm_wday]
641                   const char_type*  __days1[7];
642                   __tp._M_days_abbreviated(__days1);
643                   __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
644                                           7, __io, __tmperr);
645                   break;
646                 case 'A':
647                   // Weekday name [tm_wday].
648                   const char_type*  __days2[7];
649                   __tp._M_days(__days2);
650                   __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
651                                           7, __io, __tmperr);
652                   break;
653                 case 'h':
654                 case 'b':
655                   // Abbreviated month name [tm_mon]
656                   const char_type*  __months1[12];
657                   __tp._M_months_abbreviated(__months1);
658                   __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 
659                                           __months1, 12, __io, __tmperr);
660                   break;
661                 case 'B':
662                   // Month name [tm_mon].
663                   const char_type*  __months2[12];
664                   __tp._M_months(__months2);
665                   __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 
666                                           __months2, 12, __io, __tmperr);
667                   break;
668                 case 'c':
669                   // Default time and date representation.
670                   const char_type*  __dt[2];
671                   __tp._M_date_time_formats(__dt);
672                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
673                                                 __tm, __dt[0]);
674                   break;
675                 case 'd':
676                   // Day [01, 31]. [tm_mday]
677                   __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
678                                          __io, __tmperr);
679                   break;
680                 case 'e':
681                   // Day [1, 31], with single digits preceded by
682                   // space. [tm_mday]
683                   if (__ctype.is(ctype_base::space, *__beg))
684                     __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
685                                            1, __io, __tmperr);
686                   else
687                     __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
688                                            2, __io, __tmperr);
689                   break;
690                 case 'D':
691                   // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
692                   __cs = "%m/%d/%y";
693                   __ctype.widen(__cs, __cs + 9, __wcs);
694                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
695                                                 __tm, __wcs);
696                   break;
697                 case 'H':
698                   // Hour [00, 23]. [tm_hour]
699                   __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
700                                          __io, __tmperr);
701                   break;
702                 case 'I':
703                   // Hour [01, 12]. [tm_hour]
704                   __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
705                                          __io, __tmperr);
706                   break;
707                 case 'm':
708                   // Month [01, 12]. [tm_mon]
709                   __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 
710                                          __io, __tmperr);
711                   if (!__tmperr)
712                     __tm->tm_mon = __mem - 1;
713                   break;
714                 case 'M':
715                   // Minute [00, 59]. [tm_min]
716                   __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
717                                          __io, __tmperr);
718                   break;
719                 case 'n':
720                   if (__ctype.narrow(*__beg, 0) == '\n')
721                     ++__beg;
722                   else
723                     __tmperr |= ios_base::failbit;
724                   break;
725                 case 'R':
726                   // Equivalent to (%H:%M).
727                   __cs = "%H:%M";
728                   __ctype.widen(__cs, __cs + 6, __wcs);
729                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
730                                                 __tm, __wcs);
731                   break;
732                 case 'S':
733                   // Seconds. [tm_sec]
734                   // [00, 60] in C99 (one leap-second), [00, 61] in C89.
735 #ifdef _GLIBCXX_USE_C99
736                   __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
737 #else
738                   __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
739 #endif
740                                          __io, __tmperr);
741                   break;
742                 case 't':
743                   if (__ctype.narrow(*__beg, 0) == '\t')
744                     ++__beg;
745                   else
746                     __tmperr |= ios_base::failbit;
747                   break;
748                 case 'T':
749                   // Equivalent to (%H:%M:%S).
750                   __cs = "%H:%M:%S";
751                   __ctype.widen(__cs, __cs + 9, __wcs);
752                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
753                                                 __tm, __wcs);
754                   break;
755                 case 'x':
756                   // Locale's date.
757                   const char_type*  __dates[2];
758                   __tp._M_date_formats(__dates);
759                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
760                                                 __tm, __dates[0]);
761                   break;
762                 case 'X':
763                   // Locale's time.
764                   const char_type*  __times[2];
765                   __tp._M_time_formats(__times);
766                   __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 
767                                                 __tm, __times[0]);
768                   break;
769                 case 'y':
770                 case 'C': // C99
771                   // Two digit year. [tm_year]
772                   __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
773                                          __io, __tmperr);
774                   break;
775                 case 'Y':
776                   // Year [1900). [tm_year]
777                   __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
778                                          __io, __tmperr);
779                   if (!__tmperr)
780                     __tm->tm_year = __mem - 1900;
781                   break;
782                 case 'Z':
783                   // Timezone info.
784                   if (__ctype.is(ctype_base::upper, *__beg))
785                     {
786                       int __tmp;
787                       __beg = _M_extract_name(__beg, __end, __tmp,
788                                        __timepunct_cache<_CharT>::_S_timezones,
789                                               14, __io, __tmperr);
791                       // GMT requires special effort.
792                       if (__beg != __end && !__tmperr && __tmp == 0
793                           && (*__beg == __ctype.widen('-')
794                               || *__beg == __ctype.widen('+')))
795                         {
796                           __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
797                                                  __io, __tmperr);
798                           __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
799                                                  __io, __tmperr);
800                         }
801                     }
802                   else
803                     __tmperr |= ios_base::failbit;
804                   break;
805                 default:
806                   // Not recognized.
807                   __tmperr |= ios_base::failbit;
808                 }
809             }
810           else
811             {
812               // Verify format and input match, extract and discard.
813               if (__format[__i] == *__beg)
814                 ++__beg;
815               else
816                 __tmperr |= ios_base::failbit;
817             }
818         }
820       if (__tmperr)
821         __err |= ios_base::failbit;
822   
823       return __beg;
824     }
826   template<typename _CharT, typename _InIter>
827     _InIter
828     time_get<_CharT, _InIter>::
829     _M_extract_num(iter_type __beg, iter_type __end, int& __member,
830                    int __min, int __max, size_t __len,
831                    ios_base& __io, ios_base::iostate& __err) const
832     {
833       const locale& __loc = __io._M_getloc();
834       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
836       // As-is works for __len = 1, 2, 4, the values actually used.
837       int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
839       ++__min;
840       size_t __i = 0;
841       int __value = 0;
842       for (; __beg != __end && __i < __len; ++__beg, ++__i)
843         {
844           const char __c = __ctype.narrow(*__beg, '*');
845           if (__c >= '0' && __c <= '9')
846             {
847               __value = __value * 10 + (__c - '0');
848               const int __valuec = __value * __mult;
849               if (__valuec > __max || __valuec + __mult < __min)
850                 break;
851               __mult /= 10;
852             }
853           else
854             break;
855         }
856       if (__i == __len)
857         __member = __value;
858       else
859         __err |= ios_base::failbit;
861       return __beg;
862     }
864   // Assumptions:
865   // All elements in __names are unique.
866   template<typename _CharT, typename _InIter>
867     _InIter
868     time_get<_CharT, _InIter>::
869     _M_extract_name(iter_type __beg, iter_type __end, int& __member,
870                     const _CharT** __names, size_t __indexlen,
871                     ios_base& __io, ios_base::iostate& __err) const
872     {
873       typedef char_traits<_CharT>               __traits_type;
874       const locale& __loc = __io._M_getloc();
875       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
877       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
878                                                           * __indexlen));
879       size_t __nmatches = 0;
880       size_t __pos = 0;
881       bool __testvalid = true;
882       const char_type* __name;
884       // Look for initial matches.
885       // NB: Some of the locale data is in the form of all lowercase
886       // names, and some is in the form of initially-capitalized
887       // names. Look for both.
888       if (__beg != __end)
889         {
890           const char_type __c = *__beg;
891           for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
892             if (__c == __names[__i1][0]
893                 || __c == __ctype.toupper(__names[__i1][0]))
894               __matches[__nmatches++] = __i1;
895         }
897       while (__nmatches > 1)
898         {
899           // Find smallest matching string.
900           size_t __minlen = __traits_type::length(__names[__matches[0]]);
901           for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
902             __minlen = std::min(__minlen,
903                               __traits_type::length(__names[__matches[__i2]]));
904           ++__beg, ++__pos;
905           if (__pos < __minlen && __beg != __end)
906             for (size_t __i3 = 0; __i3 < __nmatches;)
907               {
908                 __name = __names[__matches[__i3]];
909                 if (!(__name[__pos] == *__beg))
910                   __matches[__i3] = __matches[--__nmatches];
911                 else
912                   ++__i3;
913               }
914           else
915             break;
916         }
918       if (__nmatches == 1)
919         {
920           // Make sure found name is completely extracted.
921           ++__beg, ++__pos;
922           __name = __names[__matches[0]];
923           const size_t __len = __traits_type::length(__name);
924           while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
925             ++__beg, ++__pos;
927           if (__len == __pos)
928             __member = __matches[0];
929           else
930             __testvalid = false;
931         }
932       else
933         __testvalid = false;
934       if (!__testvalid)
935         __err |= ios_base::failbit;
937       return __beg;
938     }
940   template<typename _CharT, typename _InIter>
941     _InIter
942     time_get<_CharT, _InIter>::
943     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
944                 ios_base::iostate& __err, tm* __tm) const
945     {
946       const locale& __loc = __io._M_getloc();
947       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
948       const char_type*  __times[2];
949       __tp._M_time_formats(__times);
950       __beg = _M_extract_via_format(__beg, __end, __io, __err, 
951                                     __tm, __times[0]);
952       if (__beg == __end)
953         __err |= ios_base::eofbit;
954       return __beg;
955     }
957   template<typename _CharT, typename _InIter>
958     _InIter
959     time_get<_CharT, _InIter>::
960     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
961                 ios_base::iostate& __err, tm* __tm) const
962     {
963       const locale& __loc = __io._M_getloc();
964       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
965       const char_type*  __dates[2];
966       __tp._M_date_formats(__dates);
967       __beg = _M_extract_via_format(__beg, __end, __io, __err, 
968                                     __tm, __dates[0]);
969       if (__beg == __end)
970         __err |= ios_base::eofbit;
971       return __beg;
972     }
974   template<typename _CharT, typename _InIter>
975     _InIter
976     time_get<_CharT, _InIter>::
977     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
978                    ios_base::iostate& __err, tm* __tm) const
979     {
980       typedef char_traits<_CharT>               __traits_type;
981       const locale& __loc = __io._M_getloc();
982       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
983       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
984       const char_type*  __days[7];
985       __tp._M_days_abbreviated(__days);
986       int __tmpwday;
987       ios_base::iostate __tmperr = ios_base::goodbit;
988       __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7,
989                               __io, __tmperr);
991       // Check to see if non-abbreviated name exists, and extract.
992       // NB: Assumes both _M_days and _M_days_abbreviated organized in
993       // exact same order, first to last, such that the resulting
994       // __days array with the same index points to a day, and that
995       // day's abbreviated form.
996       // NB: Also assumes that an abbreviated name is a subset of the name.
997       if (!__tmperr && __beg != __end)
998         {
999           size_t __pos = __traits_type::length(__days[__tmpwday]);
1000           __tp._M_days(__days);
1001           const char_type* __name = __days[__tmpwday];
1002           if (__name[__pos] == *__beg)
1003             {
1004               // Extract the rest of it.
1005               const size_t __len = __traits_type::length(__name);
1006               while (__pos < __len && __beg != __end
1007                      && __name[__pos] == *__beg)
1008                 ++__beg, ++__pos;
1009               if (__len != __pos)
1010                 __tmperr |= ios_base::failbit;
1011             }
1012         }
1013       if (!__tmperr)
1014         __tm->tm_wday = __tmpwday;
1015       else
1016         __err |= ios_base::failbit;
1018       if (__beg == __end)
1019         __err |= ios_base::eofbit;
1020       return __beg;
1021      }
1023   template<typename _CharT, typename _InIter>
1024     _InIter
1025     time_get<_CharT, _InIter>::
1026     do_get_monthname(iter_type __beg, iter_type __end,
1027                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
1028     {
1029       typedef char_traits<_CharT>               __traits_type;
1030       const locale& __loc = __io._M_getloc();
1031       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1032       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1033       const char_type*  __months[12];
1034       __tp._M_months_abbreviated(__months);
1035       int __tmpmon;
1036       ios_base::iostate __tmperr = ios_base::goodbit;
1037       __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, 
1038                               __io, __tmperr);
1040       // Check to see if non-abbreviated name exists, and extract.
1041       // NB: Assumes both _M_months and _M_months_abbreviated organized in
1042       // exact same order, first to last, such that the resulting
1043       // __months array with the same index points to a month, and that
1044       // month's abbreviated form.
1045       // NB: Also assumes that an abbreviated name is a subset of the name.
1046       if (!__tmperr && __beg != __end)
1047         {
1048           size_t __pos = __traits_type::length(__months[__tmpmon]);
1049           __tp._M_months(__months);
1050           const char_type* __name = __months[__tmpmon];
1051           if (__name[__pos] == *__beg)
1052             {
1053               // Extract the rest of it.
1054               const size_t __len = __traits_type::length(__name);
1055               while (__pos < __len && __beg != __end
1056                      && __name[__pos] == *__beg)
1057                 ++__beg, ++__pos;
1058               if (__len != __pos)
1059                 __tmperr |= ios_base::failbit;
1060             }
1061         }
1062       if (!__tmperr)
1063         __tm->tm_mon = __tmpmon;
1064       else
1065         __err |= ios_base::failbit;
1067       if (__beg == __end)
1068         __err |= ios_base::eofbit;
1069       return __beg;
1070     }
1072   template<typename _CharT, typename _InIter>
1073     _InIter
1074     time_get<_CharT, _InIter>::
1075     do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
1076                 ios_base::iostate& __err, tm* __tm) const
1077     {
1078       const locale& __loc = __io._M_getloc();
1079       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1081       size_t __i = 0;
1082       int __value = 0;
1083       for (; __beg != __end && __i < 4; ++__beg, ++__i)
1084         {
1085           const char __c = __ctype.narrow(*__beg, '*');
1086           if (__c >= '0' && __c <= '9')
1087             __value = __value * 10 + (__c - '0');
1088           else
1089             break;
1090         }
1091       if (__i == 2 || __i == 4)
1092         __tm->tm_year = __i == 2 ? __value : __value - 1900;
1093       else
1094         __err |= ios_base::failbit;
1096       if (__beg == __end)
1097         __err |= ios_base::eofbit;
1098       return __beg;
1099     }
1101   template<typename _CharT, typename _OutIter>
1102     _OutIter
1103     time_put<_CharT, _OutIter>::
1104     put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
1105         const _CharT* __beg, const _CharT* __end) const
1106     {
1107       const locale& __loc = __io._M_getloc();
1108       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1109       for (; __beg != __end; ++__beg)
1110         if (__ctype.narrow(*__beg, 0) != '%')
1111           {
1112             *__s = *__beg;
1113             ++__s;
1114           }
1115         else if (++__beg != __end)
1116           {
1117             char __format;
1118             char __mod = 0;
1119             const char __c = __ctype.narrow(*__beg, 0);
1120             if (__c != 'E' && __c != 'O')
1121               __format = __c;
1122             else if (++__beg != __end)
1123               {
1124                 __mod = __c;
1125                 __format = __ctype.narrow(*__beg, 0);
1126               }
1127             else
1128               break;
1129             __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
1130           }
1131         else
1132           break;
1133       return __s;
1134     }
1136   template<typename _CharT, typename _OutIter>
1137     _OutIter
1138     time_put<_CharT, _OutIter>::
1139     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
1140            char __format, char __mod) const
1141     {
1142       const locale& __loc = __io._M_getloc();
1143       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
1144       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
1146       // NB: This size is arbitrary. Should this be a data member,
1147       // initialized at construction?
1148       const size_t __maxlen = 128;
1149       char_type* __res = 
1150        static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
1152       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
1153       // is possible that the format character will be longer than one
1154       // character. Possibilities include 'E' or 'O' followed by a
1155       // format character: if __mod is not the default argument, assume
1156       // it's a valid modifier.
1157       char_type __fmt[4];
1158       __fmt[0] = __ctype.widen('%');
1159       if (!__mod)
1160         {
1161           __fmt[1] = __format;
1162           __fmt[2] = char_type();
1163         }
1164       else
1165         {
1166           __fmt[1] = __mod;
1167           __fmt[2] = __format;
1168           __fmt[3] = char_type();
1169         }
1171       __tp._M_put(__res, __maxlen, __fmt, __tm);
1173       // Write resulting, fully-formatted string to output iterator.
1174       return std::__write(__s, __res, char_traits<char_type>::length(__res));
1175     }
1178   // Inhibit implicit instantiations for required instantiations,
1179   // which are defined via explicit instantiations elsewhere.
1180   // NB: This syntax is a GNU extension.
1181 #if _GLIBCXX_EXTERN_TEMPLATE
1182   extern template class moneypunct<char, false>;
1183   extern template class moneypunct<char, true>;
1184   extern template class moneypunct_byname<char, false>;
1185   extern template class moneypunct_byname<char, true>;
1186   extern template class _GLIBCXX_LDBL_NAMESPACE money_get<char>;
1187   extern template class _GLIBCXX_LDBL_NAMESPACE money_put<char>;
1188   extern template class __timepunct<char>;
1189   extern template class time_put<char>;
1190   extern template class time_put_byname<char>;
1191   extern template class time_get<char>;
1192   extern template class time_get_byname<char>;
1193   extern template class messages<char>;
1194   extern template class messages_byname<char>;
1196   extern template
1197     const moneypunct<char, true>&
1198     use_facet<moneypunct<char, true> >(const locale&);
1200   extern template
1201     const moneypunct<char, false>&
1202     use_facet<moneypunct<char, false> >(const locale&);
1204   extern template
1205     const money_put<char>&
1206     use_facet<money_put<char> >(const locale&);
1208   extern template
1209     const money_get<char>&
1210     use_facet<money_get<char> >(const locale&);
1212   extern template
1213     const __timepunct<char>&
1214     use_facet<__timepunct<char> >(const locale&);
1216   extern template
1217     const time_put<char>&
1218     use_facet<time_put<char> >(const locale&);
1220   extern template
1221     const time_get<char>&
1222     use_facet<time_get<char> >(const locale&);
1224   extern template
1225     const messages<char>&
1226     use_facet<messages<char> >(const locale&);
1228   extern template
1229     bool
1230     has_facet<moneypunct<char> >(const locale&);
1232   extern template
1233     bool
1234     has_facet<money_put<char> >(const locale&);
1236   extern template
1237     bool
1238     has_facet<money_get<char> >(const locale&);
1240   extern template
1241     bool
1242     has_facet<__timepunct<char> >(const locale&);
1244   extern template
1245     bool
1246     has_facet<time_put<char> >(const locale&);
1248   extern template
1249     bool
1250     has_facet<time_get<char> >(const locale&);
1252   extern template
1253     bool
1254     has_facet<messages<char> >(const locale&);
1256 #ifdef _GLIBCXX_USE_WCHAR_T
1257   extern template class moneypunct<wchar_t, false>;
1258   extern template class moneypunct<wchar_t, true>;
1259   extern template class moneypunct_byname<wchar_t, false>;
1260   extern template class moneypunct_byname<wchar_t, true>;
1261   extern template class _GLIBCXX_LDBL_NAMESPACE money_get<wchar_t>;
1262   extern template class _GLIBCXX_LDBL_NAMESPACE money_put<wchar_t>;
1263   extern template class __timepunct<wchar_t>;
1264   extern template class time_put<wchar_t>;
1265   extern template class time_put_byname<wchar_t>;
1266   extern template class time_get<wchar_t>;
1267   extern template class time_get_byname<wchar_t>;
1268   extern template class messages<wchar_t>;
1269   extern template class messages_byname<wchar_t>;
1271   extern template
1272     const moneypunct<wchar_t, true>&
1273     use_facet<moneypunct<wchar_t, true> >(const locale&);
1275   extern template
1276     const moneypunct<wchar_t, false>&
1277     use_facet<moneypunct<wchar_t, false> >(const locale&);
1279   extern template
1280     const money_put<wchar_t>&
1281     use_facet<money_put<wchar_t> >(const locale&);
1283   extern template
1284     const money_get<wchar_t>&
1285     use_facet<money_get<wchar_t> >(const locale&);
1287   extern template
1288     const __timepunct<wchar_t>&
1289     use_facet<__timepunct<wchar_t> >(const locale&);
1291   extern template
1292     const time_put<wchar_t>&
1293     use_facet<time_put<wchar_t> >(const locale&);
1295   extern template
1296     const time_get<wchar_t>&
1297     use_facet<time_get<wchar_t> >(const locale&);
1299   extern template
1300     const messages<wchar_t>&
1301     use_facet<messages<wchar_t> >(const locale&);
1303   extern template
1304     bool
1305     has_facet<moneypunct<wchar_t> >(const locale&);
1307   extern template
1308     bool
1309     has_facet<money_put<wchar_t> >(const locale&);
1311   extern template
1312     bool
1313     has_facet<money_get<wchar_t> >(const locale&);
1315   extern template
1316     bool
1317     has_facet<__timepunct<wchar_t> >(const locale&);
1319   extern template
1320     bool
1321     has_facet<time_put<wchar_t> >(const locale&);
1323   extern template
1324     bool
1325     has_facet<time_get<wchar_t> >(const locale&);
1327   extern template
1328     bool
1329     has_facet<messages<wchar_t> >(const locale&);
1330 #endif
1331 #endif
1333 _GLIBCXX_END_NAMESPACE
1335 #endif