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
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 //
00032 // ISO C++ 14882: 22.1  Locales
00033 //
00034 
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 non-consecutive
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) return _M_widen[static_cast<unsigned char>(__c)];
00869     this->_M_widen_init();
00870     return this->do_widen(__c);
00871       }
00872 
00873       /**
00874        *  @brief  Widen char array
00875        *
00876        *  This function converts each char in the input to char using the
00877        *  simplest reasonable transformation.  For an underived ctype<char>
00878        *  facet, the argument will be copied unchanged.
00879        *
00880        *  This function works as if it returns ctype<char>::do_widen(c).
00881        *  do_widen() must always return the same result for the same input.
00882        *
00883        *  Note: this is not what you want for codepage conversions.  See
00884        *  codecvt for that.
00885        *
00886        *  @param lo  Pointer to first char in range.
00887        *  @param hi  Pointer to end of range.
00888        *  @param to  Pointer to the destination array.
00889        *  @return  @a hi.
00890       */
00891       const char*
00892       widen(const char* __lo, const char* __hi, char_type* __to) const
00893       {
00894     if (_M_widen_ok == 1)
00895       {
00896         memcpy(__to, __lo, __hi - __lo);
00897         return __hi;
00898       }
00899     if (!_M_widen_ok) _M_widen_init();
00900     return this->do_widen(__lo, __hi, __to);
00901       }
00902 
00903       /**
00904        *  @brief  Narrow char
00905        *
00906        *  This function converts the char to char using the simplest
00907        *  reasonable transformation.  If the conversion fails, dfault is
00908        *  returned instead.  For an underived ctype<char> facet, @a c
00909        *  will be returned unchanged.
00910        *
00911        *  This function works as if it returns ctype<char>::do_narrow(c).
00912        *  do_narrow() must always return the same result for the same input.
00913        *
00914        *  Note: this is not what you want for codepage conversions.  See
00915        *  codecvt for that.
00916        *
00917        *  @param c  The char to convert.
00918        *  @param dfault  Char to return if conversion fails.
00919        *  @return  The converted character.
00920       */
00921       char
00922       narrow(char_type __c, char __dfault) const
00923       {
00924     if (_M_narrow[static_cast<unsigned char>(__c)])
00925       return _M_narrow[static_cast<unsigned char>(__c)];
00926     const char __t = do_narrow(__c, __dfault);
00927     if (__t != __dfault) _M_narrow[static_cast<unsigned char>(__c)] = __t;
00928     return __t;
00929       }
00930 
00931       /**
00932        *  @brief  Narrow char array
00933        *
00934        *  This function converts each char in the input to char using the
00935        *  simplest reasonable transformation and writes the results to the
00936        *  destination array.  For any char in the input that cannot be
00937        *  converted, @a dfault is used instead.  For an underived ctype<char>
00938        *  facet, the argument will be copied unchanged.
00939        *
00940        *  This function works as if it returns ctype<char>::do_narrow(lo, hi,
00941        *  dfault, to).  do_narrow() must always return the same result for the
00942        *  same input.
00943        *
00944        *  Note: this is not what you want for codepage conversions.  See
00945        *  codecvt for that.
00946        *
00947        *  @param lo  Pointer to start of range.
00948        *  @param hi  Pointer to end of range.
00949        *  @param dfault  Char to use if conversion fails.
00950        *  @param to  Pointer to the destination array.
00951        *  @return  @a hi.
00952       */
00953       const char_type*
00954       narrow(const char_type* __lo, const char_type* __hi,
00955          char __dfault, char *__to) const
00956       {
00957     if (__builtin_expect(_M_narrow_ok == 1,true))
00958       {
00959         memcpy(__to, __lo, __hi - __lo);
00960         return __hi;
00961       }
00962     if (!_M_narrow_ok)
00963       _M_narrow_init();
00964     return this->do_narrow(__lo, __hi, __dfault, __to);
00965       }
00966 
00967     protected:
00968       /// Returns a pointer to the mask table provided to the constructor, or
00969       /// the default from classic_table() if none was provided.
00970       const mask*
00971       table() const throw()
00972       { return _M_table; }
00973 
00974       /// Returns a pointer to the C locale mask table.
00975       static const mask*
00976       classic_table() throw();
00977 
00978       /**
00979        *  @brief  Destructor.
00980        *
00981        *  This function deletes table() if @a del was true in the
00982        *  constructor.
00983       */
00984       virtual
00985       ~ctype();
00986 
00987       /**
00988        *  @brief  Convert to uppercase.
00989        *
00990        *  This virtual function converts the char argument to uppercase if
00991        *  possible.  If not possible (for example, '2'), returns the argument.
00992        *
00993        *  do_toupper() is a hook for a derived facet to change the behavior of
00994        *  uppercasing.  do_toupper() must always return the same result for
00995        *  the same input.
00996        *
00997        *  @param c  The char to convert.
00998        *  @return  The uppercase char if convertible, else @a c.
00999       */
01000       virtual char_type
01001       do_toupper(char_type) const;
01002 
01003       /**
01004        *  @brief  Convert array to uppercase.
01005        *
01006        *  This virtual function converts each char in the range [lo,hi) to
01007        *  uppercase if possible.  Other chars remain untouched.
01008        *
01009        *  do_toupper() is a hook for a derived facet to change the behavior of
01010        *  uppercasing.  do_toupper() must always return the same result for
01011        *  the same input.
01012        *
01013        *  @param lo  Pointer to start of range.
01014        *  @param hi  Pointer to end of range.
01015        *  @return  @a hi.
01016       */
01017       virtual const char_type*
01018       do_toupper(char_type* __lo, const char_type* __hi) const;
01019 
01020       /**
01021        *  @brief  Convert to lowercase.
01022        *
01023        *  This virtual function converts the char argument to lowercase if
01024        *  possible.  If not possible (for example, '2'), returns the argument.
01025        *
01026        *  do_tolower() is a hook for a derived facet to change the behavior of
01027        *  lowercasing.  do_tolower() must always return the same result for
01028        *  the same input.
01029        *
01030        *  @param c  The char to convert.
01031        *  @return  The lowercase char if convertible, else @a c.
01032       */
01033       virtual char_type
01034       do_tolower(char_type) const;
01035 
01036       /**
01037        *  @brief  Convert array to lowercase.
01038        *
01039        *  This virtual function converts each char in the range [lo,hi) to
01040        *  lowercase if possible.  Other chars remain untouched.
01041        *
01042        *  do_tolower() is a hook for a derived facet to change the behavior of
01043        *  lowercasing.  do_tolower() must always return the same result for
01044        *  the same input.
01045        *
01046        *  @param lo  Pointer to first char in range.
01047        *  @param hi  Pointer to end of range.
01048        *  @return  @a hi.
01049       */
01050       virtual const char_type*
01051       do_tolower(char_type* __lo, const char_type* __hi) const;
01052 
01053       /**
01054        *  @brief  Widen char
01055        *
01056        *  This virtual function converts the char to char using the simplest
01057        *  reasonable transformation.  For an underived ctype<char> facet, the
01058        *  argument will be returned unchanged.
01059        *
01060        *  do_widen() is a hook for a derived facet to change the behavior of
01061        *  widening.  do_widen() must always return the same result for the
01062        *  same input.
01063        *
01064        *  Note: this is not what you want for codepage conversions.  See
01065        *  codecvt for that.
01066        *
01067        *  @param c  The char to convert.
01068        *  @return  The converted character.
01069       */
01070       virtual char_type
01071       do_widen(char __c) const
01072       { return __c; }
01073 
01074       /**
01075        *  @brief  Widen char array
01076        *
01077        *  This function converts each char in the range [lo,hi) to char using
01078        *  the simplest reasonable transformation.  For an underived
01079        *  ctype<char> facet, the argument will be copied unchanged.
01080        *
01081        *  do_widen() is a hook for a derived facet to change the behavior of
01082        *  widening.  do_widen() must always return the same result for the
01083        *  same input.
01084        *
01085        *  Note: this is not what you want for codepage conversions.  See
01086        *  codecvt for that.
01087        *
01088        *  @param lo  Pointer to start of range.
01089        *  @param hi  Pointer to end of range.
01090        *  @param to  Pointer to the destination array.
01091        *  @return  @a hi.
01092       */
01093       virtual const char*
01094       do_widen(const char* __lo, const char* __hi, char_type* __dest) const
01095       {
01096     memcpy(__dest, __lo, __hi - __lo);
01097     return __hi;
01098       }
01099 
01100       /**
01101        *  @brief  Narrow char
01102        *
01103        *  This virtual function converts the char to char using the simplest
01104        *  reasonable transformation.  If the conversion fails, dfault is
01105        *  returned instead.  For an underived ctype<char> facet, @a c will be
01106        *  returned unchanged.
01107        *
01108        *  do_narrow() is a hook for a derived facet to change the behavior of
01109        *  narrowing.  do_narrow() must always return the same result for the
01110        *  same input.
01111        *
01112        *  Note: this is not what you want for codepage conversions.  See
01113        *  codecvt for that.
01114        *
01115        *  @param c  The char to convert.
01116        *  @param dfault  Char to return if conversion fails.
01117        *  @return  The converted char.
01118       */
01119       virtual char
01120       do_narrow(char_type __c, char) const
01121       { return __c; }
01122 
01123       /**
01124        *  @brief  Narrow char array to char array
01125        *
01126        *  This virtual function converts each char in the range [lo,hi) to
01127        *  char using the simplest reasonable transformation and writes the
01128        *  results to the destination array.  For any char in the input that
01129        *  cannot be converted, @a dfault is used instead.  For an underived
01130        *  ctype<char> facet, the argument will be copied unchanged.
01131        *
01132        *  do_narrow() is a hook for a derived facet to change the behavior of
01133        *  narrowing.  do_narrow() must always return the same result for the
01134        *  same input.
01135        *
01136        *  Note: this is not what you want for codepage conversions.  See
01137        *  codecvt for that.
01138        *
01139        *  @param lo  Pointer to start of range.
01140        *  @param hi  Pointer to end of range.
01141        *  @param dfault  Char to use if conversion fails.
01142        *  @param to  Pointer to the destination array.
01143        *  @return  @a hi.
01144       */
01145       virtual const char_type*
01146       do_narrow(const char_type* __lo, const char_type* __hi,
01147         char, char* __dest) const
01148       {
01149     memcpy(__dest, __lo, __hi - __lo);
01150     return __hi;
01151       }
01152 
01153     private:
01154 
01155       void _M_widen_init() const
01156       {
01157     char __tmp[sizeof(_M_widen)];
01158     for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
01159       __tmp[__i] = __i;
01160     do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
01161 
01162     _M_widen_ok = 1;
01163     // Set _M_widen_ok to 2 if memcpy can't be used.
01164     for (size_t __j = 0; __j < sizeof(_M_widen); ++__j)
01165       if (__tmp[__j] != _M_widen[__j])
01166         {
01167           _M_widen_ok = 2;
01168           break;
01169         }
01170       }
01171 
01172       // Fill in the narrowing cache and flag whether all values are
01173       // valid or not.  _M_narrow_ok is set to 1 if the whole table is
01174       // narrowed, 2 if only some values could be narrowed.
01175       void _M_narrow_init() const
01176       {
01177     char __tmp[sizeof(_M_narrow)];
01178     for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
01179       __tmp[__i] = __i;
01180     do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
01181 
01182     // Check if any default values were created.  Do this by
01183     // renarrowing with a different default value and comparing.
01184     bool __consecutive = true;
01185     for (size_t __j = 0; __j < sizeof(_M_narrow); ++__j)
01186       if (!_M_narrow[__j])
01187         {
01188           char __c;
01189           do_narrow(__tmp + __j, __tmp + __j + 1, 1, &__c);
01190           if (__c == 1)
01191         {
01192           __consecutive = false;
01193           break;
01194         }
01195         }
01196     _M_narrow_ok = __consecutive ? 1 : 2;
01197       }
01198     };
01199 
01200   template<>
01201     const ctype<char>&
01202     use_facet<ctype<char> >(const locale& __loc);
01203 
01204 #ifdef _GLIBCXX_USE_WCHAR_T
01205   // 22.2.1.3  ctype<wchar_t> specialization
01206   /**
01207    *  @brief  The ctype<wchar_t> specialization.
01208    *
01209    *  This class defines classification and conversion functions for the
01210    *  wchar_t type.  It gets used by wchar_t streams for many I/O operations.
01211    *  The wchar_t specialization provides a number of optimizations as well.
01212    *
01213    *  ctype<wchar_t> inherits its public methods from
01214    *  __ctype_abstract_base<wchar_t>.
01215   */
01216   template<>
01217     class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
01218     {
01219     public:
01220       // Types:
01221       /// Typedef for the template parameter wchar_t.
01222       typedef wchar_t       char_type;
01223       typedef wctype_t      __wmask_type;
01224 
01225     protected:
01226       __c_locale        _M_c_locale_ctype;
01227 
01228       // Pre-computed narrowed and widened chars.
01229       bool                      _M_narrow_ok;
01230       char                      _M_narrow[128];
01231       wint_t                    _M_widen[1 + static_cast<unsigned char>(-1)];
01232 
01233       // Pre-computed elements for do_is.
01234       mask                      _M_bit[16];
01235       __wmask_type              _M_wmask[16];
01236 
01237     public:
01238       // Data Members:
01239       /// The facet id for ctype<wchar_t>
01240       static locale::id     id;
01241 
01242       /**
01243        *  @brief  Constructor performs initialization.
01244        *
01245        *  This is the constructor provided by the standard.
01246        *
01247        *  @param refs  Passed to the base facet class.
01248       */
01249       explicit
01250       ctype(size_t __refs = 0);
01251 
01252       /**
01253        *  @brief  Constructor performs static initialization.
01254        *
01255        *  This constructor is used to construct the initial C locale facet.
01256        *
01257        *  @param cloc  Handle to C locale data.
01258        *  @param refs  Passed to the base facet class.
01259       */
01260       explicit
01261       ctype(__c_locale __cloc, size_t __refs = 0);
01262 
01263     protected:
01264       __wmask_type
01265       _M_convert_to_wmask(const mask __m) const;
01266 
01267       /// Destructor
01268       virtual
01269       ~ctype();
01270 
01271       /**
01272        *  @brief  Test wchar_t classification.
01273        *
01274        *  This function finds a mask M for @a c and compares it to mask @a m.
01275        *
01276        *  do_is() is a hook for a derived facet to change the behavior of
01277        *  classifying.  do_is() must always return the same result for the
01278        *  same input.
01279        *
01280        *  @param c  The wchar_t to find the mask of.
01281        *  @param m  The mask to compare against.
01282        *  @return  (M & m) != 0.
01283       */
01284       virtual bool
01285       do_is(mask __m, char_type __c) const;
01286 
01287       /**
01288        *  @brief  Return a mask array.
01289        *
01290        *  This function finds the mask for each wchar_t in the range [lo,hi)
01291        *  and successively writes it to vec.  vec must have as many elements
01292        *  as the input.
01293        *
01294        *  do_is() is a hook for a derived facet to change the behavior of
01295        *  classifying.  do_is() must always return the same result for the
01296        *  same input.
01297        *
01298        *  @param lo  Pointer to start of range.
01299        *  @param hi  Pointer to end of range.
01300        *  @param vec  Pointer to an array of mask storage.
01301        *  @return  @a hi.
01302       */
01303       virtual const char_type*
01304       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
01305 
01306       /**
01307        *  @brief  Find wchar_t matching mask
01308        *
01309        *  This function searches for and returns the first wchar_t c in
01310        *  [lo,hi) for which is(m,c) is true.
01311        *
01312        *  do_scan_is() is a hook for a derived facet to change the behavior of
01313        *  match searching.  do_is() must always return the same result for the
01314        *  same input.
01315        *
01316        *  @param m  The mask to compare against.
01317        *  @param lo  Pointer to start of range.
01318        *  @param hi  Pointer to end of range.
01319        *  @return  Pointer to a matching wchar_t if found, else @a hi.
01320       */
01321       virtual const char_type*
01322       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
01323 
01324       /**
01325        *  @brief  Find wchar_t not matching mask
01326        *
01327        *  This function searches for and returns a pointer to the first
01328        *  wchar_t c of [lo,hi) for which is(m,c) is false.
01329        *
01330        *  do_scan_is() is a hook for a derived facet to change the behavior of
01331        *  match searching.  do_is() must always return the same result for the
01332        *  same input.
01333        *
01334        *  @param m  The mask to compare against.
01335        *  @param lo  Pointer to start of range.
01336        *  @param hi  Pointer to end of range.
01337        *  @return  Pointer to a non-matching wchar_t if found, else @a hi.
01338       */
01339       virtual const char_type*
01340       do_scan_not(mask __m, const char_type* __lo,
01341           const char_type* __hi) const;
01342 
01343       /**
01344        *  @brief  Convert to uppercase.
01345        *
01346        *  This virtual function converts the wchar_t argument to uppercase if
01347        *  possible.  If not possible (for example, '2'), returns the argument.
01348        *
01349        *  do_toupper() is a hook for a derived facet to change the behavior of
01350        *  uppercasing.  do_toupper() must always return the same result for
01351        *  the same input.
01352        *
01353        *  @param c  The wchar_t to convert.
01354        *  @return  The uppercase wchar_t if convertible, else @a c.
01355       */
01356       virtual char_type
01357       do_toupper(char_type) const;
01358 
01359       /**
01360        *  @brief  Convert array to uppercase.
01361        *
01362        *  This virtual function converts each wchar_t in the range [lo,hi) to
01363        *  uppercase if possible.  Other elements remain untouched.
01364        *
01365        *  do_toupper() is a hook for a derived facet to change the behavior of
01366        *  uppercasing.  do_toupper() must always return the same result for
01367        *  the same input.
01368        *
01369        *  @param lo  Pointer to start of range.
01370        *  @param hi  Pointer to end of range.
01371        *  @return  @a hi.
01372       */
01373       virtual const char_type*
01374       do_toupper(char_type* __lo, const char_type* __hi) const;
01375 
01376       /**
01377        *  @brief  Convert to lowercase.
01378        *
01379        *  This virtual function converts the argument to lowercase if
01380        *  possible.  If not possible (for example, '2'), returns the argument.
01381        *
01382        *  do_tolower() is a hook for a derived facet to change the behavior of
01383        *  lowercasing.  do_tolower() must always return the same result for
01384        *  the same input.
01385        *
01386        *  @param c  The wchar_t to convert.
01387        *  @return  The lowercase wchar_t if convertible, else @a c.
01388       */
01389       virtual char_type
01390       do_tolower(char_type) const;
01391 
01392       /**
01393        *  @brief  Convert array to lowercase.
01394        *
01395        *  This virtual function converts each wchar_t in the range [lo,hi) to
01396        *  lowercase if possible.  Other elements remain untouched.
01397        *
01398        *  do_tolower() is a hook for a derived facet to change the behavior of
01399        *  lowercasing.  do_tolower() must always return the same result for
01400        *  the same input.
01401        *
01402        *  @param lo  Pointer to start of range.
01403        *  @param hi  Pointer to end of range.
01404        *  @return  @a hi.
01405       */
01406       virtual const char_type*
01407       do_tolower(char_type* __lo, const char_type* __hi) const;
01408 
01409       /**
01410        *  @brief  Widen char to wchar_t
01411        *
01412        *  This virtual function converts the char to wchar_t using the
01413        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
01414        *  facet, the argument will be cast to wchar_t.
01415        *
01416        *  do_widen() is a hook for a derived facet to change the behavior of
01417        *  widening.  do_widen() must always return the same result for the
01418        *  same input.
01419        *
01420        *  Note: this is not what you want for codepage conversions.  See
01421        *  codecvt for that.
01422        *
01423        *  @param c  The char to convert.
01424        *  @return  The converted wchar_t.
01425       */
01426       virtual char_type
01427       do_widen(char) const;
01428 
01429       /**
01430        *  @brief  Widen char array to wchar_t array
01431        *
01432        *  This function converts each char in the input to wchar_t using the
01433        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
01434        *  facet, the argument will be copied, casting each element to wchar_t.
01435        *
01436        *  do_widen() is a hook for a derived facet to change the behavior of
01437        *  widening.  do_widen() must always return the same result for the
01438        *  same input.
01439        *
01440        *  Note: this is not what you want for codepage conversions.  See
01441        *  codecvt for that.
01442        *
01443        *  @param lo  Pointer to start range.
01444        *  @param hi  Pointer to end of range.
01445        *  @param to  Pointer to the destination array.
01446        *  @return  @a hi.
01447       */
01448       virtual const char*
01449       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
01450 
01451       /**
01452        *  @brief  Narrow wchar_t to char
01453        *
01454        *  This virtual function converts the argument to char using
01455        *  the simplest reasonable transformation.  If the conversion
01456        *  fails, dfault is returned instead.  For an underived
01457        *  ctype<wchar_t> facet, @a c will be cast to char and
01458        *  returned.
01459        *
01460        *  do_narrow() is a hook for a derived facet to change the
01461        *  behavior of narrowing.  do_narrow() must always return the
01462        *  same result for the same input.
01463        *
01464        *  Note: this is not what you want for codepage conversions.  See
01465        *  codecvt for that.
01466        *
01467        *  @param c  The wchar_t to convert.
01468        *  @param dfault  Char to return if conversion fails.
01469        *  @return  The converted char.
01470       */
01471       virtual char
01472       do_narrow(char_type, char __dfault) const;
01473 
01474       /**
01475        *  @brief  Narrow wchar_t array to char array
01476        *
01477        *  This virtual function converts each wchar_t in the range [lo,hi) to
01478        *  char using the simplest reasonable transformation and writes the
01479        *  results to the destination array.  For any wchar_t in the input that
01480        *  cannot be converted, @a dfault is used instead.  For an underived
01481        *  ctype<wchar_t> facet, the argument will be copied, casting each
01482        *  element to char.
01483        *
01484        *  do_narrow() is a hook for a derived facet to change the behavior of
01485        *  narrowing.  do_narrow() must always return the same result for the
01486        *  same input.
01487        *
01488        *  Note: this is not what you want for codepage conversions.  See
01489        *  codecvt for that.
01490        *
01491        *  @param lo  Pointer to start of range.
01492        *  @param hi  Pointer to end of range.
01493        *  @param dfault  Char to use if conversion fails.
01494        *  @param to  Pointer to the destination array.
01495        *  @return  @a hi.
01496       */
01497       virtual const char_type*
01498       do_narrow(const char_type* __lo, const char_type* __hi,
01499         char __dfault, char* __dest) const;
01500 
01501       // For use at construction time only.
01502       void
01503       _M_initialize_ctype();
01504     };
01505 
01506   template<>
01507     const ctype<wchar_t>&
01508     use_facet<ctype<wchar_t> >(const locale& __loc);
01509 #endif //_GLIBCXX_USE_WCHAR_T
01510 
01511   // Include host and configuration specific ctype inlines.
01512   #include <bits/ctype_inline.h>
01513 
01514   // 22.2.1.2  Template class ctype_byname
01515   template<typename _CharT>
01516     class ctype_byname : public ctype<_CharT>
01517     {
01518     public:
01519       typedef _CharT        char_type;
01520 
01521       explicit
01522       ctype_byname(const char* __s, size_t __refs = 0);
01523 
01524     protected:
01525       virtual
01526       ~ctype_byname() { };
01527     };
01528 
01529   // 22.2.1.4  Class ctype_byname specializations.
01530   template<>
01531     ctype_byname<char>::ctype_byname(const char*, size_t refs);
01532 
01533   template<>
01534     ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
01535 
01536   // 22.2.1.5  Template class codecvt
01537   #include <bits/codecvt.h>
01538 
01539   // 22.2.2  The numeric category.
01540   class __num_base
01541   {
01542   public:
01543     // NB: Code depends on the order of _S_atoms_out elements.
01544     // Below are the indices into _S_atoms_out.
01545     enum
01546       {
01547         _S_ominus,
01548         _S_oplus,
01549         _S_ox,
01550         _S_oX,
01551         _S_odigits,
01552         _S_odigits_end = _S_odigits + 16,
01553         _S_oudigits = _S_odigits_end,
01554         _S_oudigits_end = _S_oudigits + 16,
01555         _S_oe = _S_odigits + 14,  // For scientific notation, 'e'
01556         _S_oE = _S_oudigits + 14, // For scientific notation, 'E'
01557     _S_oend = _S_oudigits_end
01558       };
01559 
01560     // A list of valid numeric literals for output.  This array
01561     // contains chars that will be passed through the current locale's
01562     // ctype<_CharT>.widen() and then used to render numbers.
01563     // For the standard "C" locale, this is
01564     // "-+xX0123456789abcdef0123456789ABCDEF".
01565     static const char* _S_atoms_out;
01566 
01567     // String literal of acceptable (narrow) input, for num_get.
01568     // "-+xX0123456789abcdefABCDEF"
01569     static const char* _S_atoms_in;
01570 
01571     enum
01572     {
01573       _S_iminus,
01574       _S_iplus,
01575       _S_ix,
01576       _S_iX,
01577       _S_izero,
01578       _S_ie = _S_izero + 14,
01579       _S_iE = _S_izero + 20,
01580       _S_iend = 26
01581     };
01582 
01583     // num_put
01584     // Construct and return valid scanf format for floating point types.
01585     static void
01586     _S_format_float(const ios_base& __io, char* __fptr, char __mod);
01587   };
01588 
01589   template<typename _CharT>
01590     struct __numpunct_cache : public locale::facet
01591     {
01592       const char*           _M_grouping;
01593       size_t                            _M_grouping_size;
01594       bool              _M_use_grouping;
01595       const _CharT*         _M_truename;
01596       size_t                            _M_truename_size;
01597       const _CharT*         _M_falsename;
01598       size_t                            _M_falsename_size;
01599       _CharT                _M_decimal_point;
01600       _CharT                _M_thousands_sep;
01601 
01602       // A list of valid numeric literals for output: in the standard
01603       // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
01604       // This array contains the chars after having been passed
01605       // through the current locale's ctype<_CharT>.widen().
01606       _CharT                _M_atoms_out[__num_base::_S_oend];
01607 
01608       // A list of valid numeric literals for input: in the standard
01609       // "C" locale, this is "-+xX0123456789abcdefABCDEF"
01610       // This array contains the chars after having been passed
01611       // through the current locale's ctype<_CharT>.widen().
01612       _CharT                _M_atoms_in[__num_base::_S_iend];
01613 
01614       bool              _M_allocated;
01615 
01616       __numpunct_cache(size_t __refs = 0) : facet(__refs),
01617       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
01618       _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL),
01619       _M_falsename_size(0), _M_decimal_point(_CharT()),
01620       _M_thousands_sep(_CharT()), _M_allocated(false)
01621       { }
01622 
01623       ~__numpunct_cache();
01624 
01625       void
01626       _M_cache(const locale& __loc);
01627 
01628     private:
01629       __numpunct_cache&
01630       operator=(const __numpunct_cache&);
01631       
01632       explicit
01633       __numpunct_cache(const __numpunct_cache&);
01634     };
01635 
01636   template<typename _CharT>
01637     __numpunct_cache<_CharT>::~__numpunct_cache()
01638     {
01639       if (_M_allocated)
01640     {
01641       delete [] _M_grouping;
01642       delete [] _M_truename;
01643       delete [] _M_falsename;
01644     }
01645     }
01646 
01647   /**
01648    *  @brief  Numpunct facet.
01649    *
01650    *  This facet stores several pieces of information related to printing and
01651    *  scanning numbers, such as the decimal point character.  It takes a
01652    *  template parameter specifying the char type.  The numpunct facet is
01653    *  used by streams for many I/O operations involving numbers.
01654    *
01655    *  The numpunct template uses protected virtual functions to provide the
01656    *  actual results.  The public accessors forward the call to the virtual
01657    *  functions.  These virtual functions are hooks for developers to
01658    *  implement the behavior they require from a numpunct facet.
01659   */
01660   template<typename _CharT>
01661     class numpunct : public locale::facet
01662     {
01663     public:
01664       // Types:
01665       //@{
01666       /// Public typedefs
01667       typedef _CharT            char_type;
01668       typedef basic_string<_CharT>  string_type;
01669       //@}
01670       typedef __numpunct_cache<_CharT>  __cache_type;
01671 
01672     protected:
01673       __cache_type*         _M_data;
01674 
01675     public:
01676       /// Numpunct facet id.
01677       static locale::id         id;
01678 
01679       /**
01680        *  @brief  Numpunct constructor.
01681        *
01682        *  @param  refs  Refcount to pass to the base class.
01683        */
01684       explicit
01685       numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
01686       { _M_initialize_numpunct(); }
01687 
01688       /**
01689        *  @brief  Internal constructor.  Not for general use.
01690        *
01691        *  This is a constructor for use by the library itself to set up the
01692        *  predefined locale facets.
01693        *
01694        *  @param  cache  __numpunct_cache object.
01695        *  @param  refs  Refcount to pass to the base class.
01696        */
01697       explicit
01698       numpunct(__cache_type* __cache, size_t __refs = 0)
01699       : facet(__refs), _M_data(__cache)
01700       { _M_initialize_numpunct(); }
01701 
01702       /**
01703        *  @brief  Internal constructor.  Not for general use.
01704        *
01705        *  This is a constructor for use by the library itself to set up new
01706        *  locales.
01707        *
01708        *  @param  cloc  The "C" locale.
01709        *  @param  refs  Refcount to pass to the base class.
01710        */
01711       explicit
01712       numpunct(__c_locale __cloc, size_t __refs = 0)
01713       : facet(__refs), _M_data(NULL)
01714       { _M_initialize_numpunct(__cloc); }
01715 
01716       /**
01717        *  @brief  Return decimal point character.
01718        *
01719        *  This function returns a char_type to use as a decimal point.  It
01720        *  does so by returning returning
01721        *  numpunct<char_type>::do_decimal_point().
01722        *
01723        *  @return  @a char_type representing a decimal point.
01724       */
01725       char_type
01726       decimal_point() const
01727       { return this->do_decimal_point(); }
01728 
01729       /**
01730        *  @brief  Return thousands separator character.
01731        *
01732        *  This function returns a char_type to use as a thousands
01733        *  separator.  It does so by returning returning
01734        *  numpunct<char_type>::do_thousands_sep().
01735        *
01736        *  @return  char_type representing a thousands separator.
01737       */
01738       char_type
01739       thousands_sep() const
01740       { return this->do_thousands_sep(); }
01741 
01742       /**
01743        *  @brief  Return grouping specification.
01744        *
01745        *  This function returns a string representing groupings for the
01746        *  integer part of a number.  Groupings indicate where thousands
01747        *  separators should be inserted in the integer part of a number.
01748        *
01749        *  Each char in the return string is interpret as an integer
01750        *  rather than a character.  These numbers represent the number
01751        *  of digits in a group.  The first char in the string
01752        *  represents the number of digits in the least significant
01753        *  group.  If a char is negative, it indicates an unlimited
01754        *  number of digits for the group.  If more chars from the
01755        *  string are required to group a number, the last char is used
01756        *  repeatedly.
01757        *
01758        *  For example, if the grouping() returns "\003\002" and is
01759        *  applied to the number 123456789, this corresponds to
01760        *  12,34,56,789.  Note that if the string was "32", this would
01761        *  put more than 50 digits into the least significant group if
01762        *  the character set is ASCII.
01763        *
01764        *  The string is returned by calling
01765        *  numpunct<char_type>::do_grouping().
01766        *
01767        *  @return  string representing grouping specification.
01768       */
01769       string
01770       grouping() const
01771       { return this->do_grouping(); }
01772 
01773       /**
01774        *  @brief  Return string representation of bool true.
01775        *
01776        *  This function returns a string_type containing the text
01777        *  representation for true bool variables.  It does so by calling
01778        *  numpunct<char_type>::do_truename().
01779        *
01780        *  @return  string_type representing printed form of true.
01781       */
01782       string_type
01783       truename() const
01784       { return this->do_truename(); }
01785 
01786       /**
01787        *  @brief  Return string representation of bool false.
01788        *
01789        *  This function returns a string_type containing the text
01790        *  representation for false bool variables.  It does so by calling
01791        *  numpunct<char_type>::do_falsename().
01792        *
01793        *  @return  string_type representing printed form of false.
01794       */
01795       string_type
01796       falsename() const
01797       { return this->do_falsename(); }
01798 
01799     protected:
01800       /// Destructor.
01801       virtual
01802       ~numpunct();
01803 
01804       /**
01805        *  @brief  Return decimal point character.
01806        *
01807        *  Returns a char_type to use as a decimal point.  This function is a
01808        *  hook for derived classes to change the value returned.
01809        *
01810        *  @return  @a char_type representing a decimal point.
01811       */
01812       virtual char_type
01813       do_decimal_point() const
01814       { return _M_data->_M_decimal_point; }
01815 
01816       /**
01817        *  @brief  Return thousands separator character.
01818        *
01819        *  Returns a char_type to use as a thousands separator.  This function
01820        *  is a hook for derived classes to change the value returned.
01821        *
01822        *  @return  @a char_type representing a thousands separator.
01823       */
01824       virtual char_type
01825       do_thousands_sep() const
01826       { return _M_data->_M_thousands_sep; }
01827 
01828       /**
01829        *  @brief  Return grouping specification.
01830        *
01831        *  Returns a string representing groupings for the integer part of a
01832        *  number.  This function is a hook for derived classes to change the
01833        *  value returned.  @see grouping() for details.
01834        *
01835        *  @return  String representing grouping specification.
01836       */
01837       virtual string
01838       do_grouping() const
01839       { return _M_data->_M_grouping; }
01840 
01841       /**
01842        *  @brief  Return string representation of bool true.
01843        *
01844        *  Returns a string_type containing the text representation for true
01845        *  bool variables.  This function is a hook for derived classes to
01846        *  change the value returned.
01847        *
01848        *  @return  string_type representing printed form of true.
01849       */
01850       virtual string_type
01851       do_truename() const
01852       { return _M_data->_M_truename; }
01853 
01854       /**
01855        *  @brief  Return string representation of bool false.
01856        *
01857        *  Returns a string_type containing the text representation for false
01858        *  bool variables.  This function is a hook for derived classes to
01859        *  change the value returned.
01860        *
01861        *  @return  string_type representing printed form of false.
01862       */
01863       virtual string_type
01864       do_falsename() const
01865       { return _M_data->_M_falsename; }
01866 
01867       // For use at construction time only.
01868       void
01869       _M_initialize_numpunct(__c_locale __cloc = NULL);
01870     };
01871 
01872   template<typename _CharT>
01873     locale::id numpunct<_CharT>::id;
01874 
01875   template<>
01876     numpunct<char>::~numpunct();
01877 
01878   template<>
01879     void
01880     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
01881 
01882 #ifdef _GLIBCXX_USE_WCHAR_T
01883   template<>
01884     numpunct<wchar_t>::~numpunct();
01885 
01886   template<>
01887     void
01888     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
01889 #endif
01890 
01891   template<typename _CharT>
01892     class numpunct_byname : public numpunct<_CharT>
01893     {
01894     public:
01895       typedef _CharT            char_type;
01896       typedef basic_string<_CharT>  string_type;
01897 
01898       explicit
01899       numpunct_byname(const char* __s, size_t __refs = 0)
01900       : numpunct<_CharT>(__refs)
01901       {
01902     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
01903       {
01904         __c_locale __tmp;
01905         this->_S_create_c_locale(__tmp, __s);
01906         this->_M_initialize_numpunct(__tmp);
01907         this->_S_destroy_c_locale(__tmp);
01908       }
01909       }
01910 
01911     protected:
01912       virtual
01913       ~numpunct_byname() { }
01914     };
01915 
01916   /**
01917    *  @brief  Facet for parsing number strings.
01918    *
01919    *  This facet encapsulates the code to parse and return a number
01920    *  from a string.  It is used by the istream numeric extraction
01921    *  operators.
01922    *
01923    *  The num_get template uses protected virtual functions to provide the
01924    *  actual results.  The public accessors forward the call to the virtual
01925    *  functions.  These virtual functions are hooks for developers to
01926    *  implement the behavior they require from the num_get facet.
01927   */
01928   template<typename _CharT, typename _InIter>
01929     class num_get : public locale::facet
01930     {
01931     public:
01932       // Types:
01933       //@{
01934       /// Public typedefs
01935       typedef _CharT            char_type;
01936       typedef _InIter           iter_type;
01937       //@}
01938 
01939       /// Numpunct facet id.
01940       static locale::id         id;
01941 
01942       /**
01943        *  @brief  Constructor performs initialization.
01944        *
01945        *  This is the constructor provided by the standard.
01946        *
01947        *  @param refs  Passed to the base facet class.
01948       */
01949       explicit
01950       num_get(size_t __refs = 0) : facet(__refs) { }
01951 
01952       /**
01953        *  @brief  Numeric parsing.
01954        *
01955        *  Parses the input stream into the bool @a v.  It does so by calling
01956        *  num_put::do_put().
01957        *
01958        *  If ios_base::boolalpha is set, attempts to read
01959        *  ctype<CharT>::truename() or ctype<CharT>::falsename().  Sets
01960        *  @a v to true or false if successful.  Sets err to
01961        *  ios_base::failbit if reading the string fails.  Sets err to
01962        *  ios_base::eofbit if the stream is emptied.
01963        *
01964        *  If ios_base::boolalpha is not set, proceeds as with reading a long,
01965        *  except if the value is 1, sets @a v to true, if the value is 0, sets
01966        *  @a v to false, and otherwise set err to ios_base::failbit.
01967        *
01968        *  @param  in  Start of input stream.
01969        *  @param  end  End of input stream.
01970        *  @param  io  Source of locale and flags.
01971        *  @param  err  Error flags to set.
01972        *  @param  v  Value to format and insert.
01973        *  @return  Iterator after reading.
01974       */
01975       iter_type
01976       get(iter_type __in, iter_type __end, ios_base& __io,
01977       ios_base::iostate& __err, bool& __v) const
01978       { return this->do_get(__in, __end, __io, __err, __v); }
01979 
01980       //@{
01981       /**
01982        *  @brief  Numeric parsing.
01983        *
01984        *  Parses the input stream into the integral variable @a v.  It does so
01985        *  by calling num_put::do_put().
01986        *
01987        *  Parsing is affected by the flag settings in @a io.
01988        *
01989        *  The basic parse is affected by the value of io.flags() &
01990        *  ios_base::basefield.  If equal to ios_base::oct, parses like the
01991        *  scanf %o specifier.  Else if equal to ios_base::hex, parses like %X
01992        *  specifier.  Else if basefield equal to 0, parses like the %i
01993        *  specifier.  Otherwise, parses like %d for signed and %u for unsigned
01994        *  types.  The matching type length modifier is also used.
01995        *
01996        *  Digit grouping is intrepreted according to numpunct::grouping() and
01997        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
01998        *  consistent, sets err to ios_base::failbit.
01999        *
02000        *  If parsing the string yields a valid value for @a v, @a v is set.
02001        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
02002        *  Sets err to ios_base::eofbit if the stream is emptied.
02003        *
02004        *  @param  in  Start of input stream.
02005        *  @param  end  End of input stream.
02006        *  @param  io  Source of locale and flags.
02007        *  @param  err  Error flags to set.
02008        *  @param  v  Value to format and insert.
02009        *  @return  Iterator after reading.
02010       */
02011       iter_type
02012       get(iter_type __in, iter_type __end, ios_base& __io,
02013       ios_base::iostate& __err, long& __v) const
02014       { return this->do_get(__in, __end, __io, __err, __v); }
02015 
02016       iter_type
02017       get(iter_type __in, iter_type __end, ios_base& __io,
02018       ios_base::iostate& __err, unsigned short& __v) const
02019       { return this->do_get(__in, __end, __io, __err, __v); }
02020 
02021       iter_type
02022       get(iter_type __in, iter_type __end, ios_base& __io,
02023       ios_base::iostate& __err, unsigned int& __v)   const
02024       { return this->do_get(__in, __end, __io, __err, __v); }
02025 
02026       iter_type
02027       get(iter_type __in, iter_type __end, ios_base& __io,
02028       ios_base::iostate& __err, unsigned long& __v)  const
02029       { return this->do_get(__in, __end, __io, __err, __v); }
02030 
02031 #ifdef _GLIBCXX_USE_LONG_LONG
02032       iter_type
02033       get(iter_type __in, iter_type __end, ios_base& __io,
02034       ios_base::iostate& __err, long long& __v) const
02035       { return this->do_get(__in, __end, __io, __err, __v); }
02036 
02037       iter_type
02038       get(iter_type __in, iter_type __end, ios_base& __io,
02039       ios_base::iostate& __err, unsigned long long& __v)  const
02040       { return this->do_get(__in, __end, __io, __err, __v); }
02041 #endif
02042       //@}
02043 
02044       //@{
02045       /**
02046        *  @brief  Numeric parsing.
02047        *
02048        *  Parses the input stream into the integral variable @a v.  It does so
02049        *  by calling num_put::do_put().
02050        *
02051        *  The input characters are parsed like the scanf %g specifier.  The
02052        *  matching type length modifier is also used.
02053        *
02054        *  The decimal point character used is numpunct::decimal_point().
02055        *  Digit grouping is intrepreted according to numpunct::grouping() and
02056        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
02057        *  consistent, sets err to ios_base::failbit.
02058        *
02059        *  If parsing the string yields a valid value for @a v, @a v is set.
02060        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
02061        *  Sets err to ios_base::eofbit if the stream is emptied.
02062        *
02063        *  @param  in  Start of input stream.
02064        *  @param  end  End of input stream.
02065        *  @param  io  Source of locale and flags.
02066        *  @param  err  Error flags to set.
02067        *  @param  v  Value to format and insert.
02068        *  @return  Iterator after reading.
02069       */
02070       iter_type
02071       get(iter_type __in, iter_type __end, ios_base& __io,
02072       ios_base::iostate& __err, float& __v) const
02073       { return this->do_get(__in, __end, __io, __err, __v); }
02074 
02075       iter_type
02076       get(iter_type __in, iter_type __end, ios_base& __io,
02077       ios_base::iostate& __err, double& __v) const
02078       { return this->do_get(__in, __end, __io, __err, __v); }
02079 
02080       iter_type
02081       get(iter_type __in, iter_type __end, ios_base& __io,
02082       ios_base::iostate& __err, long double& __v) const
02083       { return this->do_get(__in, __end, __io, __err, __v); }
02084       //@}
02085 
02086       /**
02087        *  @brief  Numeric parsing.
02088        *
02089        *  Parses the input stream into the pointer variable @a v.  It does so
02090        *  by calling num_put::do_put().
02091        *
02092        *  The input characters are parsed like the scanf %p specifier.
02093        *
02094        *  Digit grouping is intrepreted according to numpunct::grouping() and
02095        *  numpunct::thousands_sep().  If the pattern of digit groups isn't
02096        *  consistent, sets err to ios_base::failbit.
02097        *
02098        *  Note that the digit grouping effect for pointers is a bit ambiguous
02099        *  in the standard and shouldn't be relied on.  See DR 344.
02100        *
02101        *  If parsing the string yields a valid value for @a v, @a v is set.
02102        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
02103        *  Sets err to ios_base::eofbit if the stream is emptied.
02104        *
02105        *  @param  in  Start of input stream.
02106        *  @param  end  End of input stream.
02107        *  @param  io  Source of locale and flags.
02108        *  @param  err  Error flags to set.
02109        *  @param  v  Value to format and insert.
02110        *  @return  Iterator after reading.
02111       */
02112       iter_type
02113       get(iter_type __in, iter_type __end, ios_base& __io,
02114       ios_base::iostate& __err, void*& __v) const
02115       { return this->do_get(__in, __end, __io, __err, __v); }
02116 
02117     protected:
02118       /// Destructor.
02119       virtual ~num_get() { }
02120 
02121       iter_type
02122       _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
02123                string& __xtrc) const;
02124 
02125       template<typename _ValueT>
02126         iter_type
02127         _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
02128                _ValueT& __v) const;
02129 
02130       //@{
02131       /**
02132        *  @brief  Numeric parsing.
02133        *
02134        *  Parses the input stream into the variable @a v.  This function is a
02135        *  hook for derived classes to change the value returned.  @see get()
02136        *  for more details.
02137        *
02138        *  @param  in  Start of input stream.
02139        *  @param  end  End of input stream.
02140        *  @param  io  Source of locale and flags.
02141        *  @param  err  Error flags to set.
02142        *  @param  v  Value to format and insert.
02143        *  @return  Iterator after reading.
02144       */
02145       virtual iter_type
02146       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
02147 
02148 
02149       virtual iter_type
02150       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
02151 
02152       virtual iter_type
02153       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02154           unsigned short&) const;
02155 
02156       virtual iter_type
02157       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02158          unsigned int&) const;
02159 
02160       virtual iter_type
02161       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02162          unsigned long&) const;
02163 
02164 #ifdef _GLIBCXX_USE_LONG_LONG
02165       virtual iter_type
02166       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02167          long long&) const;
02168 
02169       virtual iter_type
02170       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02171          unsigned long long&) const;
02172 #endif
02173 
02174       virtual iter_type
02175       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02176          float&) const;
02177 
02178       virtual iter_type
02179       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02180          double&) const;
02181 
02182       virtual iter_type
02183       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02184          long double&) const;
02185 
02186       virtual iter_type
02187       do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
02188          void*&) const;
02189       //@}
02190     };
02191 
02192   template<typename _CharT, typename _InIter>
02193     locale::id num_get<_CharT, _InIter>::id;
02194 
02195 
02196   /**
02197    *  @brief  Facet for converting numbers to strings.
02198    *
02199    *  This facet encapsulates the code to convert a number to a string.  It is
02200    *  used by the ostream numeric insertion operators.
02201    *
02202    *  The num_put template uses protected virtual functions to provide the
02203    *  actual results.  The public accessors forward the call to the virtual
02204    *  functions.  These virtual functions are hooks for developers to
02205    *  implement the behavior they require from the num_put facet.
02206   */
02207   template<typename _CharT, typename _OutIter>
02208     class num_put : public locale::facet
02209     {
02210     public:
02211       // Types:
02212       //@{
02213       /// Public typedefs
02214       typedef _CharT        char_type;
02215       typedef _OutIter      iter_type;
02216       //@}
02217 
02218       /// Numpunct facet id.
02219       static locale::id     id;
02220 
02221       /**
02222        *  @brief  Constructor performs initialization.
02223        *
02224        *  This is the constructor provided by the standard.
02225        *
02226        *  @param refs  Passed to the base facet class.
02227       */
02228       explicit
02229       num_put(size_t __refs = 0) : facet(__refs) { }
02230 
02231       /**
02232        *  @brief  Numeric formatting.
02233        *
02234        *  Formats the boolean @a v and inserts it into a stream.  It does so
02235        *  by calling num_put::do_put().
02236        *
02237        *  If ios_base::boolalpha is set, writes ctype<CharT>::truename() or
02238        *  ctype<CharT>::falsename().  Otherwise formats @a v as an int.
02239        *
02240        *  @param  s  Stream to write to.
02241        *  @param  io  Source of locale and flags.
02242        *  @param  fill  Char_type to use for filling.
02243        *  @param  v  Value to format and insert.
02244        *  @return  Iterator after writing.
02245       */
02246       iter_type
02247       put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
02248       { return this->do_put(__s, __f, __fill, __v); }
02249 
02250       //@{
02251       /**
02252        *  @brief  Numeric formatting.
02253        *
02254        *  Formats the integral value @a v and inserts it into a
02255        *  stream.  It does so by calling num_put::do_put().
02256        *
02257        *  Formatting is affected by the flag settings in @a io.
02258        *
02259        *  The basic format is affected by the value of io.flags() &
02260        *  ios_base::basefield.  If equal to ios_base::oct, formats like the
02261        *  printf %o specifier.  Else if equal to ios_base::hex, formats like
02262        *  %x or %X with ios_base::uppercase unset or set respectively.
02263        *  Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu
02264        *  for unsigned values.  Note that if both oct and hex are set, neither
02265        *  will take effect.
02266        *
02267        *  If ios_base::showpos is set, '+' is output before positive values.
02268        *  If ios_base::showbase is set, '0' precedes octal values (except 0)
02269        *  and '0[xX]' precedes hex values.
02270        *
02271        *  Thousands separators are inserted according to numpunct::grouping()
02272        *  and numpunct::thousands_sep().  The decimal point character used is
02273        *  numpunct::decimal_point().
02274        *
02275        *  If io.width() is non-zero, enough @a fill characters are inserted to
02276        *  make the result at least that wide.  If
02277        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
02278        *  padded at the end.  If ios_base::internal, then padding occurs
02279        *  immediately after either a '+' or '-' or after '0x' or '0X'.
02280        *  Otherwise, padding occurs at the beginning.
02281        *
02282        *  @param  s  Stream to write to.
02283        *  @param  io  Source of locale and flags.
02284        *  @param  fill  Char_type to use for filling.
02285        *  @param  v  Value to format and insert.
02286        *  @return  Iterator after writing.
02287       */
02288       iter_type
02289       put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
02290       { return this->do_put(__s, __f, __fill, __v); }
02291 
02292       iter_type
02293       put(iter_type __s, ios_base& __f, char_type __fill,
02294       unsigned long __v) const
02295       { return this->do_put(__s, __f, __fill, __v); }
02296 
02297 #ifdef _GLIBCXX_USE_LONG_LONG
02298       iter_type
02299       put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
02300       { return this->do_put(__s, __f, __fill, __v); }
02301 
02302       iter_type
02303       put(iter_type __s, ios_base& __f, char_type __fill,
02304       unsigned long long __v) const
02305       { return this->do_put(__s, __f, __fill, __v); }
02306 #endif
02307       //@}
02308 
02309       //@{
02310       /**
02311        *  @brief  Numeric formatting.
02312        *
02313        *  Formats the floating point value @a v and inserts it into a stream.
02314        *  It does so by calling num_put::do_put().
02315        *
02316        *  Formatting is affected by the flag settings in @a io.
02317        *
02318        *  The basic format is affected by the value of io.flags() &
02319        *  ios_base::floatfield.  If equal to ios_base::fixed, formats like the
02320        *  printf %f specifier.  Else if equal to ios_base::scientific, formats
02321        *  like %e or %E with ios_base::uppercase unset or set respectively.
02322        *  Otherwise, formats like %g or %G depending on uppercase.  Note that
02323        *  if both fixed and scientific are set, the effect will also be like
02324        *  %g or %G.
02325        *
02326        *  The output precision is given by io.precision().  This precision is
02327        *  capped at numeric_limits::digits10 + 2 (different for double and
02328        *  long double).  The default precision is 6.
02329        *
02330        *  If ios_base::showpos is set, '+' is output before positive values.
02331        *  If ios_base::showpoint is set, a decimal point will always be
02332        *  output.
02333        *
02334        *  Thousands separators are inserted according to numpunct::grouping()
02335        *  and numpunct::thousands_sep().  The decimal point character used is
02336        *  numpunct::decimal_point().
02337        *
02338        *  If io.width() is non-zero, enough @a fill characters are inserted to
02339        *  make the result at least that wide.  If
02340        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
02341        *  padded at the end.  If ios_base::internal, then padding occurs
02342        *  immediately after either a '+' or '-' or after '0x' or '0X'.
02343        *  Otherwise, padding occurs at the beginning.
02344        *
02345        *  @param  s  Stream to write to.
02346        *  @param  io  Source of locale and flags.
02347        *  @param  fill  Char_type to use for filling.
02348        *  @param  v  Value to format and insert.
02349        *  @return  Iterator after writing.
02350       */
02351       iter_type
02352       put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
02353       { return this->do_put(__s, __f, __fill, __v); }
02354 
02355       iter_type
02356       put(iter_type __s, ios_base& __f, char_type __fill,
02357       long double __v) const
02358       { return this->do_put(__s, __f, __fill, __v); }
02359       //@}
02360 
02361       /**
02362        *  @brief  Numeric formatting.
02363        *
02364        *  Formats the pointer value @a v and inserts it into a stream.  It
02365        *  does so by calling num_put::do_put().
02366        *
02367        *  This function formats @a v as an unsigned long with ios_base::hex
02368        *  and ios_base::showbase set.
02369        *
02370        *  @param  s  Stream to write to.
02371        *  @param  io  Source of locale and flags.
02372        *  @param  fill  Char_type to use for filling.
02373        *  @param  v  Value to format and insert.
02374        *  @return  Iterator after writing.
02375       */
02376       iter_type
02377       put(iter_type __s, ios_base& __f, char_type __fill,
02378       const void* __v) const
02379       { return this->do_put(__s, __f, __fill, __v); }
02380 
02381     protected:
02382       template<typename _ValueT>
02383         iter_type
02384         _M_insert_float(iter_type, ios_base& __io, char_type __fill,
02385             char __mod, _ValueT __v) const;
02386 
02387       void
02388       _M_group_float(const char* __grouping, size_t __grouping_size,
02389              char_type __sep, const char_type* __p, char_type* __new,
02390              char_type* __cs, int& __len) const;
02391 
02392       template<typename _ValueT>
02393         iter_type
02394         _M_insert_int(iter_type, ios_base& __io, char_type __fill,
02395               _ValueT __v) const;
02396 
02397       void
02398       _M_group_int(const char* __grouping, size_t __grouping_size,
02399            char_type __sep, ios_base& __io, char_type* __new,
02400            char_type* __cs, int& __len) const;
02401 
02402       void
02403       _M_pad(char_type __fill, streamsize __w, ios_base& __io,
02404          char_type* __new, const char_type* __cs, int& __len) const;
02405 
02406       /// Destructor.
02407       virtual
02408       ~num_put() { };
02409 
02410       //@{
02411       /**
02412        *  @brief  Numeric formatting.
02413        *
02414        *  These functions do the work of formatting numeric values and
02415        *  inserting them into a stream. This function is a hook for derived
02416        *  classes to change the value returned.
02417        *
02418        *  @param  s  Stream to write to.
02419        *  @param  io  Source of locale and flags.
02420        *  @param  fill  Char_type to use for filling.
02421        *  @param  v  Value to format and insert.
02422        *  @return  Iterator after writing.
02423       */
02424       virtual iter_type
02425       do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
02426 
02427       virtual iter_type
02428       do_put(iter_type, ios_base&, char_type __fill, long __v) const;
02429 
02430       virtual iter_type
02431       do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
02432 
02433 #ifdef _GLIBCXX_USE_LONG_LONG
02434       virtual iter_type
02435       do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
02436 
02437       virtual iter_type
02438       do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
02439 #endif
02440 
02441       virtual iter_type
02442       do_put(iter_type, ios_base&, char_type __fill, double __v) const;
02443 
02444       virtual iter_type
02445       do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
02446 
02447       virtual iter_type
02448       do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
02449       //@}
02450     };
02451 
02452   template <typename _CharT, typename _OutIter>
02453     locale::id num_put<_CharT, _OutIter>::id;
02454 
02455 
02456   /**
02457    *  @brief  Facet for localized string comparison.
02458    *
02459    *  This facet encapsulates the code to compare strings in a localized
02460    *  manner.
02461    *
02462    *  The collate template uses protected virtual functions to provide
02463    *  the actual results.  The public accessors forward the call to
02464    *  the virtual functions.  These virtual functions are hooks for
02465    *  developers to implement the behavior they require from the
02466    *  collate facet.
02467   */
02468   template<typename _CharT>
02469     class collate : public locale::facet
02470     {
02471     public:
02472       // Types:
02473       //@{
02474       /// Public typedefs
02475       typedef _CharT            char_type;
02476       typedef basic_string<_CharT>  string_type;
02477       //@}
02478 
02479     protected:
02480       // Underlying "C" library locale information saved from
02481       // initialization, needed by collate_byname as well.
02482       __c_locale            _M_c_locale_collate;
02483 
02484     public:
02485       /// Numpunct facet id.
02486       static locale::id         id;
02487 
02488       /**
02489        *  @brief  Constructor performs initialization.
02490        *
02491        *  This is the constructor provided by the standard.
02492        *
02493        *  @param refs  Passed to the base facet class.
02494       */
02495       explicit
02496       collate(size_t __refs = 0)
02497       : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
02498       { }
02499 
02500       /**
02501        *  @brief  Internal constructor. Not for general use.
02502        *
02503        *  This is a constructor for use by the library itself to set up new
02504        *  locales.
02505        *
02506        *  @param cloc  The "C" locale.
02507        *  @param refs  Passed to the base facet class.
02508       */
02509       explicit
02510       collate(__c_locale __cloc, size_t __refs = 0)
02511       : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
02512       { }
02513 
02514       /**
02515        *  @brief  Compare two strings.
02516        *
02517        *  This function compares two strings and returns the result by calling
02518        *  collate::do_compare().
02519        *
02520        *  @param lo1  Start of string 1.
02521        *  @param hi1  End of string 1.
02522        *  @param lo2  Start of string 2.
02523        *  @param hi2  End of string 2.
02524        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
02525       */
02526       int
02527       compare(const _CharT* __lo1, const _CharT* __hi1,
02528           const _CharT* __lo2, const _CharT* __hi2) const
02529       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
02530 
02531       /**
02532        *  @brief  Transform string to comparable form.
02533        *
02534        *  This function is a wrapper for strxfrm functionality.  It takes the
02535        *  input string and returns a modified string that can be directly
02536        *  compared to other transformed strings.  In the "C" locale, this
02537        *  function just returns a copy of the input string.  In some other
02538        *  locales, it may replace two chars with one, change a char for
02539        *  another, etc.  It does so by returning collate::do_transform().
02540        *
02541        *  @param lo  Start of string.
02542        *  @param hi  End of string.
02543        *  @return  Transformed string_type.
02544       */
02545       string_type
02546       transform(const _CharT* __lo, const _CharT* __hi) const
02547       { return this->do_transform(__lo, __hi); }
02548 
02549       /**
02550        *  @brief  Return hash of a string.
02551        *
02552        *  This function computes and returns a hash on the input string.  It
02553        *  does so by returning collate::do_hash().
02554        *
02555        *  @param lo  Start of string.
02556        *  @param hi  End of string.
02557        *  @return  Hash value.
02558       */
02559       long
02560       hash(const _CharT* __lo, const _CharT* __hi) const
02561       { return this->do_hash(__lo, __hi); }
02562 
02563       // Used to abstract out _CharT bits in virtual member functions, below.
02564       int
02565       _M_compare(const _CharT*, const _CharT*) const;
02566 
02567       size_t
02568       _M_transform(_CharT*, const _CharT*, size_t) const;
02569 
02570   protected:
02571       /// Destructor.
02572       virtual
02573       ~collate()
02574       { _S_destroy_c_locale(_M_c_locale_collate); }
02575 
02576       /**
02577        *  @brief  Compare two strings.
02578        *
02579        *  This function is a hook for derived classes to change the value
02580        *  returned.  @see compare().
02581        *
02582        *  @param lo1  Start of string 1.
02583        *  @param hi1  End of string 1.
02584        *  @param lo2  Start of string 2.
02585        *  @param hi2  End of string 2.
02586        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
02587       */
02588       virtual int
02589       do_compare(const _CharT* __lo1, const _CharT* __hi1,
02590          const _CharT* __lo2, const _CharT* __hi2) const;
02591 
02592       /**
02593        *  @brief  Transform string to comparable form.
02594        *
02595        *  This function is a hook for derived classes to change the value
02596        *  returned.
02597        *
02598        *  @param lo1  Start of string 1.
02599        *  @param hi1  End of string 1.
02600        *  @param lo2  Start of string 2.
02601        *  @param hi2  End of string 2.
02602        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
02603       */
02604       virtual string_type
02605       do_transform(const _CharT* __lo, const _CharT* __hi) const;
02606 
02607       /**
02608        *  @brief  Return hash of a string.
02609        *
02610        *  This function computes and returns a hash on the input string.  This
02611        *  function is a hook for derived classes to change the value returned.
02612        *
02613        *  @param lo  Start of string.
02614        *  @param hi  End of string.
02615        *  @return  Hash value.
02616       */
02617       virtual long
02618       do_hash(const _CharT* __lo, const _CharT* __hi) const;
02619     };
02620 
02621   template<typename _CharT>
02622     locale::id collate<_CharT>::id;
02623 
02624   // Specializations.
02625   template<>
02626     int
02627     collate<char>::_M_compare(const char*, const char*) const;
02628 
02629   template<>
02630     size_t
02631     collate<char>::_M_transform(char*, const char*, size_t) const;
02632 
02633 #ifdef _GLIBCXX_USE_WCHAR_T
02634   template<>
02635     int
02636     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
02637 
02638   template<>
02639     size_t
02640     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
02641 #endif
02642 
02643   template<typename _CharT>
02644     class collate_byname : public collate<_CharT>
02645     {
02646     public:
02647       //@{
02648       /// Public typedefs
02649       typedef _CharT               char_type;
02650       typedef basic_string<_CharT> string_type;
02651       //@}
02652 
02653       explicit
02654       collate_byname(const char* __s, size_t __refs = 0)
02655       : collate<_CharT>(__refs)
02656       {
02657     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
02658       {
02659         this->_S_destroy_c_locale(this->_M_c_locale_collate);
02660         this->_S_create_c_locale(this->_M_c_locale_collate, __s);
02661       }
02662       }
02663 
02664     protected:
02665       virtual
02666       ~collate_byname() { }
02667     };
02668 
02669 
02670   /**
02671    *  @brief  Time format ordering data.
02672    *
02673    *  This class provides an enum representing different orderings of day,
02674    *  month, and year.
02675   */
02676   class time_base
02677   {
02678   public:
02679     enum dateorder { no_order, dmy, mdy, ymd, ydm };
02680   };
02681 
02682   template<typename _CharT>
02683     struct __timepunct_cache : public locale::facet
02684     {
02685       // List of all known timezones, with GMT first.
02686       static const _CharT*      _S_timezones[14];
02687 
02688       const _CharT*         _M_date_format;
02689       const _CharT*         _M_date_era_format;
02690       const _CharT*         _M_time_format;
02691       const _CharT*         _M_time_era_format;
02692       const _CharT*         _M_date_time_format;
02693       const _CharT*         _M_date_time_era_format;
02694       const _CharT*         _M_am;
02695       const _CharT*         _M_pm;
02696       const _CharT*         _M_am_pm_format;
02697 
02698       // Day names, starting with "C"'s Sunday.
02699       const _CharT*         _M_day1;
02700       const _CharT*         _M_day2;
02701       const _CharT*         _M_day3;
02702       const _CharT*         _M_day4;
02703       const _CharT*         _M_day5;
02704       const _CharT*         _M_day6;
02705       const _CharT*         _M_day7;
02706 
02707       // Abbreviated day names, starting with "C"'s Sun.
02708       const _CharT*         _M_aday1;
02709       const _CharT*         _M_aday2;
02710       const _CharT*         _M_aday3;
02711       const _CharT*         _M_aday4;
02712       const _CharT*         _M_aday5;
02713       const _CharT*         _M_aday6;
02714       const _CharT*         _M_aday7;
02715 
02716       // Month names, starting with "C"'s January.
02717       const _CharT*         _M_month01;
02718       const _CharT*         _M_month02;
02719       const _CharT*         _M_month03;
02720       const _CharT*         _M_month04;
02721       const _CharT*         _M_month05;
02722       const _CharT*         _M_month06;
02723       const _CharT*         _M_month07;
02724       const _CharT*         _M_month08;
02725       const _CharT*         _M_month09;
02726       const _CharT*         _M_month10;
02727       const _CharT*         _M_month11;
02728       const _CharT*         _M_month12;
02729 
02730       // Abbreviated month names, starting with "C"'s Jan.
02731       const _CharT*         _M_amonth01;
02732       const _CharT*         _M_amonth02;
02733       const _CharT*         _M_amonth03;
02734       const _CharT*         _M_amonth04;
02735       const _CharT*         _M_amonth05;
02736       const _CharT*         _M_amonth06;
02737       const _CharT*         _M_amonth07;
02738       const _CharT*         _M_amonth08;
02739       const _CharT*         _M_amonth09;
02740       const _CharT*         _M_amonth10;
02741       const _CharT*         _M_amonth11;
02742       const _CharT*         _M_amonth12;
02743 
02744       bool              _M_allocated;
02745 
02746       __timepunct_cache(size_t __refs = 0) : facet(__refs),
02747       _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL),
02748       _M_time_era_format(NULL), _M_date_time_format(NULL),
02749       _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL),
02750       _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL),
02751       _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL),
02752       _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL),
02753       _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL),
02754       _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL),
02755       _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL),
02756       _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL),
02757       _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL),
02758       _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL),
02759       _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL),
02760       _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false)
02761       { }
02762 
02763       ~__timepunct_cache();
02764 
02765       void
02766       _M_cache(const locale& __loc);
02767 
02768     private:
02769       __timepunct_cache&
02770       operator=(const __timepunct_cache&);
02771       
02772       explicit
02773       __timepunct_cache(const __timepunct_cache&);
02774     };
02775 
02776   template<typename _CharT>
02777     __timepunct_cache<_CharT>::~__timepunct_cache()
02778     {
02779       if (_M_allocated)
02780     {
02781       // Unused.
02782     }
02783     }
02784 
02785   // Specializations.
02786   template<>
02787     const char*
02788     __timepunct_cache<char>::_S_timezones[14];
02789 
02790 #ifdef _GLIBCXX_USE_WCHAR_T
02791   template<>
02792     const wchar_t*
02793     __timepunct_cache<wchar_t>::_S_timezones[14];
02794 #endif
02795 
02796   // Generic.
02797   template<typename _CharT>
02798     const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];
02799 
02800   template<typename _CharT>
02801     class __timepunct : public locale::facet
02802     {
02803     public:
02804       // Types:
02805       typedef _CharT            __char_type;
02806       typedef basic_string<_CharT>  __string_type;
02807       typedef __timepunct_cache<_CharT> __cache_type;
02808 
02809     protected:
02810       __cache_type*         _M_data;
02811       __c_locale            _M_c_locale_timepunct;
02812       const char*           _M_name_timepunct;
02813 
02814     public:
02815       /// Numpunct facet id.
02816       static locale::id         id;
02817 
02818       explicit
02819       __timepunct(size_t __refs = 0);
02820 
02821       explicit
02822       __timepunct(__cache_type* __cache, size_t __refs = 0);
02823 
02824       /**
02825        *  @brief  Internal constructor. Not for general use.
02826        *
02827        *  This is a constructor for use by the library itself to set up new
02828        *  locales.
02829        *
02830        *  @param cloc  The "C" locale.
02831        *  @param s  The name of a locale.
02832        *  @param refs  Passed to the base facet class.
02833       */
02834       explicit
02835       __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
02836 
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   template<typename _CharT, typename _InIter>
03294     class time_get_byname : public time_get<_CharT, _InIter>
03295     {
03296     public:
03297       // Types:
03298       typedef _CharT            char_type;
03299       typedef _InIter           iter_type;
03300 
03301       explicit
03302       time_get_byname(const char*, size_t __refs = 0)
03303       : time_get<_CharT, _InIter>(__refs) { }
03304 
03305     protected:
03306       virtual
03307       ~time_get_byname() { }
03308     };
03309 
03310   /**
03311    *  @brief  Facet for outputting dates and times.
03312    *
03313    *  This facet encapsulates the code to format and output dates and times
03314    *  according to formats used by strftime().
03315    *
03316    *  The time_put template uses protected virtual functions to provide the
03317    *  actual results.  The public accessors forward the call to the virtual
03318    *  functions.  These virtual functions are hooks for developers to
03319    *  implement the behavior they require from the time_put facet.
03320   */
03321   template<typename _CharT, typename _OutIter>
03322     class time_put : public locale::facet
03323     {
03324     public:
03325       // Types:
03326       //@{
03327       /// Public typedefs
03328       typedef _CharT            char_type;
03329       typedef _OutIter          iter_type;
03330       //@}
03331 
03332       /// Numpunct facet id.
03333       static locale::id         id;
03334 
03335       /**
03336        *  @brief  Constructor performs initialization.
03337        *
03338        *  This is the constructor provided by the standard.
03339        *
03340        *  @param refs  Passed to the base facet class.
03341       */
03342       explicit
03343       time_put(size_t __refs = 0)
03344       : facet(__refs) { }
03345 
03346       /**
03347        *  @brief  Format and output a time or date.
03348        *
03349        *  This function formats the data in struct tm according to the
03350        *  provided format string.  The format string is interpreted as by
03351        *  strftime().
03352        *
03353        *  @param  s  The stream to write to.
03354        *  @param  io  Source of locale.
03355        *  @param  fill  char_type to use for padding.
03356        *  @param  tm  Struct tm with date and time info to format.
03357        *  @param  beg  Start of format string.
03358        *  @param  end  End of format string.
03359        *  @return  Iterator after writing.
03360        */
03361       iter_type
03362       put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
03363       const _CharT* __beg, const _CharT* __end) const;
03364 
03365       /**
03366        *  @brief  Format and output a time or date.
03367        *
03368        *  This function formats the data in struct tm according to the
03369        *  provided format char and optional modifier.  The format and modifier
03370        *  are interpreted as by strftime().  It does so by returning
03371        *  time_put::do_put().
03372        *
03373        *  @param  s  The stream to write to.
03374        *  @param  io  Source of locale.
03375        *  @param  fill  char_type to use for padding.
03376        *  @param  tm  Struct tm with date and time info to format.
03377        *  @param  format  Format char.
03378        *  @param  mod  Optional modifier char.
03379        *  @return  Iterator after writing.
03380        */
03381       iter_type
03382       put(iter_type __s, ios_base& __io, char_type __fill,
03383       const tm* __tm, char __format, char __mod = 0) const
03384       { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
03385 
03386     protected:
03387       /// Destructor.
03388       virtual
03389       ~time_put()
03390       { }
03391 
03392       /**
03393        *  @brief  Format and output a time or date.
03394        *
03395        *  This function formats the data in struct tm according to the
03396        *  provided format char and optional modifier.  This function is a hook
03397        *  for derived classes to change the value returned.  @see put() for
03398        *  more details.
03399        *
03400        *  @param  s  The stream to write to.
03401        *  @param  io  Source of locale.
03402        *  @param  fill  char_type to use for padding.
03403        *  @param  tm  Struct tm with date and time info to format.
03404        *  @param  format  Format char.
03405        *  @param  mod  Optional modifier char.
03406        *  @return  Iterator after writing.
03407        */
03408       virtual iter_type
03409       do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
03410          char __format, char __mod) const;
03411     };
03412 
03413   template<typename _CharT, typename _OutIter>
03414     locale::id time_put<_CharT, _OutIter>::id;
03415 
03416   template<typename _CharT, typename _OutIter>
03417     class time_put_byname : public time_put<_CharT, _OutIter>
03418     {
03419     public:
03420       // Types:
03421       typedef _CharT            char_type;
03422       typedef _OutIter          iter_type;
03423 
03424       explicit
03425       time_put_byname(const char*, size_t __refs = 0)
03426       : time_put<_CharT, _OutIter>(__refs)
03427       { };
03428 
03429     protected:
03430       virtual
03431       ~time_put_byname() { }
03432     };
03433 
03434 
03435   /**
03436    *  @brief  Money format ordering data.
03437    *
03438    *  This class contains an ordered array of 4 fields to represent the
03439    *  pattern for formatting a money amount.  Each field may contain one entry
03440    *  from the part enum.  symbol, sign, and value must be present and the
03441    *  remaining field must contain either none or space.  @see
03442    *  moneypunct::pos_format() and moneypunct::neg_format() for details of how
03443    *  these fields are interpreted.
03444   */
03445   class money_base
03446   {
03447   public:
03448     enum part { none, space, symbol, sign, value };
03449     struct pattern { char field[4]; };
03450 
03451     static const pattern _S_default_pattern;
03452 
03453     enum
03454     {
03455       _S_minus,
03456       _S_zero,
03457       _S_end = 11
03458     };
03459 
03460     // String literal of acceptable (narrow) input/output, for
03461     // money_get/money_put. "-0123456789"
03462     static const char* _S_atoms;
03463 
03464     // Construct and return valid pattern consisting of some combination of:
03465     // space none symbol sign value
03466     static pattern
03467     _S_construct_pattern(char __precedes, char __space, char __posn);
03468   };
03469 
03470   template<typename _CharT, bool _Intl>
03471     struct __moneypunct_cache : public locale::facet
03472     {
03473       const char*           _M_grouping;
03474       size_t                            _M_grouping_size;
03475       bool              _M_use_grouping;
03476       _CharT                _M_decimal_point;
03477       _CharT                _M_thousands_sep;
03478       const _CharT*         _M_curr_symbol;
03479       size_t                            _M_curr_symbol_size;
03480       const _CharT*         _M_positive_sign;
03481       size_t                            _M_positive_sign_size;
03482       const _CharT*         _M_negative_sign;
03483       size_t                            _M_negative_sign_size;
03484       int               _M_frac_digits;
03485       money_base::pattern       _M_pos_format;
03486       money_base::pattern           _M_neg_format;
03487 
03488       // A list of valid numeric literals for input and output: in the standard
03489       // "C" locale, this is "-0123456789". This array contains the chars after
03490       // having been passed through the current locale's ctype<_CharT>.widen().
03491       _CharT                _M_atoms[money_base::_S_end];
03492 
03493       bool              _M_allocated;
03494 
03495       __moneypunct_cache(size_t __refs = 0) : facet(__refs),
03496       _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
03497       _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),
03498       _M_curr_symbol(NULL), _M_curr_symbol_size(0),
03499       _M_positive_sign(NULL), _M_positive_sign_size(0),
03500       _M_negative_sign(NULL), _M_negative_sign_size(0),
03501       _M_frac_digits(0),
03502       _M_pos_format(money_base::pattern()),
03503       _M_neg_format(money_base::pattern()), _M_allocated(false)
03504       { }
03505 
03506       ~__moneypunct_cache();
03507 
03508       void
03509       _M_cache(const locale& __loc);
03510 
03511     private:
03512       __moneypunct_cache&
03513       operator=(const __moneypunct_cache&);
03514       
03515       explicit
03516       __moneypunct_cache(const __moneypunct_cache&);
03517     };
03518 
03519   template<typename _CharT, bool _Intl>
03520     __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache()
03521     {
03522       if (_M_allocated)
03523     {
03524       delete [] _M_grouping;
03525       delete [] _M_curr_symbol;
03526       delete [] _M_positive_sign;
03527       delete [] _M_negative_sign;
03528     }
03529     }
03530 
03531   /**
03532    *  @brief  Facet for formatting data for money amounts.
03533    *
03534    *  This facet encapsulates the punctuation, grouping and other formatting
03535    *  features of money amount string representations.
03536   */
03537   template<typename _CharT, bool _Intl>
03538     class moneypunct : public locale::facet, public money_base
03539     {
03540     public:
03541       // Types:
03542       //@{
03543       /// Public typedefs
03544       typedef _CharT            char_type;
03545       typedef basic_string<_CharT>  string_type;
03546       //@}
03547       typedef __moneypunct_cache<_CharT, _Intl>     __cache_type;
03548 
03549     private:
03550       __cache_type*         _M_data;
03551 
03552     public:
03553       /// This value is provided by the standard, but no reason for its
03554       /// existence.
03555       static const bool         intl = _Intl;
03556       /// Numpunct facet id.
03557       static locale::id         id;
03558 
03559       /**
03560        *  @brief  Constructor performs initialization.
03561        *
03562        *  This is the constructor provided by the standard.
03563        *
03564        *  @param refs  Passed to the base facet class.
03565       */
03566       explicit
03567       moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
03568       { _M_initialize_moneypunct(); }
03569 
03570       /**
03571        *  @brief  Constructor performs initialization.
03572        *
03573        *  This is an internal constructor.
03574        *
03575        *  @param cache  Cache for optimization.
03576        *  @param refs  Passed to the base facet class.
03577       */
03578       explicit
03579       moneypunct(__cache_type* __cache, size_t __refs = 0)
03580       : facet(__refs), _M_data(__cache)
03581       { _M_initialize_moneypunct(); }
03582 
03583       /**
03584        *  @brief  Internal constructor. Not for general use.
03585        *
03586        *  This is a constructor for use by the library itself to set up new
03587        *  locales.
03588        *
03589        *  @param cloc  The "C" locale.
03590        *  @param s  The name of a locale.
03591        *  @param refs  Passed to the base facet class.
03592       */
03593       explicit
03594       moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
03595       : facet(__refs), _M_data(NULL)
03596       { _M_initialize_moneypunct(__cloc, __s); }
03597 
03598       /**
03599        *  @brief  Return decimal point character.
03600        *
03601        *  This function returns a char_type to use as a decimal point.  It
03602        *  does so by returning returning
03603        *  moneypunct<char_type>::do_decimal_point().
03604        *
03605        *  @return  @a char_type representing a decimal point.
03606       */
03607       char_type
03608       decimal_point() const
03609       { return this->do_decimal_point(); }
03610 
03611       /**
03612        *  @brief  Return thousands separator character.
03613        *
03614        *  This function returns a char_type to use as a thousands
03615        *  separator.  It does so by returning returning
03616        *  moneypunct<char_type>::do_thousands_sep().
03617        *
03618        *  @return  char_type representing a thousands separator.
03619       */
03620       char_type
03621       thousands_sep() const
03622       { return this->do_thousands_sep(); }
03623 
03624       /**
03625        *  @brief  Return grouping specification.
03626        *
03627        *  This function returns a string representing groupings for the
03628        *  integer part of an amount.  Groupings indicate where thousands
03629        *  separators should be inserted.
03630        *
03631        *  Each char in the return string is interpret as an integer rather
03632        *  than a character.  These numbers represent the number of digits in a
03633        *  group.  The first char in the string represents the number of digits
03634        *  in the least significant group.  If a char is negative, it indicates
03635        *  an unlimited number of digits for the group.  If more chars from the
03636        *  string are required to group a number, the last char is used
03637        *  repeatedly.
03638        *
03639        *  For example, if the grouping() returns "\003\002" and is applied to
03640        *  the number 123456789, this corresponds to 12,34,56,789.  Note that
03641        *  if the string was "32", this would put more than 50 digits into the
03642        *  least significant group if the character set is ASCII.
03643        *
03644        *  The string is returned by calling
03645        *  moneypunct<char_type>::do_grouping().
03646        *
03647        *  @return  string representing grouping specification.
03648       */
03649       string
03650       grouping() const
03651       { return this->do_grouping(); }
03652 
03653       /**
03654        *  @brief  Return currency symbol string.
03655        *
03656        *  This function returns a string_type to use as a currency symbol.  It
03657        *  does so by returning returning
03658        *  moneypunct<char_type>::do_curr_symbol().
03659        *
03660        *  @return  @a string_type representing a currency symbol.
03661       */
03662       string_type
03663       curr_symbol() const
03664       { return this->do_curr_symbol(); }
03665 
03666       /**
03667        *  @brief  Return positive sign string.
03668        *
03669        *  This function returns a string_type to use as a sign for positive
03670        *  amounts.  It does so by returning returning
03671        *  moneypunct<char_type>::do_positive_sign().
03672        *
03673        *  If the return value contains more than one character, the first
03674        *  character appears in the position indicated by pos_format() and the
03675        *  remainder appear at the end of the formatted string.
03676        *
03677        *  @return  @a string_type representing a positive sign.
03678       */
03679       string_type
03680       positive_sign() const
03681       { return this->do_positive_sign(); }
03682 
03683       /**
03684        *  @brief  Return negative sign string.
03685        *
03686        *  This function returns a string_type to use as a sign for negative
03687        *  amounts.  It does so by returning returning
03688        *  moneypunct<char_type>::do_negative_sign().
03689        *
03690        *  If the return value contains more than one character, the first
03691        *  character appears in the position indicated by neg_format() and the
03692        *  remainder appear at the end of the formatted string.
03693        *
03694        *  @return  @a string_type representing a negative sign.
03695       */
03696       string_type
03697       negative_sign() const
03698       { return this->do_negative_sign(); }
03699 
03700       /**
03701        *  @brief  Return number of digits in fraction.
03702        *
03703        *  This function returns the exact number of digits that make up the
03704        *  fractional part of a money amount.  It does so by returning
03705        *  returning moneypunct<char_type>::do_frac_digits().
03706        *
03707        *  The fractional part of a money amount is optional.  But if it is
03708        *  present, there must be frac_digits() digits.
03709        *
03710        *  @return  Number of digits in amount fraction.
03711       */
03712       int
03713       frac_digits() const
03714       { return this->do_frac_digits(); }
03715 
03716       //@{
03717       /**
03718        *  @brief  Return pattern for money values.
03719        *
03720        *  This function returns a pattern describing the formatting of a
03721        *  positive or negative valued money amount.  It does so by returning
03722        *  returning moneypunct<char_type>::do_pos_format() or
03723        *  moneypunct<char_type>::do_neg_format().
03724        *
03725        *  The pattern has 4 fields describing the ordering of symbol, sign,
03726        *  value, and none or space.  There must be one of each in the pattern.
03727        *  The none and space enums may not appear in the first field and space
03728        *  may not appear in the final field.
03729        *
03730        *  The parts of a money string must appear in the order indicated by
03731        *  the fields of the pattern.  The symbol field indicates that the
03732        *  value of curr_symbol() may be present.  The sign field indicates
03733        *  that the value of positive_sign() or negative_sign() must be
03734        *  present.  The value field indicates that the absolute value of the
03735        *  money amount is present.  none indicates 0 or more whitespace
03736        *  characters, except at the end, where it permits no whitespace.
03737        *  space indicates that 1 or more whitespace characters must be
03738        *  present.
03739        *
03740        *  For example, for the US locale and pos_format() pattern
03741        *  {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() ==
03742        *  '+', and value 10.01, and options set to force the symbol, the
03743        *  corresponding string is "$+10.01".
03744        *
03745        *  @return  Pattern for money values.
03746       */
03747       pattern
03748       pos_format() const
03749       { return this->do_pos_format(); }
03750 
03751       pattern
03752       neg_format() const
03753       { return this->do_neg_format(); }
03754       //@}
03755 
03756     protected:
03757       /// Destructor.
03758       virtual
03759       ~moneypunct();
03760 
03761       /**
03762        *  @brief  Return decimal point character.
03763        *
03764        *  Returns a char_type to use as a decimal point.  This function is a
03765        *  hook for derived classes to change the value returned.
03766        *
03767        *  @return  @a char_type representing a decimal point.
03768       */
03769       virtual char_type
03770       do_decimal_point() const
03771       { return _M_data->_M_decimal_point; }
03772 
03773       /**
03774        *  @brief  Return thousands separator character.
03775        *
03776        *  Returns a char_type to use as a thousands separator.  This function
03777        *  is a hook for derived classes to change the value returned.
03778        *
03779        *  @return  @a char_type representing a thousands separator.
03780       */
03781       virtual char_type
03782       do_thousands_sep() const
03783       { return _M_data->_M_thousands_sep; }
03784 
03785       /**
03786        *  @brief  Return grouping specification.
03787        *
03788        *  Returns a string representing groupings for the integer part of a
03789        *  number.  This function is a hook for derived classes to change the
03790        *  value returned.  @see grouping() for details.
03791        *
03792        *  @return  String representing grouping specification.
03793       */
03794       virtual string
03795       do_grouping() const
03796       { return _M_data->_M_grouping; }
03797 
03798       /**
03799        *  @brief  Return currency symbol string.
03800        *
03801        *  This function returns a string_type to use as a currency symbol.
03802        *  This function is a hook for derived classes to change the value
03803        *  returned.  @see curr_symbol() for details.
03804        *
03805        *  @return  @a string_type representing a currency symbol.
03806       */
03807       virtual string_type
03808       do_curr_symbol()   const
03809       { return _M_data->_M_curr_symbol; }
03810 
03811       /**
03812        *  @brief  Return positive sign string.
03813        *
03814        *  This function returns a string_type to use as a sign for positive
03815        *  amounts.  This function is a hook for derived classes to change the
03816        *  value returned.  @see positive_sign() for details.
03817        *
03818        *  @return  @a string_type representing a positive sign.
03819       */
03820       virtual string_type
03821       do_positive_sign() const
03822       { return _M_data->_M_positive_sign; }
03823 
03824       /**
03825        *  @brief  Return negative sign string.
03826        *
03827        *  This function returns a string_type to use as a sign for negative
03828        *  amounts.  This function is a hook for derived classes to change the
03829        *  value returned.  @see negative_sign() for details.
03830        *
03831        *  @return  @a string_type representing a negative sign.
03832       */
03833       virtual string_type
03834       do_negative_sign() const
03835       { return _M_data->_M_negative_sign; }
03836 
03837       /**
03838        *  @brief  Return number of digits in fraction.
03839        *
03840        *  This function returns the exact number of digits that make up the
03841        *  fractional part of a money amount.  This function is a hook for
03842        *  derived classes to change the value returned.  @see frac_digits()
03843        *  for details.
03844        *
03845        *  @return  Number of digits in amount fraction.
03846       */
03847       virtual int
03848       do_frac_digits() const
03849       { return _M_data->_M_frac_digits; }
03850 
03851       /**
03852        *  @brief  Return pattern for money values.
03853        *
03854        *  This function returns a pattern describing the formatting of a
03855        *  positive valued money amount.  This function is a hook for derived
03856        *  classes to change the value returned.  @see pos_format() for
03857        *  details.
03858        *
03859        *  @return  Pattern for money values.
03860       */
03861       virtual pattern
03862       do_pos_format() const
03863       { return _M_data->_M_pos_format; }
03864 
03865       /**
03866        *  @brief  Return pattern for money values.
03867        *
03868        *  This function returns a pattern describing the formatting of a
03869        *  negative valued money amount.  This function is a hook for derived
03870        *  classes to change the value returned.  @see neg_format() for
03871        *  details.
03872        *
03873        *  @return  Pattern for money values.
03874       */
03875       virtual pattern
03876       do_neg_format() const
03877       { return _M_data->_M_neg_format; }
03878 
03879       // For use at construction time only.
03880        void
03881        _M_initialize_moneypunct(__c_locale __cloc = NULL,
03882                 const char* __name = NULL);
03883     };
03884 
03885   template<typename _CharT, bool _Intl>
03886     locale::id moneypunct<_CharT, _Intl>::id;
03887 
03888   template<typename _CharT, bool _Intl>
03889     const bool moneypunct<_CharT, _Intl>::intl;
03890 
03891   template<>
03892     moneypunct<char, true>::~moneypunct();
03893 
03894   template<>
03895     moneypunct<char, false>::~moneypunct();
03896 
03897   template<>
03898     void
03899     moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
03900 
03901   template<>
03902     void
03903     moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
03904 
03905 #ifdef _GLIBCXX_USE_WCHAR_T
03906   template<>
03907     moneypunct<wchar_t, true>::~moneypunct();
03908 
03909   template<>
03910     moneypunct<wchar_t, false>::~moneypunct();
03911 
03912   template<>
03913     void
03914     moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
03915                             const char*);
03916 
03917   template<>
03918     void
03919     moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
03920                              const char*);
03921 #endif
03922 
03923   template<typename _CharT, bool _Intl>
03924     class moneypunct_byname : public moneypunct<_CharT, _Intl>
03925     {
03926     public:
03927       typedef _CharT            char_type;
03928       typedef basic_string<_CharT>  string_type;
03929 
03930       static const bool intl = _Intl;
03931 
03932       explicit
03933       moneypunct_byname(const char* __s, size_t __refs = 0)
03934       : moneypunct<_CharT, _Intl>(__refs)
03935       {
03936     if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
03937       {
03938         __c_locale __tmp;
03939         this->_S_create_c_locale(__tmp, __s);
03940         this->_M_initialize_moneypunct(__tmp);
03941         this->_S_destroy_c_locale(__tmp);
03942       }
03943       }
03944 
03945     protected:
03946       virtual
03947       ~moneypunct_byname() { }
03948     };
03949 
03950   template<typename _CharT, bool _Intl>
03951     const bool moneypunct_byname<_CharT, _Intl>::intl;
03952 
03953   /**
03954    *  @brief  Facet for parsing monetary amounts.
03955    *
03956    *  This facet encapsulates the code to parse and return a monetary
03957    *  amount from a string.
03958    *
03959    *  The money_get template uses protected virtual functions to
03960    *  provide the actual results.  The public accessors forward the
03961    *  call to the virtual functions.  These virtual functions are
03962    *  hooks for developers to implement the behavior they require from
03963    *  the money_get facet.
03964   */
03965   template<typename _CharT, typename _InIter>
03966     class money_get : public locale::facet
03967     {
03968     public:
03969       // Types:
03970       //@{
03971       /// Public typedefs
03972       typedef _CharT            char_type;
03973       typedef _InIter           iter_type;
03974       typedef basic_string<_CharT>  string_type;
03975       //@}
03976 
03977       /// Numpunct facet id.
03978       static locale::id         id;
03979 
03980       /**
03981        *  @brief  Constructor performs initialization.
03982        *
03983        *  This is the constructor provided by the standard.
03984        *
03985        *  @param refs  Passed to the base facet class.
03986       */
03987       explicit
03988       money_get(size_t __refs = 0) : facet(__refs) { }
03989 
03990       /**
03991        *  @brief  Read and parse a monetary value.
03992        *
03993        *  This function reads characters from @a s, interprets them as a
03994        *  monetary value according to moneypunct and ctype facets retrieved
03995        *  from io.getloc(), and returns the result in @a units as an integral
03996        *  value moneypunct::frac_digits() * the actual amount.  For example,
03997        *  the string $10.01 in a US locale would store 1001 in @a units.
03998        *
03999        *  Any characters not part of a valid money amount are not consumed.
04000        *
04001        *  If a money value cannot be parsed from the input stream, sets
04002        *  err=(err|io.failbit).  If the stream is consumed before finishing
04003        *  parsing,  sets err=(err|io.failbit|io.eofbit).  @a units is
04004        *  unchanged if parsing fails.
04005        *
04006        *  This function works by returning the result of do_get().
04007        *
04008        *  @param  s  Start of characters to parse.
04009        *  @param  end  End of characters to parse.
04010        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04011        *  @param  io  Source of facets and io state.
04012        *  @param  err  Error field to set if parsing fails.
04013        *  @param  units  Place to store result of parsing.
04014        *  @return  Iterator referencing first character beyond valid money
04015        *       amount.
04016        */
04017       iter_type
04018       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04019       ios_base::iostate& __err, long double& __units) const
04020       { return this->do_get(__s, __end, __intl, __io, __err, __units); }
04021 
04022       /**
04023        *  @brief  Read and parse a monetary value.
04024        *
04025        *  This function reads characters from @a s, interprets them as a
04026        *  monetary value according to moneypunct and ctype facets retrieved
04027        *  from io.getloc(), and returns the result in @a digits.  For example,
04028        *  the string $10.01 in a US locale would store "1001" in @a digits.
04029        *
04030        *  Any characters not part of a valid money amount are not consumed.
04031        *
04032        *  If a money value cannot be parsed from the input stream, sets
04033        *  err=(err|io.failbit).  If the stream is consumed before finishing
04034        *  parsing,  sets err=(err|io.failbit|io.eofbit).
04035        *
04036        *  This function works by returning the result of do_get().
04037        *
04038        *  @param  s  Start of characters to parse.
04039        *  @param  end  End of characters to parse.
04040        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04041        *  @param  io  Source of facets and io state.
04042        *  @param  err  Error field to set if parsing fails.
04043        *  @param  digits  Place to store result of parsing.
04044        *  @return  Iterator referencing first character beyond valid money
04045        *       amount.
04046        */
04047       iter_type
04048       get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04049       ios_base::iostate& __err, string_type& __digits) const
04050       { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
04051 
04052     protected:
04053       /// Destructor.
04054       virtual
04055       ~money_get() { }
04056 
04057       /**
04058        *  @brief  Read and parse a monetary value.
04059        *
04060        *  This function reads and parses characters representing a monetary
04061        *  value.  This function is a hook for derived classes to change the
04062        *  value returned.  @see get() for details.
04063        */
04064       virtual iter_type
04065       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04066          ios_base::iostate& __err, long double& __units) const;
04067 
04068       /**
04069        *  @brief  Read and parse a monetary value.
04070        *
04071        *  This function reads and parses characters representing a monetary
04072        *  value.  This function is a hook for derived classes to change the
04073        *  value returned.  @see get() for details.
04074        */
04075       virtual iter_type
04076       do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
04077          ios_base::iostate& __err, string_type& __digits) const;
04078 
04079       template<bool _Intl>
04080         iter_type
04081         _M_extract(iter_type __s, iter_type __end, ios_base& __io,
04082            ios_base::iostate& __err, string& __digits) const;     
04083     };
04084 
04085   template<typename _CharT, typename _InIter>
04086     locale::id money_get<_CharT, _InIter>::id;
04087 
04088   /**
04089    *  @brief  Facet for outputting monetary amounts.
04090    *
04091    *  This facet encapsulates the code to format and output a monetary
04092    *  amount.
04093    *
04094    *  The money_put template uses protected virtual functions to
04095    *  provide the actual results.  The public accessors forward the
04096    *  call to the virtual functions.  These virtual functions are
04097    *  hooks for developers to implement the behavior they require from
04098    *  the money_put facet.
04099   */
04100   template<typename _CharT, typename _OutIter>
04101     class money_put : public locale::facet
04102     {
04103     public:
04104       //@{
04105       /// Public typedefs
04106       typedef _CharT            char_type;
04107       typedef _OutIter          iter_type;
04108       typedef basic_string<_CharT>  string_type;
04109       //@}
04110 
04111       /// Numpunct facet id.
04112       static locale::id         id;
04113 
04114       /**
04115        *  @brief  Constructor performs initialization.
04116        *
04117        *  This is the constructor provided by the standard.
04118        *
04119        *  @param refs  Passed to the base facet class.
04120       */
04121       explicit
04122       money_put(size_t __refs = 0) : facet(__refs) { }
04123 
04124       /**
04125        *  @brief  Format and output a monetary value.
04126        *
04127        *  This function formats @a units as a monetary value according to
04128        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04129        *  the resulting characters to @a s.  For example, the value 1001 in a
04130        *  US locale would write "$10.01" to @a s.
04131        *
04132        *  This function works by returning the result of do_put().
04133        *
04134        *  @param  s  The stream to write to.
04135        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04136        *  @param  io  Source of facets and io state.
04137        *  @param  fill  char_type to use for padding.
04138        *  @param  units  Place to store result of parsing.
04139        *  @return  Iterator after writing.
04140        */
04141       iter_type
04142       put(iter_type __s, bool __intl, ios_base& __io,
04143       char_type __fill, long double __units) const
04144       { return this->do_put(__s, __intl, __io, __fill, __units); }
04145 
04146       /**
04147        *  @brief  Format and output a monetary value.
04148        *
04149        *  This function formats @a digits as a monetary value according to
04150        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04151        *  the resulting characters to @a s.  For example, the string "1001" in
04152        *  a US locale would write "$10.01" to @a s.
04153        *
04154        *  This function works by returning the result of do_put().
04155        *
04156        *  @param  s  The stream to write to.
04157        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04158        *  @param  io  Source of facets and io state.
04159        *  @param  fill  char_type to use for padding.
04160        *  @param  units  Place to store result of parsing.
04161        *  @return  Iterator after writing.
04162        */
04163       iter_type
04164       put(iter_type __s, bool __intl, ios_base& __io,
04165       char_type __fill, const string_type& __digits) const
04166       { return this->do_put(__s, __intl, __io, __fill, __digits); }
04167 
04168     protected:
04169       /// Destructor.
04170       virtual
04171       ~money_put() { }
04172 
04173       /**
04174        *  @brief  Format and output a monetary value.
04175        *
04176        *  This function formats @a units as a monetary value according to
04177        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04178        *  the resulting characters to @a s.  For example, the value 1001 in a
04179        *  US locale would write "$10.01" to @a s.
04180        *
04181        *  This function is a hook for derived classes to change the value
04182        *  returned.  @see put().
04183        *
04184        *  @param  s  The stream to write to.
04185        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04186        *  @param  io  Source of facets and io state.
04187        *  @param  fill  char_type to use for padding.
04188        *  @param  units  Place to store result of parsing.
04189        *  @return  Iterator after writing.
04190        */
04191       virtual iter_type
04192       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
04193          long double __units) const;
04194 
04195       /**
04196        *  @brief  Format and output a monetary value.
04197        *
04198        *  This function formats @a digits as a monetary value according to
04199        *  moneypunct and ctype facets retrieved from io.getloc(), and writes
04200        *  the resulting characters to @a s.  For example, the string "1001" in
04201        *  a US locale would write "$10.01" to @a s.
04202        *
04203        *  This function is a hook for derived classes to change the value
04204        *  returned.  @see put().
04205        *
04206        *  @param  s  The stream to write to.
04207        *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
04208        *  @param  io  Source of facets and io state.
04209        *  @param  fill  char_type to use for padding.
04210        *  @param  units  Place to store result of parsing.
04211        *  @return  Iterator after writing.
04212        */
04213       virtual iter_type
04214       do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
04215          const string_type& __digits) const;
04216 
04217       template<bool _Intl>
04218         iter_type
04219         _M_insert(iter_type __s, ios_base& __io, char_type __fill,
04220           const string_type& __digits) const;
04221     };
04222 
04223   template<typename _CharT, typename _OutIter>
04224     locale::id money_put<_CharT, _OutIter>::id;
04225 
04226   /**
04227    *  @brief  Messages facet base class providing catalog typedef.
04228    */
04229   struct messages_base
04230   {
04231     typedef int catalog;
04232   };
04233 
04234   /**
04235    *  @brief  Facet for handling message catalogs
04236    *
04237    *  This facet encapsulates the code to retrieve messages from
04238    *  message catalogs.  The only thing defined by the standard for this facet
04239    *  is the interface.  All underlying functionality is
04240    *  implementation-defined.
04241    *
04242    *  This library currently implements 3 versions of the message facet.  The
04243    *  first version (gnu) is a wrapper around gettext, provided by libintl.
04244    *  The second version (ieee) is a wrapper around catgets.  The final
04245    *  version (default) does no actual translation.  These implementations are
04246    *  only provided for char and wchar_t instantiations.
04247    *
04248    *  The messages template uses protected virtual functions to
04249    *  provide the actual results.  The public accessors forward the
04250    *  call to the virtual functions.  These virtual functions are
04251    *  hooks for developers to implement the behavior they require from
04252    *  the messages facet.
04253   */
04254   template<typename _CharT>
04255     class messages : public locale::facet, public messages_base
04256     {
04257     public:
04258       // Types:
04259       //@{
04260       /// Public typedefs
04261       typedef _CharT            char_type;
04262       typedef basic_string<_CharT>  string_type;
04263       //@}
04264 
04265     protected:
04266       // Underlying "C" library locale information saved from
04267       // initialization, needed by messages_byname as well.
04268       __c_locale            _M_c_locale_messages;
04269       const char*           _M_name_messages;
04270 
04271     public:
04272       /// Numpunct facet id.
04273       static locale::id         id;
04274 
04275       /**
04276        *  @brief  Constructor performs initialization.
04277        *
04278        *  This is the constructor provided by the standard.
04279        *
04280        *  @param refs  Passed to the base facet class.
04281       */
04282       explicit
04283       messages(size_t __refs = 0);
04284 
04285       // Non-standard.
04286       /**
04287        *  @brief  Internal constructor.  Not for general use.
04288        *
04289        *  This is a constructor for use by the library itself to set up new
04290        *  locales.
04291        *
04292        *  @param  cloc  The "C" locale.
04293        *  @param  s  The name of a locale.
04294        *  @param  refs  Refcount to pass to the base class.
04295        */
04296       explicit
04297       messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
04298 
04299       /*
04300        *  @brief  Open a message catalog.
04301        *
04302        *  This function opens and returns a handle to a message catalog by
04303        *  returning do_open(s, loc).
04304        *
04305        *  @param  s  The catalog to open.
04306        *  @param  loc  Locale to use for character set conversions.
04307        *  @return  Handle to the catalog or value < 0 if open fails.
04308       */
04309       catalog
04310       open(const basic_string<char>& __s, const locale& __loc) const
04311       { return this->do_open(__s, __loc); }
04312 
04313       // Non-standard and unorthodox, yet effective.
04314       /*
04315        *  @brief  Open a message catalog.
04316        *
04317        *  This non-standard function opens and returns a handle to a message
04318        *  catalog by returning do_open(s, loc).  The third argument provides a
04319        *  message catalog root directory for gnu gettext and is ignored
04320        *  otherwise.
04321        *
04322        *  @param  s  The catalog to open.
04323        *  @param  loc  Locale to use for character set conversions.
04324        *  @param  dir  Message catalog root directory.
04325        *  @return  Handle to the catalog or value < 0 if open fails.
04326       */
04327       catalog
04328       open(const basic_string<char>&, const locale&, const char*) const;
04329 
04330       /*
04331        *  @brief  Look up a string in a message catalog.
04332        *
04333        *  This function retrieves and returns a message from a catalog by
04334        *  returning do_get(c, set, msgid, s).
04335        *
04336        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
04337        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
04338        *
04339        *  @param  c  The catalog to access.
04340        *  @param  set  Implementation-defined.
04341        *  @param  msgid  Implementation-defined.
04342        *  @param  s  Default return value if retrieval fails.
04343        *  @return  Retrieved message or @a s if get fails.
04344       */
04345       string_type
04346       get(catalog __c, int __set, int __msgid, const string_type& __s) const
04347       { return this->do_get(__c, __set, __msgid, __s); }
04348 
04349       /*
04350        *  @brief  Close a message catalog.
04351        *
04352        *  Closes catalog @a c by calling do_close(c).
04353        *
04354        *  @param  c  The catalog to close.
04355       */
04356       void
04357       close(catalog __c) const
04358       { return this->do_close(__c); }
04359 
04360     protected:
04361       /// Destructor.
04362       virtual
04363       ~messages();
04364 
04365       /*
04366        *  @brief  Open a message catalog.
04367        *
04368        *  This function opens and returns a handle to a message catalog in an
04369        *  implementation-defined manner.  This function is a hook for derived
04370        *  classes to change the value returned.
04371        *
04372        *  @param  s  The catalog to open.
04373        *  @param  loc  Locale to use for character set conversions.
04374        *  @return  Handle to the opened catalog, value < 0 if open failed.
04375       */
04376       virtual catalog
04377       do_open(const basic_string<char>&, const locale&) const;
04378 
04379       /*
04380        *  @brief  Look up a string in a message catalog.
04381        *
04382        *  This function retrieves and returns a message from a catalog in an
04383        *  implementation-defined manner.  This function is a hook for derived
04384        *  classes to change the value returned.
04385        *
04386        *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
04387        *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
04388        *
04389        *  @param  c  The catalog to access.
04390        *  @param  set  Implementation-defined.
04391        *  @param  msgid  Implementation-defined.
04392        *  @param  s  Default return value if retrieval fails.
04393        *  @return  Retrieved message or @a s if get fails.
04394       */
04395       virtual string_type
04396       do_get(catalog, int, int, const string_type& __dfault) const;
04397 
04398       /*
04399        *  @brief  Close a message catalog.
04400        *
04401        *  @param  c  The catalog to close.
04402       */
04403       virtual void
04404       do_close(catalog) const;
04405 
04406       // Returns a locale and codeset-converted string, given a char* message.
04407       char*
04408       _M_convert_to_char(const string_type& __msg) const
04409       {
04410     // XXX
04411     return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
04412       }
04413 
04414       // Returns a locale and codeset-converted string, given a char* message.
04415       string_type
04416       _M_convert_from_char(char*) const
04417       {
04418 #if 0
04419     // Length of message string without terminating null.
04420     size_t __len = char_traits<char>::length(__msg) - 1;
04421 
04422     // "everybody can easily convert the string using
04423     // mbsrtowcs/wcsrtombs or with iconv()"
04424 
04425     // Convert char* to _CharT in locale used to open catalog.
04426     // XXX need additional template parameter on messages class for this..
04427     // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
04428     typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
04429 
04430     __codecvt_type::state_type __state;
04431     // XXX may need to initialize state.
04432     //initialize_state(__state._M_init());
04433 
04434     char* __from_next;
04435     // XXX what size for this string?
04436     _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
04437     const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
04438     __cvt.out(__state, __msg, __msg + __len, __from_next,
04439           __to, __to + __len + 1, __to_next);
04440     return string_type(__to);
04441 #endif
04442 #if 0
04443     typedef ctype<_CharT> __ctype_type;
04444     // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
04445     const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
04446     // XXX Again, proper length of converted string an issue here.
04447     // For now, assume the converted length is not larger.
04448     _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
04449     __cvt.widen(__msg, __msg + __len, __dest);
04450     return basic_string<_CharT>(__dest);
04451 #endif
04452     return string_type();
04453       }
04454      };
04455 
04456   template<typename _CharT>
04457     locale::id messages<_CharT>::id;
04458 
04459   // Specializations for required instantiations.
04460   template<>
04461     string
04462     messages<char>::do_get(catalog, int, int, const string&) const;
04463 
04464 #ifdef _GLIBCXX_USE_WCHAR_T
04465   template<>
04466     wstring
04467     messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
04468 #endif
04469 
04470   template<typename _CharT>
04471     class messages_byname : public messages<_CharT>
04472     {
04473     public:
04474       typedef _CharT            char_type;
04475       typedef basic_string<_CharT>  string_type;
04476 
04477       explicit
04478       messages_byname(const char* __s, size_t __refs = 0);
04479 
04480     protected:
04481       virtual
04482       ~messages_byname()
04483       { }
04484     };
04485 
04486   // Include host and configuration specific messages functions.
04487   #include <bits/messages_members.h>
04488 
04489 
04490   // Subclause convenience interfaces, inlines.
04491   // NB: These are inline because, when used in a loop, some compilers
04492   // can hoist the body out of the loop; then it's just as fast as the
04493   // C is*() function.
04494   //@{
04495   /// Convenience interface to ctype.is().
04496   template<typename _CharT>
04497     inline bool
04498     isspace(_CharT __c, const locale& __loc)
04499     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
04500 
04501   template<typename _CharT>
04502     inline bool
04503     isprint(_CharT __c, const locale& __loc)
04504     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
04505 
04506   template<typename _CharT>
04507     inline bool
04508     iscntrl(_CharT __c, const locale& __loc)
04509     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
04510 
04511   template<typename _CharT>
04512     inline bool
04513     isupper(_CharT __c, const locale& __loc)
04514     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
04515 
04516   template<typename _CharT>
04517     inline bool islower(_CharT __c, const locale& __loc)
04518     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
04519 
04520   template<typename _CharT>
04521     inline bool
04522     isalpha(_CharT __c, const locale& __loc)
04523     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
04524 
04525   template<typename _CharT>
04526     inline bool
04527     isdigit(_CharT __c, const locale& __loc)
04528     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
04529 
04530   template<typename _CharT>
04531     inline bool
04532     ispunct(_CharT __c, const locale& __loc)
04533     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
04534 
04535   template<typename _CharT>
04536     inline bool
04537     isxdigit(_CharT __c, const locale& __loc)
04538     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
04539 
04540   template<typename _CharT>
04541     inline bool
04542     isalnum(_CharT __c, const locale& __loc)
04543     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
04544 
04545   template<typename _CharT>
04546     inline bool
04547     isgraph(_CharT __c, const locale& __loc)
04548     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
04549 
04550   template<typename _CharT>
04551     inline _CharT
04552     toupper(_CharT __c, const locale& __loc)
04553     { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
04554 
04555   template<typename _CharT>
04556     inline _CharT
04557     tolower(_CharT __c, const locale& __loc)
04558     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
04559   //@}
04560 } // namespace std
04561 
04562 #endif

Generated on Mon Mar 6 17:32:00 2006 for libstdc++-v3 Source by  doxygen 1.4.0