# locale_facets_nonio.tcc

Go to the documentation of this file.

    00001 // Locale support -*- C++ -*-
    00002
    00003 // Copyright (C) 2007 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 2, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file locale_facets_nonio.tcc
    00031  *  This is an internal header file, included by other library headers.
    00032  *  You should not attempt to use it directly.
    00033  */
    00034
    00035 #ifndef _LOCALE_FACETS_NONIO_TCC
    00036 #define _LOCALE_FACETS_NONIO_TCC 1
    00037
    00038 #pragma GCC system_header
    00039
    00040 _GLIBCXX_BEGIN_NAMESPACE(std)
    00041
    00042   template<typename _CharT, bool _Intl>
    00043     struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
    00044     {
    00045       const __moneypunct_cache<_CharT, _Intl>*
    00046       operator() (const locale& __loc) const
    00047       {
    00048     const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
    00049     const locale::facet** __caches = __loc._M_impl->_M_caches;
    00050     if (!__caches[__i])
    00051       {
    00052         __moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
    00053         try
    00054           {
    00055         __tmp = new __moneypunct_cache<_CharT, _Intl>;
    00056         __tmp->_M_cache(__loc);
    00057           }
    00058         catch(...)
    00059           {
    00060         delete __tmp;
    00061         __throw_exception_again;
    00062           }
    00063         __loc._M_impl->_M_install_cache(__tmp, __i);
    00064       }
    00065     return static_cast<
    00066       const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
    00067       }
    00068     };
    00069
    00070   template<typename _CharT, bool _Intl>
    00071     void
    00072     __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
    00073     {
    00074       _M_allocated = true;
    00075
    00076       const moneypunct<_CharT, _Intl>& __mp =
    00077     use_facet<moneypunct<_CharT, _Intl> >(__loc);
    00078
    00079       _M_grouping_size = __mp.grouping().size();
    00080       char* __grouping = new char[_M_grouping_size];
    00081       __mp.grouping().copy(__grouping, _M_grouping_size);
    00082       _M_grouping = __grouping;
    00083       _M_use_grouping = (_M_grouping_size
    00084              && static_cast<signed char>(__mp.grouping()[0]) > 0);
    00085
    00086       _M_decimal_point = __mp.decimal_point();
    00087       _M_thousands_sep = __mp.thousands_sep();
    00088       _M_frac_digits = __mp.frac_digits();
    00089
    00090       _M_curr_symbol_size = __mp.curr_symbol().size();
    00091       _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
    00092       __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
    00093       _M_curr_symbol = __curr_symbol;
    00094
    00095       _M_positive_sign_size = __mp.positive_sign().size();
    00096       _CharT* __positive_sign = new _CharT[_M_positive_sign_size];
    00097       __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
    00098       _M_positive_sign = __positive_sign;
    00099
    00100       _M_negative_sign_size = __mp.negative_sign().size();
    00101       _CharT* __negative_sign = new _CharT[_M_negative_sign_size];
    00102       __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
    00103       _M_negative_sign = __negative_sign;
    00104
    00105       _M_pos_format = __mp.pos_format();
    00106       _M_neg_format = __mp.neg_format();
    00107
    00108       const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
    00109       __ct.widen(money_base::_S_atoms,
    00110          money_base::_S_atoms + money_base::_S_end, _M_atoms);
    00111     }
    00112
    00113 _GLIBCXX_BEGIN_LDBL_NAMESPACE
    00114
    00115   template<typename _CharT, typename _InIter>
    00116     template<bool _Intl>
    00117       _InIter
    00118       money_get<_CharT, _InIter>::
    00119       _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
    00120          ios_base::iostate& __err, string& __units) const
    00121       {
    00122     typedef char_traits<_CharT>           __traits_type;
    00123     typedef typename string_type::size_type           size_type;
    00124     typedef money_base::part              part;
    00125     typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
    00126
    00127     const locale& __loc = __io._M_getloc();
    00128     const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00129
    00130     __use_cache<__cache_type> __uc;
    00131     const __cache_type* __lc = __uc(__loc);
    00132     const char_type* __lit = __lc->_M_atoms;
    00133
    00134     // Deduced sign.
    00135     bool __negative = false;
    00136     // Sign size.
    00137     size_type __sign_size = 0;
    00138     // True if sign is mandatory.
    00139     const bool __mandatory_sign = (__lc->_M_positive_sign_size
    00140                        && __lc->_M_negative_sign_size);
    00141     // String of grouping info from thousands_sep plucked from __units.
    00142     string __grouping_tmp;
    00143     if (__lc->_M_use_grouping)
    00144       __grouping_tmp.reserve(32);
    00145     // Last position before the decimal point.
    00146     int __last_pos = 0;
    00147     // Separator positions, then, possibly, fractional digits.
    00148     int __n = 0;
    00149     // If input iterator is in a valid state.
    00150     bool __testvalid = true;
    00151     // Flag marking when a decimal point is found.
    00152     bool __testdecfound = false;
    00153
    00154     // The tentative returned string is stored here.
    00155     string __res;
    00156     __res.reserve(32);
    00157
    00158     const char_type* __lit_zero = __lit + money_base::_S_zero;
    00159     const money_base::pattern __p = __lc->_M_neg_format;
    00160     for (int __i = 0; __i < 4 && __testvalid; ++__i)
    00161       {
    00162         const part __which = static_cast<part>(__p.field[__i]);
    00163         switch (__which)
    00164           {
    00165           case money_base::symbol:
    00166         // According to 22.2.6.1.2, p2, symbol is required
    00167         // if (__io.flags() & ios_base::showbase), otherwise
    00168         // is optional and consumed only if other characters
    00169         // are needed to complete the format.
    00170         if (__io.flags() & ios_base::showbase || __sign_size > 1
    00171             || __i == 0
    00172             || (__i == 1 && (__mandatory_sign
    00173                      || (static_cast<part>(__p.field[0])
    00174                      == money_base::sign)
    00175                      || (static_cast<part>(__p.field[2])
    00176                      == money_base::space)))
    00177             || (__i == 2 && ((static_cast<part>(__p.field[3])
    00178                       == money_base::value)
    00179                      || (__mandatory_sign
    00180                      && (static_cast<part>(__p.field[3])
    00181                          == money_base::sign)))))
    00182           {
    00183             const size_type __len = __lc->_M_curr_symbol_size;
    00184             size_type __j = 0;
    00185             for (; __beg != __end && __j < __len
    00186                && *__beg == __lc->_M_curr_symbol[__j];
    00187              ++__beg, ++__j);
    00188             if (__j != __len
    00189             && (__j || __io.flags() & ios_base::showbase))
    00190               __testvalid = false;
    00191           }
    00192         break;
    00193           case money_base::sign:
    00194         // Sign might not exist, or be more than one character long.
    00195         if (__lc->_M_positive_sign_size && __beg != __end
    00196             && *__beg == __lc->_M_positive_sign[0])
    00197           {
    00198             __sign_size = __lc->_M_positive_sign_size;
    00199             ++__beg;
    00200           }
    00201         else if (__lc->_M_negative_sign_size && __beg != __end
    00202              && *__beg == __lc->_M_negative_sign[0])
    00203           {
    00204             __negative = true;
    00205             __sign_size = __lc->_M_negative_sign_size;
    00206             ++__beg;
    00207           }
    00208         else if (__lc->_M_positive_sign_size
    00209              && !__lc->_M_negative_sign_size)
    00210           // "... if no sign is detected, the result is given the sign
    00211           // that corresponds to the source of the empty string"
    00212           __negative = true;
    00213         else if (__mandatory_sign)
    00214           __testvalid = false;
    00215         break;
    00216           case money_base::value:
    00217         // Extract digits, remove and stash away the
    00218         // grouping of found thousands separators.
    00219         for (; __beg != __end; ++__beg)
    00220           {
    00221             const char_type __c = *__beg;
    00222             const char_type* __q = __traits_type::find(__lit_zero,
    00223                                    10, __c);
    00224             if (__q != 0)
    00225               {
    00226             __res += money_base::_S_atoms[__q - __lit];
    00227             ++__n;
    00228               }
    00229             else if (__c == __lc->_M_decimal_point
    00230                  && !__testdecfound)
    00231               {
    00232             __last_pos = __n;
    00233             __n = 0;
    00234             __testdecfound = true;
    00235               }
    00236             else if (__lc->_M_use_grouping
    00237                  && __c == __lc->_M_thousands_sep
    00238                  && !__testdecfound)
    00239               {
    00240             if (__n)
    00241               {
    00242                 // Mark position for later analysis.
    00243                 __grouping_tmp += static_cast<char>(__n);
    00244                 __n = 0;
    00245               }
    00246             else
    00247               {
    00248                 __testvalid = false;
    00249                 break;
    00250               }
    00251               }
    00252             else
    00253               break;
    00254           }
    00255         if (__res.empty())
    00256           __testvalid = false;
    00257         break;
    00258           case money_base::space:
    00259         // At least one space is required.
    00260         if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
    00261           ++__beg;
    00262         else
    00263           __testvalid = false;
    00264           case money_base::none:
    00265         // Only if not at the end of the pattern.
    00266         if (__i != 3)
    00267           for (; __beg != __end
    00268              && __ctype.is(ctype_base::space, *__beg); ++__beg);
    00269         break;
    00270           }
    00271       }
    00272
    00273     // Need to get the rest of the sign characters, if they exist.
    00274     if (__sign_size > 1 && __testvalid)
    00275       {
    00276         const char_type* __sign = __negative ? __lc->_M_negative_sign
    00277                                              : __lc->_M_positive_sign;
    00278         size_type __i = 1;
    00279         for (; __beg != __end && __i < __sign_size
    00280            && *__beg == __sign[__i]; ++__beg, ++__i);
    00281
    00282         if (__i != __sign_size)
    00283           __testvalid = false;
    00284       }
    00285
    00286     if (__testvalid)
    00287       {
    00288         // Strip leading zeros.
    00289         if (__res.size() > 1)
    00290           {
    00291         const size_type __first = __res.find_first_not_of('0');
    00292         const bool __only_zeros = __first == string::npos;
    00293         if (__first)
    00294           __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
    00295           }
    00296
    00297         // 22.2.6.1.2, p4
    00298         if (__negative && __res[0] != '0')
    00299           __res.insert(__res.begin(), '-');
    00300
    00301         // Test for grouping fidelity.
    00302         if (__grouping_tmp.size())
    00303           {
    00304         // Add the ending grouping.
    00305         __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos
    00306                                            : __n);
    00307         if (!std::__verify_grouping(__lc->_M_grouping,
    00308                         __lc->_M_grouping_size,
    00309                         __grouping_tmp))
    00310           __err |= ios_base::failbit;
    00311           }
    00312
    00313         // Iff not enough digits were supplied after the decimal-point.
    00314         if (__testdecfound && __lc->_M_frac_digits > 0
    00315         && __n != __lc->_M_frac_digits)
    00316           __testvalid = false;
    00317       }
    00318
    00319     // Iff valid sequence is not recognized.
    00320     if (!__testvalid)
    00321       __err |= ios_base::failbit;
    00322     else
    00323       __units.swap(__res);
    00324
    00325     // Iff no more characters are available.
    00326     if (__beg == __end)
    00327       __err |= ios_base::eofbit;
    00328     return __beg;
    00329       }
    00330
    00331 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
    00332   template<typename _CharT, typename _InIter>
    00333     _InIter
    00334     money_get<_CharT, _InIter>::
    00335     __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
    00336          ios_base::iostate& __err, double& __units) const
    00337     {
    00338       string __str;
    00339       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
    00340                      : _M_extract<false>(__beg, __end, __io, __err, __str);
    00341       std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
    00342       return __beg;
    00343     }
    00344 #endif
    00345
    00346   template<typename _CharT, typename _InIter>
    00347     _InIter
    00348     money_get<_CharT, _InIter>::
    00349     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
    00350        ios_base::iostate& __err, long double& __units) const
    00351     {
    00352       string __str;
    00353       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
    00354                  : _M_extract<false>(__beg, __end, __io, __err, __str);
    00355       std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
    00356       return __beg;
    00357     }
    00358
    00359   template<typename _CharT, typename _InIter>
    00360     _InIter
    00361     money_get<_CharT, _InIter>::
    00362     do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
    00363        ios_base::iostate& __err, string_type& __digits) const
    00364     {
    00365       typedef typename string::size_type                  size_type;
    00366
    00367       const locale& __loc = __io._M_getloc();
    00368       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00369
    00370       string __str;
    00371       __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str)
    00372                  : _M_extract<false>(__beg, __end, __io, __err, __str);
    00373       const size_type __len = __str.size();
    00374       if (__len)
    00375     {
    00376       __digits.resize(__len);
    00377       __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]);
    00378     }
    00379       return __beg;
    00380     }
    00381
    00382   template<typename _CharT, typename _OutIter>
    00383     template<bool _Intl>
    00384       _OutIter
    00385       money_put<_CharT, _OutIter>::
    00386       _M_insert(iter_type __s, ios_base& __io, char_type __fill,
    00387         const string_type& __digits) const
    00388       {
    00389     typedef typename string_type::size_type           size_type;
    00390     typedef money_base::part                          part;
    00391     typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
    00392
    00393     const locale& __loc = __io._M_getloc();
    00394     const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00395
    00396     __use_cache<__cache_type> __uc;
    00397     const __cache_type* __lc = __uc(__loc);
    00398     const char_type* __lit = __lc->_M_atoms;
    00399
    00400     // Determine if negative or positive formats are to be used, and
    00401     // discard leading negative_sign if it is present.
    00402     const char_type* __beg = __digits.data();
    00403
    00404     money_base::pattern __p;
    00405     const char_type* __sign;
    00406     size_type __sign_size;
    00407     if (!(*__beg == __lit[money_base::_S_minus]))
    00408       {
    00409         __p = __lc->_M_pos_format;
    00410         __sign = __lc->_M_positive_sign;
    00411         __sign_size = __lc->_M_positive_sign_size;
    00412       }
    00413     else
    00414       {
    00415         __p = __lc->_M_neg_format;
    00416         __sign = __lc->_M_negative_sign;
    00417         __sign_size = __lc->_M_negative_sign_size;
    00418         if (__digits.size())
    00419           ++__beg;
    00420       }
    00421
    00422     // Look for valid numbers in the ctype facet within input digits.
    00423     size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
    00424                        __beg + __digits.size()) - __beg;
    00425     if (__len)
    00426       {
    00427         // Assume valid input, and attempt to format.
    00428         // Break down input numbers into base components, as follows:
    00429         //   final_value = grouped units + (decimal point) + (digits)
    00430         string_type __value;
    00431         __value.reserve(2 * __len);
    00432
    00433         // Add thousands separators to non-decimal digits, per
    00434         // grouping rules.
    00435         long __paddec = __len - __lc->_M_frac_digits;
    00436         if (__paddec > 0)
    00437           {
    00438         if (__lc->_M_frac_digits < 0)
    00439           __paddec = __len;
    00440         if (__lc->_M_grouping_size)
    00441           {
    00442             __value.assign(2 * __paddec, char_type());
    00443             _CharT* __vend =
    00444               std::__add_grouping(&__value[0], __lc->_M_thousands_sep,
    00445                       __lc->_M_grouping,
    00446                       __lc->_M_grouping_size,
    00447                       __beg, __beg + __paddec);
    00448             __value.erase(__vend - &__value[0]);
    00449           }
    00450         else
    00451           __value.assign(__beg, __paddec);
    00452           }
    00453
    00454         // Deal with decimal point, decimal digits.
    00455         if (__lc->_M_frac_digits > 0)
    00456           {
    00457         __value += __lc->_M_decimal_point;
    00458         if (__paddec >= 0)
    00459           __value.append(__beg + __paddec, __lc->_M_frac_digits);
    00460         else
    00461           {
    00462             // Have to pad zeros in the decimal position.
    00463             __value.append(-__paddec, __lit[money_base::_S_zero]);
    00464             __value.append(__beg, __len);
    00465           }
    00466           }
    00467
    00468         // Calculate length of resulting string.
    00469         const ios_base::fmtflags __f = __io.flags()
    00470                                        & ios_base::adjustfield;
    00471         __len = __value.size() + __sign_size;
    00472         __len += ((__io.flags() & ios_base::showbase)
    00473               ? __lc->_M_curr_symbol_size : 0);
    00474
    00475         string_type __res;
    00476         __res.reserve(2 * __len);
    00477
    00478         const size_type __width = static_cast<size_type>(__io.width());
    00479         const bool __testipad = (__f == ios_base::internal
    00480                      && __len < __width);
    00481         // Fit formatted digits into the required pattern.
    00482         for (int __i = 0; __i < 4; ++__i)
    00483           {
    00484         const part __which = static_cast<part>(__p.field[__i]);
    00485         switch (__which)
    00486           {
    00487           case money_base::symbol:
    00488             if (__io.flags() & ios_base::showbase)
    00489               __res.append(__lc->_M_curr_symbol,
    00490                    __lc->_M_curr_symbol_size);
    00491             break;
    00492           case money_base::sign:
    00493             // Sign might not exist, or be more than one
    00494             // character long. In that case, add in the rest
    00495             // below.
    00496             if (__sign_size)
    00497               __res += __sign[0];
    00498             break;
    00499           case money_base::value:
    00500             __res += __value;
    00501             break;
    00502           case money_base::space:
    00503             // At least one space is required, but if internal
    00504             // formatting is required, an arbitrary number of
    00505             // fill spaces will be necessary.
    00506             if (__testipad)
    00507               __res.append(__width - __len, __fill);
    00508             else
    00509               __res += __fill;
    00510             break;
    00511           case money_base::none:
    00512             if (__testipad)
    00513               __res.append(__width - __len, __fill);
    00514             break;
    00515           }
    00516           }
    00517
    00518         // Special case of multi-part sign parts.
    00519         if (__sign_size > 1)
    00520           __res.append(__sign + 1, __sign_size - 1);
    00521
    00522         // Pad, if still necessary.
    00523         __len = __res.size();
    00524         if (__width > __len)
    00525           {
    00526         if (__f == ios_base::left)
    00527           // After.
    00528           __res.append(__width - __len, __fill);
    00529         else
    00530           // Before.
    00531           __res.insert(0, __width - __len, __fill);
    00532         __len = __width;
    00533           }
    00534
    00535         // Write resulting, fully-formatted string to output iterator.
    00536         __s = std::__write(__s, __res.data(), __len);
    00537       }
    00538     __io.width(0);
    00539     return __s;
    00540       }
    00541
    00542 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
    00543   template<typename _CharT, typename _OutIter>
    00544     _OutIter
    00545     money_put<_CharT, _OutIter>::
    00546     __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
    00547          double __units) const
    00548     { return this->do_put(__s, __intl, __io, __fill, (long double) __units); }
    00549 #endif
    00550
    00551   template<typename _CharT, typename _OutIter>
    00552     _OutIter
    00553     money_put<_CharT, _OutIter>::
    00554     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
    00555        long double __units) const
    00556     {
    00557       const locale __loc = __io.getloc();
    00558       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00559 #ifdef _GLIBCXX_USE_C99
    00560       // First try a buffer perhaps big enough.
    00561       int __cs_size = 64;
    00562       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
    00563       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    00564       // 328. Bad sprintf format modifier in money_put<>::do_put()
    00565       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
    00566                     "%.*Lf", 0, __units);
    00567       // If the buffer was not large enough, try again with the correct size.
    00568       if (__len >= __cs_size)
    00569     {
    00570       __cs_size = __len + 1;
    00571       __cs = static_cast<char*>(__builtin_alloca(__cs_size));
    00572       __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
    00573                     "%.*Lf", 0, __units);
    00574     }
    00575 #else
    00576       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
    00577       const int __cs_size =
    00578     __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3;
    00579       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
    00580       int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf",
    00581                     0, __units);
    00582 #endif
    00583       string_type __digits(__len, char_type());
    00584       __ctype.widen(__cs, __cs + __len, &__digits[0]);
    00585       return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
    00586                 : _M_insert<false>(__s, __io, __fill, __digits);
    00587     }
    00588
    00589   template<typename _CharT, typename _OutIter>
    00590     _OutIter
    00591     money_put<_CharT, _OutIter>::
    00592     do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
    00593        const string_type& __digits) const
    00594     { return __intl ? _M_insert<true>(__s, __io, __fill, __digits)
    00595                 : _M_insert<false>(__s, __io, __fill, __digits); }
    00596
    00597 _GLIBCXX_END_LDBL_NAMESPACE
    00598
    00599   // NB: Not especially useful. Without an ios_base object or some
    00600   // kind of locale reference, we are left clawing at the air where
    00601   // the side of the mountain used to be...
    00602   template<typename _CharT, typename _InIter>
    00603     time_base::dateorder
    00604     time_get<_CharT, _InIter>::do_date_order() const
    00605     { return time_base::no_order; }
    00606
    00607   // Expand a strftime format string and parse it.  E.g., do_get_date() may
    00608   // pass %m/%d/%Y => extracted characters.
    00609   template<typename _CharT, typename _InIter>
    00610     _InIter
    00611     time_get<_CharT, _InIter>::
    00612     _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
    00613               ios_base::iostate& __err, tm* __tm,
    00614               const _CharT* __format) const
    00615     {
    00616       const locale& __loc = __io._M_getloc();
    00617       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
    00618       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00619       const size_t __len = char_traits<_CharT>::length(__format);
    00620
    00621       ios_base::iostate __tmperr = ios_base::goodbit;
    00622       for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i)
    00623     {
    00624       if (__ctype.narrow(__format[__i], 0) == '%')
    00625         {
    00626           // Verify valid formatting code, attempt to extract.
    00627           char __c = __ctype.narrow(__format[++__i], 0);
    00628           int __mem = 0;
    00629           if (__c == 'E' || __c == 'O')
    00630         __c = __ctype.narrow(__format[++__i], 0);
    00631           switch (__c)
    00632         {
    00633           const char* __cs;
    00634           _CharT __wcs[10];
    00635         case 'a':
    00636           // Abbreviated weekday name [tm_wday]
    00637           const char_type*  __days1[7];
    00638           __tp._M_days_abbreviated(__days1);
    00639           __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
    00640                       7, __io, __tmperr);
    00641           break;
    00642         case 'A':
    00643           // Weekday name [tm_wday].
    00644           const char_type*  __days2[7];
    00645           __tp._M_days(__days2);
    00646           __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
    00647                       7, __io, __tmperr);
    00648           break;
    00649         case 'h':
    00650         case 'b':
    00651           // Abbreviated month name [tm_mon]
    00652           const char_type*  __months1[12];
    00653           __tp._M_months_abbreviated(__months1);
    00654           __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
    00655                       __months1, 12, __io, __tmperr);
    00656           break;
    00657         case 'B':
    00658           // Month name [tm_mon].
    00659           const char_type*  __months2[12];
    00660           __tp._M_months(__months2);
    00661           __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
    00662                       __months2, 12, __io, __tmperr);
    00663           break;
    00664         case 'c':
    00665           // Default time and date representation.
    00666           const char_type*  __dt[2];
    00667           __tp._M_date_time_formats(__dt);
    00668           __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
    00669                         __tm, __dt[0]);
    00670           break;
    00671         case 'd':
    00672           // Day [01, 31]. [tm_mday]
    00673           __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
    00674                      __io, __tmperr);
    00675           break;
    00676         case 'e':
    00677           // Day [1, 31], with single digits preceded by
    00678           // space. [tm_mday]
    00679           if (__ctype.is(ctype_base::space, *__beg))
    00680             __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
    00681                        1, __io, __tmperr);
    00682           else
    00683             __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
    00684                        2, __io, __tmperr);
    00685           break;
    00686         case 'D':
    00687           // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
    00688           __cs = "%m/%d/%y";
    00689           __ctype.widen(__cs, __cs + 9, __wcs);
    00690           __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
    00691                         __tm, __wcs);
    00692           break;
    00693         case 'H':
    00694           // Hour [00, 23]. [tm_hour]
    00695           __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
    00696                      __io, __tmperr);
    00697           break;
    00698         case 'I':
    00699           // Hour [01, 12]. [tm_hour]
    00700           __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
    00701                      __io, __tmperr);
    00702           break;
    00703         case 'm':
    00704           // Month [01, 12]. [tm_mon]
    00705           __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
    00706                      __io, __tmperr);
    00707           if (!__tmperr)
    00708             __tm->tm_mon = __mem - 1;
    00709           break;
    00710         case 'M':
    00711           // Minute [00, 59]. [tm_min]
    00712           __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
    00713                      __io, __tmperr);
    00714           break;
    00715         case 'n':
    00716           if (__ctype.narrow(*__beg, 0) == '\n')
    00717             ++__beg;
    00718           else
    00719             __tmperr |= ios_base::failbit;
    00720           break;
    00721         case 'R':
    00722           // Equivalent to (%H:%M).
    00723           __cs = "%H:%M";
    00724           __ctype.widen(__cs, __cs + 6, __wcs);
    00725           __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
    00726                         __tm, __wcs);
    00727           break;
    00728         case 'S':
    00729           // Seconds. [tm_sec]
    00730           // [00, 60] in C99 (one leap-second), [00, 61] in C89.
    00731 #ifdef _GLIBCXX_USE_C99
    00732           __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
    00733 #else
    00734           __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
    00735 #endif
    00736                      __io, __tmperr);
    00737           break;
    00738         case 't':
    00739           if (__ctype.narrow(*__beg, 0) == '\t')
    00740             ++__beg;
    00741           else
    00742             __tmperr |= ios_base::failbit;
    00743           break;
    00744         case 'T':
    00745           // Equivalent to (%H:%M:%S).
    00746           __cs = "%H:%M:%S";
    00747           __ctype.widen(__cs, __cs + 9, __wcs);
    00748           __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
    00749                         __tm, __wcs);
    00750           break;
    00751         case 'x':
    00752           // Locale's date.
    00753           const char_type*  __dates[2];
    00754           __tp._M_date_formats(__dates);
    00755           __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
    00756                         __tm, __dates[0]);
    00757           break;
    00758         case 'X':
    00759           // Locale's time.
    00760           const char_type*  __times[2];
    00761           __tp._M_time_formats(__times);
    00762           __beg = _M_extract_via_format(__beg, __end, __io, __tmperr,
    00763                         __tm, __times[0]);
    00764           break;
    00765         case 'y':
    00766         case 'C': // C99
    00767           // Two digit year. [tm_year]
    00768           __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
    00769                      __io, __tmperr);
    00770           break;
    00771         case 'Y':
    00772           // Year [1900). [tm_year]
    00773           __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
    00774                      __io, __tmperr);
    00775           if (!__tmperr)
    00776             __tm->tm_year = __mem - 1900;
    00777           break;
    00778         case 'Z':
    00779           // Timezone info.
    00780           if (__ctype.is(ctype_base::upper, *__beg))
    00781             {
    00782               int __tmp;
    00783               __beg = _M_extract_name(__beg, __end, __tmp,
    00784                        __timepunct_cache<_CharT>::_S_timezones,
    00785                           14, __io, __tmperr);
    00786
    00787               // GMT requires special effort.
    00788               if (__beg != __end && !__tmperr && __tmp == 0
    00789               && (*__beg == __ctype.widen('-')
    00790                   || *__beg == __ctype.widen('+')))
    00791             {
    00792               __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
    00793                          __io, __tmperr);
    00794               __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
    00795                          __io, __tmperr);
    00796             }
    00797             }
    00798           else
    00799             __tmperr |= ios_base::failbit;
    00800           break;
    00801         default:
    00802           // Not recognized.
    00803           __tmperr |= ios_base::failbit;
    00804         }
    00805         }
    00806       else
    00807         {
    00808           // Verify format and input match, extract and discard.
    00809           if (__format[__i] == *__beg)
    00810         ++__beg;
    00811           else
    00812         __tmperr |= ios_base::failbit;
    00813         }
    00814     }
    00815
    00816       if (__tmperr)
    00817     __err |= ios_base::failbit;
    00818
    00819       return __beg;
    00820     }
    00821
    00822   template<typename _CharT, typename _InIter>
    00823     _InIter
    00824     time_get<_CharT, _InIter>::
    00825     _M_extract_num(iter_type __beg, iter_type __end, int& __member,
    00826            int __min, int __max, size_t __len,
    00827            ios_base& __io, ios_base::iostate& __err) const
    00828     {
    00829       const locale& __loc = __io._M_getloc();
    00830       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00831
    00832       // As-is works for __len = 1, 2, 4, the values actually used.
    00833       int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
    00834
    00835       ++__min;
    00836       size_t __i = 0;
    00837       int __value = 0;
    00838       for (; __beg != __end && __i < __len; ++__beg, ++__i)
    00839     {
    00840       const char __c = __ctype.narrow(*__beg, '*');
    00841       if (__c >= '0' && __c <= '9')
    00842         {
    00843           __value = __value * 10 + (__c - '0');
    00844           const int __valuec = __value * __mult;
    00845           if (__valuec > __max || __valuec + __mult < __min)
    00846         break;
    00847           __mult /= 10;
    00848         }
    00849       else
    00850         break;
    00851     }
    00852       if (__i == __len)
    00853     __member = __value;
    00854       else
    00855     __err |= ios_base::failbit;
    00856
    00857       return __beg;
    00858     }
    00859
    00860   // Assumptions:
    00861   // All elements in __names are unique.
    00862   template<typename _CharT, typename _InIter>
    00863     _InIter
    00864     time_get<_CharT, _InIter>::
    00865     _M_extract_name(iter_type __beg, iter_type __end, int& __member,
    00866             const _CharT** __names, size_t __indexlen,
    00867             ios_base& __io, ios_base::iostate& __err) const
    00868     {
    00869       typedef char_traits<_CharT>       __traits_type;
    00870       const locale& __loc = __io._M_getloc();
    00871       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00872
    00873       int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int)
    00874                               * __indexlen));
    00875       size_t __nmatches = 0;
    00876       size_t __pos = 0;
    00877       bool __testvalid = true;
    00878       const char_type* __name;
    00879
    00880       // Look for initial matches.
    00881       // NB: Some of the locale data is in the form of all lowercase
    00882       // names, and some is in the form of initially-capitalized
    00883       // names. Look for both.
    00884       if (__beg != __end)
    00885     {
    00886       const char_type __c = *__beg;
    00887       for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
    00888         if (__c == __names[__i1][0]
    00889         || __c == __ctype.toupper(__names[__i1][0]))
    00890           __matches[__nmatches++] = __i1;
    00891     }
    00892
    00893       while (__nmatches > 1)
    00894     {
    00895       // Find smallest matching string.
    00896       size_t __minlen = __traits_type::length(__names[__matches[0]]);
    00897       for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
    00898         __minlen = std::min(__minlen,
    00899                   __traits_type::length(__names[__matches[__i2]]));
    00900       ++__beg, ++__pos;
    00901       if (__pos < __minlen && __beg != __end)
    00902         for (size_t __i3 = 0; __i3 < __nmatches;)
    00903           {
    00904         __name = __names[__matches[__i3]];
    00905         if (!(__name[__pos] == *__beg))
    00906           __matches[__i3] = __matches[--__nmatches];
    00907         else
    00908           ++__i3;
    00909           }
    00910       else
    00911         break;
    00912     }
    00913
    00914       if (__nmatches == 1)
    00915     {
    00916       // Make sure found name is completely extracted.
    00917       ++__beg, ++__pos;
    00918       __name = __names[__matches[0]];
    00919       const size_t __len = __traits_type::length(__name);
    00920       while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
    00921         ++__beg, ++__pos;
    00922
    00923       if (__len == __pos)
    00924         __member = __matches[0];
    00925       else
    00926         __testvalid = false;
    00927     }
    00928       else
    00929     __testvalid = false;
    00930       if (!__testvalid)
    00931     __err |= ios_base::failbit;
    00932
    00933       return __beg;
    00934     }
    00935
    00936   template<typename _CharT, typename _InIter>
    00937     _InIter
    00938     time_get<_CharT, _InIter>::
    00939     do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
    00940         ios_base::iostate& __err, tm* __tm) const
    00941     {
    00942       const locale& __loc = __io._M_getloc();
    00943       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
    00944       const char_type*  __times[2];
    00945       __tp._M_time_formats(__times);
    00946       __beg = _M_extract_via_format(__beg, __end, __io, __err,
    00947                     __tm, __times[0]);
    00948       if (__beg == __end)
    00949     __err |= ios_base::eofbit;
    00950       return __beg;
    00951     }
    00952
    00953   template<typename _CharT, typename _InIter>
    00954     _InIter
    00955     time_get<_CharT, _InIter>::
    00956     do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
    00957         ios_base::iostate& __err, tm* __tm) const
    00958     {
    00959       const locale& __loc = __io._M_getloc();
    00960       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
    00961       const char_type*  __dates[2];
    00962       __tp._M_date_formats(__dates);
    00963       __beg = _M_extract_via_format(__beg, __end, __io, __err,
    00964                     __tm, __dates[0]);
    00965       if (__beg == __end)
    00966     __err |= ios_base::eofbit;
    00967       return __beg;
    00968     }
    00969
    00970   template<typename _CharT, typename _InIter>
    00971     _InIter
    00972     time_get<_CharT, _InIter>::
    00973     do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
    00974            ios_base::iostate& __err, tm* __tm) const
    00975     {
    00976       typedef char_traits<_CharT>       __traits_type;
    00977       const locale& __loc = __io._M_getloc();
    00978       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
    00979       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    00980       const char_type*  __days[7];
    00981       __tp._M_days_abbreviated(__days);
    00982       int __tmpwday;
    00983       ios_base::iostate __tmperr = ios_base::goodbit;
    00984       __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7,
    00985                   __io, __tmperr);
    00986
    00987       // Check to see if non-abbreviated name exists, and extract.
    00988       // NB: Assumes both _M_days and _M_days_abbreviated organized in
    00989       // exact same order, first to last, such that the resulting
    00990       // __days array with the same index points to a day, and that
    00991       // day's abbreviated form.
    00992       // NB: Also assumes that an abbreviated name is a subset of the name.
    00993       if (!__tmperr && __beg != __end)
    00994     {
    00995       size_t __pos = __traits_type::length(__days[__tmpwday]);
    00996       __tp._M_days(__days);
    00997       const char_type* __name = __days[__tmpwday];
    00998       if (__name[__pos] == *__beg)
    00999         {
    01000           // Extract the rest of it.
    01001           const size_t __len = __traits_type::length(__name);
    01002           while (__pos < __len && __beg != __end
    01003              && __name[__pos] == *__beg)
    01004         ++__beg, ++__pos;
    01005           if (__len != __pos)
    01006         __tmperr |= ios_base::failbit;
    01007         }
    01008     }
    01009       if (!__tmperr)
    01010     __tm->tm_wday = __tmpwday;
    01011       else
    01012     __err |= ios_base::failbit;
    01013
    01014       if (__beg == __end)
    01015     __err |= ios_base::eofbit;
    01016       return __beg;
    01017      }
    01018
    01019   template<typename _CharT, typename _InIter>
    01020     _InIter
    01021     time_get<_CharT, _InIter>::
    01022     do_get_monthname(iter_type __beg, iter_type __end,
    01023                      ios_base& __io, ios_base::iostate& __err, tm* __tm) const
    01024     {
    01025       typedef char_traits<_CharT>       __traits_type;
    01026       const locale& __loc = __io._M_getloc();
    01027       const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
    01028       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    01029       const char_type*  __months[12];
    01030       __tp._M_months_abbreviated(__months);
    01031       int __tmpmon;
    01032       ios_base::iostate __tmperr = ios_base::goodbit;
    01033       __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12,
    01034                   __io, __tmperr);
    01035
    01036       // Check to see if non-abbreviated name exists, and extract.
    01037       // NB: Assumes both _M_months and _M_months_abbreviated organized in
    01038       // exact same order, first to last, such that the resulting
    01039       // __months array with the same index points to a month, and that
    01040       // month's abbreviated form.
    01041       // NB: Also assumes that an abbreviated name is a subset of the name.
    01042       if (!__tmperr && __beg != __end)
    01043     {
    01044       size_t __pos = __traits_type::length(__months[__tmpmon]);
    01045       __tp._M_months(__months);
    01046       const char_type* __name = __months[__tmpmon];
    01047       if (__name[__pos] == *__beg)
    01048         {
    01049           // Extract the rest of it.
    01050           const size_t __len = __traits_type::length(__name);
    01051           while (__pos < __len && __beg != __end
    01052              && __name[__pos] == *__beg)
    01053         ++__beg, ++__pos;
    01054           if (__len != __pos)
    01055         __tmperr |= ios_base::failbit;
    01056         }
    01057     }
    01058       if (!__tmperr)
    01059     __tm->tm_mon = __tmpmon;
    01060       else
    01061     __err |= ios_base::failbit;
    01062
    01063       if (__beg == __end)
    01064     __err |= ios_base::eofbit;
    01065       return __beg;
    01066     }
    01067
    01068   template<typename _CharT, typename _InIter>
    01069     _InIter
    01070     time_get<_CharT, _InIter>::
    01071     do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
    01072         ios_base::iostate& __err, tm* __tm) const
    01073     {
    01074       const locale& __loc = __io._M_getloc();
    01075       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
    01076
    01077       size_t __i = 0;
    01078       int __value = 0;
    01079       for (; __beg != __end && __i < 4; ++__beg, ++__i)
    01080     {
    01081       const char __c = __ctype.narrow(*__beg, '*');
    01082       if (__c >= '0' && __c <= '9')
    01083         __value = __value * 10 + (__c - '0');
    01084       else
    01085         break;
    01086     }
    01087       if (__i == 2 || __i == 4)
    01088     __tm->tm_year = __i == 2 ? __value : __value - 1900;
    01089       else
    01090     __err |= ios_base::failbit;
    01091
    01092       if (__beg == __end)
    01093     __err |= ios_base::eofbit;
    01094       return __beg;
    01095     }
    01096
    01097   template<typename _CharT, typename _OutIter>
    01098     _OutIter
    01099     time_put<_CharT, _OutIter>::
    01100     put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
    01101     const _CharT* __beg, const _CharT* __end) const
    01102     {
    01103       const locale& __loc = __io._M_getloc();
    01104       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
    01105       for (; __beg != __end; ++__beg)
    01106     if (__ctype.narrow(*__beg, 0) != '%')
    01107       {
    01108         *__s = *__beg;
    01109         ++__s;
    01110       }
    01111     else if (++__beg != __end)
    01112       {
    01113         char __format;
    01114         char __mod = 0;
    01115         const char __c = __ctype.narrow(*__beg, 0);
    01116         if (__c != 'E' && __c != 'O')
    01117           __format = __c;
    01118         else if (++__beg != __end)
    01119           {
    01120         __mod = __c;
    01121         __format = __ctype.narrow(*__beg, 0);
    01122           }
    01123         else
    01124           break;
    01125         __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
    01126       }
    01127     else
    01128       break;
    01129       return __s;
    01130     }
    01131
    01132   template<typename _CharT, typename _OutIter>
    01133     _OutIter
    01134     time_put<_CharT, _OutIter>::
    01135     do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
    01136        char __format, char __mod) const
    01137     {
    01138       const locale& __loc = __io._M_getloc();
    01139       ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
    01140       __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
    01141
    01142       // NB: This size is arbitrary. Should this be a data member,
    01143       // initialized at construction?
    01144       const size_t __maxlen = 128;
    01145       char_type* __res =
    01146        static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
    01147
    01148       // NB: In IEE 1003.1-200x, and perhaps other locale models, it
    01149       // is possible that the format character will be longer than one
    01150       // character. Possibilities include 'E' or 'O' followed by a
    01151       // format character: if __mod is not the default argument, assume
    01152       // it's a valid modifier.
    01153       char_type __fmt[4];
    01154       __fmt[0] = __ctype.widen('%');
    01155       if (!__mod)
    01156     {
    01157       __fmt[1] = __format;
    01158       __fmt[2] = char_type();
    01159     }
    01160       else
    01161     {
    01162       __fmt[1] = __mod;
    01163       __fmt[2] = __format;
    01164       __fmt[3] = char_type();
    01165     }
    01166
    01167       __tp._M_put(__res, __maxlen, __fmt, __tm);
    01168
    01169       // Write resulting, fully-formatted string to output iterator.
    01170       return std::__write(__s, __res, char_traits<char_type>::length(__res));
    01171     }
    01172
    01173
    01174   // Inhibit implicit instantiations for required instantiations,
    01175   // which are defined via explicit instantiations elsewhere.
    01176   // NB: This syntax is a GNU extension.
    01177 #if _GLIBCXX_EXTERN_TEMPLATE
    01178   extern template class moneypunct<char, false>;
    01179   extern template class moneypunct<char, true>;
    01180   extern template class moneypunct_byname<char, false>;
    01181   extern template class moneypunct_byname<char, true>;
    01182   extern template class _GLIBCXX_LDBL_NAMESPACE money_get<char>;
    01183   extern template class _GLIBCXX_LDBL_NAMESPACE money_put<char>;
    01184   extern template class __timepunct<char>;
    01185   extern template class time_put<char>;
    01186   extern template class time_put_byname<char>;
    01187   extern template class time_get<char>;
    01188   extern template class time_get_byname<char>;
    01189   extern template class messages<char>;
    01190   extern template class messages_byname<char>;
    01191
    01192   extern template
    01193     const moneypunct<char, true>&
    01194     use_facet<moneypunct<char, true> >(const locale&);
    01195
    01196   extern template
    01197     const moneypunct<char, false>&
    01198     use_facet<moneypunct<char, false> >(const locale&);
    01199
    01200   extern template
    01201     const money_put<char>&
    01202     use_facet<money_put<char> >(const locale&);
    01203
    01204   extern template
    01205     const money_get<char>&
    01206     use_facet<money_get<char> >(const locale&);
    01207
    01208   extern template
    01209     const __timepunct<char>&
    01210     use_facet<__timepunct<char> >(const locale&);
    01211
    01212   extern template
    01213     const time_put<char>&
    01214     use_facet<time_put<char> >(const locale&);
    01215
    01216   extern template
    01217     const time_get<char>&
    01218     use_facet<time_get<char> >(const locale&);
    01219
    01220   extern template
    01221     const messages<char>&
    01222     use_facet<messages<char> >(const locale&);
    01223
    01224   extern template
    01225     bool
    01226     has_facet<moneypunct<char> >(const locale&);
    01227
    01228   extern template
    01229     bool
    01230     has_facet<money_put<char> >(const locale&);
    01231
    01232   extern template
    01233     bool
    01234     has_facet<money_get<char> >(const locale&);
    01235
    01236   extern template
    01237     bool
    01238     has_facet<__timepunct<char> >(const locale&);
    01239
    01240   extern template
    01241     bool
    01242     has_facet<time_put<char> >(const locale&);
    01243
    01244   extern template
    01245     bool
    01246     has_facet<time_get<char> >(const locale&);
    01247
    01248   extern template
    01249     bool
    01250     has_facet<messages<char> >(const locale&);
    01251
    01252 #ifdef _GLIBCXX_USE_WCHAR_T
    01253   extern template class moneypunct<wchar_t, false>;
    01254   extern template class moneypunct<wchar_t, true>;
    01255   extern template class moneypunct_byname<wchar_t, false>;
    01256   extern template class moneypunct_byname<wchar_t, true>;
    01257   extern template class _GLIBCXX_LDBL_NAMESPACE money_get<wchar_t>;
    01258   extern template class _GLIBCXX_LDBL_NAMESPACE money_put<wchar_t>;
    01259   extern template class __timepunct<wchar_t>;
    01260   extern template class time_put<wchar_t>;
    01261   extern template class time_put_byname<wchar_t>;
    01262   extern template class time_get<wchar_t>;
    01263   extern template class time_get_byname<wchar_t>;
    01264   extern template class messages<wchar_t>;
    01265   extern template class messages_byname<wchar_t>;
    01266
    01267   extern template
    01268     const moneypunct<wchar_t, true>&
    01269     use_facet<moneypunct<wchar_t, true> >(const locale&);
    01270
    01271   extern template
    01272     const moneypunct<wchar_t, false>&
    01273     use_facet<moneypunct<wchar_t, false> >(const locale&);
    01274
    01275   extern template
    01276     const money_put<wchar_t>&
    01277     use_facet<money_put<wchar_t> >(const locale&);
    01278
    01279   extern template
    01280     const money_get<wchar_t>&
    01281     use_facet<money_get<wchar_t> >(const locale&);
    01282
    01283   extern template
    01284     const __timepunct<wchar_t>&
    01285     use_facet<__timepunct<wchar_t> >(const locale&);
    01286
    01287   extern template
    01288     const time_put<wchar_t>&
    01289     use_facet<time_put<wchar_t> >(const locale&);
    01290
    01291   extern template
    01292     const time_get<wchar_t>&
    01293     use_facet<time_get<wchar_t> >(const locale&);
    01294
    01295   extern template
    01296     const messages<wchar_t>&
    01297     use_facet<messages<wchar_t> >(const locale&);
    01298
    01299   extern template
    01300     bool
    01301     has_facet<moneypunct<wchar_t> >(const locale&);
    01302
    01303   extern template
    01304     bool
    01305     has_facet<money_put<wchar_t> >(const locale&);
    01306
    01307   extern template
    01308     bool
    01309     has_facet<money_get<wchar_t> >(const locale&);
    01310
    01311   extern template
    01312     bool
    01313     has_facet<__timepunct<wchar_t> >(const locale&);
    01314
    01315   extern template
    01316     bool
    01317     has_facet<time_put<wchar_t> >(const locale&);
    01318
    01319   extern template
    01320     bool
    01321     has_facet<time_get<wchar_t> >(const locale&);
    01322
    01323   extern template
    01324     bool
    01325     has_facet<messages<wchar_t> >(const locale&);
    01326 #endif
    01327 #endif
    01328
    01329 _GLIBCXX_END_NAMESPACE
    01330
    01331 #endif