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

Generated on Thu Nov 1 13:12:03 2007 for libstdc++ by  doxygen 1.5.1