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, 2004, 2005
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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 
00035 /** @file locale_facets.h
00036  *  This is an internal header file, included by other library headers.
00037  *  You should not attempt to use it directly.
00038  */
00039 
00040 #ifndef _LOCALE_FACETS_H
00041 #define _LOCALE_FACETS_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 _GLIBCXX_USE_WCHAR_T
00055 # define  _GLIBCXX_NUM_FACETS 28
00056 #else
00057 # define  _GLIBCXX_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);
00067 
00068   // Explicit specializations for required types.
00069   template<>
00070     void
00071     __convert_to_v(const char*, float&, ios_base::iostate&,
00072            const __c_locale&);
00073 
00074   template<>
00075     void
00076     __convert_to_v(const char*, double&, ios_base::iostate&,
00077            const __c_locale&);
00078 
00079   template<>
00080     void
00081     __convert_to_v(const char*, long double&, ios_base::iostate&,
00082            const __c_locale&);
00083 
00084   // NB: __pad is a struct, rather than a function, so it can be
00085   // partially-specialized.
00086   template<typename _CharT, typename _Traits>
00087     struct __pad
00088     {
00089       static void
00090       _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
00091          const _CharT* __olds, const streamsize __newlen,
00092          const streamsize __oldlen, const bool __num);
00093     };
00094 
00095   // Used by both numeric and monetary facets.
00096   // Inserts "group separator" characters into an array of characters.
00097   // It's recursive, one iteration per group.  It moves the characters
00098   // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
00099   // only with __glen != 0.
00100   template<typename _CharT>
00101     _CharT*
00102     __add_grouping(_CharT* __s, _CharT __sep,
00103            const char* __gbeg, size_t __gsize,
00104            const _CharT* __first, const _CharT* __last);
00105 
00106   // This template permits specializing facet output code for
00107   // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
00108   // significantly more efficient than incrementing iterators.
00109   template<typename _CharT>
00110     inline
00111     ostreambuf_iterator<_CharT>
00112     __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
00113     {
00114       __s._M_put(__ws, __len);
00115       return __s;
00116     }
00117 
00118   // This is the unspecialized form of the template.
00119   template<typename _CharT, typename _OutIter>
00120     inline
00121     _OutIter
00122     __write(_OutIter __s, const _CharT* __ws, int __len)
00123     {
00124       for (int __j = 0; __j < __len; __j++, ++__s)
00125     *__s = __ws[__j];
00126       return __s;
00127     }
00128 
00129 
00130   // 22.2.1.1  Template class ctype
00131   // Include host and configuration specific ctype enums for ctype_base.
00132   #include <bits/ctype_base.h>
00133 
00134   // Common base for ctype<_CharT>.
00135   /**
00136    *  @brief  Common base for ctype facet
00137    *
00138    *  This template class provides implementations of the public functions
00139    *  that forward to the protected virtual functions.
00140    *
00141    *  This template also provides abtract stubs for the protected virtual
00142    *  functions.
00143   */
00144   template<typename _CharT>
00145     class __ctype_abstract_base : public locale::facet, public ctype_base
00146     {
00147     public:
00148       // Types:
00149       /// Typedef for the template parameter
00150       typedef _CharT char_type;
00151 
00152       /**
00153        *  @brief  Test char_type classification.
00154        *
00155        *  This function finds a mask M for @a c and compares it to mask @a m.
00156        *  It does so by returning the value of ctype<char_type>::do_is().
00157        *
00158        *  @param c  The char_type to compare the mask of.
00159        *  @param m  The mask to compare against.
00160        *  @return  (M & m) != 0.
00161       */
00162       bool
00163       is(mask __m, char_type __c) const
00164       { return this->do_is(__m, __c); }
00165 
00166       /**
00167        *  @brief  Return a mask array.
00168        *
00169        *  This function finds the mask for each char_type in the range [lo,hi)
00170        *  and successively writes it to vec.  vec must have as many elements
00171        *  as the char array.  It does so by returning the value of
00172        *  ctype<char_type>::do_is().
00173        *
00174        *  @param lo  Pointer to start of range.
00175        *  @param hi  Pointer to end of range.
00176        *  @param vec  Pointer to an array of mask storage.
00177        *  @return  @a hi.
00178       */
00179       const char_type*
00180       is(const char_type *__lo, const char_type *__hi, mask *__vec) const
00181       { return this->do_is(__lo, __hi, __vec); }
00182 
00183       /**
00184        *  @brief  Find char_type matching a mask
00185        *
00186        *  This function searches for and returns the first char_type c in
00187        *  [lo,hi) for which is(m,c) is true.  It does so by returning
00188        *  ctype<char_type>::do_scan_is().
00189        *
00190        *  @param m  The mask to compare against.
00191        *  @param lo  Pointer to start of range.
00192        *  @param hi  Pointer to end of range.
00193        *  @return  Pointer to matching char_type if found, else @a hi.
00194       */
00195       const char_type*
00196       scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
00197       { return this->do_scan_is(__m, __lo, __hi); }
00198 
00199       /**
00200        *  @brief  Find char_type not matching a mask
00201        *
00202        *  This function searches for and returns the first char_type c in
00203        *  [lo,hi) for which is(m,c) is false.  It does so by returning
00204        *  ctype<char_type>::do_scan_not().
00205        *
00206        *  @param m  The mask to compare against.
00207        *  @param lo  Pointer to first char in range.
00208        *  @param hi  Pointer to end of range.
00209        *  @return  Pointer to non-matching char if found, else @a hi.
00210       */
00211       const char_type*
00212       scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
00213       { return this->do_scan_not(__m, __lo, __hi); }
00214 
00215       /**
00216        *  @brief  Convert to uppercase.
00217        *
00218        *  This function converts the argument to uppercase if possible.
00219        *  If not possible (for example, '2'), returns the argument.  It does
00220        *  so by returning ctype<char_type>::do_toupper().
00221        *
00222        *  @param c  The char_type to convert.
00223        *  @return  The uppercase char_type if convertible, else @a c.
00224       */
00225       char_type
00226       toupper(char_type __c) const
00227       { return this->do_toupper(__c); }
00228 
00229       /**
00230        *  @brief  Convert array to uppercase.
00231        *
00232        *  This function converts each char_type in the range [lo,hi) to
00233        *  uppercase if possible.  Other elements remain untouched.  It does so
00234        *  by returning ctype<char_type>:: do_toupper(lo, hi).
00235        *
00236        *  @param lo  Pointer to start of range.
00237        *  @param hi  Pointer to end of range.
00238        *  @return  @a hi.
00239       */
00240       const char_type*
00241       toupper(char_type *__lo, const char_type* __hi) const
00242       { return this->do_toupper(__lo, __hi); }
00243 
00244       /**
00245        *  @brief  Convert to lowercase.
00246        *
00247        *  This function converts the argument to lowercase if possible.  If
00248        *  not possible (for example, '2'), returns the argument.  It does so
00249        *  by returning ctype<char_type>::do_tolower(c).
00250        *
00251        *  @param c  The char_type to convert.
00252        *  @return  The lowercase char_type if convertible, else @a c.
00253       */
00254       char_type
00255       tolower(char_type __c) const
00256       { return this->do_tolower(__c); }
00257 
00258       /**
00259        *  @brief  Convert array to lowercase.
00260        *
00261        *  This function converts each char_type in the range [lo,hi) to
00262        *  lowercase if possible.  Other elements remain untouched.  It does so
00263        *  by returning ctype<char_type>:: do_tolower(lo, hi).
00264        *
00265        *  @param lo  Pointer to start of range.
00266        *  @param hi  Pointer to end of range.
00267        *  @return  @a hi.
00268       */
00269       const char_type*
00270       tolower(char_type* __lo, const char_type* __hi) const
00271       { return this->do_tolower(__lo, __hi); }
00272 
00273       /**
00274        *  @brief  Widen char to char_type
00275        *
00276        *  This function converts the char argument to char_type using the
00277        *  simplest reasonable transformation.  It does so by returning
00278        *  ctype<char_type>::do_widen(c).
00279        *
00280        *  Note: this is not what you want for codepage conversions.  See
00281        *  codecvt for that.
00282        *
00283        *  @param c  The char to convert.
00284        *  @return  The converted char_type.
00285       */
00286       char_type
00287       widen(char __c) const
00288       { return this->do_widen(__c); }
00289 
00290       /**
00291        *  @brief  Widen array to char_type
00292        *
00293        *  This function converts each char in the input to char_type using the
00294        *  simplest reasonable transformation.  It does so by returning
00295        *  ctype<char_type>::do_widen(c).
00296        *
00297        *  Note: this is not what you want for codepage conversions.  See
00298        *  codecvt for that.
00299        *
00300        *  @param lo  Pointer to start of range.
00301        *  @param hi  Pointer to end of range.
00302        *  @param to  Pointer to the destination array.
00303        *  @return  @a hi.
00304       */
00305       const char*
00306       widen(const char* __lo, const char* __hi, char_type* __to) const
00307       { return this->do_widen(__lo, __hi, __to); }
00308 
00309       /**
00310        *  @brief  Narrow char_type to char
00311        *
00312        *  This function converts the char_type to char using the simplest
00313        *  reasonable transformation.  If the conversion fails, dfault is
00314        *  returned instead.  It does so by returning
00315        *  ctype<char_type>::do_narrow(c).
00316        *
00317        *  Note: this is not what you want for codepage conversions.  See
00318        *  codecvt for that.
00319        *
00320        *  @param c  The char_type to convert.
00321        *  @param dfault  Char to return if conversion fails.
00322        *  @return  The converted char.
00323       */
00324       char
00325       narrow(char_type __c, char __dfault) const
00326       { return this->do_narrow(__c, __dfault); }
00327 
00328       /**
00329        *  @brief  Narrow array to char array
00330        *
00331        *  This function converts each char_type in the input to char using the
00332        *  simplest reasonable transformation and writes the results to the
00333        *  destination array.  For any char_type in the input that cannot be
00334        *  converted, @a dfault is used instead.  It does so by returning
00335        *  ctype<char_type>::do_narrow(lo, hi, dfault, to).
00336        *
00337        *  Note: this is not what you want for codepage conversions.  See
00338        *  codecvt for that.
00339        *
00340        *  @param lo  Pointer to start of range.
00341        *  @param hi  Pointer to end of range.
00342        *  @param dfault  Char to use if conversion fails.
00343        *  @param to  Pointer to the destination array.
00344        *  @return  @a hi.
00345       */
00346       const char_type*
00347       narrow(const char_type* __lo, const char_type* __hi,
00348           char __dfault, char *__to) const
00349       { return this->do_narrow(__lo, __hi, __dfault, __to); }
00350 
00351     protected:
00352       explicit
00353       __ctype_abstract_base(size_t __refs = 0): facet(__refs) { }
00354 
00355       virtual
00356       ~__ctype_abstract_base() { }
00357 
00358       /**
00359        *  @brief  Test char_type classification.
00360        *
00361        *  This function finds a mask M for @a c and compares it to mask @a m.
00362        *
00363        *  do_is() is a hook for a derived facet to change the behavior of
00364        *  classifying.  do_is() must always return the same result for the
00365        *  same input.
00366        *
00367        *  @param c  The char_type to find the mask of.
00368        *  @param m  The mask to compare against.
00369        *  @return  (M & m) != 0.
00370       */
00371       virtual bool
00372       do_is(mask __m, char_type __c) const = 0;
00373 
00374       /**
00375        *  @brief  Return a mask array.
00376        *
00377        *  This function finds the mask for each char_type in the range [lo,hi)
00378        *  and successively writes it to vec.  vec must have as many elements
00379        *  as the input.
00380        *
00381        *  do_is() is a hook for a derived facet to change the behavior of
00382        *  classifying.  do_is() must always return the same result for the
00383        *  same input.
00384        *
00385        *  @param lo  Pointer to start of range.
00386        *  @param hi  Pointer to end of range.
00387        *  @param vec  Pointer to an array of mask storage.
00388        *  @return  @a hi.
00389       */
00390       virtual const char_type*
00391       do_is(const char_type* __lo, const char_type* __hi,
00392         mask* __vec) const = 0;
00393 
00394       /**
00395        *  @brief  Find char_type matching mask
00396        *
00397        *  This function searches for and returns the first char_type c in
00398        *  [lo,hi) for which is(m,c) is true.
00399        *
00400        *  do_scan_is() is a hook for a derived facet to change the behavior of
00401        *  match searching.  do_is() must always return the same result for the
00402        *  same input.
00403        *
00404        *  @param m  The mask to compare against.
00405        *  @param lo  Pointer to start of range.
00406        *  @param hi  Pointer to end of range.
00407        *  @return  Pointer to a matching char_type if found, else @a hi.
00408       */
00409       virtual const char_type*
00410       do_scan_is(mask __m, const char_type* __lo,
00411          const char_type* __hi) const = 0;
00412 
00413       /**
00414        *  @brief  Find char_type not matching mask
00415        *
00416        *  This function searches for and returns a pointer to the first
00417        *  char_type c of [lo,hi) for which is(m,c) is false.
00418        *
00419        *  do_scan_is() is a hook for a derived facet to change the behavior of
00420        *  match searching.  do_is() must always return the same result for the
00421        *  same input.
00422        *
00423        *  @param m  The mask to compare against.
00424        *  @param lo  Pointer to start of range.
00425        *  @param hi  Pointer to end of range.
00426        *  @return  Pointer to a non-matching char_type if found, else @a hi.
00427       */
00428       virtual const char_type*
00429       do_scan_not(mask __m, const char_type* __lo,
00430           const char_type* __hi) const = 0;
00431 
00432       /**
00433        *  @brief  Convert to uppercase.
00434        *
00435        *  This virtual function converts the char_type argument to uppercase
00436        *  if possible.  If not possible (for example, '2'), returns the
00437        *  argument.
00438        *
00439        *  do_toupper() is a hook for a derived facet to change the behavior of
00440        *  uppercasing.  do_toupper() must always return the same result for
00441        *  the same input.
00442        *
00443        *  @param c  The char_type to convert.
00444        *  @return  The uppercase char_type if convertible, else @a c.
00445       */
00446       virtual char_type
00447       do_toupper(char_type) const = 0;
00448 
00449       /**
00450        *  @brief  Convert array to uppercase.
00451        *
00452        *  This virtual function converts each char_type in the range [lo,hi)
00453        *  to uppercase if possible.  Other elements remain untouched.
00454        *
00455        *  do_toupper() is a hook for a derived facet to change the behavior of
00456        *  uppercasing.  do_toupper() must always return the same result for
00457        *  the same input.
00458        *
00459        *  @param lo  Pointer to start of range.
00460        *  @param hi  Pointer to end of range.
00461        *  @return  @a hi.
00462       */
00463       virtual const char_type*
00464       do_toupper(char_type* __lo, const char_type* __hi) const = 0;
00465 
00466       /**
00467        *  @brief  Convert to lowercase.
00468        *
00469        *  This virtual function converts the argument to lowercase if
00470        *  possible.  If not possible (for example, '2'), returns the argument.
00471        *
00472        *  do_tolower() is a hook for a derived facet to change the behavior of
00473        *  lowercasing.  do_tolower() must always return the same result for
00474        *  the same input.
00475        *
00476        *  @param c  The char_type to convert.
00477        *  @return  The lowercase char_type if convertible, else @a c.
00478       */
00479       virtual char_type
00480       do_tolower(char_type) const = 0;
00481 
00482       /**
00483        *  @brief  Convert array to lowercase.
00484        *
00485        *  This virtual function converts each char_type in the range [lo,hi)
00486        *  to lowercase if possible.  Other elements remain untouched.
00487        *
00488        *  do_tolower() is a hook for a derived facet to change the behavior of
00489        *  lowercasing.  do_tolower() must always return the same result for
00490        *  the same input.
00491        *
00492        *  @param lo  Pointer to start of range.
00493        *  @param hi  Pointer to end of range.
00494        *  @return  @a hi.
00495       */
00496       virtual const char_type*
00497       do_tolower(char_type* __lo, const char_type* __hi) const = 0;
00498 
00499       /**
00500        *  @brief  Widen char
00501        *
00502        *  This virtual function converts the char to char_type using the
00503        *  simplest reasonable transformation.
00504        *
00505        *  do_widen() is a hook for a derived facet to change the behavior of
00506        *  widening.  do_widen() must always return the same result for the
00507        *  same input.
00508        *
00509        *  Note: this is not what you want for codepage conversions.  See
00510        *  codecvt for that.
00511        *
00512        *  @param c  The char to convert.
00513        *  @return  The converted char_type
00514       */
00515       virtual char_type
00516       do_widen(char) const = 0;
00517 
00518       /**
00519        *  @brief  Widen char array
00520        *
00521        *  This function converts each char in the input to char_type using the
00522        *  simplest reasonable transformation.
00523        *
00524        *  do_widen() is a hook for a derived facet to change the behavior of
00525        *  widening.  do_widen() must always return the same result for the
00526        *  same input.
00527        *
00528        *  Note: this is not what you want for codepage conversions.  See
00529        *  codecvt for that.
00530        *
00531        *  @param lo  Pointer to start range.
00532        *  @param hi  Pointer to end of range.
00533        *  @param to  Pointer to the destination array.
00534        *  @return  @a hi.
00535       */
00536       virtual const char*
00537       do_widen(const char* __lo, const char* __hi,
00538            char_type* __dest) const = 0;
00539 
00540       /**
00541        *  @brief  Narrow char_type to char
00542        *
00543        *  This virtual function converts the argument to char using the
00544        *  simplest reasonable transformation.  If the conversion fails, dfault
00545        *  is returned instead.
00546        *
00547        *  do_narrow() is a hook for a derived facet to change the behavior of
00548        *  narrowing.  do_narrow() must always return the same result for the
00549        *  same input.
00550        *
00551        *  Note: this is not what you want for codepage conversions.  See
00552        *  codecvt for that.
00553        *
00554        *  @param c  The char_type to convert.
00555        *  @param dfault  Char to return if conversion fails.
00556        *  @return  The converted char.
00557       */
00558       virtual char
00559       do_narrow(char_type, char __dfault) const = 0;
00560 
00561       /**
00562        *  @brief  Narrow char_type array to char
00563        *
00564        *  This virtual function converts each char_type in the range [lo,hi) to
00565        *  char using the simplest reasonable transformation and writes the
00566        *  results to the destination array.  For any element in the input that
00567        *  cannot be converted, @a dfault is used instead.
00568        *
00569        *  do_narrow() is a hook for a derived facet to change the behavior of
00570        *  narrowing.  do_narrow() must always return the same result for the
00571        *  same input.
00572        *
00573        *  Note: this is not what you want for codepage conversions.  See
00574        *  codecvt for that.
00575        *
00576        *  @param lo  Pointer to start of range.
00577        *  @param hi  Pointer to end of range.
00578        *  @param dfault  Char to use if conversion fails.
00579        *  @param to  Pointer to the destination array.
00580        *  @return  @a hi.
00581       */
00582       virtual const char_type*
00583       do_narrow(const char_type* __lo, const char_type* __hi,
00584         char __dfault, char* __dest) const = 0;
00585     };
00586 
00587   // NB: Generic, mostly useless implementation.
00588   /**
00589    *  @brief  Template ctype facet
00590    *
00591    *  This template class defines classification and conversion functions for
00592    *  character sets.  It wraps <cctype> functionality.  Ctype gets used by
00593    *  streams for many I/O operations.
00594    *
00595    *  This template provides the protected virtual functions the developer
00596    *  will have to replace in a derived class or specialization to make a
00597    *  working facet.  The public functions that access them are defined in
00598    *  __ctype_abstract_base, to allow for implementation flexibility.  See
00599    *  ctype<wchar_t> for an example.  The functions are documented in
00600    *  __ctype_abstract_base.
00601    *
00602    *  Note: implementations are provided for all the protected virtual
00603    *  functions, but will likely not be useful.
00604   */
00605   template<typename _CharT>
00606     class ctype : public __ctype_abstract_base<_CharT>
00607     {
00608     public:
00609       // Types:
00610       typedef _CharT            char_type;
00611       typedef typename __ctype_abstract_base<_CharT>::mask mask;
00612 
00613       /// The facet id for ctype<char_type>
00614       static locale::id         id;
00615 
00616       explicit
00617       ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
00618 
00619    protected:
00620       virtual
00621       ~ctype();
00622 
00623       virtual bool
00624       do_is(mask __m, char_type __c) const;
00625 
00626       virtual const char_type*
00627       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
00628 
00629       virtual const char_type*
00630       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
00631 
00632       virtual const char_type*
00633       do_scan_not(mask __m, const char_type* __lo,
00634           const char_type* __hi) const;
00635 
00636       virtual char_type
00637       do_toupper(char_type __c) const;
00638 
00639       virtual const char_type*
00640       do_toupper(char_type* __lo, const char_type* __hi) const;
00641 
00642       virtual char_type
00643       do_tolower(char_type __c) const;
00644 
00645       virtual const char_type*
00646       do_tolower(char_type* __lo, const char_type* __hi) const;
00647 
00648       virtual char_type
00649       do_widen(char __c) const;
00650 
00651       virtual const char*
00652       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
00653 
00654       virtual char
00655       do_narrow(char_type, char __dfault) const;
00656 
00657       virtual const char_type*
00658       do_narrow(const char_type* __lo, const char_type* __hi,
00659         char __dfault, char* __dest) const;
00660     };
00661 
00662   template<typename _CharT>
00663     locale::id ctype<_CharT>::id;
00664 
00665   // 22.2.1.3  ctype<char> specialization.
00666   /**
00667    *  @brief  The ctype<char> specialization.
00668    *
00669    *  This class defines classification and conversion functions for
00670    *  the char type.  It gets used by char streams for many I/O
00671    *  operations.  The char specialization provides a number of
00672    *  optimizations as well.
00673   */
00674   template<>
00675     class ctype<char> : public locale::facet, public ctype_base
00676     {
00677     public:
00678       // Types:
00679       /// Typedef for the template parameter char.
00680       typedef char      char_type;
00681 
00682     protected:
00683       // Data Members:
00684       __c_locale        _M_c_locale_ctype;
00685       bool          _M_del;
00686       __to_type         _M_toupper;
00687       __to_type         _M_tolower;
00688       const mask*       _M_table;
00689       mutable char      _M_widen_ok;
00690       mutable char      _M_widen[1 + static_cast<unsigned char>(-1)];
00691       mutable char      _M_narrow[1 + static_cast<unsigned char>(-1)];
00692       mutable char      _M_narrow_ok;   // 0 uninitialized, 1 init,
00693                         // 2 memcpy can't be used
00694 
00695     public:
00696       /// The facet id for ctype<char>
00697       static locale::id        id;
00698       /// The size of the mask table.  It is SCHAR_MAX + 1.
00699       static const size_t      table_size = 1 + static_cast<unsigned char>(-1);
00700 
00701       /**
00702        *  @brief  Constructor performs initialization.
00703        *
00704        *  This is the constructor provided by the standard.
00705        *
00706        *  @param table If non-zero, table is used as the per-char mask.
00707        *               Else classic_table() is used.
00708        *  @param del   If true, passes ownership of table to this facet.
00709        *  @param refs  Passed to the base facet class.
00710       */
00711       explicit
00712       ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
00713 
00714       /**
00715        *  @brief  Constructor performs static initialization.
00716        *
00717        *  This constructor is used to construct the initial C locale facet.
00718        *
00719        *  @param cloc  Handle to C locale data.
00720        *  @param table If non-zero, table is used as the per-char mask.
00721        *  @param del   If true, passes ownership of table to this facet.
00722        *  @param refs  Passed to the base facet class.
00723       */
00724       explicit
00725       ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
00726         size_t __refs = 0);
00727 
00728       /**
00729        *  @brief  Test char classification.
00730        *
00731        *  This function compares the mask table[c] to @a m.
00732        *
00733        *  @param c  The char to compare the mask of.
00734        *  @param m  The mask to compare against.
00735        *  @return  True if m & table[c] is true, false otherwise.
00736       */
00737       inline bool
00738       is(mask __m, char __c) const;
00739 
00740       /**
00741        *  @brief  Return a mask array.
00742        *
00743        *  This function finds the mask for each char in the range [lo, hi) and
00744        *  successively writes it to vec.  vec must have as many elements as
00745        *  the char array.
00746        *
00747        *  @param lo  Pointer to start of range.
00748        *  @param hi  Pointer to end of range.
00749        *  @param vec  Pointer to an array of mask storage.
00750        *  @return  @a hi.
00751       */
00752       inline const char*
00753       is(const char* __lo, const char* __hi, mask* __vec) const;
00754 
00755       /**
00756        *  @brief  Find char matching a mask
00757        *
00758        *  This function searches for and returns the first char in [lo,hi) for
00759        *  which is(m,char) is true.
00760        *
00761        *  @param m  The mask to compare against.
00762        *  @param lo  Pointer to start of range.
00763        *  @param hi  Pointer to end of range.
00764        *  @return  Pointer to a matching char if found, else @a hi.
00765       */
00766       inline const char*
00767       scan_is(mask __m, const char* __lo, const char* __hi) const;
00768 
00769       /**
00770        *  @brief  Find char not matching a mask
00771        *
00772        *  This function searches for and returns a pointer to the first char
00773        *  in [lo,hi) for which is(m,char) is false.
00774        *
00775        *  @param m  The mask to compare against.
00776        *  @param lo  Pointer to start of range.
00777        *  @param hi  Pointer to end of range.
00778        *  @return  Pointer to a non-matching char if found, else @a hi.
00779       */
00780       inline const char*
00781       scan_not(mask __m, const char* __lo, const char* __hi) const;
00782 
00783       /**
00784        *  @brief  Convert to uppercase.
00785        *
00786        *  This function converts the char argument to uppercase if possible.
00787        *  If not possible (for example, '2'), returns the argument.
00788        *
00789        *  toupper() acts as if it returns ctype<char>::do_toupper(c).
00790        *  do_toupper() must always return the same result for the same input.
00791        *
00792        *  @param c  The char to convert.
00793        *  @return  The uppercase char if convertible, else @a c.
00794       */
00795       char_type
00796       toupper(char_type __c) const
00797       { return this->do_toupper(__c); }
00798 
00799       /**
00800        *  @brief  Convert array to uppercase.
00801        *
00802        *  This function converts each char in the range [lo,hi) to uppercase
00803        *  if possible.  Other chars remain untouched.
00804        *
00805        *  toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi).
00806        *  do_toupper() must always return the same result for the same input.
00807        *
00808        *  @param lo  Pointer to first char in range.
00809        *  @param hi  Pointer to end of range.
00810        *  @return  @a hi.
00811       */
00812       const char_type*
00813       toupper(char_type *__lo, const char_type* __hi) const
00814       { return this->do_toupper(__lo, __hi); }
00815 
00816       /**
00817        *  @brief  Convert to lowercase.
00818        *
00819        *  This function converts the char argument to lowercase if possible.
00820        *  If not possible (for example, '2'), returns the argument.
00821        *
00822        *  tolower() acts as if it returns ctype<char>::do_tolower(c).
00823        *  do_tolower() must always return the same result for the same input.
00824        *
00825        *  @param c  The char to convert.
00826        *  @return  The lowercase char if convertible, else @a c.
00827       */
00828       char_type
00829       tolower(char_type __c) const
00830       { return this->do_tolower(__c); }
00831 
00832       /**
00833        *  @brief  Convert array to lowercase.
00834        *
00835        *  This function converts each char in the range [lo,hi) to lowercase
00836        *  if possible.  Other chars remain untouched.
00837        *
00838        *  tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi).
00839        *  do_tolower() must always return the same result for the same input.
00840        *
00841        *  @param lo  Pointer to first char in range.
00842        *  @param hi  Pointer to end of range.
00843        *  @return  @a hi.
00844       */
00845       const char_type*
00846       tolower(char_type* __lo, const char_type* __hi) const
00847       { return this->do_tolower(__lo, __hi); }
00848 
00849       /**
00850        *  @brief  Widen char
00851        *
00852        *  This function converts the char to char_type using the simplest
00853        *  reasonable transformation.  For an underived ctype<char> facet, the
00854        *  argument will be returned unchanged.
00855        *
00856        *  This function works as if it returns ctype<char>::do_widen(c).
00857        *  do_widen() must always return the same result for the same input.
00858        *
00859        *  Note: this is not what you want for codepage conversions.  See
00860        *  codecvt for that.
00861        *
00862        *  @param c  The char to convert.
00863        *  @return  The converted character.
00864       */
00865       char_type
00866       widen(char __c) const
00867       {
00868     if (_M_widen_ok)
00869       return _M_widen[static_cast<unsigned char>(__c)];
00870     this->_M_widen_init();
00871     return this->do_widen(__c);
00872       }
00873 
00874       /**
00875        *  @brief  Widen char array
00876        *
00877        *  This function converts each char in the input to char using the
00878        *  simplest reasonable transformation.  For an underived ctype<char>
00879        *  facet, the argument will be copied unchanged.
00880        *
00881        *  This function works as if it returns ctype<char>::do_widen(c).
00882        *  do_widen() must always return the same result for the same input.
00883        *
00884        *  Note: this is not what you want for codepage conversions.  See
00885        *  codecvt for that.
00886        *
00887        *  @param lo  Pointer to first char in range.
00888        *  @param hi  Pointer to end of range.
00889        *  @param to  Pointer to the destination array.
00890        *  @return  @a hi.
00891       */
00892       const char*
00893       widen(const char* __lo, const char* __hi, char_type* __to) const
00894       {
00895     if (_M_widen_ok == 1)
00896       {
00897         memcpy(__to, __lo, __hi - __lo);
00898         return __hi;
00899       }
00900     if (!_M_widen_ok)
00901       _M_widen_init();
00902     return this->do_widen(__lo, __hi, __to);
00903       }
00904 
00905       /**
00906        *  @brief  Narrow char
00907        *
00908        *  This function converts the char to char using the simplest
00909        *  reasonable transformation.  If the conversion fails, dfault is
00910        *  returned instead.  For an underived ctype<char> facet, @a c
00911        *  will be returned unchanged.
00912        *
00913        *  This function works as if it returns ctype<char>::do_narrow(c).
00914        *  do_narrow() must always return the same result for the same input.
00915        *
00916        *  Note: this is not what you want for codepage conversions.  See
00917        *  codecvt for that.
00918        *
00919        *  @param c  The char to convert.
00920        *  @param dfault  Char to return if conversion fails.
00921        *  @return  The converted character.
00922       */
00923       char
00924       narrow(char_type __c, char __dfault) const
00925       {
00926     if (_M_narrow[static_cast<unsigned char>(__c)])
00927       return _M_narrow[static_cast<unsigned char>(__c)];
00928     const char __t = do_narrow(__c, __dfault);
00929     if (__t != __dfault)
00930       _M_narrow[static_cast<unsigned char>(__c)] = __t;
00931     return __t;
00932       }
00933 
00934       /**
00935        *  @brief  Narrow char array
00936        *
00937        *  This function converts each char in the input to char using the
00938        *  simplest reasonable transformation and writes the results to the
00939        *  destination array.  For any char in the input that cannot be
00940        *  converted, @a dfault is used instead.  For an underived ctype<char>
00941        *  facet, the argument will be copied unchanged.
00942        *
00943        *  This function works as if it returns ctype<char>::do_narrow(lo, hi,
00944        *  dfault, to).  do_narrow() must always return the same result for the
00945        *  same input.
00946        *
00947        *  Note: this is not what you want for codepage conversions.  See
00948        *  codecvt for that.
00949        *
00950        *  @param lo  Pointer to start of range.
00951        *  @param hi  Pointer to end of range.
00952        *  @param dfault  Char to use if conversion fails.
00953        *  @param to  Pointer to the destination array.
00954        *  @return  @a hi.
00955       */
00956       const char_type*
00957       narrow(const char_type* __lo, const char_type* __hi,
00958          char __dfault, char *__to) const
00959       {
00960     if (__builtin_expect(_M_narrow_ok == 1, true))
00961       {
00962         memcpy(__to, __lo, __hi - __lo);
00963         return __hi;
00964       }
00965     if (!_M_narrow_ok)
00966       _M_narrow_init();
00967     return this->do_narrow(__lo, __hi, __dfault, __to);
00968       }
00969 
00970     protected:
00971       /// Returns a pointer to the mask table provided to the constructor, or
00972       /// the default from classic_table() if none was provided.
00973       const mask*
00974       table() const throw()
00975       { return _M_table; }
00976 
00977       /// Returns a pointer to the C locale mask table.
00978       static const mask*
00979       classic_table() throw();
00980 
00981       /**
00982        *  @brief  Destructor.
00983        *
00984        *  This function deletes table() if @a del was true in the
00985        *  constructor.
00986       */
00987       virtual
00988       ~ctype();
00989 
00990       /**
00991        *  @brief  Convert to uppercase.
00992        *
00993        *  This virtual function converts the char argument to uppercase if
00994        *  possible.  If not possible (for example, '2'), returns the argument.
00995        *
00996        *  do_toupper() is a hook for a derived facet to change the behavior of
00997        *  uppercasing.  do_toupper() must always return the same result for
00998        *  the same input.
00999        *
01000        *  @param c  The char to convert.
01001        *  @return  The uppercase char if convertible, else @a c.
01002       */
01003       virtual char_type
01004       do_toupper(char_type) const;
01005 
01006       /**
01007        *  @brief  Convert array to uppercase.
01008        *
01009        *  This virtual function converts each char in the range [lo,hi) to
01010        *  uppercase if possible.  Other chars remain untouched.
01011        *
01012        *  do_toupper() is a hook for a derived facet to change the behavior of
01013        *  uppercasing.  do_toupper() must always return the same result for
01014        *  the same input.
01015        *
01016        *  @param lo  Pointer to start of range.
01017        *  @param hi  Pointer to end of range.
01018        *  @return  @a hi.
01019       */
01020       virtual const char_type*
01021       do_toupper(char_type* __lo, const char_type* __hi) const;
01022 
01023       /**
01024        *  @brief  Convert to lowercase.
01025        *
01026        *  This virtual function converts the char argument to lowercase if
01027        *  possible.  If not possible (for example, '2'), returns the argument.
01028        *
01029        *  do_tolower() is a hook for a derived facet to change the behavior of
01030        *  lowercasing.  do_tolower() must always return the same result for
01031        *  the same input.
01032        *
01033        *  @param c  The char to convert.
01034        *  @return  The lowercase char if convertible, else @a c.
01035       */
01036       virtual char_type
01037       do_tolower(char_type) const;
01038 
01039       /**
01040        *  @brief  Convert array to lowercase.
01041        *
01042        *  This virtual function converts each char in the range [lo,hi) to
01043        *  lowercase if possible.  Other chars remain untouched.
01044        *
01045        *  do_tolower() is a hook for a derived facet to change the behavior of
01046        *  lowercasing.  do_tolower() must always return the same result for
01047        *  the same input.
01048        *
01049        *  @param lo  Pointer to first char in range.
01050        *  @param hi  Pointer to end of range.
01051        *  @return  @a hi.
01052       */
01053       virtual const char_type*
01054       do_tolower(char_type* __lo, const char_type* __hi) const;
01055 
01056       /**
01057        *  @brief  Widen char
01058        *
01059        *  This virtual function converts the char to char using the simplest
01060        *  reasonable transformation.  For an underived ctype<char> facet, the
01061        *  argument will be returned unchanged.
01062        *
01063        *  do_widen() is a hook for a derived facet to change the behavior of
01064        *  widening.  do_widen() must always return the same result for the
01065        *  same input.
01066        *
01067        *  Note: this is not what you want for codepage conversions.  See
01068        *  codecvt for that.
01069        *
01070        *  @param c  The char to convert.
01071        *  @return  The converted character.
01072       */
01073       virtual char_type
01074       do_widen(char __c) const
01075       { return __c; }
01076 
01077       /**
01078        *  @brief  Widen char array
01079        *
01080        *  This function converts each char in the range [lo,hi) to char using
01081        *  the simplest reasonable transformation.  For an underived
01082        *  ctype<char> facet, the argument will be copied unchanged.
01083        *
01084        *  do_widen() is a hook for a derived facet to change the behavior of
01085        *  widening.  do_widen() must always return the same result for the
01086        *  same input.
01087        *
01088        *  Note: this is not what you want for codepage conversions.  See
01089        *  codecvt for that.
01090        *
01091        *  @param lo  Pointer to start of range.
01092        *  @param hi  Pointer to end of range.
01093        *  @param to  Pointer to the destination array.
01094        *  @return  @a hi.
01095       */
01096       virtual const char*
01097       do_widen(const char* __lo, const char* __hi, char_type* __dest) const
01098       {
01099     memcpy(__dest, __lo, __hi - __lo);
01100     return __hi;
01101       }
01102 
01103       /**
01104        *  @brief  Narrow char
01105        *
01106        *  This virtual function converts the char to char using the simplest
01107        *  reasonable transformation.  If the conversion fails, dfault is
01108        *  returned instead.  For an underived ctype<char> facet, @a c will be
01109        *  returned unchanged.
01110        *
01111        *  do_narrow() is a hook for a derived facet to change the behavior of
01112        *  narrowing.  do_narrow() must always return the same result for the
01113        *  same input.
01114        *
01115        *  Note: this is not what you want for codepage conversions.  See
01116        *  codecvt for that.
01117        *
01118        *  @param c  The char to convert.
01119        *  @param dfault  Char to return if conversion fails.
01120        *  @return  The converted char.
01121       */
01122       virtual char
01123       do_narrow(char_type __c, char) const
01124       { return __c; }
01125 
01126       /**
01127        *  @brief  Narrow char array to char array
01128        *
01129        *  This virtual function converts each char in the range [lo,hi) to
01130        *  char using the simplest reasonable transformation and writes the
01131        *  results to the destination array.  For any char in the input that
01132        *  cannot be converted, @a dfault is used instead.  For an underived
01133        *  ctype<char> facet, the argument will be copied unchanged.
01134        *
01135        *  do_narrow() is a hook for a derived facet to change the behavior of
01136        *  narrowing.  do_narrow() must always return the same result for the
01137        *  same input.
01138        *
01139        *  Note: this is not what you want for codepage conversions.  See
01140        *  codecvt for that.
01141        *
01142        *  @param lo  Pointer to start of range.
01143        *  @param hi  Pointer to end of range.
01144        *  @param dfault  Char to use if conversion fails.
01145        *  @param to  Pointer to the destination array.
01146        *  @return  @a hi.
01147       */
01148       virtual const char_type*
01149       do_narrow(const char_type* __lo, const char_type* __hi,
01150         char, char* __dest) const
01151       {
01152     memcpy(__dest, __lo, __hi - __lo);
01153     return __hi;
01154       }
01155 
01156     private:
01157 
01158       void _M_widen_init() const
01159       {
01160     char __tmp[sizeof(_M_widen)];
01161     for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
01162       __tmp[__i] = __i;
01163     do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
01164 
01165     _M_widen_ok = 1;
01166     // Set _M_widen_ok to 2 if memcpy can't be used.
01167     if (memcmp(__tmp, _M_widen, sizeof(_M_widen)))
01168       _M_widen_ok = 2;
01169       }
01170 
01171       // Fill in the narrowing cache and flag whether all values are
01172       // valid or not.  _M_narrow_ok is set to 2 if memcpy can't
01173       // be used.
01174       void _M_narrow_init() const
01175       {
01176     char __tmp[sizeof(_M_narrow)];
01177     for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
01178       __tmp[__i] = __i;
01179     do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
01180 
01181     _M_narrow_ok = 1;
01182     if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow)))
01183       _M_narrow_ok = 2;
01184     else
01185       {
01186         // Deal with the special case of zero: renarrow with a
01187         // different default and compare.
01188         char __c;
01189         do_narrow(__tmp, __tmp + 1, 1, &__c);
01190         if (__c == 1)
01191           _M_narrow_ok = 2;
01192       }
01193       }
01194     };
01195 
01196   template<>
01197     const ctype<char>&
01198     use_facet<ctype<char> >(const locale& __loc);
01199 
01200 #ifdef _GLIBCXX_USE_WCHAR_T
01201   // 22.2.1.3  ctype<wchar_t> specialization
01202   /**
01203    *  @brief  The ctype<wchar_t> specialization.
01204    *
01205    *  This class defines classification and conversion functions for the
01206    *  wchar_t type.  It gets used by wchar_t streams for many I/O operations.
01207    *  The wchar_t specialization provides a number of optimizations as well.
01208    *
01209    *  ctype<wchar_t> inherits its public methods from
01210    *  __ctype_abstract_base<wchar_t>.
01211   */
01212   template<>
01213     class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
01214     {
01215     public:
01216       // Types:
01217       /// Typedef for the template parameter wchar_t.
01218       typedef wchar_t       char_type;
01219       typedef wctype_t      __wmask_type;
01220 
01221     protected:
01222       __c_locale        _M_c_locale_ctype;
01223 
01224       // Pre-computed narrowed and widened chars.
01225       bool                      _M_narrow_ok;
01226       char                      _M_narrow[128];
01227       wint_t                    _M_widen[1 + static_cast<unsigned char>(-1)];
01228 
01229       // Pre-computed elements for do_is.
01230       mask                      _M_bit[16];
01231       __wmask_type              _M_wmask[16];
01232 
01233     public:
01234       // Data Members:
01235       /// The facet id for ctype<wchar_t>
01236       static locale::id     id;
01237 
01238       /**
01239        *  @brief  Constructor performs initialization.
01240        *
01241        *  This is the constructor provided by the standard.
01242        *
01243        *  @param refs  Passed to the base facet class.
01244       */
01245       explicit
01246       ctype(size_t __refs = 0);
01247 
01248       /**
01249        *  @brief  Constructor performs static initialization.
01250        *
01251        *  This constructor is used to construct the initial C locale facet.
01252        *
01253        *  @param cloc  Handle to C locale data.
01254        *  @param refs  Passed to the base facet class.
01255       */
01256       explicit
01257       ctype(__c_locale __cloc, size_t __refs = 0);
01258 
01259     protected:
01260       __wmask_type
01261       _M_convert_to_wmask(const mask __m) const;
01262 
01263       /// Destructor
01264       virtual
01265       ~ctype();
01266 
01267       /**
01268        *  @brief  Test wchar_t classification.
01269        *
01270        *  This function finds a mask M for @a c and compares it to mask @a m.
01271        *
01272        *  do_is() is a hook for a derived facet to change the behavior of
01273        *  classifying.  do_is() must always return the same result for the
01274        *  same input.
01275        *
01276        *  @param c  The wchar_t to find the mask of.
01277        *  @param m  The mask to compare against.
01278        *  @return  (M & m) != 0.
01279       */
01280       virtual bool
01281       do_is(mask __m, char_type __c) const;
01282 
01283       /**
01284        *  @brief  Return a mask array.
01285        *
01286        *  This function finds the mask for each wchar_t in the range [lo,hi)
01287        *  and successively writes it to vec.  vec must have as many elements
01288        *  as the input.
01289        *
01290        *  do_is() is a hook for a derived facet to change the behavior of
01291        *  classifying.  do_is() must always return the same result for the
01292        *  same input.
01293        *
01294        *  @param lo  Pointer to start of range.
01295        *  @param hi  Pointer to end of range.
01296        *  @param vec  Pointer to an array of mask storage.
01297        *  @return  @a hi.
01298       */
01299       virtual const char_type*
01300       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
01301 
01302       /**
01303        *  @brief  Find wchar_t matching mask
01304        *
01305        *  This function searches for and returns the first wchar_t c in
01306        *  [lo,hi) for which is(m,c) is true.
01307        *
01308        *  do_scan_is() is a hook for a derived facet to change the behavior of
01309        *  match searching.  do_is() must always return the same result for the
01310        *  same input.
01311        *
01312        *  @param m  The mask to compare against.
01313        *  @param lo  Pointer to start of range.
01314        *  @param hi  Pointer to end of range.
01315        *  @return  Pointer to a matching wchar_t if found, else @a hi.
01316       */
01317       virtual const char_type*
01318       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
01319 
01320       /**
01321        *  @brief  Find wchar_t not matching mask
01322        *
01323        *  This function searches for and returns a pointer to the first
01324        *  wchar_t c of [lo,hi) for which is(m,c) is false.
01325        *
01326        *  do_scan_is() is a hook for a derived facet to change the behavior of
01327        *  match searching.  do_is() must always return the same result for the
01328        *  same input.
01329        *
01330        *  @param m  The mask to compare against.
01331        *  @param lo  Pointer to start of range.
01332        *  @param hi  Pointer to end of range.
01333        *  @return  Pointer to a non-matching wchar_t if found, else @a hi.
01334       */
01335       virtual const char_type*
01336       do_scan_not(mask __m, const char_type* __lo,
01337           const char_type* __hi) const;
01338 
01339       /**
01340        *  @brief  Convert to uppercase.
01341        *
01342        *  This virtual function converts the wchar_t argument to uppercase if
01343        *  possible.  If not possible (for example, '2'), returns the argument.
01344        *
01345        *  do_toupper() is a hook for a derived facet to change the behavior of
01346        *  uppercasing.  do_toupper() must always return the same result for
01347        *  the same input.
01348        *
01349        *  @param c  The wchar_t to convert.
01350        *  @return  The uppercase wchar_t if convertible, else @a c.
01351       */
01352       virtual char_type
01353       do_toupper(char_type) const;
01354 
01355       /**
01356        *  @brief  Convert array to uppercase.
01357        *
01358        *  This virtual function converts each wchar_t in the range [lo,hi) to
01359        *  uppercase if possible.  Other elements remain untouched.
01360        *
01361        *  do_toupper() is a hook for a derived facet to change the behavior of
01362        *  uppercasing.  do_toupper() must always return the same result for
01363        *  the same input.
01364        *
01365        *  @param lo  Pointer to start of range.
01366        *  @param hi  Pointer to end of range.
01367        *  @return  @a hi.
01368       */
01369       virtual const char_type*
01370       do_toupper(char_type* __lo, const char_type* __hi) const;
01371 
01372       /**
01373        *  @brief  Convert to lowercase.
01374        *
01375        *  This virtual function converts the argument to lowercase if
01376        *  possible.  If not possible (for example, '2'), returns the argument.
01377        *
01378        *  do_tolower() is a hook for a derived facet to change the behavior of
01379        *  lowercasing.  do_tolower() must always return the same result for
01380        *  the same input.
01381        *
01382        *  @param c  The wchar_t to convert.
01383        *  @return  The lowercase wchar_t if convertible, else @a c.
01384       */
01385       virtual char_type
01386       do_tolower(char_type) const;
01387 
01388       /**
01389        *  @brief  Convert array to lowercase.
01390        *
01391        *  This virtual function converts each wchar_t in the range [lo,hi) to
01392        *  lowercase if possible.  Other elements remain untouched.
01393        *
01394        *  do_tolower() is a hook for a derived facet to change the behavior of
01395        *  lowercasing.  do_tolower() must always return the same result for
01396        *  the same input.
01397        *
01398        *  @param lo  Pointer to start of range.
01399        *  @param hi  Pointer to end of range.
01400        *  @return  @a hi.
01401       */
01402       virtual const char_type*
01403       do_tolower(char_type* __lo, const char_type* __hi) const;
01404 
01405       /**
01406        *  @brief  Widen char to wchar_t
01407        *
01408        *  This virtual function converts the char to wchar_t using the
01409        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
01410        *  facet, the argument will be cast to wchar_t.
01411        *
01412        *  do_widen() is a hook for a derived facet to change the behavior of
01413        *  widening.  do_widen() must always return the same result for the
01414        *  same input.
01415        *
01416        *  Note: this is not what you want for codepage conversions.  See
01417        *  codecvt for that.
01418        *
01419        *  @param c  The char to convert.
01420        *  @return  The converted wchar_t.
01421       */
01422       virtual char_type
01423       do_widen(char) const;
01424 
01425       /**
01426        *  @brief  Widen char array to wchar_t array
01427        *
01428        *  This function converts each char in the input to wchar_t using the
01429        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
01430        *  facet, the argument will be copied, casting each element to wchar_t.
01431        *
01432        *  do_widen() is a hook for a derived facet to change the behavior of
01433        *  widening.  do_widen() must always return the same result for the
01434        *  same input.
01435        *
01436        *  Note: this is not what you want for codepage conversions.  See
01437        *  codecvt for that.
01438        *
01439        *  @param lo  Pointer to start range.
01440        *  @param hi  Pointer to end of range.
01441        *  @param to  Pointer to the destination array.
01442        *  @return  @a hi.
01443       */
01444       virtual const char*
01445       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
01446 
01447       /**
01448        *  @brief  Narrow wchar_t to char
01449        *
01450        *  This virtual function converts the argument to char using
01451        *  the simplest reasonable transformation.  If the conversion
01452        *  fails, dfault is returned instead.  For an underived
01453        *  ctype<wchar_t> facet, @a c will be cast to char and
01454        *  returned.
01455        *
01456        *  do_narrow() is a hook for a derived facet to change the
01457        *  behavior of narrowing.  do_narrow() must always return the
01458        *  same result for the same input.
01459        *
01460        *  Note: this is not what you want for codepage conversions.  See
01461        *  codecvt for that.
01462        *
01463        *  @param c  The wchar_t to convert.
01464        *  @param dfault  Char to return if conversion fails.
01465        *  @return  The converted char.
01466       */
01467       virtual char
01468       do_narrow(char_type, char __dfault) const;
01469 
01470       /**
01471        *  @brief  Narrow wchar_t array to char array
01472        *
01473        *  This virtual function converts each wchar_t in the range [lo,hi) to
01474        *  char using the simplest reasonable transformation and writes the
01475        *  results to the destination array.  For any wchar_t in the input that
01476        *  cannot be converted, @a dfault is used instead.  For an underived
01477        *  ctype<wchar_t> facet, the argument will be copied, casting each
01478        *  element to char.
01479        *
01480        *  do_narrow() is a hook for a derived facet to change the behavior of
01481        *  narrowing.  do_narrow() must always return the same result for the
01482        *  same input.
01483        *
01484        *  Note: this is not what you want for codepage conversions.  See
01485        *  codecvt for that.
01486        *
01487        *  @param lo  Pointer to start of range.
01488        *  @param hi  Pointer to end of range.
01489        *  @param dfault  Char to use if conversion fails.
01490        *  @param to  Pointer to the destination array.
01491        *  @return  @a hi.
01492       */
01493       virtual const char_type*
01494       do_narrow(const char_type* __lo, const char_type* __hi,
01495         char __dfault, char* __dest) const;
01496 
01497       // For use at construction time only.
01498       void
01499       _M_initialize_ctype();
01500     };
01501 
01502   template<>
01503     const ctype<wchar_t>&
01504     use_facet<ctype<wchar_t> >(const locale& __loc);
01505 #endif //_GLIBCXX_USE_WCHAR_T
01506 
01507   // Include host and configuration specific ctype inlines.
01508   #include <bits/ctype_inline.h>
01509 
01510   /// @brief  class ctype_byname [22.2.1.2].
01511   template<typename _CharT>
01512     class ctype_byname : public ctype<_CharT>
01513     {
01514     public:
01515       typedef _CharT        char_type;
01516 
01517       explicit
01518       ctype_byname(const char* __s, size_t __refs = 0);
01519 
01520     protected:
01521       virtual
01522       ~ctype_byname() { };
01523     };
01524 
01525   /// 22.2.1.4  Class ctype_byname specializations.
01526   template<>
01527     ctype_byname<char>::ctype_byname(const char*, size_t refs);
01528 
01529   template<>
01530     ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
01531 
01532   // 22.2.1.5  Template class codecvt
01533   #include <bits/codecvt.h>
01534 
01535   // 22.2.2  The numeric category.
01536   class __num_base
01537   {
01538   public:
01539     // NB: Code depends on the order of _S_atoms_out elements.
01540     // Below are the indices into _S_atoms_out.
01541     enum
01542       {
01543         _S_ominus,
01544         _S_oplus,
01545         _S_ox,
01546         _S_oX,
01547         _S_odigits,
01548         _S_odigits_end = _S_odigits + 16,
01549         _S_oudigits = _S_odigits_end,
01550         _S_oudigits_end = _S_oudigits + 16,
01551         _S_oe = _S_odigits + 14,  // For scientific notation, 'e'
01552         _S_oE = _S_oudigits + 14, // For scientific notation, 'E'
01553     _S_oend = _S_oudigits_end
01554       };
01555 
01556     // A list of valid numeric literals for output.  This array
01557     // contains chars that will be passed through the current locale's
01558     // ctype<_CharT>.widen() and then used to render numbers.
01559     // For the standard "C" locale, this is
01560     // "-+xX0123456789abcdef0123456789ABCDEF".
01561     static const char* _S_atoms_out;
01562 
01563     // String literal of acceptable (narrow) input, for num_get.
01564     // "-+xX0123456789abcdefABCDEF"
01565     static const char* _S_atoms_in;
01566 
01567     enum
01568     {
01569       _S_iminus,
01570       _S_iplus,
01571       _S_ix,
01572       _S_iX,
01573       _S_izero,
01574       _S_ie = _S_izero + 14,
01575       _S_iE = _S_izero + 20,
01576       _S_iend = 26
01577     };
01578 
01579     // num_put
01580     // Construct and return valid scanf format for floating point types.
01581     static void
01582     _S_format_float(const ios_base& __io, char* __fptr, char __mod);
01583   };
01584 
01585   template<typename _CharT>
01586     struct __numpunct_cache : public locale::facet
01587     {
01588       const char*           _M_grouping;
01589       size_t                            _M_grouping_size;
01590       bool              _M_use_grouping;
01591       const _CharT*         _M_truename;
01592       size_t                            _M_truename_size;
01593       const _CharT*         _M_falsename;
01594       size_t                            _M_falsename_size;
01595       _CharT                _M_decimal_point;
01596       _CharT                _M_thousands_sep;
01597 
01598       // A list of valid numeric literals for output: in the standard
01599       // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
01600       // This array contains the chars after having been passed
01601       // through the current locale's ctype<_CharT>.widen().
01602       _CharT                _M_atoms_out[__num_base::_S_oend];
01603 
01604       // A list of valid numeric literals for input: in the standard
01605       // "C" locale, this is "-+xX0123456789abcdefABCDEF"
01606       // This array contains the chars after having been passed
01607       // through the current locale's ctype<_CharT>.widen().
01608       _CharT                _M_atoms_in[__num_base::_S_iend];
01609 
01610       bool              _M_allocated;
01611 
01612       __numpunct_cache(size_t __refs = 0) : facet(__refs),
01613       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
01614       _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL),
01615       _M_falsename_size(0), _M_decimal_point(_CharT()),
01616       _M_thousands_sep(_CharT()), _M_allocated(false)
01617       { }
01618 
01619       ~__numpunct_cache();
01620 
01621       void
01622       _M_cache(const locale& __loc);
01623 
01624     private:
01625       __numpunct_cache&
01626       operator=(const __numpunct_cache&);
01627       
01628       explicit
01629       __numpunct_cache(const __numpunct_cache&);
01630     };
01631 
01632   template<typename _CharT>
01633     __numpunct_cache<_CharT>::~__numpunct_cache()
01634     {
01635       if (_M_allocated)
01636     {
01637       delete [] _M_grouping;
01638       delete [] _M_truename;
01639       delete [] _M_falsename;
01640     }
01641     }
01642 
01643   /**
01644    *  @brief  Numpunct facet.
01645    *
01646    *  This facet stores several pieces of information related to printing and
01647    *  scanning numbers, such as the decimal point character.  It takes a
01648    *  template parameter specifying the char type.  The numpunct facet is
01649    *  used by streams for many I/O operations involving numbers.
01650    *
01651    *  The numpunct template uses protected virtual functions to provide the
01652    *  actual results.  The public accessors forward the call to the virtual
01653    *  functions.  These virtual functions are hooks for developers to
01654    *  implement the behavior they require from a numpunct facet.
01655   */
01656   template<typename _CharT>
01657     class numpunct : public locale::facet
01658     {
01659     public:
01660       // Types:
01661       //@{
01662       /// Public typedefs
01663       typedef _CharT            char_type;
01664       typedef basic_string<_CharT>  string_type;
01665       //@}
01666       typedef __numpunct_cache<_CharT>  __cache_type;
01667 
01668     protected:
01669       __cache_type*         _M_data;
01670 
01671     public:
01672       /// Numpunct facet id.
01673       static locale::id         id;
01674 
01675       /**
01676        *  @brief  Numpunct constructor.
01677        *
01678        *  @param  refs  Refcount to pass to the base class.
01679        */
01680       explicit
01681       numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
01682       { _M_initialize_numpunct(); }
01683 
01684       /**
01685        *  @brief  Internal constructor.  Not for general use.
01686        *
01687        *  This is a constructor for use by the library itself to set up the
01688        *  predefined locale facets.
01689        *
01690        *  @param  cache  __numpunct_cache object.
01691        *  @param  refs  Refcount to pass to the base class.
01692        */
01693       explicit
01694       numpunct(__cache_type* __cache, size_t __refs = 0)
01695       : facet(__refs), _M_data(__cache)
01696       { _M_initialize_numpunct(); }
01697 
01698       /**
01699        *  @brief  Internal constructor.  Not for general use.
01700        *
01701        *  This is a constructor for use by the library itself to set up new
01702        *  locales.
01703        *
01704        *  @param  cloc  The "C" locale.
01705        *  @param  refs  Refcount to pass to the base class.
01706        */
01707       explicit
01708       numpunct(__c_locale __cloc, size_t __refs = 0)
01709       : facet(__refs), _M_data(NULL)
01710       { _M_initialize_numpunct(__cloc); }
01711 
01712       /**
01713        *  @brief  Return decimal point character.
01714        *
01715        *  This function returns a char_type to use as a decimal point.  It
01716        *  does so by returning returning
01717        *  numpunct<char_type>::do_decimal_point().
01718        *
01719        *  @return  @a char_type representing a decimal point.
01720       */
01721       char_type
01722       decimal_point() const
01723       { return this->do_decimal_point(); }
01724 
01725       /**
01726        *  @brief  Return thousands separator character.
01727        *
01728        *  This function returns a char_type to use as a thousands
01729        *  separator.  It does so by returning returning
01730        *  numpunct<char_type>::do_thousands_sep().
01731        *
01732        *  @return  char_type representing a thousands separator.
01733       */
01734       char_type
01735       thousands_sep() const
01736       { return this->do_thousands_sep(); }
01737 
01738       /**
01739        *  @brief  Return grouping specification.
01740        *
01741        *  This function returns a string representing groupings for the
01742        *  integer part of a number.  Groupings indicate where thousands
01743        *  separators should be inserted in the integer part of a number.
01744        *
01745        *  Each char in the return string is interpret as an integer
01746        *  rather than a character.  These numbers represent the number
01747        *  of digits in a group.  The first char in the string
01748        *  represents the number of digits in the least significant
01749        *  group.  If a char is negative, it indicates an unlimited
01750        *  number of digits for the group.  If more chars from the
01751        *  string are required to group a number, the last char is used
01752        *  repeatedly.
01753        *
01754        *  For example, if the grouping() returns "\003\002" and is
01755        *  applied to the number 123456789, this corresponds to
01756        *  12,34,56,789.  Note that if the string was "32", this would
01757        *  put more than 50 digits into the least significant group if
01758        *  the character set is ASCII.
01759        *
01760        *  The string is returned by calling
01761        *  numpunct<char_type>::do_grouping().
01762        *
01763        *  @return  string representing grouping specification.
01764       */
01765       string
01766       grouping() const
01767       { return this->do_grouping(); }
01768 
01769       /**
01770        *  @brief  Return string representation of bool true.
01771        *
01772        *  This function returns a string_type containing the text
01773        *  representation for true bool variables.  It does so by calling
01774        *  numpunct<char_type>::do_truename().
01775        *
01776        *  @return  string_type representing printed form of true.
01777       */
01778       string_type
01779       truename() const
01780       { return this->do_truename(); }
01781 
01782       /**
01783        *  @brief  Return string representation of bool false.
01784        *
01785        *  This function returns a string_type containing the text
01786        *  representation for false bool variables.  It does so by calling
01787        *  numpunct<char_type>::do_falsename().
01788        *
01789        *  @return  string_type representing printed form of false.
01790       */
01791       string_type
01792       falsename() const
01793       { return this->do_falsename(); }
01794 
01795     protected:
01796       /// Destructor.
01797       virtual
01798       ~numpunct();
01799 
01800       /**
01801        *  @brief  Return decimal point character.
01802        *
01803        *  Returns a char_type to use as a decimal point.  This function is a
01804        *  hook for derived classes to change the value returned.
01805        *
01806        *  @return  @a char_type representing a decimal point.
01807       */
01808       virtual char_type
01809       do_decimal_point() const
01810       { return _M_data->_M_decimal_point; }
01811 
01812       /**
01813        *  @brief  Return thousands separator character.
01814        *
01815        *  Returns a char_type to use as a thousands separator.  This function
01816        *  is a hook for derived classes to change the value returned.
01817        *
01818        *  @return  @a char_type representing a thousands separator.
01819       */
01820       virtual char_type
01821       do_thousands_sep() const
01822       { return _M_data->_M_thousands_sep; }
01823 
01824       /**
01825        *  @brief  Return grouping specification.
01826        *
01827        *  Returns a string representing groupings for the integer part of a
01828        *  number.  This function is a hook for derived classes to change the
01829        *  value returned.  @see grouping() for details.
01830        *
01831        *  @return  String representing grouping specification.
01832       */
01833       virtual string
01834       do_grouping() const
01835       { return _M_data->_M_grouping; }
01836 
01837       /**
01838        *  @brief  Return string representation of bool true.
01839        *
01840        *  Returns a string_type containing the text representation for true
01841        *  bool variables.  This function is a hook for derived classes to
01842        *  change the value returned.
01843        *
01844        *  @return  string_type representing printed form of true.
01845       */
01846       virtual string_type
01847       do_truename() const
01848       { return _M_data->_M_truename; }
01849 
01850       /**
01851        *  @brief  Return string representation of bool false.
01852        *
01853        *  Returns a string_type containing the text representation for false
01854        *  bool variables.  This function is a hook for derived classes to
01855        *  change the value returned.
01856        *
01857        *  @return  string_type representing printed form of false.
01858       */
01859       virtual string_type
01860       do_falsename() const
01861       { return _M_data->_M_falsename; }
01862 
01863       // For use at construction time only.
01864       void
01865       _M_initialize_numpunct(__c_locale __cloc = NULL);
01866     };
01867 
01868   template<typename _CharT>
01869     locale::id numpunct<_CharT>::id;
01870 
01871   template<>
01872     numpunct<char>::~numpunct();
01873 
01874   template<>
01875     void
01876     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
01877 
01878 #ifdef _GLIBCXX_USE_WCHAR_T
01879   template<>
01880     numpunct<wchar_t>::~numpunct();
01881 
01882   template<>
01883     void
01884     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
01885 #endif
01886 
01887   /// @brief  class numpunct_byname [22.2.3.2].
01888   template<typename _CharT>
01889     class numpunct_byname : public numpunct<_CharT>
01890     {
01891     public:
01892       typedef _CharT            char_type;
01893       typedef basic_string<_CharT>  string_type;
01894 
01895       explicit
01896       numpunct_byname(const char* __s, size_t __refs = 0)
01897       : numpunct<_CharT>(__refs)
01898       {
01899     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
01900       {
01901         __c_locale __tmp;
01902         this->_S_create_c_locale(__tmp, __s);
01903         this->_M_initialize_numpunct(__tmp);
01904         this->_S_destroy_c_locale(__tmp);
01905       }
01906       }
01907 
01908     protected:
01909       virtual
01910       ~numpunct_byname() { }
01911     };
01912 
01913   /**
01914    *  @brief  Facet for parsing number strings.
01915    *
01916    *  This facet encapsulates the code to parse and return a number
01917    *  from a string.  It is used by the istream numeric extraction
01918    *  operators.
01919    *
01920    *  The num_get template uses protected virtual functions to provide the
01921    *  actual results.  The public accessors forward the call to the virtual
01922    *  functions.  These virtual functions are hooks for developers to
01923    *  implement the behavior they require from the num_get facet.
01924   */
01925   template<typename _CharT, typename _InIter>
01926     class num_get : public locale::facet
01927     {
01928     public:
01929       // Types:
01930       //@{
01931       /// Public typedefs
01932       typedef _CharT            char_type;
01933       typedef _InIter           iter_type;
01934       //@}
01935 
01936       /// Numpunct facet id.
01937       static locale::id         id;
01938 
01939       /**
01940        *  @brief  Constructor performs initialization.
01941        *
01942        *  This is the constructor provided by the standard.
01943        *
01944        *  @param refs  Passed to the base facet class.
01945       */
01946       explicit
01947       num_get(size_t __refs = 0) : facet(__refs) { }
01948 
01949       /**
01950        *  @brief  Numeric parsing.
01951        *
01952        *  Parses the input stream into the bool @a v.  It does so by calling
01953        *  num_get::do_get().
01954        *
01955        *  If ios_base::boolalpha is set, attempts to read
01956        *  ctype<CharT>::truename() or ctype<CharT>::falsename().  Sets
01957        *  @a v to true or false if successful.  Sets err to
01958        *  ios_base::failbit if reading the string fails.  Sets err to
01959        *  ios_base::eofbit if the stream is emptied.
01960        *
01961        *  If ios_base::boolalpha is not set, proceeds as with reading a long,
01962        *  except if the value is 1, sets @a v to true, if the value is 0, sets
01963        *  @a v to false, and otherwise set err to ios_base::failbit.
01964        *
01965        *  @param  in  Start of input stream.
01966        *  @param  end  End of input stream.
01967        *  @param  io  Source of locale and flags.
01968        *  @param  err  Error flags to set.
01969        *  @param  v  Value to format and insert.
01970        *  @return  Iterator after reading.
01971       */
01972       iter_type
01973       get(iter_type __in, iter_type __end, ios_base& __io,
01974       ios_base::iostate& __err, bool& __v) const
01975       { return this->do_get(__in, __end, __io, __err, __v); }
01976 
01977       //@{
01978       /**
01979        *  @brief  Numeric parsing.
01980        *
01981        *  Parses the input stream into the integral variable @a v.  It does so
01982        *  by calling num_get::do_get().
01983        *
01984        *  Parsing is affected by the flag settings in @a io.
01985        *
01986        *  The basic parse is affected by the value of io.flags() &
01987        *  ios_base::basefield.  If equal to ios_base::oct, parses like the
01988        *  scanf %o specifier.  Else if equal to ios_base::hex, parses like %X
01989        *  specifier.  Else if basefield equal to 0, parses like the %i
01990        *  specifier.  Otherwise, parses like %d for signed and %u for unsigned
01991        *  types.  The matching type length modifier is also used.
01992        *
01993        *  Digit grouping is intrepreted according to numpunct::grouping() and
01994        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
01995        *  consistent, sets err to ios_base::failbit.
01996        *
01997        *  If parsing the string yields a valid value for @a v, @a v is set.
01998        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
01999        *  Sets err to ios_base::eofbit if the stream is emptied.
02000        *
02001        *  @param  in  Start of input stream.
02002        *  @param  end  End of input stream.
02003        *  @param  io  Source of locale and flags.
02004        *  @param  err  Error flags to set.
02005        *  @param  v  Value to format and insert.
02006        *  @return  Iterator after reading.
02007       */
02008       iter_type
02009       get(iter_type __in, iter_type __end, ios_base& __io,
02010       ios_base::iostate& __err, long& __v) const
02011       { return this->do_get(__in, __end, __io, __err, __v); }
02012 
02013       iter_type
02014       get(iter_type __in, iter_type __end, ios_base& __io,
02015       ios_base::iostate& __err, unsigned short& __v) const
02016       { return this->do_get(__in, __end, __io, __err, __v); }
02017 
02018       iter_type
02019       get(iter_type __in, iter_type __end, ios_base& __io,
02020       ios_base::iostate& __err, unsigned int& __v)   const
02021       { return this->do_get(__in, __end, __io, __err, __v); }
02022 
02023       iter_type
02024       get(iter_type __in, iter_type __end, ios_base& __io,
02025       ios_base::iostate& __err, unsigned long& __v)  const
02026       { return this->do_get(__in, __end, __io, __err, __v); }
02027 
02028 #ifdef _GLIBCXX_USE_LONG_LONG
02029       iter_type
02030       get(iter_type __in, iter_type __end, ios_base& __io,
02031       ios_base::iostate& __err, long long& __v) const
02032       { return this->do_get(__in, __end, __io, __err, __v); }
02033 
02034       iter_type
02035       get(iter_type __in, iter_type __end, ios_base& __io,
02036       ios_base::iostate& __err, unsigned long long& __v)  const
02037       { return this->do_get(__in, __end, __io, __err, __v); }
02038 #endif
02039       //@}
02040 
02041       //@{
02042       /**
02043        *  @brief  Numeric parsing.
02044        *
02045        *  Parses the input stream into the integral variable @a v.  It does so
02046        *  by calling num_get::do_get().
02047        *
02048        *  The input characters are parsed like the scanf %g specifier.  The
02049        *  matching type length modifier is also used.
02050        *
02051        *  The decimal point character used is numpunct::decimal_point().
02052        *  Digit grouping is intrepreted according to numpunct::grouping() and
02053        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
02054        *  consistent, sets err to ios_base::failbit.
02055        *
02056        *  If parsing the string yields a valid value for @a v, @a v is set.
02057        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
02058        *  Sets err to ios_base::eofbit if the stream is emptied.
02059        *
02060        *  @param  in  Start of input stream.
02061        *  @param  end  End of input stream.
02062        *  @param  io  Source of locale and flags.
02063        *  @param  err  Error flags to set.
02064        *  @param  v  Value to format and insert.
02065        *  @return  Iterator after reading.
02066       */
02067       iter_type
02068       get(iter_type __in, iter_type __end, ios_base& __io,
02069       ios_base::iostate& __err, float& __v) const
02070       { return this->do_get(__in, __end, __io, __err, __v); }
02071 
02072       iter_type
02073       get(iter_type __in, iter_type __end, ios_base& __io,
02074       ios_base::iostate& __err, double& __v) const
02075       { return this->do_get(__in, __end, __io, __err, __v); }
02076 
02077       iter_type
02078       get(iter_type __in, iter_type __end, ios_base& __io,
02079       ios_base::iostate& __err, long double& __v) const
02080       { return this->do_get(__in, __end, __io, __err, __v); }
02081       //@}
02082 
02083       /**
02084        *  @brief  Numeric parsing.
02085        *
02086        *  Parses the input stream into the pointer variable @a v.  It does so
02087        *  by calling num_get::do_get().
02088        *
02089        *  The input characters are parsed like the scanf %p specifier.
02090        *
02091        *  Digit grouping is intrepreted according to numpunct::grouping() and
02092        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
02093        *  consistent, sets err to ios_base::failbit.
02094        *
02095        *  Note that the digit grouping effect for pointers is a bit ambiguous
02096        *  in the standard and shouldn't be relied on.  See DR 344.
02097        *
02098        *  If parsing the string yields a valid value for @a v, @a v is set.
02099        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
02100        *  Sets err to ios_base::eofbit if the stream is emptied.
02101        *
02102        *  @param  in  Start of input stream.
02103        *  @param  end  End of input stream.
02104        *  @param  io  Source of locale and flags.
02105        *  @param  err  Error flags to set.
02106        *  @param  v  Value to format and insert.
02107        *  @return  Iterator after reading.
02108       */
02109       iter_type
02110       get(iter_type __in, iter_type __end, ios_base& __io,
02111       ios_base::iostate& __err, void*& __v) const
02112       { return this->do_get(__in, __end, __io, __err, __v); }
02113 
02114     protected:
02115       /// Destructor.
02116       virtual ~num_get() { }
02117 
02118       iter_type
02119       _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
02120                string& __xtrc) const;
02121 
02122       template<typename _ValueT>
02123         iter_type
02124         _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
02125                _ValueT& __v) const;
02126 
02127       //@{
02128       /**
02129        *  @brief  Numeric parsing.
02130        *
02131        *  Parses the input stream into the variable @a v.  This function is a
02132        *  hook for derived classes to change the value returned.  @see get()
02133        *  for more details.
02134        *
02135        *  @param  in  Start of input stream.
02136        *  @param  end  End of input stream.
02137        *  @param  io  Source of locale and flags.
02138        *  @param  err  Error flags to set.
02139        *  @param  v  Value to format and insert.
02140        *  @return  Iterator after reading.
02141       */
02142       virtual iter_type
02143       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
02144 
02145 
02146       virtual iter_type
02147       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
02148 
02149       virtual iter_type
02150       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02151           unsigned short&) const;
02152 
02153       virtual iter_type
02154       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02155          unsigned int&) const;
02156 
02157       virtual iter_type
02158       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02159          unsigned long&) const;
02160 
02161 #ifdef _GLIBCXX_USE_LONG_LONG
02162       virtual iter_type
02163       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02164          long long&) const;
02165 
02166       virtual iter_type
02167       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02168          unsigned long long&) const;
02169 #endif
02170 
02171       virtual iter_type
02172       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02173          float&) const;
02174 
02175       virtual iter_type
02176       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02177          double&) const;
02178 
02179       virtual iter_type
02180       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02181          long double&) const;
02182 
02183       virtual iter_type
02184       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02185          void*&) const;
02186       //@}
02187     };
02188 
02189   template<typename _CharT, typename _InIter>
02190     locale::id num_get<_CharT, _InIter>::id;
02191 
02192 
02193   /**
02194    *  @brief  Facet for converting numbers to strings.
02195    *
02196    *  This facet encapsulates the code to convert a number to a string.  It is
02197    *  used by the ostream numeric insertion operators.
02198    *
02199    *  The num_put template uses protected virtual functions to provide the
02200    *  actual results.  The public accessors forward the call to the virtual
02201    *  functions.  These virtual functions are hooks for developers to
02202    *  implement the behavior they require from the num_put facet.
02203   */
02204   template<typename _CharT, typename _OutIter>
02205     class num_put : public locale::facet
02206     {
02207     public:
02208       // Types:
02209       //@{
02210       /// Public typedefs
02211       typedef _CharT        char_type;
02212       typedef _OutIter      iter_type;
02213       //@}
02214 
02215       /// Numpunct facet id.
02216       static locale::id     id;
02217 
02218       /**
02219        *  @brief  Constructor performs initialization.
02220        *
02221        *  This is the constructor provided by the standard.
02222        *
02223        *  @param refs  Passed to the base facet class.
02224       */
02225       explicit
02226       num_put(size_t __refs = 0) : facet(__refs) { }
02227 
02228       /**
02229        *  @brief  Numeric formatting.
02230        *
02231        *  Formats the boolean @a v and inserts it into a stream.  It does so
02232        *  by calling num_put::do_put().
02233        *
02234        *  If ios_base::boolalpha is set, writes ctype<CharT>::truename() or
02235        *  ctype<CharT>::falsename().  Otherwise formats @a v as an int.
02236        *
02237        *  @param  s  Stream to write to.
02238        *  @param  io  Source of locale and flags.
02239        *  @param  fill  Char_type to use for filling.
02240        *  @param  v  Value to format and insert.
02241        *  @return  Iterator after writing.
02242       */
02243       iter_type
02244       put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
02245       { return this->do_put(__s, __f, __fill, __v); }
02246 
02247       //@{
02248       /**
02249        *  @brief  Numeric formatting.
02250        *
02251        *  Formats the integral value @a v and inserts it into a
02252        *  stream.  It does so by calling num_put::do_put().
02253        *
02254        *  Formatting is affected by the flag settings in @a io.
02255        *
02256        *  The basic format is affected by the value of io.flags() &
02257        *  ios_base::basefield.  If equal to ios_base::oct, formats like the
02258        *  printf %o specifier.  Else if equal to ios_base::hex, formats like
02259        *  %x or %X with ios_base::uppercase unset or set respectively.
02260        *  Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu
02261        *  for unsigned values.  Note that if both oct and hex are set, neither
02262        *  will take effect.
02263        *
02264        *  If ios_base::showpos is set, '+' is output before positive values.
02265        *  If ios_base::showbase is set, '0' precedes octal values (except 0)
02266        *  and '0[xX]' precedes hex values.
02267        *
02268        *  Thousands separators are inserted according to numpunct::grouping()
02269        *  and numpunct::thousands_sep().  The decimal point character used is
02270        *  numpunct::decimal_point().
02271        *
02272        *  If io.width() is non-zero, enough @a fill characters are inserted to
02273        *  make the result at least that wide.  If
02274        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
02275        *  padded at the end.  If ios_base::internal, then padding occurs
02276        *  immediately after either a '+' or '-' or after '0x' or '0X'.
02277        *  Otherwise, padding occurs at the beginning.
02278        *
02279        *  @param  s  Stream to write to.
02280        *  @param  io  Source of locale and flags.
02281        *  @param  fill  Char_type to use for filling.
02282        *  @param  v  Value to format and insert.
02283        *  @return  Iterator after writing.
02284       */
02285       iter_type
02286       put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
02287       { return this->do_put(__s, __f, __fill, __v); }
02288 
02289       iter_type
02290       put(iter_type __s, ios_base& __f, char_type __fill,
02291       unsigned long __v) const
02292       { return this->do_put(__s, __f, __fill, __v); }
02293 
02294 #ifdef _GLIBCXX_USE_LONG_LONG
02295       iter_type
02296       put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
02297       { return this->do_put(__s, __f, __fill, __v); }
02298 
02299       iter_type
02300       put(iter_type __s, ios_base& __f, char_type __fill,
02301       unsigned long long __v) const
02302       { return this->do_put(__s, __f, __fill, __v); }
02303 #endif
02304       //@}
02305 
02306       //@{
02307       /**
02308        *  @brief  Numeric formatting.
02309        *
02310        *  Formats the floating point value @a v and inserts it into a stream.
02311        *  It does so by calling num_put::do_put().
02312        *
02313        *  Formatting is affected by the flag settings in @a io.
02314        *
02315        *  The basic format is affected by the value of io.flags() &
02316        *  ios_base::floatfield.  If equal to ios_base::fixed, formats like the
02317        *  printf %f specifier.  Else if equal to ios_base::scientific, formats
02318        *  like %e or %E with ios_base::uppercase unset or set respectively.
02319        *  Otherwise, formats like %g or %G depending on uppercase.  Note that
02320        *  if both fixed and scientific are set, the effect will also be like
02321        *  %g or %G.
02322        *
02323        *  The output precision is given by io.precision().  This precision is
02324        *  capped at numeric_limits::digits10 + 2 (different for double and
02325        *  long double).  The default precision is 6.
02326        *
02327        *  If ios_base::showpos is set, '+' is output before positive values.
02328        *  If ios_base::showpoint is set, a decimal point will always be
02329        *  output.
02330        *
02331        *  Thousands separators are inserted according to numpunct::grouping()
02332        *  and numpunct::thousands_sep().  The decimal point character used is
02333        *  numpunct::decimal_point().
02334        *
02335        *  If io.width() is non-zero, enough @a fill characters are inserted to
02336        *  make the result at least that wide.  If
02337        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
02338        *  padded at the end.  If ios_base::internal, then padding occurs
02339        *  immediately after either a '+' or '-' or after '0x' or '0X'.
02340        *  Otherwise, padding occurs at the beginning.
02341        *
02342        *  @param  s  Stream to write to.
02343        *  @param  io  Source of locale and flags.
02344        *  @param  fill  Char_type to use for filling.
02345        *  @param  v  Value to format and insert.
02346        *  @return  Iterator after writing.
02347       */
02348       iter_type
02349       put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
02350       { return this->do_put(__s, __f, __fill, __v); }
02351 
02352       iter_type
02353       put(iter_type __s, ios_base& __f, char_type __fill,
02354       long double __v) const
02355       { return this->do_put(__s, __f, __fill, __v); }
02356       //@}
02357 
02358       /**
02359        *  @brief  Numeric formatting.
02360        *
02361        *  Formats the pointer value @a v and inserts it into a stream.  It
02362        *  does so by calling num_put::do_put().
02363        *
02364        *  This function formats @a v as an unsigned long with ios_base::hex
02365        *  and ios_base::showbase set.
02366        *
02367        *  @param  s  Stream to write to.
02368        *  @param  io  Source of locale and flags.
02369        *  @param  fill  Char_type to use for filling.
02370        *  @param  v  Value to format and insert.
02371        *  @return  Iterator after writing.
02372       */
02373       iter_type
02374       put(iter_type __s, ios_base& __f, char_type __fill,
02375       const void* __v) const
02376       { return this->do_put(__s, __f, __fill, __v); }
02377 
02378     protected:
02379       template<typename _ValueT>
02380         iter_type
02381         _M_insert_float(iter_type, ios_base& __io, char_type __fill,
02382             char __mod, _ValueT __v) const;
02383 
02384       void
02385       _M_group_float(const char* __grouping, size_t __grouping_size,
02386              char_type __sep, const char_type* __p, char_type* __new,
02387              char_type* __cs, int& __len) const;
02388 
02389       template<typename _ValueT>
02390         iter_type
02391         _M_insert_int(iter_type, ios_base& __io, char_type __fill,
02392               _ValueT __v) const;
02393 
02394       void
02395       _M_group_int(const char* __grouping, size_t __grouping_size,
02396            char_type __sep, ios_base& __io, char_type* __new,
02397            char_type* __cs, int& __len) const;
02398 
02399       void
02400       _M_pad(char_type __fill, streamsize __w, ios_base& __io,
02401          char_type* __new, const char_type* __cs, int& __len) const;
02402 
02403       /// Destructor.
02404       virtual
02405       ~num_put() { };
02406 
02407       //@{
02408       /**
02409        *  @brief  Numeric formatting.
02410        *
02411        *  These functions do the work of formatting numeric values and
02412        *  inserting them into a stream. This function is a hook for derived
02413        *  classes to change the value returned.
02414        *
02415        *  @param  s  Stream to write to.
02416        *  @param  io  Source of locale and flags.
02417        *  @param  fill  Char_type to use for filling.
02418        *  @param  v  Value to format and insert.
02419        *  @return  Iterator after writing.
02420       */
02421       virtual iter_type
02422       do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
02423 
02424       virtual iter_type
02425       do_put(iter_type, ios_base&, char_type __fill, long __v) const;
02426 
02427       virtual iter_type
02428       do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
02429 
02430 #ifdef _GLIBCXX_USE_LONG_LONG
02431       virtual iter_type
02432       do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
02433 
02434       virtual iter_type
02435       do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
02436 #endif
02437 
02438       virtual iter_type
02439       do_put(iter_type, ios_base&, char_type __fill, double __v) const;
02440 
02441       virtual iter_type
02442       do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
02443 
02444       virtual iter_type
02445       do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
02446       //@}
02447     };
02448 
02449   template <typename _CharT, typename _OutIter>
02450     locale::id num_put<_CharT, _OutIter>::id;
02451 
02452 
02453   /**
02454    *  @brief  Facet for localized string comparison.
02455    *
02456    *  This facet encapsulates the code to compare strings in a localized
02457    *  manner.
02458    *
02459    *  The collate template uses protected virtual functions to provide
02460    *  the actual results.  The public accessors forward the call to
02461    *  the virtual functions.  These virtual functions are hooks for
02462    *  developers to implement the behavior they require from the
02463    *  collate facet.
02464   */
02465   template<typename _CharT>
02466     class collate : public locale::facet
02467     {
02468     public:
02469       // Types:
02470       //@{
02471       /// Public typedefs
02472       typedef _CharT            char_type;
02473       typedef basic_string<_CharT>  string_type;
02474       //@}
02475 
02476     protected:
02477       // Underlying "C" library locale information saved from
02478       // initialization, needed by collate_byname as well.
02479       __c_locale            _M_c_locale_collate;
02480 
02481     public:
02482       /// Numpunct facet id.
02483       static locale::id         id;
02484 
02485       /**
02486        *  @brief  Constructor performs initialization.
02487        *
02488        *  This is the constructor provided by the standard.
02489        *
02490        *  @param refs  Passed to the base facet class.
02491       */
02492       explicit
02493       collate(size_t __refs = 0)
02494       : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
02495       { }
02496 
02497       /**
02498        *  @brief  Internal constructor. Not for general use.
02499        *
02500        *  This is a constructor for use by the library itself to set up new
02501        *  locales.
02502        *
02503        *  @param cloc  The "C" locale.
02504        *  @param refs  Passed to the base facet class.
02505       */
02506       explicit
02507       collate(__c_locale __cloc, size_t __refs = 0)
02508       : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
02509       { }
02510 
02511       /**
02512        *  @brief  Compare two strings.
02513        *
02514        *  This function compares two strings and returns the result by calling
02515        *  collate::do_compare().
02516        *
02517        *  @param lo1  Start of string 1.
02518        *  @param hi1  End of string 1.
02519        *  @param lo2  Start of string 2.
02520        *  @param hi2  End of string 2.
02521        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
02522       */
02523       int
02524       compare(const _CharT* __lo1, const _CharT* __hi1,
02525           const _CharT* __lo2, const _CharT* __hi2) const
02526       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
02527 
02528       /**
02529        *  @brief  Transform string to comparable form.
02530        *
02531        *  This function is a wrapper for strxfrm functionality.  It takes the
02532        *  input string and returns a modified string that can be directly
02533        *  compared to other transformed strings.  In the "C" locale, this
02534        *  function just returns a copy of the input string.  In some other
02535        *  locales, it may replace two chars with one, change a char for
02536        *  another, etc.  It does so by returning collate::do_transform().
02537        *
02538        *  @param lo  Start of string.
02539        *  @param hi  End of string.
02540        *  @return  Transformed string_type.
02541       */
02542       string_type
02543       transform(const _CharT* __lo, const _CharT* __hi) const
02544       { return this->do_transform(__lo, __hi); }
02545 
02546       /**
02547        *  @brief  Return hash of a string.
02548        *
02549        *  This function computes and returns a hash on the input string.  It
02550        *  does so by returning collate::do_hash().
02551        *
02552        *  @param lo  Start of string.
02553        *  @param hi  End of string.
02554        *  @return  Hash value.
02555       */
02556       long
02557       hash(const _CharT* __lo, const _CharT* __hi) const
02558       { return this->do_hash(__lo, __hi); }
02559 
02560       // Used to abstract out _CharT bits in virtual member functions, below.
02561       int
02562       _M_compare(const _CharT*, const _CharT*) const;
02563 
02564       size_t
02565       _M_transform(_CharT*, const _CharT*, size_t) const;
02566 
02567   protected:
02568       /// Destructor.
02569       virtual
02570       ~collate()
02571       { _S_destroy_c_locale(_M_c_locale_collate); }
02572 
02573       /**
02574        *  @brief  Compare two strings.
02575        *
02576        *  This function is a hook for derived classes to change the value
02577        *  returned.  @see compare().
02578        *
02579        *  @param lo1  Start of string 1.
02580        *  @param hi1  End of string 1.
02581        *  @param lo2  Start of string 2.
02582        *  @param hi2  End of string 2.
02583        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
02584       */
02585       virtual int
02586       do_compare(const _CharT* __lo1, const _CharT* __hi1,
02587          const _CharT* __lo2, const _CharT* __hi2) const;
02588 
02589       /**
02590        *  @brief  Transform string to comparable form.
02591        *
02592        *  This function is a hook for derived classes to change the value
02593        *  returned.
02594        *
02595        *  @param lo1  Start of string 1.
02596        *  @param hi1  End of string 1.
02597        *  @param lo2  Start of string 2.
02598        *  @param hi2  End of string 2.
02599        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
02600       */
02601       virtual string_type
02602       do_transform(const _CharT* __lo, const _CharT* __hi) const;
02603 
02604       /**
02605        *  @brief  Return hash of a string.
02606        *
02607        *  This function computes and returns a hash on the input string.  This
02608        *  function is a hook for derived classes to change the value returned.
02609        *
02610        *  @param lo  Start of string.
02611        *  @param hi  End of string.
02612        *  @return  Hash value.
02613       */
02614       virtual long
02615       do_hash(const _CharT* __lo, const _CharT* __hi) const;
02616     };
02617 
02618   template<typename _CharT>
02619     locale::id collate<_CharT>::id;
02620 
02621   // Specializations.
02622   template<>
02623     int
02624     collate<char>::_M_compare(const char*, const char*) const;
02625 
02626   template<>
02627     size_t
02628     collate<char>::_M_transform(char*, const char*, size_t) const;
02629 
02630 #ifdef _GLIBCXX_USE_WCHAR_T
02631   template<>
02632     int
02633     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
02634 
02635   template<>
02636     size_t
02637     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
02638 #endif
02639 
02640   /// @brief  class collate_byname [22.2.4.2].
02641   template<typename _CharT>
02642     class collate_byname : public collate<_CharT>
02643     {
02644     public:
02645       //@{
02646       /// Public typedefs
02647       typedef _CharT               char_type;
02648       typedef basic_string<_CharT> string_type;
02649       //@}
02650 
02651       explicit
02652       collate_byname(const char* __s, size_t __refs = 0)
02653       : collate<_CharT>(__refs)
02654       {
02655     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
02656       {
02657         this->_S_destroy_c_locale(this->_M_c_locale_collate);
02658         this->_S_create_c_locale(this->_M_c_locale_collate, __s);
02659       }
02660       }
02661 
02662     protected:
02663       virtual
02664       ~collate_byname() { }
02665     };
02666 
02667 
02668   /**
02669    *  @brief  Time format ordering data.
02670    *
02671    *  This class provides an enum representing different orderings of day,
02672    *  month, and year.
02673   */
02674   class time_base
02675   {
02676   public:
02677     enum dateorder { no_order, dmy, mdy, ymd, ydm };
02678   };
02679 
02680   template<typename _CharT>
02681     struct __timepunct_cache : public locale::facet
02682     {
02683       // List of all known timezones, with GMT first.
02684       static const _CharT*      _S_timezones[14];
02685 
02686       const _CharT*         _M_date_format;
02687       const _CharT*         _M_date_era_format;
02688       const _CharT*         _M_time_format;
02689       const _CharT*         _M_time_era_format;
02690       const _CharT*         _M_date_time_format;
02691       const _CharT*         _M_date_time_era_format;
02692       const _CharT*         _M_am;
02693       const _CharT*         _M_pm;
02694       const _CharT*         _M_am_pm_format;
02695 
02696       // Day names, starting with "C"'s Sunday.
02697       const _CharT*         _M_day1;
02698       const _CharT*         _M_day2;
02699       const _CharT*         _M_day3;
02700       const _CharT*         _M_day4;
02701       const _CharT*         _M_day5;
02702       const _CharT*         _M_day6;
02703       const _CharT*         _M_day7;
02704 
02705       // Abbreviated day names, starting with "C"'s Sun.
02706       const _CharT*         _M_aday1;
02707       const _CharT*         _M_aday2;
02708       const _CharT*         _M_aday3;
02709       const _CharT*         _M_aday4;
02710       const _CharT*         _M_aday5;
02711       const _CharT*         _M_aday6;
02712       const _CharT*         _M_aday7;
02713 
02714       // Month names, starting with "C"'s January.
02715       const _CharT*         _M_month01;
02716       const _CharT*         _M_month02;
02717       const _CharT*         _M_month03;
02718       const _CharT*         _M_month04;
02719       const _CharT*         _M_month05;
02720       const _CharT*         _M_month06;
02721       const _CharT*         _M_month07;
02722       const _CharT*         _M_month08;
02723       const _CharT*         _M_month09;
02724       const _CharT*         _M_month10;
02725       const _CharT*         _M_month11;
02726       const _CharT*         _M_month12;
02727 
02728       // Abbreviated month names, starting with "C"'s Jan.
02729       const _CharT*         _M_amonth01;
02730       const _CharT*         _M_amonth02;
02731       const _CharT*         _M_amonth03;
02732       const _CharT*         _M_amonth04;
02733       const _CharT*         _M_amonth05;
02734       const _CharT*         _M_amonth06;
02735       const _CharT*         _M_amonth07;
02736       const _CharT*         _M_amonth08;
02737       const _CharT*         _M_amonth09;
02738       const _CharT*         _M_amonth10;
02739       const _CharT*         _M_amonth11;
02740       const _CharT*         _M_amonth12;
02741 
02742       bool              _M_allocated;
02743 
02744       __timepunct_cache(size_t __refs = 0) : facet(__refs),
02745       _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL),
02746       _M_time_era_format(NULL), _M_date_time_format(NULL),
02747       _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL),
02748       _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL),
02749       _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL),
02750       _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL),
02751       _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL),
02752       _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL),
02753       _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL),
02754       _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL),
02755       _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL),
02756       _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL),
02757       _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL),
02758       _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false)
02759       { }
02760 
02761       ~__timepunct_cache();
02762 
02763       void
02764       _M_cache(const locale& __loc);
02765 
02766     private:
02767       __timepunct_cache&
02768       operator=(const __timepunct_cache&);
02769       
02770       explicit
02771       __timepunct_cache(const __timepunct_cache&);
02772     };
02773 
02774   template<typename _CharT>
02775     __timepunct_cache<_CharT>::~__timepunct_cache()
02776     {
02777       if (_M_allocated)
02778     {
02779       // Unused.
02780     }
02781     }
02782 
02783   // Specializations.
02784   template<>
02785     const char*
02786     __timepunct_cache<char>::_S_timezones[14];
02787 
02788 #ifdef _GLIBCXX_USE_WCHAR_T
02789   template<>
02790     const wchar_t*
02791     __timepunct_cache<wchar_t>::_S_timezones[14];
02792 #endif
02793 
02794   // Generic.
02795   template<typename _CharT>
02796     const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];
02797 
02798   template<typename _CharT>
02799     class __timepunct : public locale::facet
02800     {
02801     public:
02802       // Types:
02803       typedef _CharT            __char_type;
02804       typedef basic_string<_CharT>  __string_type;
02805       typedef __timepunct_cache<_CharT> __cache_type;
02806 
02807     protected:
02808       __cache_type*         _M_data;
02809       __c_locale            _M_c_locale_timepunct;
02810       const char*           _M_name_timepunct;
02811 
02812     public:
02813       /// Numpunct facet id.
02814       static locale::id         id;
02815 
02816       explicit
02817       __timepunct(size_t __refs = 0);
02818 
02819       explicit
02820       __timepunct(__cache_type* __cache, size_t __refs = 0);
02821 
02822       /**
02823        *  @brief  Internal constructor. Not for general use.
02824        *
02825        *  This is a constructor for use by the library itself to set up new
02826        *  locales.
02827        *
02828        *  @param cloc  The "C" locale.
02829        *  @param s  The name of a locale.
02830        *  @param refs  Passed to the base facet class.
02831       */
02832       explicit
02833       __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
02834 
02835       // FIXME: for error checking purposes _M_put should return the return
02836       // value of strftime/wcsftime.
02837       void
02838       _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
02839          const tm* __tm) const;
02840 
02841       void
02842       _M_date_formats(const _CharT** __date) const
02843       {
02844     // Always have default first.
02845     __date[0] = _M_data->_M_date_format;
02846     __date[1] = _M_data->_M_date_era_format;
02847       }
02848 
02849       void
02850       _M_time_formats(const _CharT** __time) const
02851       {
02852     // Always have default first.
02853     __time[0] = _M_data->_M_time_format;
02854     __time[1] = _M_data->_M_time_era_format;
02855       }
02856 
02857       void
02858       _M_date_time_formats(const _CharT** __dt) const
02859       {
02860     // Always have default first.
02861     __dt[0] = _M_data->_M_date_time_format;
02862     __dt[1] = _M_data->_M_date_time_era_format;
02863       }
02864 
02865       void
02866       _M_am_pm_format(const _CharT* __ampm) const
02867       { __ampm = _M_data->_M_am_pm_format; }
02868 
02869       void
02870       _M_am_pm(const _CharT** __ampm) const
02871       {
02872     __ampm[0] = _M_data->_M_am;
02873     __ampm[1] = _M_data->_M_pm;
02874       }
02875 
02876       void
02877       _M_days(const _CharT** __days) const
02878       {
02879     __days[0] = _M_data->_M_day1;
02880     __days[1] = _M_data->_M_day2;
02881     __days[2] = _M_data->_M_day3;
02882     __days[3] = _M_data->_M_day4;
02883     __days[4] = _M_data->_M_day5;
02884     __days[5] = _M_data->_M_day6;
02885     __days[6] = _M_data->_M_day7;
02886       }
02887 
02888       void
02889       _M_days_abbreviated(const _CharT** __days) const
02890       {
02891     __days[0] = _M_data->_M_aday1;
02892     __days[1] = _M_data->_M_aday2;
02893     __days[2] = _M_data->_M_aday3;
02894     __days[3] = _M_data->_M_aday4;
02895     __days[4] = _M_data->_M_aday5;
02896     __days[5] = _M_data->_M_aday6;
02897     __days[6] = _M_data->_M_aday7;
02898       }
02899 
02900       void
02901       _M_months(const _CharT** __months) const
02902       {
02903     __months[0] = _M_data->_M_month01;
02904     __months[1] = _M_data->_M_month02;
02905     __months[2] = _M_data->_M_month03;
02906     __months[3] = _M_data->_M_month04;
02907     __months[4] = _M_data->_M_month05;
02908     __months[5] = _M_data->_M_month06;
02909     __months[6] = _M_data->_M_month07;
02910     __months[7] = _M_data->_M_month08;
02911     __months[8] = _M_data->_M_month09;
02912     __months[9] = _M_data->_M_month10;
02913     __months[10] = _M_data->_M_month11;
02914     __months[11] = _M_data->_M_month12;
02915       }
02916 
02917       void
02918       _M_months_abbreviated(const _CharT** __months) const
02919       {
02920     __months[0] = _M_data->_M_amonth01;
02921     __months[1] = _M_data->_M_amonth02;
02922     __months[2] = _M_data->_M_amonth03;
02923     __months[3] = _M_data->_M_amonth04;
02924     __months[4] = _M_data->_M_amonth05;
02925     __months[5] = _M_data->_M_amonth06;
02926     __months[6] = _M_data->_M_amonth07;
02927     __months[7] = _M_data->_M_amonth08;
02928     __months[8] = _M_data->_M_amonth09;
02929     __months[9] = _M_data->_M_amonth10;
02930     __months[10] = _M_data->_M_amonth11;
02931     __months[11] = _M_data->_M_amonth12;
02932       }
02933 
02934     protected:
02935       virtual
02936       ~__timepunct();
02937 
02938       // For use at construction time only.
02939       void
02940       _M_initialize_timepunct(__c_locale __cloc = NULL);
02941     };
02942 
02943   template<typename _CharT>
02944     locale::id __timepunct<_CharT>::id;
02945 
02946   // Specializations.
02947   template<>
02948     void
02949     __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
02950 
02951   template<>
02952     void
02953     __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
02954 
02955 #ifdef _GLIBCXX_USE_WCHAR_T
02956   template<>
02957     void
02958     __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
02959 
02960   template<>
02961     void
02962     __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
02963                  const tm*) const;
02964 #endif
02965 
02966   // Include host and configuration specific timepunct functions.
02967   #include <bits/time_members.h>
02968 
02969   /**
02970    *  @brief  Facet for parsing dates and times.
02971    *
02972    *  This facet encapsulates the code to parse and return a date or
02973    *  time from a string.  It is used by the istream numeric
02974    *  extraction operators.
02975    *
02976    *  The time_get template uses protected virtual functions to provide the
02977    *  actual results.  The public accessors forward the call to the virtual
02978    *  functions.  These virtual functions are hooks for developers to
02979    *  implement the behavior they require from the time_get facet.
02980   */
02981   template<typename _CharT, typename _InIter>
02982     class time_get : public locale::facet, public time_base
02983     {
02984     public:
02985       // Types:
02986       //@{
02987       /// Public typedefs
02988       typedef _CharT            char_type;
02989       typedef _InIter           iter_type;
02990       //@}
02991       typedef basic_string<_CharT>  __string_type;
02992 
02993       /// Numpunct facet id.
02994       static locale::id         id;
02995 
02996       /**
02997        *  @brief  Constructor performs initialization.
02998        *
02999        *  This is the constructor provided by the standard.
03000        *
03001        *  @param refs  Passed to the base facet class.
03002       */
03003       explicit
03004       time_get(size_t __refs = 0)
03005       : facet (__refs) { }
03006 
03007       /**
03008        *  @brief  Return preferred order of month, day, and year.
03009        *
03010        *  This function returns an enum from timebase::dateorder giving the
03011        *  preferred ordering if the format "x" given to time_put::put() only
03012        *  uses month, day, and year.  If the format "x" for the associated
03013        *  locale uses other fields, this function returns
03014        *  timebase::dateorder::noorder.
03015        *
03016        *  NOTE: The library always returns noorder at the moment.
03017        *
03018        *  @return  A member of timebase::dateorder.
03019       */
03020       dateorder
03021       date_order()  const
03022       { return this->do_date_order(); }
03023 
03024       /**
03025        *  @brief  Parse input time string.
03026        *
03027        *  This function parses a time according to the format "x" and puts the
03028        *  results into a user-supplied struct tm.  The result is returned by
03029        *  calling time_get::do_get_time().
03030        *
03031        *  If there is a valid time string according to format "x", @a tm will
03032        *  be filled in accordingly and the returned iterator will point to the
03033        *  first character beyond the time string.  If an error occurs before
03034        *  the end, err |= ios_base::failbit.  If parsing reads all the
03035        *  characters, err |= ios_base::eofbit.
03036        *
03037        *  @param  beg  Start of string to parse.
03038        *  @param  end  End of string to parse.
03039        *  @param  io  Source of the locale.
03040        *  @param  err  Error flags to set.
03041        *  @param  tm  Pointer to struct tm to fill in.
03042        *  @return  Iterator to first char beyond time string.
03043       */
03044       iter_type
03045       get_time(iter_type __beg, iter_type __end, ios_base& __io,
03046            ios_base::iostate& __err, tm* __tm)  const
03047       { return this->do_get_time(__beg, __end, __io, __err, __tm); }
03048 
03049       /**
03050        *  @brief  Parse input date string.
03051        *
03052        *  This function parses a date according to the format "X" and puts the
03053        *  results into a user-supplied struct tm.  The result is returned by
03054        *  calling time_get::do_get_date().
03055        *
03056        *  If there is a valid date string according to format "X", @a tm will
03057        *  be filled in accordingly and the returned iterator will point to the
03058        *  first character beyond the date string.  If an error occurs before
03059        *  the end, err |= ios_base::failbit.  If parsing reads all the
03060        *  characters, err |= ios_base::eofbit.
03061        *
03062        *  @param  beg  Start of string to parse.
03063        *  @param  end  End of string to parse.
03064        *  @param  io  Source of the locale.
03065        *  @param  err  Error flags to set.
03066        *  @param  tm  Pointer to struct tm to fill in.
03067        *  @return  Iterator to first char beyond date string.
03068       */
03069       iter_type
03070       get_date(iter_type __beg, iter_type __end, ios_base& __io,
03071            ios_base::iostate& __err, tm* __tm)  const
03072       { return this->do_get_date(__beg, __end, __io, __err, __tm); }
03073 
03074       /**
03075        *  @brief  Parse input weekday string.
03076        *
03077        *  This function parses a weekday name and puts the results into a
03078        *  user-supplied struct tm.  The result is returned by calling
03079        *  time_get::do_get_weekday().
03080        *
03081        *  Parsing starts by parsing an abbreviated weekday name.  If a valid
03082        *  abbreviation is followed by a character that would lead to the full
03083        *  weekday name, parsing continues until the full name is found or an
03084        *  error occurs.  Otherwise parsing finishes at the end of the
03085        *  abbreviated name.
03086        *
03087        *  If an error occurs before the end, err |= ios_base::failbit.  If
03088        *  parsing reads all the characters, err |= ios_base::eofbit.
03089        *
03090        *  @param  beg  Start of string to parse.
03091        *  @param  end  End of string to parse.
03092        *  @param  io  Source of the locale.
03093        *  @param  err  Error flags to set.
03094        *  @param  tm  Pointer to struct tm to fill in.
03095        *  @return  Iterator to first char beyond weekday name.
03096       */
03097       iter_type
03098       get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
03099           ios_base::iostate& __err, tm* __tm) const
03100       { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
03101 
03102       /**
03103        *  @brief  Parse input month string.
03104        *
03105        *  This function parses a month name and puts the results into a
03106        *  user-supplied struct tm.  The result is returned by calling
03107        *  time_get::do_get_monthname().
03108        *
03109        *  Parsing starts by parsing an abbreviated month name.  If a valid
03110        *  abbreviation is followed by a character that would lead to the full
03111        *  month name, parsing continues until the full name is found or an
03112        *  error occurs.  Otherwise parsing finishes at the end of the
03113        *  abbreviated name.
03114        *
03115        *  If an error occurs before the end, err |= ios_base::failbit.  If
03116        *  parsing reads all the characters, err |=
03117        *  ios_base::eofbit.
03118        *
03119        *  @param  beg  Start of string to parse.
03120        *  @param  end  End of string to parse.
03121        *  @param  io  Source of the locale.
03122        *  @param  err  Error flags to set.
03123        *  @param  tm  Pointer to struct tm to fill in.
03124        *  @return  Iterator to first char beyond month name.
03125       */
03126       iter_type
03127       get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
03128             ios_base::iostate& __err, tm* __tm) const
03129       { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
03130 
03131       /**
03132        *  @brief  Parse input year string.
03133        *
03134        *  This function reads up to 4 characters to parse a year string and
03135        *  puts the results into a user-supplied struct tm.  The result is
03136        *  returned by calling time_get::do_get_year().
03137        *
03138        *  4 consecutive digits are interpreted as a full year.  If there are
03139        *  exactly 2 consecutive digits, the library interprets this as the
03140        *  number of years since 1900.
03141        *
03142        *  If an error occurs before the end, err |= ios_base::failbit.  If
03143        *  parsing reads all the characters, err |= ios_base::eofbit.
03144        *
03145        *  @param  beg  Start of string to parse.
03146        *  @param  end  End of string to parse.
03147        *  @param  io  Source of the locale.
03148        *  @param  err  Error flags to set.
03149        *  @param  tm  Pointer to struct tm to fill in.
03150        *  @return  Iterator to first char beyond year.
03151       */
03152       iter_type
03153       get_year(iter_type __beg, iter_type __end, ios_base& __io,
03154            ios_base::iostate& __err, tm* __tm) const
03155       { return this->do_get_year(__beg, __end, __io, __err, __tm); }
03156 
03157     protected:
03158       /// Destructor.
03159       virtual
03160       ~time_get() { }
03161 
03162       /**
03163        *  @brief  Return preferred order of month, day, and year.
03164        *
03165        *  This function returns an enum from timebase::dateorder giving the
03166        *  preferred ordering if the format "x" given to time_put::put() only
03167        *  uses month, day, and year.  This function is a hook for derived
03168        *  classes to change the value returned.
03169        *
03170        *  @return  A member of timebase::dateorder.
03171       */
03172       virtual dateorder
03173       do_date_order() const;
03174 
03175       /**
03176        *  @brief  Parse input time string.
03177        *
03178        *  This function parses a time according to the format "x" and puts the
03179        *  results into a user-supplied struct tm.  This function is a hook for
03180        *  derived classes to change the value returned.  @see get_time() for
03181        *  details.
03182        *
03183        *  @param  beg  Start of string to parse.
03184        *  @param  end  End of string to parse.
03185        *  @param  io  Source of the locale.
03186        *  @param  err  Error flags to set.
03187        *  @param  tm  Pointer to struct tm to fill in.
03188        *  @return  Iterator to first char beyond time string.
03189       */
03190       virtual iter_type
03191       do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
03192           ios_base::iostate& __err, tm* __tm) const;
03193 
03194       /**
03195        *  @brief  Parse input date string.
03196        *
03197        *  This function parses a date according to the format "X" and puts the
03198        *  results into a user-supplied struct tm.  This function is a hook for
03199        *  derived classes to change the value returned.  @see get_date() for
03200        *  details.
03201        *
03202        *  @param  beg  Start of string to parse.
03203        *  @param  end  End of string to parse.
03204        *  @param  io  Source of the locale.
03205        *  @param  err  Error flags to set.
03206        *  @param  tm  Pointer to struct tm to fill in.
03207        *  @return  Iterator to first char beyond date string.
03208       */
03209       virtual iter_type
03210       do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
03211           ios_base::iostate& __err, tm* __tm) const;
03212 
03213       /**
03214        *  @brief  Parse input weekday string.
03215        *
03216        *  This function parses a weekday name and puts the results into a
03217        *  user-supplied struct tm.  This function is a hook for derived
03218        *  classes to change the value returned.  @see get_weekday() for
03219        *  details.
03220        *
03221        *  @param  beg  Start of string to parse.
03222        *  @param  end  End of string to parse.
03223        *  @param  io  Source of the locale.
03224        *  @param  err  Error flags to set.
03225        *  @param  tm  Pointer to struct tm to fill in.
03226        *  @return  Iterator to first char beyond weekday name.
03227       */
03228       virtual iter_type
03229       do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
03230              ios_base::iostate& __err, tm* __tm) const;
03231 
03232       /**
03233        *  @brief  Parse input month string.
03234        *
03235        *  This function parses a month name and puts the results into a
03236        *  user-supplied struct tm.  This function is a hook for derived
03237        *  classes to change the value returned.  @see get_monthname() for
03238        *  details.
03239        *
03240        *  @param  beg  Start of string to parse.
03241        *  @param  end  End of string to parse.
03242        *  @param  io  Source of the locale.
03243        *  @param  err  Error flags to set.
03244        *  @param  tm  Pointer to struct tm to fill in.
03245        *  @return  Iterator to first char beyond month name.
03246       */
03247       virtual iter_type
03248       do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
03249                ios_base::iostate& __err, tm* __tm) const;
03250 
03251       /**
03252        *  @brief  Parse input year string.
03253        *
03254        *  This function reads up to 4 characters to parse a year string and
03255        *  puts the results into a user-supplied struct tm.  This function is a
03256        *  hook for derived classes to change the value returned.  @see
03257        *  get_year() for details.
03258        *
03259        *  @param  beg  Start of string to parse.
03260        *  @param  end  End of string to parse.
03261        *  @param  io  Source of the locale.
03262        *  @param  err  Error flags to set.
03263        *  @param  tm  Pointer to struct tm to fill in.
03264        *  @return  Iterator to first char beyond year.
03265       */
03266       virtual iter_type
03267       do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
03268           ios_base::iostate& __err, tm* __tm) const;
03269 
03270       // Extract numeric component of length __len.
03271       iter_type
03272       _M_extract_num(iter_type __beg, iter_type __end, int& __member,
03273              int __min, int __max, size_t __len,
03274              ios_base& __io, ios_base::iostate& __err) const;
03275 
03276       // Extract day or month name, or any unique array of string
03277       // literals in a const _CharT* array.
03278       iter_type
03279       _M_extract_name(iter_type __beg, iter_type __end, int& __member,
03280               const _CharT** __names, size_t __indexlen,
03281               ios_base& __io, ios_base::iostate& __err) const;
03282 
03283       // Extract on a component-by-component basis, via __format argument.
03284       iter_type
03285       _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
03286                 ios_base::iostate& __err, tm* __tm,
03287                 const _CharT* __format) const;
03288     };
03289 
03290   template<typename _CharT, typename _InIter>
03291     locale::id time_get<_CharT, _InIter>::id;
03292 
03293   /// @brief  class time_get_byname [22.2.5.2].
03294   template<typename _CharT, typename _InIter>
03295     class time_get_byname : public time_get<_CharT, _InIter>
03296     {
03297     public:
03298       // Types:
03299       typedef _CharT            char_type;
03300       typedef _InIter           iter_type;
03301 
03302       explicit
03303       time_get_byname(const char*, size_t __refs = 0)
03304       : time_get<_CharT, _InIter>(__refs) { }
03305 
03306     protected:
03307       virtual
03308       ~time_get_byname() { }
03309     };
03310 
03311   /**
03312    *  @brief  Facet for outputting dates and times.
03313    *
03314    *  This facet encapsulates the code to format and output dates and times
03315    *  according to formats used by strftime().
03316    *
03317    *  The time_put template uses protected virtual functions to provide the
03318    *  actual results.  The public accessors forward the call to the virtual
03319    *  functions.  These virtual functions are hooks for developers to
03320    *  implement the behavior they require from the time_put facet.
03321   */
03322   template<typename _CharT, typename _OutIter>
03323     class time_put : public locale::facet
03324     {
03325     public:
03326       // Types:
03327       //@{
03328       /// Public typedefs
03329       typedef _CharT            char_type;
03330       typedef _OutIter          iter_type;
03331       //@}
03332 
03333       /// Numpunct facet id.
03334       static locale::id         id;
03335 
03336       /**
03337        *  @brief  Constructor performs initialization.
03338        *
03339        *  This is the constructor provided by the standard.
03340        *
03341        *  @param refs  Passed to the base facet class.
03342       */
03343       explicit
03344       time_put(size_t __refs = 0)
03345       : facet(__refs) { }
03346 
03347       /**
03348        *  @brief  Format and output a time or date.
03349        *
03350        *  This function formats the data in struct tm according to the
03351        *  provided format string.  The format string is interpreted as by
03352        *  strftime().
03353        *
03354        *  @param  s  The stream to write to.
03355        *  @param  io  Source of locale.
03356        *  @param  fill  char_type to use for padding.
03357        *  @param  tm  Struct tm with date and time info to format.
03358        *  @param  beg  Start of format string.
03359        *  @param  end  End of format string.
03360        *  @return  Iterator after writing.
03361        */
03362       iter_type
03363       put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
03364       const _CharT* __beg, const _CharT* __end) const;
03365 
03366       /**
03367        *  @brief  Format and output a time or date.
03368        *
03369        *  This function formats the data in struct tm according to the
03370        *  provided format char and optional modifier.  The format and modifier
03371        *  are interpreted as by strftime().  It does so by returning
03372        *  time_put::do_put().
03373        *
03374        *  @param  s  The stream to write to.
03375        *  @param  io  Source of locale.
03376        *  @param  fill  char_type to use for padding.
03377        *  @param  tm  Struct tm with date and time info to format.
03378        *  @param  format  Format char.
03379        *  @param  mod  Optional modifier char.
03380        *  @return  Iterator after writing.
03381        */
03382       iter_type
03383       put(iter_type __s, ios_base& __io, char_type __fill,
03384       const tm* __tm, char __format, char __mod = 0) const
03385       { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
03386 
03387     protected:
03388       /// Destructor.
03389       virtual
03390       ~time_put()
03391       { }
03392 
03393       /**
03394        *  @brief  Format and output a time or date.
03395        *
03396        *  This function formats the data in struct tm according to the
03397        *  provided format char and optional modifier.  This function is a hook
03398        *  for derived classes to change the value returned.  @see put() for
03399        *  more details.
03400        *
03401        *  @param  s  The stream to write to.
03402        *  @param  io  Source of locale.
03403        *  @param  fill  char_type to use for padding.
03404        *  @param  tm  Struct tm with date and time info to format.
03405        *  @param  format  Format char.
03406        *  @param  mod  Optional modifier char.
03407        *  @return  Iterator after writing.
03408        */
03409       virtual iter_type
03410       do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
03411          char __format, char __mod) const;
03412     };
03413 
03414   template<typename _CharT, typename _OutIter>
03415     locale::id time_put<_CharT, _OutIter>::id;
03416 
03417   /// @brief  class time_put_byname [22.2.5.4].
03418   template<typename _CharT, typename _OutIter>
03419     class time_put_byname : public time_put<_CharT, _OutIter>
03420     {
03421     public:
03422       // Types:
03423       typedef _CharT            char_type;
03424       typedef _OutIter          iter_type;
03425 
03426       explicit
03427       time_put_byname(const char*, size_t __refs = 0)
03428       : time_put<_CharT, _OutIter>(__refs)
03429       { };
03430 
03431     protected:
03432       virtual
03433       ~time_put_byname() { }
03434     };
03435 
03436 
03437   /**
03438    *  @brief  Money format ordering data.
03439    *
03440    *  This class contains an ordered array of 4 fields to represent the
03441    *  pattern for formatting a money amount.  Each field may contain one entry
03442    *  from the part enum.  symbol, sign, and value must be present and the
03443    *  remaining field must contain either none or space.  @see
03444    *  moneypunct::pos_format() and moneypunct::neg_format() for details of how
03445    *  these fields are interpreted.
03446   */
03447   class money_base
03448   {
03449   public:
03450     enum part { none, space, symbol, sign, value };
03451     struct pattern { char field[4]; };
03452 
03453     static const pattern _S_default_pattern;
03454 
03455     enum
03456     {
03457       _S_minus,
03458       _S_zero,
03459       _S_end = 11
03460     };
03461 
03462     // String literal of acceptable (narrow) input/output, for
03463     // money_get/money_put. "-0123456789"
03464     static const char* _S_atoms;
03465 
03466     // Construct and return valid pattern consisting of some combination of:
03467     // space none symbol sign value
03468     static pattern
03469     _S_construct_pattern(char __precedes, char __space, char __posn);
03470   };
03471 
03472   template<typename _CharT, bool _Intl>
03473     struct __moneypunct_cache : public locale::facet
03474     {
03475       const char*           _M_grouping;
03476       size_t                            _M_grouping_size;
03477       bool              _M_use_grouping;
03478       _CharT                _M_decimal_point;
03479       _CharT                _M_thousands_sep;
03480       const _CharT*         _M_curr_symbol;
03481       size_t                            _M_curr_symbol_size;
03482       const _CharT*         _M_positive_sign;
03483       size_t                            _M_positive_sign_size;
03484       const _CharT*         _M_negative_sign;
03485       size_t                            _M_negative_sign_size;
03486       int               _M_frac_digits;
03487       money_base::pattern       _M_pos_format;
03488       money_base::pattern           _M_neg_format;
03489 
03490       // A list of valid numeric literals for input and output: in the standard
03491       // "C" locale, this is "-0123456789". This array contains the chars after
03492       // having been passed through the current locale's ctype<_CharT>.widen().
03493       _CharT                _M_atoms[money_base::_S_end];
03494 
03495       bool              _M_allocated;
03496 
03497       __moneypunct_cache(size_t __refs = 0) : facet(__refs),
03498       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
03499       _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),
03500       _M_curr_symbol(NULL), _M_curr_symbol_size(0),
03501       _M_positive_sign(NULL), _M_positive_sign_size(0),
03502       _M_negative_sign(NULL), _M_negative_sign_size(0),
03503       _M_frac_digits(0),
03504       _M_pos_format(money_base::pattern()),
03505       _M_neg_format(money_base::pattern()), _M_allocated(false)
03506       { }
03507 
03508       ~__moneypunct_cache();
03509 
03510       void
03511       _M_cache(const locale& __loc);
03512 
03513     private:
03514       __moneypunct_cache&
03515       operator=(const __moneypunct_cache&);
03516       
03517       explicit
03518       __moneypunct_cache(const __moneypunct_cache&);
03519     };
03520 
03521   template<typename _CharT, bool _Intl>
03522     __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache()
03523     {
03524       if (_M_allocated)
03525     {
03526       delete [] _M_grouping;
03527       delete [] _M_curr_symbol;
03528       delete [] _M_positive_sign;
03529       delete [] _M_negative_sign;
03530     }
03531     }
03532 
03533   /**
03534    *  @brief  Facet for formatting data for money amounts.
03535    *
03536    *  This facet encapsulates the punctuation, grouping and other formatting
03537    *  features of money amount string representations.
03538   */
03539   template<typename _CharT, bool _Intl>
03540     class moneypunct : public locale::facet, public money_base
03541     {
03542     public:
03543       // Types:
03544       //@{
03545       /// Public typedefs
03546       typedef _CharT            char_type;
03547       typedef basic_string<_CharT>  string_type;
03548       //@}
03549       typedef __moneypunct_cache<_CharT, _Intl>     __cache_type;
03550 
03551     private:
03552       __cache_type*         _M_data;
03553 
03554     public:
03555       /// This value is provided by the standard, but no reason for its
03556       /// existence.
03557       static const bool         intl = _Intl;
03558       /// Numpunct facet id.
03559       static locale::id         id;
03560 
03561       /**
03562        *  @brief  Constructor performs initialization.
03563        *
03564        *  This is the constructor provided by the standard.
03565        *
03566        *  @param refs  Passed to the base facet class.
03567       */
03568       explicit
03569       moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
03570       { _M_initialize_moneypunct(); }
03571 
03572       /**
03573        *  @brief  Constructor performs initialization.
03574        *
03575        *  This is an internal constructor.
03576        *
03577        *  @param cache  Cache for optimization.
03578        *  @param refs  Passed to the base facet class.
03579       */
03580       explicit
03581       moneypunct(__cache_type* __cache, size_t __refs = 0)
03582       : facet(__refs), _M_data(__cache)
03583       { _M_initialize_moneypunct(); }
03584 
03585       /**
03586        *  @brief  Internal constructor. Not for general use.
03587        *
03588        *  This is a constructor for use by the library itself to set up new
03589        *  locales.
03590        *
03591        *  @param cloc  The "C" locale.
03592        *  @param s  The name of a locale.
03593        *  @param refs  Passed to the base facet class.
03594       */
03595       explicit
03596       moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
03597       : facet(__refs), _M_data(NULL)
03598       { _M_initialize_moneypunct(__cloc, __s); }
03599 
03600       /**
03601        *  @brief  Return decimal point character.
03602        *
03603        *  This function returns a char_type to use as a decimal point.  It
03604        *  does so by returning returning
03605        *  moneypunct<char_type>::do_decimal_point().
03606        *
03607        *  @return  @a char_type representing a decimal point.
03608       */
03609       char_type
03610       decimal_point() const
03611       { return this->do_decimal_point(); }
03612 
03613       /**
03614        *  @brief  Return thousands separator character.
03615        *
03616        *  This function returns a char_type to use as a thousands
03617        *  separator.  It does so by returning returning
03618        *  moneypunct<char_type>::do_thousands_sep().
03619        *
03620        *  @return  char_type representing a thousands separator.
03621       */
03622       char_type
03623       thousands_sep() const
03624       { return this->do_thousands_sep(); }
03625 
03626       /**
03627        *  @brief  Return grouping specification.
03628        *
03629        *  This function returns a string representing groupings for the
03630        *  integer part of an amount.  Groupings indicate where thousands
03631        *  separators should be inserted.
03632        *
03633        *  Each char in the return string is interpret as an integer rather
03634        *  than a character.  These numbers represent the number of digits in a
03635        *  group.  The first char in the string represents the number of digits
03636        *  in the least significant group.  If a char is negative, it indicates
03637        *  an unlimited number of digits for the group.  If more chars from the
03638        *  string are required to group a number, the last char is used
03639        *  repeatedly.
03640        *
03641        *  For example, if the grouping() returns "\003\002" and is applied to
03642        *  the number 123456789, this corresponds to 12,34,56,789.  Note that
03643        *  if the string was "32", this would put more than 50 digits into the
03644        *  least significant group if the character set is ASCII.
03645        *
03646        *  The string is returned by calling
03647        *  moneypunct<char_type>::do_grouping().
03648        *
03649        *  @return  string representing grouping specification.
03650       */
03651       string
03652       grouping() const
03653       { return this->do_grouping(); }
03654 
03655       /**
03656        *  @brief  Return currency symbol string.
03657        *
03658        *  This function returns a string_type to use as a currency symbol.  It
03659        *  does so by returning returning
03660        *  moneypunct<char_type>::do_curr_symbol().
03661        *
03662        *  @return  @a string_type representing a currency symbol.
03663       */
03664       string_type
03665       curr_symbol() const
03666       { return this->do_curr_symbol(); }
03667 
03668       /**
03669        *  @brief  Return positive sign string.
03670        *
03671        *  This function returns a string_type to use as a sign for positive
03672        *  amounts.  It does so by returning returning
03673        *  moneypunct<char_type>::do_positive_sign().
03674        *
03675        *  If the return value contains more than one character, the first
03676        *  character appears in the position indicated by pos_format() and the
03677        *  remainder appear at the end of the formatted string.
03678        *
03679        *  @return  @a string_type representing a positive sign.
03680       */
03681       string_type
03682       positive_sign() const
03683       { return this->do_positive_sign(); }
03684 
03685       /**
03686        *  @brief  Return negative sign string.
03687        *
03688        *  This function returns a string_type to use as a sign for negative
03689        *  amounts.  It does so by returning returning
03690        *  moneypunct<char_type>::do_negative_sign().
03691        *
03692        *  If the return value contains more than one character, the first
03693        *  character appears in the position indicated by neg_format() and the
03694        *  remainder appear at the end of the formatted string.
03695        *
03696        *  @return  @a string_type representing a negative sign.
03697       */
03698       string_type
03699       negative_sign() const
03700       { return this->do_negative_sign(); }
03701 
03702       /**
03703        *  @brief  Return number of digits in fraction.
03704        *
03705        *  This function returns the exact number of digits that make up the
03706        *  fractional part of a money amount.  It does so by returning
03707        *  returning moneypunct<char_type>::do_frac_digits().
03708        *
03709        *  The fractional part of a money amount is optional.  But if it is
03710        *  present, there must be frac_digits() digits.
03711        *
03712        *  @return  Number of digits in amount fraction.
03713       */
03714       int
03715       frac_digits() const
03716       { return this->do_frac_digits(); }
03717 
03718       //@{
03719       /**
03720        *  @brief  Return pattern for money values.
03721        *
03722        *  This function returns a pattern describing the formatting of a
03723        *  positive or negative valued money amount.  It does so by returning
03724        *  returning moneypunct<char_type>::do_pos_format() or
03725        *  moneypunct<char_type>::do_neg_format().
03726        *
03727        *  The pattern has 4 fields describing the ordering of symbol, sign,
03728        *  value, and none or space.  There must be one of each in the pattern.
03729        *  The none and space enums may not appear in the first field and space
03730        *  may not appear in the final field.
03731        *
03732        *  The parts of a money string must appear in the order indicated by
03733        *  the fields of the pattern.  The symbol field indicates that the
03734        *  value of curr_symbol() may be present.  The sign field indicates
03735        *  that the value of positive_sign() or negative_sign() must be
03736        *  present.  The value field indicates that the absolute value of the
03737        *  money amount is present.  none indicates 0 or more whitespace
03738        *  characters, except at the end, where it permits no whitespace.
03739        *  space indicates that 1 or more whitespace characters must be
03740        *  present.
03741        *
03742        *  For example, for the US locale and pos_format() pattern
03743        *  {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() ==
03744        *  '+', and value 10.01, and options set to force the symbol, the
03745        *  corresponding string is "$+10.01".
03746        *
03747        *  @return  Pattern for money values.
03748       */
03749       pattern
03750       pos_format() const
03751       { return this->do_pos_format(); }
03752 
03753       pattern
03754       neg_format() const
03755       { return this->do_neg_format(); }
03756       //@}
03757 
03758     protected:
03759       /// Destructor.
03760       virtual
03761       ~moneypunct();
03762 
03763       /**
03764        *  @brief  Return decimal point character.
03765        *
03766        *  Returns a char_type to use as a decimal point.  This function is a
03767        *  hook for derived classes to change the value returned.
03768        *
03769        *  @return  @a char_type representing a decimal point.
03770       */
03771       virtual char_type
03772       do_decimal_point() const
03773       { return _M_data->_M_decimal_point; }
03774 
03775       /**
03776        *  @brief  Return thousands separator character.
03777        *
03778        *  Returns a char_type to use as a thousands separator.  This function
03779        *  is a hook for derived classes to change the value returned.
03780        *
03781        *  @return  @a char_type representing a thousands separator.
03782       */
03783       virtual char_type
03784       do_thousands_sep() const
03785       { return _M_data->_M_thousands_sep; }
03786 
03787       /**
03788        *  @brief  Return grouping specification.
03789        *
03790        *  Returns a string representing groupings for the integer part of a
03791        *  number.  This function is a hook for derived classes to change the
03792        *  value returned.  @see grouping() for details.
03793        *
03794        *  @return  String representing grouping specification.
03795       */
03796       virtual string
03797       do_grouping() const
03798       { return _M_data->_M_grouping; }
03799 
03800       /**
03801        *  @brief  Return currency symbol string.
03802        *
03803        *  This function returns a string_type to use as a currency symbol.
03804        *  This function is a hook for derived classes to change the value
03805        *  returned.  @see curr_symbol() for details.
03806        *
03807        *  @return  @a string_type representing a currency symbol.
03808       */
03809       virtual string_type
03810       do_curr_symbol()   const
03811       { return _M_data->_M_curr_symbol; }
03812 
03813       /**
03814        *  @brief  Return positive sign string.
03815        *
03816        *  This function returns a string_type to use as a sign for positive
03817        *  amounts.  This function is a hook for derived classes to change the
03818        *  value returned.  @see positive_sign() for details.
03819        *
03820        *  @return  @a string_type representing a positive sign.
03821       */
03822       virtual string_type
03823       do_positive_sign() const
03824       { return _M_data->_M_positive_sign; }
03825 
03826       /**
03827        *  @brief  Return negative sign string.
03828        *
03829        *  This function returns a string_type to use as a sign for negative
03830        *  amounts.  This function is a hook for derived classes to change the
03831        *  value returned.  @see negative_sign() for details.
03832        *
03833        *  @return  @a string_type representing a negative sign.
03834       */
03835       virtual string_type
03836       do_negative_sign() const
03837       { return _M_data->_M_negative_sign; }
03838 
03839       /**
03840        *  @brief  Return number of digits in fraction.
03841        *
03842        *  This function returns the exact number of digits that make up the
03843        *  fractional part of a money amount.  This function is a hook for
03844        *  derived classes to change the value returned.  @see frac_digits()
03845        *  for details.
03846        *
03847        *  @return  Number of digits in amount fraction.
03848       */
03849       virtual int
03850       do_frac_digits() const
03851       { return _M_data->_M_frac_digits; }
03852 
03853       /**
03854        *  @brief  Return pattern for money values.
03855        *
03856        *  This function returns a pattern describing the formatting of a
03857        *  positive valued money amount.  This function is a hook for derived
03858        *  classes to change the value returned.  @see pos_format() for
03859        *  details.
03860        *
03861        *  @return  Pattern for money values.
03862       */
03863       virtual pattern
03864       do_pos_format() const
03865       { return _M_data->_M_pos_format; }
03866 
03867       /**
03868        *  @brief  Return pattern for money values.
03869        *
03870        *  This function returns a pattern describing the formatting of a
03871        *  negative valued money amount.  This function is a hook for derived
03872        *  classes to change the value returned.  @see neg_format() for
03873        *  details.
03874        *
03875        *  @return  Pattern for money values.
03876       */
03877       virtual pattern
03878       do_neg_format() const
03879       { return _M_data->_M_neg_format; }
03880 
03881       // For use at construction time only.
03882        void
03883        _M_initialize_moneypunct(__c_locale __cloc = NULL,
03884                 const char* __name = NULL);
03885     };
03886 
03887   template<typename _CharT, bool _Intl>
03888     locale::id moneypunct<_CharT, _Intl>::id;
03889 
03890   template<typename _CharT, bool _Intl>
03891     const bool moneypunct<_CharT, _Intl>::intl;
03892 
03893   template<>
03894     moneypunct<char, true>::~moneypunct();
03895 
03896   template<>
03897     moneypunct<char, false>::~moneypunct();
03898 
03899   template<>
03900     void
03901     moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
03902 
03903   template<>
03904     void
03905     moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
03906 
03907 #ifdef _GLIBCXX_USE_WCHAR_T
03908   template<>
03909     moneypunct<wchar_t, true>::~moneypunct();
03910 
03911   template<>
03912     moneypunct<wchar_t, false>::~moneypunct();
03913 
03914   template<>
03915     void
03916     moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
03917                             const char*);
03918 
03919   template<>
03920     void
03921     moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
03922                              const char*);
03923 #endif
03924 
03925   /// @brief  class moneypunct_byname [22.2.6.4].
03926   template<typename _CharT, bool _Intl>
03927     class moneypunct_byname : public moneypunct<_CharT, _Intl>
03928     {
03929     public:
03930       typedef _CharT            char_type;
03931       typedef basic_string<_CharT>  string_type;
03932 
03933       static const bool intl = _Intl;
03934 
03935       explicit
03936       moneypunct_byname(const char* __s, size_t __refs = 0)
03937       : moneypunct<_CharT, _Intl>(__refs)
03938       {
03939     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
03940       {
03941         __c_locale __tmp;
03942         this->_S_create_c_locale(__tmp, __s);
03943         this->_M_initialize_moneypunct(__tmp);
03944         this->_S_destroy_c_locale(__tmp);
03945       }
03946       }
03947 
03948     protected:
03949       virtual
03950       ~moneypunct_byname() { }
03951     };
03952 
03953   template<typename _CharT, bool _Intl>
03954     const bool moneypunct_byname<_CharT, _Intl>::intl;
03955 
03956   /**
03957    *  @brief  Facet for parsing monetary amounts.
03958    *
03959    *  This facet encapsulates the code to parse and return a monetary
03960    *  amount from a string.
03961    *
03962    *  The money_get template uses protected virtual functions to
03963    *  provide the actual results.  The public accessors forward the
03964    *  call to the virtual functions.  These virtual functions are
03965    *  hooks for developers to implement the behavior they require from
03966    *  the money_get facet.
03967   */
03968   template<typename _CharT, typename _InIter>
03969     class money_get : public locale::facet
03970     {
03971     public:
03972       // Types:
03973       //@{
03974       /// Public typedefs
03975       typedef _CharT            char_type;
03976       typedef _InIter           iter_type;
03977       typedef basic_string<_CharT>  string_type;
03978       //@}
03979 
03980       /// Numpunct facet id.
03981       static locale::id         id;
03982 
03983       /**
03984        *  @brief  Constructor performs initialization.
03985        *
03986        *  This is the constructor provided by the standard.
03987        *
03988        *  @param refs  Passed to the base facet class.
03989       */
03990       explicit
03991       money_get(size_t __refs = 0) : facet(__refs) { }
03992 
03993       /**
03994        *  @brief  Read and parse a monetary value.
03995        *
03996        *  This function reads characters from @a s, interprets them as a
03997        *  monetary value according to moneypunct and ctype facets retrieved
03998        *  from io.getloc(), and returns the result in @a units as an integral
03999        *  value moneypunct::frac_digits() * the actual amount.  For example,
04000        *  the string $10.01 in a US locale would store 1001 in @a units.
04001        *
04002        *  Any characters not part of a valid money amount are not consumed.
04003        *
04004        *  If a money value cannot be parsed from the input stream, sets
04005        *  err=(err|io.failbit).  If the stream is consumed before finishing
04006        *  parsing,  sets err=(err|io.failbit|io.eofbit).  @a units is
04007        *  unchanged if parsing fails.
04008        *
04009        *  This function works by returning the result of do_get().
04010        *
04011        *  @param  s  Start of characters to parse.
04012        *  @param  end  End of characters to parse.
04013        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04014        *  @param  io  Source of facets and io state.
04015        *  @param  err  Error field to set if parsing fails.
04016        *  @param  units  Place to store result of parsing.
04017        *  @return  Iterator referencing first character beyond valid money
04018        *       amount.
04019        */
04020       iter_type
04021       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04022       ios_base::iostate& __err, long double& __units) const
04023       { return this->do_get(__s, __end, __intl, __io, __err, __units); }
04024 
04025       /**
04026        *  @brief  Read and parse a monetary value.
04027        *
04028        *  This function reads characters from @a s, interprets them as a
04029        *  monetary value according to moneypunct and ctype facets retrieved
04030        *  from io.getloc(), and returns the result in @a digits.  For example,
04031        *  the string $10.01 in a US locale would store "1001" in @a digits.
04032        *
04033        *  Any characters not part of a valid money amount are not consumed.
04034        *
04035        *  If a money value cannot be parsed from the input stream, sets
04036        *  err=(err|io.failbit).  If the stream is consumed before finishing
04037        *  parsing,  sets err=(err|io.failbit|io.eofbit).
04038        *
04039        *  This function works by returning the result of do_get().
04040        *
04041        *  @param  s  Start of characters to parse.
04042        *  @param  end  End of characters to parse.
04043        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04044        *  @param  io  Source of facets and io state.
04045        *  @param  err  Error field to set if parsing fails.
04046        *  @param  digits  Place to store result of parsing.
04047        *  @return  Iterator referencing first character beyond valid money
04048        *       amount.
04049        */
04050       iter_type
04051       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04052       ios_base::iostate& __err, string_type& __digits) const
04053       { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
04054 
04055     protected:
04056       /// Destructor.
04057       virtual
04058       ~money_get() { }
04059 
04060       /**
04061        *  @brief  Read and parse a monetary value.
04062        *
04063        *  This function reads and parses characters representing a monetary
04064        *  value.  This function is a hook for derived classes to change the
04065        *  value returned.  @see get() for details.
04066        */
04067       virtual iter_type
04068       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04069          ios_base::iostate& __err, long double& __units) const;
04070 
04071       /**
04072        *  @brief  Read and parse a monetary value.
04073        *
04074        *  This function reads and parses characters representing a monetary
04075        *  value.  This function is a hook for derived classes to change the
04076        *  value returned.  @see get() for details.
04077        */
04078       virtual iter_type
04079       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04080          ios_base::iostate& __err, string_type& __digits) const;
04081 
04082       template<bool _Intl>
04083         iter_type
04084         _M_extract(iter_type __s, iter_type __end, ios_base& __io,
04085            ios_base::iostate& __err, string& __digits) const;     
04086     };
04087 
04088   template<typename _CharT, typename _InIter>
04089     locale::id money_get<_CharT, _InIter>::id;
04090 
04091   /**
04092    *  @brief  Facet for outputting monetary amounts.
04093    *
04094    *  This facet encapsulates the code to format and output a monetary
04095    *  amount.
04096    *
04097    *  The money_put template uses protected virtual functions to
04098    *  provide the actual results.  The public accessors forward the
04099    *  call to the virtual functions.  These virtual functions are
04100    *  hooks for developers to implement the behavior they require from
04101    *  the money_put facet.
04102   */
04103   template<typename _CharT, typename _OutIter>
04104     class money_put : public locale::facet
04105     {
04106     public:
04107       //@{
04108       /// Public typedefs
04109       typedef _CharT            char_type;
04110       typedef _OutIter          iter_type;
04111       typedef basic_string<_CharT>  string_type;
04112       //@}
04113 
04114       /// Numpunct facet id.
04115       static locale::id         id;
04116 
04117       /**
04118        *  @brief  Constructor performs initialization.
04119        *
04120        *  This is the constructor provided by the standard.
04121        *
04122        *  @param refs  Passed to the base facet class.
04123       */
04124       explicit
04125       money_put(size_t __refs = 0) : facet(__refs) { }
04126 
04127       /**
04128        *  @brief  Format and output a monetary value.
04129        *
04130        *  This function formats @a units as a monetary value according to
04131        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04132        *  the resulting characters to @a s.  For example, the value 1001 in a
04133        *  US locale would write "$10.01" to @a s.
04134        *
04135        *  This function works by returning the result of do_put().
04136        *
04137        *  @param  s  The stream to write to.
04138        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04139        *  @param  io  Source of facets and io state.
04140        *  @param  fill  char_type to use for padding.
04141        *  @param  units  Place to store result of parsing.
04142        *  @return  Iterator after writing.
04143        */
04144       iter_type
04145       put(iter_type __s, bool __intl, ios_base& __io,
04146       char_type __fill, long double __units) const
04147       { return this->do_put(__s, __intl, __io, __fill, __units); }
04148 
04149       /**
04150        *  @brief  Format and output a monetary value.
04151        *
04152        *  This function formats @a digits as a monetary value according to
04153        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04154        *  the resulting characters to @a s.  For example, the string "1001" in
04155        *  a US locale would write "$10.01" to @a s.
04156        *
04157        *  This function works by returning the result of do_put().
04158        *
04159        *  @param  s  The stream to write to.
04160        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04161        *  @param  io  Source of facets and io state.
04162        *  @param  fill  char_type to use for padding.
04163        *  @param  units  Place to store result of parsing.
04164        *  @return  Iterator after writing.
04165        */
04166       iter_type
04167       put(iter_type __s, bool __intl, ios_base& __io,
04168       char_type __fill, const string_type& __digits) const
04169       { return this->do_put(__s, __intl, __io, __fill, __digits); }
04170 
04171     protected:
04172       /// Destructor.
04173       virtual
04174       ~money_put() { }
04175 
04176       /**
04177        *  @brief  Format and output a monetary value.
04178        *
04179        *  This function formats @a units as a monetary value according to
04180        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04181        *  the resulting characters to @a s.  For example, the value 1001 in a
04182        *  US locale would write "$10.01" to @a s.
04183        *
04184        *  This function is a hook for derived classes to change the value
04185        *  returned.  @see put().
04186        *
04187        *  @param  s  The stream to write to.
04188        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04189        *  @param  io  Source of facets and io state.
04190        *  @param  fill  char_type to use for padding.
04191        *  @param  units  Place to store result of parsing.
04192        *  @return  Iterator after writing.
04193        */
04194       virtual iter_type
04195       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
04196          long double __units) const;
04197 
04198       /**
04199        *  @brief  Format and output a monetary value.
04200        *
04201        *  This function formats @a digits as a monetary value according to
04202        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04203        *  the resulting characters to @a s.  For example, the string "1001" in
04204        *  a US locale would write "$10.01" to @a s.
04205        *
04206        *  This function is a hook for derived classes to change the value
04207        *  returned.  @see put().
04208        *
04209        *  @param  s  The stream to write to.
04210        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04211        *  @param  io  Source of facets and io state.
04212        *  @param  fill  char_type to use for padding.
04213        *  @param  units  Place to store result of parsing.
04214        *  @return  Iterator after writing.
04215        */
04216       virtual iter_type
04217       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
04218          const string_type& __digits) const;
04219 
04220       template<bool _Intl>
04221         iter_type
04222         _M_insert(iter_type __s, ios_base& __io, char_type __fill,
04223           const string_type& __digits) const;
04224     };
04225 
04226   template<typename _CharT, typename _OutIter>
04227     locale::id money_put<_CharT, _OutIter>::id;
04228 
04229   /**
04230    *  @brief  Messages facet base class providing catalog typedef.
04231    */
04232   struct messages_base
04233   {
04234     typedef int catalog;
04235   };
04236 
04237   /**
04238    *  @brief  Facet for handling message catalogs
04239    *
04240    *  This facet encapsulates the code to retrieve messages from
04241    *  message catalogs.  The only thing defined by the standard for this facet
04242    *  is the interface.  All underlying functionality is
04243    *  implementation-defined.
04244    *
04245    *  This library currently implements 3 versions of the message facet.  The
04246    *  first version (gnu) is a wrapper around gettext, provided by libintl.
04247    *  The second version (ieee) is a wrapper around catgets.  The final
04248    *  version (default) does no actual translation.  These implementations are
04249    *  only provided for char and wchar_t instantiations.
04250    *
04251    *  The messages template uses protected virtual functions to
04252    *  provide the actual results.  The public accessors forward the
04253    *  call to the virtual functions.  These virtual functions are
04254    *  hooks for developers to implement the behavior they require from
04255    *  the messages facet.
04256   */
04257   template<typename _CharT>
04258     class messages : public locale::facet, public messages_base
04259     {
04260     public:
04261       // Types:
04262       //@{
04263       /// Public typedefs
04264       typedef _CharT            char_type;
04265       typedef basic_string<_CharT>  string_type;
04266       //@}
04267 
04268     protected:
04269       // Underlying "C" library locale information saved from
04270       // initialization, needed by messages_byname as well.
04271       __c_locale            _M_c_locale_messages;
04272       const char*           _M_name_messages;
04273 
04274     public:
04275       /// Numpunct facet id.
04276       static locale::id         id;
04277 
04278       /**
04279        *  @brief  Constructor performs initialization.
04280        *
04281        *  This is the constructor provided by the standard.
04282        *
04283        *  @param refs  Passed to the base facet class.
04284       */
04285       explicit
04286       messages(size_t __refs = 0);
04287 
04288       // Non-standard.
04289       /**
04290        *  @brief  Internal constructor.  Not for general use.
04291        *
04292        *  This is a constructor for use by the library itself to set up new
04293        *  locales.
04294        *
04295        *  @param  cloc  The "C" locale.
04296        *  @param  s  The name of a locale.
04297        *  @param  refs  Refcount to pass to the base class.
04298        */
04299       explicit
04300       messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
04301 
04302       /*
04303        *  @brief  Open a message catalog.
04304        *
04305        *  This function opens and returns a handle to a message catalog by
04306        *  returning do_open(s, loc).
04307        *
04308        *  @param  s  The catalog to open.
04309        *  @param  loc  Locale to use for character set conversions.
04310        *  @return  Handle to the catalog or value < 0 if open fails.
04311       */
04312       catalog
04313       open(const basic_string<char>& __s, const locale& __loc) const
04314       { return this->do_open(__s, __loc); }
04315 
04316       // Non-standard and unorthodox, yet effective.
04317       /*
04318        *  @brief  Open a message catalog.
04319        *
04320        *  This non-standard function opens and returns a handle to a message
04321        *  catalog by returning do_open(s, loc).  The third argument provides a
04322        *  message catalog root directory for gnu gettext and is ignored
04323        *  otherwise.
04324        *
04325        *  @param  s  The catalog to open.
04326        *  @param  loc  Locale to use for character set conversions.
04327        *  @param  dir  Message catalog root directory.
04328        *  @return  Handle to the catalog or value < 0 if open fails.
04329       */
04330       catalog
04331       open(const basic_string<char>&, const locale&, const char*) const;
04332 
04333       /*
04334        *  @brief  Look up a string in a message catalog.
04335        *
04336        *  This function retrieves and returns a message from a catalog by
04337        *  returning do_get(c, set, msgid, s).
04338        *
04339        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
04340        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
04341        *
04342        *  @param  c  The catalog to access.
04343        *  @param  set  Implementation-defined.
04344        *  @param  msgid  Implementation-defined.
04345        *  @param  s  Default return value if retrieval fails.
04346        *  @return  Retrieved message or @a s if get fails.
04347       */
04348       string_type
04349       get(catalog __c, int __set, int __msgid, const string_type& __s) const
04350       { return this->do_get(__c, __set, __msgid, __s); }
04351 
04352       /*
04353        *  @brief  Close a message catalog.
04354        *
04355        *  Closes catalog @a c by calling do_close(c).
04356        *
04357        *  @param  c  The catalog to close.
04358       */
04359       void
04360       close(catalog __c) const
04361       { return this->do_close(__c); }
04362 
04363     protected:
04364       /// Destructor.
04365       virtual
04366       ~messages();
04367 
04368       /*
04369        *  @brief  Open a message catalog.
04370        *
04371        *  This function opens and returns a handle to a message catalog in an
04372        *  implementation-defined manner.  This function is a hook for derived
04373        *  classes to change the value returned.
04374        *
04375        *  @param  s  The catalog to open.
04376        *  @param  loc  Locale to use for character set conversions.
04377        *  @return  Handle to the opened catalog, value < 0 if open failed.
04378       */
04379       virtual catalog
04380       do_open(const basic_string<char>&, const locale&) const;
04381 
04382       /*
04383        *  @brief  Look up a string in a message catalog.
04384        *
04385        *  This function retrieves and returns a message from a catalog in an
04386        *  implementation-defined manner.  This function is a hook for derived
04387        *  classes to change the value returned.
04388        *
04389        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
04390        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
04391        *
04392        *  @param  c  The catalog to access.
04393        *  @param  set  Implementation-defined.
04394        *  @param  msgid  Implementation-defined.
04395        *  @param  s  Default return value if retrieval fails.
04396        *  @return  Retrieved message or @a s if get fails.
04397       */
04398       virtual string_type
04399       do_get(catalog, int, int, const string_type& __dfault) const;
04400 
04401       /*
04402        *  @brief  Close a message catalog.
04403        *
04404        *  @param  c  The catalog to close.
04405       */
04406       virtual void
04407       do_close(catalog) const;
04408 
04409       // Returns a locale and codeset-converted string, given a char* message.
04410       char*
04411       _M_convert_to_char(const string_type& __msg) const
04412       {
04413     // XXX
04414     return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
04415       }
04416 
04417       // Returns a locale and codeset-converted string, given a char* message.
04418       string_type
04419       _M_convert_from_char(char*) const
04420       {
04421 #if 0
04422     // Length of message string without terminating null.
04423     size_t __len = char_traits<char>::length(__msg) - 1;
04424 
04425     // "everybody can easily convert the string using
04426     // mbsrtowcs/wcsrtombs or with iconv()"
04427 
04428     // Convert char* to _CharT in locale used to open catalog.
04429     // XXX need additional template parameter on messages class for this..
04430     // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
04431     typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
04432 
04433     __codecvt_type::state_type __state;
04434     // XXX may need to initialize state.
04435     //initialize_state(__state._M_init());
04436 
04437     char* __from_next;
04438     // XXX what size for this string?
04439     _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
04440     const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
04441     __cvt.out(__state, __msg, __msg + __len, __from_next,
04442           __to, __to + __len + 1, __to_next);
04443     return string_type(__to);
04444 #endif
04445 #if 0
04446     typedef ctype<_CharT> __ctype_type;
04447     // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
04448     const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
04449     // XXX Again, proper length of converted string an issue here.
04450     // For now, assume the converted length is not larger.
04451     _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
04452     __cvt.widen(__msg, __msg + __len, __dest);
04453     return basic_string<_CharT>(__dest);
04454 #endif
04455     return string_type();
04456       }
04457      };
04458 
04459   template<typename _CharT>
04460     locale::id messages<_CharT>::id;
04461 
04462   // Specializations for required instantiations.
04463   template<>
04464     string
04465     messages<char>::do_get(catalog, int, int, const string&) const;
04466 
04467 #ifdef _GLIBCXX_USE_WCHAR_T
04468   template<>
04469     wstring
04470     messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
04471 #endif
04472 
04473    /// @brief class messages_byname [22.2.7.2].
04474    template<typename _CharT>
04475     class messages_byname : public messages<_CharT>
04476     {
04477     public:
04478       typedef _CharT            char_type;
04479       typedef basic_string<_CharT>  string_type;
04480 
04481       explicit
04482       messages_byname(const char* __s, size_t __refs = 0);
04483 
04484     protected:
04485       virtual
04486       ~messages_byname()
04487       { }
04488     };
04489 
04490   // Include host and configuration specific messages functions.
04491   #include <bits/messages_members.h>
04492 
04493 
04494   // Subclause convenience interfaces, inlines.
04495   // NB: These are inline because, when used in a loop, some compilers
04496   // can hoist the body out of the loop; then it's just as fast as the
04497   // C is*() function.
04498 
04499   /// Convenience interface to ctype.is(ctype_base::space, __c).
04500   template<typename _CharT>
04501     inline bool
04502     isspace(_CharT __c, const locale& __loc)
04503     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
04504 
04505   /// Convenience interface to ctype.is(ctype_base::print, __c).
04506   template<typename _CharT>
04507     inline bool
04508     isprint(_CharT __c, const locale& __loc)
04509     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
04510 
04511   /// Convenience interface to ctype.is(ctype_base::cntrl, __c).
04512   template<typename _CharT>
04513     inline bool
04514     iscntrl(_CharT __c, const locale& __loc)
04515     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
04516 
04517   /// Convenience interface to ctype.is(ctype_base::upper, __c).
04518   template<typename _CharT>
04519     inline bool
04520     isupper(_CharT __c, const locale& __loc)
04521     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
04522 
04523   /// Convenience interface to ctype.is(ctype_base::lower, __c).
04524   template<typename _CharT>
04525     inline bool 
04526     islower(_CharT __c, const locale& __loc)
04527     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
04528 
04529   /// Convenience interface to ctype.is(ctype_base::alpha, __c).
04530   template<typename _CharT>
04531     inline bool
04532     isalpha(_CharT __c, const locale& __loc)
04533     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
04534 
04535   /// Convenience interface to ctype.is(ctype_base::digit, __c).
04536   template<typename _CharT>
04537     inline bool
04538     isdigit(_CharT __c, const locale& __loc)
04539     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
04540 
04541   /// Convenience interface to ctype.is(ctype_base::punct, __c).
04542   template<typename _CharT>
04543     inline bool
04544     ispunct(_CharT __c, const locale& __loc)
04545     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
04546 
04547   /// Convenience interface to ctype.is(ctype_base::xdigit, __c).
04548   template<typename _CharT>
04549     inline bool
04550     isxdigit(_CharT __c, const locale& __loc)
04551     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
04552 
04553   /// Convenience interface to ctype.is(ctype_base::alnum, __c).
04554   template<typename _CharT>
04555     inline bool
04556     isalnum(_CharT __c, const locale& __loc)
04557     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
04558 
04559   /// Convenience interface to ctype.is(ctype_base::graph, __c).
04560   template<typename _CharT>
04561     inline bool
04562     isgraph(_CharT __c, const locale& __loc)
04563     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
04564 
04565   /// Convenience interface to ctype.toupper(__c).
04566   template<typename _CharT>
04567     inline _CharT
04568     toupper(_CharT __c, const locale& __loc)
04569     { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
04570 
04571   /// Convenience interface to ctype.tolower(__c).
04572   template<typename _CharT>
04573     inline _CharT
04574     tolower(_CharT __c, const locale& __loc)
04575     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
04576 } // namespace std
04577 
04578 #endif

Generated on Thu Nov 1 17:35:59 2007 for libstdc++ by  doxygen 1.5.1