source: svn/trunk/newcon3bcm2_21bu/toolchain/include/c++/3.4.2/bits/locale_facets.tcc

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

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