locale_facets.tcc

00001 // Locale support -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 // Warning: this file is not meant for user inclusion. Use <locale>.
00032 
00033 #ifndef _CPP_BITS_LOCFACETS_TCC
00034 #define _CPP_BITS_LOCFACETS_TCC 1
00035 
00036 #pragma GCC system_header
00037 
00038 #include <cerrno>
00039 #include <clocale>          // For localeconv
00040 #include <cstdlib>          // For strof, strtold
00041 #include <cmath>            // For ceil
00042 #include <cctype>           // For isspace
00043 #include <limits>           // For numeric_limits
00044 #include <typeinfo>         // For bad_cast.
00045 #include <bits/streambuf_iterator.h>
00046 
00047 namespace std
00048 {
00049   template<typename _Facet>
00050     locale
00051     locale::combine(const locale& __other) const
00052     {
00053       _Impl* __tmp = new _Impl(*_M_impl, 1);
00054       __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
00055       return locale(__tmp);
00056     }
00057 
00058   template<typename _CharT, typename _Traits, typename _Alloc>
00059     bool
00060     locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
00061                        const basic_string<_CharT, _Traits, _Alloc>& __s2) const
00062     {
00063       typedef std::collate<_CharT> __collate_type;
00064       const __collate_type& __collate = use_facet<__collate_type>(*this);
00065       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
00066                 __s2.data(), __s2.data() + __s2.length()) < 0);
00067     }
00068 
00069   template<typename _Facet>
00070     const _Facet&
00071     use_facet(const locale& __loc)
00072     {
00073       size_t __i = _Facet::id._M_id();
00074       locale::facet** __facets = __loc._M_impl->_M_facets;
00075       if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
00076         __throw_bad_cast();
00077       return static_cast<const _Facet&>(*__facets[__i]);
00078     }
00079 
00080   template<typename _Facet>
00081     bool
00082     has_facet(const locale& __loc) throw()
00083     {
00084       size_t __i = _Facet::id._M_id();
00085       locale::facet** __facets = __loc._M_impl->_M_facets;
00086       return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
00087     }
00088 
00089 
00090   // Stage 1: Determine a conversion specifier.
00091   template<typename _CharT, typename _InIter>
00092     _InIter
00093     num_get<_CharT, _InIter>::
00094     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
00095              ios_base::iostate& __err, string& __xtrc) const
00096     {
00097       typedef char_traits<_CharT>       __traits_type;
00098       const locale __loc = __io.getloc();
00099       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
00100       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
00101 
00102       // First check for sign.
00103       const char_type __plus = __ctype.widen('+');
00104       const char_type __minus = __ctype.widen('-');
00105       int __pos = 0;
00106       char_type  __c = *__beg;
00107       if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
00108       && __beg != __end)
00109     {
00110       __xtrc += __ctype.narrow(__c, char());
00111       ++__pos;
00112       __c = *(++__beg);
00113     }
00114 
00115       // Next, strip leading zeros.
00116       const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]);
00117       bool __found_zero = false;
00118       while (__traits_type::eq(__c, __zero) && __beg != __end)
00119     {
00120       __c = *(++__beg);
00121       __found_zero = true;
00122     }
00123       if (__found_zero)
00124     {
00125       __xtrc += _S_atoms_in[_M_zero];
00126       ++__pos;
00127     }
00128 
00129       // Only need acceptable digits for floating point numbers.
00130       const size_t __len = _M_E - _M_zero + 1;
00131       char_type  __watoms[__len];
00132       __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms);
00133       bool __found_dec = false;
00134       bool __found_sci = false;
00135       const char_type __dec = __np.decimal_point();
00136 
00137       string __found_grouping;
00138       const string __grouping = __np.grouping();
00139       bool __check_grouping = __grouping.size();
00140       int __sep_pos = 0;
00141       const char_type __sep = __np.thousands_sep();
00142 
00143       while (__beg != __end)
00144         {
00145       // Only look in digits.
00146           const char_type* __p = __traits_type::find(__watoms, 10,  __c);
00147 
00148           // NB: strchr returns true for __c == 0x0
00149           if (__p && !__traits_type::eq(__c, char_type()))
00150         {
00151           // Try first for acceptable digit; record it if found.
00152           ++__pos;
00153           __xtrc += _S_atoms_in[__p - __watoms];
00154           ++__sep_pos;
00155           __c = *(++__beg);
00156         }
00157           else if (__traits_type::eq(__c, __sep) 
00158            && __check_grouping && !__found_dec)
00159         {
00160               // NB: Thousands separator at the beginning of a string
00161               // is a no-no, as is two consecutive thousands separators.
00162               if (__sep_pos)
00163                 {
00164                   __found_grouping += static_cast<char>(__sep_pos);
00165                   __sep_pos = 0;
00166           __c = *(++__beg);
00167                 }
00168               else
00169         {
00170           __err |= ios_base::failbit;
00171           break;
00172         }
00173             }
00174       else if (__traits_type::eq(__c, __dec) && !__found_dec)
00175         {
00176           // According to the standard, if no grouping chars are seen,
00177           // no grouping check is applied. Therefore __found_grouping
00178           // must be adjusted only if __dec comes after some __sep.
00179           if (__found_grouping.size())
00180         __found_grouping += static_cast<char>(__sep_pos);
00181           ++__pos;
00182           __xtrc += '.';
00183           __c = *(++__beg);
00184           __found_dec = true;
00185         }
00186       else if ((__traits_type::eq(__c, __watoms[_M_e]) 
00187             || __traits_type::eq(__c, __watoms[_M_E])) 
00188            && !__found_sci && __pos)
00189         {
00190           // Scientific notation.
00191           ++__pos;
00192           __xtrc += __ctype.narrow(__c, char());
00193           __c = *(++__beg);
00194 
00195           // Remove optional plus or minus sign, if they exist.
00196           if (__traits_type::eq(__c, __plus) 
00197           || __traits_type::eq(__c, __minus))
00198         {
00199           ++__pos;
00200           __xtrc += __ctype.narrow(__c, char());
00201           __c = *(++__beg);
00202         }
00203           __found_sci = true;
00204         }
00205       else
00206         // Not a valid input item.
00207         break;
00208         }
00209 
00210       // Digit grouping is checked. If grouping and found_grouping don't
00211       // match, then get very very upset, and set failbit.
00212       if (__check_grouping && __found_grouping.size())
00213         {
00214           // Add the ending grouping if a decimal wasn't found.
00215       if (!__found_dec)
00216         __found_grouping += static_cast<char>(__sep_pos);
00217           if (!__verify_grouping(__grouping, __found_grouping))
00218         __err |= ios_base::failbit;
00219         }
00220 
00221       // Finish up
00222       __xtrc += char();
00223       if (__beg == __end)
00224         __err |= ios_base::eofbit;
00225       return __beg;
00226     }
00227 
00228   // Stage 1: Determine a conversion specifier.
00229   template<typename _CharT, typename _InIter>
00230     _InIter
00231     num_get<_CharT, _InIter>::
00232     _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
00233            ios_base::iostate& __err, string& __xtrc, int& __base) const
00234     {
00235       typedef char_traits<_CharT>       __traits_type;
00236       const locale __loc = __io.getloc();
00237       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
00238       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
00239  
00240       // NB: Iff __basefield == 0, this can change based on contents.
00241       ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
00242       if (__basefield == ios_base::oct)
00243         __base = 8;
00244       else if (__basefield == ios_base::hex)
00245         __base = 16;
00246       else
00247     __base = 10;
00248 
00249       // First check for sign.
00250       int __pos = 0;
00251       char_type  __c = *__beg;
00252       const char_type __plus = __ctype.widen('+');
00253       const char_type __minus = __ctype.widen('-');
00254 
00255       if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus))
00256       && __beg != __end)
00257     {
00258       __xtrc += __ctype.narrow(__c, char());
00259       ++__pos;
00260       __c = *(++__beg);
00261     }
00262 
00263       // Next, strip leading zeros and check required digits for base formats.
00264       const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]);
00265       const char_type __x = __ctype.widen('x');
00266       const char_type __X = __ctype.widen('X');
00267       if (__base == 10)
00268     {
00269       bool __found_zero = false;
00270       while (__traits_type::eq(__c, __zero) && __beg != __end)
00271         {
00272           __c = *(++__beg);
00273           __found_zero = true;
00274         }
00275       if (__found_zero)
00276         {
00277           __xtrc += _S_atoms_in[_M_zero];
00278           ++__pos;
00279           if (__basefield == 0)
00280         {         
00281           if ((__traits_type::eq(__c, __x) 
00282                || __traits_type::eq(__c, __X))
00283               && __beg != __end)
00284             {
00285               __xtrc += __ctype.narrow(__c, char());
00286               ++__pos;
00287               __c = *(++__beg);
00288               __base = 16;
00289             }
00290           else 
00291             __base = 8;
00292         }
00293         }
00294     }
00295       else if (__base == 16)
00296     {
00297       if (__traits_type::eq(__c, __zero) && __beg != __end)
00298         {
00299           __xtrc += _S_atoms_in[_M_zero];
00300           ++__pos;
00301           __c = *(++__beg); 
00302           if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X))
00303           && __beg != __end)
00304         {
00305           __xtrc += __ctype.narrow(__c, char());
00306           ++__pos;
00307           __c = *(++__beg);
00308         }
00309         }
00310     }
00311 
00312       // At this point, base is determined. If not hex, only allow
00313       // base digits as valid input.
00314       size_t __len;
00315       if (__base == 16)
00316     __len = _M_size;
00317       else
00318     __len = __base;
00319 
00320       // Extract.
00321       char_type __watoms[_M_size];
00322       __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms);
00323       string __found_grouping;
00324       const string __grouping = __np.grouping();
00325       bool __check_grouping = __grouping.size();
00326       int __sep_pos = 0;
00327       const char_type __sep = __np.thousands_sep();
00328       while (__beg != __end)
00329         {
00330           const char_type* __p = __traits_type::find(__watoms, __len,  __c);
00331 
00332           // NB: strchr returns true for __c == 0x0
00333           if (__p && !__traits_type::eq(__c, char_type()))
00334         {
00335           // Try first for acceptable digit; record it if found.
00336           __xtrc += _S_atoms_in[__p - __watoms];
00337           ++__pos;
00338           ++__sep_pos;
00339           __c = *(++__beg);
00340         }
00341           else if (__traits_type::eq(__c, __sep) && __check_grouping)
00342         {
00343               // NB: Thousands separator at the beginning of a string
00344               // is a no-no, as is two consecutive thousands separators.
00345               if (__sep_pos)
00346                 {
00347                   __found_grouping += static_cast<char>(__sep_pos);
00348                   __sep_pos = 0;
00349           __c = *(++__beg);
00350                 }
00351               else
00352         {
00353           __err |= ios_base::failbit;
00354           break;
00355         }
00356             }
00357       else
00358         // Not a valid input item.
00359         break;
00360         }
00361 
00362       // Digit grouping is checked. If grouping and found_grouping don't
00363       // match, then get very very upset, and set failbit.
00364       if (__check_grouping && __found_grouping.size())
00365         {
00366           // Add the ending grouping.
00367           __found_grouping += static_cast<char>(__sep_pos);
00368           if (!__verify_grouping(__grouping, __found_grouping))
00369         __err |= ios_base::failbit;
00370         }
00371 
00372       // Finish up.
00373       __xtrc += char();
00374       if (__beg == __end)
00375         __err |= ios_base::eofbit;
00376       return __beg;
00377     }
00378 
00379 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00380   //17.  Bad bool parsing
00381   template<typename _CharT, typename _InIter>
00382     _InIter
00383     num_get<_CharT, _InIter>::
00384     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00385            ios_base::iostate& __err, bool& __v) const
00386     {
00387       // Parse bool values as unsigned long
00388       if (!(__io.flags() & ios_base::boolalpha))
00389         {
00390           // NB: We can't just call do_get(long) here, as it might
00391           // refer to a derived class.
00392           string __xtrc;
00393           int __base;
00394           __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00395 
00396       unsigned long __ul; 
00397       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
00398       if (!(__err & ios_base::failbit) && __ul <= 1)
00399         __v = __ul;
00400       else 
00401             __err |= ios_base::failbit;
00402         }
00403 
00404       // Parse bool values as alphanumeric
00405       else
00406         {
00407       typedef char_traits<_CharT>           __traits_type;
00408       typedef basic_string<_CharT>      __string_type;
00409 
00410           locale __loc = __io.getloc();
00411       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 
00412       const __string_type __true = __np.truename();
00413       const __string_type __false = __np.falsename();
00414           const char_type* __trues = __true.c_str();
00415           const char_type* __falses = __false.c_str();
00416           const size_t __truen =  __true.size() - 1;
00417           const size_t __falsen =  __false.size() - 1;
00418 
00419           for (size_t __n = 0; __beg != __end; ++__n)
00420             {
00421               char_type __c = *__beg++;
00422               bool __testf = __n <= __falsen 
00423                      ? __traits_type::eq(__c, __falses[__n]) : false;
00424               bool __testt = __n <= __truen 
00425                      ? __traits_type::eq(__c, __trues[__n]) : false;
00426               if (!(__testf || __testt))
00427                 {
00428                   __err |= ios_base::failbit;
00429                   break;
00430                 }
00431               else if (__testf && __n == __falsen)
00432                 {
00433                   __v = 0;
00434                   break;
00435                 }
00436               else if (__testt && __n == __truen)
00437                 {
00438                   __v = 1;
00439                   break;
00440                 }
00441             }
00442           if (__beg == __end)
00443             __err |= ios_base::eofbit;
00444         }
00445       return __beg;
00446     }
00447 #endif
00448 
00449   template<typename _CharT, typename _InIter>
00450     _InIter
00451     num_get<_CharT, _InIter>::
00452     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00453            ios_base::iostate& __err, long& __v) const
00454     {
00455       string __xtrc;
00456       int __base;
00457       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00458       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
00459       return __beg;
00460     }
00461 
00462   template<typename _CharT, typename _InIter>
00463     _InIter
00464     num_get<_CharT, _InIter>::
00465     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00466            ios_base::iostate& __err, unsigned short& __v) const
00467     {
00468       string __xtrc;
00469       int __base;
00470       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00471       unsigned long __ul;
00472       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
00473       if (!(__err & ios_base::failbit) 
00474       && __ul <= numeric_limits<unsigned short>::max())
00475     __v = static_cast<unsigned short>(__ul);
00476       else 
00477     __err |= ios_base::failbit;
00478       return __beg;
00479     }
00480 
00481   template<typename _CharT, typename _InIter>
00482     _InIter
00483     num_get<_CharT, _InIter>::
00484     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00485            ios_base::iostate& __err, unsigned int& __v) const
00486     {
00487       string __xtrc;
00488       int __base;
00489       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00490       unsigned long __ul;
00491       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
00492       if (!(__err & ios_base::failbit) 
00493       && __ul <= numeric_limits<unsigned int>::max())
00494     __v = static_cast<unsigned int>(__ul);
00495       else 
00496     __err |= ios_base::failbit;
00497       return __beg;
00498     }
00499 
00500   template<typename _CharT, typename _InIter>
00501     _InIter
00502     num_get<_CharT, _InIter>::
00503     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00504            ios_base::iostate& __err, unsigned long& __v) const
00505     {
00506       string __xtrc;
00507       int __base;
00508       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00509       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
00510       return __beg;
00511     }
00512 
00513 #ifdef _GLIBCPP_USE_LONG_LONG
00514   template<typename _CharT, typename _InIter>
00515     _InIter
00516     num_get<_CharT, _InIter>::
00517     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00518            ios_base::iostate& __err, long long& __v) const
00519     {
00520       string __xtrc;
00521       int __base;
00522       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00523       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
00524       return __beg;
00525     }
00526 
00527   template<typename _CharT, typename _InIter>
00528     _InIter
00529     num_get<_CharT, _InIter>::
00530     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00531            ios_base::iostate& __err, unsigned long long& __v) const
00532     {
00533       string __xtrc;
00534       int __base;
00535       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00536       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
00537       return __beg;
00538     }
00539 #endif
00540 
00541   template<typename _CharT, typename _InIter>
00542     _InIter
00543     num_get<_CharT, _InIter>::
00544     do_get(iter_type __beg, iter_type __end, ios_base& __io, 
00545        ios_base::iostate& __err, float& __v) const
00546     {
00547       string __xtrc;
00548       __xtrc.reserve(32);
00549       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00550       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
00551       return __beg;
00552     }
00553 
00554   template<typename _CharT, typename _InIter>
00555     _InIter
00556     num_get<_CharT, _InIter>::
00557     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00558            ios_base::iostate& __err, double& __v) const
00559     {
00560       string __xtrc;
00561       __xtrc.reserve(32);
00562       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00563       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
00564       return __beg;
00565     }
00566 
00567   template<typename _CharT, typename _InIter>
00568     _InIter
00569     num_get<_CharT, _InIter>::
00570     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00571            ios_base::iostate& __err, long double& __v) const
00572     {
00573       string __xtrc;
00574       __xtrc.reserve(32);
00575       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00576       __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
00577       return __beg;
00578     }
00579 
00580   template<typename _CharT, typename _InIter>
00581     _InIter
00582     num_get<_CharT, _InIter>::
00583     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00584            ios_base::iostate& __err, void*& __v) const
00585     {
00586       // Prepare for hex formatted input
00587       typedef ios_base::fmtflags        fmtflags;
00588       fmtflags __fmt = __io.flags();
00589       fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
00590                              | ios_base::uppercase | ios_base::internal);
00591       __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
00592 
00593       string __xtrc;
00594       int __base;
00595       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
00596 
00597       // Reset from hex formatted input
00598       __io.flags(__fmt);
00599 
00600       unsigned long __ul;
00601       __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
00602       if (!(__err & ios_base::failbit))
00603     __v = reinterpret_cast<void*>(__ul);
00604       else 
00605     __err |= ios_base::failbit;
00606       return __beg;
00607     }
00608 
00609   // For use by integer and floating-point types after they have been
00610   // converted into a char_type string.
00611   template<typename _CharT, typename _OutIter>
00612     void
00613     num_put<_CharT, _OutIter>::
00614     _M_pad(_CharT __fill, streamsize __w, ios_base& __io, 
00615        _CharT* __new, const _CharT* __cs, int& __len) const
00616     {
00617       // [22.2.2.2.2] Stage 3.
00618       // If necessary, pad.
00619       __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, 
00620                           __w, __len, true);
00621       __len = static_cast<int>(__w);
00622     }
00623 
00624   // Forwarding functions to peel signed from unsigned integer types.
00625   template<typename _CharT>
00626     inline int
00627     __int_to_char(_CharT* __out, const int __size, long __v,
00628                const _CharT* __lit, ios_base::fmtflags __flags)
00629     {
00630       unsigned long __ul = static_cast<unsigned long>(__v);
00631       bool __neg = false;
00632       if (__v < 0) 
00633     {
00634       __ul = -__ul;
00635       __neg = true;
00636     }
00637       return __int_to_char(__out, __size, __ul, __lit, __flags, __neg); 
00638     }
00639 
00640   template<typename _CharT>
00641     inline int
00642     __int_to_char(_CharT* __out, const int __size, unsigned long __v,
00643                const _CharT* __lit, ios_base::fmtflags __flags)
00644     { return __int_to_char(__out, __size, __v, __lit, __flags, false); }
00645 
00646 #ifdef _GLIBCPP_USE_LONG_LONG
00647   template<typename _CharT>
00648     inline int
00649     __int_to_char(_CharT* __out, const int __size, long long __v,
00650                const _CharT* __lit, ios_base::fmtflags __flags)
00651     { 
00652       unsigned long long __ull = static_cast<unsigned long long>(__v);
00653       bool __neg = false;
00654       if (__v < 0) 
00655     {
00656       __ull = -__ull;
00657       __neg = true;
00658     }
00659       return __int_to_char(__out, __size, __ull, __lit, __flags, __neg); 
00660     }
00661 
00662   template<typename _CharT>
00663     inline int
00664     __int_to_char(_CharT* __out, const int __size, unsigned long long __v,
00665                const _CharT* __lit, ios_base::fmtflags __flags)
00666     { return __int_to_char(__out, __size, __v, __lit, __flags, false); }
00667 #endif
00668       
00669   template<typename _CharT, typename _ValueT>
00670     int
00671     __int_to_char(_CharT* __out, const int __size, _ValueT __v,
00672           const _CharT* __lit, ios_base::fmtflags __flags, bool __neg)
00673     {
00674       // Don't write base if already 0.
00675       const bool __showbase = (__flags & ios_base::showbase) && __v;
00676       const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
00677       _CharT* __buf = __out + __size - 1;
00678       _CharT* __bufend = __out + __size;
00679 
00680       if (__builtin_expect(__basefield == ios_base::oct, false))
00681     {
00682       // Octal.
00683       do 
00684         {
00685           *__buf-- = __lit[(__v & 0x7) + __num_base::_S_digits];
00686           __v >>= 3;
00687         } 
00688       while (__v != 0);
00689       if (__showbase)
00690         *__buf-- = __lit[__num_base::_S_digits];
00691     }
00692       else if (__builtin_expect(__basefield == ios_base::hex, false))
00693     {
00694       // Hex.
00695       const bool __uppercase = __flags & ios_base::uppercase;
00696       int __case_offset = __uppercase
00697                           ? __num_base::_S_udigits : __num_base::_S_digits;
00698       do 
00699         {
00700           *__buf-- = __lit[(__v & 0xf) + __case_offset];
00701           __v >>= 4;
00702         } 
00703       while (__v != 0);
00704       if (__showbase)
00705         {
00706           // 'x' or 'X'
00707           *__buf-- = __lit[__num_base::_S_x + __uppercase];
00708           // '0'
00709           *__buf-- = __lit[__num_base::_S_digits];
00710         }
00711     }
00712       else
00713     {
00714       // Decimal.
00715       do 
00716         {
00717           *__buf-- = __lit[(__v % 10) + __num_base::_S_digits];
00718           __v /= 10;
00719         } 
00720       while (__v != 0);
00721       if (__neg)
00722         *__buf-- = __lit[__num_base::_S_minus];
00723       else if (__flags & ios_base::showpos)
00724         *__buf-- = __lit[__num_base::_S_plus];
00725     }
00726       int __ret = __bufend - __buf - 1;
00727       return __ret;
00728     }
00729 
00730   template<typename _CharT, typename _OutIter>
00731     void
00732     num_put<_CharT, _OutIter>::
00733     _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io, 
00734          _CharT* __new, _CharT* __cs, int& __len) const
00735     {
00736       // By itself __add_grouping cannot deal correctly with __ws when
00737       // ios::showbase is set and ios_base::oct || ios_base::hex.
00738       // Therefore we take care "by hand" of the initial 0, 0x or 0X.
00739       // However, remember that the latter do not occur if the number
00740       // printed is '0' (__len == 1).
00741       streamsize __off = 0;
00742       const ios_base::fmtflags __basefield = __io.flags() 
00743                                          & ios_base::basefield;
00744       if ((__io.flags() & ios_base::showbase) && __len > 1)
00745     if (__basefield == ios_base::oct)
00746       {
00747         __off = 1;
00748         *__new = *__cs;
00749       }
00750     else if (__basefield == ios_base::hex)
00751       {
00752         __off = 2;
00753         *__new = *__cs;
00754         *(__new + 1) = *(__cs + 1);
00755       }
00756       _CharT* __p;
00757       __p = __add_grouping(__new + __off, __sep, 
00758                __grouping.c_str(),
00759                __grouping.c_str() + __grouping.size(),
00760                __cs + __off, __cs + __len);
00761       __len = __p - __new;
00762     }
00763 
00764   template<typename _CharT, typename _OutIter>
00765     template<typename _ValueT>
00766       _OutIter
00767       num_put<_CharT, _OutIter>::
00768       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, 
00769              _ValueT __v) const
00770       {
00771         typedef __locale_cache<_CharT> __cache_type;
00772         __cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
00773         _CharT* __lit = __lc._M_literals;
00774 
00775     // Long enough to hold hex, dec, and octal representations.
00776     int __ilen = 4 * sizeof(_ValueT);
00777     _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
00778                                  * __ilen));
00779 
00780     // [22.2.2.2.2] Stage 1, numeric conversion to character.
00781     // Result is returned right-justified in the buffer.
00782     int __len;
00783     __len = __int_to_char(&__cs[0], __ilen, __v, __lit, __io.flags());
00784     __cs = __cs + __ilen - __len;
00785     
00786     // Add grouping, if necessary. 
00787     _CharT* __cs2;
00788     if (__lc._M_use_grouping)
00789       {
00790         // Grouping can add (almost) as many separators as the
00791         // number of digits, but no more.
00792         __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
00793                               * __len * 2));
00794         _M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io, 
00795              __cs2, __cs, __len);
00796         __cs = __cs2;
00797       }
00798     
00799     // Pad.
00800     _CharT* __cs3;
00801     streamsize __w = __io.width();
00802     if (__w > static_cast<streamsize>(__len))
00803       {
00804         __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
00805                               * __w));
00806         _M_pad(__fill, __w, __io, __cs3, __cs, __len);
00807         __cs = __cs3;
00808       }
00809     __io.width(0);
00810 
00811     // [22.2.2.2.2] Stage 4.
00812     // Write resulting, fully-formatted string to output iterator.
00813     return __write(__s, __cs, __len);
00814       } 
00815 
00816   template<typename _CharT, typename _OutIter>
00817     void
00818     num_put<_CharT, _OutIter>::
00819     _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p, 
00820            _CharT* __new, _CharT* __cs, int& __len) const
00821     {
00822 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00823       //282. What types does numpunct grouping refer to?
00824       // Add grouping, if necessary. 
00825       _CharT* __p2;
00826       int __declen = __p ? __p - __cs : __len;
00827       __p2 = __add_grouping(__new, __sep, 
00828                 __grouping.c_str(),
00829                 __grouping.c_str() + __grouping.size(),
00830                 __cs, __cs + __declen);
00831       
00832       // Tack on decimal part.
00833       int __newlen = __p2 - __new;
00834       if (__p)
00835     {
00836       char_traits<_CharT>::copy(__p2, __p, __len - __declen);
00837       __newlen += __len - __declen;
00838     }    
00839       __len = __newlen;
00840 #endif
00841     }
00842 
00843   // The following code uses snprintf (or sprintf(), when
00844   // _GLIBCPP_USE_C99 is not defined) to convert floating point values
00845   // for insertion into a stream.  An optimization would be to replace
00846   // them with code that works directly on a wide buffer and then use
00847   // __pad to do the padding.  It would be good to replace them anyway
00848   // to gain back the efficiency that C++ provides by knowing up front
00849   // the type of the values to insert.  Also, sprintf is dangerous
00850   // since may lead to accidental buffer overruns.  This
00851   // implementation follows the C++ standard fairly directly as
00852   // outlined in 22.2.2.2 [lib.locale.num.put]
00853   template<typename _CharT, typename _OutIter>
00854     template<typename _ValueT>
00855       _OutIter
00856       num_put<_CharT, _OutIter>::
00857       _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
00858                _ValueT __v) const
00859       {
00860     // Note: digits10 is rounded down: add 1 to ensure the maximum
00861     // available precision.  Then, in general, one more 1 needs to
00862     // be added since, when the %{g,G} conversion specifiers are
00863     // chosen inside _S_format_float, the precision field is "the
00864     // maximum number of significant digits", *not* the "number of
00865     // digits to appear after the decimal point", as happens for
00866     // %{e,E,f,F} (C99, 7.19.6.1,4).
00867     const int __max_digits = numeric_limits<_ValueT>::digits10 + 2;
00868 
00869     // Use default precision if out of range.
00870     streamsize __prec = __io.precision();
00871     if (__prec > static_cast<streamsize>(__max_digits))
00872       __prec = static_cast<streamsize>(__max_digits);
00873     else if (__prec < static_cast<streamsize>(0))
00874       __prec = static_cast<streamsize>(6);
00875 
00876         typedef __locale_cache<_CharT> __cache_type;
00877         __cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
00878 
00879     // [22.2.2.2.2] Stage 1, numeric conversion to character.
00880     int __len;
00881     // Long enough for the max format spec.
00882     char __fbuf[16];
00883 
00884 #ifdef _GLIBCPP_USE_C99
00885     // First try a buffer perhaps big enough (for sure sufficient
00886     // for non-ios_base::fixed outputs)
00887     int __cs_size = __max_digits * 3;
00888     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
00889 
00890     _S_format_float(__io, __fbuf, __mod, __prec);
00891     __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
00892                  _S_c_locale, __prec);
00893 
00894     // If the buffer was not large enough, try again with the correct size.
00895     if (__len >= __cs_size)
00896       {
00897         __cs_size = __len + 1; 
00898         __cs = static_cast<char*>(__builtin_alloca(__cs_size));
00899         __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
00900                      _S_c_locale, __prec);
00901       }
00902 #else
00903     // Consider the possibility of long ios_base::fixed outputs
00904     const bool __fixed = __io.flags() & ios_base::fixed;
00905     const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
00906 
00907     // ios_base::fixed outputs may need up to __max_exp+1 chars
00908     // for the integer part + up to __max_digits chars for the
00909     // fractional part + 3 chars for sign, decimal point, '\0'. On
00910     // the other hand, for non-fixed outputs __max_digits*3 chars
00911     // are largely sufficient.
00912     const int __cs_size = __fixed ? __max_exp + __max_digits + 4 
00913                                   : __max_digits * 3;
00914     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
00915 
00916     _S_format_float(__io, __fbuf, __mod, __prec);
00917     __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
00918 #endif
00919 
00920       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
00921       // numpunct.decimal_point() values for '.' and adding grouping.
00922       const locale __loc = __io.getloc();
00923       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
00924 
00925       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
00926                                * __len));
00927       __ctype.widen(__cs, __cs + __len, __ws);
00928       
00929       // Replace decimal point.
00930       const _CharT __cdec = __ctype.widen('.');
00931       const _CharT __dec = __lc._M_decimal_point;
00932       const _CharT* __p;
00933       if (__p = char_traits<_CharT>::find(__ws, __len, __cdec))
00934     __ws[__p - __ws] = __dec;
00935 
00936       // Add grouping, if necessary. 
00937       _CharT* __ws2;
00938       if (__lc._M_use_grouping)
00939     {
00940         // Grouping can add (almost) as many separators as the
00941         // number of digits, but no more.
00942         __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
00943                               * __len * 2));
00944         _M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p, 
00945                __ws2, __ws, __len);
00946         __ws = __ws2;
00947     }
00948 
00949       // Pad.
00950       _CharT* __ws3;
00951       streamsize __w = __io.width();
00952       if (__w > static_cast<streamsize>(__len))
00953     {
00954       __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
00955       _M_pad(__fill, __w, __io, __ws3, __ws, __len);
00956       __ws = __ws3;
00957     }
00958       __io.width(0);
00959       
00960       // [22.2.2.2.2] Stage 4.
00961       // Write resulting, fully-formatted string to output iterator.
00962       return __write(__s, __ws, __len);
00963       }
00964 
00965   template<typename _CharT, typename _OutIter>
00966     _OutIter
00967     num_put<_CharT, _OutIter>::
00968     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
00969     {
00970       ios_base::fmtflags __flags = __io.flags();
00971       if ((__flags & ios_base::boolalpha) == 0)
00972         {
00973           unsigned long __uv = __v;
00974           __s = _M_convert_int(__s, __io, __fill, __uv);
00975         }
00976       else
00977         {
00978       typedef __locale_cache<_CharT> __cache_type;
00979       __cache_type& __lc = static_cast<__cache_type&>(__io._M_cache());
00980       typedef basic_string<_CharT>  __string_type;
00981       __string_type __name;
00982           if (__v)
00983         __name = __lc._M_truename;
00984           else
00985         __name = __lc._M_falsename;
00986 
00987       const _CharT* __cs = __name.c_str();
00988       int __len = __name.size();
00989       _CharT* __cs3;
00990       streamsize __w = __io.width();
00991       if (__w > static_cast<streamsize>(__len))
00992         {
00993           __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
00994                                 * __w));
00995           _M_pad(__fill, __w, __io, __cs3, __cs, __len);
00996           __cs = __cs3;
00997         }
00998       __io.width(0);
00999       __s = __write(__s, __cs, __len);
01000     }
01001       return __s;
01002     }
01003 
01004   template<typename _CharT, typename _OutIter>
01005     _OutIter
01006     num_put<_CharT, _OutIter>::
01007     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
01008     { return _M_convert_int(__s, __io, __fill, __v); }
01009 
01010   template<typename _CharT, typename _OutIter>
01011     _OutIter
01012     num_put<_CharT, _OutIter>::
01013     do_put(iter_type __s, ios_base& __io, char_type __fill,
01014            unsigned long __v) const
01015     { return _M_convert_int(__s, __io, __fill, __v); }
01016 
01017 #ifdef _GLIBCPP_USE_LONG_LONG
01018   template<typename _CharT, typename _OutIter>
01019     _OutIter
01020     num_put<_CharT, _OutIter>::
01021     do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
01022     { return _M_convert_int(__s, __b, __fill, __v); }
01023 
01024   template<typename _CharT, typename _OutIter>
01025     _OutIter
01026     num_put<_CharT, _OutIter>::
01027     do_put(iter_type __s, ios_base& __io, char_type __fill,
01028            unsigned long long __v) const
01029     { return _M_convert_int(__s, __io, __fill, __v); }
01030 #endif
01031 
01032   template<typename _CharT, typename _OutIter>
01033     _OutIter
01034     num_put<_CharT, _OutIter>::
01035     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
01036     { return _M_convert_float(__s, __io, __fill, char(), __v); }
01037 
01038   template<typename _CharT, typename _OutIter>
01039     _OutIter
01040     num_put<_CharT, _OutIter>::
01041     do_put(iter_type __s, ios_base& __io, char_type __fill, 
01042        long double __v) const
01043     { return _M_convert_float(__s, __io, __fill, 'L', __v); }
01044 
01045   template<typename _CharT, typename _OutIter>
01046     _OutIter
01047     num_put<_CharT, _OutIter>::
01048     do_put(iter_type __s, ios_base& __io, char_type __fill,
01049            const void* __v) const
01050     {
01051       ios_base::fmtflags __flags = __io.flags();
01052       ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
01053                    | ios_base::uppercase | ios_base::internal);
01054       __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
01055       try 
01056     {
01057       __s = _M_convert_int(__s, __io, __fill, 
01058                    reinterpret_cast<unsigned long>(__v));
01059       __io.flags(__flags);
01060     }
01061       catch (...) 
01062     {
01063       __io.flags(__flags);
01064       __throw_exception_again;
01065     }
01066       return __s;
01067     }
01068 
01069 
01070   template<typename _CharT, typename _InIter>
01071     _InIter
01072     money_get<_CharT, _InIter>::
01073     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
01074        ios_base::iostate& __err, long double& __units) const
01075     { 
01076       string_type __str;
01077       __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); 
01078 
01079       const int __n = numeric_limits<long double>::digits10;
01080       char* __cs = static_cast<char*>(__builtin_alloca(__n));
01081       const locale __loc = __io.getloc();
01082       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
01083       const _CharT* __wcs = __str.c_str();
01084       __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
01085       __convert_to_v(__cs, __units, __err, _S_c_locale);
01086       return __beg;
01087     }
01088 
01089   template<typename _CharT, typename _InIter>
01090     _InIter
01091     money_get<_CharT, _InIter>::
01092     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 
01093        ios_base::iostate& __err, string_type& __units) const
01094     { 
01095       // These contortions are quite unfortunate.
01096       typedef moneypunct<_CharT, true>      __money_true;
01097       typedef moneypunct<_CharT, false>     __money_false;
01098       typedef money_base::part          part;
01099       typedef typename string_type::size_type   size_type;
01100 
01101       const locale __loc = __io.getloc();
01102       const __money_true& __mpt = use_facet<__money_true>(__loc); 
01103       const __money_false& __mpf = use_facet<__money_false>(__loc); 
01104       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
01105 
01106       const money_base::pattern __p = __intl ? __mpt.neg_format() 
01107                          : __mpf.neg_format();
01108 
01109       const string_type __pos_sign =__intl ? __mpt.positive_sign() 
01110                        : __mpf.positive_sign();
01111       const string_type __neg_sign =__intl ? __mpt.negative_sign() 
01112                        : __mpf.negative_sign();
01113       const char_type __d = __intl ? __mpt.decimal_point() 
01114                            : __mpf.decimal_point();
01115       const char_type __sep = __intl ? __mpt.thousands_sep() 
01116                          : __mpf.thousands_sep();
01117 
01118       const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping();
01119 
01120       // Set to deduced positive or negative sign, depending.
01121       string_type __sign;
01122       // String of grouping info from thousands_sep plucked from __units.
01123       string __grouping_tmp; 
01124       // Marker for thousands_sep position.
01125       int __sep_pos = 0;
01126       // If input iterator is in a valid state.
01127       bool __testvalid = true;
01128       // Flag marking when a decimal point is found.
01129       bool __testdecfound = false; 
01130 
01131       // The tentative returned string is stored here.
01132       string_type __temp_units;
01133 
01134       char_type __c = *__beg;
01135       char_type __eof = static_cast<char_type>(char_traits<char_type>::eof());
01136       for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i)
01137     {
01138       part __which = static_cast<part>(__p.field[__i]);
01139       switch (__which)
01140         {
01141         case money_base::symbol:
01142           if (__io.flags() & ios_base::showbase 
01143               || __i < 2 || __sign.size() > 1
01144               || ((static_cast<part>(__p.field[3]) != money_base::none)
01145               && __i == 2)) 
01146             {
01147               // According to 22.2.6.1.2.2, symbol is required
01148               // if (__io.flags() & ios_base::showbase),
01149               // otherwise is optional and consumed only if
01150               // other characters are needed to complete the
01151               // format.
01152               const string_type __symbol = __intl ? __mpt.curr_symbol()
01153                                  : __mpf.curr_symbol();
01154               size_type __len = __symbol.size();
01155               size_type __j = 0;
01156               while (__beg != __end 
01157                  && __j < __len && __symbol[__j] == __c)
01158             {
01159               __c = *(++__beg);
01160               ++__j;
01161             }
01162               // When (__io.flags() & ios_base::showbase)
01163               // symbol is required.
01164               if (__j != __len && (__io.flags() & ios_base::showbase))
01165             __testvalid = false;
01166             }
01167           break;
01168         case money_base::sign:          
01169           // Sign might not exist, or be more than one character long. 
01170           if (__pos_sign.size() && __neg_sign.size())
01171           {
01172             // Sign is mandatory.
01173             if (__c == __pos_sign[0])
01174               {
01175             __sign = __pos_sign;
01176             __c = *(++__beg);
01177               }
01178             else if (__c == __neg_sign[0])
01179               {
01180             __sign = __neg_sign;
01181             __c = *(++__beg);
01182               }
01183             else
01184               __testvalid = false;
01185           }
01186           else if (__pos_sign.size() && __c == __pos_sign[0])
01187             {
01188               __sign = __pos_sign;
01189               __c = *(++__beg);
01190             }
01191           else if (__neg_sign.size() && __c == __neg_sign[0])
01192             {
01193               __sign = __neg_sign;
01194               __c = *(++__beg);
01195             }
01196           break;
01197         case money_base::value:
01198           // Extract digits, remove and stash away the
01199           // grouping of found thousands separators.
01200           while (__beg != __end 
01201              && (__ctype.is(ctype_base::digit, __c) 
01202                  || (__c == __d && !__testdecfound)
01203                  || __c == __sep))
01204             {
01205               if (__c == __d)
01206             {
01207               __grouping_tmp += static_cast<char>(__sep_pos);
01208               __sep_pos = 0;
01209               __testdecfound = true;
01210             }
01211               else if (__c == __sep)
01212             {
01213               if (__grouping.size())
01214                 {
01215                   // Mark position for later analysis.
01216                   __grouping_tmp += static_cast<char>(__sep_pos);
01217                   __sep_pos = 0;
01218                 }
01219               else
01220                 {
01221                   __testvalid = false;
01222                   break;
01223                 }
01224             }
01225               else
01226             {
01227               __temp_units += __c;
01228               ++__sep_pos;
01229             }
01230               __c = *(++__beg);
01231             }
01232           break;
01233         case money_base::space:
01234         case money_base::none:
01235           // Only if not at the end of the pattern.
01236           if (__i != 3)
01237             while (__beg != __end 
01238                && __ctype.is(ctype_base::space, __c))
01239               __c = *(++__beg);
01240           break;
01241         }
01242     }
01243 
01244       // Need to get the rest of the sign characters, if they exist.
01245       if (__sign.size() > 1)
01246     {
01247       size_type __len = __sign.size();
01248       size_type __i = 1;
01249       for (; __c != __eof && __i < __len; ++__i)
01250         while (__beg != __end && __c != __sign[__i])
01251           __c = *(++__beg);
01252       
01253       if (__i != __len)
01254         __testvalid = false;
01255     }
01256 
01257       // Strip leading zeros.
01258       while (__temp_units[0] == __ctype.widen('0'))
01259     __temp_units.erase(__temp_units.begin());
01260 
01261       if (__sign.size() && __sign == __neg_sign)
01262     __temp_units.insert(__temp_units.begin(), __ctype.widen('-'));
01263 
01264       // Test for grouping fidelity.
01265       if (__grouping.size() && __grouping_tmp.size())
01266     {
01267       if (!__verify_grouping(__grouping, __grouping_tmp))
01268         __testvalid = false;
01269     }
01270 
01271       // Iff no more characters are available.      
01272       if (__c == __eof)
01273     __err |= ios_base::eofbit;
01274 
01275       // Iff valid sequence is not recognized.
01276       if (!__testvalid || !__temp_units.size())
01277     __err |= ios_base::failbit;
01278       else
01279     // Use the "swap trick" to copy __temp_units into __units.
01280     __temp_units.swap(__units);
01281 
01282       return __beg; 
01283     }
01284 
01285   template<typename _CharT, typename _OutIter>
01286     _OutIter
01287     money_put<_CharT, _OutIter>::
01288     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
01289        long double __units) const
01290     { 
01291       const locale __loc = __io.getloc();
01292       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
01293 #ifdef _GLIBCPP_USE_C99
01294       // First try a buffer perhaps big enough.
01295       int __cs_size = 64;
01296       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
01297       int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
01298                    _S_c_locale);
01299       // If the buffer was not large enough, try again with the correct size.
01300       if (__len >= __cs_size)
01301     {
01302       __cs_size = __len + 1;
01303       __cs = static_cast<char*>(__builtin_alloca(__cs_size));
01304       __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
01305                    _S_c_locale);
01306     }
01307 #else
01308       // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
01309       // decimal digit, '\0'. 
01310       const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
01311       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
01312       int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale);
01313 #endif
01314       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
01315                                * __cs_size));
01316       __ctype.widen(__cs, __cs + __len, __ws);
01317       string_type __digits(__ws);
01318       return this->do_put(__s, __intl, __io, __fill, __digits); 
01319     }
01320 
01321   template<typename _CharT, typename _OutIter>
01322     _OutIter
01323     money_put<_CharT, _OutIter>::
01324     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
01325        const string_type& __digits) const
01326     { 
01327       typedef typename string_type::size_type   size_type;
01328       typedef money_base::part          part;
01329 
01330       const locale __loc = __io.getloc();
01331       const size_type __width = static_cast<size_type>(__io.width());
01332 
01333       // These contortions are quite unfortunate.
01334       typedef moneypunct<_CharT, true> __money_true;
01335       typedef moneypunct<_CharT, false> __money_false;
01336       const __money_true& __mpt = use_facet<__money_true>(__loc); 
01337       const __money_false& __mpf = use_facet<__money_false>(__loc); 
01338       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
01339 
01340       // Determine if negative or positive formats are to be used, and
01341       // discard leading negative_sign if it is present.
01342       const char_type* __beg = __digits.data();
01343       const char_type* __end = __beg + __digits.size();
01344       money_base::pattern __p;
01345       string_type __sign;
01346       if (*__beg != __ctype.widen('-'))
01347     {
01348       __p = __intl ? __mpt.pos_format() : __mpf.pos_format();
01349       __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign();
01350     }
01351       else
01352     {
01353       __p = __intl ? __mpt.neg_format() : __mpf.neg_format();
01354       __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign();
01355       ++__beg;
01356     }
01357       
01358       // Look for valid numbers in the current ctype facet within input digits.
01359       __end = __ctype.scan_not(ctype_base::digit, __beg, __end);
01360       if (__beg != __end)
01361     {
01362       // Assume valid input, and attempt to format.
01363       // Break down input numbers into base components, as follows:
01364       //   final_value = grouped units + (decimal point) + (digits)
01365       string_type __res;
01366       string_type __value;
01367       const string_type __symbol = __intl ? __mpt.curr_symbol() 
01368                               : __mpf.curr_symbol();
01369 
01370       // Deal with decimal point, decimal digits.
01371       const int __frac = __intl ? __mpt.frac_digits() 
01372                         : __mpf.frac_digits();
01373       if (__frac > 0)
01374         {
01375           const char_type __d = __intl ? __mpt.decimal_point() 
01376                        : __mpf.decimal_point();
01377           if (__end - __beg >= __frac)
01378         {
01379           __value = string_type(__end - __frac, __end);
01380           __value.insert(__value.begin(), __d);
01381           __end -= __frac;
01382         }
01383           else
01384         {
01385           // Have to pad zeros in the decimal position.
01386           __value = string_type(__beg, __end);
01387           int __paddec = __frac - (__end - __beg);
01388           char_type __zero = __ctype.widen('0');
01389           __value.insert(__value.begin(), __paddec, __zero);
01390           __value.insert(__value.begin(), __d);
01391           __beg = __end;
01392         }
01393         }
01394 
01395       // Add thousands separators to non-decimal digits, per
01396       // grouping rules.
01397       if (__beg != __end)
01398         {
01399           const string __grouping = __intl ? __mpt.grouping() 
01400                            : __mpf.grouping();
01401           if (__grouping.size())
01402         {
01403           const char_type __sep = __intl ? __mpt.thousands_sep() 
01404                                  : __mpf.thousands_sep();
01405           const char* __gbeg = __grouping.c_str();
01406           const char* __gend = __gbeg + __grouping.size();
01407           const int __n = (__end - __beg) * 2;
01408           _CharT* __ws2 =
01409                   static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
01410           _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
01411                             __gend, __beg, __end);
01412           __value.insert(0, __ws2, __ws_end - __ws2);
01413         }
01414           else
01415         __value.insert(0, string_type(__beg, __end));
01416         }
01417 
01418       // Calculate length of resulting string.
01419       ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield;
01420       size_type __len = __value.size() + __sign.size();
01421       __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0;
01422       bool __testipad = __f == ios_base::internal && __len < __width;
01423 
01424       // Fit formatted digits into the required pattern.
01425       for (int __i = 0; __i < 4; ++__i)
01426         {
01427           part __which = static_cast<part>(__p.field[__i]);
01428           switch (__which)
01429         {
01430         case money_base::symbol:
01431           if (__io.flags() & ios_base::showbase)
01432             __res += __symbol;
01433           break;
01434         case money_base::sign:          
01435           // Sign might not exist, or be more than one
01436           // charater long. In that case, add in the rest
01437           // below.
01438           if (__sign.size())
01439             __res += __sign[0];
01440           break;
01441         case money_base::value:
01442           __res += __value;
01443           break;
01444         case money_base::space:
01445           // At least one space is required, but if internal
01446           // formatting is required, an arbitrary number of
01447           // fill spaces will be necessary.
01448           if (__testipad)
01449             __res += string_type(__width - __len, __fill);
01450           else
01451             __res += __ctype.widen(__fill);
01452           break;
01453         case money_base::none:
01454           if (__testipad)
01455             __res += string_type(__width - __len, __fill);
01456           break;
01457         }
01458         }
01459 
01460       // Special case of multi-part sign parts.
01461       if (__sign.size() > 1)
01462         __res += string_type(__sign.begin() + 1, __sign.end());
01463 
01464       // Pad, if still necessary.
01465       __len = __res.size();
01466       if (__width > __len)
01467         {
01468           if (__f == ios_base::left)
01469         // After.
01470         __res.append(__width - __len, __fill);
01471           else
01472         // Before.
01473         __res.insert(0, string_type(__width - __len, __fill));
01474           __len = __width;
01475         }
01476 
01477       // Write resulting, fully-formatted string to output iterator.
01478       __s = __write(__s, __res.c_str(), __len);
01479     }
01480       __io.width(0);
01481       return __s; 
01482     }
01483 
01484 
01485   // NB: Not especially useful. Without an ios_base object or some
01486   // kind of locale reference, we are left clawing at the air where
01487   // the side of the mountain used to be...
01488   template<typename _CharT, typename _InIter>
01489     time_base::dateorder
01490     time_get<_CharT, _InIter>::do_date_order() const
01491     { return time_base::no_order; }
01492 
01493   template<typename _CharT, typename _InIter>
01494     void
01495     time_get<_CharT, _InIter>::
01496     _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
01497               ios_base::iostate& __err, tm* __tm, 
01498               const _CharT* __format) const
01499     {  
01500       locale __loc = __io.getloc();
01501       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
01502       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
01503       size_t __len = char_traits<_CharT>::length(__format);
01504 
01505       for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
01506     {
01507       char __c = __format[__i];
01508       if (__c == '%')
01509         {
01510           // Verify valid formatting code, attempt to extract.
01511           __c = __format[++__i];
01512           char __mod = 0;
01513           int __mem = 0; 
01514           if (__c == 'E' || __c == 'O')
01515         {
01516           __mod = __c;
01517           __c = __format[++__i];
01518         }
01519           switch (__c)
01520         {
01521           const char* __cs;
01522           _CharT __wcs[10];
01523         case 'a':
01524           // Abbreviated weekday name [tm_wday]
01525           const char_type*  __days1[7];
01526           __tp._M_days_abbreviated(__days1);
01527           _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, 
01528                   __err);
01529           break;
01530         case 'A':
01531           // Weekday name [tm_wday].
01532           const char_type*  __days2[7];
01533           __tp._M_days(__days2);
01534           _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, 
01535                   __err);
01536           break;
01537         case 'h':
01538         case 'b':
01539           // Abbreviated month name [tm_mon]
01540           const char_type*  __months1[12];
01541           __tp._M_months_abbreviated(__months1);
01542           _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, 
01543                   __err);
01544           break;
01545         case 'B':
01546           // Month name [tm_mon].
01547           const char_type*  __months2[12];
01548           __tp._M_months(__months2);
01549           _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, 
01550                   __err);
01551           break;
01552         case 'c':
01553           // Default time and date representation.
01554           const char_type*  __dt[2];
01555           __tp._M_date_time_formats(__dt);
01556           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
01557                     __dt[0]);
01558           break;
01559         case 'd':
01560           // Day [01, 31]. [tm_mday]
01561           _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 
01562                  __ctype, __err);
01563           break;
01564         case 'D':
01565           // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
01566           __cs = "%m/%d/%y";
01567           __ctype.widen(__cs, __cs + 9, __wcs);
01568           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
01569                     __wcs);
01570           break;
01571         case 'H':
01572           // Hour [00, 23]. [tm_hour]
01573           _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
01574                  __ctype, __err);
01575           break;
01576         case 'I':
01577           // Hour [01, 12]. [tm_hour]
01578           _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, 
01579                  __ctype, __err);
01580           break;
01581         case 'm':
01582           // Month [01, 12]. [tm_mon]
01583           _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype, 
01584                  __err);
01585           if (!__err)
01586             __tm->tm_mon = __mem - 1;
01587           break;
01588         case 'M':
01589           // Minute [00, 59]. [tm_min]
01590           _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
01591                  __ctype, __err);
01592           break;
01593         case 'n':
01594           if (__ctype.narrow(*__beg, 0) == '\n')
01595             ++__beg;
01596           else
01597             __err |= ios_base::failbit;
01598           break;
01599         case 'R':
01600           // Equivalent to (%H:%M).
01601           __cs = "%H:%M";
01602           __ctype.widen(__cs, __cs + 6, __wcs);
01603           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
01604                     __wcs);
01605           break;
01606         case 'S':
01607           // Seconds.
01608           _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2,
01609                  __ctype, __err);
01610           break;
01611         case 't':
01612           if (__ctype.narrow(*__beg, 0) == '\t')
01613             ++__beg;
01614           else
01615         __err |= ios_base::failbit;
01616           break;
01617         case 'T':
01618           // Equivalent to (%H:%M:%S).
01619           __cs = "%H:%M:%S";
01620           __ctype.widen(__cs, __cs + 9, __wcs);
01621           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
01622                     __wcs);
01623           break;
01624         case 'x':
01625           // Locale's date.
01626           const char_type*  __dates[2];
01627           __tp._M_date_formats(__dates);
01628           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
01629                     __dates[0]);
01630           break;
01631         case 'X':
01632           // Locale's time.
01633           const char_type*  __times[2];
01634           __tp._M_time_formats(__times);
01635           _M_extract_via_format(__beg, __end, __io, __err, __tm, 
01636                     __times[0]);
01637           break;
01638         case 'y':
01639           // Two digit year. [tm_year]
01640           _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, 
01641                  __ctype, __err);
01642           break;
01643         case 'Y':
01644           // Year [1900). [tm_year]
01645           _M_extract_num(__beg, __end, __mem, 0, 
01646                  numeric_limits<int>::max(), 4, 
01647                  __ctype, __err);
01648           if (!__err)
01649             __tm->tm_year = __mem - 1900;
01650           break;
01651         case 'Z':
01652           // Timezone info.
01653           if (__ctype.is(ctype_base::upper, *__beg))
01654             {
01655               int __tmp;
01656               _M_extract_name(__beg, __end, __tmp, 
01657                       __timepunct<_CharT>::_S_timezones, 
01658                       14, __err);
01659               
01660               // GMT requires special effort.
01661               char_type __c = *__beg;
01662               if (!__err && __tmp == 0 
01663               && (__c == __ctype.widen('-') 
01664                   || __c == __ctype.widen('+')))
01665             {
01666               _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
01667                       __ctype, __err);
01668               _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
01669                       __ctype, __err);
01670             }       
01671               }
01672               else
01673             __err |= ios_base::failbit;
01674               break;
01675             default:
01676               // Not recognized.
01677               __err |= ios_base::failbit;
01678             }
01679         }
01680           else
01681         {
01682           // Verify format and input match, extract and discard.
01683           if (__c == __ctype.narrow(*__beg, 0))
01684             ++__beg;
01685           else
01686             __err |= ios_base::failbit;
01687         }
01688     }
01689     }
01690 
01691   template<typename _CharT, typename _InIter>
01692     void
01693     time_get<_CharT, _InIter>::
01694     _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
01695            int __min, int __max, size_t __len, 
01696            const ctype<_CharT>& __ctype, 
01697            ios_base::iostate& __err) const
01698     {
01699       size_t __i = 0;
01700       string __digits;
01701       bool __testvalid = true;
01702       char_type __c = *__beg;
01703       while (__beg != __end && __i < __len 
01704          && __ctype.is(ctype_base::digit, __c)) 
01705     {
01706       __digits += __ctype.narrow(__c, 0);
01707       __c = *(++__beg);
01708       ++__i;
01709     }
01710       if (__i == __len)
01711     {
01712       int __value = atoi(__digits.c_str());
01713       if (__min <= __value && __value <= __max)
01714         __member = __value;
01715       else
01716         __testvalid = false;
01717     }
01718       else
01719     __testvalid = false;
01720       if (!__testvalid)
01721     __err |= ios_base::failbit;
01722     }
01723 
01724   // Assumptions:
01725   // All elements in __names are unique.
01726   template<typename _CharT, typename _InIter>
01727     void
01728     time_get<_CharT, _InIter>::
01729     _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
01730             const _CharT** __names, size_t __indexlen, 
01731             ios_base::iostate& __err) const
01732     {
01733       typedef char_traits<_CharT>       __traits_type;
01734       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) 
01735                               * __indexlen));
01736       size_t __nmatches = 0;
01737       size_t __pos = 0;
01738       bool __testvalid = true;
01739       const char_type* __name;
01740 
01741       char_type __c = *__beg;
01742       // Look for initial matches.
01743       for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
01744     if (__c == __names[__i1][0])
01745       __matches[__nmatches++] = __i1;
01746       
01747       while (__nmatches > 1)
01748     {
01749       // Find smallest matching string.
01750       size_t __minlen = 10;
01751       for (size_t __i2 = 0; __i2 < __nmatches; ++__i2)
01752         __minlen = min(__minlen,
01753                __traits_type::length(__names[__matches[__i2]]));
01754       
01755       if (__pos < __minlen && __beg != __end)
01756         {
01757           ++__pos;
01758           __c = *(++__beg);
01759           for (size_t __i3 = 0; __i3 < __nmatches; ++__i3)
01760         {
01761           __name = __names[__matches[__i3]];
01762           if (__name[__pos] != __c)
01763             __matches[__i3] = __matches[--__nmatches];
01764         }
01765         }
01766       else
01767         break;
01768     }
01769 
01770       if (__nmatches == 1)
01771     {
01772       // Make sure found name is completely extracted.
01773       __name = __names[__matches[0]];
01774       const size_t __len = __traits_type::length(__name);
01775       while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
01776         ++__beg, ++__pos;
01777 
01778       if (__len == __pos)
01779         __member = __matches[0];
01780       else
01781         __testvalid = false;
01782     }
01783       else
01784     __testvalid = false;
01785       if (!__testvalid)
01786     __err |= ios_base::failbit;
01787     }
01788 
01789   template<typename _CharT, typename _InIter>
01790     _InIter
01791     time_get<_CharT, _InIter>::
01792     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
01793         ios_base::iostate& __err, tm* __tm) const
01794     {
01795       _CharT __wcs[3];
01796       const char* __cs = "%X";
01797       locale __loc = __io.getloc();
01798       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
01799       __ctype.widen(__cs, __cs + 3, __wcs);
01800       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
01801       if (__beg == __end)
01802     __err |= ios_base::eofbit;
01803       return __beg;
01804     }
01805 
01806   template<typename _CharT, typename _InIter>
01807     _InIter
01808     time_get<_CharT, _InIter>::
01809     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
01810         ios_base::iostate& __err, tm* __tm) const
01811     {
01812       _CharT __wcs[3];
01813       const char* __cs = "%x";
01814       locale __loc = __io.getloc();
01815       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
01816       __ctype.widen(__cs, __cs + 3, __wcs);
01817       _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs);
01818       if (__beg == __end)
01819     __err |= ios_base::eofbit;
01820       return __beg;
01821     }
01822 
01823   template<typename _CharT, typename _InIter>
01824     _InIter
01825     time_get<_CharT, _InIter>::
01826     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 
01827            ios_base::iostate& __err, tm* __tm) const
01828     {
01829       typedef char_traits<_CharT>       __traits_type;
01830       locale __loc = __io.getloc();
01831       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
01832       const char_type*  __days[7];
01833       __tp._M_days_abbreviated(__days);
01834       int __tmpwday;
01835       _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err);
01836 
01837       // Check to see if non-abbreviated name exists, and extract.
01838       // NB: Assumes both _M_days and _M_days_abbreviated organized in
01839       // exact same order, first to last, such that the resulting
01840       // __days array with the same index points to a day, and that
01841       // day's abbreviated form.
01842       // NB: Also assumes that an abbreviated name is a subset of the name. 
01843       if (!__err)
01844     {
01845       size_t __pos = __traits_type::length(__days[__tmpwday]);
01846       __tp._M_days(__days);
01847       const char_type* __name = __days[__tmpwday];
01848       if (__name[__pos] == *__beg)
01849         {
01850           // Extract the rest of it.
01851           const size_t __len = __traits_type::length(__name);
01852           while (__pos < __len && __beg != __end 
01853              && __name[__pos] == *__beg)
01854         ++__beg, ++__pos;
01855           if (__len != __pos)
01856         __err |= ios_base::failbit;
01857         }
01858       if (!__err)
01859         __tm->tm_wday = __tmpwday;
01860     }
01861       if (__beg == __end)
01862     __err |= ios_base::eofbit;
01863       return __beg;
01864      }
01865 
01866   template<typename _CharT, typename _InIter>
01867     _InIter
01868     time_get<_CharT, _InIter>::
01869     do_get_monthname(iter_type __beg, iter_type __end,
01870                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
01871     {
01872       typedef char_traits<_CharT>       __traits_type;
01873       locale __loc = __io.getloc();
01874       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
01875       const char_type*  __months[12];
01876       __tp._M_months_abbreviated(__months);
01877       int __tmpmon;
01878       _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err);
01879 
01880       // Check to see if non-abbreviated name exists, and extract.
01881       // NB: Assumes both _M_months and _M_months_abbreviated organized in
01882       // exact same order, first to last, such that the resulting
01883       // __months array with the same index points to a month, and that
01884       // month's abbreviated form.
01885       // NB: Also assumes that an abbreviated name is a subset of the name. 
01886       if (!__err)
01887     {
01888       size_t __pos = __traits_type::length(__months[__tmpmon]);
01889       __tp._M_months(__months);
01890       const char_type* __name = __months[__tmpmon];
01891       if (__name[__pos] == *__beg)
01892         {
01893           // Extract the rest of it.
01894           const size_t __len = __traits_type::length(__name);
01895           while (__pos < __len && __beg != __end 
01896              && __name[__pos] == *__beg)
01897         ++__beg, ++__pos;
01898           if (__len != __pos)
01899         __err |= ios_base::failbit;
01900         }
01901       if (!__err)
01902         __tm->tm_mon = __tmpmon;
01903     }
01904  
01905       if (__beg == __end)
01906     __err |= ios_base::eofbit;
01907       return __beg;
01908     }
01909 
01910   template<typename _CharT, typename _InIter>
01911     _InIter
01912     time_get<_CharT, _InIter>::
01913     do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 
01914         ios_base::iostate& __err, tm* __tm) const
01915     {
01916       locale __loc = __io.getloc();
01917       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
01918 
01919       char_type __c = *__beg;
01920       size_t __i = 0;
01921       string __digits;
01922       while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c))
01923     {
01924       __digits += __ctype.narrow(__c, 0);
01925       __c = *(++__beg);
01926       ++__i;
01927     }
01928       if (__i == 2 || __i == 4)
01929     {
01930       long __l;
01931       __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
01932       if (!(__err & ios_base::failbit) && __l <= INT_MAX)
01933         {
01934           __l = __i == 2 ? __l : __l - 1900; 
01935           __tm->tm_year = static_cast<int>(__l);
01936         }
01937     }
01938       else
01939     __err |= ios_base::failbit;
01940       if (__beg == __end)
01941     __err |= ios_base::eofbit;
01942       return __beg;
01943     }
01944 
01945   template<typename _CharT, typename _OutIter>
01946     _OutIter
01947     time_put<_CharT, _OutIter>::
01948     put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
01949     const _CharT* __beg, const _CharT* __end) const
01950     {
01951       locale __loc = __io.getloc();
01952       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
01953       while (__beg != __end)
01954     {
01955       char __c = __ctype.narrow(*__beg, 0);
01956       ++__beg;
01957       if (__c == '%')
01958         {
01959           char __format;
01960           char __mod = 0;
01961           size_t __len = 1; 
01962           __c = __ctype.narrow(*__beg, 0);
01963           ++__beg;
01964           if (__c == 'E' || __c == 'O')
01965         {
01966           __mod = __c;
01967           __format = __ctype.narrow(*__beg, 0);
01968           ++__beg;
01969         }
01970           else
01971         __format = __c;
01972           __s = this->do_put(__s, __io, _CharT(), __tm, __format, __mod);
01973         }
01974       else
01975         {
01976           *__s = __c;
01977           ++__s;
01978         }
01979     }
01980       return __s;
01981     }
01982 
01983   template<typename _CharT, typename _OutIter>
01984     _OutIter
01985     time_put<_CharT, _OutIter>::
01986     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 
01987        char __format, char __mod) const
01988     { 
01989       locale __loc = __io.getloc();
01990       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
01991       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
01992 
01993       // NB: This size is arbitrary. Should this be a data member,
01994       // initialized at construction?
01995       const size_t __maxlen = 64;
01996       char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
01997 
01998       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
01999       // is possible that the format character will be longer than one
02000       // character. Possibilities include 'E' or 'O' followed by a
02001       // format character: if __mod is not the default argument, assume
02002       // it's a valid modifier.
02003       char_type __fmt[4];
02004       __fmt[0] = __ctype.widen('%'); 
02005       if (!__mod)
02006     {
02007       __fmt[1] = __format;
02008       __fmt[2] = char_type();
02009     }
02010       else
02011     {
02012       __fmt[1] = __mod;
02013       __fmt[2] = __format;
02014       __fmt[3] = char_type();
02015     }
02016 
02017       __tp._M_put(__res, __maxlen, __fmt, __tm);
02018 
02019       // Write resulting, fully-formatted string to output iterator.
02020       return __write(__s, __res, char_traits<char_type>::length(__res));
02021     }
02022 
02023 
02024   // Generic version does nothing.
02025   template<typename _CharT>
02026     int
02027     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
02028     { return 0; }
02029 
02030   // Generic version does nothing.
02031   template<typename _CharT>
02032     size_t
02033     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
02034     { return 0; }
02035 
02036   template<typename _CharT>
02037     int
02038     collate<_CharT>::
02039     do_compare(const _CharT* __lo1, const _CharT* __hi1, 
02040            const _CharT* __lo2, const _CharT* __hi2) const
02041     { 
02042       // strcoll assumes zero-terminated strings so we make a copy
02043       // and then put a zero at the end.
02044       const string_type __one(__lo1, __hi1);
02045       const string_type __two(__lo2, __hi2);
02046 
02047       const _CharT* __p = __one.c_str();
02048       const _CharT* __pend = __one.c_str() + __one.length();
02049       const _CharT* __q = __two.c_str();
02050       const _CharT* __qend = __two.c_str() + __two.length();
02051 
02052       // strcoll stops when it sees a nul character so we break
02053       // the strings into zero-terminated substrings and pass those
02054       // to strcoll.
02055       for (;;)
02056     {
02057       int __res = _M_compare(__p, __q);
02058       if (__res)
02059         return __res;
02060 
02061       __p += char_traits<_CharT>::length(__p);
02062       __q += char_traits<_CharT>::length(__q);
02063       if (__p == __pend && __q == __qend)
02064         return 0;
02065       else if (__p == __pend)
02066         return -1;
02067       else if (__q == __qend)
02068         return 1;
02069 
02070       __p++;
02071       __q++;
02072     }
02073     }
02074 
02075  template<typename _CharT>
02076     typename collate<_CharT>::string_type
02077     collate<_CharT>::
02078     do_transform(const _CharT* __lo, const _CharT* __hi) const
02079     {
02080       // strxfrm assumes zero-terminated strings so we make a copy
02081       string_type __str(__lo, __hi);
02082 
02083       const _CharT* __p = __str.c_str();
02084       const _CharT* __pend = __str.c_str() + __str.length();
02085 
02086       size_t __len = (__hi - __lo) * 2;
02087 
02088       string_type __ret;
02089 
02090       // strxfrm stops when it sees a nul character so we break
02091       // the string into zero-terminated substrings and pass those
02092       // to strxfrm.
02093       for (;;)
02094     {
02095       // First try a buffer perhaps big enough.
02096       _CharT* __c =
02097         static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
02098       size_t __res = _M_transform(__c, __p, __len);
02099       // If the buffer was not large enough, try again with the
02100       // correct size.
02101       if (__res >= __len)
02102         {
02103           __len = __res + 1;
02104           __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02105                               * __len));
02106           __res = _M_transform(__c, __p, __res + 1);
02107         }
02108 
02109       __ret.append(__c, __res);
02110       __p += char_traits<_CharT>::length(__p);
02111       if (__p == __pend)
02112         return __ret;
02113 
02114       __p++;
02115       __ret.push_back(_CharT());
02116     }
02117     }
02118 
02119  template<typename _CharT>
02120     long
02121     collate<_CharT>::
02122     do_hash(const _CharT* __lo, const _CharT* __hi) const
02123     { 
02124       unsigned long __val = 0;
02125       for (; __lo < __hi; ++__lo)
02126     __val = *__lo + ((__val << 7) | 
02127                (__val >> (numeric_limits<unsigned long>::digits - 7)));
02128       return static_cast<long>(__val);
02129     }
02130 
02131   // Construct correctly padded string, as per 22.2.2.2.2
02132   // Assumes 
02133   // __newlen > __oldlen
02134   // __news is allocated for __newlen size
02135   // Used by both num_put and ostream inserters: if __num,
02136   // internal-adjusted objects are padded according to the rules below
02137   // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
02138   // ones are.
02139 
02140   // NB: Of the two parameters, _CharT can be deduced from the
02141   // function arguments. The other (_Traits) has to be explicitly specified.
02142   template<typename _CharT, typename _Traits>
02143     void 
02144     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, 
02145                    _CharT* __news, const _CharT* __olds, 
02146                    const streamsize __newlen, 
02147                    const streamsize __oldlen, const bool __num)
02148     {
02149       size_t __plen = static_cast<size_t>(__newlen - __oldlen);
02150       _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02151                                  * __plen));
02152       _Traits::assign(__pads, __plen, __fill); 
02153 
02154       _CharT* __beg;
02155       _CharT* __end;
02156       size_t __mod = 0;
02157       size_t __beglen; //either __plen or __oldlen
02158       ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
02159 
02160       if (__adjust == ios_base::left)
02161     {
02162       // Padding last.
02163       __beg = const_cast<_CharT*>(__olds);
02164       __beglen = __oldlen;
02165       __end = __pads;
02166     }
02167       else if (__adjust == ios_base::internal && __num)
02168     {
02169       // Pad after the sign, if there is one.
02170       // Pad after 0[xX], if there is one.
02171       // Who came up with these rules, anyway? Jeeze.
02172           locale __loc = __io.getloc();
02173       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
02174       const _CharT __minus = __ctype.widen('-');
02175       const _CharT __plus = __ctype.widen('+');
02176       bool __testsign = _Traits::eq(__olds[0], __minus)
02177                     || _Traits::eq(__olds[0], __plus);
02178 
02179       bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0]) 
02180                    && (_Traits::eq(__ctype.widen('x'), __olds[1]) 
02181                    || _Traits::eq(__ctype.widen('X'), __olds[1]));
02182       if (__testhex)
02183         {
02184           __news[0] = __olds[0]; 
02185           __news[1] = __olds[1];
02186           __mod += 2;
02187           __news += 2;
02188           __beg = __pads;
02189           __beglen = __plen;
02190           __end = const_cast<_CharT*>(__olds + __mod);
02191         }
02192       else if (__testsign)
02193         {
02194           _Traits::eq((__news[0] = __olds[0]), __plus) ? __plus : __minus;
02195           ++__mod;
02196           ++__news;
02197           __beg = __pads;
02198           __beglen = __plen;
02199           __end = const_cast<_CharT*>(__olds + __mod);
02200         }
02201       else
02202         {
02203           // Padding first.
02204           __beg = __pads;
02205           __beglen = __plen;
02206           __end = const_cast<_CharT*>(__olds);
02207         }
02208     }
02209       else
02210     {
02211       // Padding first.
02212       __beg = __pads;
02213       __beglen = __plen;
02214       __end = const_cast<_CharT*>(__olds);
02215     }
02216       _Traits::copy(__news, __beg, __beglen);
02217       _Traits::copy(__news + __beglen, __end, 
02218               __newlen - __beglen - __mod);
02219     }
02220 
02221   template<typename _CharT>
02222     bool
02223     __verify_grouping(const basic_string<_CharT>& __grouping, 
02224               basic_string<_CharT>& __grouping_tmp)
02225     {         
02226       int __i = 0;
02227       int __j = 0;
02228       const int __len = __grouping.size();
02229       const int __n = __grouping_tmp.size();
02230       bool __test = true;
02231       
02232       // Parsed number groupings have to match the
02233       // numpunct::grouping string exactly, starting at the
02234       // right-most point of the parsed sequence of elements ...
02235       while (__test && __i < __n - 1)
02236     for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i)
02237       __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1];
02238       // ... but the last parsed grouping can be <= numpunct
02239       // grouping.
02240       __j == __len ? __j = 0 : __j;
02241       __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1];
02242       return __test;
02243     }
02244 
02245   template<typename _CharT>
02246     _CharT*
02247     __add_grouping(_CharT* __s, _CharT __sep,  
02248            const char* __gbeg, const char* __gend, 
02249            const _CharT* __first, const _CharT* __last)
02250     {
02251       if (__last - __first > *__gbeg)
02252         {
02253           __s = __add_grouping(__s,  __sep, 
02254                    (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
02255                    __gend, __first, __last - *__gbeg);
02256           __first = __last - *__gbeg;
02257           *__s++ = __sep;
02258         }
02259       do
02260     *__s++ = *__first++;
02261       while (__first != __last);
02262       return __s;
02263     }
02264 
02265   template<typename _CharT>
02266     void
02267     __locale_cache<_CharT>::_M_init(const locale& __loc)
02268     {
02269       if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
02270         {
02271           const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
02272           _M_falsename = __np.falsename();
02273           _M_truename = __np.truename();
02274           _M_thousands_sep = __np.thousands_sep();
02275           _M_decimal_point = __np.decimal_point();
02276           _M_grouping = __np.grouping();
02277           _M_use_grouping = _M_grouping.size() != 0 
02278                             && _M_grouping.data()[0] != 0;
02279         }
02280       if (__builtin_expect(has_facet<ctype<_CharT> >(__loc), true))
02281         {
02282           const ctype<_CharT>& __ct = use_facet< ctype<_CharT> >(__loc);
02283           __ct.widen(__num_base::_S_atoms_out,
02284                      __num_base::_S_atoms_out + __num_base::_S_end, 
02285                      _M_literals);
02286         }
02287     }
02288 
02289   template<typename _CharT>
02290     void
02291     __locale_cache<_CharT>::_S_callback(ios_base::event __ev, ios_base& __io, int)
02292     {
02293       switch (__ev)
02294     {
02295     case ios_base::erase_event:
02296       if (__io.pword(0) && !__io.iword(0))
02297         delete &__io._M_cache();
02298       break;
02299 
02300     case ios_base::imbue_event:
02301       break;
02302 
02303     case ios_base::copyfmt_event:
02304       // This routine is called with the new ios_base, but pword(0) still
02305       // points to the cache from the old ios_base.  This replaces it with
02306       // a new cache.  Done here, so we don't get an extra callback from
02307       // basic_ios::_M_cache_locale.
02308       typedef __locale_cache<_CharT> __cache_t;
02309       __io.pword(0) = auto_ptr<__cache_t>(new __cache_t()).release();
02310       __io.iword(0) = 0;
02311       break;
02312     }
02313     }
02314 
02315 #if 1
02316       // XXX GLIBCXX_ABI Deprecated, compatibility only.
02317   template<typename _CharT, typename _OutIter>
02318     template<typename _ValueT>
02319       _OutIter
02320       num_put<_CharT, _OutIter>::
02321       _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
02322              char __modl, _ValueT __v) const
02323       {
02324     // [22.2.2.2.2] Stage 1, numeric conversion to character.
02325 
02326     // Long enough for the max format spec.
02327     char __fbuf[16];
02328     _S_format_int(__io, __fbuf, __mod, __modl);
02329 #ifdef _GLIBCPP_USE_C99
02330     // First try a buffer perhaps big enough.
02331     int __cs_size = 64;
02332     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
02333     int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
02334                      _S_c_locale);
02335     // If the buffer was not large enough, try again with the correct size.
02336     if (__len >= __cs_size)
02337       {
02338         __cs_size = __len + 1;
02339         __cs = static_cast<char*>(__builtin_alloca(__cs_size));
02340         __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, 
02341                      _S_c_locale);
02342       }
02343 #else
02344     // Leave room for "+/-," "0x," and commas. This size is
02345     // arbitrary, but should be largely sufficient.
02346     char __cs[128];
02347     int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
02348 #endif
02349     return _M_widen_int(__s, __io, __fill, __cs, __len);
02350       }
02351 
02352   template<typename _CharT, typename _OutIter>
02353     _OutIter
02354     num_put<_CharT, _OutIter>::
02355     _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
02356            int __len) const
02357     {
02358       typedef char_traits<_CharT>       __traits_type;
02359       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
02360       // numpunct.decimal_point() values for '.' and adding grouping.
02361       const locale __loc = __io.getloc();
02362       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
02363       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02364                                * __len));
02365       // Grouping can add (almost) as many separators as the number of
02366       // digits, but no more.
02367       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02368                                 * __len * 2));
02369       __ctype.widen(__cs, __cs + __len, __ws);
02370       
02371       // Replace decimal point.
02372       const _CharT* __p;
02373       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
02374       if (__p = __traits_type::find(__ws, __len, __ctype.widen('.')))
02375     __ws[__p - __ws] = __np.decimal_point();
02376 
02377 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
02378 //282. What types does numpunct grouping refer to?
02379       // Add grouping, if necessary. 
02380       const string __grouping = __np.grouping();
02381       if (__grouping.size())
02382     {
02383       _CharT* __p2;
02384       int __declen = __p ? __p - __ws : __len;
02385       __p2 = __add_grouping(__ws2, __np.thousands_sep(), 
02386                 __grouping.c_str(),
02387                 __grouping.c_str() + __grouping.size(),
02388                 __ws, __ws + __declen);
02389       int __newlen = __p2 - __ws2;
02390     
02391       // Tack on decimal part.
02392       if (__p)
02393         {
02394           __traits_type::copy(__p2, __p, __len - __declen);
02395           __newlen += __len - __declen;
02396         }    
02397 
02398       // Switch strings, establish correct new length.
02399       __ws = __ws2;
02400       __len = __newlen;
02401     }
02402 #endif
02403       return _M_insert(__s, __io, __fill, __ws, __len);
02404     }
02405 
02406   template<typename _CharT, typename _OutIter>
02407     _OutIter
02408     num_put<_CharT, _OutIter>::
02409     _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, 
02410          int __len) const
02411     {
02412       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
02413       // numpunct.decimal_point() values for '.' and adding grouping.
02414       const locale __loc = __io.getloc();
02415       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
02416       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02417                                * __len));
02418       // Grouping can add (almost) as many separators as the number of
02419       // digits, but no more.
02420       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02421                                 * __len * 2));
02422       __ctype.widen(__cs, __cs + __len, __ws);
02423 
02424       // Add grouping, if necessary. 
02425       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
02426       const string __grouping = __np.grouping();
02427       if (__grouping.size())
02428     {
02429       // By itself __add_grouping cannot deal correctly with __ws when
02430       // ios::showbase is set and ios_base::oct || ios_base::hex.
02431       // Therefore we take care "by hand" of the initial 0, 0x or 0X.
02432       // However, remember that the latter do not occur if the number
02433       // printed is '0' (__len == 1).
02434       streamsize __off = 0;
02435       const ios_base::fmtflags __basefield = __io.flags() 
02436                              & ios_base::basefield;
02437       if ((__io.flags() & ios_base::showbase) && __len > 1)
02438         if (__basefield == ios_base::oct)
02439           {
02440         __off = 1;
02441         *__ws2 = *__ws;
02442           }
02443         else if (__basefield == ios_base::hex)
02444           {
02445         __off = 2;
02446         *__ws2 = *__ws;
02447         *(__ws2 + 1) = *(__ws + 1);
02448           }
02449       _CharT* __p;
02450       __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), 
02451                    __grouping.c_str(),
02452                    __grouping.c_str() + __grouping.size(),
02453                    __ws + __off, __ws + __len);
02454       __len = __p - __ws2;
02455       // Switch strings.
02456       __ws = __ws2;
02457     }
02458       return _M_insert(__s, __io, __fill, __ws, __len);
02459     }
02460 
02461   // For use by integer and floating-point types after they have been
02462   // converted into a char_type string.
02463   template<typename _CharT, typename _OutIter>
02464     _OutIter
02465     num_put<_CharT, _OutIter>::
02466     _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, 
02467           int __len) const
02468     {
02469       typedef char_traits<_CharT>       __traits_type;
02470       // [22.2.2.2.2] Stage 3.
02471       // If necessary, pad.
02472       streamsize __w = __io.width();
02473       _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
02474                                 * __w));
02475       if (__w > static_cast<streamsize>(__len))
02476     {
02477       __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws, 
02478                            __w, __len, true);
02479       __len = static_cast<int>(__w);
02480       // Switch strings.
02481       __ws = __ws2;
02482     }
02483       __io.width(0);
02484 
02485       // [22.2.2.2.2] Stage 4.
02486       // Write resulting, fully-formatted string to output iterator.
02487       return __write(__s, __ws, __len);
02488     }
02489 #endif
02490 
02491   // Inhibit implicit instantiations for required instantiations,
02492   // which are defined via explicit instantiations elsewhere.  
02493   // NB: This syntax is a GNU extension.
02494 #if _GLIBCPP_EXTERN_TEMPLATE
02495   extern template class moneypunct<char, false>;
02496   extern template class moneypunct<char, true>;
02497   extern template class moneypunct_byname<char, false>;
02498   extern template class moneypunct_byname<char, true>;
02499   extern template class money_get<char>;
02500   extern template class money_put<char>;
02501   extern template class numpunct<char>;
02502   extern template class numpunct_byname<char>;
02503   extern template class num_get<char>;
02504   extern template class num_put<char>; 
02505   extern template class __timepunct<char>;
02506   extern template class time_put<char>;
02507   extern template class time_put_byname<char>;
02508   extern template class time_get<char>;
02509   extern template class time_get_byname<char>;
02510   extern template class messages<char>;
02511   extern template class messages_byname<char>;
02512   extern template class ctype_byname<char>;
02513   extern template class codecvt_byname<char, char, mbstate_t>;
02514   extern template class collate<char>;
02515   extern template class collate_byname<char>;
02516 
02517   extern template
02518     const codecvt<char, char, mbstate_t>& 
02519     use_facet<codecvt<char, char, mbstate_t> >(const locale&);
02520 
02521   extern template
02522     const collate<char>& 
02523     use_facet<collate<char> >(const locale&);
02524 
02525   extern template
02526     const numpunct<char>& 
02527     use_facet<numpunct<char> >(const locale&);
02528 
02529   extern template 
02530     const num_put<char>& 
02531     use_facet<num_put<char> >(const locale&);
02532 
02533   extern template 
02534     const num_get<char>& 
02535     use_facet<num_get<char> >(const locale&);
02536 
02537   extern template
02538     const moneypunct<char, true>& 
02539     use_facet<moneypunct<char, true> >(const locale&);
02540 
02541   extern template
02542     const moneypunct<char, false>& 
02543     use_facet<moneypunct<char, false> >(const locale&);
02544 
02545   extern template 
02546     const money_put<char>& 
02547     use_facet<money_put<char> >(const locale&);
02548 
02549   extern template 
02550     const money_get<char>& 
02551     use_facet<money_get<char> >(const locale&);
02552 
02553   extern template
02554     const __timepunct<char>& 
02555     use_facet<__timepunct<char> >(const locale&);
02556 
02557   extern template 
02558     const time_put<char>& 
02559     use_facet<time_put<char> >(const locale&);
02560 
02561   extern template 
02562     const time_get<char>& 
02563     use_facet<time_get<char> >(const locale&);
02564 
02565   extern template 
02566     const messages<char>& 
02567     use_facet<messages<char> >(const locale&);
02568 
02569   extern template 
02570     bool
02571     has_facet<ctype<char> >(const locale&);
02572 
02573   extern template 
02574     bool
02575     has_facet<codecvt<char, char, mbstate_t> >(const locale&);
02576 
02577   extern template 
02578     bool
02579     has_facet<collate<char> >(const locale&);
02580 
02581   extern template 
02582     bool
02583     has_facet<numpunct<char> >(const locale&);
02584 
02585   extern template 
02586     bool
02587     has_facet<num_put<char> >(const locale&);
02588 
02589   extern template 
02590     bool
02591     has_facet<num_get<char> >(const locale&);
02592 
02593   extern template 
02594     bool
02595     has_facet<moneypunct<char> >(const locale&);
02596 
02597   extern template 
02598     bool
02599     has_facet<money_put<char> >(const locale&);
02600 
02601   extern template 
02602     bool
02603     has_facet<money_get<char> >(const locale&);
02604 
02605   extern template 
02606     bool
02607     has_facet<__timepunct<char> >(const locale&);
02608 
02609   extern template 
02610     bool
02611     has_facet<time_put<char> >(const locale&);
02612 
02613   extern template 
02614     bool
02615     has_facet<time_get<char> >(const locale&);
02616 
02617   extern template 
02618     bool
02619     has_facet<messages<char> >(const locale&);
02620 
02621 #ifdef _GLIBCPP_USE_WCHAR_T
02622   extern template class moneypunct<wchar_t, false>;
02623   extern template class moneypunct<wchar_t, true>;
02624   extern template class moneypunct_byname<wchar_t, false>;
02625   extern template class moneypunct_byname<wchar_t, true>;
02626   extern template class money_get<wchar_t>;
02627   extern template class money_put<wchar_t>;
02628   extern template class numpunct<wchar_t>;
02629   extern template class numpunct_byname<wchar_t>;
02630   extern template class num_get<wchar_t>;
02631   extern template class num_put<wchar_t>;
02632   extern template class __timepunct<wchar_t>;
02633   extern template class time_put<wchar_t>;
02634   extern template class time_put_byname<wchar_t>;
02635   extern template class time_get<wchar_t>;
02636   extern template class time_get_byname<wchar_t>;
02637   extern template class messages<wchar_t>;
02638   extern template class messages_byname<wchar_t>;
02639   extern template class ctype_byname<wchar_t>;
02640   extern template class codecvt_byname<wchar_t, char, mbstate_t>;
02641   extern template class collate<wchar_t>;
02642   extern template class collate_byname<wchar_t>;
02643 
02644   extern template
02645     const codecvt<wchar_t, char, mbstate_t>& 
02646     use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&);
02647 
02648   extern template
02649     const collate<wchar_t>& 
02650     use_facet<collate<wchar_t> >(const locale&);
02651 
02652   extern template
02653     const numpunct<wchar_t>& 
02654     use_facet<numpunct<wchar_t> >(const locale&);
02655 
02656   extern template 
02657     const num_put<wchar_t>& 
02658     use_facet<num_put<wchar_t> >(const locale&);
02659 
02660   extern template 
02661     const num_get<wchar_t>& 
02662     use_facet<num_get<wchar_t> >(const locale&);
02663 
02664   extern template
02665     const moneypunct<wchar_t, true>& 
02666     use_facet<moneypunct<wchar_t, true> >(const locale&);
02667 
02668   extern template
02669     const moneypunct<wchar_t, false>& 
02670     use_facet<moneypunct<wchar_t, false> >(const locale&);
02671  
02672   extern template 
02673     const money_put<wchar_t>& 
02674     use_facet<money_put<wchar_t> >(const locale&);
02675 
02676   extern template 
02677     const money_get<wchar_t>& 
02678     use_facet<money_get<wchar_t> >(const locale&);
02679 
02680   extern template
02681     const __timepunct<wchar_t>& 
02682     use_facet<__timepunct<wchar_t> >(const locale&);
02683 
02684   extern template 
02685     const time_put<wchar_t>& 
02686     use_facet<time_put<wchar_t> >(const locale&);
02687 
02688   extern template 
02689     const time_get<wchar_t>& 
02690     use_facet<time_get<wchar_t> >(const locale&);
02691 
02692   extern template 
02693     const messages<wchar_t>& 
02694     use_facet<messages<wchar_t> >(const locale&);
02695 
02696  extern template 
02697     bool
02698     has_facet<ctype<wchar_t> >(const locale&);
02699 
02700   extern template 
02701     bool
02702     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
02703 
02704   extern template 
02705     bool
02706     has_facet<collate<wchar_t> >(const locale&);
02707 
02708   extern template 
02709     bool
02710     has_facet<numpunct<wchar_t> >(const locale&);
02711 
02712   extern template 
02713     bool
02714     has_facet<num_put<wchar_t> >(const locale&);
02715 
02716   extern template 
02717     bool
02718     has_facet<num_get<wchar_t> >(const locale&);
02719 
02720   extern template 
02721     bool
02722     has_facet<moneypunct<wchar_t> >(const locale&);
02723 
02724   extern template 
02725     bool
02726     has_facet<money_put<wchar_t> >(const locale&);
02727 
02728   extern template 
02729     bool
02730     has_facet<money_get<wchar_t> >(const locale&);
02731 
02732   extern template 
02733     bool
02734     has_facet<__timepunct<wchar_t> >(const locale&);
02735 
02736   extern template 
02737     bool
02738     has_facet<time_put<wchar_t> >(const locale&);
02739 
02740   extern template 
02741     bool
02742     has_facet<time_get<wchar_t> >(const locale&);
02743 
02744   extern template 
02745     bool
02746     has_facet<messages<wchar_t> >(const locale&);
02747 #endif
02748 #endif
02749 } // namespace std
02750 
02751 #endif

Generated on Tue Apr 29 20:16:22 2003 for libstdc++-v3 Source by doxygen1.3