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

Generated on Thu Jul 23 21:16:09 2009 for libstdc++ by  doxygen 1.5.8