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