# locale_facets.h

Go to the documentation of this file.

    00001 // Locale support -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 2, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 //
    00032 // ISO C++ 14882: 22.1  Locales
    00033 //
    00034
    00040 #ifndef _CPP_BITS_LOCFACETS_H
    00041 #define _CPP_BITS_LOCFACETS_H   1
    00042
    00043 #pragma GCC system_header
    00044
    00045 #include <ctime>    // For struct tm
    00046 #include <cwctype>  // For wctype_t
    00047 #include <iosfwd>
    00048 #include <bits/ios_base.h>  // For ios_base, ios_base::iostate
    00049 #include <streambuf>
    00050
    00051 namespace std
    00052 {
    00053   // NB: Don't instantiate required wchar_t facets if no wchar_t support.
    00054 #ifdef _GLIBCPP_USE_WCHAR_T
    00055 # define  _GLIBCPP_NUM_FACETS 28
    00056 #else
    00057 # define  _GLIBCPP_NUM_FACETS 14
    00058 #endif
    00059
    00060   // Convert string to numeric value of type _Tv and store results.
    00061   // NB: This is specialized for all required types, there is no
    00062   // generic definition.
    00063   template<typename _Tv>
    00064     void
    00065     __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
    00066            const __c_locale& __cloc, int __base = 10);
    00067
    00068   // Explicit specializations for required types.
    00069   template<>
    00070     void
    00071     __convert_to_v(const char*, long&, ios_base::iostate&,
    00072            const __c_locale&, int);
    00073
    00074   template<>
    00075     void
    00076     __convert_to_v(const char*, unsigned long&, ios_base::iostate&,
    00077            const __c_locale&, int);
    00078
    00079 #ifdef _GLIBCPP_USE_LONG_LONG
    00080   template<>
    00081     void
    00082     __convert_to_v(const char*, long long&, ios_base::iostate&,
    00083            const __c_locale&, int);
    00084
    00085   template<>
    00086     void
    00087     __convert_to_v(const char*, unsigned long long&, ios_base::iostate&,
    00088            const __c_locale&, int);
    00089 #endif
    00090
    00091   template<>
    00092     void
    00093     __convert_to_v(const char*, float&, ios_base::iostate&,
    00094            const __c_locale&, int);
    00095
    00096   template<>
    00097     void
    00098     __convert_to_v(const char*, double&, ios_base::iostate&,
    00099            const __c_locale&, int);
    00100
    00101  template<>
    00102     void
    00103     __convert_to_v(const char*, long double&, ios_base::iostate&,
    00104            const __c_locale&, int);
    00105
    00106   // NB: __pad is a struct, rather than a function, so it can be
    00107   // partially-specialized.
    00108   template<typename _CharT, typename _Traits>
    00109     struct __pad
    00110     {
    00111       static void
    00112       _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
    00113          const _CharT* __olds, const streamsize __newlen,
    00114          const streamsize __oldlen, const bool __num);
    00115     };
    00116
    00117   // Used by both numeric and monetary facets.
    00118   // Check to make sure that the __grouping_tmp string constructed in
    00119   // money_get or num_get matches the canonical grouping for a given
    00120   // locale.
    00121   // __grouping_tmp is parsed L to R
    00122   // 1,222,444 == __grouping_tmp of "\1\3\3"
    00123   // __grouping is parsed R to L
    00124   // 1,222,444 == __grouping of "\3" == "\3\3\3"
    00125   template<typename _CharT>
    00126     bool
    00127     __verify_grouping(const basic_string<_CharT>& __grouping,
    00128               basic_string<_CharT>& __grouping_tmp);
    00129
    00130   // Used by both numeric and monetary facets.
    00131   // Inserts "group separator" characters into an array of characters.
    00132   // It's recursive, one iteration per group.  It moves the characters
    00133   // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
    00134   // only with __gbeg != __gend.
    00135   template<typename _CharT>
    00136     _CharT*
    00137     __add_grouping(_CharT* __s, _CharT __sep,
    00138            const char* __gbeg, const char* __gend,
    00139            const _CharT* __first, const _CharT* __last);
    00140
    00141   // This template permits specializing facet output code for
    00142   // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
    00143   // significantly more efficient than incrementing iterators.
    00144   template<typename _CharT>
    00145     inline
    00146     ostreambuf_iterator<_CharT>
    00147     __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
    00148     {
    00149       __s._M_put(__ws, __len);
    00150       return __s;
    00151     }
    00152
    00153   // This is the unspecialized form of the template.
    00154   template<typename _CharT, typename _OutIter>
    00155     inline
    00156     _OutIter
    00157     __write(_OutIter __s, const _CharT* __ws, int __len)
    00158     {
    00159       for (int __j = 0; __j < __len; __j++, ++__s)
    00160     *__s = __ws[__j];
    00161       return __s;
    00162     }
    00163
    00164   // 22.2.1.1  Template class ctype
    00165   // Include host and configuration specific ctype enums for ctype_base.
    00166   #include <bits/ctype_base.h>
    00167
    00168   // Common base for ctype<_CharT>.
    00169   template<typename _CharT>
    00170     class __ctype_abstract_base : public locale::facet, public ctype_base
    00171     {
    00172     public:
    00173       // Types:
    00174       typedef _CharT char_type;
    00175
    00176       bool
    00177       is(mask __m, char_type __c) const
    00178       { return this->do_is(__m, __c); }
    00179
    00180       const char_type*
    00181       is(const char_type *__lo, const char_type *__hi, mask *__vec) const
    00182       { return this->do_is(__lo, __hi, __vec); }
    00183
    00184       const char_type*
    00185       scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
    00186       { return this->do_scan_is(__m, __lo, __hi); }
    00187
    00188       const char_type*
    00189       scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
    00190       { return this->do_scan_not(__m, __lo, __hi); }
    00191
    00192       char_type
    00193       toupper(char_type __c) const
    00194       { return this->do_toupper(__c); }
    00195
    00196       const char_type*
    00197       toupper(char_type *__lo, const char_type* __hi) const
    00198       { return this->do_toupper(__lo, __hi); }
    00199
    00200       char_type
    00201       tolower(char_type __c) const
    00202       { return this->do_tolower(__c); }
    00203
    00204       const char_type*
    00205       tolower(char_type* __lo, const char_type* __hi) const
    00206       { return this->do_tolower(__lo, __hi); }
    00207
    00208       char_type
    00209       widen(char __c) const
    00210       { return this->do_widen(__c); }
    00211
    00212       const char*
    00213       widen(const char* __lo, const char* __hi, char_type* __to) const
    00214       { return this->do_widen(__lo, __hi, __to); }
    00215
    00216       char
    00217       narrow(char_type __c, char __dfault) const
    00218       { return this->do_narrow(__c, __dfault); }
    00219
    00220       const char_type*
    00221       narrow(const char_type* __lo, const char_type* __hi,
    00222           char __dfault, char *__to) const
    00223       { return this->do_narrow(__lo, __hi, __dfault, __to); }
    00224
    00225     protected:
    00226       explicit
    00227       __ctype_abstract_base(size_t __refs = 0): locale::facet(__refs) { }
    00228
    00229       virtual
    00230       ~__ctype_abstract_base() { }
    00231
    00232       virtual bool
    00233       do_is(mask __m, char_type __c) const = 0;
    00234
    00235       virtual const char_type*
    00236       do_is(const char_type* __lo, const char_type* __hi,
    00237         mask* __vec) const = 0;
    00238
    00239       virtual const char_type*
    00240       do_scan_is(mask __m, const char_type* __lo,
    00241          const char_type* __hi) const = 0;
    00242
    00243       virtual const char_type*
    00244       do_scan_not(mask __m, const char_type* __lo,
    00245           const char_type* __hi) const = 0;
    00246
    00247       virtual char_type
    00248       do_toupper(char_type) const = 0;
    00249
    00250       virtual const char_type*
    00251       do_toupper(char_type* __lo, const char_type* __hi) const = 0;
    00252
    00253       virtual char_type
    00254       do_tolower(char_type) const = 0;
    00255
    00256       virtual const char_type*
    00257       do_tolower(char_type* __lo, const char_type* __hi) const = 0;
    00258
    00259       virtual char_type
    00260       do_widen(char) const = 0;
    00261
    00262       virtual const char*
    00263       do_widen(const char* __lo, const char* __hi,
    00264            char_type* __dest) const = 0;
    00265
    00266       virtual char
    00267       do_narrow(char_type, char __dfault) const = 0;
    00268
    00269       virtual const char_type*
    00270       do_narrow(const char_type* __lo, const char_type* __hi,
    00271          char __dfault, char* __dest) const = 0;
    00272     };
    00273
    00274   // NB: Generic, mostly useless implementation.
    00275   template<typename _CharT>
    00276     class ctype : public __ctype_abstract_base<_CharT>
    00277     {
    00278     public:
    00279       // Types:
    00280       typedef _CharT            char_type;
    00281       typedef typename ctype::mask  mask;
    00282
    00283       static locale::id             id;
    00284
    00285       explicit
    00286       ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
    00287
    00288    protected:
    00289       virtual
    00290       ~ctype();
    00291
    00292       virtual bool
    00293       do_is(mask __m, char_type __c) const;
    00294
    00295       virtual const char_type*
    00296       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
    00297
    00298       virtual const char_type*
    00299       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
    00300
    00301       virtual const char_type*
    00302       do_scan_not(mask __m, const char_type* __lo,
    00303           const char_type* __hi) const;
    00304
    00305       virtual char_type
    00306       do_toupper(char_type __c) const;
    00307
    00308       virtual const char_type*
    00309       do_toupper(char_type* __lo, const char_type* __hi) const;
    00310
    00311       virtual char_type
    00312       do_tolower(char_type __c) const;
    00313
    00314       virtual const char_type*
    00315       do_tolower(char_type* __lo, const char_type* __hi) const;
    00316
    00317       virtual char_type
    00318       do_widen(char __c) const;
    00319
    00320       virtual const char*
    00321       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
    00322
    00323       virtual char
    00324       do_narrow(char_type, char __dfault) const;
    00325
    00326       virtual const char_type*
    00327       do_narrow(const char_type* __lo, const char_type* __hi,
    00328         char __dfault, char* __dest) const;
    00329     };
    00330
    00331   template<typename _CharT>
    00332     locale::id ctype<_CharT>::id;
    00333
    00334   // 22.2.1.3  ctype<char> specialization.
    00335   template<>
    00336     class ctype<char> : public __ctype_abstract_base<char>
    00337     {
    00338     public:
    00339       // Types:
    00340       typedef char          char_type;
    00341
    00342     protected:
    00343       // Data Members:
    00344       __c_locale        _M_c_locale_ctype;
    00345       bool              _M_del;
    00346       __to_type             _M_toupper;
    00347       __to_type             _M_tolower;
    00348       const mask*               _M_table;
    00349
    00350     public:
    00351       static locale::id        id;
    00352       static const size_t      table_size = 1 + static_cast<unsigned char>(-1);
    00353
    00354       explicit
    00355       ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
    00356
    00357       explicit
    00358       ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
    00359         size_t __refs = 0);
    00360
    00361       inline bool
    00362       is(mask __m, char __c) const;
    00363
    00364       inline const char*
    00365       is(const char* __lo, const char* __hi, mask* __vec) const;
    00366
    00367       inline const char*
    00368       scan_is(mask __m, const char* __lo, const char* __hi) const;
    00369
    00370       inline const char*
    00371       scan_not(mask __m, const char* __lo, const char* __hi) const;
    00372
    00373     protected:
    00374       const mask*
    00375       table() const throw()
    00376       { return _M_table; }
    00377
    00378       static const mask*
    00379       classic_table() throw();
    00380
    00381       virtual
    00382       ~ctype();
    00383
    00384       virtual bool
    00385       do_is(mask __m, char_type __c) const;
    00386
    00387       virtual const char_type*
    00388       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
    00389
    00390       virtual const char_type*
    00391       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
    00392
    00393       virtual const char_type*
    00394       do_scan_not(mask __m, const char_type* __lo,
    00395           const char_type* __hi) const;
    00396
    00397       virtual char_type
    00398       do_toupper(char_type) const;
    00399
    00400       virtual const char_type*
    00401       do_toupper(char_type* __lo, const char_type* __hi) const;
    00402
    00403       virtual char_type
    00404       do_tolower(char_type) const;
    00405
    00406       virtual const char_type*
    00407       do_tolower(char_type* __lo, const char_type* __hi) const;
    00408
    00409       virtual char_type
    00410       do_widen(char) const;
    00411
    00412       virtual const char*
    00413       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
    00414
    00415       virtual char
    00416       do_narrow(char_type, char __dfault) const;
    00417
    00418       virtual const char_type*
    00419       do_narrow(const char_type* __lo, const char_type* __hi,
    00420         char __dfault, char* __dest) const;
    00421     };
    00422
    00423   template<>
    00424     const ctype<char>&
    00425     use_facet<ctype<char> >(const locale& __loc);
    00426
    00427 #ifdef _GLIBCPP_USE_WCHAR_T
    00428   // 22.2.1.3  ctype<wchar_t> specialization
    00429   template<>
    00430     class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
    00431     {
    00432     public:
    00433       // Types:
    00434       typedef wchar_t           char_type;
    00435       typedef wctype_t          __wmask_type;
    00436
    00437     protected:
    00438       __c_locale        _M_c_locale_ctype;
    00439
    00440     public:
    00441       // Data Members:
    00442       static locale::id         id;
    00443
    00444       explicit
    00445       ctype(size_t __refs = 0);
    00446
    00447       explicit
    00448       ctype(__c_locale __cloc, size_t __refs = 0);
    00449
    00450     protected:
    00451       __wmask_type
    00452       _M_convert_to_wmask(const mask __m) const;
    00453
    00454       virtual
    00455       ~ctype();
    00456
    00457       virtual bool
    00458       do_is(mask __m, char_type __c) const;
    00459
    00460       virtual const char_type*
    00461       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
    00462
    00463       virtual const char_type*
    00464       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
    00465
    00466       virtual const char_type*
    00467       do_scan_not(mask __m, const char_type* __lo,
    00468           const char_type* __hi) const;
    00469
    00470       virtual char_type
    00471       do_toupper(char_type) const;
    00472
    00473       virtual const char_type*
    00474       do_toupper(char_type* __lo, const char_type* __hi) const;
    00475
    00476       virtual char_type
    00477       do_tolower(char_type) const;
    00478
    00479       virtual const char_type*
    00480       do_tolower(char_type* __lo, const char_type* __hi) const;
    00481
    00482       virtual char_type
    00483       do_widen(char) const;
    00484
    00485       virtual const char*
    00486       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
    00487
    00488       virtual char
    00489       do_narrow(char_type, char __dfault) const;
    00490
    00491       virtual const char_type*
    00492       do_narrow(const char_type* __lo, const char_type* __hi,
    00493         char __dfault, char* __dest) const;
    00494
    00495     };
    00496
    00497   template<>
    00498     const ctype<wchar_t>&
    00499     use_facet<ctype<wchar_t> >(const locale& __loc);
    00500 #endif //_GLIBCPP_USE_WCHAR_T
    00501
    00502   // Include host and configuration specific ctype inlines.
    00503   #include <bits/ctype_inline.h>
    00504
    00505   // 22.2.1.2  Template class ctype_byname
    00506   template<typename _CharT>
    00507     class ctype_byname : public ctype<_CharT>
    00508     {
    00509     public:
    00510       typedef _CharT        char_type;
    00511
    00512       explicit
    00513       ctype_byname(const char* __s, size_t __refs = 0);
    00514
    00515     protected:
    00516       virtual
    00517       ~ctype_byname() { };
    00518     };
    00519
    00520   // 22.2.1.4  Class ctype_byname specializations.
    00521   template<>
    00522     ctype_byname<char>::ctype_byname(const char*, size_t refs);
    00523
    00524   template<>
    00525     ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
    00526
    00527   // 22.2.1.5  Template class codecvt
    00528   #include <bits/codecvt.h>
    00529
    00530   // 22.2.2  The numeric category.
    00531   class __num_base
    00532   {
    00533   public:
    00534     // NB: Code depends on the order of _S_atoms_out elements.
    00535     // Below are the indices into _S_atoms_out.
    00536     enum
    00537       {
    00538         _S_minus,
    00539         _S_plus,
    00540         _S_x,
    00541         _S_X,
    00542         _S_digits,
    00543         _S_digits_end = _S_digits + 16,
    00544         _S_udigits = _S_digits_end,
    00545         _S_udigits_end = _S_udigits + 16,
    00546         _S_e = _S_digits + 14,  // For scientific notation, 'e'
    00547         _S_E = _S_udigits + 14, // For scientific notation, 'E'
    00548     _S_end = _S_udigits_end
    00549       };
    00550
    00551     // A list of valid numeric literals for output.  This array
    00552     // contains chars that will be passed through the current locale's
    00553     // ctype<_CharT>.widen() and then used to render numbers.
    00554     // For the standard "C" locale, this is
    00555     // "-+xX0123456789abcdef0123456789ABCDEF".
    00556     static const char* _S_atoms_out;
    00557
    00558   protected:
    00559     // String literal of acceptable (narrow) input, for num_get.
    00560     // "0123456789eEabcdfABCDF"
    00561     static const char* _S_atoms_in;
    00562
    00563     enum
    00564     {
    00565       _M_zero,
    00566       _M_e = _M_zero + 10,
    00567       _M_E = _M_zero + 11,
    00568       _M_size = 21 + 1
    00569     };
    00570
    00571     // num_put
    00572     // Construct and return valid scanf format for floating point types.
    00573     static void
    00574     _S_format_float(const ios_base& __io, char* __fptr, char __mod,
    00575             streamsize __prec);
    00576
    00577     // Construct and return valid scanf format for integer types.
    00578     static void
    00579     _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
    00580   };
    00581
    00582
    00583   template<typename _CharT>
    00584     class numpunct : public locale::facet
    00585     {
    00586     public:
    00587       // Types:
    00588       typedef _CharT                char_type;
    00589       typedef basic_string<_CharT>  string_type;
    00590
    00591       static locale::id         id;
    00592
    00593     private:
    00594       char_type             _M_decimal_point;
    00595       char_type             _M_thousands_sep;
    00596       const char*           _M_grouping;
    00597       const char_type*          _M_truename;
    00598       const char_type*          _M_falsename;
    00599
    00600     public:
    00601       explicit
    00602       numpunct(size_t __refs = 0) : locale::facet(__refs)
    00603       { _M_initialize_numpunct(); }
    00604
    00605       explicit
    00606       numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
    00607       { _M_initialize_numpunct(__cloc); }
    00608
    00609       char_type
    00610       decimal_point() const
    00611       { return this->do_decimal_point(); }
    00612
    00613       char_type
    00614       thousands_sep() const
    00615       { return this->do_thousands_sep(); }
    00616
    00617       string
    00618       grouping() const
    00619       { return this->do_grouping(); }
    00620
    00621       string_type
    00622       truename() const
    00623       { return this->do_truename(); }
    00624
    00625       string_type
    00626       falsename() const
    00627       { return this->do_falsename(); }
    00628
    00629     protected:
    00630       virtual
    00631       ~numpunct();
    00632
    00633       virtual char_type
    00634       do_decimal_point() const
    00635       { return _M_decimal_point; }
    00636
    00637       virtual char_type
    00638       do_thousands_sep() const
    00639       { return _M_thousands_sep; }
    00640
    00641       virtual string
    00642       do_grouping() const
    00643       { return _M_grouping; }
    00644
    00645       virtual string_type
    00646       do_truename() const
    00647       { return _M_truename; }
    00648
    00649       virtual string_type
    00650       do_falsename() const
    00651       { return _M_falsename; }
    00652
    00653       // For use at construction time only.
    00654       void
    00655       _M_initialize_numpunct(__c_locale __cloc = NULL);
    00656     };
    00657
    00658   template<typename _CharT>
    00659     locale::id numpunct<_CharT>::id;
    00660
    00661   template<>
    00662     numpunct<char>::~numpunct();
    00663
    00664   template<>
    00665     void
    00666     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
    00667
    00668 #ifdef _GLIBCPP_USE_WCHAR_T
    00669   template<>
    00670     numpunct<wchar_t>::~numpunct();
    00671
    00672   template<>
    00673     void
    00674     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
    00675 #endif
    00676
    00677   template<typename _CharT>
    00678     class numpunct_byname : public numpunct<_CharT>
    00679     {
    00680       // Data Member.
    00681       __c_locale            _M_c_locale_numpunct;
    00682
    00683     public:
    00684       typedef _CharT                char_type;
    00685       typedef basic_string<_CharT>  string_type;
    00686
    00687       explicit
    00688       numpunct_byname(const char* __s, size_t __refs = 0)
    00689       : numpunct<_CharT>(__refs)
    00690       {
    00691     _S_create_c_locale(_M_c_locale_numpunct, __s);
    00692     _M_initialize_numpunct(_M_c_locale_numpunct);
    00693       }
    00694
    00695     protected:
    00696       virtual
    00697       ~numpunct_byname()
    00698       { _S_destroy_c_locale(_M_c_locale_numpunct); }
    00699     };
    00700
    00701   template<typename _CharT, typename _InIter>
    00702     class num_get : public locale::facet, public __num_base
    00703     {
    00704     public:
    00705       // Types:
    00706       typedef _CharT            char_type;
    00707       typedef _InIter           iter_type;
    00708
    00709       static locale::id         id;
    00710
    00711       explicit
    00712       num_get(size_t __refs = 0) : locale::facet(__refs) { }
    00713
    00714       iter_type
    00715       get(iter_type __in, iter_type __end, ios_base& __io,
    00716       ios_base::iostate& __err, bool& __v) const
    00717       { return this->do_get(__in, __end, __io, __err, __v); }
    00718
    00719       iter_type
    00720       get(iter_type __in, iter_type __end, ios_base& __io,
    00721       ios_base::iostate& __err, long& __v) const
    00722       { return this->do_get(__in, __end, __io, __err, __v); }
    00723
    00724       iter_type
    00725       get(iter_type __in, iter_type __end, ios_base& __io,
    00726       ios_base::iostate& __err, unsigned short& __v) const
    00727       { return this->do_get(__in, __end, __io, __err, __v); }
    00728
    00729       iter_type
    00730       get(iter_type __in, iter_type __end, ios_base& __io,
    00731       ios_base::iostate& __err, unsigned int& __v)   const
    00732       { return this->do_get(__in, __end, __io, __err, __v); }
    00733
    00734       iter_type
    00735       get(iter_type __in, iter_type __end, ios_base& __io,
    00736       ios_base::iostate& __err, unsigned long& __v)  const
    00737       { return this->do_get(__in, __end, __io, __err, __v); }
    00738
    00739 #ifdef _GLIBCPP_USE_LONG_LONG
    00740       iter_type
    00741       get(iter_type __in, iter_type __end, ios_base& __io,
    00742       ios_base::iostate& __err, long long& __v) const
    00743       { return this->do_get(__in, __end, __io, __err, __v); }
    00744
    00745       iter_type
    00746       get(iter_type __in, iter_type __end, ios_base& __io,
    00747       ios_base::iostate& __err, unsigned long long& __v)  const
    00748       { return this->do_get(__in, __end, __io, __err, __v); }
    00749 #endif
    00750
    00751       iter_type
    00752       get(iter_type __in, iter_type __end, ios_base& __io,
    00753       ios_base::iostate& __err, float& __v) const
    00754       { return this->do_get(__in, __end, __io, __err, __v); }
    00755
    00756       iter_type
    00757       get(iter_type __in, iter_type __end, ios_base& __io,
    00758       ios_base::iostate& __err, double& __v) const
    00759       { return this->do_get(__in, __end, __io, __err, __v); }
    00760
    00761       iter_type
    00762       get(iter_type __in, iter_type __end, ios_base& __io,
    00763       ios_base::iostate& __err, long double& __v) const
    00764       { return this->do_get(__in, __end, __io, __err, __v); }
    00765
    00766       iter_type
    00767       get(iter_type __in, iter_type __end, ios_base& __io,
    00768       ios_base::iostate& __err, void*& __v) const
    00769       { return this->do_get(__in, __end, __io, __err, __v); }
    00770
    00771     protected:
    00772       virtual ~num_get() { }
    00773
    00774       iter_type
    00775       _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
    00776                string& __xtrc) const;
    00777
    00778       iter_type
    00779       _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
    00780              string& __xtrc, int& __base) const;
    00781
    00782       virtual iter_type
    00783       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
    00784
    00785
    00786       virtual iter_type
    00787       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
    00788
    00789       virtual iter_type
    00790       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00791           unsigned short&) const;
    00792
    00793       virtual iter_type
    00794       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00795          unsigned int&) const;
    00796
    00797       virtual iter_type
    00798       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00799          unsigned long&) const;
    00800
    00801 #ifdef _GLIBCPP_USE_LONG_LONG
    00802       virtual iter_type
    00803       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00804          long long&) const;
    00805
    00806       virtual iter_type
    00807       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00808          unsigned long long&) const;
    00809 #endif
    00810
    00811       virtual iter_type
    00812       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00813          float&) const;
    00814
    00815       virtual iter_type
    00816       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00817          double&) const;
    00818
    00819       virtual iter_type
    00820       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00821          long double&) const;
    00822
    00823       virtual iter_type
    00824       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
    00825          void*&) const;
    00826     };
    00827
    00828   template<typename _CharT, typename _InIter>
    00829     locale::id num_get<_CharT, _InIter>::id;
    00830
    00831 #if 0
    00832   // Partial specialization for istreambuf_iterator, so can use traits_type.
    00833   template<typename _CharT>
    00834     class num_get<_CharT, istreambuf_iterator<_CharT> >;
    00835
    00836       iter_type
    00837       _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
    00838                string& __xtrc) const;
    00839
    00840       iter_type
    00841       _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
    00842              string& __xtrc, int& __base) const;
    00843
    00844       virtual iter_type
    00845       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
    00846 #endif
    00847
    00848   template<typename _CharT, typename _OutIter>
    00849     class num_put : public locale::facet, public __num_base
    00850     {
    00851     public:
    00852       // Types:
    00853       typedef _CharT        char_type;
    00854       typedef _OutIter      iter_type;
    00855       static locale::id     id;
    00856
    00857       explicit
    00858       num_put(size_t __refs = 0) : locale::facet(__refs) { }
    00859
    00860       iter_type
    00861       put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
    00862       { return this->do_put(__s, __f, __fill, __v); }
    00863
    00864       iter_type
    00865       put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
    00866       { return this->do_put(__s, __f, __fill, __v); }
    00867
    00868       iter_type
    00869       put(iter_type __s, ios_base& __f, char_type __fill,
    00870       unsigned long __v) const
    00871       { return this->do_put(__s, __f, __fill, __v); }
    00872
    00873 #ifdef _GLIBCPP_USE_LONG_LONG
    00874       iter_type
    00875       put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
    00876       { return this->do_put(__s, __f, __fill, __v); }
    00877
    00878       iter_type
    00879       put(iter_type __s, ios_base& __f, char_type __fill,
    00880       unsigned long long __v) const
    00881       { return this->do_put(__s, __f, __fill, __v); }
    00882 #endif
    00883
    00884       iter_type
    00885       put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
    00886       { return this->do_put(__s, __f, __fill, __v); }
    00887
    00888       iter_type
    00889       put(iter_type __s, ios_base& __f, char_type __fill,
    00890       long double __v) const
    00891       { return this->do_put(__s, __f, __fill, __v); }
    00892
    00893       iter_type
    00894       put(iter_type __s, ios_base& __f, char_type __fill,
    00895       const void* __v) const
    00896       { return this->do_put(__s, __f, __fill, __v); }
    00897
    00898     protected:
    00899       template<typename _ValueT>
    00900         iter_type
    00901         _M_convert_float(iter_type, ios_base& __io, char_type __fill,
    00902              char __mod, _ValueT __v) const;
    00903
    00904       void
    00905       _M_group_float(const string& __grouping, char_type __sep,
    00906              const char_type* __p, char_type* __new, char_type* __cs,
    00907              int& __len) const;
    00908
    00909       template<typename _ValueT>
    00910         iter_type
    00911         _M_convert_int(iter_type, ios_base& __io, char_type __fill,
    00912                _ValueT __v) const;
    00913
    00914       void
    00915       _M_group_int(const string& __grouping, char_type __sep,
    00916            ios_base& __io, char_type* __new, char_type* __cs,
    00917            int& __len) const;
    00918
    00919       void
    00920       _M_pad(char_type __fill, streamsize __w, ios_base& __io,
    00921          char_type* __new, const char_type* __cs, int& __len) const;
    00922
    00923 #if 1
    00924       // XXX GLIBCXX_ABI Deprecated, compatibility only.
    00925       template<typename _ValueT>
    00926         iter_type
    00927         _M_convert_int(iter_type, ios_base& __io, char_type __fill,
    00928                char __mod, char __modl, _ValueT __v) const;
    00929
    00930       iter_type
    00931       _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs,
    00932              int __len) const;
    00933
    00934       iter_type
    00935       _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs,
    00936            int __len) const;
    00937
    00938       iter_type
    00939       _M_insert(iter_type, ios_base& __io, char_type __fill,
    00940         const char_type* __ws, int __len) const;
    00941 #endif
    00942
    00943      virtual
    00944       ~num_put() { };
    00945
    00946       virtual iter_type
    00947       do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
    00948
    00949       virtual iter_type
    00950       do_put(iter_type, ios_base&, char_type __fill, long __v) const;
    00951
    00952       virtual iter_type
    00953       do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
    00954
    00955 #ifdef _GLIBCPP_USE_LONG_LONG
    00956       virtual iter_type
    00957       do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
    00958
    00959       virtual iter_type
    00960       do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
    00961 #endif
    00962
    00963       virtual iter_type
    00964       do_put(iter_type, ios_base&, char_type __fill, double __v) const;
    00965
    00966       virtual iter_type
    00967       do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
    00968
    00969       virtual iter_type
    00970       do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
    00971     };
    00972
    00973   template <typename _CharT, typename _OutIter>
    00974     locale::id num_put<_CharT, _OutIter>::id;
    00975
    00976
    00977   template<typename _CharT>
    00978     class collate : public locale::facet
    00979     {
    00980     public:
    00981       // Types:
    00982       typedef _CharT                char_type;
    00983       typedef basic_string<_CharT>  string_type;
    00984
    00985     protected:
    00986       // Underlying "C" library locale information saved from
    00987       // initialization, needed by collate_byname as well.
    00988       __c_locale            _M_c_locale_collate;
    00989
    00990     public:
    00991       static locale::id         id;
    00992
    00993       explicit
    00994       collate(size_t __refs = 0)
    00995       : locale::facet(__refs)
    00996       { _M_c_locale_collate = _S_c_locale; }
    00997
    00998       explicit
    00999       collate(__c_locale __cloc, size_t __refs = 0)
    01000       : locale::facet(__refs)
    01001       { _M_c_locale_collate = _S_clone_c_locale(__cloc); }
    01002
    01003       int
    01004       compare(const _CharT* __lo1, const _CharT* __hi1,
    01005           const _CharT* __lo2, const _CharT* __hi2) const
    01006       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
    01007
    01008       string_type
    01009       transform(const _CharT* __lo, const _CharT* __hi) const
    01010       { return this->do_transform(__lo, __hi); }
    01011
    01012       long
    01013       hash(const _CharT* __lo, const _CharT* __hi) const
    01014       { return this->do_hash(__lo, __hi); }
    01015
    01016       // Used to abstract out _CharT bits in virtual member functions, below.
    01017       int
    01018       _M_compare(const _CharT*, const _CharT*) const;
    01019
    01020       size_t
    01021       _M_transform(_CharT*, const _CharT*, size_t) const;
    01022
    01023   protected:
    01024       virtual
    01025       ~collate()
    01026       { _S_destroy_c_locale(_M_c_locale_collate); }
    01027
    01028       virtual int
    01029       do_compare(const _CharT* __lo1, const _CharT* __hi1,
    01030          const _CharT* __lo2, const _CharT* __hi2) const;
    01031
    01032       virtual string_type
    01033       do_transform(const _CharT* __lo, const _CharT* __hi) const;
    01034
    01035       virtual long
    01036       do_hash(const _CharT* __lo, const _CharT* __hi) const;
    01037     };
    01038
    01039   template<typename _CharT>
    01040     locale::id collate<_CharT>::id;
    01041
    01042   // Specializations.
    01043   template<>
    01044     int
    01045     collate<char>::_M_compare(const char*, const char*) const;
    01046
    01047   template<>
    01048     size_t
    01049     collate<char>::_M_transform(char*, const char*, size_t) const;
    01050
    01051 #ifdef _GLIBCPP_USE_WCHAR_T
    01052   template<>
    01053     int
    01054     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
    01055
    01056   template<>
    01057     size_t
    01058     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
    01059 #endif
    01060
    01061   template<typename _CharT>
    01062     class collate_byname : public collate<_CharT>
    01063     {
    01064     public:
    01065       typedef _CharT               char_type;
    01066       typedef basic_string<_CharT> string_type;
    01067
    01068       explicit
    01069       collate_byname(const char* __s, size_t __refs = 0)
    01070       : collate<_CharT>(__refs)
    01071       {
    01072     _S_destroy_c_locale(_M_c_locale_collate);
    01073     _S_create_c_locale(_M_c_locale_collate, __s);
    01074       }
    01075
    01076     protected:
    01077       virtual
    01078       ~collate_byname() { }
    01079     };
    01080
    01081
    01082   class time_base
    01083   {
    01084   public:
    01085     enum dateorder { no_order, dmy, mdy, ymd, ydm };
    01086   };
    01087
    01088   template<typename _CharT>
    01089     class __timepunct : public locale::facet
    01090     {
    01091     public:
    01092       // Types:
    01093       typedef _CharT                __char_type;
    01094       typedef basic_string<_CharT>  __string_type;
    01095
    01096       static locale::id         id;
    01097
    01098       // List of all known timezones, with GMT first.
    01099       static const _CharT*      _S_timezones[14];
    01100
    01101     protected:
    01102       __c_locale            _M_c_locale_timepunct;
    01103       char*             _M_name_timepunct;
    01104       const _CharT*             _M_date_format;
    01105       const _CharT*             _M_date_era_format;
    01106       const _CharT*             _M_time_format;
    01107       const _CharT*             _M_time_era_format;
    01108       const _CharT*         _M_date_time_format;
    01109       const _CharT*         _M_date_time_era_format;
    01110       const _CharT*             _M_am;
    01111       const _CharT*             _M_pm;
    01112       const _CharT*         _M_am_pm_format;
    01113
    01114       // Day names, starting with "C"'s Sunday.
    01115       const _CharT*             _M_day1;
    01116       const _CharT*             _M_day2;
    01117       const _CharT*             _M_day3;
    01118       const _CharT*             _M_day4;
    01119       const _CharT*             _M_day5;
    01120       const _CharT*             _M_day6;
    01121       const _CharT*             _M_day7;
    01122
    01123       // Abbreviated day names, starting with "C"'s Sun.
    01124       const _CharT*             _M_day_a1;
    01125       const _CharT*             _M_day_a2;
    01126       const _CharT*             _M_day_a3;
    01127       const _CharT*             _M_day_a4;
    01128       const _CharT*             _M_day_a5;
    01129       const _CharT*             _M_day_a6;
    01130       const _CharT*             _M_day_a7;
    01131
    01132       // Month names, starting with "C"'s January.
    01133       const _CharT*             _M_month01;
    01134       const _CharT*             _M_month02;
    01135       const _CharT*             _M_month03;
    01136       const _CharT*             _M_month04;
    01137       const _CharT*             _M_month05;
    01138       const _CharT*             _M_month06;
    01139       const _CharT*             _M_month07;
    01140       const _CharT*             _M_month08;
    01141       const _CharT*             _M_month09;
    01142       const _CharT*             _M_month10;
    01143       const _CharT*             _M_month11;
    01144       const _CharT*             _M_month12;
    01145
    01146       // Abbreviated month names, starting with "C"'s Jan.
    01147       const _CharT*             _M_month_a01;
    01148       const _CharT*             _M_month_a02;
    01149       const _CharT*             _M_month_a03;
    01150       const _CharT*             _M_month_a04;
    01151       const _CharT*             _M_month_a05;
    01152       const _CharT*             _M_month_a06;
    01153       const _CharT*             _M_month_a07;
    01154       const _CharT*             _M_month_a08;
    01155       const _CharT*             _M_month_a09;
    01156       const _CharT*             _M_month_a10;
    01157       const _CharT*             _M_month_a11;
    01158       const _CharT*             _M_month_a12;
    01159
    01160     public:
    01161       explicit
    01162       __timepunct(size_t __refs = 0);
    01163
    01164       explicit
    01165       __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
    01166
    01167       void
    01168       _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
    01169          const tm* __tm) const;
    01170
    01171       void
    01172       _M_date_formats(const _CharT** __date) const
    01173       {
    01174     // Always have default first.
    01175     __date[0] = _M_date_format;
    01176     __date[1] = _M_date_era_format;
    01177       }
    01178
    01179       void
    01180       _M_time_formats(const _CharT** __time) const
    01181       {
    01182     // Always have default first.
    01183     __time[0] = _M_time_format;
    01184     __time[1] = _M_time_era_format;
    01185       }
    01186
    01187       void
    01188       _M_ampm(const _CharT** __ampm) const
    01189       {
    01190     __ampm[0] = _M_am;
    01191     __ampm[1] = _M_pm;
    01192       }
    01193
    01194       void
    01195       _M_date_time_formats(const _CharT** __dt) const
    01196       {
    01197     // Always have default first.
    01198     __dt[0] = _M_date_time_format;
    01199     __dt[1] = _M_date_time_era_format;
    01200       }
    01201
    01202       void
    01203       _M_days(const _CharT** __days) const
    01204       {
    01205     __days[0] = _M_day1;
    01206     __days[1] = _M_day2;
    01207     __days[2] = _M_day3;
    01208     __days[3] = _M_day4;
    01209     __days[4] = _M_day5;
    01210     __days[5] = _M_day6;
    01211     __days[6] = _M_day7;
    01212       }
    01213
    01214       void
    01215       _M_days_abbreviated(const _CharT** __days) const
    01216       {
    01217     __days[0] = _M_day_a1;
    01218     __days[1] = _M_day_a2;
    01219     __days[2] = _M_day_a3;
    01220     __days[3] = _M_day_a4;
    01221     __days[4] = _M_day_a5;
    01222     __days[5] = _M_day_a6;
    01223     __days[6] = _M_day_a7;
    01224       }
    01225
    01226       void
    01227       _M_months(const _CharT** __months) const
    01228       {
    01229     __months[0] = _M_month01;
    01230     __months[1] = _M_month02;
    01231     __months[2] = _M_month03;
    01232     __months[3] = _M_month04;
    01233     __months[4] = _M_month05;
    01234     __months[5] = _M_month06;
    01235     __months[6] = _M_month07;
    01236     __months[7] = _M_month08;
    01237     __months[8] = _M_month09;
    01238     __months[9] = _M_month10;
    01239     __months[10] = _M_month11;
    01240     __months[11] = _M_month12;
    01241       }
    01242
    01243       void
    01244       _M_months_abbreviated(const _CharT** __months) const
    01245       {
    01246     __months[0] = _M_month_a01;
    01247     __months[1] = _M_month_a02;
    01248     __months[2] = _M_month_a03;
    01249     __months[3] = _M_month_a04;
    01250     __months[4] = _M_month_a05;
    01251     __months[5] = _M_month_a06;
    01252     __months[6] = _M_month_a07;
    01253     __months[7] = _M_month_a08;
    01254     __months[8] = _M_month_a09;
    01255     __months[9] = _M_month_a10;
    01256     __months[10] = _M_month_a11;
    01257     __months[11] = _M_month_a12;
    01258       }
    01259
    01260     protected:
    01261       virtual
    01262       ~__timepunct();
    01263
    01264       // For use at construction time only.
    01265       void
    01266       _M_initialize_timepunct(__c_locale __cloc = NULL);
    01267     };
    01268
    01269   template<typename _CharT>
    01270     locale::id __timepunct<_CharT>::id;
    01271
    01272   // Specializations.
    01273   template<>
    01274     const char*
    01275     __timepunct<char>::_S_timezones[14];
    01276
    01277   template<>
    01278     void
    01279     __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
    01280
    01281   template<>
    01282     void
    01283     __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
    01284
    01285 #ifdef _GLIBCPP_USE_WCHAR_T
    01286   template<>
    01287     const wchar_t*
    01288     __timepunct<wchar_t>::_S_timezones[14];
    01289
    01290   template<>
    01291     void
    01292     __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
    01293
    01294   template<>
    01295     void
    01296     __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
    01297                  const tm*) const;
    01298 #endif
    01299
    01300   // Generic.
    01301   template<typename _CharT>
    01302     const _CharT* __timepunct<_CharT>::_S_timezones[14];
    01303
    01304   // Include host and configuration specific timepunct functions.
    01305   #include <bits/time_members.h>
    01306
    01307   template<typename _CharT, typename _InIter>
    01308     class time_get : public locale::facet, public time_base
    01309     {
    01310     public:
    01311       // Types:
    01312       typedef _CharT            char_type;
    01313       typedef _InIter           iter_type;
    01314       typedef basic_string<_CharT>  __string_type;
    01315
    01316       static locale::id         id;
    01317
    01318       explicit
    01319       time_get(size_t __refs = 0)
    01320       : locale::facet (__refs) { }
    01321
    01322       dateorder
    01323       date_order()  const
    01324       { return this->do_date_order(); }
    01325
    01326       iter_type
    01327       get_time(iter_type __beg, iter_type __end, ios_base& __io,
    01328            ios_base::iostate& __err, tm* __tm)  const
    01329       { return this->do_get_time(__beg, __end, __io, __err, __tm); }
    01330
    01331       iter_type
    01332       get_date(iter_type __beg, iter_type __end, ios_base& __io,
    01333            ios_base::iostate& __err, tm* __tm)  const
    01334       { return this->do_get_date(__beg, __end, __io, __err, __tm); }
    01335
    01336       iter_type
    01337       get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
    01338           ios_base::iostate& __err, tm* __tm) const
    01339       { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
    01340
    01341       iter_type
    01342       get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
    01343             ios_base::iostate& __err, tm* __tm) const
    01344       { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
    01345
    01346       iter_type
    01347       get_year(iter_type __beg, iter_type __end, ios_base& __io,
    01348            ios_base::iostate& __err, tm* __tm) const
    01349       { return this->do_get_year(__beg, __end, __io, __err, __tm); }
    01350
    01351     protected:
    01352       virtual
    01353       ~time_get() { }
    01354
    01355       virtual dateorder
    01356       do_date_order() const;
    01357
    01358       virtual iter_type
    01359       do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
    01360           ios_base::iostate& __err, tm* __tm) const;
    01361
    01362       virtual iter_type
    01363       do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
    01364           ios_base::iostate& __err, tm* __tm) const;
    01365
    01366       virtual iter_type
    01367       do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
    01368              ios_base::iostate& __err, tm* __tm) const;
    01369
    01370       virtual iter_type
    01371       do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
    01372                ios_base::iostate& __err, tm* __tm) const;
    01373
    01374       virtual iter_type
    01375       do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
    01376           ios_base::iostate& __err, tm* __tm) const;
    01377
    01378       // Extract numeric component of length __len.
    01379       void
    01380       _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
    01381              int __min, int __max, size_t __len,
    01382              const ctype<_CharT>& __ctype,
    01383              ios_base::iostate& __err) const;
    01384
    01385       // Extract day or month name, or any unique array of string
    01386       // literals in a const _CharT* array.
    01387       void
    01388       _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
    01389               const _CharT** __names, size_t __indexlen,
    01390               ios_base::iostate& __err) const;
    01391
    01392       // Extract on a component-by-component basis, via __format argument.
    01393       void
    01394       _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
    01395                 ios_base::iostate& __err, tm* __tm,
    01396                 const _CharT* __format) const;
    01397     };
    01398
    01399   template<typename _CharT, typename _InIter>
    01400     locale::id time_get<_CharT, _InIter>::id;
    01401
    01402   template<typename _CharT, typename _InIter>
    01403     class time_get_byname : public time_get<_CharT, _InIter>
    01404     {
    01405     public:
    01406       // Types:
    01407       typedef _CharT            char_type;
    01408       typedef _InIter           iter_type;
    01409
    01410       explicit
    01411       time_get_byname(const char*, size_t __refs = 0)
    01412       : time_get<_CharT, _InIter>(__refs) { }
    01413
    01414     protected:
    01415       virtual
    01416       ~time_get_byname() { }
    01417     };
    01418
    01419   template<typename _CharT, typename _OutIter>
    01420     class time_put : public locale::facet, public time_base
    01421     {
    01422     public:
    01423       // Types:
    01424       typedef _CharT            char_type;
    01425       typedef _OutIter          iter_type;
    01426
    01427       static locale::id             id;
    01428
    01429       explicit
    01430       time_put(size_t __refs = 0)
    01431       : locale::facet(__refs) { }
    01432
    01433       iter_type
    01434       put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
    01435       const _CharT* __beg, const _CharT* __end) const;
    01436
    01437       iter_type
    01438       put(iter_type __s, ios_base& __io, char_type __fill,
    01439       const tm* __tm, char __format, char __mod = 0) const
    01440       { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
    01441
    01442     protected:
    01443       virtual
    01444       ~time_put()
    01445       { }
    01446
    01447       virtual iter_type
    01448       do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
    01449          char __format, char __mod) const;
    01450     };
    01451
    01452   template<typename _CharT, typename _OutIter>
    01453     locale::id time_put<_CharT, _OutIter>::id;
    01454
    01455   template<typename _CharT, typename _OutIter>
    01456     class time_put_byname : public time_put<_CharT, _OutIter>
    01457     {
    01458     public:
    01459       // Types:
    01460       typedef _CharT            char_type;
    01461       typedef _OutIter          iter_type;
    01462
    01463       explicit
    01464       time_put_byname(const char* /*__s*/, size_t __refs = 0)
    01465       : time_put<_CharT, _OutIter>(__refs)
    01466       { };
    01467
    01468     protected:
    01469       virtual
    01470       ~time_put_byname() { }
    01471     };
    01472
    01473
    01474   class money_base
    01475   {
    01476   public:
    01477     enum part { none, space, symbol, sign, value };
    01478     struct pattern { char field[4]; };
    01479
    01480     static const pattern _S_default_pattern;
    01481
    01482     // Construct and return valid pattern consisting of some combination of:
    01483     // space none symbol sign value
    01484     static pattern
    01485     _S_construct_pattern(char __precedes, char __space, char __posn);
    01486   };
    01487
    01488   template<typename _CharT, bool _Intl>
    01489     class moneypunct : public locale::facet, public money_base
    01490     {
    01491     public:
    01492       // Types:
    01493       typedef _CharT            char_type;
    01494       typedef basic_string<_CharT>  string_type;
    01495
    01496       static const bool         intl = _Intl;
    01497       static locale::id         id;
    01498
    01499     private:
    01500       const char*           _M_grouping;
    01501       char_type             _M_decimal_point;
    01502       char_type             _M_thousands_sep;
    01503       const char_type*          _M_curr_symbol;
    01504       const char_type*          _M_positive_sign;
    01505       const char_type*          _M_negative_sign;
    01506       int               _M_frac_digits;
    01507       pattern               _M_pos_format;
    01508       pattern               _M_neg_format;
    01509
    01510     public:
    01511       explicit
    01512       moneypunct(size_t __refs = 0) : locale::facet(__refs)
    01513       { _M_initialize_moneypunct(); }
    01514
    01515       explicit
    01516       moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
    01517       : locale::facet(__refs)
    01518       { _M_initialize_moneypunct(__cloc, __s); }
    01519
    01520       char_type
    01521       decimal_point() const
    01522       { return this->do_decimal_point(); }
    01523
    01524       char_type
    01525       thousands_sep() const
    01526       { return this->do_thousands_sep(); }
    01527
    01528       string
    01529       grouping() const
    01530       { return this->do_grouping(); }
    01531
    01532       string_type
    01533       curr_symbol() const
    01534       { return this->do_curr_symbol(); }
    01535
    01536       string_type
    01537       positive_sign() const
    01538       { return this->do_positive_sign(); }
    01539
    01540       string_type
    01541       negative_sign() const
    01542       { return this->do_negative_sign(); }
    01543
    01544       int
    01545       frac_digits() const
    01546       { return this->do_frac_digits(); }
    01547
    01548       pattern
    01549       pos_format() const
    01550       { return this->do_pos_format(); }
    01551
    01552       pattern
    01553       neg_format() const
    01554       { return this->do_neg_format(); }
    01555
    01556     protected:
    01557       virtual
    01558       ~moneypunct();
    01559
    01560       virtual char_type
    01561       do_decimal_point() const
    01562       { return _M_decimal_point; }
    01563
    01564       virtual char_type
    01565       do_thousands_sep() const
    01566       { return _M_thousands_sep; }
    01567
    01568       virtual string
    01569       do_grouping() const
    01570       { return _M_grouping; }
    01571
    01572       virtual string_type
    01573       do_curr_symbol()   const
    01574       { return _M_curr_symbol; }
    01575
    01576       virtual string_type
    01577       do_positive_sign() const
    01578       { return _M_positive_sign; }
    01579
    01580       virtual string_type
    01581       do_negative_sign() const
    01582       { return _M_negative_sign; }
    01583
    01584       virtual int
    01585       do_frac_digits() const
    01586       { return _M_frac_digits; }
    01587
    01588       virtual pattern
    01589       do_pos_format() const
    01590       { return _M_pos_format; }
    01591
    01592       virtual pattern
    01593       do_neg_format() const
    01594       { return _M_neg_format; }
    01595
    01596       // For use at construction time only.
    01597        void
    01598        _M_initialize_moneypunct(__c_locale __cloc = NULL,
    01599                 const char* __name = NULL);
    01600     };
    01601
    01602   template<typename _CharT, bool _Intl>
    01603     locale::id moneypunct<_CharT, _Intl>::id;
    01604
    01605   template<typename _CharT, bool _Intl>
    01606     const bool moneypunct<_CharT, _Intl>::intl;
    01607
    01608   template<>
    01609     moneypunct<char, true>::~moneypunct();
    01610
    01611   template<>
    01612     moneypunct<char, false>::~moneypunct();
    01613
    01614   template<>
    01615     void
    01616     moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
    01617
    01618   template<>
    01619     void
    01620     moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
    01621
    01622 #ifdef _GLIBCPP_USE_WCHAR_T
    01623   template<>
    01624     moneypunct<wchar_t, true>::~moneypunct();
    01625
    01626   template<>
    01627     moneypunct<wchar_t, false>::~moneypunct();
    01628
    01629   template<>
    01630     void
    01631     moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
    01632                             const char*);
    01633
    01634   template<>
    01635     void
    01636     moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
    01637                              const char*);
    01638 #endif
    01639
    01640   template<typename _CharT, bool _Intl>
    01641     class moneypunct_byname : public moneypunct<_CharT, _Intl>
    01642     {
    01643       __c_locale            _M_c_locale_moneypunct;
    01644
    01645     public:
    01646       typedef _CharT            char_type;
    01647       typedef basic_string<_CharT>  string_type;
    01648
    01649       static const bool intl = _Intl;
    01650
    01651       explicit
    01652       moneypunct_byname(const char* __s, size_t __refs = 0)
    01653       : moneypunct<_CharT, _Intl>(__refs)
    01654       {
    01655     _S_create_c_locale(_M_c_locale_moneypunct, __s);
    01656     _M_initialize_moneypunct(_M_c_locale_moneypunct);
    01657       }
    01658
    01659     protected:
    01660       virtual
    01661       ~moneypunct_byname()
    01662       { _S_destroy_c_locale(_M_c_locale_moneypunct); }
    01663     };
    01664
    01665   template<typename _CharT, bool _Intl>
    01666     const bool moneypunct_byname<_CharT, _Intl>::intl;
    01667
    01668   template<typename _CharT, typename _InIter>
    01669     class money_get : public locale::facet
    01670     {
    01671     public:
    01672       // Types:
    01673       typedef _CharT                char_type;
    01674       typedef _InIter               iter_type;
    01675       typedef basic_string<_CharT>  string_type;
    01676
    01677       static locale::id         id;
    01678
    01679       explicit
    01680       money_get(size_t __refs = 0) : locale::facet(__refs) { }
    01681
    01682       iter_type
    01683       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
    01684       ios_base::iostate& __err, long double& __units) const
    01685       { return this->do_get(__s, __end, __intl, __io, __err, __units); }
    01686
    01687       iter_type
    01688       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
    01689       ios_base::iostate& __err, string_type& __digits) const
    01690       { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
    01691
    01692     protected:
    01693       virtual
    01694       ~money_get() { }
    01695
    01696       virtual iter_type
    01697       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
    01698          ios_base::iostate& __err, long double& __units) const;
    01699
    01700       virtual iter_type
    01701       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
    01702          ios_base::iostate& __err, string_type& __digits) const;
    01703     };
    01704
    01705   template<typename _CharT, typename _InIter>
    01706     locale::id money_get<_CharT, _InIter>::id;
    01707
    01708   template<typename _CharT, typename _OutIter>
    01709     class money_put : public locale::facet
    01710     {
    01711     public:
    01712       typedef _CharT                char_type;
    01713       typedef _OutIter              iter_type;
    01714       typedef basic_string<_CharT>  string_type;
    01715
    01716       static locale::id         id;
    01717
    01718       explicit
    01719       money_put(size_t __refs = 0) : locale::facet(__refs) { }
    01720
    01721       iter_type
    01722       put(iter_type __s, bool __intl, ios_base& __io,
    01723       char_type __fill, long double __units) const
    01724       { return this->do_put(__s, __intl, __io, __fill, __units); }
    01725
    01726       iter_type
    01727       put(iter_type __s, bool __intl, ios_base& __io,
    01728       char_type __fill, const string_type& __digits) const
    01729       { return this->do_put(__s, __intl, __io, __fill, __digits); }
    01730
    01731     protected:
    01732       virtual
    01733       ~money_put() { }
    01734
    01735       virtual iter_type
    01736       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
    01737          long double __units) const;
    01738
    01739       virtual iter_type
    01740       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
    01741          const string_type& __digits) const;
    01742     };
    01743
    01744   template<typename _CharT, typename _OutIter>
    01745     locale::id money_put<_CharT, _OutIter>::id;
    01746
    01747
    01748   struct messages_base
    01749   {
    01750     typedef int catalog;
    01751   };
    01752
    01753   template<typename _CharT>
    01754     class messages : public locale::facet, public messages_base
    01755     {
    01756     public:
    01757       // Types:
    01758       typedef _CharT            char_type;
    01759       typedef basic_string<_CharT>  string_type;
    01760
    01761     protected:
    01762       // Underlying "C" library locale information saved from
    01763       // initialization, needed by messages_byname as well.
    01764       __c_locale            _M_c_locale_messages;
    01765       char*             _M_name_messages;
    01766
    01767     public:
    01768       static locale::id         id;
    01769
    01770       explicit
    01771       messages(size_t __refs = 0);
    01772
    01773       // Non-standard.
    01774       explicit
    01775       messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
    01776
    01777       catalog
    01778       open(const basic_string<char>& __s, const locale& __loc) const
    01779       { return this->do_open(__s, __loc); }
    01780
    01781       // Non-standard and unorthodox, yet effective.
    01782       catalog
    01783       open(const basic_string<char>&, const locale&, const char*) const;
    01784
    01785       string_type
    01786       get(catalog __c, int __set, int __msgid, const string_type& __s) const
    01787       { return this->do_get(__c, __set, __msgid, __s); }
    01788
    01789       void
    01790       close(catalog __c) const
    01791       { return this->do_close(__c); }
    01792
    01793     protected:
    01794       virtual
    01795       ~messages();
    01796
    01797       virtual catalog
    01798       do_open(const basic_string<char>&, const locale&) const;
    01799
    01800       virtual string_type
    01801       do_get(catalog, int, int, const string_type& __dfault) const;
    01802
    01803       virtual void
    01804       do_close(catalog) const;
    01805
    01806       // Returns a locale and codeset-converted string, given a char* message.
    01807       char*
    01808       _M_convert_to_char(const string_type& __msg) const
    01809       {
    01810     // XXX
    01811     return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
    01812       }
    01813
    01814       // Returns a locale and codeset-converted string, given a char* message.
    01815       string_type
    01816       _M_convert_from_char(char* __msg) const
    01817       {
    01818     // Length of message string without terminating null.
    01819     size_t __len = char_traits<char>::length(__msg) - 1;
    01820
    01821     // "everybody can easily convert the string using
    01822     // mbsrtowcs/wcsrtombs or with iconv()"
    01823 #if 0
    01824     // Convert char* to _CharT in locale used to open catalog.
    01825     // XXX need additional template parameter on messages class for this..
    01826     // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
    01827     typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
    01828
    01829     __codecvt_type::state_type __state;
    01830     // XXX may need to initialize state.
    01831     //initialize_state(__state._M_init());
    01832
    01833     char* __from_next;
    01834     // XXX what size for this string?
    01835     _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
    01836     const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
    01837     __cvt.out(__state, __msg, __msg + __len, __from_next,
    01838           __to, __to + __len + 1, __to_next);
    01839     return string_type(__to);
    01840 #endif
    01841 #if 0
    01842     typedef ctype<_CharT> __ctype_type;
    01843     // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
    01844     const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
    01845     // XXX Again, proper length of converted string an issue here.
    01846     // For now, assume the converted length is not larger.
    01847     _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
    01848     __cvt.widen(__msg, __msg + __len, __dest);
    01849     return basic_string<_CharT>(__dest);
    01850 #endif
    01851     return string_type();
    01852       }
    01853      };
    01854
    01855   template<typename _CharT>
    01856     locale::id messages<_CharT>::id;
    01857
    01858   // Specializations for required instantiations.
    01859   template<>
    01860     string
    01861     messages<char>::do_get(catalog, int, int, const string&) const;
    01862
    01863 #ifdef _GLIBCPP_USE_WCHAR_T
    01864   template<>
    01865     wstring
    01866     messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
    01867 #endif
    01868
    01869   template<typename _CharT>
    01870     class messages_byname : public messages<_CharT>
    01871     {
    01872     public:
    01873       typedef _CharT                char_type;
    01874       typedef basic_string<_CharT>  string_type;
    01875
    01876       explicit
    01877       messages_byname(const char* __s, size_t __refs = 0);
    01878
    01879     protected:
    01880       virtual
    01881       ~messages_byname()
    01882       { }
    01883     };
    01884
    01885   // Include host and configuration specific messages functions.
    01886   #include <bits/messages_members.h>
    01887
    01888
    01889   // Subclause convenience interfaces, inlines.
    01890   // NB: These are inline because, when used in a loop, some compilers
    01891   // can hoist the body out of the loop; then it's just as fast as the
    01892   // C is*() function.
    01893   template<typename _CharT>
    01894     inline bool
    01895     isspace(_CharT __c, const locale& __loc)
    01896     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
    01897
    01898   template<typename _CharT>
    01899     inline bool
    01900     isprint(_CharT __c, const locale& __loc)
    01901     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
    01902
    01903   template<typename _CharT>
    01904     inline bool
    01905     iscntrl(_CharT __c, const locale& __loc)
    01906     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
    01907
    01908   template<typename _CharT>
    01909     inline bool
    01910     isupper(_CharT __c, const locale& __loc)
    01911     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
    01912
    01913   template<typename _CharT>
    01914     inline bool islower(_CharT __c, const locale& __loc)
    01915     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
    01916
    01917   template<typename _CharT>
    01918     inline bool
    01919     isalpha(_CharT __c, const locale& __loc)
    01920     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
    01921
    01922   template<typename _CharT>
    01923     inline bool
    01924     isdigit(_CharT __c, const locale& __loc)
    01925     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
    01926
    01927   template<typename _CharT>
    01928     inline bool
    01929     ispunct(_CharT __c, const locale& __loc)
    01930     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
    01931
    01932   template<typename _CharT>
    01933     inline bool
    01934     isxdigit(_CharT __c, const locale& __loc)
    01935     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
    01936
    01937   template<typename _CharT>
    01938     inline bool
    01939     isalnum(_CharT __c, const locale& __loc)
    01940     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
    01941
    01942   template<typename _CharT>
    01943     inline bool
    01944     isgraph(_CharT __c, const locale& __loc)
    01945     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
    01946
    01947   template<typename _CharT>
    01948     inline _CharT
    01949     toupper(_CharT __c, const locale& __loc)
    01950     { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
    01951
    01952   template<typename _CharT>
    01953     inline _CharT
    01954     tolower(_CharT __c, const locale& __loc)
    01955     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
    01956
    01957   // __locale_cache holds the information extracted from the
    01958   // numpunct<> and moneypunct<> facets in a form optimized for
    01959   // parsing and formatting.  To avoid breaking the 3.2 library
    01960   // API, it is stored in ios_base::_M_local_word[0]. as a member of basic_ios and accessed via a void* pointer in
    01961   // the ios_base object passed to the _get and _put facets.
    01962
    01963   // Its intent is to avoid the cost of creating a locale object and
    01964   // calling the virtual functions in locale facets.
    01965   class __locale_cache_base
    01966   {
    01967   public:
    01968     virtual
    01969     ~__locale_cache_base() {}
    01970   };
    01971
    01972   template<typename _CharT>
    01973     class __locale_cache : public __locale_cache_base
    01974     {
    01975       // Types:
    01976       typedef _CharT                char_type;
    01977       typedef char_traits<_CharT>       traits_type;
    01978       typedef basic_string<_CharT>  string_type;
    01979
    01980
    01981     public:
    01982       // Data Members:
    01983
    01984       // A list of valid numeric literals: for the standard "C" locale, this
    01985       // is "-+xX0123456789abcdef0123456789ABCDEF".  This array contains the
    01986       // chars after having been passed through the current locale's
    01987       // ctype<_CharT>.widen().
    01988       _CharT                    _M_literals[__num_base::_S_end];
    01989
    01990
    01991       // The sign used to separate decimal values: for standard US
    01992       // locales, this would usually be: "."
    01993       // Abstracted from numpunct::decimal_point().
    01994       _CharT                    _M_decimal_point;
    01995
    01996       // The sign used to separate groups of digits into smaller
    01997       // strings that the eye can parse with less difficulty: for
    01998       // standard US locales, this would usually be: ","
    01999       // Abstracted from numpunct::thousands_sep().
    02000       _CharT                    _M_thousands_sep;
    02001
    02002       // However the US's "false" and "true" are translated.
    02003       // From numpunct::truename() and numpunct::falsename(), respectively.
    02004       string_type       _M_truename;
    02005       string_type       _M_falsename;
    02006
    02007       // If we are checking groupings. This should be equivalent to
    02008       // numpunct::groupings().size() != 0
    02009       bool                      _M_use_grouping;
    02010
    02011       // If we are using numpunct's groupings, this is the current grouping
    02012       // string in effect (from numpunct::grouping()).
    02013       string                    _M_grouping;
    02014
    02015       __locale_cache() : _M_use_grouping(false)
    02016       { };
    02017
    02018       __locale_cache&
    02019       operator=(const __locale_cache& __lc);
    02020
    02021
    02022       // Make sure the cache is built before the first use.
    02023       void
    02024       _M_init(const locale&);
    02025
    02026       // ios_base::pword callbacks come here
    02027       static void
    02028       _S_callback(ios_base::event __ev, ios_base& __io, int);
    02029     };
    02030 } // namespace std
    02031
    02032 #endif