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