Home | History | Annotate | Download | only in bits
      1 // Locale support -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file locale_facets_nonio.h
     26  *  This is an internal header file, included by other library headers.
     27  *  You should not attempt to use it directly.
     28  */
     29 
     30 //
     31 // ISO C++ 14882: 22.1  Locales
     32 //
     33 
     34 #ifndef _LOCALE_FACETS_NONIO_H
     35 #define _LOCALE_FACETS_NONIO_H 1
     36 
     37 #pragma GCC system_header
     38 
     39 #include <ctime>	// For struct tm
     40 
     41 _GLIBCXX_BEGIN_NAMESPACE(std)
     42 
     43   /**
     44    *  @brief  Time format ordering data.
     45    *
     46    *  This class provides an enum representing different orderings of day,
     47    *  month, and year.
     48   */
     49   class time_base
     50   {
     51   public:
     52     enum dateorder { no_order, dmy, mdy, ymd, ydm };
     53   };
     54 
     55   template<typename _CharT>
     56     struct __timepunct_cache : public locale::facet
     57     {
     58       // List of all known timezones, with GMT first.
     59       static const _CharT*		_S_timezones[14];
     60 
     61       const _CharT*			_M_date_format;
     62       const _CharT*			_M_date_era_format;
     63       const _CharT*			_M_time_format;
     64       const _CharT*			_M_time_era_format;
     65       const _CharT*			_M_date_time_format;
     66       const _CharT*			_M_date_time_era_format;
     67       const _CharT*			_M_am;
     68       const _CharT*			_M_pm;
     69       const _CharT*			_M_am_pm_format;
     70 
     71       // Day names, starting with "C"'s Sunday.
     72       const _CharT*			_M_day1;
     73       const _CharT*			_M_day2;
     74       const _CharT*			_M_day3;
     75       const _CharT*			_M_day4;
     76       const _CharT*			_M_day5;
     77       const _CharT*			_M_day6;
     78       const _CharT*			_M_day7;
     79 
     80       // Abbreviated day names, starting with "C"'s Sun.
     81       const _CharT*			_M_aday1;
     82       const _CharT*			_M_aday2;
     83       const _CharT*			_M_aday3;
     84       const _CharT*			_M_aday4;
     85       const _CharT*			_M_aday5;
     86       const _CharT*			_M_aday6;
     87       const _CharT*			_M_aday7;
     88 
     89       // Month names, starting with "C"'s January.
     90       const _CharT*			_M_month01;
     91       const _CharT*			_M_month02;
     92       const _CharT*			_M_month03;
     93       const _CharT*			_M_month04;
     94       const _CharT*			_M_month05;
     95       const _CharT*			_M_month06;
     96       const _CharT*			_M_month07;
     97       const _CharT*			_M_month08;
     98       const _CharT*			_M_month09;
     99       const _CharT*			_M_month10;
    100       const _CharT*			_M_month11;
    101       const _CharT*			_M_month12;
    102 
    103       // Abbreviated month names, starting with "C"'s Jan.
    104       const _CharT*			_M_amonth01;
    105       const _CharT*			_M_amonth02;
    106       const _CharT*			_M_amonth03;
    107       const _CharT*			_M_amonth04;
    108       const _CharT*			_M_amonth05;
    109       const _CharT*			_M_amonth06;
    110       const _CharT*			_M_amonth07;
    111       const _CharT*			_M_amonth08;
    112       const _CharT*			_M_amonth09;
    113       const _CharT*			_M_amonth10;
    114       const _CharT*			_M_amonth11;
    115       const _CharT*			_M_amonth12;
    116 
    117       bool				_M_allocated;
    118 
    119       __timepunct_cache(size_t __refs = 0) : facet(__refs),
    120       _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL),
    121       _M_time_era_format(NULL), _M_date_time_format(NULL),
    122       _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL),
    123       _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL),
    124       _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL),
    125       _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL),
    126       _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL),
    127       _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL),
    128       _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL),
    129       _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL),
    130       _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL),
    131       _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL),
    132       _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL),
    133       _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false)
    134       { }
    135 
    136       ~__timepunct_cache();
    137 
    138       void
    139       _M_cache(const locale& __loc);
    140 
    141     private:
    142       __timepunct_cache&
    143       operator=(const __timepunct_cache&);
    144 
    145       explicit
    146       __timepunct_cache(const __timepunct_cache&);
    147     };
    148 
    149   template<typename _CharT>
    150     __timepunct_cache<_CharT>::~__timepunct_cache()
    151     {
    152       if (_M_allocated)
    153 	{
    154 	  // Unused.
    155 	}
    156     }
    157 
    158   // Specializations.
    159   template<>
    160     const char*
    161     __timepunct_cache<char>::_S_timezones[14];
    162 
    163 #ifdef _GLIBCXX_USE_WCHAR_T
    164   template<>
    165     const wchar_t*
    166     __timepunct_cache<wchar_t>::_S_timezones[14];
    167 #endif
    168 
    169   // Generic.
    170   template<typename _CharT>
    171     const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];
    172 
    173   template<typename _CharT>
    174     class __timepunct : public locale::facet
    175     {
    176     public:
    177       // Types:
    178       typedef _CharT			__char_type;
    179       typedef basic_string<_CharT>	__string_type;
    180       typedef __timepunct_cache<_CharT>	__cache_type;
    181 
    182     protected:
    183       __cache_type*			_M_data;
    184       __c_locale			_M_c_locale_timepunct;
    185       const char*			_M_name_timepunct;
    186 
    187     public:
    188       /// Numpunct facet id.
    189       static locale::id			id;
    190 
    191       explicit
    192       __timepunct(size_t __refs = 0);
    193 
    194       explicit
    195       __timepunct(__cache_type* __cache, size_t __refs = 0);
    196 
    197       /**
    198        *  @brief  Internal constructor. Not for general use.
    199        *
    200        *  This is a constructor for use by the library itself to set up new
    201        *  locales.
    202        *
    203        *  @param cloc  The "C" locale.
    204        *  @param s  The name of a locale.
    205        *  @param refs  Passed to the base facet class.
    206       */
    207       explicit
    208       __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
    209 
    210       // FIXME: for error checking purposes _M_put should return the return
    211       // value of strftime/wcsftime.
    212       void
    213       _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
    214 	     const tm* __tm) const;
    215 
    216       void
    217       _M_date_formats(const _CharT** __date) const
    218       {
    219 	// Always have default first.
    220 	__date[0] = _M_data->_M_date_format;
    221 	__date[1] = _M_data->_M_date_era_format;
    222       }
    223 
    224       void
    225       _M_time_formats(const _CharT** __time) const
    226       {
    227 	// Always have default first.
    228 	__time[0] = _M_data->_M_time_format;
    229 	__time[1] = _M_data->_M_time_era_format;
    230       }
    231 
    232       void
    233       _M_date_time_formats(const _CharT** __dt) const
    234       {
    235 	// Always have default first.
    236 	__dt[0] = _M_data->_M_date_time_format;
    237 	__dt[1] = _M_data->_M_date_time_era_format;
    238       }
    239 
    240       void
    241       _M_am_pm_format(const _CharT* __ampm) const
    242       { __ampm = _M_data->_M_am_pm_format; }
    243 
    244       void
    245       _M_am_pm(const _CharT** __ampm) const
    246       {
    247 	__ampm[0] = _M_data->_M_am;
    248 	__ampm[1] = _M_data->_M_pm;
    249       }
    250 
    251       void
    252       _M_days(const _CharT** __days) const
    253       {
    254 	__days[0] = _M_data->_M_day1;
    255 	__days[1] = _M_data->_M_day2;
    256 	__days[2] = _M_data->_M_day3;
    257 	__days[3] = _M_data->_M_day4;
    258 	__days[4] = _M_data->_M_day5;
    259 	__days[5] = _M_data->_M_day6;
    260 	__days[6] = _M_data->_M_day7;
    261       }
    262 
    263       void
    264       _M_days_abbreviated(const _CharT** __days) const
    265       {
    266 	__days[0] = _M_data->_M_aday1;
    267 	__days[1] = _M_data->_M_aday2;
    268 	__days[2] = _M_data->_M_aday3;
    269 	__days[3] = _M_data->_M_aday4;
    270 	__days[4] = _M_data->_M_aday5;
    271 	__days[5] = _M_data->_M_aday6;
    272 	__days[6] = _M_data->_M_aday7;
    273       }
    274 
    275       void
    276       _M_months(const _CharT** __months) const
    277       {
    278 	__months[0] = _M_data->_M_month01;
    279 	__months[1] = _M_data->_M_month02;
    280 	__months[2] = _M_data->_M_month03;
    281 	__months[3] = _M_data->_M_month04;
    282 	__months[4] = _M_data->_M_month05;
    283 	__months[5] = _M_data->_M_month06;
    284 	__months[6] = _M_data->_M_month07;
    285 	__months[7] = _M_data->_M_month08;
    286 	__months[8] = _M_data->_M_month09;
    287 	__months[9] = _M_data->_M_month10;
    288 	__months[10] = _M_data->_M_month11;
    289 	__months[11] = _M_data->_M_month12;
    290       }
    291 
    292       void
    293       _M_months_abbreviated(const _CharT** __months) const
    294       {
    295 	__months[0] = _M_data->_M_amonth01;
    296 	__months[1] = _M_data->_M_amonth02;
    297 	__months[2] = _M_data->_M_amonth03;
    298 	__months[3] = _M_data->_M_amonth04;
    299 	__months[4] = _M_data->_M_amonth05;
    300 	__months[5] = _M_data->_M_amonth06;
    301 	__months[6] = _M_data->_M_amonth07;
    302 	__months[7] = _M_data->_M_amonth08;
    303 	__months[8] = _M_data->_M_amonth09;
    304 	__months[9] = _M_data->_M_amonth10;
    305 	__months[10] = _M_data->_M_amonth11;
    306 	__months[11] = _M_data->_M_amonth12;
    307       }
    308 
    309     protected:
    310       virtual
    311       ~__timepunct();
    312 
    313       // For use at construction time only.
    314       void
    315       _M_initialize_timepunct(__c_locale __cloc = NULL);
    316     };
    317 
    318   template<typename _CharT>
    319     locale::id __timepunct<_CharT>::id;
    320 
    321   // Specializations.
    322   template<>
    323     void
    324     __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
    325 
    326   template<>
    327     void
    328     __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
    329 
    330 #ifdef _GLIBCXX_USE_WCHAR_T
    331   template<>
    332     void
    333     __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
    334 
    335   template<>
    336     void
    337     __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
    338 				 const tm*) const;
    339 #endif
    340 
    341 _GLIBCXX_END_NAMESPACE
    342 
    343   // Include host and configuration specific timepunct functions.
    344   #include <bits/time_members.h>
    345 
    346 _GLIBCXX_BEGIN_NAMESPACE(std)
    347 
    348   /**
    349    *  @brief  Facet for parsing dates and times.
    350    *
    351    *  This facet encapsulates the code to parse and return a date or
    352    *  time from a string.  It is used by the istream numeric
    353    *  extraction operators.
    354    *
    355    *  The time_get template uses protected virtual functions to provide the
    356    *  actual results.  The public accessors forward the call to the virtual
    357    *  functions.  These virtual functions are hooks for developers to
    358    *  implement the behavior they require from the time_get facet.
    359   */
    360   template<typename _CharT, typename _InIter>
    361     class time_get : public locale::facet, public time_base
    362     {
    363     public:
    364       // Types:
    365       //@{
    366       /// Public typedefs
    367       typedef _CharT			char_type;
    368       typedef _InIter			iter_type;
    369       //@}
    370       typedef basic_string<_CharT>	__string_type;
    371 
    372       /// Numpunct facet id.
    373       static locale::id			id;
    374 
    375       /**
    376        *  @brief  Constructor performs initialization.
    377        *
    378        *  This is the constructor provided by the standard.
    379        *
    380        *  @param refs  Passed to the base facet class.
    381       */
    382       explicit
    383       time_get(size_t __refs = 0)
    384       : facet (__refs) { }
    385 
    386       /**
    387        *  @brief  Return preferred order of month, day, and year.
    388        *
    389        *  This function returns an enum from timebase::dateorder giving the
    390        *  preferred ordering if the format "x" given to time_put::put() only
    391        *  uses month, day, and year.  If the format "x" for the associated
    392        *  locale uses other fields, this function returns
    393        *  timebase::dateorder::noorder.
    394        *
    395        *  NOTE: The library always returns noorder at the moment.
    396        *
    397        *  @return  A member of timebase::dateorder.
    398       */
    399       dateorder
    400       date_order()  const
    401       { return this->do_date_order(); }
    402 
    403       /**
    404        *  @brief  Parse input time string.
    405        *
    406        *  This function parses a time according to the format "x" and puts the
    407        *  results into a user-supplied struct tm.  The result is returned by
    408        *  calling time_get::do_get_time().
    409        *
    410        *  If there is a valid time string according to format "x", @a tm will
    411        *  be filled in accordingly and the returned iterator will point to the
    412        *  first character beyond the time string.  If an error occurs before
    413        *  the end, err |= ios_base::failbit.  If parsing reads all the
    414        *  characters, err |= ios_base::eofbit.
    415        *
    416        *  @param  beg  Start of string to parse.
    417        *  @param  end  End of string to parse.
    418        *  @param  io  Source of the locale.
    419        *  @param  err  Error flags to set.
    420        *  @param  tm  Pointer to struct tm to fill in.
    421        *  @return  Iterator to first char beyond time string.
    422       */
    423       iter_type
    424       get_time(iter_type __beg, iter_type __end, ios_base& __io,
    425 	       ios_base::iostate& __err, tm* __tm)  const
    426       { return this->do_get_time(__beg, __end, __io, __err, __tm); }
    427 
    428       /**
    429        *  @brief  Parse input date string.
    430        *
    431        *  This function parses a date according to the format "X" and puts the
    432        *  results into a user-supplied struct tm.  The result is returned by
    433        *  calling time_get::do_get_date().
    434        *
    435        *  If there is a valid date string according to format "X", @a tm will
    436        *  be filled in accordingly and the returned iterator will point to the
    437        *  first character beyond the date string.  If an error occurs before
    438        *  the end, err |= ios_base::failbit.  If parsing reads all the
    439        *  characters, err |= ios_base::eofbit.
    440        *
    441        *  @param  beg  Start of string to parse.
    442        *  @param  end  End of string to parse.
    443        *  @param  io  Source of the locale.
    444        *  @param  err  Error flags to set.
    445        *  @param  tm  Pointer to struct tm to fill in.
    446        *  @return  Iterator to first char beyond date string.
    447       */
    448       iter_type
    449       get_date(iter_type __beg, iter_type __end, ios_base& __io,
    450 	       ios_base::iostate& __err, tm* __tm)  const
    451       { return this->do_get_date(__beg, __end, __io, __err, __tm); }
    452 
    453       /**
    454        *  @brief  Parse input weekday string.
    455        *
    456        *  This function parses a weekday name and puts the results into a
    457        *  user-supplied struct tm.  The result is returned by calling
    458        *  time_get::do_get_weekday().
    459        *
    460        *  Parsing starts by parsing an abbreviated weekday name.  If a valid
    461        *  abbreviation is followed by a character that would lead to the full
    462        *  weekday name, parsing continues until the full name is found or an
    463        *  error occurs.  Otherwise parsing finishes at the end of the
    464        *  abbreviated name.
    465        *
    466        *  If an error occurs before the end, err |= ios_base::failbit.  If
    467        *  parsing reads all the characters, err |= ios_base::eofbit.
    468        *
    469        *  @param  beg  Start of string to parse.
    470        *  @param  end  End of string to parse.
    471        *  @param  io  Source of the locale.
    472        *  @param  err  Error flags to set.
    473        *  @param  tm  Pointer to struct tm to fill in.
    474        *  @return  Iterator to first char beyond weekday name.
    475       */
    476       iter_type
    477       get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
    478 		  ios_base::iostate& __err, tm* __tm) const
    479       { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
    480 
    481       /**
    482        *  @brief  Parse input month string.
    483        *
    484        *  This function parses a month name and puts the results into a
    485        *  user-supplied struct tm.  The result is returned by calling
    486        *  time_get::do_get_monthname().
    487        *
    488        *  Parsing starts by parsing an abbreviated month name.  If a valid
    489        *  abbreviation is followed by a character that would lead to the full
    490        *  month name, parsing continues until the full name is found or an
    491        *  error occurs.  Otherwise parsing finishes at the end of the
    492        *  abbreviated name.
    493        *
    494        *  If an error occurs before the end, err |= ios_base::failbit.  If
    495        *  parsing reads all the characters, err |=
    496        *  ios_base::eofbit.
    497        *
    498        *  @param  beg  Start of string to parse.
    499        *  @param  end  End of string to parse.
    500        *  @param  io  Source of the locale.
    501        *  @param  err  Error flags to set.
    502        *  @param  tm  Pointer to struct tm to fill in.
    503        *  @return  Iterator to first char beyond month name.
    504       */
    505       iter_type
    506       get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
    507 		    ios_base::iostate& __err, tm* __tm) const
    508       { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
    509 
    510       /**
    511        *  @brief  Parse input year string.
    512        *
    513        *  This function reads up to 4 characters to parse a year string and
    514        *  puts the results into a user-supplied struct tm.  The result is
    515        *  returned by calling time_get::do_get_year().
    516        *
    517        *  4 consecutive digits are interpreted as a full year.  If there are
    518        *  exactly 2 consecutive digits, the library interprets this as the
    519        *  number of years since 1900.
    520        *
    521        *  If an error occurs before the end, err |= ios_base::failbit.  If
    522        *  parsing reads all the characters, err |= ios_base::eofbit.
    523        *
    524        *  @param  beg  Start of string to parse.
    525        *  @param  end  End of string to parse.
    526        *  @param  io  Source of the locale.
    527        *  @param  err  Error flags to set.
    528        *  @param  tm  Pointer to struct tm to fill in.
    529        *  @return  Iterator to first char beyond year.
    530       */
    531       iter_type
    532       get_year(iter_type __beg, iter_type __end, ios_base& __io,
    533 	       ios_base::iostate& __err, tm* __tm) const
    534       { return this->do_get_year(__beg, __end, __io, __err, __tm); }
    535 
    536     protected:
    537       /// Destructor.
    538       virtual
    539       ~time_get() { }
    540 
    541       /**
    542        *  @brief  Return preferred order of month, day, and year.
    543        *
    544        *  This function returns an enum from timebase::dateorder giving the
    545        *  preferred ordering if the format "x" given to time_put::put() only
    546        *  uses month, day, and year.  This function is a hook for derived
    547        *  classes to change the value returned.
    548        *
    549        *  @return  A member of timebase::dateorder.
    550       */
    551       virtual dateorder
    552       do_date_order() const;
    553 
    554       /**
    555        *  @brief  Parse input time string.
    556        *
    557        *  This function parses a time according to the format "x" and puts the
    558        *  results into a user-supplied struct tm.  This function is a hook for
    559        *  derived classes to change the value returned.  @see get_time() for
    560        *  details.
    561        *
    562        *  @param  beg  Start of string to parse.
    563        *  @param  end  End of string to parse.
    564        *  @param  io  Source of the locale.
    565        *  @param  err  Error flags to set.
    566        *  @param  tm  Pointer to struct tm to fill in.
    567        *  @return  Iterator to first char beyond time string.
    568       */
    569       virtual iter_type
    570       do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
    571 		  ios_base::iostate& __err, tm* __tm) const;
    572 
    573       /**
    574        *  @brief  Parse input date string.
    575        *
    576        *  This function parses a date according to the format "X" and puts the
    577        *  results into a user-supplied struct tm.  This function is a hook for
    578        *  derived classes to change the value returned.  @see get_date() for
    579        *  details.
    580        *
    581        *  @param  beg  Start of string to parse.
    582        *  @param  end  End of string to parse.
    583        *  @param  io  Source of the locale.
    584        *  @param  err  Error flags to set.
    585        *  @param  tm  Pointer to struct tm to fill in.
    586        *  @return  Iterator to first char beyond date string.
    587       */
    588       virtual iter_type
    589       do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
    590 		  ios_base::iostate& __err, tm* __tm) const;
    591 
    592       /**
    593        *  @brief  Parse input weekday string.
    594        *
    595        *  This function parses a weekday name and puts the results into a
    596        *  user-supplied struct tm.  This function is a hook for derived
    597        *  classes to change the value returned.  @see get_weekday() for
    598        *  details.
    599        *
    600        *  @param  beg  Start of string to parse.
    601        *  @param  end  End of string to parse.
    602        *  @param  io  Source of the locale.
    603        *  @param  err  Error flags to set.
    604        *  @param  tm  Pointer to struct tm to fill in.
    605        *  @return  Iterator to first char beyond weekday name.
    606       */
    607       virtual iter_type
    608       do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
    609 		     ios_base::iostate& __err, tm* __tm) const;
    610 
    611       /**
    612        *  @brief  Parse input month string.
    613        *
    614        *  This function parses a month name and puts the results into a
    615        *  user-supplied struct tm.  This function is a hook for derived
    616        *  classes to change the value returned.  @see get_monthname() for
    617        *  details.
    618        *
    619        *  @param  beg  Start of string to parse.
    620        *  @param  end  End of string to parse.
    621        *  @param  io  Source of the locale.
    622        *  @param  err  Error flags to set.
    623        *  @param  tm  Pointer to struct tm to fill in.
    624        *  @return  Iterator to first char beyond month name.
    625       */
    626       virtual iter_type
    627       do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
    628 		       ios_base::iostate& __err, tm* __tm) const;
    629 
    630       /**
    631        *  @brief  Parse input year string.
    632        *
    633        *  This function reads up to 4 characters to parse a year string and
    634        *  puts the results into a user-supplied struct tm.  This function is a
    635        *  hook for derived classes to change the value returned.  @see
    636        *  get_year() for details.
    637        *
    638        *  @param  beg  Start of string to parse.
    639        *  @param  end  End of string to parse.
    640        *  @param  io  Source of the locale.
    641        *  @param  err  Error flags to set.
    642        *  @param  tm  Pointer to struct tm to fill in.
    643        *  @return  Iterator to first char beyond year.
    644       */
    645       virtual iter_type
    646       do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
    647 		  ios_base::iostate& __err, tm* __tm) const;
    648 
    649       // Extract numeric component of length __len.
    650       iter_type
    651       _M_extract_num(iter_type __beg, iter_type __end, int& __member,
    652 		     int __min, int __max, size_t __len,
    653 		     ios_base& __io, ios_base::iostate& __err) const;
    654 
    655       // Extract day or month name, or any unique array of string
    656       // literals in a const _CharT* array.
    657       iter_type
    658       _M_extract_name(iter_type __beg, iter_type __end, int& __member,
    659 		      const _CharT** __names, size_t __indexlen,
    660 		      ios_base& __io, ios_base::iostate& __err) const;
    661 
    662       // Extract on a component-by-component basis, via __format argument.
    663       iter_type
    664       _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
    665 			    ios_base::iostate& __err, tm* __tm,
    666 			    const _CharT* __format) const;
    667     };
    668 
    669   template<typename _CharT, typename _InIter>
    670     locale::id time_get<_CharT, _InIter>::id;
    671 
    672   /// class time_get_byname [22.2.5.2].
    673   template<typename _CharT, typename _InIter>
    674     class time_get_byname : public time_get<_CharT, _InIter>
    675     {
    676     public:
    677       // Types:
    678       typedef _CharT			char_type;
    679       typedef _InIter			iter_type;
    680 
    681       explicit
    682       time_get_byname(const char*, size_t __refs = 0)
    683       : time_get<_CharT, _InIter>(__refs) { }
    684 
    685     protected:
    686       virtual
    687       ~time_get_byname() { }
    688     };
    689 
    690   /**
    691    *  @brief  Facet for outputting dates and times.
    692    *
    693    *  This facet encapsulates the code to format and output dates and times
    694    *  according to formats used by strftime().
    695    *
    696    *  The time_put template uses protected virtual functions to provide the
    697    *  actual results.  The public accessors forward the call to the virtual
    698    *  functions.  These virtual functions are hooks for developers to
    699    *  implement the behavior they require from the time_put facet.
    700   */
    701   template<typename _CharT, typename _OutIter>
    702     class time_put : public locale::facet
    703     {
    704     public:
    705       // Types:
    706       //@{
    707       /// Public typedefs
    708       typedef _CharT			char_type;
    709       typedef _OutIter			iter_type;
    710       //@}
    711 
    712       /// Numpunct facet id.
    713       static locale::id			id;
    714 
    715       /**
    716        *  @brief  Constructor performs initialization.
    717        *
    718        *  This is the constructor provided by the standard.
    719        *
    720        *  @param refs  Passed to the base facet class.
    721       */
    722       explicit
    723       time_put(size_t __refs = 0)
    724       : facet(__refs) { }
    725 
    726       /**
    727        *  @brief  Format and output a time or date.
    728        *
    729        *  This function formats the data in struct tm according to the
    730        *  provided format string.  The format string is interpreted as by
    731        *  strftime().
    732        *
    733        *  @param  s  The stream to write to.
    734        *  @param  io  Source of locale.
    735        *  @param  fill  char_type to use for padding.
    736        *  @param  tm  Struct tm with date and time info to format.
    737        *  @param  beg  Start of format string.
    738        *  @param  end  End of format string.
    739        *  @return  Iterator after writing.
    740        */
    741       iter_type
    742       put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
    743 	  const _CharT* __beg, const _CharT* __end) const;
    744 
    745       /**
    746        *  @brief  Format and output a time or date.
    747        *
    748        *  This function formats the data in struct tm according to the
    749        *  provided format char and optional modifier.  The format and modifier
    750        *  are interpreted as by strftime().  It does so by returning
    751        *  time_put::do_put().
    752        *
    753        *  @param  s  The stream to write to.
    754        *  @param  io  Source of locale.
    755        *  @param  fill  char_type to use for padding.
    756        *  @param  tm  Struct tm with date and time info to format.
    757        *  @param  format  Format char.
    758        *  @param  mod  Optional modifier char.
    759        *  @return  Iterator after writing.
    760        */
    761       iter_type
    762       put(iter_type __s, ios_base& __io, char_type __fill,
    763 	  const tm* __tm, char __format, char __mod = 0) const
    764       { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
    765 
    766     protected:
    767       /// Destructor.
    768       virtual
    769       ~time_put()
    770       { }
    771 
    772       /**
    773        *  @brief  Format and output a time or date.
    774        *
    775        *  This function formats the data in struct tm according to the
    776        *  provided format char and optional modifier.  This function is a hook
    777        *  for derived classes to change the value returned.  @see put() for
    778        *  more details.
    779        *
    780        *  @param  s  The stream to write to.
    781        *  @param  io  Source of locale.
    782        *  @param  fill  char_type to use for padding.
    783        *  @param  tm  Struct tm with date and time info to format.
    784        *  @param  format  Format char.
    785        *  @param  mod  Optional modifier char.
    786        *  @return  Iterator after writing.
    787        */
    788       virtual iter_type
    789       do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
    790 	     char __format, char __mod) const;
    791     };
    792 
    793   template<typename _CharT, typename _OutIter>
    794     locale::id time_put<_CharT, _OutIter>::id;
    795 
    796   /// class time_put_byname [22.2.5.4].
    797   template<typename _CharT, typename _OutIter>
    798     class time_put_byname : public time_put<_CharT, _OutIter>
    799     {
    800     public:
    801       // Types:
    802       typedef _CharT			char_type;
    803       typedef _OutIter			iter_type;
    804 
    805       explicit
    806       time_put_byname(const char*, size_t __refs = 0)
    807       : time_put<_CharT, _OutIter>(__refs)
    808       { };
    809 
    810     protected:
    811       virtual
    812       ~time_put_byname() { }
    813     };
    814 
    815 
    816   /**
    817    *  @brief  Money format ordering data.
    818    *
    819    *  This class contains an ordered array of 4 fields to represent the
    820    *  pattern for formatting a money amount.  Each field may contain one entry
    821    *  from the part enum.  symbol, sign, and value must be present and the
    822    *  remaining field must contain either none or space.  @see
    823    *  moneypunct::pos_format() and moneypunct::neg_format() for details of how
    824    *  these fields are interpreted.
    825   */
    826   class money_base
    827   {
    828   public:
    829     enum part { none, space, symbol, sign, value };
    830     struct pattern { char field[4]; };
    831 
    832     static const pattern _S_default_pattern;
    833 
    834     enum
    835     {
    836       _S_minus,
    837       _S_zero,
    838       _S_end = 11
    839     };
    840 
    841     // String literal of acceptable (narrow) input/output, for
    842     // money_get/money_put. "-0123456789"
    843     static const char* _S_atoms;
    844 
    845     // Construct and return valid pattern consisting of some combination of:
    846     // space none symbol sign value
    847     static pattern
    848     _S_construct_pattern(char __precedes, char __space, char __posn);
    849   };
    850 
    851   template<typename _CharT, bool _Intl>
    852     struct __moneypunct_cache : public locale::facet
    853     {
    854       const char*			_M_grouping;
    855       size_t                            _M_grouping_size;
    856       bool				_M_use_grouping;
    857       _CharT				_M_decimal_point;
    858       _CharT				_M_thousands_sep;
    859       const _CharT*			_M_curr_symbol;
    860       size_t                            _M_curr_symbol_size;
    861       const _CharT*			_M_positive_sign;
    862       size_t                            _M_positive_sign_size;
    863       const _CharT*			_M_negative_sign;
    864       size_t                            _M_negative_sign_size;
    865       int				_M_frac_digits;
    866       money_base::pattern		_M_pos_format;
    867       money_base::pattern	        _M_neg_format;
    868 
    869       // A list of valid numeric literals for input and output: in the standard
    870       // "C" locale, this is "-0123456789". This array contains the chars after
    871       // having been passed through the current locale's ctype<_CharT>.widen().
    872       _CharT				_M_atoms[money_base::_S_end];
    873 
    874       bool				_M_allocated;
    875 
    876       __moneypunct_cache(size_t __refs = 0) : facet(__refs),
    877       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
    878       _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),
    879       _M_curr_symbol(NULL), _M_curr_symbol_size(0),
    880       _M_positive_sign(NULL), _M_positive_sign_size(0),
    881       _M_negative_sign(NULL), _M_negative_sign_size(0),
    882       _M_frac_digits(0),
    883       _M_pos_format(money_base::pattern()),
    884       _M_neg_format(money_base::pattern()), _M_allocated(false)
    885       { }
    886 
    887       ~__moneypunct_cache();
    888 
    889       void
    890       _M_cache(const locale& __loc);
    891 
    892     private:
    893       __moneypunct_cache&
    894       operator=(const __moneypunct_cache&);
    895 
    896       explicit
    897       __moneypunct_cache(const __moneypunct_cache&);
    898     };
    899 
    900   template<typename _CharT, bool _Intl>
    901     __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache()
    902     {
    903       if (_M_allocated)
    904 	{
    905 	  delete [] _M_grouping;
    906 	  delete [] _M_curr_symbol;
    907 	  delete [] _M_positive_sign;
    908 	  delete [] _M_negative_sign;
    909 	}
    910     }
    911 
    912   /**
    913    *  @brief  Facet for formatting data for money amounts.
    914    *
    915    *  This facet encapsulates the punctuation, grouping and other formatting
    916    *  features of money amount string representations.
    917   */
    918   template<typename _CharT, bool _Intl>
    919     class moneypunct : public locale::facet, public money_base
    920     {
    921     public:
    922       // Types:
    923       //@{
    924       /// Public typedefs
    925       typedef _CharT			char_type;
    926       typedef basic_string<_CharT>	string_type;
    927       //@}
    928       typedef __moneypunct_cache<_CharT, _Intl>     __cache_type;
    929 
    930     private:
    931       __cache_type*			_M_data;
    932 
    933     public:
    934       /// This value is provided by the standard, but no reason for its
    935       /// existence.
    936       static const bool			intl = _Intl;
    937       /// Numpunct facet id.
    938       static locale::id			id;
    939 
    940       /**
    941        *  @brief  Constructor performs initialization.
    942        *
    943        *  This is the constructor provided by the standard.
    944        *
    945        *  @param refs  Passed to the base facet class.
    946       */
    947       explicit
    948       moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
    949       { _M_initialize_moneypunct(); }
    950 
    951       /**
    952        *  @brief  Constructor performs initialization.
    953        *
    954        *  This is an internal constructor.
    955        *
    956        *  @param cache  Cache for optimization.
    957        *  @param refs  Passed to the base facet class.
    958       */
    959       explicit
    960       moneypunct(__cache_type* __cache, size_t __refs = 0)
    961       : facet(__refs), _M_data(__cache)
    962       { _M_initialize_moneypunct(); }
    963 
    964       /**
    965        *  @brief  Internal constructor. Not for general use.
    966        *
    967        *  This is a constructor for use by the library itself to set up new
    968        *  locales.
    969        *
    970        *  @param cloc  The "C" locale.
    971        *  @param s  The name of a locale.
    972        *  @param refs  Passed to the base facet class.
    973       */
    974       explicit
    975       moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
    976       : facet(__refs), _M_data(NULL)
    977       { _M_initialize_moneypunct(__cloc, __s); }
    978 
    979       /**
    980        *  @brief  Return decimal point character.
    981        *
    982        *  This function returns a char_type to use as a decimal point.  It
    983        *  does so by returning returning
    984        *  moneypunct<char_type>::do_decimal_point().
    985        *
    986        *  @return  @a char_type representing a decimal point.
    987       */
    988       char_type
    989       decimal_point() const
    990       { return this->do_decimal_point(); }
    991 
    992       /**
    993        *  @brief  Return thousands separator character.
    994        *
    995        *  This function returns a char_type to use as a thousands
    996        *  separator.  It does so by returning returning
    997        *  moneypunct<char_type>::do_thousands_sep().
    998        *
    999        *  @return  char_type representing a thousands separator.
   1000       */
   1001       char_type
   1002       thousands_sep() const
   1003       { return this->do_thousands_sep(); }
   1004 
   1005       /**
   1006        *  @brief  Return grouping specification.
   1007        *
   1008        *  This function returns a string representing groupings for the
   1009        *  integer part of an amount.  Groupings indicate where thousands
   1010        *  separators should be inserted.
   1011        *
   1012        *  Each char in the return string is interpret as an integer rather
   1013        *  than a character.  These numbers represent the number of digits in a
   1014        *  group.  The first char in the string represents the number of digits
   1015        *  in the least significant group.  If a char is negative, it indicates
   1016        *  an unlimited number of digits for the group.  If more chars from the
   1017        *  string are required to group a number, the last char is used
   1018        *  repeatedly.
   1019        *
   1020        *  For example, if the grouping() returns "\003\002" and is applied to
   1021        *  the number 123456789, this corresponds to 12,34,56,789.  Note that
   1022        *  if the string was "32", this would put more than 50 digits into the
   1023        *  least significant group if the character set is ASCII.
   1024        *
   1025        *  The string is returned by calling
   1026        *  moneypunct<char_type>::do_grouping().
   1027        *
   1028        *  @return  string representing grouping specification.
   1029       */
   1030       string
   1031       grouping() const
   1032       { return this->do_grouping(); }
   1033 
   1034       /**
   1035        *  @brief  Return currency symbol string.
   1036        *
   1037        *  This function returns a string_type to use as a currency symbol.  It
   1038        *  does so by returning returning
   1039        *  moneypunct<char_type>::do_curr_symbol().
   1040        *
   1041        *  @return  @a string_type representing a currency symbol.
   1042       */
   1043       string_type
   1044       curr_symbol() const
   1045       { return this->do_curr_symbol(); }
   1046 
   1047       /**
   1048        *  @brief  Return positive sign string.
   1049        *
   1050        *  This function returns a string_type to use as a sign for positive
   1051        *  amounts.  It does so by returning returning
   1052        *  moneypunct<char_type>::do_positive_sign().
   1053        *
   1054        *  If the return value contains more than one character, the first
   1055        *  character appears in the position indicated by pos_format() and the
   1056        *  remainder appear at the end of the formatted string.
   1057        *
   1058        *  @return  @a string_type representing a positive sign.
   1059       */
   1060       string_type
   1061       positive_sign() const
   1062       { return this->do_positive_sign(); }
   1063 
   1064       /**
   1065        *  @brief  Return negative sign string.
   1066        *
   1067        *  This function returns a string_type to use as a sign for negative
   1068        *  amounts.  It does so by returning returning
   1069        *  moneypunct<char_type>::do_negative_sign().
   1070        *
   1071        *  If the return value contains more than one character, the first
   1072        *  character appears in the position indicated by neg_format() and the
   1073        *  remainder appear at the end of the formatted string.
   1074        *
   1075        *  @return  @a string_type representing a negative sign.
   1076       */
   1077       string_type
   1078       negative_sign() const
   1079       { return this->do_negative_sign(); }
   1080 
   1081       /**
   1082        *  @brief  Return number of digits in fraction.
   1083        *
   1084        *  This function returns the exact number of digits that make up the
   1085        *  fractional part of a money amount.  It does so by returning
   1086        *  returning moneypunct<char_type>::do_frac_digits().
   1087        *
   1088        *  The fractional part of a money amount is optional.  But if it is
   1089        *  present, there must be frac_digits() digits.
   1090        *
   1091        *  @return  Number of digits in amount fraction.
   1092       */
   1093       int
   1094       frac_digits() const
   1095       { return this->do_frac_digits(); }
   1096 
   1097       //@{
   1098       /**
   1099        *  @brief  Return pattern for money values.
   1100        *
   1101        *  This function returns a pattern describing the formatting of a
   1102        *  positive or negative valued money amount.  It does so by returning
   1103        *  returning moneypunct<char_type>::do_pos_format() or
   1104        *  moneypunct<char_type>::do_neg_format().
   1105        *
   1106        *  The pattern has 4 fields describing the ordering of symbol, sign,
   1107        *  value, and none or space.  There must be one of each in the pattern.
   1108        *  The none and space enums may not appear in the first field and space
   1109        *  may not appear in the final field.
   1110        *
   1111        *  The parts of a money string must appear in the order indicated by
   1112        *  the fields of the pattern.  The symbol field indicates that the
   1113        *  value of curr_symbol() may be present.  The sign field indicates
   1114        *  that the value of positive_sign() or negative_sign() must be
   1115        *  present.  The value field indicates that the absolute value of the
   1116        *  money amount is present.  none indicates 0 or more whitespace
   1117        *  characters, except at the end, where it permits no whitespace.
   1118        *  space indicates that 1 or more whitespace characters must be
   1119        *  present.
   1120        *
   1121        *  For example, for the US locale and pos_format() pattern
   1122        *  {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() ==
   1123        *  '+', and value 10.01, and options set to force the symbol, the
   1124        *  corresponding string is "$+10.01".
   1125        *
   1126        *  @return  Pattern for money values.
   1127       */
   1128       pattern
   1129       pos_format() const
   1130       { return this->do_pos_format(); }
   1131 
   1132       pattern
   1133       neg_format() const
   1134       { return this->do_neg_format(); }
   1135       //@}
   1136 
   1137     protected:
   1138       /// Destructor.
   1139       virtual
   1140       ~moneypunct();
   1141 
   1142       /**
   1143        *  @brief  Return decimal point character.
   1144        *
   1145        *  Returns a char_type to use as a decimal point.  This function is a
   1146        *  hook for derived classes to change the value returned.
   1147        *
   1148        *  @return  @a char_type representing a decimal point.
   1149       */
   1150       virtual char_type
   1151       do_decimal_point() const
   1152       { return _M_data->_M_decimal_point; }
   1153 
   1154       /**
   1155        *  @brief  Return thousands separator character.
   1156        *
   1157        *  Returns a char_type to use as a thousands separator.  This function
   1158        *  is a hook for derived classes to change the value returned.
   1159        *
   1160        *  @return  @a char_type representing a thousands separator.
   1161       */
   1162       virtual char_type
   1163       do_thousands_sep() const
   1164       { return _M_data->_M_thousands_sep; }
   1165 
   1166       /**
   1167        *  @brief  Return grouping specification.
   1168        *
   1169        *  Returns a string representing groupings for the integer part of a
   1170        *  number.  This function is a hook for derived classes to change the
   1171        *  value returned.  @see grouping() for details.
   1172        *
   1173        *  @return  String representing grouping specification.
   1174       */
   1175       virtual string
   1176       do_grouping() const
   1177       { return _M_data->_M_grouping; }
   1178 
   1179       /**
   1180        *  @brief  Return currency symbol string.
   1181        *
   1182        *  This function returns a string_type to use as a currency symbol.
   1183        *  This function is a hook for derived classes to change the value
   1184        *  returned.  @see curr_symbol() for details.
   1185        *
   1186        *  @return  @a string_type representing a currency symbol.
   1187       */
   1188       virtual string_type
   1189       do_curr_symbol()   const
   1190       { return _M_data->_M_curr_symbol; }
   1191 
   1192       /**
   1193        *  @brief  Return positive sign string.
   1194        *
   1195        *  This function returns a string_type to use as a sign for positive
   1196        *  amounts.  This function is a hook for derived classes to change the
   1197        *  value returned.  @see positive_sign() for details.
   1198        *
   1199        *  @return  @a string_type representing a positive sign.
   1200       */
   1201       virtual string_type
   1202       do_positive_sign() const
   1203       { return _M_data->_M_positive_sign; }
   1204 
   1205       /**
   1206        *  @brief  Return negative sign string.
   1207        *
   1208        *  This function returns a string_type to use as a sign for negative
   1209        *  amounts.  This function is a hook for derived classes to change the
   1210        *  value returned.  @see negative_sign() for details.
   1211        *
   1212        *  @return  @a string_type representing a negative sign.
   1213       */
   1214       virtual string_type
   1215       do_negative_sign() const
   1216       { return _M_data->_M_negative_sign; }
   1217 
   1218       /**
   1219        *  @brief  Return number of digits in fraction.
   1220        *
   1221        *  This function returns the exact number of digits that make up the
   1222        *  fractional part of a money amount.  This function is a hook for
   1223        *  derived classes to change the value returned.  @see frac_digits()
   1224        *  for details.
   1225        *
   1226        *  @return  Number of digits in amount fraction.
   1227       */
   1228       virtual int
   1229       do_frac_digits() const
   1230       { return _M_data->_M_frac_digits; }
   1231 
   1232       /**
   1233        *  @brief  Return pattern for money values.
   1234        *
   1235        *  This function returns a pattern describing the formatting of a
   1236        *  positive valued money amount.  This function is a hook for derived
   1237        *  classes to change the value returned.  @see pos_format() for
   1238        *  details.
   1239        *
   1240        *  @return  Pattern for money values.
   1241       */
   1242       virtual pattern
   1243       do_pos_format() const
   1244       { return _M_data->_M_pos_format; }
   1245 
   1246       /**
   1247        *  @brief  Return pattern for money values.
   1248        *
   1249        *  This function returns a pattern describing the formatting of a
   1250        *  negative valued money amount.  This function is a hook for derived
   1251        *  classes to change the value returned.  @see neg_format() for
   1252        *  details.
   1253        *
   1254        *  @return  Pattern for money values.
   1255       */
   1256       virtual pattern
   1257       do_neg_format() const
   1258       { return _M_data->_M_neg_format; }
   1259 
   1260       // For use at construction time only.
   1261        void
   1262        _M_initialize_moneypunct(__c_locale __cloc = NULL,
   1263 				const char* __name = NULL);
   1264     };
   1265 
   1266   template<typename _CharT, bool _Intl>
   1267     locale::id moneypunct<_CharT, _Intl>::id;
   1268 
   1269   template<typename _CharT, bool _Intl>
   1270     const bool moneypunct<_CharT, _Intl>::intl;
   1271 
   1272   template<>
   1273     moneypunct<char, true>::~moneypunct();
   1274 
   1275   template<>
   1276     moneypunct<char, false>::~moneypunct();
   1277 
   1278   template<>
   1279     void
   1280     moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
   1281 
   1282   template<>
   1283     void
   1284     moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
   1285 
   1286 #ifdef _GLIBCXX_USE_WCHAR_T
   1287   template<>
   1288     moneypunct<wchar_t, true>::~moneypunct();
   1289 
   1290   template<>
   1291     moneypunct<wchar_t, false>::~moneypunct();
   1292 
   1293   template<>
   1294     void
   1295     moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
   1296 							const char*);
   1297 
   1298   template<>
   1299     void
   1300     moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
   1301 							 const char*);
   1302 #endif
   1303 
   1304   /// class moneypunct_byname [22.2.6.4].
   1305   template<typename _CharT, bool _Intl>
   1306     class moneypunct_byname : public moneypunct<_CharT, _Intl>
   1307     {
   1308     public:
   1309       typedef _CharT			char_type;
   1310       typedef basic_string<_CharT>	string_type;
   1311 
   1312       static const bool intl = _Intl;
   1313 
   1314       explicit
   1315       moneypunct_byname(const char* __s, size_t __refs = 0)
   1316       : moneypunct<_CharT, _Intl>(__refs)
   1317       {
   1318 	if (__builtin_strcmp(__s, "C") != 0
   1319 	    && __builtin_strcmp(__s, "POSIX") != 0)
   1320 	  {
   1321 	    __c_locale __tmp;
   1322 	    this->_S_create_c_locale(__tmp, __s);
   1323 	    this->_M_initialize_moneypunct(__tmp);
   1324 	    this->_S_destroy_c_locale(__tmp);
   1325 	  }
   1326       }
   1327 
   1328     protected:
   1329       virtual
   1330       ~moneypunct_byname() { }
   1331     };
   1332 
   1333   template<typename _CharT, bool _Intl>
   1334     const bool moneypunct_byname<_CharT, _Intl>::intl;
   1335 
   1336 _GLIBCXX_BEGIN_LDBL_NAMESPACE
   1337 
   1338   /**
   1339    *  @brief  Facet for parsing monetary amounts.
   1340    *
   1341    *  This facet encapsulates the code to parse and return a monetary
   1342    *  amount from a string.
   1343    *
   1344    *  The money_get template uses protected virtual functions to
   1345    *  provide the actual results.  The public accessors forward the
   1346    *  call to the virtual functions.  These virtual functions are
   1347    *  hooks for developers to implement the behavior they require from
   1348    *  the money_get facet.
   1349   */
   1350   template<typename _CharT, typename _InIter>
   1351     class money_get : public locale::facet
   1352     {
   1353     public:
   1354       // Types:
   1355       //@{
   1356       /// Public typedefs
   1357       typedef _CharT			char_type;
   1358       typedef _InIter			iter_type;
   1359       typedef basic_string<_CharT>	string_type;
   1360       //@}
   1361 
   1362       /// Numpunct facet id.
   1363       static locale::id			id;
   1364 
   1365       /**
   1366        *  @brief  Constructor performs initialization.
   1367        *
   1368        *  This is the constructor provided by the standard.
   1369        *
   1370        *  @param refs  Passed to the base facet class.
   1371       */
   1372       explicit
   1373       money_get(size_t __refs = 0) : facet(__refs) { }
   1374 
   1375       /**
   1376        *  @brief  Read and parse a monetary value.
   1377        *
   1378        *  This function reads characters from @a s, interprets them as a
   1379        *  monetary value according to moneypunct and ctype facets retrieved
   1380        *  from io.getloc(), and returns the result in @a units as an integral
   1381        *  value moneypunct::frac_digits() * the actual amount.  For example,
   1382        *  the string $10.01 in a US locale would store 1001 in @a units.
   1383        *
   1384        *  Any characters not part of a valid money amount are not consumed.
   1385        *
   1386        *  If a money value cannot be parsed from the input stream, sets
   1387        *  err=(err|io.failbit).  If the stream is consumed before finishing
   1388        *  parsing,  sets err=(err|io.failbit|io.eofbit).  @a units is
   1389        *  unchanged if parsing fails.
   1390        *
   1391        *  This function works by returning the result of do_get().
   1392        *
   1393        *  @param  s  Start of characters to parse.
   1394        *  @param  end  End of characters to parse.
   1395        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
   1396        *  @param  io  Source of facets and io state.
   1397        *  @param  err  Error field to set if parsing fails.
   1398        *  @param  units  Place to store result of parsing.
   1399        *  @return  Iterator referencing first character beyond valid money
   1400        *	   amount.
   1401        */
   1402       iter_type
   1403       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
   1404 	  ios_base::iostate& __err, long double& __units) const
   1405       { return this->do_get(__s, __end, __intl, __io, __err, __units); }
   1406 
   1407       /**
   1408        *  @brief  Read and parse a monetary value.
   1409        *
   1410        *  This function reads characters from @a s, interprets them as a
   1411        *  monetary value according to moneypunct and ctype facets retrieved
   1412        *  from io.getloc(), and returns the result in @a digits.  For example,
   1413        *  the string $10.01 in a US locale would store "1001" in @a digits.
   1414        *
   1415        *  Any characters not part of a valid money amount are not consumed.
   1416        *
   1417        *  If a money value cannot be parsed from the input stream, sets
   1418        *  err=(err|io.failbit).  If the stream is consumed before finishing
   1419        *  parsing,  sets err=(err|io.failbit|io.eofbit).
   1420        *
   1421        *  This function works by returning the result of do_get().
   1422        *
   1423        *  @param  s  Start of characters to parse.
   1424        *  @param  end  End of characters to parse.
   1425        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
   1426        *  @param  io  Source of facets and io state.
   1427        *  @param  err  Error field to set if parsing fails.
   1428        *  @param  digits  Place to store result of parsing.
   1429        *  @return  Iterator referencing first character beyond valid money
   1430        *	   amount.
   1431        */
   1432       iter_type
   1433       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
   1434 	  ios_base::iostate& __err, string_type& __digits) const
   1435       { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
   1436 
   1437     protected:
   1438       /// Destructor.
   1439       virtual
   1440       ~money_get() { }
   1441 
   1442       /**
   1443        *  @brief  Read and parse a monetary value.
   1444        *
   1445        *  This function reads and parses characters representing a monetary
   1446        *  value.  This function is a hook for derived classes to change the
   1447        *  value returned.  @see get() for details.
   1448        */
   1449       // XXX GLIBCXX_ABI Deprecated
   1450 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
   1451       virtual iter_type
   1452       __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
   1453 	       ios_base::iostate& __err, double& __units) const;
   1454 #else
   1455       virtual iter_type
   1456       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
   1457 	     ios_base::iostate& __err, long double& __units) const;
   1458 #endif
   1459 
   1460       /**
   1461        *  @brief  Read and parse a monetary value.
   1462        *
   1463        *  This function reads and parses characters representing a monetary
   1464        *  value.  This function is a hook for derived classes to change the
   1465        *  value returned.  @see get() for details.
   1466        */
   1467       virtual iter_type
   1468       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
   1469 	     ios_base::iostate& __err, string_type& __digits) const;
   1470 
   1471       // XXX GLIBCXX_ABI Deprecated
   1472 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
   1473       virtual iter_type
   1474       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
   1475 	     ios_base::iostate& __err, long double& __units) const;
   1476 #endif
   1477 
   1478       template<bool _Intl>
   1479         iter_type
   1480         _M_extract(iter_type __s, iter_type __end, ios_base& __io,
   1481 		   ios_base::iostate& __err, string& __digits) const;
   1482     };
   1483 
   1484   template<typename _CharT, typename _InIter>
   1485     locale::id money_get<_CharT, _InIter>::id;
   1486 
   1487   /**
   1488    *  @brief  Facet for outputting monetary amounts.
   1489    *
   1490    *  This facet encapsulates the code to format and output a monetary
   1491    *  amount.
   1492    *
   1493    *  The money_put template uses protected virtual functions to
   1494    *  provide the actual results.  The public accessors forward the
   1495    *  call to the virtual functions.  These virtual functions are
   1496    *  hooks for developers to implement the behavior they require from
   1497    *  the money_put facet.
   1498   */
   1499   template<typename _CharT, typename _OutIter>
   1500     class money_put : public locale::facet
   1501     {
   1502     public:
   1503       //@{
   1504       /// Public typedefs
   1505       typedef _CharT			char_type;
   1506       typedef _OutIter			iter_type;
   1507       typedef basic_string<_CharT>	string_type;
   1508       //@}
   1509 
   1510       /// Numpunct facet id.
   1511       static locale::id			id;
   1512 
   1513       /**
   1514        *  @brief  Constructor performs initialization.
   1515        *
   1516        *  This is the constructor provided by the standard.
   1517        *
   1518        *  @param refs  Passed to the base facet class.
   1519       */
   1520       explicit
   1521       money_put(size_t __refs = 0) : facet(__refs) { }
   1522 
   1523       /**
   1524        *  @brief  Format and output a monetary value.
   1525        *
   1526        *  This function formats @a units as a monetary value according to
   1527        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
   1528        *  the resulting characters to @a s.  For example, the value 1001 in a
   1529        *  US locale would write "$10.01" to @a s.
   1530        *
   1531        *  This function works by returning the result of do_put().
   1532        *
   1533        *  @param  s  The stream to write to.
   1534        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
   1535        *  @param  io  Source of facets and io state.
   1536        *  @param  fill  char_type to use for padding.
   1537        *  @param  units  Place to store result of parsing.
   1538        *  @return  Iterator after writing.
   1539        */
   1540       iter_type
   1541       put(iter_type __s, bool __intl, ios_base& __io,
   1542 	  char_type __fill, long double __units) const
   1543       { return this->do_put(__s, __intl, __io, __fill, __units); }
   1544 
   1545       /**
   1546        *  @brief  Format and output a monetary value.
   1547        *
   1548        *  This function formats @a digits as a monetary value according to
   1549        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
   1550        *  the resulting characters to @a s.  For example, the string "1001" in
   1551        *  a US locale would write "$10.01" to @a s.
   1552        *
   1553        *  This function works by returning the result of do_put().
   1554        *
   1555        *  @param  s  The stream to write to.
   1556        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
   1557        *  @param  io  Source of facets and io state.
   1558        *  @param  fill  char_type to use for padding.
   1559        *  @param  units  Place to store result of parsing.
   1560        *  @return  Iterator after writing.
   1561        */
   1562       iter_type
   1563       put(iter_type __s, bool __intl, ios_base& __io,
   1564 	  char_type __fill, const string_type& __digits) const
   1565       { return this->do_put(__s, __intl, __io, __fill, __digits); }
   1566 
   1567     protected:
   1568       /// Destructor.
   1569       virtual
   1570       ~money_put() { }
   1571 
   1572       /**
   1573        *  @brief  Format and output a monetary value.
   1574        *
   1575        *  This function formats @a units as a monetary value according to
   1576        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
   1577        *  the resulting characters to @a s.  For example, the value 1001 in a
   1578        *  US locale would write "$10.01" to @a s.
   1579        *
   1580        *  This function is a hook for derived classes to change the value
   1581        *  returned.  @see put().
   1582        *
   1583        *  @param  s  The stream to write to.
   1584        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
   1585        *  @param  io  Source of facets and io state.
   1586        *  @param  fill  char_type to use for padding.
   1587        *  @param  units  Place to store result of parsing.
   1588        *  @return  Iterator after writing.
   1589        */
   1590       // XXX GLIBCXX_ABI Deprecated
   1591 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
   1592       virtual iter_type
   1593       __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
   1594 	       double __units) const;
   1595 #else
   1596       virtual iter_type
   1597       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
   1598 	     long double __units) const;
   1599 #endif
   1600 
   1601       /**
   1602        *  @brief  Format and output a monetary value.
   1603        *
   1604        *  This function formats @a digits as a monetary value according to
   1605        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
   1606        *  the resulting characters to @a s.  For example, the string "1001" in
   1607        *  a US locale would write "$10.01" to @a s.
   1608        *
   1609        *  This function is a hook for derived classes to change the value
   1610        *  returned.  @see put().
   1611        *
   1612        *  @param  s  The stream to write to.
   1613        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
   1614        *  @param  io  Source of facets and io state.
   1615        *  @param  fill  char_type to use for padding.
   1616        *  @param  units  Place to store result of parsing.
   1617        *  @return  Iterator after writing.
   1618        */
   1619       virtual iter_type
   1620       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
   1621 	     const string_type& __digits) const;
   1622 
   1623       // XXX GLIBCXX_ABI Deprecated
   1624 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
   1625       virtual iter_type
   1626       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
   1627 	     long double __units) const;
   1628 #endif
   1629 
   1630       template<bool _Intl>
   1631         iter_type
   1632         _M_insert(iter_type __s, ios_base& __io, char_type __fill,
   1633 		  const string_type& __digits) const;
   1634     };
   1635 
   1636   template<typename _CharT, typename _OutIter>
   1637     locale::id money_put<_CharT, _OutIter>::id;
   1638 
   1639 _GLIBCXX_END_LDBL_NAMESPACE
   1640 
   1641   /**
   1642    *  @brief  Messages facet base class providing catalog typedef.
   1643    */
   1644   struct messages_base
   1645   {
   1646     typedef int catalog;
   1647   };
   1648 
   1649   /**
   1650    *  @brief  Facet for handling message catalogs
   1651    *
   1652    *  This facet encapsulates the code to retrieve messages from
   1653    *  message catalogs.  The only thing defined by the standard for this facet
   1654    *  is the interface.  All underlying functionality is
   1655    *  implementation-defined.
   1656    *
   1657    *  This library currently implements 3 versions of the message facet.  The
   1658    *  first version (gnu) is a wrapper around gettext, provided by libintl.
   1659    *  The second version (ieee) is a wrapper around catgets.  The final
   1660    *  version (default) does no actual translation.  These implementations are
   1661    *  only provided for char and wchar_t instantiations.
   1662    *
   1663    *  The messages template uses protected virtual functions to
   1664    *  provide the actual results.  The public accessors forward the
   1665    *  call to the virtual functions.  These virtual functions are
   1666    *  hooks for developers to implement the behavior they require from
   1667    *  the messages facet.
   1668   */
   1669   template<typename _CharT>
   1670     class messages : public locale::facet, public messages_base
   1671     {
   1672     public:
   1673       // Types:
   1674       //@{
   1675       /// Public typedefs
   1676       typedef _CharT			char_type;
   1677       typedef basic_string<_CharT>	string_type;
   1678       //@}
   1679 
   1680     protected:
   1681       // Underlying "C" library locale information saved from
   1682       // initialization, needed by messages_byname as well.
   1683       __c_locale			_M_c_locale_messages;
   1684       const char*			_M_name_messages;
   1685 
   1686     public:
   1687       /// Numpunct facet id.
   1688       static locale::id			id;
   1689 
   1690       /**
   1691        *  @brief  Constructor performs initialization.
   1692        *
   1693        *  This is the constructor provided by the standard.
   1694        *
   1695        *  @param refs  Passed to the base facet class.
   1696       */
   1697       explicit
   1698       messages(size_t __refs = 0);
   1699 
   1700       // Non-standard.
   1701       /**
   1702        *  @brief  Internal constructor.  Not for general use.
   1703        *
   1704        *  This is a constructor for use by the library itself to set up new
   1705        *  locales.
   1706        *
   1707        *  @param  cloc  The "C" locale.
   1708        *  @param  s  The name of a locale.
   1709        *  @param  refs  Refcount to pass to the base class.
   1710        */
   1711       explicit
   1712       messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
   1713 
   1714       /*
   1715        *  @brief  Open a message catalog.
   1716        *
   1717        *  This function opens and returns a handle to a message catalog by
   1718        *  returning do_open(s, loc).
   1719        *
   1720        *  @param  s  The catalog to open.
   1721        *  @param  loc  Locale to use for character set conversions.
   1722        *  @return  Handle to the catalog or value < 0 if open fails.
   1723       */
   1724       catalog
   1725       open(const basic_string<char>& __s, const locale& __loc) const
   1726       { return this->do_open(__s, __loc); }
   1727 
   1728       // Non-standard and unorthodox, yet effective.
   1729       /*
   1730        *  @brief  Open a message catalog.
   1731        *
   1732        *  This non-standard function opens and returns a handle to a message
   1733        *  catalog by returning do_open(s, loc).  The third argument provides a
   1734        *  message catalog root directory for gnu gettext and is ignored
   1735        *  otherwise.
   1736        *
   1737        *  @param  s  The catalog to open.
   1738        *  @param  loc  Locale to use for character set conversions.
   1739        *  @param  dir  Message catalog root directory.
   1740        *  @return  Handle to the catalog or value < 0 if open fails.
   1741       */
   1742       catalog
   1743       open(const basic_string<char>&, const locale&, const char*) const;
   1744 
   1745       /*
   1746        *  @brief  Look up a string in a message catalog.
   1747        *
   1748        *  This function retrieves and returns a message from a catalog by
   1749        *  returning do_get(c, set, msgid, s).
   1750        *
   1751        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
   1752        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
   1753        *
   1754        *  @param  c  The catalog to access.
   1755        *  @param  set  Implementation-defined.
   1756        *  @param  msgid  Implementation-defined.
   1757        *  @param  s  Default return value if retrieval fails.
   1758        *  @return  Retrieved message or @a s if get fails.
   1759       */
   1760       string_type
   1761       get(catalog __c, int __set, int __msgid, const string_type& __s) const
   1762       { return this->do_get(__c, __set, __msgid, __s); }
   1763 
   1764       /*
   1765        *  @brief  Close a message catalog.
   1766        *
   1767        *  Closes catalog @a c by calling do_close(c).
   1768        *
   1769        *  @param  c  The catalog to close.
   1770       */
   1771       void
   1772       close(catalog __c) const
   1773       { return this->do_close(__c); }
   1774 
   1775     protected:
   1776       /// Destructor.
   1777       virtual
   1778       ~messages();
   1779 
   1780       /*
   1781        *  @brief  Open a message catalog.
   1782        *
   1783        *  This function opens and returns a handle to a message catalog in an
   1784        *  implementation-defined manner.  This function is a hook for derived
   1785        *  classes to change the value returned.
   1786        *
   1787        *  @param  s  The catalog to open.
   1788        *  @param  loc  Locale to use for character set conversions.
   1789        *  @return  Handle to the opened catalog, value < 0 if open failed.
   1790       */
   1791       virtual catalog
   1792       do_open(const basic_string<char>&, const locale&) const;
   1793 
   1794       /*
   1795        *  @brief  Look up a string in a message catalog.
   1796        *
   1797        *  This function retrieves and returns a message from a catalog in an
   1798        *  implementation-defined manner.  This function is a hook for derived
   1799        *  classes to change the value returned.
   1800        *
   1801        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
   1802        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
   1803        *
   1804        *  @param  c  The catalog to access.
   1805        *  @param  set  Implementation-defined.
   1806        *  @param  msgid  Implementation-defined.
   1807        *  @param  s  Default return value if retrieval fails.
   1808        *  @return  Retrieved message or @a s if get fails.
   1809       */
   1810       virtual string_type
   1811       do_get(catalog, int, int, const string_type& __dfault) const;
   1812 
   1813       /*
   1814        *  @brief  Close a message catalog.
   1815        *
   1816        *  @param  c  The catalog to close.
   1817       */
   1818       virtual void
   1819       do_close(catalog) const;
   1820 
   1821       // Returns a locale and codeset-converted string, given a char* message.
   1822       char*
   1823       _M_convert_to_char(const string_type& __msg) const
   1824       {
   1825 	// XXX
   1826 	return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
   1827       }
   1828 
   1829       // Returns a locale and codeset-converted string, given a char* message.
   1830       string_type
   1831       _M_convert_from_char(char*) const
   1832       {
   1833 #if 0
   1834 	// Length of message string without terminating null.
   1835 	size_t __len = char_traits<char>::length(__msg) - 1;
   1836 
   1837 	// "everybody can easily convert the string using
   1838 	// mbsrtowcs/wcsrtombs or with iconv()"
   1839 
   1840 	// Convert char* to _CharT in locale used to open catalog.
   1841 	// XXX need additional template parameter on messages class for this..
   1842 	// typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
   1843 	typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
   1844 
   1845 	__codecvt_type::state_type __state;
   1846 	// XXX may need to initialize state.
   1847 	//initialize_state(__state._M_init());
   1848 
   1849 	char* __from_next;
   1850 	// XXX what size for this string?
   1851 	_CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
   1852 	const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
   1853 	__cvt.out(__state, __msg, __msg + __len, __from_next,
   1854 		  __to, __to + __len + 1, __to_next);
   1855 	return string_type(__to);
   1856 #endif
   1857 #if 0
   1858 	typedef ctype<_CharT> __ctype_type;
   1859 	// const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
   1860 	const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
   1861 	// XXX Again, proper length of converted string an issue here.
   1862 	// For now, assume the converted length is not larger.
   1863 	_CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
   1864 	__cvt.widen(__msg, __msg + __len, __dest);
   1865 	return basic_string<_CharT>(__dest);
   1866 #endif
   1867 	return string_type();
   1868       }
   1869      };
   1870 
   1871   template<typename _CharT>
   1872     locale::id messages<_CharT>::id;
   1873 
   1874   // Specializations for required instantiations.
   1875   template<>
   1876     string
   1877     messages<char>::do_get(catalog, int, int, const string&) const;
   1878 
   1879 #ifdef _GLIBCXX_USE_WCHAR_T
   1880   template<>
   1881     wstring
   1882     messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
   1883 #endif
   1884 
   1885    /// class messages_byname [22.2.7.2].
   1886    template<typename _CharT>
   1887     class messages_byname : public messages<_CharT>
   1888     {
   1889     public:
   1890       typedef _CharT			char_type;
   1891       typedef basic_string<_CharT>	string_type;
   1892 
   1893       explicit
   1894       messages_byname(const char* __s, size_t __refs = 0);
   1895 
   1896     protected:
   1897       virtual
   1898       ~messages_byname()
   1899       { }
   1900     };
   1901 
   1902 _GLIBCXX_END_NAMESPACE
   1903 
   1904 // Include host and configuration specific messages functions.
   1905 #include <bits/messages_members.h>
   1906 
   1907 // 22.2.1.5  Template class codecvt
   1908 #include <bits/codecvt.h>
   1909 
   1910 #ifndef _GLIBCXX_EXPORT_TEMPLATE
   1911 # include <bits/locale_facets_nonio.tcc>
   1912 #endif
   1913 
   1914 #endif
   1915