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, 2005,
00004 // 2006, 2007
00005 // Free Software Foundation, Inc.
00006 //
00007 // This file is part of the GNU ISO C++ Library.  This library is free
00008 // software; you can redistribute it and/or modify it under the
00009 // terms of the GNU General Public License as published by the
00010 // Free Software Foundation; either version 2, or (at your option)
00011 // any later version.
00012 
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 
00018 // You should have received a copy of the GNU General Public License along
00019 // with this library; see the file COPYING.  If not, write to the Free
00020 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021 // USA.
00022 
00023 // As a special exception, you may use this file as part of a free software
00024 // library without restriction.  Specifically, if other files instantiate
00025 // templates or use macros or inline functions from this file, or you compile
00026 // this file and link it with other files to produce an executable, this
00027 // file does not by itself cause the resulting executable to be covered by
00028 // the GNU General Public License.  This exception does not however
00029 // invalidate any other reasons why the executable file might be covered by
00030 // the GNU General Public License.
00031 
00032 /** @file locale_facets.tcc
00033  *  This is an internal header file, included by other library headers.
00034  *  You should not attempt to use it directly.
00035  */
00036 
00037 #ifndef _LOCALE_FACETS_TCC
00038 #define _LOCALE_FACETS_TCC 1
00039 
00040 #pragma GCC system_header
00041 
00042 _GLIBCXX_BEGIN_NAMESPACE(std)
00043 
00044   // Routine to access a cache for the facet.  If the cache didn't
00045   // exist before, it gets constructed on the fly.
00046   template<typename _Facet>
00047     struct __use_cache
00048     {
00049       const _Facet*
00050       operator() (const locale& __loc) const;
00051     };
00052 
00053   // Specializations.
00054   template<typename _CharT>
00055     struct __use_cache<__numpunct_cache<_CharT> >
00056     {
00057       const __numpunct_cache<_CharT>*
00058       operator() (const locale& __loc) const
00059       {
00060     const size_t __i = numpunct<_CharT>::id._M_id();
00061     const locale::facet** __caches = __loc._M_impl->_M_caches;
00062     if (!__caches[__i])
00063       {
00064         __numpunct_cache<_CharT>* __tmp = NULL;
00065         try
00066           {
00067         __tmp = new __numpunct_cache<_CharT>;
00068         __tmp->_M_cache(__loc);
00069           }
00070         catch(...)
00071           {
00072         delete __tmp;
00073         __throw_exception_again;
00074           }
00075         __loc._M_impl->_M_install_cache(__tmp, __i);
00076       }
00077     return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
00078       }
00079     };
00080 
00081   template<typename _CharT>
00082     void
00083     __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
00084     {
00085       _M_allocated = true;
00086 
00087       const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
00088 
00089       _M_grouping_size = __np.grouping().size();
00090       char* __grouping = new char[_M_grouping_size];
00091       __np.grouping().copy(__grouping, _M_grouping_size);
00092       _M_grouping = __grouping;
00093       _M_use_grouping = (_M_grouping_size
00094              && static_cast<signed char>(__np.grouping()[0]) > 0);
00095 
00096       _M_truename_size = __np.truename().size();
00097       _CharT* __truename = new _CharT[_M_truename_size];
00098       __np.truename().copy(__truename, _M_truename_size);
00099       _M_truename = __truename;
00100 
00101       _M_falsename_size = __np.falsename().size();
00102       _CharT* __falsename = new _CharT[_M_falsename_size];
00103       __np.falsename().copy(__falsename, _M_falsename_size);
00104       _M_falsename = __falsename;
00105 
00106       _M_decimal_point = __np.decimal_point();
00107       _M_thousands_sep = __np.thousands_sep();
00108 
00109       const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
00110       __ct.widen(__num_base::_S_atoms_out,
00111          __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
00112       __ct.widen(__num_base::_S_atoms_in,
00113          __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
00114     }
00115 
00116   // Used by both numeric and monetary facets.
00117   // Check to make sure that the __grouping_tmp string constructed in
00118   // money_get or num_get matches the canonical grouping for a given
00119   // locale.
00120   // __grouping_tmp is parsed L to R
00121   // 1,222,444 == __grouping_tmp of "\1\3\3"
00122   // __grouping is parsed R to L
00123   // 1,222,444 == __grouping of "\3" == "\3\3\3"
00124   bool
00125   __verify_grouping(const char* __grouping, size_t __grouping_size,
00126             const string& __grouping_tmp);
00127 
00128 _GLIBCXX_BEGIN_LDBL_NAMESPACE
00129 
00130   template<typename _CharT, typename _InIter>
00131     _InIter
00132     num_get<_CharT, _InIter>::
00133     _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
00134              ios_base::iostate& __err, string& __xtrc) const
00135     {
00136       typedef char_traits<_CharT>           __traits_type;
00137       typedef __numpunct_cache<_CharT>                  __cache_type;
00138       __use_cache<__cache_type> __uc;
00139       const locale& __loc = __io._M_getloc();
00140       const __cache_type* __lc = __uc(__loc);
00141       const _CharT* __lit = __lc->_M_atoms_in;
00142       char_type __c = char_type();
00143 
00144       // True if __beg becomes equal to __end.
00145       bool __testeof = __beg == __end;
00146 
00147       // First check for sign.
00148       if (!__testeof)
00149     {
00150       __c = *__beg;
00151       const bool __plus = __c == __lit[__num_base::_S_iplus];
00152       if ((__plus || __c == __lit[__num_base::_S_iminus])
00153           && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
00154           && !(__c == __lc->_M_decimal_point))
00155         {
00156           __xtrc += __plus ? '+' : '-';
00157           if (++__beg != __end)
00158         __c = *__beg;
00159           else
00160         __testeof = true;
00161         }
00162     }
00163 
00164       // Next, look for leading zeros.
00165       bool __found_mantissa = false;
00166       int __sep_pos = 0;
00167       while (!__testeof)
00168     {
00169       if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
00170           || __c == __lc->_M_decimal_point)
00171         break;
00172       else if (__c == __lit[__num_base::_S_izero])
00173         {
00174           if (!__found_mantissa)
00175         {
00176           __xtrc += '0';
00177           __found_mantissa = true;
00178         }
00179           ++__sep_pos;
00180 
00181           if (++__beg != __end)
00182         __c = *__beg;
00183           else
00184         __testeof = true;
00185         }
00186       else
00187         break;
00188     }
00189 
00190       // Only need acceptable digits for floating point numbers.
00191       bool __found_dec = false;
00192       bool __found_sci = false;
00193       string __found_grouping;
00194       if (__lc->_M_use_grouping)
00195     __found_grouping.reserve(32);
00196       const char_type* __lit_zero = __lit + __num_base::_S_izero;
00197 
00198       if (!__lc->_M_allocated)
00199     // "C" locale
00200     while (!__testeof)
00201       {
00202         const int __digit = _M_find(__lit_zero, 10, __c);
00203         if (__digit != -1)
00204           {
00205         __xtrc += '0' + __digit;
00206         __found_mantissa = true;
00207           }
00208         else if (__c == __lc->_M_decimal_point
00209              && !__found_dec && !__found_sci)
00210           {
00211         __xtrc += '.';
00212         __found_dec = true;
00213           }
00214         else if ((__c == __lit[__num_base::_S_ie] 
00215               || __c == __lit[__num_base::_S_iE])
00216              && !__found_sci && __found_mantissa)
00217           {
00218         // Scientific notation.
00219         __xtrc += 'e';
00220         __found_sci = true;
00221         
00222         // Remove optional plus or minus sign, if they exist.
00223         if (++__beg != __end)
00224           {
00225             __c = *__beg;
00226             const bool __plus = __c == __lit[__num_base::_S_iplus];
00227             if (__plus || __c == __lit[__num_base::_S_iminus])
00228               __xtrc += __plus ? '+' : '-';
00229             else
00230               continue;
00231           }
00232         else
00233           {
00234             __testeof = true;
00235             break;
00236           }
00237           }
00238         else
00239           break;
00240 
00241         if (++__beg != __end)
00242           __c = *__beg;
00243         else
00244           __testeof = true;
00245       }
00246       else
00247     while (!__testeof)
00248       {
00249         // According to 22.2.2.1.2, p8-9, first look for thousands_sep
00250         // and decimal_point.
00251         if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
00252           {
00253         if (!__found_dec && !__found_sci)
00254           {
00255             // NB: Thousands separator at the beginning of a string
00256             // is a no-no, as is two consecutive thousands separators.
00257             if (__sep_pos)
00258               {
00259             __found_grouping += static_cast<char>(__sep_pos);
00260             __sep_pos = 0;
00261               }
00262             else
00263               {
00264             // NB: __convert_to_v will not assign __v and will
00265             // set the failbit.
00266             __xtrc.clear();
00267             break;
00268               }
00269           }
00270         else
00271           break;
00272           }
00273         else if (__c == __lc->_M_decimal_point)
00274           {
00275         if (!__found_dec && !__found_sci)
00276           {
00277             // If no grouping chars are seen, no grouping check
00278             // is applied. Therefore __found_grouping is adjusted
00279             // only if decimal_point comes after some thousands_sep.
00280             if (__found_grouping.size())
00281               __found_grouping += static_cast<char>(__sep_pos);
00282             __xtrc += '.';
00283             __found_dec = true;
00284           }
00285         else
00286           break;
00287           }
00288         else
00289           {
00290         const char_type* __q =
00291           __traits_type::find(__lit_zero, 10, __c);
00292         if (__q)
00293           {
00294             __xtrc += '0' + (__q - __lit_zero);
00295             __found_mantissa = true;
00296             ++__sep_pos;
00297           }
00298         else if ((__c == __lit[__num_base::_S_ie] 
00299               || __c == __lit[__num_base::_S_iE])
00300              && !__found_sci && __found_mantissa)
00301           {
00302             // Scientific notation.
00303             if (__found_grouping.size() && !__found_dec)
00304               __found_grouping += static_cast<char>(__sep_pos);
00305             __xtrc += 'e';
00306             __found_sci = true;
00307             
00308             // Remove optional plus or minus sign, if they exist.
00309             if (++__beg != __end)
00310               {
00311             __c = *__beg;
00312             const bool __plus = __c == __lit[__num_base::_S_iplus];
00313             if ((__plus || __c == __lit[__num_base::_S_iminus])
00314                 && !(__lc->_M_use_grouping
00315                  && __c == __lc->_M_thousands_sep)
00316                 && !(__c == __lc->_M_decimal_point))
00317               __xtrc += __plus ? '+' : '-';
00318             else
00319               continue;
00320               }
00321             else
00322               {
00323             __testeof = true;
00324             break;
00325               }
00326           }
00327         else
00328           break;
00329           }
00330         
00331         if (++__beg != __end)
00332           __c = *__beg;
00333         else
00334           __testeof = true;
00335       }
00336 
00337       // Digit grouping is checked. If grouping and found_grouping don't
00338       // match, then get very very upset, and set failbit.
00339       if (__found_grouping.size())
00340         {
00341           // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
00342       if (!__found_dec && !__found_sci)
00343         __found_grouping += static_cast<char>(__sep_pos);
00344 
00345           if (!std::__verify_grouping(__lc->_M_grouping, 
00346                       __lc->_M_grouping_size,
00347                       __found_grouping))
00348         __err |= ios_base::failbit;
00349         }
00350 
00351       // Finish up.
00352       if (__testeof)
00353         __err |= ios_base::eofbit;
00354       return __beg;
00355     }
00356 
00357   template<typename _CharT, typename _InIter>
00358     template<typename _ValueT>
00359       _InIter
00360       num_get<_CharT, _InIter>::
00361       _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
00362              ios_base::iostate& __err, _ValueT& __v) const
00363       {
00364         typedef char_traits<_CharT>              __traits_type;
00365     using __gnu_cxx::__add_unsigned;
00366     typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
00367     typedef __numpunct_cache<_CharT>                     __cache_type;
00368     __use_cache<__cache_type> __uc;
00369     const locale& __loc = __io._M_getloc();
00370     const __cache_type* __lc = __uc(__loc);
00371     const _CharT* __lit = __lc->_M_atoms_in;
00372     char_type __c = char_type();
00373 
00374     // NB: Iff __basefield == 0, __base can change based on contents.
00375     const ios_base::fmtflags __basefield = __io.flags()
00376                                            & ios_base::basefield;
00377     const bool __oct = __basefield == ios_base::oct;
00378     int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
00379 
00380     // True if __beg becomes equal to __end.
00381     bool __testeof = __beg == __end;
00382 
00383     // First check for sign.
00384     bool __negative = false;
00385     if (!__testeof)
00386       {
00387         __c = *__beg;
00388         if (__gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
00389           __negative = __c == __lit[__num_base::_S_iminus];
00390         if ((__negative || __c == __lit[__num_base::_S_iplus])
00391         && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
00392         && !(__c == __lc->_M_decimal_point))
00393           {
00394         if (++__beg != __end)
00395           __c = *__beg;
00396         else
00397           __testeof = true;
00398           }
00399       }
00400 
00401     // Next, look for leading zeros and check required digits
00402     // for base formats.
00403     bool __found_zero = false;
00404     int __sep_pos = 0;
00405     while (!__testeof)
00406       {
00407         if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
00408         || __c == __lc->_M_decimal_point)
00409           break;
00410         else if (__c == __lit[__num_base::_S_izero] 
00411              && (!__found_zero || __base == 10))
00412           {
00413         __found_zero = true;
00414         ++__sep_pos;
00415         if (__basefield == 0)
00416           __base = 8;
00417         if (__base == 8)
00418           __sep_pos = 0;
00419           }
00420         else if (__found_zero
00421              && (__c == __lit[__num_base::_S_ix]
00422              || __c == __lit[__num_base::_S_iX]))
00423           {
00424         if (__basefield == 0)
00425           __base = 16;
00426         if (__base == 16)
00427           {
00428             __found_zero = false;
00429             __sep_pos = 0;
00430           }
00431         else
00432           break;
00433           }
00434         else
00435           break;
00436 
00437         if (++__beg != __end)
00438           {
00439         __c = *__beg;
00440         if (!__found_zero)
00441           break;
00442           }
00443         else
00444           __testeof = true;
00445       }
00446     
00447     // At this point, base is determined. If not hex, only allow
00448     // base digits as valid input.
00449     const size_t __len = (__base == 16 ? __num_base::_S_iend
00450                   - __num_base::_S_izero : __base);
00451 
00452     // Extract.
00453     string __found_grouping;
00454     if (__lc->_M_use_grouping)
00455       __found_grouping.reserve(32);
00456     bool __testfail = false;
00457     const __unsigned_type __max = __negative
00458       ? -__gnu_cxx::__numeric_traits<_ValueT>::__min
00459       : __gnu_cxx::__numeric_traits<_ValueT>::__max;
00460     const __unsigned_type __smax = __max / __base;
00461     __unsigned_type __result = 0;
00462     int __digit = 0;
00463     const char_type* __lit_zero = __lit + __num_base::_S_izero;
00464 
00465     if (!__lc->_M_allocated)
00466       // "C" locale
00467       while (!__testeof)
00468         {
00469           __digit = _M_find(__lit_zero, __len, __c);
00470           if (__digit == -1)
00471         break;
00472           
00473           if (__result > __smax)
00474         __testfail = true;
00475           else
00476         {
00477           __result *= __base;
00478           __testfail |= __result > __max - __digit;
00479           __result += __digit;
00480           ++__sep_pos;
00481         }
00482           
00483           if (++__beg != __end)
00484         __c = *__beg;
00485           else
00486         __testeof = true;
00487         }
00488     else
00489       while (!__testeof)
00490         {
00491           // According to 22.2.2.1.2, p8-9, first look for thousands_sep
00492           // and decimal_point.
00493           if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
00494         {
00495           // NB: Thousands separator at the beginning of a string
00496           // is a no-no, as is two consecutive thousands separators.
00497           if (__sep_pos)
00498             {
00499               __found_grouping += static_cast<char>(__sep_pos);
00500               __sep_pos = 0;
00501             }
00502           else
00503             {
00504               __testfail = true;
00505               break;
00506             }
00507         }
00508           else if (__c == __lc->_M_decimal_point)
00509         break;
00510           else
00511         {
00512           const char_type* __q =
00513             __traits_type::find(__lit_zero, __len, __c);
00514           if (!__q)
00515             break;
00516           
00517           __digit = __q - __lit_zero;
00518           if (__digit > 15)
00519             __digit -= 6;
00520           if (__result > __smax)
00521             __testfail = true;
00522           else
00523             {
00524               __result *= __base;
00525               __testfail |= __result > __max - __digit;
00526               __result += __digit;
00527               ++__sep_pos;
00528             }
00529         }
00530           
00531           if (++__beg != __end)
00532         __c = *__beg;
00533           else
00534         __testeof = true;
00535         }
00536     
00537     // Digit grouping is checked. If grouping and found_grouping don't
00538     // match, then get very very upset, and set failbit.
00539     if (__found_grouping.size())
00540       {
00541         // Add the ending grouping.
00542         __found_grouping += static_cast<char>(__sep_pos);
00543 
00544         if (!std::__verify_grouping(__lc->_M_grouping,
00545                     __lc->_M_grouping_size,
00546                     __found_grouping))
00547           __err |= ios_base::failbit;
00548       }
00549 
00550     if (!__testfail && (__sep_pos || __found_zero 
00551                 || __found_grouping.size()))
00552       __v = __negative ? -__result : __result;
00553     else
00554       __err |= ios_base::failbit;
00555 
00556     if (__testeof)
00557       __err |= ios_base::eofbit;
00558     return __beg;
00559       }
00560 
00561   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00562   // 17.  Bad bool parsing
00563   template<typename _CharT, typename _InIter>
00564     _InIter
00565     num_get<_CharT, _InIter>::
00566     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00567            ios_base::iostate& __err, bool& __v) const
00568     {
00569       if (!(__io.flags() & ios_base::boolalpha))
00570         {
00571       // Parse bool values as long.
00572           // NB: We can't just call do_get(long) here, as it might
00573           // refer to a derived class.
00574       long __l = -1;
00575           __beg = _M_extract_int(__beg, __end, __io, __err, __l);
00576       if (__l == 0 || __l == 1)
00577         __v = bool(__l);
00578       else
00579             __err |= ios_base::failbit;
00580         }
00581       else
00582         {
00583       // Parse bool values as alphanumeric.
00584       typedef __numpunct_cache<_CharT>              __cache_type;
00585       __use_cache<__cache_type> __uc;
00586       const locale& __loc = __io._M_getloc();
00587       const __cache_type* __lc = __uc(__loc);
00588 
00589       bool __testf = true;
00590       bool __testt = true;
00591       size_t __n;
00592       bool __testeof = __beg == __end;
00593           for (__n = 0; !__testeof; ++__n)
00594             {
00595           const char_type __c = *__beg;
00596 
00597           if (__testf)
00598             {
00599           if (__n < __lc->_M_falsename_size)
00600             __testf = __c == __lc->_M_falsename[__n];
00601           else
00602             break;
00603         }
00604 
00605           if (__testt)
00606             {
00607           if (__n < __lc->_M_truename_size)
00608             __testt = __c == __lc->_M_truename[__n];
00609           else
00610             break;
00611         }
00612 
00613           if (!__testf && !__testt)
00614         break;
00615           
00616           if (++__beg == __end)
00617         __testeof = true;
00618             }
00619       if (__testf && __n == __lc->_M_falsename_size)
00620         __v = false;
00621       else if (__testt && __n == __lc->_M_truename_size)
00622         __v = true;
00623       else
00624         __err |= ios_base::failbit;
00625 
00626           if (__testeof)
00627             __err |= ios_base::eofbit;
00628         }
00629       return __beg;
00630     }
00631 
00632   template<typename _CharT, typename _InIter>
00633     _InIter
00634     num_get<_CharT, _InIter>::
00635     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00636            ios_base::iostate& __err, long& __v) const
00637     { return _M_extract_int(__beg, __end, __io, __err, __v); }
00638 
00639   template<typename _CharT, typename _InIter>
00640     _InIter
00641     num_get<_CharT, _InIter>::
00642     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00643            ios_base::iostate& __err, unsigned short& __v) const
00644     { return _M_extract_int(__beg, __end, __io, __err, __v); }
00645 
00646   template<typename _CharT, typename _InIter>
00647     _InIter
00648     num_get<_CharT, _InIter>::
00649     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00650            ios_base::iostate& __err, unsigned int& __v) const
00651     { return _M_extract_int(__beg, __end, __io, __err, __v); }
00652 
00653   template<typename _CharT, typename _InIter>
00654     _InIter
00655     num_get<_CharT, _InIter>::
00656     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00657            ios_base::iostate& __err, unsigned long& __v) const
00658     { return _M_extract_int(__beg, __end, __io, __err, __v); }
00659 
00660 #ifdef _GLIBCXX_USE_LONG_LONG
00661   template<typename _CharT, typename _InIter>
00662     _InIter
00663     num_get<_CharT, _InIter>::
00664     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00665            ios_base::iostate& __err, long long& __v) const
00666     { return _M_extract_int(__beg, __end, __io, __err, __v); }
00667 
00668   template<typename _CharT, typename _InIter>
00669     _InIter
00670     num_get<_CharT, _InIter>::
00671     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00672            ios_base::iostate& __err, unsigned long long& __v) const
00673     { return _M_extract_int(__beg, __end, __io, __err, __v); }
00674 #endif
00675 
00676   template<typename _CharT, typename _InIter>
00677     _InIter
00678     num_get<_CharT, _InIter>::
00679     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00680        ios_base::iostate& __err, float& __v) const
00681     {
00682       string __xtrc;
00683       __xtrc.reserve(32);
00684       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00685       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
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, double& __v) const
00694     {
00695       string __xtrc;
00696       __xtrc.reserve(32);
00697       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00698       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
00699       return __beg;
00700     }
00701 
00702 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
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, double& __v) const
00708     {
00709       string __xtrc;
00710       __xtrc.reserve(32);
00711       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00712       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
00713       return __beg;
00714     }
00715 #endif
00716 
00717   template<typename _CharT, typename _InIter>
00718     _InIter
00719     num_get<_CharT, _InIter>::
00720     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00721            ios_base::iostate& __err, long double& __v) const
00722     {
00723       string __xtrc;
00724       __xtrc.reserve(32);
00725       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
00726       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
00727       return __beg;
00728     }
00729 
00730   template<typename _CharT, typename _InIter>
00731     _InIter
00732     num_get<_CharT, _InIter>::
00733     do_get(iter_type __beg, iter_type __end, ios_base& __io,
00734            ios_base::iostate& __err, void*& __v) const
00735     {
00736       // Prepare for hex formatted input.
00737       typedef ios_base::fmtflags        fmtflags;
00738       const fmtflags __fmt = __io.flags();
00739       __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
00740 
00741       typedef __gnu_cxx::__conditional_type<(sizeof(void*)
00742                          <= sizeof(unsigned long)),
00743     unsigned long, unsigned long long>::__type _UIntPtrType;       
00744 
00745       _UIntPtrType __ul;
00746       __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
00747 
00748       // Reset from hex formatted input.
00749       __io.flags(__fmt);
00750 
00751       if (!(__err & ios_base::failbit))
00752     __v = reinterpret_cast<void*>(__ul);
00753       return __beg;
00754     }
00755 
00756   // For use by integer and floating-point types after they have been
00757   // converted into a char_type string.
00758   template<typename _CharT, typename _OutIter>
00759     void
00760     num_put<_CharT, _OutIter>::
00761     _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
00762        _CharT* __new, const _CharT* __cs, int& __len) const
00763     {
00764       // [22.2.2.2.2] Stage 3.
00765       // If necessary, pad.
00766       __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new,
00767                           __cs, __w, __len);
00768       __len = static_cast<int>(__w);
00769     }
00770 
00771 _GLIBCXX_END_LDBL_NAMESPACE
00772 
00773   template<typename _CharT, typename _ValueT>
00774     int
00775     __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
00776           ios_base::fmtflags __flags, bool __dec)
00777     {
00778       _CharT* __buf = __bufend;
00779       if (__builtin_expect(__dec, true))
00780     {
00781       // Decimal.
00782       do
00783         {
00784           *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
00785           __v /= 10;
00786         }
00787       while (__v != 0);
00788     }
00789       else if ((__flags & ios_base::basefield) == ios_base::oct)
00790     {
00791       // Octal.
00792       do
00793         {
00794           *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
00795           __v >>= 3;
00796         }
00797       while (__v != 0);
00798     }
00799       else
00800     {
00801       // Hex.
00802       const bool __uppercase = __flags & ios_base::uppercase;
00803       const int __case_offset = __uppercase ? __num_base::_S_oudigits
00804                                             : __num_base::_S_odigits;
00805       do
00806         {
00807           *--__buf = __lit[(__v & 0xf) + __case_offset];
00808           __v >>= 4;
00809         }
00810       while (__v != 0);
00811     }
00812       return __bufend - __buf;
00813     }
00814 
00815 _GLIBCXX_BEGIN_LDBL_NAMESPACE
00816 
00817   template<typename _CharT, typename _OutIter>
00818     void
00819     num_put<_CharT, _OutIter>::
00820     _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
00821          ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
00822     {
00823       _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
00824                     __grouping_size, __cs, __cs + __len);
00825       __len = __p - __new;
00826     }
00827   
00828   template<typename _CharT, typename _OutIter>
00829     template<typename _ValueT>
00830       _OutIter
00831       num_put<_CharT, _OutIter>::
00832       _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
00833             _ValueT __v) const
00834       {
00835     using __gnu_cxx::__add_unsigned;
00836     typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
00837     typedef __numpunct_cache<_CharT>                 __cache_type;
00838     __use_cache<__cache_type> __uc;
00839     const locale& __loc = __io._M_getloc();
00840     const __cache_type* __lc = __uc(__loc);
00841     const _CharT* __lit = __lc->_M_atoms_out;
00842     const ios_base::fmtflags __flags = __io.flags();
00843 
00844     // Long enough to hold hex, dec, and octal representations.
00845     const int __ilen = 5 * sizeof(_ValueT);
00846     _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
00847                                  * __ilen));
00848 
00849     // [22.2.2.2.2] Stage 1, numeric conversion to character.
00850     // Result is returned right-justified in the buffer.
00851     const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
00852     const bool __dec = (__basefield != ios_base::oct
00853                 && __basefield != ios_base::hex);
00854     const __unsigned_type __u = ((__v > 0 || !__dec)
00855                      ? __unsigned_type(__v)
00856                      : -__unsigned_type(__v));
00857     int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec);
00858     __cs += __ilen - __len;
00859 
00860     // Add grouping, if necessary.
00861     if (__lc->_M_use_grouping)
00862       {
00863         // Grouping can add (almost) as many separators as the number
00864         // of digits + space is reserved for numeric base or sign.
00865         _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
00866                                   * (__len + 1)
00867                                   * 2));
00868         _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
00869              __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
00870         __cs = __cs2 + 2;
00871       }
00872 
00873     // Complete Stage 1, prepend numeric base or sign.
00874     if (__builtin_expect(__dec, true))
00875       {
00876         // Decimal.
00877         if (__v >= 0)
00878           {
00879         if (bool(__flags & ios_base::showpos)
00880             && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
00881           *--__cs = __lit[__num_base::_S_oplus], ++__len;
00882           }
00883         else
00884           *--__cs = __lit[__num_base::_S_ominus], ++__len;
00885       }
00886     else if (bool(__flags & ios_base::showbase) && __v)
00887       {
00888         if (__basefield == ios_base::oct)
00889           *--__cs = __lit[__num_base::_S_odigits], ++__len;
00890         else
00891           {
00892         // 'x' or 'X'
00893         const bool __uppercase = __flags & ios_base::uppercase;
00894         *--__cs = __lit[__num_base::_S_ox + __uppercase];
00895         // '0'
00896         *--__cs = __lit[__num_base::_S_odigits];
00897         __len += 2;
00898           }
00899       }
00900 
00901     // Pad.
00902     const streamsize __w = __io.width();
00903     if (__w > static_cast<streamsize>(__len))
00904       {
00905         _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
00906                                   * __w));
00907         _M_pad(__fill, __w, __io, __cs3, __cs, __len);
00908         __cs = __cs3;
00909       }
00910     __io.width(0);
00911 
00912     // [22.2.2.2.2] Stage 4.
00913     // Write resulting, fully-formatted string to output iterator.
00914     return std::__write(__s, __cs, __len);
00915       }
00916 
00917   template<typename _CharT, typename _OutIter>
00918     void
00919     num_put<_CharT, _OutIter>::
00920     _M_group_float(const char* __grouping, size_t __grouping_size,
00921            _CharT __sep, const _CharT* __p, _CharT* __new,
00922            _CharT* __cs, int& __len) const
00923     {
00924       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00925       // 282. What types does numpunct grouping refer to?
00926       // Add grouping, if necessary.
00927       const int __declen = __p ? __p - __cs : __len;
00928       _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
00929                      __grouping_size,
00930                      __cs, __cs + __declen);
00931 
00932       // Tack on decimal part.
00933       int __newlen = __p2 - __new;
00934       if (__p)
00935     {
00936       char_traits<_CharT>::copy(__p2, __p, __len - __declen);
00937       __newlen += __len - __declen;
00938     }
00939       __len = __newlen;
00940     }
00941 
00942   // The following code uses vsnprintf (or vsprintf(), when
00943   // _GLIBCXX_USE_C99 is not defined) to convert floating point values
00944   // for insertion into a stream.  An optimization would be to replace
00945   // them with code that works directly on a wide buffer and then use
00946   // __pad to do the padding.  It would be good to replace them anyway
00947   // to gain back the efficiency that C++ provides by knowing up front
00948   // the type of the values to insert.  Also, sprintf is dangerous
00949   // since may lead to accidental buffer overruns.  This
00950   // implementation follows the C++ standard fairly directly as
00951   // outlined in 22.2.2.2 [lib.locale.num.put]
00952   template<typename _CharT, typename _OutIter>
00953     template<typename _ValueT>
00954       _OutIter
00955       num_put<_CharT, _OutIter>::
00956       _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
00957                _ValueT __v) const
00958       {
00959     typedef __numpunct_cache<_CharT>                __cache_type;
00960     __use_cache<__cache_type> __uc;
00961     const locale& __loc = __io._M_getloc();
00962     const __cache_type* __lc = __uc(__loc);
00963 
00964     // Use default precision if out of range.
00965     const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision();
00966 
00967     const int __max_digits =
00968       __gnu_cxx::__numeric_traits<_ValueT>::__digits10;
00969 
00970     // [22.2.2.2.2] Stage 1, numeric conversion to character.
00971     int __len;
00972     // Long enough for the max format spec.
00973     char __fbuf[16];
00974     __num_base::_S_format_float(__io, __fbuf, __mod);
00975 
00976 #ifdef _GLIBCXX_USE_C99
00977     // First try a buffer perhaps big enough (most probably sufficient
00978     // for non-ios_base::fixed outputs)
00979     int __cs_size = __max_digits * 3;
00980     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
00981     __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
00982                       __fbuf, __prec, __v);
00983 
00984     // If the buffer was not large enough, try again with the correct size.
00985     if (__len >= __cs_size)
00986       {
00987         __cs_size = __len + 1;
00988         __cs = static_cast<char*>(__builtin_alloca(__cs_size));
00989         __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
00990                       __fbuf, __prec, __v);
00991       }
00992 #else
00993     // Consider the possibility of long ios_base::fixed outputs
00994     const bool __fixed = __io.flags() & ios_base::fixed;
00995     const int __max_exp =
00996       __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10;
00997 
00998     // The size of the output string is computed as follows.
00999     // ios_base::fixed outputs may need up to __max_exp + 1 chars
01000     // for the integer part + __prec chars for the fractional part
01001     // + 3 chars for sign, decimal point, '\0'. On the other hand,
01002     // for non-fixed outputs __max_digits * 2 + __prec chars are
01003     // largely sufficient.
01004     const int __cs_size = __fixed ? __max_exp + __prec + 4
01005                                   : __max_digits * 2 + __prec;
01006     char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
01007     __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, 
01008                       __prec, __v);
01009 #endif
01010 
01011     // [22.2.2.2.2] Stage 2, convert to char_type, using correct
01012     // numpunct.decimal_point() values for '.' and adding grouping.
01013     const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
01014     
01015     _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
01016                                  * __len));
01017     __ctype.widen(__cs, __cs + __len, __ws);
01018     
01019     // Replace decimal point.
01020     _CharT* __wp = 0;
01021     const char* __p = char_traits<char>::find(__cs, __len, '.');
01022     if (__p)
01023       {
01024         __wp = __ws + (__p - __cs);
01025         *__wp = __lc->_M_decimal_point;
01026       }
01027     
01028     // Add grouping, if necessary.
01029     // N.B. Make sure to not group things like 2e20, i.e., no decimal
01030     // point, scientific notation.
01031     if (__lc->_M_use_grouping
01032         && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
01033                       && __cs[1] >= '0' && __cs[2] >= '0')))
01034       {
01035         // Grouping can add (almost) as many separators as the
01036         // number of digits, but no more.
01037         _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
01038                                   * __len * 2));
01039         
01040         streamsize __off = 0;
01041         if (__cs[0] == '-' || __cs[0] == '+')
01042           {
01043         __off = 1;
01044         __ws2[0] = __ws[0];
01045         __len -= 1;
01046           }
01047         
01048         _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
01049                __lc->_M_thousands_sep, __wp, __ws2 + __off,
01050                __ws + __off, __len);
01051         __len += __off;
01052         
01053         __ws = __ws2;
01054       }
01055 
01056     // Pad.
01057     const streamsize __w = __io.width();
01058     if (__w > static_cast<streamsize>(__len))
01059       {
01060         _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
01061                                   * __w));
01062         _M_pad(__fill, __w, __io, __ws3, __ws, __len);
01063         __ws = __ws3;
01064       }
01065     __io.width(0);
01066     
01067     // [22.2.2.2.2] Stage 4.
01068     // Write resulting, fully-formatted string to output iterator.
01069     return std::__write(__s, __ws, __len);
01070       }
01071   
01072   template<typename _CharT, typename _OutIter>
01073     _OutIter
01074     num_put<_CharT, _OutIter>::
01075     do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
01076     {
01077       const ios_base::fmtflags __flags = __io.flags();
01078       if ((__flags & ios_base::boolalpha) == 0)
01079         {
01080           const long __l = __v;
01081           __s = _M_insert_int(__s, __io, __fill, __l);
01082         }
01083       else
01084         {
01085       typedef __numpunct_cache<_CharT>              __cache_type;
01086       __use_cache<__cache_type> __uc;
01087       const locale& __loc = __io._M_getloc();
01088       const __cache_type* __lc = __uc(__loc);
01089 
01090       const _CharT* __name = __v ? __lc->_M_truename
01091                                  : __lc->_M_falsename;
01092       int __len = __v ? __lc->_M_truename_size
01093                       : __lc->_M_falsename_size;
01094 
01095       const streamsize __w = __io.width();
01096       if (__w > static_cast<streamsize>(__len))
01097         {
01098           _CharT* __cs
01099         = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
01100                             * __w));
01101           _M_pad(__fill, __w, __io, __cs, __name, __len);
01102           __name = __cs;
01103         }
01104       __io.width(0);
01105       __s = std::__write(__s, __name, __len);
01106     }
01107       return __s;
01108     }
01109 
01110   template<typename _CharT, typename _OutIter>
01111     _OutIter
01112     num_put<_CharT, _OutIter>::
01113     do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
01114     { return _M_insert_int(__s, __io, __fill, __v); }
01115 
01116   template<typename _CharT, typename _OutIter>
01117     _OutIter
01118     num_put<_CharT, _OutIter>::
01119     do_put(iter_type __s, ios_base& __io, char_type __fill,
01120            unsigned long __v) const
01121     { return _M_insert_int(__s, __io, __fill, __v); }
01122 
01123 #ifdef _GLIBCXX_USE_LONG_LONG
01124   template<typename _CharT, typename _OutIter>
01125     _OutIter
01126     num_put<_CharT, _OutIter>::
01127     do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const
01128     { return _M_insert_int(__s, __io, __fill, __v); }
01129 
01130   template<typename _CharT, typename _OutIter>
01131     _OutIter
01132     num_put<_CharT, _OutIter>::
01133     do_put(iter_type __s, ios_base& __io, char_type __fill,
01134            unsigned long long __v) const
01135     { return _M_insert_int(__s, __io, __fill, __v); }
01136 #endif
01137 
01138   template<typename _CharT, typename _OutIter>
01139     _OutIter
01140     num_put<_CharT, _OutIter>::
01141     do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
01142     { return _M_insert_float(__s, __io, __fill, char(), __v); }
01143 
01144 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
01145   template<typename _CharT, typename _OutIter>
01146     _OutIter
01147     num_put<_CharT, _OutIter>::
01148     __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
01149     { return _M_insert_float(__s, __io, __fill, char(), __v); }
01150 #endif
01151 
01152   template<typename _CharT, typename _OutIter>
01153     _OutIter
01154     num_put<_CharT, _OutIter>::
01155     do_put(iter_type __s, ios_base& __io, char_type __fill,
01156        long double __v) const
01157     { return _M_insert_float(__s, __io, __fill, 'L', __v); }
01158 
01159   template<typename _CharT, typename _OutIter>
01160     _OutIter
01161     num_put<_CharT, _OutIter>::
01162     do_put(iter_type __s, ios_base& __io, char_type __fill,
01163            const void* __v) const
01164     {
01165       const ios_base::fmtflags __flags = __io.flags();
01166       const ios_base::fmtflags __fmt = ~(ios_base::basefield
01167                      | ios_base::uppercase
01168                      | ios_base::internal);
01169       __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
01170 
01171       typedef __gnu_cxx::__conditional_type<(sizeof(const void*)
01172                          <= sizeof(unsigned long)),
01173     unsigned long, unsigned long long>::__type _UIntPtrType;       
01174 
01175       __s = _M_insert_int(__s, __io, __fill,
01176               reinterpret_cast<_UIntPtrType>(__v));
01177       __io.flags(__flags);
01178       return __s;
01179     }
01180 
01181 _GLIBCXX_END_LDBL_NAMESPACE
01182 
01183   // Construct correctly padded string, as per 22.2.2.2.2
01184   // Assumes
01185   // __newlen > __oldlen
01186   // __news is allocated for __newlen size
01187 
01188   // NB: Of the two parameters, _CharT can be deduced from the
01189   // function arguments. The other (_Traits) has to be explicitly specified.
01190   template<typename _CharT, typename _Traits>
01191     void
01192     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
01193                    _CharT* __news, const _CharT* __olds,
01194                    const streamsize __newlen,
01195                    const streamsize __oldlen)
01196     {
01197       const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
01198       const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
01199 
01200       // Padding last.
01201       if (__adjust == ios_base::left)
01202     {
01203       _Traits::copy(__news, __olds, __oldlen);
01204       _Traits::assign(__news + __oldlen, __plen, __fill);
01205       return;
01206     }
01207 
01208       size_t __mod = 0;
01209       if (__adjust == ios_base::internal)
01210     {
01211       // Pad after the sign, if there is one.
01212       // Pad after 0[xX], if there is one.
01213       // Who came up with these rules, anyway? Jeeze.
01214           const locale& __loc = __io._M_getloc();
01215       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
01216 
01217       if (__ctype.widen('-') == __olds[0]
01218           || __ctype.widen('+') == __olds[0])
01219         {
01220           __news[0] = __olds[0];
01221           __mod = 1;
01222           ++__news;
01223         }
01224       else if (__ctype.widen('0') == __olds[0]
01225            && __oldlen > 1
01226            && (__ctype.widen('x') == __olds[1]
01227                || __ctype.widen('X') == __olds[1]))
01228         {
01229           __news[0] = __olds[0];
01230           __news[1] = __olds[1];
01231           __mod = 2;
01232           __news += 2;
01233         }
01234       // else Padding first.
01235     }
01236       _Traits::assign(__news, __plen, __fill);
01237       _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod);
01238     }
01239 
01240   template<typename _CharT>
01241     _CharT*
01242     __add_grouping(_CharT* __s, _CharT __sep,
01243            const char* __gbeg, size_t __gsize,
01244            const _CharT* __first, const _CharT* __last)
01245     {
01246       size_t __idx = 0;
01247       size_t __ctr = 0;
01248 
01249       while (__last - __first > __gbeg[__idx]
01250          && static_cast<signed char>(__gbeg[__idx]) > 0)
01251     {
01252       __last -= __gbeg[__idx];
01253       __idx < __gsize - 1 ? ++__idx : ++__ctr;
01254     }
01255 
01256       while (__first != __last)
01257     *__s++ = *__first++;
01258 
01259       while (__ctr--)
01260     {
01261       *__s++ = __sep;     
01262       for (char __i = __gbeg[__idx]; __i > 0; --__i)
01263         *__s++ = *__first++;
01264     }
01265 
01266       while (__idx--)
01267     {
01268       *__s++ = __sep;     
01269       for (char __i = __gbeg[__idx]; __i > 0; --__i)
01270         *__s++ = *__first++;
01271     }
01272 
01273       return __s;
01274     }
01275 
01276   // Inhibit implicit instantiations for required instantiations,
01277   // which are defined via explicit instantiations elsewhere.
01278   // NB: This syntax is a GNU extension.
01279 #if _GLIBCXX_EXTERN_TEMPLATE
01280   extern template class numpunct<char>;
01281   extern template class numpunct_byname<char>;
01282   extern template class _GLIBCXX_LDBL_NAMESPACE num_get<char>;
01283   extern template class _GLIBCXX_LDBL_NAMESPACE num_put<char>;
01284   extern template class ctype_byname<char>;
01285 
01286   extern template
01287     const numpunct<char>&
01288     use_facet<numpunct<char> >(const locale&);
01289 
01290   extern template
01291     const num_put<char>&
01292     use_facet<num_put<char> >(const locale&);
01293 
01294   extern template
01295     const num_get<char>&
01296     use_facet<num_get<char> >(const locale&);
01297 
01298   extern template
01299     bool
01300     has_facet<ctype<char> >(const locale&);
01301 
01302   extern template
01303     bool
01304     has_facet<numpunct<char> >(const locale&);
01305 
01306   extern template
01307     bool
01308     has_facet<num_put<char> >(const locale&);
01309 
01310   extern template
01311     bool
01312     has_facet<num_get<char> >(const locale&);
01313 
01314 #ifdef _GLIBCXX_USE_WCHAR_T
01315   extern template class numpunct<wchar_t>;
01316   extern template class numpunct_byname<wchar_t>;
01317   extern template class _GLIBCXX_LDBL_NAMESPACE num_get<wchar_t>;
01318   extern template class _GLIBCXX_LDBL_NAMESPACE num_put<wchar_t>;
01319   extern template class ctype_byname<wchar_t>;
01320 
01321   extern template
01322     const numpunct<wchar_t>&
01323     use_facet<numpunct<wchar_t> >(const locale&);
01324 
01325   extern template
01326     const num_put<wchar_t>&
01327     use_facet<num_put<wchar_t> >(const locale&);
01328 
01329   extern template
01330     const num_get<wchar_t>&
01331     use_facet<num_get<wchar_t> >(const locale&);
01332 
01333  extern template
01334     bool
01335     has_facet<ctype<wchar_t> >(const locale&);
01336 
01337   extern template
01338     bool
01339     has_facet<numpunct<wchar_t> >(const locale&);
01340 
01341   extern template
01342     bool
01343     has_facet<num_put<wchar_t> >(const locale&);
01344 
01345   extern template
01346     bool
01347     has_facet<num_get<wchar_t> >(const locale&);
01348 #endif
01349 #endif
01350 
01351 _GLIBCXX_END_NAMESPACE
01352 
01353 #endif

Generated on Sat Oct 25 05:09:04 2008 for libstdc++ by  doxygen 1.5.6