locale_facets.h

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

Generated on Fri May 6 01:09:01 2005 for libstdc++-v3 Source by  doxygen 1.4.2