locale_facets.tcc

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

Generated on Tue Jan 30 17:31:51 2007 for GNU C++ STL by doxygen 1.3.6