197403Sobrien// Locale support -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
497403Sobrien// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien/** @file locale_facets.h
3297403Sobrien *  This is an internal header file, included by other library headers.
3397403Sobrien *  You should not attempt to use it directly.
3497403Sobrien */
3597403Sobrien
36169691Skan//
37169691Skan// ISO C++ 14882: 22.1  Locales
38169691Skan//
39169691Skan
40132720Skan#ifndef _LOCALE_FACETS_H
41132720Skan#define _LOCALE_FACETS_H 1
4297403Sobrien
4397403Sobrien#pragma GCC system_header
4497403Sobrien
4597403Sobrien#include <ctime>	// For struct tm
4697403Sobrien#include <cwctype>	// For wctype_t
47169691Skan#include <bits/ctype_base.h>
48117397Skan#include <iosfwd>
49117397Skan#include <bits/ios_base.h>  // For ios_base, ios_base::iostate
50117397Skan#include <streambuf>
51169691Skan#include <bits/cpp_type_traits.h>
5297403Sobrien
53169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
54169691Skan
5597403Sobrien  // NB: Don't instantiate required wchar_t facets if no wchar_t support.
56132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
57132720Skan# define  _GLIBCXX_NUM_FACETS 28
5897403Sobrien#else
59132720Skan# define  _GLIBCXX_NUM_FACETS 14
6097403Sobrien#endif
6197403Sobrien
62132720Skan  // Convert string to numeric value of type _Tv and store results.
63117397Skan  // NB: This is specialized for all required types, there is no
64117397Skan  // generic definition.
65117397Skan  template<typename _Tv>
66117397Skan    void
67132720Skan    __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
68132720Skan		   const __c_locale& __cloc);
69117397Skan
70117397Skan  // Explicit specializations for required types.
71117397Skan  template<>
72117397Skan    void
73132720Skan    __convert_to_v(const char*, float&, ios_base::iostate&,
74132720Skan		   const __c_locale&);
75117397Skan
76117397Skan  template<>
77117397Skan    void
78132720Skan    __convert_to_v(const char*, double&, ios_base::iostate&,
79132720Skan		   const __c_locale&);
80117397Skan
81117397Skan  template<>
82117397Skan    void
83132720Skan    __convert_to_v(const char*, long double&, ios_base::iostate&,
84132720Skan		   const __c_locale&);
85117397Skan
86117397Skan  // NB: __pad is a struct, rather than a function, so it can be
87117397Skan  // partially-specialized.
88102782Skan  template<typename _CharT, typename _Traits>
89117397Skan    struct __pad
90117397Skan    {
91117397Skan      static void
92132720Skan      _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
93132720Skan	     const _CharT* __olds, const streamsize __newlen,
94117397Skan	     const streamsize __oldlen, const bool __num);
95117397Skan    };
96102782Skan
97117397Skan  // Used by both numeric and monetary facets.
98117397Skan  // Inserts "group separator" characters into an array of characters.
99117397Skan  // It's recursive, one iteration per group.  It moves the characters
100117397Skan  // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
101132720Skan  // only with __glen != 0.
102117397Skan  template<typename _CharT>
103117397Skan    _CharT*
104132720Skan    __add_grouping(_CharT* __s, _CharT __sep,
105132720Skan		   const char* __gbeg, size_t __gsize,
106117397Skan		   const _CharT* __first, const _CharT* __last);
107117397Skan
108117397Skan  // This template permits specializing facet output code for
109117397Skan  // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
110117397Skan  // significantly more efficient than incrementing iterators.
111117397Skan  template<typename _CharT>
112117397Skan    inline
113117397Skan    ostreambuf_iterator<_CharT>
114117397Skan    __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
115117397Skan    {
116117397Skan      __s._M_put(__ws, __len);
117117397Skan      return __s;
118117397Skan    }
119117397Skan
120117397Skan  // This is the unspecialized form of the template.
121117397Skan  template<typename _CharT, typename _OutIter>
122117397Skan    inline
123117397Skan    _OutIter
124117397Skan    __write(_OutIter __s, const _CharT* __ws, int __len)
125117397Skan    {
126117397Skan      for (int __j = 0; __j < __len; __j++, ++__s)
127117397Skan	*__s = __ws[__j];
128117397Skan      return __s;
129117397Skan    }
130117397Skan
131132720Skan
13297403Sobrien  // 22.2.1.1  Template class ctype
13397403Sobrien  // Include host and configuration specific ctype enums for ctype_base.
13497403Sobrien
135132720Skan  // Common base for ctype<_CharT>.
136132720Skan  /**
137132720Skan   *  @brief  Common base for ctype facet
138132720Skan   *
139132720Skan   *  This template class provides implementations of the public functions
140132720Skan   *  that forward to the protected virtual functions.
141132720Skan   *
142132720Skan   *  This template also provides abtract stubs for the protected virtual
143132720Skan   *  functions.
144132720Skan  */
14597403Sobrien  template<typename _CharT>
14697403Sobrien    class __ctype_abstract_base : public locale::facet, public ctype_base
14797403Sobrien    {
14897403Sobrien    public:
14997403Sobrien      // Types:
150132720Skan      /// Typedef for the template parameter
15197403Sobrien      typedef _CharT char_type;
15297403Sobrien
153132720Skan      /**
154132720Skan       *  @brief  Test char_type classification.
155132720Skan       *
156132720Skan       *  This function finds a mask M for @a c and compares it to mask @a m.
157132720Skan       *  It does so by returning the value of ctype<char_type>::do_is().
158132720Skan       *
159132720Skan       *  @param c  The char_type to compare the mask of.
160132720Skan       *  @param m  The mask to compare against.
161132720Skan       *  @return  (M & m) != 0.
162132720Skan      */
163132720Skan      bool
16497403Sobrien      is(mask __m, char_type __c) const
16597403Sobrien      { return this->do_is(__m, __c); }
16697403Sobrien
167132720Skan      /**
168132720Skan       *  @brief  Return a mask array.
169132720Skan       *
170132720Skan       *  This function finds the mask for each char_type in the range [lo,hi)
171132720Skan       *  and successively writes it to vec.  vec must have as many elements
172132720Skan       *  as the char array.  It does so by returning the value of
173132720Skan       *  ctype<char_type>::do_is().
174132720Skan       *
175132720Skan       *  @param lo  Pointer to start of range.
176132720Skan       *  @param hi  Pointer to end of range.
177132720Skan       *  @param vec  Pointer to an array of mask storage.
178132720Skan       *  @return  @a hi.
179132720Skan      */
18097403Sobrien      const char_type*
181132720Skan      is(const char_type *__lo, const char_type *__hi, mask *__vec) const
18297403Sobrien      { return this->do_is(__lo, __hi, __vec); }
18397403Sobrien
184132720Skan      /**
185132720Skan       *  @brief  Find char_type matching a mask
186132720Skan       *
187132720Skan       *  This function searches for and returns the first char_type c in
188132720Skan       *  [lo,hi) for which is(m,c) is true.  It does so by returning
189132720Skan       *  ctype<char_type>::do_scan_is().
190132720Skan       *
191132720Skan       *  @param m  The mask to compare against.
192132720Skan       *  @param lo  Pointer to start of range.
193132720Skan       *  @param hi  Pointer to end of range.
194132720Skan       *  @return  Pointer to matching char_type if found, else @a hi.
195132720Skan      */
19697403Sobrien      const char_type*
19797403Sobrien      scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
19897403Sobrien      { return this->do_scan_is(__m, __lo, __hi); }
19997403Sobrien
200132720Skan      /**
201132720Skan       *  @brief  Find char_type not matching a mask
202132720Skan       *
203132720Skan       *  This function searches for and returns the first char_type c in
204132720Skan       *  [lo,hi) for which is(m,c) is false.  It does so by returning
205132720Skan       *  ctype<char_type>::do_scan_not().
206132720Skan       *
207132720Skan       *  @param m  The mask to compare against.
208132720Skan       *  @param lo  Pointer to first char in range.
209132720Skan       *  @param hi  Pointer to end of range.
210132720Skan       *  @return  Pointer to non-matching char if found, else @a hi.
211132720Skan      */
21297403Sobrien      const char_type*
21397403Sobrien      scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
21497403Sobrien      { return this->do_scan_not(__m, __lo, __hi); }
21597403Sobrien
216132720Skan      /**
217132720Skan       *  @brief  Convert to uppercase.
218132720Skan       *
219132720Skan       *  This function converts the argument to uppercase if possible.
220132720Skan       *  If not possible (for example, '2'), returns the argument.  It does
221132720Skan       *  so by returning ctype<char_type>::do_toupper().
222132720Skan       *
223132720Skan       *  @param c  The char_type to convert.
224132720Skan       *  @return  The uppercase char_type if convertible, else @a c.
225132720Skan      */
226132720Skan      char_type
22797403Sobrien      toupper(char_type __c) const
22897403Sobrien      { return this->do_toupper(__c); }
22997403Sobrien
230132720Skan      /**
231132720Skan       *  @brief  Convert array to uppercase.
232132720Skan       *
233132720Skan       *  This function converts each char_type in the range [lo,hi) to
234132720Skan       *  uppercase if possible.  Other elements remain untouched.  It does so
235132720Skan       *  by returning ctype<char_type>:: do_toupper(lo, hi).
236132720Skan       *
237132720Skan       *  @param lo  Pointer to start of range.
238132720Skan       *  @param hi  Pointer to end of range.
239132720Skan       *  @return  @a hi.
240132720Skan      */
24197403Sobrien      const char_type*
24297403Sobrien      toupper(char_type *__lo, const char_type* __hi) const
24397403Sobrien      { return this->do_toupper(__lo, __hi); }
24497403Sobrien
245132720Skan      /**
246132720Skan       *  @brief  Convert to lowercase.
247132720Skan       *
248132720Skan       *  This function converts the argument to lowercase if possible.  If
249132720Skan       *  not possible (for example, '2'), returns the argument.  It does so
250132720Skan       *  by returning ctype<char_type>::do_tolower(c).
251132720Skan       *
252132720Skan       *  @param c  The char_type to convert.
253132720Skan       *  @return  The lowercase char_type if convertible, else @a c.
254132720Skan      */
255132720Skan      char_type
25697403Sobrien      tolower(char_type __c) const
25797403Sobrien      { return this->do_tolower(__c); }
25897403Sobrien
259132720Skan      /**
260132720Skan       *  @brief  Convert array to lowercase.
261132720Skan       *
262132720Skan       *  This function converts each char_type in the range [lo,hi) to
263132720Skan       *  lowercase if possible.  Other elements remain untouched.  It does so
264132720Skan       *  by returning ctype<char_type>:: do_tolower(lo, hi).
265132720Skan       *
266132720Skan       *  @param lo  Pointer to start of range.
267132720Skan       *  @param hi  Pointer to end of range.
268132720Skan       *  @return  @a hi.
269132720Skan      */
27097403Sobrien      const char_type*
27197403Sobrien      tolower(char_type* __lo, const char_type* __hi) const
27297403Sobrien      { return this->do_tolower(__lo, __hi); }
27397403Sobrien
274132720Skan      /**
275132720Skan       *  @brief  Widen char to char_type
276132720Skan       *
277132720Skan       *  This function converts the char argument to char_type using the
278132720Skan       *  simplest reasonable transformation.  It does so by returning
279132720Skan       *  ctype<char_type>::do_widen(c).
280132720Skan       *
281132720Skan       *  Note: this is not what you want for codepage conversions.  See
282132720Skan       *  codecvt for that.
283132720Skan       *
284132720Skan       *  @param c  The char to convert.
285132720Skan       *  @return  The converted char_type.
286132720Skan      */
287132720Skan      char_type
28897403Sobrien      widen(char __c) const
28997403Sobrien      { return this->do_widen(__c); }
29097403Sobrien
291132720Skan      /**
292132720Skan       *  @brief  Widen array to char_type
293132720Skan       *
294132720Skan       *  This function converts each char in the input to char_type using the
295132720Skan       *  simplest reasonable transformation.  It does so by returning
296132720Skan       *  ctype<char_type>::do_widen(c).
297132720Skan       *
298132720Skan       *  Note: this is not what you want for codepage conversions.  See
299132720Skan       *  codecvt for that.
300132720Skan       *
301132720Skan       *  @param lo  Pointer to start of range.
302132720Skan       *  @param hi  Pointer to end of range.
303132720Skan       *  @param to  Pointer to the destination array.
304132720Skan       *  @return  @a hi.
305132720Skan      */
30697403Sobrien      const char*
30797403Sobrien      widen(const char* __lo, const char* __hi, char_type* __to) const
30897403Sobrien      { return this->do_widen(__lo, __hi, __to); }
30997403Sobrien
310132720Skan      /**
311132720Skan       *  @brief  Narrow char_type to char
312132720Skan       *
313132720Skan       *  This function converts the char_type to char using the simplest
314132720Skan       *  reasonable transformation.  If the conversion fails, dfault is
315132720Skan       *  returned instead.  It does so by returning
316132720Skan       *  ctype<char_type>::do_narrow(c).
317132720Skan       *
318132720Skan       *  Note: this is not what you want for codepage conversions.  See
319132720Skan       *  codecvt for that.
320132720Skan       *
321132720Skan       *  @param c  The char_type to convert.
322132720Skan       *  @param dfault  Char to return if conversion fails.
323132720Skan       *  @return  The converted char.
324132720Skan      */
325132720Skan      char
32697403Sobrien      narrow(char_type __c, char __dfault) const
32797403Sobrien      { return this->do_narrow(__c, __dfault); }
32897403Sobrien
329132720Skan      /**
330132720Skan       *  @brief  Narrow array to char array
331132720Skan       *
332132720Skan       *  This function converts each char_type in the input to char using the
333132720Skan       *  simplest reasonable transformation and writes the results to the
334132720Skan       *  destination array.  For any char_type in the input that cannot be
335132720Skan       *  converted, @a dfault is used instead.  It does so by returning
336132720Skan       *  ctype<char_type>::do_narrow(lo, hi, dfault, to).
337132720Skan       *
338132720Skan       *  Note: this is not what you want for codepage conversions.  See
339132720Skan       *  codecvt for that.
340132720Skan       *
341132720Skan       *  @param lo  Pointer to start of range.
342132720Skan       *  @param hi  Pointer to end of range.
343132720Skan       *  @param dfault  Char to use if conversion fails.
344132720Skan       *  @param to  Pointer to the destination array.
345132720Skan       *  @return  @a hi.
346132720Skan      */
34797403Sobrien      const char_type*
34897403Sobrien      narrow(const char_type* __lo, const char_type* __hi,
34997403Sobrien	      char __dfault, char *__to) const
35097403Sobrien      { return this->do_narrow(__lo, __hi, __dfault, __to); }
35197403Sobrien
35297403Sobrien    protected:
353132720Skan      explicit
354132720Skan      __ctype_abstract_base(size_t __refs = 0): facet(__refs) { }
35597403Sobrien
356132720Skan      virtual
35797403Sobrien      ~__ctype_abstract_base() { }
358132720Skan
359132720Skan      /**
360132720Skan       *  @brief  Test char_type classification.
361132720Skan       *
362132720Skan       *  This function finds a mask M for @a c and compares it to mask @a m.
363132720Skan       *
364132720Skan       *  do_is() is a hook for a derived facet to change the behavior of
365132720Skan       *  classifying.  do_is() must always return the same result for the
366132720Skan       *  same input.
367132720Skan       *
368132720Skan       *  @param c  The char_type to find the mask of.
369132720Skan       *  @param m  The mask to compare against.
370132720Skan       *  @return  (M & m) != 0.
371132720Skan      */
372132720Skan      virtual bool
37397403Sobrien      do_is(mask __m, char_type __c) const = 0;
37497403Sobrien
375132720Skan      /**
376132720Skan       *  @brief  Return a mask array.
377132720Skan       *
378132720Skan       *  This function finds the mask for each char_type in the range [lo,hi)
379132720Skan       *  and successively writes it to vec.  vec must have as many elements
380132720Skan       *  as the input.
381132720Skan       *
382132720Skan       *  do_is() is a hook for a derived facet to change the behavior of
383132720Skan       *  classifying.  do_is() must always return the same result for the
384132720Skan       *  same input.
385132720Skan       *
386132720Skan       *  @param lo  Pointer to start of range.
387132720Skan       *  @param hi  Pointer to end of range.
388132720Skan       *  @param vec  Pointer to an array of mask storage.
389132720Skan       *  @return  @a hi.
390132720Skan      */
39197403Sobrien      virtual const char_type*
392132720Skan      do_is(const char_type* __lo, const char_type* __hi,
39397403Sobrien	    mask* __vec) const = 0;
39497403Sobrien
395132720Skan      /**
396132720Skan       *  @brief  Find char_type matching mask
397132720Skan       *
398132720Skan       *  This function searches for and returns the first char_type c in
399132720Skan       *  [lo,hi) for which is(m,c) is true.
400132720Skan       *
401132720Skan       *  do_scan_is() is a hook for a derived facet to change the behavior of
402132720Skan       *  match searching.  do_is() must always return the same result for the
403132720Skan       *  same input.
404132720Skan       *
405132720Skan       *  @param m  The mask to compare against.
406132720Skan       *  @param lo  Pointer to start of range.
407132720Skan       *  @param hi  Pointer to end of range.
408132720Skan       *  @return  Pointer to a matching char_type if found, else @a hi.
409132720Skan      */
41097403Sobrien      virtual const char_type*
41197403Sobrien      do_scan_is(mask __m, const char_type* __lo,
41297403Sobrien		 const char_type* __hi) const = 0;
41397403Sobrien
414132720Skan      /**
415132720Skan       *  @brief  Find char_type not matching mask
416132720Skan       *
417132720Skan       *  This function searches for and returns a pointer to the first
418132720Skan       *  char_type c of [lo,hi) for which is(m,c) is false.
419132720Skan       *
420132720Skan       *  do_scan_is() is a hook for a derived facet to change the behavior of
421132720Skan       *  match searching.  do_is() must always return the same result for the
422132720Skan       *  same input.
423132720Skan       *
424132720Skan       *  @param m  The mask to compare against.
425132720Skan       *  @param lo  Pointer to start of range.
426132720Skan       *  @param hi  Pointer to end of range.
427132720Skan       *  @return  Pointer to a non-matching char_type if found, else @a hi.
428132720Skan      */
42997403Sobrien      virtual const char_type*
430132720Skan      do_scan_not(mask __m, const char_type* __lo,
43197403Sobrien		  const char_type* __hi) const = 0;
43297403Sobrien
433132720Skan      /**
434132720Skan       *  @brief  Convert to uppercase.
435132720Skan       *
436132720Skan       *  This virtual function converts the char_type argument to uppercase
437132720Skan       *  if possible.  If not possible (for example, '2'), returns the
438132720Skan       *  argument.
439132720Skan       *
440132720Skan       *  do_toupper() is a hook for a derived facet to change the behavior of
441132720Skan       *  uppercasing.  do_toupper() must always return the same result for
442132720Skan       *  the same input.
443132720Skan       *
444132720Skan       *  @param c  The char_type to convert.
445132720Skan       *  @return  The uppercase char_type if convertible, else @a c.
446132720Skan      */
447132720Skan      virtual char_type
44897403Sobrien      do_toupper(char_type) const = 0;
44997403Sobrien
450132720Skan      /**
451132720Skan       *  @brief  Convert array to uppercase.
452132720Skan       *
453132720Skan       *  This virtual function converts each char_type in the range [lo,hi)
454132720Skan       *  to uppercase if possible.  Other elements remain untouched.
455132720Skan       *
456132720Skan       *  do_toupper() is a hook for a derived facet to change the behavior of
457132720Skan       *  uppercasing.  do_toupper() must always return the same result for
458132720Skan       *  the same input.
459132720Skan       *
460132720Skan       *  @param lo  Pointer to start of range.
461132720Skan       *  @param hi  Pointer to end of range.
462132720Skan       *  @return  @a hi.
463132720Skan      */
46497403Sobrien      virtual const char_type*
46597403Sobrien      do_toupper(char_type* __lo, const char_type* __hi) const = 0;
46697403Sobrien
467132720Skan      /**
468132720Skan       *  @brief  Convert to lowercase.
469132720Skan       *
470132720Skan       *  This virtual function converts the argument to lowercase if
471132720Skan       *  possible.  If not possible (for example, '2'), returns the argument.
472132720Skan       *
473132720Skan       *  do_tolower() is a hook for a derived facet to change the behavior of
474132720Skan       *  lowercasing.  do_tolower() must always return the same result for
475132720Skan       *  the same input.
476132720Skan       *
477132720Skan       *  @param c  The char_type to convert.
478132720Skan       *  @return  The lowercase char_type if convertible, else @a c.
479132720Skan      */
480132720Skan      virtual char_type
48197403Sobrien      do_tolower(char_type) const = 0;
48297403Sobrien
483132720Skan      /**
484132720Skan       *  @brief  Convert array to lowercase.
485132720Skan       *
486132720Skan       *  This virtual function converts each char_type in the range [lo,hi)
487132720Skan       *  to lowercase if possible.  Other elements remain untouched.
488132720Skan       *
489132720Skan       *  do_tolower() is a hook for a derived facet to change the behavior of
490132720Skan       *  lowercasing.  do_tolower() must always return the same result for
491132720Skan       *  the same input.
492132720Skan       *
493132720Skan       *  @param lo  Pointer to start of range.
494132720Skan       *  @param hi  Pointer to end of range.
495132720Skan       *  @return  @a hi.
496132720Skan      */
49797403Sobrien      virtual const char_type*
49897403Sobrien      do_tolower(char_type* __lo, const char_type* __hi) const = 0;
499132720Skan
500132720Skan      /**
501132720Skan       *  @brief  Widen char
502132720Skan       *
503132720Skan       *  This virtual function converts the char to char_type using the
504132720Skan       *  simplest reasonable transformation.
505132720Skan       *
506132720Skan       *  do_widen() is a hook for a derived facet to change the behavior of
507132720Skan       *  widening.  do_widen() must always return the same result for the
508132720Skan       *  same input.
509132720Skan       *
510132720Skan       *  Note: this is not what you want for codepage conversions.  See
511132720Skan       *  codecvt for that.
512132720Skan       *
513132720Skan       *  @param c  The char to convert.
514132720Skan       *  @return  The converted char_type
515132720Skan      */
516132720Skan      virtual char_type
51797403Sobrien      do_widen(char) const = 0;
51897403Sobrien
519132720Skan      /**
520132720Skan       *  @brief  Widen char array
521132720Skan       *
522132720Skan       *  This function converts each char in the input to char_type using the
523132720Skan       *  simplest reasonable transformation.
524132720Skan       *
525132720Skan       *  do_widen() is a hook for a derived facet to change the behavior of
526132720Skan       *  widening.  do_widen() must always return the same result for the
527132720Skan       *  same input.
528132720Skan       *
529132720Skan       *  Note: this is not what you want for codepage conversions.  See
530132720Skan       *  codecvt for that.
531132720Skan       *
532132720Skan       *  @param lo  Pointer to start range.
533132720Skan       *  @param hi  Pointer to end of range.
534132720Skan       *  @param to  Pointer to the destination array.
535132720Skan       *  @return  @a hi.
536132720Skan      */
53797403Sobrien      virtual const char*
538132720Skan      do_widen(const char* __lo, const char* __hi,
53997403Sobrien	       char_type* __dest) const = 0;
54097403Sobrien
541132720Skan      /**
542132720Skan       *  @brief  Narrow char_type to char
543132720Skan       *
544132720Skan       *  This virtual function converts the argument to char using the
545132720Skan       *  simplest reasonable transformation.  If the conversion fails, dfault
546132720Skan       *  is returned instead.
547132720Skan       *
548132720Skan       *  do_narrow() is a hook for a derived facet to change the behavior of
549132720Skan       *  narrowing.  do_narrow() must always return the same result for the
550132720Skan       *  same input.
551132720Skan       *
552132720Skan       *  Note: this is not what you want for codepage conversions.  See
553132720Skan       *  codecvt for that.
554132720Skan       *
555132720Skan       *  @param c  The char_type to convert.
556132720Skan       *  @param dfault  Char to return if conversion fails.
557132720Skan       *  @return  The converted char.
558132720Skan      */
559132720Skan      virtual char
56097403Sobrien      do_narrow(char_type, char __dfault) const = 0;
56197403Sobrien
562132720Skan      /**
563132720Skan       *  @brief  Narrow char_type array to char
564132720Skan       *
565132720Skan       *  This virtual function converts each char_type in the range [lo,hi) to
566132720Skan       *  char using the simplest reasonable transformation and writes the
567132720Skan       *  results to the destination array.  For any element in the input that
568132720Skan       *  cannot be converted, @a dfault is used instead.
569132720Skan       *
570132720Skan       *  do_narrow() is a hook for a derived facet to change the behavior of
571132720Skan       *  narrowing.  do_narrow() must always return the same result for the
572132720Skan       *  same input.
573132720Skan       *
574132720Skan       *  Note: this is not what you want for codepage conversions.  See
575132720Skan       *  codecvt for that.
576132720Skan       *
577132720Skan       *  @param lo  Pointer to start of range.
578132720Skan       *  @param hi  Pointer to end of range.
579132720Skan       *  @param dfault  Char to use if conversion fails.
580132720Skan       *  @param to  Pointer to the destination array.
581132720Skan       *  @return  @a hi.
582132720Skan      */
58397403Sobrien      virtual const char_type*
58497403Sobrien      do_narrow(const char_type* __lo, const char_type* __hi,
585132720Skan		char __dfault, char* __dest) const = 0;
58697403Sobrien    };
58797403Sobrien
58897403Sobrien  // NB: Generic, mostly useless implementation.
589132720Skan  /**
590132720Skan   *  @brief  Template ctype facet
591132720Skan   *
592132720Skan   *  This template class defines classification and conversion functions for
593132720Skan   *  character sets.  It wraps <cctype> functionality.  Ctype gets used by
594132720Skan   *  streams for many I/O operations.
595132720Skan   *
596132720Skan   *  This template provides the protected virtual functions the developer
597132720Skan   *  will have to replace in a derived class or specialization to make a
598132720Skan   *  working facet.  The public functions that access them are defined in
599132720Skan   *  __ctype_abstract_base, to allow for implementation flexibility.  See
600132720Skan   *  ctype<wchar_t> for an example.  The functions are documented in
601132720Skan   *  __ctype_abstract_base.
602132720Skan   *
603132720Skan   *  Note: implementations are provided for all the protected virtual
604132720Skan   *  functions, but will likely not be useful.
605132720Skan  */
60697403Sobrien  template<typename _CharT>
60797403Sobrien    class ctype : public __ctype_abstract_base<_CharT>
60897403Sobrien    {
60997403Sobrien    public:
61097403Sobrien      // Types:
611132720Skan      typedef _CharT			char_type;
612132720Skan      typedef typename __ctype_abstract_base<_CharT>::mask mask;
61397403Sobrien
614132720Skan      /// The facet id for ctype<char_type>
615132720Skan      static locale::id			id;
61697403Sobrien
617132720Skan      explicit
61897403Sobrien      ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
61997403Sobrien
62097403Sobrien   protected:
621132720Skan      virtual
62297403Sobrien      ~ctype();
62397403Sobrien
624132720Skan      virtual bool
62597403Sobrien      do_is(mask __m, char_type __c) const;
62697403Sobrien
62797403Sobrien      virtual const char_type*
62897403Sobrien      do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
62997403Sobrien
63097403Sobrien      virtual const char_type*
63197403Sobrien      do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
63297403Sobrien
63397403Sobrien      virtual const char_type*
63497403Sobrien      do_scan_not(mask __m, const char_type* __lo,
63597403Sobrien		  const char_type* __hi) const;
63697403Sobrien
637132720Skan      virtual char_type
63897403Sobrien      do_toupper(char_type __c) const;
63997403Sobrien
64097403Sobrien      virtual const char_type*
64197403Sobrien      do_toupper(char_type* __lo, const char_type* __hi) const;
64297403Sobrien
643132720Skan      virtual char_type
64497403Sobrien      do_tolower(char_type __c) const;
64597403Sobrien
64697403Sobrien      virtual const char_type*
64797403Sobrien      do_tolower(char_type* __lo, const char_type* __hi) const;
64897403Sobrien
649132720Skan      virtual char_type
65097403Sobrien      do_widen(char __c) const;
65197403Sobrien
65297403Sobrien      virtual const char*
65397403Sobrien      do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
65497403Sobrien
655132720Skan      virtual char
65697403Sobrien      do_narrow(char_type, char __dfault) const;
65797403Sobrien
65897403Sobrien      virtual const char_type*
65997403Sobrien      do_narrow(const char_type* __lo, const char_type* __hi,
66097403Sobrien		char __dfault, char* __dest) const;
66197403Sobrien    };
66297403Sobrien
66397403Sobrien  template<typename _CharT>
66497403Sobrien    locale::id ctype<_CharT>::id;
66597403Sobrien
66697403Sobrien  // 22.2.1.3  ctype<char> specialization.
667132720Skan  /**
668132720Skan   *  @brief  The ctype<char> specialization.
669132720Skan   *
670132720Skan   *  This class defines classification and conversion functions for
671132720Skan   *  the char type.  It gets used by char streams for many I/O
672132720Skan   *  operations.  The char specialization provides a number of
673132720Skan   *  optimizations as well.
674132720Skan  */
67597403Sobrien  template<>
676132720Skan    class ctype<char> : public locale::facet, public ctype_base
67797403Sobrien    {
67897403Sobrien    public:
67997403Sobrien      // Types:
680132720Skan      /// Typedef for the template parameter char.
681132720Skan      typedef char		char_type;
68297403Sobrien
68397403Sobrien    protected:
68497403Sobrien      // Data Members:
68597403Sobrien      __c_locale		_M_c_locale_ctype;
686132720Skan      bool			_M_del;
687132720Skan      __to_type			_M_toupper;
688132720Skan      __to_type			_M_tolower;
689132720Skan      const mask*		_M_table;
690132720Skan      mutable char		_M_widen_ok;
691132720Skan      mutable char		_M_widen[1 + static_cast<unsigned char>(-1)];
692132720Skan      mutable char		_M_narrow[1 + static_cast<unsigned char>(-1)];
693132720Skan      mutable char		_M_narrow_ok;	// 0 uninitialized, 1 init,
694146897Skan						// 2 memcpy can't be used
695132720Skan
69697403Sobrien    public:
697132720Skan      /// The facet id for ctype<char>
69897403Sobrien      static locale::id        id;
699132720Skan      /// The size of the mask table.  It is SCHAR_MAX + 1.
70097403Sobrien      static const size_t      table_size = 1 + static_cast<unsigned char>(-1);
70197403Sobrien
702132720Skan      /**
703132720Skan       *  @brief  Constructor performs initialization.
704132720Skan       *
705132720Skan       *  This is the constructor provided by the standard.
706132720Skan       *
707132720Skan       *  @param table If non-zero, table is used as the per-char mask.
708132720Skan       *               Else classic_table() is used.
709132720Skan       *  @param del   If true, passes ownership of table to this facet.
710132720Skan       *  @param refs  Passed to the base facet class.
711132720Skan      */
712132720Skan      explicit
71397403Sobrien      ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
71497403Sobrien
715132720Skan      /**
716132720Skan       *  @brief  Constructor performs static initialization.
717132720Skan       *
718132720Skan       *  This constructor is used to construct the initial C locale facet.
719132720Skan       *
720132720Skan       *  @param cloc  Handle to C locale data.
721132720Skan       *  @param table If non-zero, table is used as the per-char mask.
722132720Skan       *  @param del   If true, passes ownership of table to this facet.
723132720Skan       *  @param refs  Passed to the base facet class.
724132720Skan      */
725132720Skan      explicit
726132720Skan      ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
72797403Sobrien	    size_t __refs = 0);
72897403Sobrien
729132720Skan      /**
730132720Skan       *  @brief  Test char classification.
731132720Skan       *
732132720Skan       *  This function compares the mask table[c] to @a m.
733132720Skan       *
734132720Skan       *  @param c  The char to compare the mask of.
735132720Skan       *  @param m  The mask to compare against.
736132720Skan       *  @return  True if m & table[c] is true, false otherwise.
737132720Skan      */
738132720Skan      inline bool
73997403Sobrien      is(mask __m, char __c) const;
740132720Skan
741132720Skan      /**
742132720Skan       *  @brief  Return a mask array.
743132720Skan       *
744132720Skan       *  This function finds the mask for each char in the range [lo, hi) and
745132720Skan       *  successively writes it to vec.  vec must have as many elements as
746132720Skan       *  the char array.
747132720Skan       *
748132720Skan       *  @param lo  Pointer to start of range.
749132720Skan       *  @param hi  Pointer to end of range.
750132720Skan       *  @param vec  Pointer to an array of mask storage.
751132720Skan       *  @return  @a hi.
752132720Skan      */
75397403Sobrien      inline const char*
75497403Sobrien      is(const char* __lo, const char* __hi, mask* __vec) const;
755132720Skan
756132720Skan      /**
757132720Skan       *  @brief  Find char matching a mask
758132720Skan       *
759132720Skan       *  This function searches for and returns the first char in [lo,hi) for
760132720Skan       *  which is(m,char) is true.
761132720Skan       *
762132720Skan       *  @param m  The mask to compare against.
763132720Skan       *  @param lo  Pointer to start of range.
764132720Skan       *  @param hi  Pointer to end of range.
765132720Skan       *  @return  Pointer to a matching char if found, else @a hi.
766132720Skan      */
76797403Sobrien      inline const char*
76897403Sobrien      scan_is(mask __m, const char* __lo, const char* __hi) const;
76997403Sobrien
770132720Skan      /**
771132720Skan       *  @brief  Find char not matching a mask
772132720Skan       *
773132720Skan       *  This function searches for and returns a pointer to the first char
774132720Skan       *  in [lo,hi) for which is(m,char) is false.
775132720Skan       *
776132720Skan       *  @param m  The mask to compare against.
777132720Skan       *  @param lo  Pointer to start of range.
778132720Skan       *  @param hi  Pointer to end of range.
779132720Skan       *  @return  Pointer to a non-matching char if found, else @a hi.
780132720Skan      */
78197403Sobrien      inline const char*
78297403Sobrien      scan_not(mask __m, const char* __lo, const char* __hi) const;
783132720Skan
784132720Skan      /**
785132720Skan       *  @brief  Convert to uppercase.
786132720Skan       *
787132720Skan       *  This function converts the char argument to uppercase if possible.
788132720Skan       *  If not possible (for example, '2'), returns the argument.
789132720Skan       *
790132720Skan       *  toupper() acts as if it returns ctype<char>::do_toupper(c).
791132720Skan       *  do_toupper() must always return the same result for the same input.
792132720Skan       *
793132720Skan       *  @param c  The char to convert.
794132720Skan       *  @return  The uppercase char if convertible, else @a c.
795132720Skan      */
796132720Skan      char_type
797132720Skan      toupper(char_type __c) const
798132720Skan      { return this->do_toupper(__c); }
799132720Skan
800132720Skan      /**
801132720Skan       *  @brief  Convert array to uppercase.
802132720Skan       *
803132720Skan       *  This function converts each char in the range [lo,hi) to uppercase
804132720Skan       *  if possible.  Other chars remain untouched.
805132720Skan       *
806132720Skan       *  toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi).
807132720Skan       *  do_toupper() must always return the same result for the same input.
808132720Skan       *
809132720Skan       *  @param lo  Pointer to first char in range.
810132720Skan       *  @param hi  Pointer to end of range.
811132720Skan       *  @return  @a hi.
812132720Skan      */
813132720Skan      const char_type*
814132720Skan      toupper(char_type *__lo, const char_type* __hi) const
815132720Skan      { return this->do_toupper(__lo, __hi); }
816132720Skan
817132720Skan      /**
818132720Skan       *  @brief  Convert to lowercase.
819132720Skan       *
820132720Skan       *  This function converts the char argument to lowercase if possible.
821132720Skan       *  If not possible (for example, '2'), returns the argument.
822132720Skan       *
823132720Skan       *  tolower() acts as if it returns ctype<char>::do_tolower(c).
824132720Skan       *  do_tolower() must always return the same result for the same input.
825132720Skan       *
826132720Skan       *  @param c  The char to convert.
827132720Skan       *  @return  The lowercase char if convertible, else @a c.
828132720Skan      */
829132720Skan      char_type
830132720Skan      tolower(char_type __c) const
831132720Skan      { return this->do_tolower(__c); }
832132720Skan
833132720Skan      /**
834132720Skan       *  @brief  Convert array to lowercase.
835132720Skan       *
836132720Skan       *  This function converts each char in the range [lo,hi) to lowercase
837132720Skan       *  if possible.  Other chars remain untouched.
838132720Skan       *
839132720Skan       *  tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi).
840132720Skan       *  do_tolower() must always return the same result for the same input.
841132720Skan       *
842132720Skan       *  @param lo  Pointer to first char in range.
843132720Skan       *  @param hi  Pointer to end of range.
844132720Skan       *  @return  @a hi.
845132720Skan      */
846132720Skan      const char_type*
847132720Skan      tolower(char_type* __lo, const char_type* __hi) const
848132720Skan      { return this->do_tolower(__lo, __hi); }
849132720Skan
850132720Skan      /**
851132720Skan       *  @brief  Widen char
852132720Skan       *
853132720Skan       *  This function converts the char to char_type using the simplest
854132720Skan       *  reasonable transformation.  For an underived ctype<char> facet, the
855132720Skan       *  argument will be returned unchanged.
856132720Skan       *
857132720Skan       *  This function works as if it returns ctype<char>::do_widen(c).
858132720Skan       *  do_widen() must always return the same result for the same input.
859132720Skan       *
860132720Skan       *  Note: this is not what you want for codepage conversions.  See
861132720Skan       *  codecvt for that.
862132720Skan       *
863132720Skan       *  @param c  The char to convert.
864132720Skan       *  @return  The converted character.
865132720Skan      */
866132720Skan      char_type
867132720Skan      widen(char __c) const
868132720Skan      {
869146897Skan	if (_M_widen_ok)
870146897Skan	  return _M_widen[static_cast<unsigned char>(__c)];
871132720Skan	this->_M_widen_init();
872132720Skan	return this->do_widen(__c);
873132720Skan      }
874132720Skan
875132720Skan      /**
876132720Skan       *  @brief  Widen char array
877132720Skan       *
878132720Skan       *  This function converts each char in the input to char using the
879132720Skan       *  simplest reasonable transformation.  For an underived ctype<char>
880132720Skan       *  facet, the argument will be copied unchanged.
881132720Skan       *
882132720Skan       *  This function works as if it returns ctype<char>::do_widen(c).
883132720Skan       *  do_widen() must always return the same result for the same input.
884132720Skan       *
885132720Skan       *  Note: this is not what you want for codepage conversions.  See
886132720Skan       *  codecvt for that.
887132720Skan       *
888132720Skan       *  @param lo  Pointer to first char in range.
889132720Skan       *  @param hi  Pointer to end of range.
890132720Skan       *  @param to  Pointer to the destination array.
891132720Skan       *  @return  @a hi.
892132720Skan      */
893132720Skan      const char*
894132720Skan      widen(const char* __lo, const char* __hi, char_type* __to) const
895132720Skan      {
896132720Skan	if (_M_widen_ok == 1)
897132720Skan	  {
898132720Skan	    memcpy(__to, __lo, __hi - __lo);
899132720Skan	    return __hi;
900132720Skan	  }
901146897Skan	if (!_M_widen_ok)
902146897Skan	  _M_widen_init();
903132720Skan	return this->do_widen(__lo, __hi, __to);
904132720Skan      }
905132720Skan
906132720Skan      /**
907132720Skan       *  @brief  Narrow char
908132720Skan       *
909132720Skan       *  This function converts the char to char using the simplest
910132720Skan       *  reasonable transformation.  If the conversion fails, dfault is
911132720Skan       *  returned instead.  For an underived ctype<char> facet, @a c
912132720Skan       *  will be returned unchanged.
913132720Skan       *
914132720Skan       *  This function works as if it returns ctype<char>::do_narrow(c).
915132720Skan       *  do_narrow() must always return the same result for the same input.
916132720Skan       *
917132720Skan       *  Note: this is not what you want for codepage conversions.  See
918132720Skan       *  codecvt for that.
919132720Skan       *
920132720Skan       *  @param c  The char to convert.
921132720Skan       *  @param dfault  Char to return if conversion fails.
922132720Skan       *  @return  The converted character.
923132720Skan      */
924132720Skan      char
925132720Skan      narrow(char_type __c, char __dfault) const
926132720Skan      {
927132720Skan	if (_M_narrow[static_cast<unsigned char>(__c)])
928132720Skan	  return _M_narrow[static_cast<unsigned char>(__c)];
929132720Skan	const char __t = do_narrow(__c, __dfault);
930146897Skan	if (__t != __dfault)
931146897Skan	  _M_narrow[static_cast<unsigned char>(__c)] = __t;
932132720Skan	return __t;
933132720Skan      }
934132720Skan
935132720Skan      /**
936132720Skan       *  @brief  Narrow char array
937132720Skan       *
938132720Skan       *  This function converts each char in the input to char using the
939132720Skan       *  simplest reasonable transformation and writes the results to the
940132720Skan       *  destination array.  For any char in the input that cannot be
941132720Skan       *  converted, @a dfault is used instead.  For an underived ctype<char>
942132720Skan       *  facet, the argument will be copied unchanged.
943132720Skan       *
944132720Skan       *  This function works as if it returns ctype<char>::do_narrow(lo, hi,
945132720Skan       *  dfault, to).  do_narrow() must always return the same result for the
946132720Skan       *  same input.
947132720Skan       *
948132720Skan       *  Note: this is not what you want for codepage conversions.  See
949132720Skan       *  codecvt for that.
950132720Skan       *
951132720Skan       *  @param lo  Pointer to start of range.
952132720Skan       *  @param hi  Pointer to end of range.
953132720Skan       *  @param dfault  Char to use if conversion fails.
954132720Skan       *  @param to  Pointer to the destination array.
955132720Skan       *  @return  @a hi.
956132720Skan      */
957132720Skan      const char_type*
958132720Skan      narrow(const char_type* __lo, const char_type* __hi,
959132720Skan	     char __dfault, char *__to) const
960132720Skan      {
961146897Skan	if (__builtin_expect(_M_narrow_ok == 1, true))
962132720Skan	  {
963132720Skan	    memcpy(__to, __lo, __hi - __lo);
964132720Skan	    return __hi;
965132720Skan	  }
966132720Skan	if (!_M_narrow_ok)
967132720Skan	  _M_narrow_init();
968132720Skan	return this->do_narrow(__lo, __hi, __dfault, __to);
969132720Skan      }
970132720Skan
97197403Sobrien    protected:
972132720Skan      /// Returns a pointer to the mask table provided to the constructor, or
973132720Skan      /// the default from classic_table() if none was provided.
974132720Skan      const mask*
97597403Sobrien      table() const throw()
97697403Sobrien      { return _M_table; }
97797403Sobrien
978132720Skan      /// Returns a pointer to the C locale mask table.
979132720Skan      static const mask*
98097403Sobrien      classic_table() throw();
98197403Sobrien
982132720Skan      /**
983132720Skan       *  @brief  Destructor.
984132720Skan       *
985132720Skan       *  This function deletes table() if @a del was true in the
986132720Skan       *  constructor.
987132720Skan      */
988132720Skan      virtual
98997403Sobrien      ~ctype();
99097403Sobrien
991132720Skan      /**
992132720Skan       *  @brief  Convert to uppercase.
993132720Skan       *
994132720Skan       *  This virtual function converts the char argument to uppercase if
995132720Skan       *  possible.  If not possible (for example, '2'), returns the argument.
996132720Skan       *
997132720Skan       *  do_toupper() is a hook for a derived facet to change the behavior of
998132720Skan       *  uppercasing.  do_toupper() must always return the same result for
999132720Skan       *  the same input.
1000132720Skan       *
1001132720Skan       *  @param c  The char to convert.
1002132720Skan       *  @return  The uppercase char if convertible, else @a c.
1003132720Skan      */
1004132720Skan      virtual char_type
100597403Sobrien      do_toupper(char_type) const;
100697403Sobrien
1007132720Skan      /**
1008132720Skan       *  @brief  Convert array to uppercase.
1009132720Skan       *
1010132720Skan       *  This virtual function converts each char in the range [lo,hi) to
1011132720Skan       *  uppercase if possible.  Other chars remain untouched.
1012132720Skan       *
1013132720Skan       *  do_toupper() is a hook for a derived facet to change the behavior of
1014132720Skan       *  uppercasing.  do_toupper() must always return the same result for
1015132720Skan       *  the same input.
1016132720Skan       *
1017132720Skan       *  @param lo  Pointer to start of range.
1018132720Skan       *  @param hi  Pointer to end of range.
1019132720Skan       *  @return  @a hi.
1020132720Skan      */
102197403Sobrien      virtual const char_type*
102297403Sobrien      do_toupper(char_type* __lo, const char_type* __hi) const;
102397403Sobrien
1024132720Skan      /**
1025132720Skan       *  @brief  Convert to lowercase.
1026132720Skan       *
1027132720Skan       *  This virtual function converts the char argument to lowercase if
1028132720Skan       *  possible.  If not possible (for example, '2'), returns the argument.
1029132720Skan       *
1030132720Skan       *  do_tolower() is a hook for a derived facet to change the behavior of
1031132720Skan       *  lowercasing.  do_tolower() must always return the same result for
1032132720Skan       *  the same input.
1033132720Skan       *
1034132720Skan       *  @param c  The char to convert.
1035132720Skan       *  @return  The lowercase char if convertible, else @a c.
1036132720Skan      */
1037132720Skan      virtual char_type
103897403Sobrien      do_tolower(char_type) const;
103997403Sobrien
1040132720Skan      /**
1041132720Skan       *  @brief  Convert array to lowercase.
1042132720Skan       *
1043132720Skan       *  This virtual function converts each char in the range [lo,hi) to
1044132720Skan       *  lowercase if possible.  Other chars remain untouched.
1045132720Skan       *
1046132720Skan       *  do_tolower() is a hook for a derived facet to change the behavior of
1047132720Skan       *  lowercasing.  do_tolower() must always return the same result for
1048132720Skan       *  the same input.
1049132720Skan       *
1050132720Skan       *  @param lo  Pointer to first char in range.
1051132720Skan       *  @param hi  Pointer to end of range.
1052132720Skan       *  @return  @a hi.
1053132720Skan      */
105497403Sobrien      virtual const char_type*
105597403Sobrien      do_tolower(char_type* __lo, const char_type* __hi) const;
105697403Sobrien
1057132720Skan      /**
1058132720Skan       *  @brief  Widen char
1059132720Skan       *
1060132720Skan       *  This virtual function converts the char to char using the simplest
1061132720Skan       *  reasonable transformation.  For an underived ctype<char> facet, the
1062132720Skan       *  argument will be returned unchanged.
1063132720Skan       *
1064132720Skan       *  do_widen() is a hook for a derived facet to change the behavior of
1065132720Skan       *  widening.  do_widen() must always return the same result for the
1066132720Skan       *  same input.
1067132720Skan       *
1068132720Skan       *  Note: this is not what you want for codepage conversions.  See
1069132720Skan       *  codecvt for that.
1070132720Skan       *
1071132720Skan       *  @param c  The char to convert.
1072132720Skan       *  @return  The converted character.
1073132720Skan      */
1074132720Skan      virtual char_type
1075132720Skan      do_widen(char __c) const
1076132720Skan      { return __c; }
1077132720Skan
1078132720Skan      /**
1079132720Skan       *  @brief  Widen char array
1080132720Skan       *
1081132720Skan       *  This function converts each char in the range [lo,hi) to char using
1082132720Skan       *  the simplest reasonable transformation.  For an underived
1083132720Skan       *  ctype<char> facet, the argument will be copied unchanged.
1084132720Skan       *
1085132720Skan       *  do_widen() is a hook for a derived facet to change the behavior of
1086132720Skan       *  widening.  do_widen() must always return the same result for the
1087132720Skan       *  same input.
1088132720Skan       *
1089132720Skan       *  Note: this is not what you want for codepage conversions.  See
1090132720Skan       *  codecvt for that.
1091132720Skan       *
1092132720Skan       *  @param lo  Pointer to start of range.
1093132720Skan       *  @param hi  Pointer to end of range.
1094132720Skan       *  @param to  Pointer to the destination array.
1095132720Skan       *  @return  @a hi.
1096132720Skan      */
109797403Sobrien      virtual const char*
1098132720Skan      do_widen(const char* __lo, const char* __hi, char_type* __dest) const
1099132720Skan      {
1100132720Skan	memcpy(__dest, __lo, __hi - __lo);
1101132720Skan	return __hi;
1102132720Skan      }
110397403Sobrien
1104132720Skan      /**
1105132720Skan       *  @brief  Narrow char
1106132720Skan       *
1107132720Skan       *  This virtual function converts the char to char using the simplest
1108132720Skan       *  reasonable transformation.  If the conversion fails, dfault is
1109132720Skan       *  returned instead.  For an underived ctype<char> facet, @a c will be
1110132720Skan       *  returned unchanged.
1111132720Skan       *
1112132720Skan       *  do_narrow() is a hook for a derived facet to change the behavior of
1113132720Skan       *  narrowing.  do_narrow() must always return the same result for the
1114132720Skan       *  same input.
1115132720Skan       *
1116132720Skan       *  Note: this is not what you want for codepage conversions.  See
1117132720Skan       *  codecvt for that.
1118132720Skan       *
1119132720Skan       *  @param c  The char to convert.
1120132720Skan       *  @param dfault  Char to return if conversion fails.
1121132720Skan       *  @return  The converted char.
1122132720Skan      */
1123132720Skan      virtual char
1124132720Skan      do_narrow(char_type __c, char) const
1125132720Skan      { return __c; }
112697403Sobrien
1127132720Skan      /**
1128132720Skan       *  @brief  Narrow char array to char array
1129132720Skan       *
1130132720Skan       *  This virtual function converts each char in the range [lo,hi) to
1131132720Skan       *  char using the simplest reasonable transformation and writes the
1132132720Skan       *  results to the destination array.  For any char in the input that
1133132720Skan       *  cannot be converted, @a dfault is used instead.  For an underived
1134132720Skan       *  ctype<char> facet, the argument will be copied unchanged.
1135132720Skan       *
1136132720Skan       *  do_narrow() is a hook for a derived facet to change the behavior of
1137132720Skan       *  narrowing.  do_narrow() must always return the same result for the
1138132720Skan       *  same input.
1139132720Skan       *
1140132720Skan       *  Note: this is not what you want for codepage conversions.  See
1141132720Skan       *  codecvt for that.
1142132720Skan       *
1143132720Skan       *  @param lo  Pointer to start of range.
1144132720Skan       *  @param hi  Pointer to end of range.
1145132720Skan       *  @param dfault  Char to use if conversion fails.
1146132720Skan       *  @param to  Pointer to the destination array.
1147132720Skan       *  @return  @a hi.
1148132720Skan      */
114997403Sobrien      virtual const char_type*
115097403Sobrien      do_narrow(const char_type* __lo, const char_type* __hi,
1151132720Skan		char, char* __dest) const
1152132720Skan      {
1153132720Skan	memcpy(__dest, __lo, __hi - __lo);
1154132720Skan	return __hi;
1155132720Skan      }
1156132720Skan
1157132720Skan    private:
1158132720Skan
1159132720Skan      void _M_widen_init() const
1160132720Skan      {
1161132720Skan	char __tmp[sizeof(_M_widen)];
1162132720Skan	for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
1163132720Skan	  __tmp[__i] = __i;
1164132720Skan	do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
1165132720Skan
1166132720Skan	_M_widen_ok = 1;
1167132720Skan	// Set _M_widen_ok to 2 if memcpy can't be used.
1168146897Skan	if (memcmp(__tmp, _M_widen, sizeof(_M_widen)))
1169146897Skan	  _M_widen_ok = 2;
1170132720Skan      }
1171132720Skan
1172132720Skan      // Fill in the narrowing cache and flag whether all values are
1173146897Skan      // valid or not.  _M_narrow_ok is set to 2 if memcpy can't
1174146897Skan      // be used.
1175132720Skan      void _M_narrow_init() const
1176132720Skan      {
1177132720Skan	char __tmp[sizeof(_M_narrow)];
1178132720Skan	for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
1179132720Skan	  __tmp[__i] = __i;
1180132720Skan	do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
1181132720Skan
1182146897Skan	_M_narrow_ok = 1;
1183146897Skan	if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow)))
1184146897Skan	  _M_narrow_ok = 2;
1185146897Skan	else
1186146897Skan	  {
1187146897Skan	    // Deal with the special case of zero: renarrow with a
1188146897Skan	    // different default and compare.
1189146897Skan	    char __c;
1190146897Skan	    do_narrow(__tmp, __tmp + 1, 1, &__c);
1191146897Skan	    if (__c == 1)
1192146897Skan	      _M_narrow_ok = 2;
1193146897Skan	  }
1194132720Skan      }
119597403Sobrien    };
1196132720Skan
119797403Sobrien  template<>
119897403Sobrien    const ctype<char>&
119997403Sobrien    use_facet<ctype<char> >(const locale& __loc);
120097403Sobrien
1201132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
120297403Sobrien  // 22.2.1.3  ctype<wchar_t> specialization
1203132720Skan  /**
1204132720Skan   *  @brief  The ctype<wchar_t> specialization.
1205132720Skan   *
1206132720Skan   *  This class defines classification and conversion functions for the
1207132720Skan   *  wchar_t type.  It gets used by wchar_t streams for many I/O operations.
1208132720Skan   *  The wchar_t specialization provides a number of optimizations as well.
1209132720Skan   *
1210132720Skan   *  ctype<wchar_t> inherits its public methods from
1211132720Skan   *  __ctype_abstract_base<wchar_t>.
1212132720Skan  */
121397403Sobrien  template<>
121497403Sobrien    class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
121597403Sobrien    {
121697403Sobrien    public:
121797403Sobrien      // Types:
1218132720Skan      /// Typedef for the template parameter wchar_t.
1219132720Skan      typedef wchar_t		char_type;
1220132720Skan      typedef wctype_t		__wmask_type;
122197403Sobrien
122297403Sobrien    protected:
122397403Sobrien      __c_locale		_M_c_locale_ctype;
122497403Sobrien
1225132720Skan      // Pre-computed narrowed and widened chars.
1226132720Skan      bool                      _M_narrow_ok;
1227132720Skan      char                      _M_narrow[128];
1228132720Skan      wint_t                    _M_widen[1 + static_cast<unsigned char>(-1)];
1229132720Skan
1230132720Skan      // Pre-computed elements for do_is.
1231132720Skan      mask                      _M_bit[16];
1232132720Skan      __wmask_type              _M_wmask[16];
1233132720Skan
123497403Sobrien    public:
123597403Sobrien      // Data Members:
1236132720Skan      /// The facet id for ctype<wchar_t>
1237132720Skan      static locale::id		id;
123897403Sobrien
1239132720Skan      /**
1240132720Skan       *  @brief  Constructor performs initialization.
1241132720Skan       *
1242132720Skan       *  This is the constructor provided by the standard.
1243132720Skan       *
1244132720Skan       *  @param refs  Passed to the base facet class.
1245132720Skan      */
1246132720Skan      explicit
124797403Sobrien      ctype(size_t __refs = 0);
124897403Sobrien
1249132720Skan      /**
1250132720Skan       *  @brief  Constructor performs static initialization.
1251132720Skan       *
1252132720Skan       *  This constructor is used to construct the initial C locale facet.
1253132720Skan       *
1254132720Skan       *  @param cloc  Handle to C locale data.
1255132720Skan       *  @param refs  Passed to the base facet class.
1256132720Skan      */
1257132720Skan      explicit
125897403Sobrien      ctype(__c_locale __cloc, size_t __refs = 0);
125997403Sobrien
126097403Sobrien    protected:
126197403Sobrien      __wmask_type
126297403Sobrien      _M_convert_to_wmask(const mask __m) const;
126397403Sobrien
1264132720Skan      /// Destructor
1265132720Skan      virtual
126697403Sobrien      ~ctype();
126797403Sobrien
1268132720Skan      /**
1269132720Skan       *  @brief  Test wchar_t classification.
1270132720Skan       *
1271132720Skan       *  This function finds a mask M for @a c and compares it to mask @a m.
1272132720Skan       *
1273132720Skan       *  do_is() is a hook for a derived facet to change the behavior of
1274132720Skan       *  classifying.  do_is() must always return the same result for the
1275132720Skan       *  same input.
1276132720Skan       *
1277132720Skan       *  @param c  The wchar_t to find the mask of.
1278132720Skan       *  @param m  The mask to compare against.
1279132720Skan       *  @return  (M & m) != 0.
1280132720Skan      */
1281132720Skan      virtual bool
128297403Sobrien      do_is(mask __m, char_type __c) const;
128397403Sobrien
1284132720Skan      /**
1285132720Skan       *  @brief  Return a mask array.
1286132720Skan       *
1287132720Skan       *  This function finds the mask for each wchar_t in the range [lo,hi)
1288132720Skan       *  and successively writes it to vec.  vec must have as many elements
1289132720Skan       *  as the input.
1290132720Skan       *
1291132720Skan       *  do_is() is a hook for a derived facet to change the behavior of
1292132720Skan       *  classifying.  do_is() must always return the same result for the
1293132720Skan       *  same input.
1294132720Skan       *
1295132720Skan       *  @param lo  Pointer to start of range.
1296132720Skan       *  @param hi  Pointer to end of range.
1297132720Skan       *  @param vec  Pointer to an array of mask storage.
1298132720Skan       *  @return  @a hi.
1299132720Skan      */
130097403Sobrien      virtual const char_type*
130197403Sobrien      do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
130297403Sobrien
1303132720Skan      /**
1304132720Skan       *  @brief  Find wchar_t matching mask
1305132720Skan       *
1306132720Skan       *  This function searches for and returns the first wchar_t c in
1307132720Skan       *  [lo,hi) for which is(m,c) is true.
1308132720Skan       *
1309132720Skan       *  do_scan_is() is a hook for a derived facet to change the behavior of
1310132720Skan       *  match searching.  do_is() must always return the same result for the
1311132720Skan       *  same input.
1312132720Skan       *
1313132720Skan       *  @param m  The mask to compare against.
1314132720Skan       *  @param lo  Pointer to start of range.
1315132720Skan       *  @param hi  Pointer to end of range.
1316132720Skan       *  @return  Pointer to a matching wchar_t if found, else @a hi.
1317132720Skan      */
131897403Sobrien      virtual const char_type*
131997403Sobrien      do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
132097403Sobrien
1321132720Skan      /**
1322132720Skan       *  @brief  Find wchar_t not matching mask
1323132720Skan       *
1324132720Skan       *  This function searches for and returns a pointer to the first
1325132720Skan       *  wchar_t c of [lo,hi) for which is(m,c) is false.
1326132720Skan       *
1327132720Skan       *  do_scan_is() is a hook for a derived facet to change the behavior of
1328132720Skan       *  match searching.  do_is() must always return the same result for the
1329132720Skan       *  same input.
1330132720Skan       *
1331132720Skan       *  @param m  The mask to compare against.
1332132720Skan       *  @param lo  Pointer to start of range.
1333132720Skan       *  @param hi  Pointer to end of range.
1334132720Skan       *  @return  Pointer to a non-matching wchar_t if found, else @a hi.
1335132720Skan      */
133697403Sobrien      virtual const char_type*
1337132720Skan      do_scan_not(mask __m, const char_type* __lo,
133897403Sobrien		  const char_type* __hi) const;
133997403Sobrien
1340132720Skan      /**
1341132720Skan       *  @brief  Convert to uppercase.
1342132720Skan       *
1343132720Skan       *  This virtual function converts the wchar_t argument to uppercase if
1344132720Skan       *  possible.  If not possible (for example, '2'), returns the argument.
1345132720Skan       *
1346132720Skan       *  do_toupper() is a hook for a derived facet to change the behavior of
1347132720Skan       *  uppercasing.  do_toupper() must always return the same result for
1348132720Skan       *  the same input.
1349132720Skan       *
1350132720Skan       *  @param c  The wchar_t to convert.
1351132720Skan       *  @return  The uppercase wchar_t if convertible, else @a c.
1352132720Skan      */
1353132720Skan      virtual char_type
135497403Sobrien      do_toupper(char_type) const;
135597403Sobrien
1356132720Skan      /**
1357132720Skan       *  @brief  Convert array to uppercase.
1358132720Skan       *
1359132720Skan       *  This virtual function converts each wchar_t in the range [lo,hi) to
1360132720Skan       *  uppercase if possible.  Other elements remain untouched.
1361132720Skan       *
1362132720Skan       *  do_toupper() is a hook for a derived facet to change the behavior of
1363132720Skan       *  uppercasing.  do_toupper() must always return the same result for
1364132720Skan       *  the same input.
1365132720Skan       *
1366132720Skan       *  @param lo  Pointer to start of range.
1367132720Skan       *  @param hi  Pointer to end of range.
1368132720Skan       *  @return  @a hi.
1369132720Skan      */
137097403Sobrien      virtual const char_type*
137197403Sobrien      do_toupper(char_type* __lo, const char_type* __hi) const;
137297403Sobrien
1373132720Skan      /**
1374132720Skan       *  @brief  Convert to lowercase.
1375132720Skan       *
1376132720Skan       *  This virtual function converts the argument to lowercase if
1377132720Skan       *  possible.  If not possible (for example, '2'), returns the argument.
1378132720Skan       *
1379132720Skan       *  do_tolower() is a hook for a derived facet to change the behavior of
1380132720Skan       *  lowercasing.  do_tolower() must always return the same result for
1381132720Skan       *  the same input.
1382132720Skan       *
1383132720Skan       *  @param c  The wchar_t to convert.
1384132720Skan       *  @return  The lowercase wchar_t if convertible, else @a c.
1385132720Skan      */
1386132720Skan      virtual char_type
138797403Sobrien      do_tolower(char_type) const;
138897403Sobrien
1389132720Skan      /**
1390132720Skan       *  @brief  Convert array to lowercase.
1391132720Skan       *
1392132720Skan       *  This virtual function converts each wchar_t in the range [lo,hi) to
1393132720Skan       *  lowercase if possible.  Other elements remain untouched.
1394132720Skan       *
1395132720Skan       *  do_tolower() is a hook for a derived facet to change the behavior of
1396132720Skan       *  lowercasing.  do_tolower() must always return the same result for
1397132720Skan       *  the same input.
1398132720Skan       *
1399132720Skan       *  @param lo  Pointer to start of range.
1400132720Skan       *  @param hi  Pointer to end of range.
1401132720Skan       *  @return  @a hi.
1402132720Skan      */
140397403Sobrien      virtual const char_type*
140497403Sobrien      do_tolower(char_type* __lo, const char_type* __hi) const;
1405132720Skan
1406132720Skan      /**
1407132720Skan       *  @brief  Widen char to wchar_t
1408132720Skan       *
1409132720Skan       *  This virtual function converts the char to wchar_t using the
1410132720Skan       *  simplest reasonable transformation.  For an underived ctype<wchar_t>
1411132720Skan       *  facet, the argument will be cast to wchar_t.
1412132720Skan       *
1413132720Skan       *  do_widen() is a hook for a derived facet to change the behavior of
1414132720Skan       *  widening.  do_widen() must always return the same result for the
1415132720Skan       *  same input.
1416132720Skan       *
1417132720Skan       *  Note: this is not what you want for codepage conversions.  See
1418132720Skan       *  codecvt for that.
1419132720Skan       *
1420132720Skan       *  @param c  The char to convert.
1421132720Skan       *  @return  The converted wchar_t.
1422132720Skan      */
1423132720Skan      virtual char_type
142497403Sobrien      do_widen(char) const;
142597403Sobrien
1426132720Skan      /**
1427132720Skan       *  @brief  Widen char array to wchar_t array
1428132720Skan       *
1429132720Skan       *  This function converts each char in the input to wchar_t using the
1430132720Skan       *  simplest reasonable transformation.  For an underived ctype<wchar_t>
1431132720Skan       *  facet, the argument will be copied, casting each element to wchar_t.
1432132720Skan       *
1433132720Skan       *  do_widen() is a hook for a derived facet to change the behavior of
1434132720Skan       *  widening.  do_widen() must always return the same result for the
1435132720Skan       *  same input.
1436132720Skan       *
1437132720Skan       *  Note: this is not what you want for codepage conversions.  See
1438132720Skan       *  codecvt for that.
1439132720Skan       *
1440132720Skan       *  @param lo  Pointer to start range.
1441132720Skan       *  @param hi  Pointer to end of range.
1442132720Skan       *  @param to  Pointer to the destination array.
1443132720Skan       *  @return  @a hi.
1444132720Skan      */
144597403Sobrien      virtual const char*
144697403Sobrien      do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
144797403Sobrien
1448132720Skan      /**
1449132720Skan       *  @brief  Narrow wchar_t to char
1450132720Skan       *
1451132720Skan       *  This virtual function converts the argument to char using
1452132720Skan       *  the simplest reasonable transformation.  If the conversion
1453132720Skan       *  fails, dfault is returned instead.  For an underived
1454132720Skan       *  ctype<wchar_t> facet, @a c will be cast to char and
1455132720Skan       *  returned.
1456132720Skan       *
1457132720Skan       *  do_narrow() is a hook for a derived facet to change the
1458132720Skan       *  behavior of narrowing.  do_narrow() must always return the
1459132720Skan       *  same result for the same input.
1460132720Skan       *
1461132720Skan       *  Note: this is not what you want for codepage conversions.  See
1462132720Skan       *  codecvt for that.
1463132720Skan       *
1464132720Skan       *  @param c  The wchar_t to convert.
1465132720Skan       *  @param dfault  Char to return if conversion fails.
1466132720Skan       *  @return  The converted char.
1467132720Skan      */
1468132720Skan      virtual char
146997403Sobrien      do_narrow(char_type, char __dfault) const;
147097403Sobrien
1471132720Skan      /**
1472132720Skan       *  @brief  Narrow wchar_t array to char array
1473132720Skan       *
1474132720Skan       *  This virtual function converts each wchar_t in the range [lo,hi) to
1475132720Skan       *  char using the simplest reasonable transformation and writes the
1476132720Skan       *  results to the destination array.  For any wchar_t in the input that
1477132720Skan       *  cannot be converted, @a dfault is used instead.  For an underived
1478132720Skan       *  ctype<wchar_t> facet, the argument will be copied, casting each
1479132720Skan       *  element to char.
1480132720Skan       *
1481132720Skan       *  do_narrow() is a hook for a derived facet to change the behavior of
1482132720Skan       *  narrowing.  do_narrow() must always return the same result for the
1483132720Skan       *  same input.
1484132720Skan       *
1485132720Skan       *  Note: this is not what you want for codepage conversions.  See
1486132720Skan       *  codecvt for that.
1487132720Skan       *
1488132720Skan       *  @param lo  Pointer to start of range.
1489132720Skan       *  @param hi  Pointer to end of range.
1490132720Skan       *  @param dfault  Char to use if conversion fails.
1491132720Skan       *  @param to  Pointer to the destination array.
1492132720Skan       *  @return  @a hi.
1493132720Skan      */
149497403Sobrien      virtual const char_type*
149597403Sobrien      do_narrow(const char_type* __lo, const char_type* __hi,
149697403Sobrien		char __dfault, char* __dest) const;
149797403Sobrien
1498132720Skan      // For use at construction time only.
1499132720Skan      void
1500132720Skan      _M_initialize_ctype();
150197403Sobrien    };
150297403Sobrien
150397403Sobrien  template<>
150497403Sobrien    const ctype<wchar_t>&
150597403Sobrien    use_facet<ctype<wchar_t> >(const locale& __loc);
1506132720Skan#endif //_GLIBCXX_USE_WCHAR_T
150797403Sobrien
1508169691Skan  /// @brief  class ctype_byname [22.2.1.2].
150997403Sobrien  template<typename _CharT>
151097403Sobrien    class ctype_byname : public ctype<_CharT>
151197403Sobrien    {
151297403Sobrien    public:
1513132720Skan      typedef _CharT		char_type;
151497403Sobrien
1515132720Skan      explicit
151697403Sobrien      ctype_byname(const char* __s, size_t __refs = 0);
151797403Sobrien
151897403Sobrien    protected:
1519132720Skan      virtual
152097403Sobrien      ~ctype_byname() { };
152197403Sobrien    };
152297403Sobrien
1523169691Skan  /// 22.2.1.4  Class ctype_byname specializations.
152497403Sobrien  template<>
152597403Sobrien    ctype_byname<char>::ctype_byname(const char*, size_t refs);
152697403Sobrien
152797403Sobrien  template<>
152897403Sobrien    ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
152997403Sobrien
1530169691Skan_GLIBCXX_END_NAMESPACE
153197403Sobrien
1532169691Skan// Include host and configuration specific ctype inlines.
1533169691Skan#include <bits/ctype_inline.h>
1534169691Skan
1535169691Skan// 22.2.1.5  Template class codecvt
1536169691Skan#include <bits/codecvt.h>
1537169691Skan
1538169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
1539169691Skan
154097403Sobrien  // 22.2.2  The numeric category.
1541132720Skan  class __num_base
154297403Sobrien  {
1543117397Skan  public:
1544117397Skan    // NB: Code depends on the order of _S_atoms_out elements.
1545117397Skan    // Below are the indices into _S_atoms_out.
1546132720Skan    enum
1547132720Skan      {
1548132720Skan        _S_ominus,
1549132720Skan        _S_oplus,
1550132720Skan        _S_ox,
1551132720Skan        _S_oX,
1552132720Skan        _S_odigits,
1553132720Skan        _S_odigits_end = _S_odigits + 16,
1554132720Skan        _S_oudigits = _S_odigits_end,
1555132720Skan        _S_oudigits_end = _S_oudigits + 16,
1556132720Skan        _S_oe = _S_odigits + 14,  // For scientific notation, 'e'
1557132720Skan        _S_oE = _S_oudigits + 14, // For scientific notation, 'E'
1558132720Skan	_S_oend = _S_oudigits_end
1559117397Skan      };
1560132720Skan
1561117397Skan    // A list of valid numeric literals for output.  This array
1562117397Skan    // contains chars that will be passed through the current locale's
1563117397Skan    // ctype<_CharT>.widen() and then used to render numbers.
1564117397Skan    // For the standard "C" locale, this is
1565117397Skan    // "-+xX0123456789abcdef0123456789ABCDEF".
1566117397Skan    static const char* _S_atoms_out;
1567117397Skan
156897403Sobrien    // String literal of acceptable (narrow) input, for num_get.
1569132720Skan    // "-+xX0123456789abcdefABCDEF"
1570117397Skan    static const char* _S_atoms_in;
157197403Sobrien
1572132720Skan    enum
1573132720Skan    {
1574132720Skan      _S_iminus,
1575132720Skan      _S_iplus,
1576132720Skan      _S_ix,
1577132720Skan      _S_iX,
1578132720Skan      _S_izero,
1579132720Skan      _S_ie = _S_izero + 14,
1580132720Skan      _S_iE = _S_izero + 20,
1581132720Skan      _S_iend = 26
158297403Sobrien    };
158397403Sobrien
158497403Sobrien    // num_put
158597403Sobrien    // Construct and return valid scanf format for floating point types.
1586117397Skan    static void
1587132720Skan    _S_format_float(const ios_base& __io, char* __fptr, char __mod);
158897403Sobrien  };
158997403Sobrien
1590132720Skan  template<typename _CharT>
1591132720Skan    struct __numpunct_cache : public locale::facet
1592132720Skan    {
1593132720Skan      const char*			_M_grouping;
1594132720Skan      size_t                            _M_grouping_size;
1595132720Skan      bool				_M_use_grouping;
1596132720Skan      const _CharT*			_M_truename;
1597132720Skan      size_t                            _M_truename_size;
1598132720Skan      const _CharT*			_M_falsename;
1599132720Skan      size_t                            _M_falsename_size;
1600132720Skan      _CharT				_M_decimal_point;
1601132720Skan      _CharT				_M_thousands_sep;
160297403Sobrien
1603132720Skan      // A list of valid numeric literals for output: in the standard
1604132720Skan      // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
1605132720Skan      // This array contains the chars after having been passed
1606132720Skan      // through the current locale's ctype<_CharT>.widen().
1607132720Skan      _CharT				_M_atoms_out[__num_base::_S_oend];
1608132720Skan
1609132720Skan      // A list of valid numeric literals for input: in the standard
1610132720Skan      // "C" locale, this is "-+xX0123456789abcdefABCDEF"
1611132720Skan      // This array contains the chars after having been passed
1612132720Skan      // through the current locale's ctype<_CharT>.widen().
1613132720Skan      _CharT				_M_atoms_in[__num_base::_S_iend];
1614132720Skan
1615132720Skan      bool				_M_allocated;
1616132720Skan
1617132720Skan      __numpunct_cache(size_t __refs = 0) : facet(__refs),
1618132720Skan      _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
1619132720Skan      _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL),
1620132720Skan      _M_falsename_size(0), _M_decimal_point(_CharT()),
1621132720Skan      _M_thousands_sep(_CharT()), _M_allocated(false)
1622132720Skan      { }
1623132720Skan
1624132720Skan      ~__numpunct_cache();
1625132720Skan
1626132720Skan      void
1627132720Skan      _M_cache(const locale& __loc);
1628132720Skan
1629132720Skan    private:
1630132720Skan      __numpunct_cache&
1631132720Skan      operator=(const __numpunct_cache&);
1632132720Skan
1633132720Skan      explicit
1634132720Skan      __numpunct_cache(const __numpunct_cache&);
1635132720Skan    };
1636132720Skan
163797403Sobrien  template<typename _CharT>
1638132720Skan    __numpunct_cache<_CharT>::~__numpunct_cache()
1639132720Skan    {
1640132720Skan      if (_M_allocated)
1641132720Skan	{
1642132720Skan	  delete [] _M_grouping;
1643132720Skan	  delete [] _M_truename;
1644132720Skan	  delete [] _M_falsename;
1645132720Skan	}
1646132720Skan    }
1647117397Skan
1648132720Skan  /**
1649132720Skan   *  @brief  Numpunct facet.
1650132720Skan   *
1651132720Skan   *  This facet stores several pieces of information related to printing and
1652132720Skan   *  scanning numbers, such as the decimal point character.  It takes a
1653132720Skan   *  template parameter specifying the char type.  The numpunct facet is
1654132720Skan   *  used by streams for many I/O operations involving numbers.
1655132720Skan   *
1656132720Skan   *  The numpunct template uses protected virtual functions to provide the
1657132720Skan   *  actual results.  The public accessors forward the call to the virtual
1658132720Skan   *  functions.  These virtual functions are hooks for developers to
1659132720Skan   *  implement the behavior they require from a numpunct facet.
1660132720Skan  */
1661117397Skan  template<typename _CharT>
166297403Sobrien    class numpunct : public locale::facet
166397403Sobrien    {
166497403Sobrien    public:
166597403Sobrien      // Types:
1666132720Skan      //@{
1667132720Skan      /// Public typedefs
1668132720Skan      typedef _CharT			char_type;
1669132720Skan      typedef basic_string<_CharT>	string_type;
1670132720Skan      //@}
1671132720Skan      typedef __numpunct_cache<_CharT>  __cache_type;
167297403Sobrien
1673132720Skan    protected:
1674132720Skan      __cache_type*			_M_data;
1675117397Skan
1676132720Skan    public:
1677132720Skan      /// Numpunct facet id.
1678132720Skan      static locale::id			id;
167997403Sobrien
1680132720Skan      /**
1681132720Skan       *  @brief  Numpunct constructor.
1682132720Skan       *
1683132720Skan       *  @param  refs  Refcount to pass to the base class.
1684132720Skan       */
1685132720Skan      explicit
1686132720Skan      numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
1687132720Skan      { _M_initialize_numpunct(); }
168897403Sobrien
1689132720Skan      /**
1690132720Skan       *  @brief  Internal constructor.  Not for general use.
1691132720Skan       *
1692132720Skan       *  This is a constructor for use by the library itself to set up the
1693132720Skan       *  predefined locale facets.
1694132720Skan       *
1695132720Skan       *  @param  cache  __numpunct_cache object.
1696132720Skan       *  @param  refs  Refcount to pass to the base class.
1697132720Skan       */
1698132720Skan      explicit
1699132720Skan      numpunct(__cache_type* __cache, size_t __refs = 0)
1700132720Skan      : facet(__refs), _M_data(__cache)
170197403Sobrien      { _M_initialize_numpunct(); }
170297403Sobrien
1703132720Skan      /**
1704132720Skan       *  @brief  Internal constructor.  Not for general use.
1705132720Skan       *
1706132720Skan       *  This is a constructor for use by the library itself to set up new
1707132720Skan       *  locales.
1708132720Skan       *
1709132720Skan       *  @param  cloc  The "C" locale.
1710132720Skan       *  @param  refs  Refcount to pass to the base class.
1711132720Skan       */
1712132720Skan      explicit
1713132720Skan      numpunct(__c_locale __cloc, size_t __refs = 0)
1714132720Skan      : facet(__refs), _M_data(NULL)
171597403Sobrien      { _M_initialize_numpunct(__cloc); }
171697403Sobrien
1717132720Skan      /**
1718132720Skan       *  @brief  Return decimal point character.
1719132720Skan       *
1720132720Skan       *  This function returns a char_type to use as a decimal point.  It
1721132720Skan       *  does so by returning returning
1722132720Skan       *  numpunct<char_type>::do_decimal_point().
1723132720Skan       *
1724132720Skan       *  @return  @a char_type representing a decimal point.
1725132720Skan      */
1726132720Skan      char_type
172797403Sobrien      decimal_point() const
172897403Sobrien      { return this->do_decimal_point(); }
172997403Sobrien
1730132720Skan      /**
1731132720Skan       *  @brief  Return thousands separator character.
1732132720Skan       *
1733132720Skan       *  This function returns a char_type to use as a thousands
1734132720Skan       *  separator.  It does so by returning returning
1735132720Skan       *  numpunct<char_type>::do_thousands_sep().
1736132720Skan       *
1737132720Skan       *  @return  char_type representing a thousands separator.
1738132720Skan      */
1739132720Skan      char_type
174097403Sobrien      thousands_sep() const
174197403Sobrien      { return this->do_thousands_sep(); }
174297403Sobrien
1743132720Skan      /**
1744132720Skan       *  @brief  Return grouping specification.
1745132720Skan       *
1746132720Skan       *  This function returns a string representing groupings for the
1747132720Skan       *  integer part of a number.  Groupings indicate where thousands
1748132720Skan       *  separators should be inserted in the integer part of a number.
1749132720Skan       *
1750132720Skan       *  Each char in the return string is interpret as an integer
1751132720Skan       *  rather than a character.  These numbers represent the number
1752132720Skan       *  of digits in a group.  The first char in the string
1753132720Skan       *  represents the number of digits in the least significant
1754132720Skan       *  group.  If a char is negative, it indicates an unlimited
1755132720Skan       *  number of digits for the group.  If more chars from the
1756132720Skan       *  string are required to group a number, the last char is used
1757132720Skan       *  repeatedly.
1758132720Skan       *
1759132720Skan       *  For example, if the grouping() returns "\003\002" and is
1760132720Skan       *  applied to the number 123456789, this corresponds to
1761132720Skan       *  12,34,56,789.  Note that if the string was "32", this would
1762132720Skan       *  put more than 50 digits into the least significant group if
1763132720Skan       *  the character set is ASCII.
1764132720Skan       *
1765132720Skan       *  The string is returned by calling
1766132720Skan       *  numpunct<char_type>::do_grouping().
1767132720Skan       *
1768132720Skan       *  @return  string representing grouping specification.
1769132720Skan      */
1770132720Skan      string
177197403Sobrien      grouping() const
177297403Sobrien      { return this->do_grouping(); }
177397403Sobrien
1774132720Skan      /**
1775132720Skan       *  @brief  Return string representation of bool true.
1776132720Skan       *
1777132720Skan       *  This function returns a string_type containing the text
1778132720Skan       *  representation for true bool variables.  It does so by calling
1779132720Skan       *  numpunct<char_type>::do_truename().
1780132720Skan       *
1781132720Skan       *  @return  string_type representing printed form of true.
1782132720Skan      */
1783132720Skan      string_type
178497403Sobrien      truename() const
178597403Sobrien      { return this->do_truename(); }
178697403Sobrien
1787132720Skan      /**
1788132720Skan       *  @brief  Return string representation of bool false.
1789132720Skan       *
1790132720Skan       *  This function returns a string_type containing the text
1791132720Skan       *  representation for false bool variables.  It does so by calling
1792132720Skan       *  numpunct<char_type>::do_falsename().
1793132720Skan       *
1794132720Skan       *  @return  string_type representing printed form of false.
1795132720Skan      */
1796132720Skan      string_type
179797403Sobrien      falsename() const
179897403Sobrien      { return this->do_falsename(); }
179997403Sobrien
180097403Sobrien    protected:
1801132720Skan      /// Destructor.
1802132720Skan      virtual
180397403Sobrien      ~numpunct();
180497403Sobrien
1805132720Skan      /**
1806132720Skan       *  @brief  Return decimal point character.
1807132720Skan       *
1808132720Skan       *  Returns a char_type to use as a decimal point.  This function is a
1809132720Skan       *  hook for derived classes to change the value returned.
1810132720Skan       *
1811132720Skan       *  @return  @a char_type representing a decimal point.
1812132720Skan      */
1813132720Skan      virtual char_type
181497403Sobrien      do_decimal_point() const
1815132720Skan      { return _M_data->_M_decimal_point; }
181697403Sobrien
1817132720Skan      /**
1818132720Skan       *  @brief  Return thousands separator character.
1819132720Skan       *
1820132720Skan       *  Returns a char_type to use as a thousands separator.  This function
1821132720Skan       *  is a hook for derived classes to change the value returned.
1822132720Skan       *
1823132720Skan       *  @return  @a char_type representing a thousands separator.
1824132720Skan      */
1825132720Skan      virtual char_type
182697403Sobrien      do_thousands_sep() const
1827132720Skan      { return _M_data->_M_thousands_sep; }
182897403Sobrien
1829132720Skan      /**
1830132720Skan       *  @brief  Return grouping specification.
1831132720Skan       *
1832132720Skan       *  Returns a string representing groupings for the integer part of a
1833132720Skan       *  number.  This function is a hook for derived classes to change the
1834132720Skan       *  value returned.  @see grouping() for details.
1835132720Skan       *
1836132720Skan       *  @return  String representing grouping specification.
1837132720Skan      */
183897403Sobrien      virtual string
183997403Sobrien      do_grouping() const
1840132720Skan      { return _M_data->_M_grouping; }
184197403Sobrien
1842132720Skan      /**
1843132720Skan       *  @brief  Return string representation of bool true.
1844132720Skan       *
1845132720Skan       *  Returns a string_type containing the text representation for true
1846132720Skan       *  bool variables.  This function is a hook for derived classes to
1847132720Skan       *  change the value returned.
1848132720Skan       *
1849132720Skan       *  @return  string_type representing printed form of true.
1850132720Skan      */
1851132720Skan      virtual string_type
185297403Sobrien      do_truename() const
1853132720Skan      { return _M_data->_M_truename; }
185497403Sobrien
1855132720Skan      /**
1856132720Skan       *  @brief  Return string representation of bool false.
1857132720Skan       *
1858132720Skan       *  Returns a string_type containing the text representation for false
1859132720Skan       *  bool variables.  This function is a hook for derived classes to
1860132720Skan       *  change the value returned.
1861132720Skan       *
1862132720Skan       *  @return  string_type representing printed form of false.
1863132720Skan      */
1864132720Skan      virtual string_type
186597403Sobrien      do_falsename() const
1866132720Skan      { return _M_data->_M_falsename; }
186797403Sobrien
186897403Sobrien      // For use at construction time only.
1869132720Skan      void
1870107606Sobrien      _M_initialize_numpunct(__c_locale __cloc = NULL);
187197403Sobrien    };
187297403Sobrien
187397403Sobrien  template<typename _CharT>
187497403Sobrien    locale::id numpunct<_CharT>::id;
187597403Sobrien
1876132720Skan  template<>
187797403Sobrien    numpunct<char>::~numpunct();
187897403Sobrien
1879132720Skan  template<>
188097403Sobrien    void
188197403Sobrien    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
188297403Sobrien
1883132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
1884132720Skan  template<>
188597403Sobrien    numpunct<wchar_t>::~numpunct();
188697403Sobrien
1887132720Skan  template<>
188897403Sobrien    void
188997403Sobrien    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
189097403Sobrien#endif
189197403Sobrien
1892169691Skan  /// @brief  class numpunct_byname [22.2.3.2].
189397403Sobrien  template<typename _CharT>
189497403Sobrien    class numpunct_byname : public numpunct<_CharT>
189597403Sobrien    {
189697403Sobrien    public:
1897132720Skan      typedef _CharT			char_type;
1898132720Skan      typedef basic_string<_CharT>	string_type;
189997403Sobrien
1900132720Skan      explicit
190197403Sobrien      numpunct_byname(const char* __s, size_t __refs = 0)
190297403Sobrien      : numpunct<_CharT>(__refs)
190397403Sobrien      {
1904132720Skan	if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
1905132720Skan	  {
1906132720Skan	    __c_locale __tmp;
1907132720Skan	    this->_S_create_c_locale(__tmp, __s);
1908132720Skan	    this->_M_initialize_numpunct(__tmp);
1909132720Skan	    this->_S_destroy_c_locale(__tmp);
1910132720Skan	  }
191197403Sobrien      }
191297403Sobrien
191397403Sobrien    protected:
1914132720Skan      virtual
1915132720Skan      ~numpunct_byname() { }
191697403Sobrien    };
191797403Sobrien
1918169691Skan_GLIBCXX_BEGIN_LDBL_NAMESPACE
1919132720Skan  /**
1920132720Skan   *  @brief  Facet for parsing number strings.
1921132720Skan   *
1922132720Skan   *  This facet encapsulates the code to parse and return a number
1923132720Skan   *  from a string.  It is used by the istream numeric extraction
1924132720Skan   *  operators.
1925132720Skan   *
1926132720Skan   *  The num_get template uses protected virtual functions to provide the
1927132720Skan   *  actual results.  The public accessors forward the call to the virtual
1928132720Skan   *  functions.  These virtual functions are hooks for developers to
1929132720Skan   *  implement the behavior they require from the num_get facet.
1930132720Skan  */
193197403Sobrien  template<typename _CharT, typename _InIter>
1932132720Skan    class num_get : public locale::facet
193397403Sobrien    {
193497403Sobrien    public:
193597403Sobrien      // Types:
1936132720Skan      //@{
1937132720Skan      /// Public typedefs
1938132720Skan      typedef _CharT			char_type;
1939132720Skan      typedef _InIter			iter_type;
1940132720Skan      //@}
194197403Sobrien
1942132720Skan      /// Numpunct facet id.
1943132720Skan      static locale::id			id;
194497403Sobrien
1945132720Skan      /**
1946132720Skan       *  @brief  Constructor performs initialization.
1947132720Skan       *
1948132720Skan       *  This is the constructor provided by the standard.
1949132720Skan       *
1950132720Skan       *  @param refs  Passed to the base facet class.
1951132720Skan      */
1952132720Skan      explicit
1953132720Skan      num_get(size_t __refs = 0) : facet(__refs) { }
195497403Sobrien
1955132720Skan      /**
1956132720Skan       *  @brief  Numeric parsing.
1957132720Skan       *
1958132720Skan       *  Parses the input stream into the bool @a v.  It does so by calling
1959169691Skan       *  num_get::do_get().
1960132720Skan       *
1961132720Skan       *  If ios_base::boolalpha is set, attempts to read
1962132720Skan       *  ctype<CharT>::truename() or ctype<CharT>::falsename().  Sets
1963132720Skan       *  @a v to true or false if successful.  Sets err to
1964132720Skan       *  ios_base::failbit if reading the string fails.  Sets err to
1965132720Skan       *  ios_base::eofbit if the stream is emptied.
1966132720Skan       *
1967132720Skan       *  If ios_base::boolalpha is not set, proceeds as with reading a long,
1968132720Skan       *  except if the value is 1, sets @a v to true, if the value is 0, sets
1969132720Skan       *  @a v to false, and otherwise set err to ios_base::failbit.
1970132720Skan       *
1971132720Skan       *  @param  in  Start of input stream.
1972132720Skan       *  @param  end  End of input stream.
1973132720Skan       *  @param  io  Source of locale and flags.
1974132720Skan       *  @param  err  Error flags to set.
1975132720Skan       *  @param  v  Value to format and insert.
1976132720Skan       *  @return  Iterator after reading.
1977132720Skan      */
1978132720Skan      iter_type
197997403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
198097403Sobrien	  ios_base::iostate& __err, bool& __v) const
198197403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
198297403Sobrien
1983132720Skan      //@{
1984132720Skan      /**
1985132720Skan       *  @brief  Numeric parsing.
1986132720Skan       *
1987132720Skan       *  Parses the input stream into the integral variable @a v.  It does so
1988169691Skan       *  by calling num_get::do_get().
1989132720Skan       *
1990132720Skan       *  Parsing is affected by the flag settings in @a io.
1991132720Skan       *
1992132720Skan       *  The basic parse is affected by the value of io.flags() &
1993132720Skan       *  ios_base::basefield.  If equal to ios_base::oct, parses like the
1994132720Skan       *  scanf %o specifier.  Else if equal to ios_base::hex, parses like %X
1995132720Skan       *  specifier.  Else if basefield equal to 0, parses like the %i
1996132720Skan       *  specifier.  Otherwise, parses like %d for signed and %u for unsigned
1997132720Skan       *  types.  The matching type length modifier is also used.
1998132720Skan       *
1999132720Skan       *  Digit grouping is intrepreted according to numpunct::grouping() and
2000132720Skan       *  numpunct::thousands_sep().  If the pattern of digit groups isn't
2001132720Skan       *  consistent, sets err to ios_base::failbit.
2002132720Skan       *
2003132720Skan       *  If parsing the string yields a valid value for @a v, @a v is set.
2004132720Skan       *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
2005132720Skan       *  Sets err to ios_base::eofbit if the stream is emptied.
2006132720Skan       *
2007132720Skan       *  @param  in  Start of input stream.
2008132720Skan       *  @param  end  End of input stream.
2009132720Skan       *  @param  io  Source of locale and flags.
2010132720Skan       *  @param  err  Error flags to set.
2011132720Skan       *  @param  v  Value to format and insert.
2012132720Skan       *  @return  Iterator after reading.
2013132720Skan      */
201497403Sobrien      iter_type
2015132720Skan      get(iter_type __in, iter_type __end, ios_base& __io,
201697403Sobrien	  ios_base::iostate& __err, long& __v) const
201797403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
201897403Sobrien
2019132720Skan      iter_type
202097403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
202197403Sobrien	  ios_base::iostate& __err, unsigned short& __v) const
202297403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
202397403Sobrien
2024132720Skan      iter_type
202597403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
202697403Sobrien	  ios_base::iostate& __err, unsigned int& __v)   const
202797403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
202897403Sobrien
2029132720Skan      iter_type
203097403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
203197403Sobrien	  ios_base::iostate& __err, unsigned long& __v)  const
203297403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
203397403Sobrien
2034132720Skan#ifdef _GLIBCXX_USE_LONG_LONG
2035132720Skan      iter_type
203697403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
203797403Sobrien	  ios_base::iostate& __err, long long& __v) const
203897403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
203997403Sobrien
2040132720Skan      iter_type
204197403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
204297403Sobrien	  ios_base::iostate& __err, unsigned long long& __v)  const
204397403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
204497403Sobrien#endif
2045132720Skan      //@}
204697403Sobrien
2047132720Skan      //@{
2048132720Skan      /**
2049132720Skan       *  @brief  Numeric parsing.
2050132720Skan       *
2051132720Skan       *  Parses the input stream into the integral variable @a v.  It does so
2052169691Skan       *  by calling num_get::do_get().
2053132720Skan       *
2054132720Skan       *  The input characters are parsed like the scanf %g specifier.  The
2055132720Skan       *  matching type length modifier is also used.
2056132720Skan       *
2057132720Skan       *  The decimal point character used is numpunct::decimal_point().
2058132720Skan       *  Digit grouping is intrepreted according to numpunct::grouping() and
2059132720Skan       *  numpunct::thousands_sep().  If the pattern of digit groups isn't
2060132720Skan       *  consistent, sets err to ios_base::failbit.
2061132720Skan       *
2062132720Skan       *  If parsing the string yields a valid value for @a v, @a v is set.
2063132720Skan       *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
2064132720Skan       *  Sets err to ios_base::eofbit if the stream is emptied.
2065132720Skan       *
2066132720Skan       *  @param  in  Start of input stream.
2067132720Skan       *  @param  end  End of input stream.
2068132720Skan       *  @param  io  Source of locale and flags.
2069132720Skan       *  @param  err  Error flags to set.
2070132720Skan       *  @param  v  Value to format and insert.
2071132720Skan       *  @return  Iterator after reading.
2072132720Skan      */
2073132720Skan      iter_type
207497403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
207597403Sobrien	  ios_base::iostate& __err, float& __v) const
207697403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
207797403Sobrien
2078132720Skan      iter_type
207997403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
208097403Sobrien	  ios_base::iostate& __err, double& __v) const
208197403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
208297403Sobrien
2083132720Skan      iter_type
208497403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
208597403Sobrien	  ios_base::iostate& __err, long double& __v) const
208697403Sobrien      { return this->do_get(__in, __end, __io, __err, __v); }
2087132720Skan      //@}
208897403Sobrien
2089132720Skan      /**
2090132720Skan       *  @brief  Numeric parsing.
2091132720Skan       *
2092132720Skan       *  Parses the input stream into the pointer variable @a v.  It does so
2093169691Skan       *  by calling num_get::do_get().
2094132720Skan       *
2095132720Skan       *  The input characters are parsed like the scanf %p specifier.
2096132720Skan       *
2097132720Skan       *  Digit grouping is intrepreted according to numpunct::grouping() and
2098132720Skan       *  numpunct::thousands_sep().  If the pattern of digit groups isn't
2099132720Skan       *  consistent, sets err to ios_base::failbit.
2100132720Skan       *
2101132720Skan       *  Note that the digit grouping effect for pointers is a bit ambiguous
2102132720Skan       *  in the standard and shouldn't be relied on.  See DR 344.
2103132720Skan       *
2104132720Skan       *  If parsing the string yields a valid value for @a v, @a v is set.
2105132720Skan       *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
2106132720Skan       *  Sets err to ios_base::eofbit if the stream is emptied.
2107132720Skan       *
2108132720Skan       *  @param  in  Start of input stream.
2109132720Skan       *  @param  end  End of input stream.
2110132720Skan       *  @param  io  Source of locale and flags.
2111132720Skan       *  @param  err  Error flags to set.
2112132720Skan       *  @param  v  Value to format and insert.
2113132720Skan       *  @return  Iterator after reading.
2114132720Skan      */
2115132720Skan      iter_type
211697403Sobrien      get(iter_type __in, iter_type __end, ios_base& __io,
211797403Sobrien	  ios_base::iostate& __err, void*& __v) const
2118132720Skan      { return this->do_get(__in, __end, __io, __err, __v); }
211997403Sobrien
212097403Sobrien    protected:
2121132720Skan      /// Destructor.
212297403Sobrien      virtual ~num_get() { }
212397403Sobrien
2124132720Skan      iter_type
2125132720Skan      _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
212697403Sobrien		       string& __xtrc) const;
212797403Sobrien
2128132720Skan      template<typename _ValueT>
2129132720Skan        iter_type
2130132720Skan        _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
2131132720Skan		       _ValueT& __v) const;
213297403Sobrien
2133169691Skan      template<typename _CharT2>
2134169691Skan      typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type
2135169691Skan        _M_find(const _CharT2*, size_t __len, _CharT2 __c) const
2136169691Skan        {
2137169691Skan	  int __ret = -1;
2138169691Skan	  if (__len <= 10)
2139169691Skan	    {
2140169691Skan	      if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len))
2141169691Skan		__ret = __c - _CharT2('0');
2142169691Skan	    }
2143169691Skan	  else
2144169691Skan	    {
2145169691Skan	      if (__c >= _CharT2('0') && __c <= _CharT2('9'))
2146169691Skan		__ret = __c - _CharT2('0');
2147169691Skan	      else if (__c >= _CharT2('a') && __c <= _CharT2('f'))
2148169691Skan		__ret = 10 + (__c - _CharT2('a'));
2149169691Skan	      else if (__c >= _CharT2('A') && __c <= _CharT2('F'))
2150169691Skan		__ret = 10 + (__c - _CharT2('A'));
2151169691Skan	    }
2152169691Skan	  return __ret;
2153169691Skan	}
2154169691Skan
2155169691Skan      template<typename _CharT2>
2156169691Skan      typename __gnu_cxx::__enable_if<!__is_char<_CharT2>::__value,
2157169691Skan				      int>::__type
2158169691Skan        _M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const
2159169691Skan        {
2160169691Skan	  int __ret = -1;
2161169691Skan	  const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c);
2162169691Skan	  if (__q)
2163169691Skan	    {
2164169691Skan	      __ret = __q - __zero;
2165169691Skan	      if (__ret > 15)
2166169691Skan		__ret -= 6;
2167169691Skan	    }
2168169691Skan	  return __ret;
2169169691Skan	}
2170169691Skan
2171132720Skan      //@{
2172132720Skan      /**
2173132720Skan       *  @brief  Numeric parsing.
2174132720Skan       *
2175132720Skan       *  Parses the input stream into the variable @a v.  This function is a
2176132720Skan       *  hook for derived classes to change the value returned.  @see get()
2177132720Skan       *  for more details.
2178132720Skan       *
2179132720Skan       *  @param  in  Start of input stream.
2180132720Skan       *  @param  end  End of input stream.
2181132720Skan       *  @param  io  Source of locale and flags.
2182132720Skan       *  @param  err  Error flags to set.
2183132720Skan       *  @param  v  Value to format and insert.
2184132720Skan       *  @return  Iterator after reading.
2185132720Skan      */
2186132720Skan      virtual iter_type
218797403Sobrien      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
218897403Sobrien
2189102782Skan
2190132720Skan      virtual iter_type
219197403Sobrien      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
219297403Sobrien
2193132720Skan      virtual iter_type
2194132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
219597403Sobrien	      unsigned short&) const;
219697403Sobrien
2197132720Skan      virtual iter_type
2198132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
219997403Sobrien	     unsigned int&) const;
220097403Sobrien
2201132720Skan      virtual iter_type
2202132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
220397403Sobrien	     unsigned long&) const;
220497403Sobrien
2205132720Skan#ifdef _GLIBCXX_USE_LONG_LONG
2206132720Skan      virtual iter_type
2207132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
220897403Sobrien	     long long&) const;
220997403Sobrien
2210132720Skan      virtual iter_type
2211132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
221297403Sobrien	     unsigned long long&) const;
221397403Sobrien#endif
221497403Sobrien
2215132720Skan      virtual iter_type
2216132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
221797403Sobrien	     float&) const;
221897403Sobrien
2219132720Skan      virtual iter_type
2220132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
222197403Sobrien	     double&) const;
222297403Sobrien
2223169691Skan      // XXX GLIBCXX_ABI Deprecated
2224169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
2225132720Skan      virtual iter_type
2226169691Skan      __do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
2227169691Skan	       double&) const;
2228169691Skan#else
2229169691Skan      virtual iter_type
2230132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
223197403Sobrien	     long double&) const;
2232169691Skan#endif
223397403Sobrien
2234132720Skan      virtual iter_type
2235132720Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
223697403Sobrien	     void*&) const;
2237169691Skan
2238169691Skan      // XXX GLIBCXX_ABI Deprecated
2239169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
2240169691Skan      virtual iter_type
2241169691Skan      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
2242169691Skan	     long double&) const;
2243169691Skan#endif
2244132720Skan      //@}
224597403Sobrien    };
224697403Sobrien
224797403Sobrien  template<typename _CharT, typename _InIter>
224897403Sobrien    locale::id num_get<_CharT, _InIter>::id;
224997403Sobrien
2250102782Skan
2251132720Skan  /**
2252132720Skan   *  @brief  Facet for converting numbers to strings.
2253132720Skan   *
2254132720Skan   *  This facet encapsulates the code to convert a number to a string.  It is
2255132720Skan   *  used by the ostream numeric insertion operators.
2256132720Skan   *
2257132720Skan   *  The num_put template uses protected virtual functions to provide the
2258132720Skan   *  actual results.  The public accessors forward the call to the virtual
2259132720Skan   *  functions.  These virtual functions are hooks for developers to
2260132720Skan   *  implement the behavior they require from the num_put facet.
2261132720Skan  */
226297403Sobrien  template<typename _CharT, typename _OutIter>
2263132720Skan    class num_put : public locale::facet
226497403Sobrien    {
226597403Sobrien    public:
226697403Sobrien      // Types:
2267132720Skan      //@{
2268132720Skan      /// Public typedefs
2269132720Skan      typedef _CharT		char_type;
2270132720Skan      typedef _OutIter		iter_type;
2271132720Skan      //@}
2272132720Skan
2273132720Skan      /// Numpunct facet id.
227497403Sobrien      static locale::id		id;
227597403Sobrien
2276132720Skan      /**
2277132720Skan       *  @brief  Constructor performs initialization.
2278132720Skan       *
2279132720Skan       *  This is the constructor provided by the standard.
2280132720Skan       *
2281132720Skan       *  @param refs  Passed to the base facet class.
2282132720Skan      */
2283132720Skan      explicit
2284132720Skan      num_put(size_t __refs = 0) : facet(__refs) { }
228597403Sobrien
2286132720Skan      /**
2287132720Skan       *  @brief  Numeric formatting.
2288132720Skan       *
2289132720Skan       *  Formats the boolean @a v and inserts it into a stream.  It does so
2290132720Skan       *  by calling num_put::do_put().
2291132720Skan       *
2292132720Skan       *  If ios_base::boolalpha is set, writes ctype<CharT>::truename() or
2293132720Skan       *  ctype<CharT>::falsename().  Otherwise formats @a v as an int.
2294132720Skan       *
2295132720Skan       *  @param  s  Stream to write to.
2296132720Skan       *  @param  io  Source of locale and flags.
2297132720Skan       *  @param  fill  Char_type to use for filling.
2298132720Skan       *  @param  v  Value to format and insert.
2299132720Skan       *  @return  Iterator after writing.
2300132720Skan      */
2301132720Skan      iter_type
230297403Sobrien      put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
230397403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
230497403Sobrien
2305132720Skan      //@{
2306132720Skan      /**
2307132720Skan       *  @brief  Numeric formatting.
2308132720Skan       *
2309132720Skan       *  Formats the integral value @a v and inserts it into a
2310132720Skan       *  stream.  It does so by calling num_put::do_put().
2311132720Skan       *
2312132720Skan       *  Formatting is affected by the flag settings in @a io.
2313132720Skan       *
2314132720Skan       *  The basic format is affected by the value of io.flags() &
2315132720Skan       *  ios_base::basefield.  If equal to ios_base::oct, formats like the
2316132720Skan       *  printf %o specifier.  Else if equal to ios_base::hex, formats like
2317132720Skan       *  %x or %X with ios_base::uppercase unset or set respectively.
2318132720Skan       *  Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu
2319132720Skan       *  for unsigned values.  Note that if both oct and hex are set, neither
2320132720Skan       *  will take effect.
2321132720Skan       *
2322132720Skan       *  If ios_base::showpos is set, '+' is output before positive values.
2323132720Skan       *  If ios_base::showbase is set, '0' precedes octal values (except 0)
2324132720Skan       *  and '0[xX]' precedes hex values.
2325132720Skan       *
2326132720Skan       *  Thousands separators are inserted according to numpunct::grouping()
2327132720Skan       *  and numpunct::thousands_sep().  The decimal point character used is
2328132720Skan       *  numpunct::decimal_point().
2329132720Skan       *
2330132720Skan       *  If io.width() is non-zero, enough @a fill characters are inserted to
2331132720Skan       *  make the result at least that wide.  If
2332132720Skan       *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
2333132720Skan       *  padded at the end.  If ios_base::internal, then padding occurs
2334132720Skan       *  immediately after either a '+' or '-' or after '0x' or '0X'.
2335132720Skan       *  Otherwise, padding occurs at the beginning.
2336132720Skan       *
2337132720Skan       *  @param  s  Stream to write to.
2338132720Skan       *  @param  io  Source of locale and flags.
2339132720Skan       *  @param  fill  Char_type to use for filling.
2340132720Skan       *  @param  v  Value to format and insert.
2341132720Skan       *  @return  Iterator after writing.
2342132720Skan      */
2343132720Skan      iter_type
234497403Sobrien      put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
234597403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
234697403Sobrien
2347132720Skan      iter_type
2348132720Skan      put(iter_type __s, ios_base& __f, char_type __fill,
234997403Sobrien	  unsigned long __v) const
235097403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
235197403Sobrien
2352132720Skan#ifdef _GLIBCXX_USE_LONG_LONG
2353132720Skan      iter_type
235497403Sobrien      put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
235597403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
235697403Sobrien
2357132720Skan      iter_type
2358132720Skan      put(iter_type __s, ios_base& __f, char_type __fill,
235997403Sobrien	  unsigned long long __v) const
236097403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
236197403Sobrien#endif
2362132720Skan      //@}
236397403Sobrien
2364132720Skan      //@{
2365132720Skan      /**
2366132720Skan       *  @brief  Numeric formatting.
2367132720Skan       *
2368132720Skan       *  Formats the floating point value @a v and inserts it into a stream.
2369132720Skan       *  It does so by calling num_put::do_put().
2370132720Skan       *
2371132720Skan       *  Formatting is affected by the flag settings in @a io.
2372132720Skan       *
2373132720Skan       *  The basic format is affected by the value of io.flags() &
2374132720Skan       *  ios_base::floatfield.  If equal to ios_base::fixed, formats like the
2375132720Skan       *  printf %f specifier.  Else if equal to ios_base::scientific, formats
2376132720Skan       *  like %e or %E with ios_base::uppercase unset or set respectively.
2377132720Skan       *  Otherwise, formats like %g or %G depending on uppercase.  Note that
2378132720Skan       *  if both fixed and scientific are set, the effect will also be like
2379132720Skan       *  %g or %G.
2380132720Skan       *
2381132720Skan       *  The output precision is given by io.precision().  This precision is
2382132720Skan       *  capped at numeric_limits::digits10 + 2 (different for double and
2383132720Skan       *  long double).  The default precision is 6.
2384132720Skan       *
2385132720Skan       *  If ios_base::showpos is set, '+' is output before positive values.
2386132720Skan       *  If ios_base::showpoint is set, a decimal point will always be
2387132720Skan       *  output.
2388132720Skan       *
2389132720Skan       *  Thousands separators are inserted according to numpunct::grouping()
2390132720Skan       *  and numpunct::thousands_sep().  The decimal point character used is
2391132720Skan       *  numpunct::decimal_point().
2392132720Skan       *
2393132720Skan       *  If io.width() is non-zero, enough @a fill characters are inserted to
2394132720Skan       *  make the result at least that wide.  If
2395132720Skan       *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
2396132720Skan       *  padded at the end.  If ios_base::internal, then padding occurs
2397132720Skan       *  immediately after either a '+' or '-' or after '0x' or '0X'.
2398132720Skan       *  Otherwise, padding occurs at the beginning.
2399132720Skan       *
2400132720Skan       *  @param  s  Stream to write to.
2401132720Skan       *  @param  io  Source of locale and flags.
2402132720Skan       *  @param  fill  Char_type to use for filling.
2403132720Skan       *  @param  v  Value to format and insert.
2404132720Skan       *  @return  Iterator after writing.
2405132720Skan      */
2406132720Skan      iter_type
240797403Sobrien      put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
240897403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
240997403Sobrien
2410132720Skan      iter_type
2411132720Skan      put(iter_type __s, ios_base& __f, char_type __fill,
241297403Sobrien	  long double __v) const
241397403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
2414132720Skan      //@}
241597403Sobrien
2416132720Skan      /**
2417132720Skan       *  @brief  Numeric formatting.
2418132720Skan       *
2419132720Skan       *  Formats the pointer value @a v and inserts it into a stream.  It
2420132720Skan       *  does so by calling num_put::do_put().
2421132720Skan       *
2422132720Skan       *  This function formats @a v as an unsigned long with ios_base::hex
2423132720Skan       *  and ios_base::showbase set.
2424132720Skan       *
2425132720Skan       *  @param  s  Stream to write to.
2426132720Skan       *  @param  io  Source of locale and flags.
2427132720Skan       *  @param  fill  Char_type to use for filling.
2428132720Skan       *  @param  v  Value to format and insert.
2429132720Skan       *  @return  Iterator after writing.
2430132720Skan      */
2431132720Skan      iter_type
2432132720Skan      put(iter_type __s, ios_base& __f, char_type __fill,
243397403Sobrien	  const void* __v) const
243497403Sobrien      { return this->do_put(__s, __f, __fill, __v); }
243597403Sobrien
243697403Sobrien    protected:
243797403Sobrien      template<typename _ValueT>
243897403Sobrien        iter_type
2439132720Skan        _M_insert_float(iter_type, ios_base& __io, char_type __fill,
2440132720Skan			char __mod, _ValueT __v) const;
244197403Sobrien
2442117397Skan      void
2443132720Skan      _M_group_float(const char* __grouping, size_t __grouping_size,
2444132720Skan		     char_type __sep, const char_type* __p, char_type* __new,
2445132720Skan		     char_type* __cs, int& __len) const;
2446117397Skan
244797403Sobrien      template<typename _ValueT>
244897403Sobrien        iter_type
2449132720Skan        _M_insert_int(iter_type, ios_base& __io, char_type __fill,
2450132720Skan		      _ValueT __v) const;
2451117397Skan
2452117397Skan      void
2453132720Skan      _M_group_int(const char* __grouping, size_t __grouping_size,
2454132720Skan		   char_type __sep, ios_base& __io, char_type* __new,
2455132720Skan		   char_type* __cs, int& __len) const;
2456117397Skan
2457117397Skan      void
2458132720Skan      _M_pad(char_type __fill, streamsize __w, ios_base& __io,
2459117397Skan	     char_type* __new, const char_type* __cs, int& __len) const;
2460117397Skan
2461132720Skan      /// Destructor.
2462132720Skan      virtual
246397403Sobrien      ~num_put() { };
246497403Sobrien
2465132720Skan      //@{
2466132720Skan      /**
2467132720Skan       *  @brief  Numeric formatting.
2468132720Skan       *
2469132720Skan       *  These functions do the work of formatting numeric values and
2470132720Skan       *  inserting them into a stream. This function is a hook for derived
2471132720Skan       *  classes to change the value returned.
2472132720Skan       *
2473132720Skan       *  @param  s  Stream to write to.
2474132720Skan       *  @param  io  Source of locale and flags.
2475132720Skan       *  @param  fill  Char_type to use for filling.
2476132720Skan       *  @param  v  Value to format and insert.
2477132720Skan       *  @return  Iterator after writing.
2478132720Skan      */
2479132720Skan      virtual iter_type
248097403Sobrien      do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
248197403Sobrien
2482132720Skan      virtual iter_type
248397403Sobrien      do_put(iter_type, ios_base&, char_type __fill, long __v) const;
248497403Sobrien
2485132720Skan      virtual iter_type
248697403Sobrien      do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
248797403Sobrien
2488132720Skan#ifdef _GLIBCXX_USE_LONG_LONG
2489132720Skan      virtual iter_type
249097403Sobrien      do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
249197403Sobrien
249297403Sobrien      virtual iter_type
249397403Sobrien      do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
249497403Sobrien#endif
249597403Sobrien
2496132720Skan      virtual iter_type
249797403Sobrien      do_put(iter_type, ios_base&, char_type __fill, double __v) const;
249897403Sobrien
2499169691Skan      // XXX GLIBCXX_ABI Deprecated
2500169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
2501132720Skan      virtual iter_type
2502169691Skan      __do_put(iter_type, ios_base&, char_type __fill, double __v) const;
2503169691Skan#else
2504169691Skan      virtual iter_type
250597403Sobrien      do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
2506169691Skan#endif
250797403Sobrien
2508132720Skan      virtual iter_type
250997403Sobrien      do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
2510169691Skan
2511169691Skan      // XXX GLIBCXX_ABI Deprecated
2512169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
2513169691Skan      virtual iter_type
2514169691Skan      do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
2515169691Skan#endif
2516132720Skan      //@}
251797403Sobrien    };
251897403Sobrien
251997403Sobrien  template <typename _CharT, typename _OutIter>
252097403Sobrien    locale::id num_put<_CharT, _OutIter>::id;
252197403Sobrien
2522169691Skan_GLIBCXX_END_LDBL_NAMESPACE
252397403Sobrien
2524132720Skan  /**
2525132720Skan   *  @brief  Facet for localized string comparison.
2526132720Skan   *
2527132720Skan   *  This facet encapsulates the code to compare strings in a localized
2528132720Skan   *  manner.
2529132720Skan   *
2530132720Skan   *  The collate template uses protected virtual functions to provide
2531132720Skan   *  the actual results.  The public accessors forward the call to
2532132720Skan   *  the virtual functions.  These virtual functions are hooks for
2533132720Skan   *  developers to implement the behavior they require from the
2534132720Skan   *  collate facet.
2535132720Skan  */
253697403Sobrien  template<typename _CharT>
253797403Sobrien    class collate : public locale::facet
253897403Sobrien    {
253997403Sobrien    public:
254097403Sobrien      // Types:
2541132720Skan      //@{
2542132720Skan      /// Public typedefs
2543132720Skan      typedef _CharT			char_type;
2544132720Skan      typedef basic_string<_CharT>	string_type;
2545132720Skan      //@}
254697403Sobrien
254797403Sobrien    protected:
254897403Sobrien      // Underlying "C" library locale information saved from
254997403Sobrien      // initialization, needed by collate_byname as well.
255097403Sobrien      __c_locale			_M_c_locale_collate;
2551132720Skan
255297403Sobrien    public:
2553132720Skan      /// Numpunct facet id.
2554132720Skan      static locale::id			id;
255597403Sobrien
2556132720Skan      /**
2557132720Skan       *  @brief  Constructor performs initialization.
2558132720Skan       *
2559132720Skan       *  This is the constructor provided by the standard.
2560132720Skan       *
2561132720Skan       *  @param refs  Passed to the base facet class.
2562132720Skan      */
2563132720Skan      explicit
256497403Sobrien      collate(size_t __refs = 0)
2565132720Skan      : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
2566132720Skan      { }
256797403Sobrien
2568132720Skan      /**
2569132720Skan       *  @brief  Internal constructor. Not for general use.
2570132720Skan       *
2571132720Skan       *  This is a constructor for use by the library itself to set up new
2572132720Skan       *  locales.
2573132720Skan       *
2574132720Skan       *  @param cloc  The "C" locale.
2575132720Skan       *  @param refs  Passed to the base facet class.
2576132720Skan      */
2577132720Skan      explicit
2578132720Skan      collate(__c_locale __cloc, size_t __refs = 0)
2579132720Skan      : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
2580132720Skan      { }
258197403Sobrien
2582132720Skan      /**
2583132720Skan       *  @brief  Compare two strings.
2584132720Skan       *
2585132720Skan       *  This function compares two strings and returns the result by calling
2586132720Skan       *  collate::do_compare().
2587132720Skan       *
2588132720Skan       *  @param lo1  Start of string 1.
2589132720Skan       *  @param hi1  End of string 1.
2590132720Skan       *  @param lo2  Start of string 2.
2591132720Skan       *  @param hi2  End of string 2.
2592132720Skan       *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
2593132720Skan      */
2594132720Skan      int
259597403Sobrien      compare(const _CharT* __lo1, const _CharT* __hi1,
259697403Sobrien	      const _CharT* __lo2, const _CharT* __hi2) const
259797403Sobrien      { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
259897403Sobrien
2599132720Skan      /**
2600132720Skan       *  @brief  Transform string to comparable form.
2601132720Skan       *
2602132720Skan       *  This function is a wrapper for strxfrm functionality.  It takes the
2603132720Skan       *  input string and returns a modified string that can be directly
2604132720Skan       *  compared to other transformed strings.  In the "C" locale, this
2605132720Skan       *  function just returns a copy of the input string.  In some other
2606132720Skan       *  locales, it may replace two chars with one, change a char for
2607132720Skan       *  another, etc.  It does so by returning collate::do_transform().
2608132720Skan       *
2609132720Skan       *  @param lo  Start of string.
2610132720Skan       *  @param hi  End of string.
2611132720Skan       *  @return  Transformed string_type.
2612132720Skan      */
2613132720Skan      string_type
261497403Sobrien      transform(const _CharT* __lo, const _CharT* __hi) const
261597403Sobrien      { return this->do_transform(__lo, __hi); }
261697403Sobrien
2617132720Skan      /**
2618132720Skan       *  @brief  Return hash of a string.
2619132720Skan       *
2620132720Skan       *  This function computes and returns a hash on the input string.  It
2621132720Skan       *  does so by returning collate::do_hash().
2622132720Skan       *
2623132720Skan       *  @param lo  Start of string.
2624132720Skan       *  @param hi  End of string.
2625132720Skan       *  @return  Hash value.
2626132720Skan      */
2627132720Skan      long
262897403Sobrien      hash(const _CharT* __lo, const _CharT* __hi) const
262997403Sobrien      { return this->do_hash(__lo, __hi); }
2630132720Skan
263197403Sobrien      // Used to abstract out _CharT bits in virtual member functions, below.
263297403Sobrien      int
263397403Sobrien      _M_compare(const _CharT*, const _CharT*) const;
263497403Sobrien
263597403Sobrien      size_t
263697403Sobrien      _M_transform(_CharT*, const _CharT*, size_t) const;
263797403Sobrien
263897403Sobrien  protected:
2639132720Skan      /// Destructor.
264097403Sobrien      virtual
2641132720Skan      ~collate()
2642107606Sobrien      { _S_destroy_c_locale(_M_c_locale_collate); }
264397403Sobrien
2644132720Skan      /**
2645132720Skan       *  @brief  Compare two strings.
2646132720Skan       *
2647132720Skan       *  This function is a hook for derived classes to change the value
2648132720Skan       *  returned.  @see compare().
2649132720Skan       *
2650132720Skan       *  @param lo1  Start of string 1.
2651132720Skan       *  @param hi1  End of string 1.
2652132720Skan       *  @param lo2  Start of string 2.
2653132720Skan       *  @param hi2  End of string 2.
2654132720Skan       *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
2655132720Skan      */
2656132720Skan      virtual int
265797403Sobrien      do_compare(const _CharT* __lo1, const _CharT* __hi1,
265897403Sobrien		 const _CharT* __lo2, const _CharT* __hi2) const;
265997403Sobrien
2660132720Skan      /**
2661132720Skan       *  @brief  Transform string to comparable form.
2662132720Skan       *
2663132720Skan       *  This function is a hook for derived classes to change the value
2664132720Skan       *  returned.
2665132720Skan       *
2666132720Skan       *  @param lo1  Start of string 1.
2667132720Skan       *  @param hi1  End of string 1.
2668132720Skan       *  @param lo2  Start of string 2.
2669132720Skan       *  @param hi2  End of string 2.
2670132720Skan       *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
2671132720Skan      */
2672132720Skan      virtual string_type
267397403Sobrien      do_transform(const _CharT* __lo, const _CharT* __hi) const;
267497403Sobrien
2675132720Skan      /**
2676132720Skan       *  @brief  Return hash of a string.
2677132720Skan       *
2678132720Skan       *  This function computes and returns a hash on the input string.  This
2679132720Skan       *  function is a hook for derived classes to change the value returned.
2680132720Skan       *
2681132720Skan       *  @param lo  Start of string.
2682132720Skan       *  @param hi  End of string.
2683132720Skan       *  @return  Hash value.
2684132720Skan      */
2685132720Skan      virtual long
268697403Sobrien      do_hash(const _CharT* __lo, const _CharT* __hi) const;
268797403Sobrien    };
268897403Sobrien
268997403Sobrien  template<typename _CharT>
269097403Sobrien    locale::id collate<_CharT>::id;
269197403Sobrien
269297403Sobrien  // Specializations.
269397403Sobrien  template<>
2694132720Skan    int
269597403Sobrien    collate<char>::_M_compare(const char*, const char*) const;
269697403Sobrien
269797403Sobrien  template<>
269897403Sobrien    size_t
269997403Sobrien    collate<char>::_M_transform(char*, const char*, size_t) const;
270097403Sobrien
2701132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
270297403Sobrien  template<>
2703132720Skan    int
270497403Sobrien    collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
270597403Sobrien
270697403Sobrien  template<>
270797403Sobrien    size_t
270897403Sobrien    collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
270997403Sobrien#endif
271097403Sobrien
2711169691Skan  /// @brief  class collate_byname [22.2.4.2].
271297403Sobrien  template<typename _CharT>
271397403Sobrien    class collate_byname : public collate<_CharT>
271497403Sobrien    {
271597403Sobrien    public:
2716132720Skan      //@{
2717132720Skan      /// Public typedefs
271897403Sobrien      typedef _CharT               char_type;
271997403Sobrien      typedef basic_string<_CharT> string_type;
2720132720Skan      //@}
272197403Sobrien
2722132720Skan      explicit
272397403Sobrien      collate_byname(const char* __s, size_t __refs = 0)
2724132720Skan      : collate<_CharT>(__refs)
2725132720Skan      {
2726132720Skan	if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
2727132720Skan	  {
2728132720Skan	    this->_S_destroy_c_locale(this->_M_c_locale_collate);
2729132720Skan	    this->_S_create_c_locale(this->_M_c_locale_collate, __s);
2730132720Skan	  }
273197403Sobrien      }
273297403Sobrien
273397403Sobrien    protected:
2734132720Skan      virtual
273597403Sobrien      ~collate_byname() { }
273697403Sobrien    };
273797403Sobrien
273897403Sobrien
2739132720Skan  /**
2740132720Skan   *  @brief  Time format ordering data.
2741132720Skan   *
2742132720Skan   *  This class provides an enum representing different orderings of day,
2743132720Skan   *  month, and year.
2744132720Skan  */
274597403Sobrien  class time_base
274697403Sobrien  {
274797403Sobrien  public:
274897403Sobrien    enum dateorder { no_order, dmy, mdy, ymd, ydm };
274997403Sobrien  };
275097403Sobrien
275197403Sobrien  template<typename _CharT>
2752132720Skan    struct __timepunct_cache : public locale::facet
275397403Sobrien    {
275497403Sobrien      // List of all known timezones, with GMT first.
2755132720Skan      static const _CharT*		_S_timezones[14];
275697403Sobrien
2757132720Skan      const _CharT*			_M_date_format;
2758132720Skan      const _CharT*			_M_date_era_format;
2759132720Skan      const _CharT*			_M_time_format;
2760132720Skan      const _CharT*			_M_time_era_format;
276197403Sobrien      const _CharT*			_M_date_time_format;
276297403Sobrien      const _CharT*			_M_date_time_era_format;
2763132720Skan      const _CharT*			_M_am;
2764132720Skan      const _CharT*			_M_pm;
276597403Sobrien      const _CharT*			_M_am_pm_format;
276697403Sobrien
276797403Sobrien      // Day names, starting with "C"'s Sunday.
2768132720Skan      const _CharT*			_M_day1;
2769132720Skan      const _CharT*			_M_day2;
2770132720Skan      const _CharT*			_M_day3;
2771132720Skan      const _CharT*			_M_day4;
2772132720Skan      const _CharT*			_M_day5;
2773132720Skan      const _CharT*			_M_day6;
2774132720Skan      const _CharT*			_M_day7;
277597403Sobrien
277697403Sobrien      // Abbreviated day names, starting with "C"'s Sun.
2777132720Skan      const _CharT*			_M_aday1;
2778132720Skan      const _CharT*			_M_aday2;
2779132720Skan      const _CharT*			_M_aday3;
2780132720Skan      const _CharT*			_M_aday4;
2781132720Skan      const _CharT*			_M_aday5;
2782132720Skan      const _CharT*			_M_aday6;
2783132720Skan      const _CharT*			_M_aday7;
278497403Sobrien
278597403Sobrien      // Month names, starting with "C"'s January.
2786132720Skan      const _CharT*			_M_month01;
2787132720Skan      const _CharT*			_M_month02;
2788132720Skan      const _CharT*			_M_month03;
2789132720Skan      const _CharT*			_M_month04;
2790132720Skan      const _CharT*			_M_month05;
2791132720Skan      const _CharT*			_M_month06;
2792132720Skan      const _CharT*			_M_month07;
2793132720Skan      const _CharT*			_M_month08;
2794132720Skan      const _CharT*			_M_month09;
2795132720Skan      const _CharT*			_M_month10;
2796132720Skan      const _CharT*			_M_month11;
2797132720Skan      const _CharT*			_M_month12;
279897403Sobrien
279997403Sobrien      // Abbreviated month names, starting with "C"'s Jan.
2800132720Skan      const _CharT*			_M_amonth01;
2801132720Skan      const _CharT*			_M_amonth02;
2802132720Skan      const _CharT*			_M_amonth03;
2803132720Skan      const _CharT*			_M_amonth04;
2804132720Skan      const _CharT*			_M_amonth05;
2805132720Skan      const _CharT*			_M_amonth06;
2806132720Skan      const _CharT*			_M_amonth07;
2807132720Skan      const _CharT*			_M_amonth08;
2808132720Skan      const _CharT*			_M_amonth09;
2809132720Skan      const _CharT*			_M_amonth10;
2810132720Skan      const _CharT*			_M_amonth11;
2811132720Skan      const _CharT*			_M_amonth12;
281297403Sobrien
2813132720Skan      bool				_M_allocated;
2814132720Skan
2815132720Skan      __timepunct_cache(size_t __refs = 0) : facet(__refs),
2816132720Skan      _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL),
2817132720Skan      _M_time_era_format(NULL), _M_date_time_format(NULL),
2818132720Skan      _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL),
2819132720Skan      _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL),
2820132720Skan      _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL),
2821132720Skan      _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL),
2822132720Skan      _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL),
2823132720Skan      _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL),
2824132720Skan      _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL),
2825132720Skan      _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL),
2826132720Skan      _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL),
2827132720Skan      _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL),
2828132720Skan      _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL),
2829132720Skan      _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false)
2830132720Skan      { }
2831132720Skan
2832132720Skan      ~__timepunct_cache();
2833132720Skan
2834132720Skan      void
2835132720Skan      _M_cache(const locale& __loc);
2836132720Skan
2837132720Skan    private:
2838132720Skan      __timepunct_cache&
2839132720Skan      operator=(const __timepunct_cache&);
2840132720Skan
2841132720Skan      explicit
2842132720Skan      __timepunct_cache(const __timepunct_cache&);
2843132720Skan    };
2844132720Skan
2845132720Skan  template<typename _CharT>
2846132720Skan    __timepunct_cache<_CharT>::~__timepunct_cache()
2847132720Skan    {
2848132720Skan      if (_M_allocated)
2849132720Skan	{
2850132720Skan	  // Unused.
2851132720Skan	}
2852132720Skan    }
2853132720Skan
2854132720Skan  // Specializations.
2855132720Skan  template<>
2856132720Skan    const char*
2857132720Skan    __timepunct_cache<char>::_S_timezones[14];
2858132720Skan
2859132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
2860132720Skan  template<>
2861132720Skan    const wchar_t*
2862132720Skan    __timepunct_cache<wchar_t>::_S_timezones[14];
2863132720Skan#endif
2864132720Skan
2865132720Skan  // Generic.
2866132720Skan  template<typename _CharT>
2867132720Skan    const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];
2868132720Skan
2869132720Skan  template<typename _CharT>
2870132720Skan    class __timepunct : public locale::facet
2871132720Skan    {
287297403Sobrien    public:
2873132720Skan      // Types:
2874132720Skan      typedef _CharT			__char_type;
2875132720Skan      typedef basic_string<_CharT>	__string_type;
2876132720Skan      typedef __timepunct_cache<_CharT>	__cache_type;
2877132720Skan
2878132720Skan    protected:
2879132720Skan      __cache_type*			_M_data;
2880132720Skan      __c_locale			_M_c_locale_timepunct;
2881132720Skan      const char*			_M_name_timepunct;
2882132720Skan
2883132720Skan    public:
2884132720Skan      /// Numpunct facet id.
2885132720Skan      static locale::id			id;
2886132720Skan
2887132720Skan      explicit
2888110614Skan      __timepunct(size_t __refs = 0);
288997403Sobrien
2890132720Skan      explicit
2891132720Skan      __timepunct(__cache_type* __cache, size_t __refs = 0);
2892132720Skan
2893132720Skan      /**
2894132720Skan       *  @brief  Internal constructor. Not for general use.
2895132720Skan       *
2896132720Skan       *  This is a constructor for use by the library itself to set up new
2897132720Skan       *  locales.
2898132720Skan       *
2899132720Skan       *  @param cloc  The "C" locale.
2900132720Skan       *  @param s  The name of a locale.
2901132720Skan       *  @param refs  Passed to the base facet class.
2902132720Skan      */
2903132720Skan      explicit
2904110614Skan      __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
290597403Sobrien
2906169691Skan      // FIXME: for error checking purposes _M_put should return the return
2907169691Skan      // value of strftime/wcsftime.
290897403Sobrien      void
2909132720Skan      _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
291097403Sobrien	     const tm* __tm) const;
291197403Sobrien
291297403Sobrien      void
291397403Sobrien      _M_date_formats(const _CharT** __date) const
291497403Sobrien      {
291597403Sobrien	// Always have default first.
2916132720Skan	__date[0] = _M_data->_M_date_format;
2917132720Skan	__date[1] = _M_data->_M_date_era_format;
291897403Sobrien      }
291997403Sobrien
292097403Sobrien      void
292197403Sobrien      _M_time_formats(const _CharT** __time) const
292297403Sobrien      {
292397403Sobrien	// Always have default first.
2924132720Skan	__time[0] = _M_data->_M_time_format;
2925132720Skan	__time[1] = _M_data->_M_time_era_format;
292697403Sobrien      }
292797403Sobrien
292897403Sobrien      void
292997403Sobrien      _M_date_time_formats(const _CharT** __dt) const
293097403Sobrien      {
293197403Sobrien	// Always have default first.
2932132720Skan	__dt[0] = _M_data->_M_date_time_format;
2933132720Skan	__dt[1] = _M_data->_M_date_time_era_format;
293497403Sobrien      }
293597403Sobrien
293697403Sobrien      void
2937132720Skan      _M_am_pm_format(const _CharT* __ampm) const
2938132720Skan      { __ampm = _M_data->_M_am_pm_format; }
2939132720Skan
2940132720Skan      void
2941132720Skan      _M_am_pm(const _CharT** __ampm) const
2942132720Skan      {
2943132720Skan	__ampm[0] = _M_data->_M_am;
2944132720Skan	__ampm[1] = _M_data->_M_pm;
2945132720Skan      }
2946132720Skan
2947132720Skan      void
294897403Sobrien      _M_days(const _CharT** __days) const
2949132720Skan      {
2950132720Skan	__days[0] = _M_data->_M_day1;
2951132720Skan	__days[1] = _M_data->_M_day2;
2952132720Skan	__days[2] = _M_data->_M_day3;
2953132720Skan	__days[3] = _M_data->_M_day4;
2954132720Skan	__days[4] = _M_data->_M_day5;
2955132720Skan	__days[5] = _M_data->_M_day6;
2956132720Skan	__days[6] = _M_data->_M_day7;
295797403Sobrien      }
295897403Sobrien
295997403Sobrien      void
296097403Sobrien      _M_days_abbreviated(const _CharT** __days) const
2961132720Skan      {
2962132720Skan	__days[0] = _M_data->_M_aday1;
2963132720Skan	__days[1] = _M_data->_M_aday2;
2964132720Skan	__days[2] = _M_data->_M_aday3;
2965132720Skan	__days[3] = _M_data->_M_aday4;
2966132720Skan	__days[4] = _M_data->_M_aday5;
2967132720Skan	__days[5] = _M_data->_M_aday6;
2968132720Skan	__days[6] = _M_data->_M_aday7;
296997403Sobrien      }
297097403Sobrien
297197403Sobrien      void
297297403Sobrien      _M_months(const _CharT** __months) const
2973132720Skan      {
2974132720Skan	__months[0] = _M_data->_M_month01;
2975132720Skan	__months[1] = _M_data->_M_month02;
2976132720Skan	__months[2] = _M_data->_M_month03;
2977132720Skan	__months[3] = _M_data->_M_month04;
2978132720Skan	__months[4] = _M_data->_M_month05;
2979132720Skan	__months[5] = _M_data->_M_month06;
2980132720Skan	__months[6] = _M_data->_M_month07;
2981132720Skan	__months[7] = _M_data->_M_month08;
2982132720Skan	__months[8] = _M_data->_M_month09;
2983132720Skan	__months[9] = _M_data->_M_month10;
2984132720Skan	__months[10] = _M_data->_M_month11;
2985132720Skan	__months[11] = _M_data->_M_month12;
298697403Sobrien      }
298797403Sobrien
298897403Sobrien      void
298997403Sobrien      _M_months_abbreviated(const _CharT** __months) const
2990132720Skan      {
2991132720Skan	__months[0] = _M_data->_M_amonth01;
2992132720Skan	__months[1] = _M_data->_M_amonth02;
2993132720Skan	__months[2] = _M_data->_M_amonth03;
2994132720Skan	__months[3] = _M_data->_M_amonth04;
2995132720Skan	__months[4] = _M_data->_M_amonth05;
2996132720Skan	__months[5] = _M_data->_M_amonth06;
2997132720Skan	__months[6] = _M_data->_M_amonth07;
2998132720Skan	__months[7] = _M_data->_M_amonth08;
2999132720Skan	__months[8] = _M_data->_M_amonth09;
3000132720Skan	__months[9] = _M_data->_M_amonth10;
3001132720Skan	__months[10] = _M_data->_M_amonth11;
3002132720Skan	__months[11] = _M_data->_M_amonth12;
300397403Sobrien      }
300497403Sobrien
300597403Sobrien    protected:
3006132720Skan      virtual
3007110614Skan      ~__timepunct();
300897403Sobrien
300997403Sobrien      // For use at construction time only.
3010132720Skan      void
3011107606Sobrien      _M_initialize_timepunct(__c_locale __cloc = NULL);
301297403Sobrien    };
301397403Sobrien
301497403Sobrien  template<typename _CharT>
301597403Sobrien    locale::id __timepunct<_CharT>::id;
301697403Sobrien
301797403Sobrien  // Specializations.
3018132720Skan  template<>
301997403Sobrien    void
302097403Sobrien    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
302197403Sobrien
302297403Sobrien  template<>
302397403Sobrien    void
302497403Sobrien    __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
302597403Sobrien
3026132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
3027132720Skan  template<>
302897403Sobrien    void
302997403Sobrien    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
303097403Sobrien
303197403Sobrien  template<>
303297403Sobrien    void
3033132720Skan    __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
303497403Sobrien				 const tm*) const;
303597403Sobrien#endif
303697403Sobrien
3037169691Skan_GLIBCXX_END_NAMESPACE
3038169691Skan
3039110614Skan  // Include host and configuration specific timepunct functions.
3040110614Skan  #include <bits/time_members.h>
304197403Sobrien
3042169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
3043169691Skan
3044132720Skan  /**
3045132720Skan   *  @brief  Facet for parsing dates and times.
3046132720Skan   *
3047132720Skan   *  This facet encapsulates the code to parse and return a date or
3048132720Skan   *  time from a string.  It is used by the istream numeric
3049132720Skan   *  extraction operators.
3050132720Skan   *
3051132720Skan   *  The time_get template uses protected virtual functions to provide the
3052132720Skan   *  actual results.  The public accessors forward the call to the virtual
3053132720Skan   *  functions.  These virtual functions are hooks for developers to
3054132720Skan   *  implement the behavior they require from the time_get facet.
3055132720Skan  */
305697403Sobrien  template<typename _CharT, typename _InIter>
305797403Sobrien    class time_get : public locale::facet, public time_base
305897403Sobrien    {
305997403Sobrien    public:
306097403Sobrien      // Types:
3061132720Skan      //@{
3062132720Skan      /// Public typedefs
3063132720Skan      typedef _CharT			char_type;
3064132720Skan      typedef _InIter			iter_type;
3065132720Skan      //@}
3066132720Skan      typedef basic_string<_CharT>	__string_type;
306797403Sobrien
3068132720Skan      /// Numpunct facet id.
3069132720Skan      static locale::id			id;
307097403Sobrien
3071132720Skan      /**
3072132720Skan       *  @brief  Constructor performs initialization.
3073132720Skan       *
3074132720Skan       *  This is the constructor provided by the standard.
3075132720Skan       *
3076132720Skan       *  @param refs  Passed to the base facet class.
3077132720Skan      */
3078132720Skan      explicit
3079132720Skan      time_get(size_t __refs = 0)
3080132720Skan      : facet (__refs) { }
308197403Sobrien
3082132720Skan      /**
3083132720Skan       *  @brief  Return preferred order of month, day, and year.
3084132720Skan       *
3085132720Skan       *  This function returns an enum from timebase::dateorder giving the
3086132720Skan       *  preferred ordering if the format "x" given to time_put::put() only
3087132720Skan       *  uses month, day, and year.  If the format "x" for the associated
3088132720Skan       *  locale uses other fields, this function returns
3089132720Skan       *  timebase::dateorder::noorder.
3090132720Skan       *
3091132720Skan       *  NOTE: The library always returns noorder at the moment.
3092132720Skan       *
3093132720Skan       *  @return  A member of timebase::dateorder.
3094132720Skan      */
3095132720Skan      dateorder
309697403Sobrien      date_order()  const
309797403Sobrien      { return this->do_date_order(); }
309897403Sobrien
3099132720Skan      /**
3100132720Skan       *  @brief  Parse input time string.
3101132720Skan       *
3102132720Skan       *  This function parses a time according to the format "x" and puts the
3103132720Skan       *  results into a user-supplied struct tm.  The result is returned by
3104132720Skan       *  calling time_get::do_get_time().
3105132720Skan       *
3106132720Skan       *  If there is a valid time string according to format "x", @a tm will
3107132720Skan       *  be filled in accordingly and the returned iterator will point to the
3108132720Skan       *  first character beyond the time string.  If an error occurs before
3109132720Skan       *  the end, err |= ios_base::failbit.  If parsing reads all the
3110132720Skan       *  characters, err |= ios_base::eofbit.
3111132720Skan       *
3112132720Skan       *  @param  beg  Start of string to parse.
3113132720Skan       *  @param  end  End of string to parse.
3114132720Skan       *  @param  io  Source of the locale.
3115132720Skan       *  @param  err  Error flags to set.
3116132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3117132720Skan       *  @return  Iterator to first char beyond time string.
3118132720Skan      */
3119132720Skan      iter_type
3120132720Skan      get_time(iter_type __beg, iter_type __end, ios_base& __io,
312197403Sobrien	       ios_base::iostate& __err, tm* __tm)  const
312297403Sobrien      { return this->do_get_time(__beg, __end, __io, __err, __tm); }
312397403Sobrien
3124132720Skan      /**
3125132720Skan       *  @brief  Parse input date string.
3126132720Skan       *
3127132720Skan       *  This function parses a date according to the format "X" and puts the
3128132720Skan       *  results into a user-supplied struct tm.  The result is returned by
3129132720Skan       *  calling time_get::do_get_date().
3130132720Skan       *
3131132720Skan       *  If there is a valid date string according to format "X", @a tm will
3132132720Skan       *  be filled in accordingly and the returned iterator will point to the
3133132720Skan       *  first character beyond the date string.  If an error occurs before
3134132720Skan       *  the end, err |= ios_base::failbit.  If parsing reads all the
3135132720Skan       *  characters, err |= ios_base::eofbit.
3136132720Skan       *
3137132720Skan       *  @param  beg  Start of string to parse.
3138132720Skan       *  @param  end  End of string to parse.
3139132720Skan       *  @param  io  Source of the locale.
3140132720Skan       *  @param  err  Error flags to set.
3141132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3142132720Skan       *  @return  Iterator to first char beyond date string.
3143132720Skan      */
3144132720Skan      iter_type
314597403Sobrien      get_date(iter_type __beg, iter_type __end, ios_base& __io,
314697403Sobrien	       ios_base::iostate& __err, tm* __tm)  const
314797403Sobrien      { return this->do_get_date(__beg, __end, __io, __err, __tm); }
314897403Sobrien
3149132720Skan      /**
3150132720Skan       *  @brief  Parse input weekday string.
3151132720Skan       *
3152132720Skan       *  This function parses a weekday name and puts the results into a
3153132720Skan       *  user-supplied struct tm.  The result is returned by calling
3154132720Skan       *  time_get::do_get_weekday().
3155132720Skan       *
3156132720Skan       *  Parsing starts by parsing an abbreviated weekday name.  If a valid
3157132720Skan       *  abbreviation is followed by a character that would lead to the full
3158132720Skan       *  weekday name, parsing continues until the full name is found or an
3159132720Skan       *  error occurs.  Otherwise parsing finishes at the end of the
3160132720Skan       *  abbreviated name.
3161132720Skan       *
3162132720Skan       *  If an error occurs before the end, err |= ios_base::failbit.  If
3163132720Skan       *  parsing reads all the characters, err |= ios_base::eofbit.
3164132720Skan       *
3165132720Skan       *  @param  beg  Start of string to parse.
3166132720Skan       *  @param  end  End of string to parse.
3167132720Skan       *  @param  io  Source of the locale.
3168132720Skan       *  @param  err  Error flags to set.
3169132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3170132720Skan       *  @return  Iterator to first char beyond weekday name.
3171132720Skan      */
3172132720Skan      iter_type
317397403Sobrien      get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
317497403Sobrien		  ios_base::iostate& __err, tm* __tm) const
317597403Sobrien      { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
317697403Sobrien
3177132720Skan      /**
3178132720Skan       *  @brief  Parse input month string.
3179132720Skan       *
3180132720Skan       *  This function parses a month name and puts the results into a
3181132720Skan       *  user-supplied struct tm.  The result is returned by calling
3182132720Skan       *  time_get::do_get_monthname().
3183132720Skan       *
3184132720Skan       *  Parsing starts by parsing an abbreviated month name.  If a valid
3185132720Skan       *  abbreviation is followed by a character that would lead to the full
3186132720Skan       *  month name, parsing continues until the full name is found or an
3187132720Skan       *  error occurs.  Otherwise parsing finishes at the end of the
3188132720Skan       *  abbreviated name.
3189132720Skan       *
3190132720Skan       *  If an error occurs before the end, err |= ios_base::failbit.  If
3191132720Skan       *  parsing reads all the characters, err |=
3192132720Skan       *  ios_base::eofbit.
3193132720Skan       *
3194132720Skan       *  @param  beg  Start of string to parse.
3195132720Skan       *  @param  end  End of string to parse.
3196132720Skan       *  @param  io  Source of the locale.
3197132720Skan       *  @param  err  Error flags to set.
3198132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3199132720Skan       *  @return  Iterator to first char beyond month name.
3200132720Skan      */
3201132720Skan      iter_type
3202132720Skan      get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
320397403Sobrien		    ios_base::iostate& __err, tm* __tm) const
320497403Sobrien      { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
320597403Sobrien
3206132720Skan      /**
3207132720Skan       *  @brief  Parse input year string.
3208132720Skan       *
3209132720Skan       *  This function reads up to 4 characters to parse a year string and
3210132720Skan       *  puts the results into a user-supplied struct tm.  The result is
3211132720Skan       *  returned by calling time_get::do_get_year().
3212132720Skan       *
3213132720Skan       *  4 consecutive digits are interpreted as a full year.  If there are
3214132720Skan       *  exactly 2 consecutive digits, the library interprets this as the
3215132720Skan       *  number of years since 1900.
3216132720Skan       *
3217132720Skan       *  If an error occurs before the end, err |= ios_base::failbit.  If
3218132720Skan       *  parsing reads all the characters, err |= ios_base::eofbit.
3219132720Skan       *
3220132720Skan       *  @param  beg  Start of string to parse.
3221132720Skan       *  @param  end  End of string to parse.
3222132720Skan       *  @param  io  Source of the locale.
3223132720Skan       *  @param  err  Error flags to set.
3224132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3225132720Skan       *  @return  Iterator to first char beyond year.
3226132720Skan      */
3227132720Skan      iter_type
322897403Sobrien      get_year(iter_type __beg, iter_type __end, ios_base& __io,
322997403Sobrien	       ios_base::iostate& __err, tm* __tm) const
323097403Sobrien      { return this->do_get_year(__beg, __end, __io, __err, __tm); }
323197403Sobrien
323297403Sobrien    protected:
3233132720Skan      /// Destructor.
3234132720Skan      virtual
323597403Sobrien      ~time_get() { }
323697403Sobrien
3237132720Skan      /**
3238132720Skan       *  @brief  Return preferred order of month, day, and year.
3239132720Skan       *
3240132720Skan       *  This function returns an enum from timebase::dateorder giving the
3241132720Skan       *  preferred ordering if the format "x" given to time_put::put() only
3242132720Skan       *  uses month, day, and year.  This function is a hook for derived
3243132720Skan       *  classes to change the value returned.
3244132720Skan       *
3245132720Skan       *  @return  A member of timebase::dateorder.
3246132720Skan      */
3247132720Skan      virtual dateorder
324897403Sobrien      do_date_order() const;
324997403Sobrien
3250132720Skan      /**
3251132720Skan       *  @brief  Parse input time string.
3252132720Skan       *
3253132720Skan       *  This function parses a time according to the format "x" and puts the
3254132720Skan       *  results into a user-supplied struct tm.  This function is a hook for
3255132720Skan       *  derived classes to change the value returned.  @see get_time() for
3256132720Skan       *  details.
3257132720Skan       *
3258132720Skan       *  @param  beg  Start of string to parse.
3259132720Skan       *  @param  end  End of string to parse.
3260132720Skan       *  @param  io  Source of the locale.
3261132720Skan       *  @param  err  Error flags to set.
3262132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3263132720Skan       *  @return  Iterator to first char beyond time string.
3264132720Skan      */
3265132720Skan      virtual iter_type
326697403Sobrien      do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
326797403Sobrien		  ios_base::iostate& __err, tm* __tm) const;
326897403Sobrien
3269132720Skan      /**
3270132720Skan       *  @brief  Parse input date string.
3271132720Skan       *
3272132720Skan       *  This function parses a date according to the format "X" and puts the
3273132720Skan       *  results into a user-supplied struct tm.  This function is a hook for
3274132720Skan       *  derived classes to change the value returned.  @see get_date() for
3275132720Skan       *  details.
3276132720Skan       *
3277132720Skan       *  @param  beg  Start of string to parse.
3278132720Skan       *  @param  end  End of string to parse.
3279132720Skan       *  @param  io  Source of the locale.
3280132720Skan       *  @param  err  Error flags to set.
3281132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3282132720Skan       *  @return  Iterator to first char beyond date string.
3283132720Skan      */
3284132720Skan      virtual iter_type
328597403Sobrien      do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
328697403Sobrien		  ios_base::iostate& __err, tm* __tm) const;
328797403Sobrien
3288132720Skan      /**
3289132720Skan       *  @brief  Parse input weekday string.
3290132720Skan       *
3291132720Skan       *  This function parses a weekday name and puts the results into a
3292132720Skan       *  user-supplied struct tm.  This function is a hook for derived
3293132720Skan       *  classes to change the value returned.  @see get_weekday() for
3294132720Skan       *  details.
3295132720Skan       *
3296132720Skan       *  @param  beg  Start of string to parse.
3297132720Skan       *  @param  end  End of string to parse.
3298132720Skan       *  @param  io  Source of the locale.
3299132720Skan       *  @param  err  Error flags to set.
3300132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3301132720Skan       *  @return  Iterator to first char beyond weekday name.
3302132720Skan      */
3303132720Skan      virtual iter_type
330497403Sobrien      do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
330597403Sobrien		     ios_base::iostate& __err, tm* __tm) const;
330697403Sobrien
3307132720Skan      /**
3308132720Skan       *  @brief  Parse input month string.
3309132720Skan       *
3310132720Skan       *  This function parses a month name and puts the results into a
3311132720Skan       *  user-supplied struct tm.  This function is a hook for derived
3312132720Skan       *  classes to change the value returned.  @see get_monthname() for
3313132720Skan       *  details.
3314132720Skan       *
3315132720Skan       *  @param  beg  Start of string to parse.
3316132720Skan       *  @param  end  End of string to parse.
3317132720Skan       *  @param  io  Source of the locale.
3318132720Skan       *  @param  err  Error flags to set.
3319132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3320132720Skan       *  @return  Iterator to first char beyond month name.
3321132720Skan      */
3322132720Skan      virtual iter_type
3323132720Skan      do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
332497403Sobrien		       ios_base::iostate& __err, tm* __tm) const;
332597403Sobrien
3326132720Skan      /**
3327132720Skan       *  @brief  Parse input year string.
3328132720Skan       *
3329132720Skan       *  This function reads up to 4 characters to parse a year string and
3330132720Skan       *  puts the results into a user-supplied struct tm.  This function is a
3331132720Skan       *  hook for derived classes to change the value returned.  @see
3332132720Skan       *  get_year() for details.
3333132720Skan       *
3334132720Skan       *  @param  beg  Start of string to parse.
3335132720Skan       *  @param  end  End of string to parse.
3336132720Skan       *  @param  io  Source of the locale.
3337132720Skan       *  @param  err  Error flags to set.
3338132720Skan       *  @param  tm  Pointer to struct tm to fill in.
3339132720Skan       *  @return  Iterator to first char beyond year.
3340132720Skan      */
3341132720Skan      virtual iter_type
334297403Sobrien      do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
334397403Sobrien		  ios_base::iostate& __err, tm* __tm) const;
334497403Sobrien
334597403Sobrien      // Extract numeric component of length __len.
3346132720Skan      iter_type
3347132720Skan      _M_extract_num(iter_type __beg, iter_type __end, int& __member,
334897403Sobrien		     int __min, int __max, size_t __len,
3349132720Skan		     ios_base& __io, ios_base::iostate& __err) const;
3350132720Skan
335197403Sobrien      // Extract day or month name, or any unique array of string
335297403Sobrien      // literals in a const _CharT* array.
3353132720Skan      iter_type
3354132720Skan      _M_extract_name(iter_type __beg, iter_type __end, int& __member,
3355132720Skan		      const _CharT** __names, size_t __indexlen,
3356132720Skan		      ios_base& __io, ios_base::iostate& __err) const;
335797403Sobrien
335897403Sobrien      // Extract on a component-by-component basis, via __format argument.
3359132720Skan      iter_type
3360132720Skan      _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
3361132720Skan			    ios_base::iostate& __err, tm* __tm,
336297403Sobrien			    const _CharT* __format) const;
336397403Sobrien    };
336497403Sobrien
336597403Sobrien  template<typename _CharT, typename _InIter>
336697403Sobrien    locale::id time_get<_CharT, _InIter>::id;
336797403Sobrien
3368169691Skan  /// @brief  class time_get_byname [22.2.5.2].
336997403Sobrien  template<typename _CharT, typename _InIter>
337097403Sobrien    class time_get_byname : public time_get<_CharT, _InIter>
337197403Sobrien    {
337297403Sobrien    public:
337397403Sobrien      // Types:
3374132720Skan      typedef _CharT			char_type;
3375132720Skan      typedef _InIter			iter_type;
337697403Sobrien
3377132720Skan      explicit
3378132720Skan      time_get_byname(const char*, size_t __refs = 0)
337997403Sobrien      : time_get<_CharT, _InIter>(__refs) { }
338097403Sobrien
338197403Sobrien    protected:
3382132720Skan      virtual
338397403Sobrien      ~time_get_byname() { }
338497403Sobrien    };
338597403Sobrien
3386132720Skan  /**
3387132720Skan   *  @brief  Facet for outputting dates and times.
3388132720Skan   *
3389132720Skan   *  This facet encapsulates the code to format and output dates and times
3390132720Skan   *  according to formats used by strftime().
3391132720Skan   *
3392132720Skan   *  The time_put template uses protected virtual functions to provide the
3393132720Skan   *  actual results.  The public accessors forward the call to the virtual
3394132720Skan   *  functions.  These virtual functions are hooks for developers to
3395132720Skan   *  implement the behavior they require from the time_put facet.
3396132720Skan  */
339797403Sobrien  template<typename _CharT, typename _OutIter>
3398132720Skan    class time_put : public locale::facet
339997403Sobrien    {
340097403Sobrien    public:
340197403Sobrien      // Types:
3402132720Skan      //@{
3403132720Skan      /// Public typedefs
3404132720Skan      typedef _CharT			char_type;
3405132720Skan      typedef _OutIter			iter_type;
3406132720Skan      //@}
340797403Sobrien
3408132720Skan      /// Numpunct facet id.
3409132720Skan      static locale::id			id;
341097403Sobrien
3411132720Skan      /**
3412132720Skan       *  @brief  Constructor performs initialization.
3413132720Skan       *
3414132720Skan       *  This is the constructor provided by the standard.
3415132720Skan       *
3416132720Skan       *  @param refs  Passed to the base facet class.
3417132720Skan      */
3418132720Skan      explicit
3419132720Skan      time_put(size_t __refs = 0)
3420132720Skan      : facet(__refs) { }
342197403Sobrien
3422132720Skan      /**
3423132720Skan       *  @brief  Format and output a time or date.
3424132720Skan       *
3425132720Skan       *  This function formats the data in struct tm according to the
3426132720Skan       *  provided format string.  The format string is interpreted as by
3427132720Skan       *  strftime().
3428132720Skan       *
3429132720Skan       *  @param  s  The stream to write to.
3430132720Skan       *  @param  io  Source of locale.
3431132720Skan       *  @param  fill  char_type to use for padding.
3432132720Skan       *  @param  tm  Struct tm with date and time info to format.
3433132720Skan       *  @param  beg  Start of format string.
3434132720Skan       *  @param  end  End of format string.
3435132720Skan       *  @return  Iterator after writing.
3436132720Skan       */
3437132720Skan      iter_type
3438132720Skan      put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
343997403Sobrien	  const _CharT* __beg, const _CharT* __end) const;
344097403Sobrien
3441132720Skan      /**
3442132720Skan       *  @brief  Format and output a time or date.
3443132720Skan       *
3444132720Skan       *  This function formats the data in struct tm according to the
3445132720Skan       *  provided format char and optional modifier.  The format and modifier
3446132720Skan       *  are interpreted as by strftime().  It does so by returning
3447132720Skan       *  time_put::do_put().
3448132720Skan       *
3449132720Skan       *  @param  s  The stream to write to.
3450132720Skan       *  @param  io  Source of locale.
3451132720Skan       *  @param  fill  char_type to use for padding.
3452132720Skan       *  @param  tm  Struct tm with date and time info to format.
3453132720Skan       *  @param  format  Format char.
3454132720Skan       *  @param  mod  Optional modifier char.
3455132720Skan       *  @return  Iterator after writing.
3456132720Skan       */
3457132720Skan      iter_type
345897403Sobrien      put(iter_type __s, ios_base& __io, char_type __fill,
345997403Sobrien	  const tm* __tm, char __format, char __mod = 0) const
346097403Sobrien      { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
346197403Sobrien
346297403Sobrien    protected:
3463132720Skan      /// Destructor.
3464132720Skan      virtual
346597403Sobrien      ~time_put()
346697403Sobrien      { }
346797403Sobrien
3468132720Skan      /**
3469132720Skan       *  @brief  Format and output a time or date.
3470132720Skan       *
3471132720Skan       *  This function formats the data in struct tm according to the
3472132720Skan       *  provided format char and optional modifier.  This function is a hook
3473132720Skan       *  for derived classes to change the value returned.  @see put() for
3474132720Skan       *  more details.
3475132720Skan       *
3476132720Skan       *  @param  s  The stream to write to.
3477132720Skan       *  @param  io  Source of locale.
3478132720Skan       *  @param  fill  char_type to use for padding.
3479132720Skan       *  @param  tm  Struct tm with date and time info to format.
3480132720Skan       *  @param  format  Format char.
3481132720Skan       *  @param  mod  Optional modifier char.
3482132720Skan       *  @return  Iterator after writing.
3483132720Skan       */
3484132720Skan      virtual iter_type
3485132720Skan      do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
348697403Sobrien	     char __format, char __mod) const;
348797403Sobrien    };
348897403Sobrien
348997403Sobrien  template<typename _CharT, typename _OutIter>
349097403Sobrien    locale::id time_put<_CharT, _OutIter>::id;
349197403Sobrien
3492169691Skan  /// @brief  class time_put_byname [22.2.5.4].
349397403Sobrien  template<typename _CharT, typename _OutIter>
349497403Sobrien    class time_put_byname : public time_put<_CharT, _OutIter>
349597403Sobrien    {
349697403Sobrien    public:
349797403Sobrien      // Types:
3498132720Skan      typedef _CharT			char_type;
3499132720Skan      typedef _OutIter			iter_type;
350097403Sobrien
3501132720Skan      explicit
3502132720Skan      time_put_byname(const char*, size_t __refs = 0)
3503132720Skan      : time_put<_CharT, _OutIter>(__refs)
350497403Sobrien      { };
350597403Sobrien
350697403Sobrien    protected:
3507132720Skan      virtual
350897403Sobrien      ~time_put_byname() { }
350997403Sobrien    };
351097403Sobrien
351197403Sobrien
3512132720Skan  /**
3513132720Skan   *  @brief  Money format ordering data.
3514132720Skan   *
3515132720Skan   *  This class contains an ordered array of 4 fields to represent the
3516132720Skan   *  pattern for formatting a money amount.  Each field may contain one entry
3517132720Skan   *  from the part enum.  symbol, sign, and value must be present and the
3518132720Skan   *  remaining field must contain either none or space.  @see
3519132720Skan   *  moneypunct::pos_format() and moneypunct::neg_format() for details of how
3520132720Skan   *  these fields are interpreted.
3521132720Skan  */
352297403Sobrien  class money_base
352397403Sobrien  {
352497403Sobrien  public:
352597403Sobrien    enum part { none, space, symbol, sign, value };
352697403Sobrien    struct pattern { char field[4]; };
352797403Sobrien
352897403Sobrien    static const pattern _S_default_pattern;
352997403Sobrien
3530132720Skan    enum
3531132720Skan    {
3532132720Skan      _S_minus,
3533132720Skan      _S_zero,
3534132720Skan      _S_end = 11
3535132720Skan    };
3536132720Skan
3537132720Skan    // String literal of acceptable (narrow) input/output, for
3538132720Skan    // money_get/money_put. "-0123456789"
3539132720Skan    static const char* _S_atoms;
3540132720Skan
354197403Sobrien    // Construct and return valid pattern consisting of some combination of:
354297403Sobrien    // space none symbol sign value
3543132720Skan    static pattern
354497403Sobrien    _S_construct_pattern(char __precedes, char __space, char __posn);
354597403Sobrien  };
354697403Sobrien
354797403Sobrien  template<typename _CharT, bool _Intl>
3548132720Skan    struct __moneypunct_cache : public locale::facet
3549132720Skan    {
3550132720Skan      const char*			_M_grouping;
3551132720Skan      size_t                            _M_grouping_size;
3552132720Skan      bool				_M_use_grouping;
3553132720Skan      _CharT				_M_decimal_point;
3554132720Skan      _CharT				_M_thousands_sep;
3555132720Skan      const _CharT*			_M_curr_symbol;
3556132720Skan      size_t                            _M_curr_symbol_size;
3557132720Skan      const _CharT*			_M_positive_sign;
3558132720Skan      size_t                            _M_positive_sign_size;
3559132720Skan      const _CharT*			_M_negative_sign;
3560132720Skan      size_t                            _M_negative_sign_size;
3561132720Skan      int				_M_frac_digits;
3562132720Skan      money_base::pattern		_M_pos_format;
3563132720Skan      money_base::pattern	        _M_neg_format;
3564132720Skan
3565132720Skan      // A list of valid numeric literals for input and output: in the standard
3566132720Skan      // "C" locale, this is "-0123456789". This array contains the chars after
3567132720Skan      // having been passed through the current locale's ctype<_CharT>.widen().
3568132720Skan      _CharT				_M_atoms[money_base::_S_end];
3569132720Skan
3570132720Skan      bool				_M_allocated;
3571132720Skan
3572132720Skan      __moneypunct_cache(size_t __refs = 0) : facet(__refs),
3573132720Skan      _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),
3574132720Skan      _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),
3575132720Skan      _M_curr_symbol(NULL), _M_curr_symbol_size(0),
3576132720Skan      _M_positive_sign(NULL), _M_positive_sign_size(0),
3577132720Skan      _M_negative_sign(NULL), _M_negative_sign_size(0),
3578132720Skan      _M_frac_digits(0),
3579132720Skan      _M_pos_format(money_base::pattern()),
3580132720Skan      _M_neg_format(money_base::pattern()), _M_allocated(false)
3581132720Skan      { }
3582132720Skan
3583132720Skan      ~__moneypunct_cache();
3584132720Skan
3585132720Skan      void
3586132720Skan      _M_cache(const locale& __loc);
3587132720Skan
3588132720Skan    private:
3589132720Skan      __moneypunct_cache&
3590132720Skan      operator=(const __moneypunct_cache&);
3591132720Skan
3592132720Skan      explicit
3593132720Skan      __moneypunct_cache(const __moneypunct_cache&);
3594132720Skan    };
3595132720Skan
3596132720Skan  template<typename _CharT, bool _Intl>
3597132720Skan    __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache()
3598132720Skan    {
3599132720Skan      if (_M_allocated)
3600132720Skan	{
3601132720Skan	  delete [] _M_grouping;
3602132720Skan	  delete [] _M_curr_symbol;
3603132720Skan	  delete [] _M_positive_sign;
3604132720Skan	  delete [] _M_negative_sign;
3605132720Skan	}
3606132720Skan    }
3607132720Skan
3608132720Skan  /**
3609132720Skan   *  @brief  Facet for formatting data for money amounts.
3610132720Skan   *
3611132720Skan   *  This facet encapsulates the punctuation, grouping and other formatting
3612132720Skan   *  features of money amount string representations.
3613132720Skan  */
3614132720Skan  template<typename _CharT, bool _Intl>
361597403Sobrien    class moneypunct : public locale::facet, public money_base
361697403Sobrien    {
361797403Sobrien    public:
361897403Sobrien      // Types:
3619132720Skan      //@{
3620132720Skan      /// Public typedefs
3621132720Skan      typedef _CharT			char_type;
3622132720Skan      typedef basic_string<_CharT>	string_type;
3623132720Skan      //@}
3624132720Skan      typedef __moneypunct_cache<_CharT, _Intl>     __cache_type;
362597403Sobrien
362697403Sobrien    private:
3627132720Skan      __cache_type*			_M_data;
362897403Sobrien
362997403Sobrien    public:
3630132720Skan      /// This value is provided by the standard, but no reason for its
3631132720Skan      /// existence.
3632132720Skan      static const bool			intl = _Intl;
3633132720Skan      /// Numpunct facet id.
3634132720Skan      static locale::id			id;
3635132720Skan
3636132720Skan      /**
3637132720Skan       *  @brief  Constructor performs initialization.
3638132720Skan       *
3639132720Skan       *  This is the constructor provided by the standard.
3640132720Skan       *
3641132720Skan       *  @param refs  Passed to the base facet class.
3642132720Skan      */
3643132720Skan      explicit
3644132720Skan      moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)
364597403Sobrien      { _M_initialize_moneypunct(); }
364697403Sobrien
3647132720Skan      /**
3648132720Skan       *  @brief  Constructor performs initialization.
3649132720Skan       *
3650132720Skan       *  This is an internal constructor.
3651132720Skan       *
3652132720Skan       *  @param cache  Cache for optimization.
3653132720Skan       *  @param refs  Passed to the base facet class.
3654132720Skan      */
3655132720Skan      explicit
3656132720Skan      moneypunct(__cache_type* __cache, size_t __refs = 0)
3657132720Skan      : facet(__refs), _M_data(__cache)
3658132720Skan      { _M_initialize_moneypunct(); }
3659132720Skan
3660132720Skan      /**
3661132720Skan       *  @brief  Internal constructor. Not for general use.
3662132720Skan       *
3663132720Skan       *  This is a constructor for use by the library itself to set up new
3664132720Skan       *  locales.
3665132720Skan       *
3666132720Skan       *  @param cloc  The "C" locale.
3667132720Skan       *  @param s  The name of a locale.
3668132720Skan       *  @param refs  Passed to the base facet class.
3669132720Skan      */
3670132720Skan      explicit
3671132720Skan      moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
3672132720Skan      : facet(__refs), _M_data(NULL)
3673102782Skan      { _M_initialize_moneypunct(__cloc, __s); }
367497403Sobrien
3675132720Skan      /**
3676132720Skan       *  @brief  Return decimal point character.
3677132720Skan       *
3678132720Skan       *  This function returns a char_type to use as a decimal point.  It
3679132720Skan       *  does so by returning returning
3680132720Skan       *  moneypunct<char_type>::do_decimal_point().
3681132720Skan       *
3682132720Skan       *  @return  @a char_type representing a decimal point.
3683132720Skan      */
368497403Sobrien      char_type
368597403Sobrien      decimal_point() const
368697403Sobrien      { return this->do_decimal_point(); }
3687132720Skan
3688132720Skan      /**
3689132720Skan       *  @brief  Return thousands separator character.
3690132720Skan       *
3691132720Skan       *  This function returns a char_type to use as a thousands
3692132720Skan       *  separator.  It does so by returning returning
3693132720Skan       *  moneypunct<char_type>::do_thousands_sep().
3694132720Skan       *
3695132720Skan       *  @return  char_type representing a thousands separator.
3696132720Skan      */
369797403Sobrien      char_type
369897403Sobrien      thousands_sep() const
369997403Sobrien      { return this->do_thousands_sep(); }
3700132720Skan
3701132720Skan      /**
3702132720Skan       *  @brief  Return grouping specification.
3703132720Skan       *
3704132720Skan       *  This function returns a string representing groupings for the
3705132720Skan       *  integer part of an amount.  Groupings indicate where thousands
3706132720Skan       *  separators should be inserted.
3707132720Skan       *
3708132720Skan       *  Each char in the return string is interpret as an integer rather
3709132720Skan       *  than a character.  These numbers represent the number of digits in a
3710132720Skan       *  group.  The first char in the string represents the number of digits
3711132720Skan       *  in the least significant group.  If a char is negative, it indicates
3712132720Skan       *  an unlimited number of digits for the group.  If more chars from the
3713132720Skan       *  string are required to group a number, the last char is used
3714132720Skan       *  repeatedly.
3715132720Skan       *
3716132720Skan       *  For example, if the grouping() returns "\003\002" and is applied to
3717132720Skan       *  the number 123456789, this corresponds to 12,34,56,789.  Note that
3718132720Skan       *  if the string was "32", this would put more than 50 digits into the
3719132720Skan       *  least significant group if the character set is ASCII.
3720132720Skan       *
3721132720Skan       *  The string is returned by calling
3722132720Skan       *  moneypunct<char_type>::do_grouping().
3723132720Skan       *
3724132720Skan       *  @return  string representing grouping specification.
3725132720Skan      */
3726132720Skan      string
372797403Sobrien      grouping() const
372897403Sobrien      { return this->do_grouping(); }
372997403Sobrien
3730132720Skan      /**
3731132720Skan       *  @brief  Return currency symbol string.
3732132720Skan       *
3733132720Skan       *  This function returns a string_type to use as a currency symbol.  It
3734132720Skan       *  does so by returning returning
3735132720Skan       *  moneypunct<char_type>::do_curr_symbol().
3736132720Skan       *
3737132720Skan       *  @return  @a string_type representing a currency symbol.
3738132720Skan      */
3739132720Skan      string_type
374097403Sobrien      curr_symbol() const
374197403Sobrien      { return this->do_curr_symbol(); }
374297403Sobrien
3743132720Skan      /**
3744132720Skan       *  @brief  Return positive sign string.
3745132720Skan       *
3746132720Skan       *  This function returns a string_type to use as a sign for positive
3747132720Skan       *  amounts.  It does so by returning returning
3748132720Skan       *  moneypunct<char_type>::do_positive_sign().
3749132720Skan       *
3750132720Skan       *  If the return value contains more than one character, the first
3751132720Skan       *  character appears in the position indicated by pos_format() and the
3752132720Skan       *  remainder appear at the end of the formatted string.
3753132720Skan       *
3754132720Skan       *  @return  @a string_type representing a positive sign.
3755132720Skan      */
3756132720Skan      string_type
375797403Sobrien      positive_sign() const
375897403Sobrien      { return this->do_positive_sign(); }
375997403Sobrien
3760132720Skan      /**
3761132720Skan       *  @brief  Return negative sign string.
3762132720Skan       *
3763132720Skan       *  This function returns a string_type to use as a sign for negative
3764132720Skan       *  amounts.  It does so by returning returning
3765132720Skan       *  moneypunct<char_type>::do_negative_sign().
3766132720Skan       *
3767132720Skan       *  If the return value contains more than one character, the first
3768132720Skan       *  character appears in the position indicated by neg_format() and the
3769132720Skan       *  remainder appear at the end of the formatted string.
3770132720Skan       *
3771132720Skan       *  @return  @a string_type representing a negative sign.
3772132720Skan      */
3773132720Skan      string_type
377497403Sobrien      negative_sign() const
377597403Sobrien      { return this->do_negative_sign(); }
377697403Sobrien
3777132720Skan      /**
3778132720Skan       *  @brief  Return number of digits in fraction.
3779132720Skan       *
3780132720Skan       *  This function returns the exact number of digits that make up the
3781132720Skan       *  fractional part of a money amount.  It does so by returning
3782132720Skan       *  returning moneypunct<char_type>::do_frac_digits().
3783132720Skan       *
3784132720Skan       *  The fractional part of a money amount is optional.  But if it is
3785132720Skan       *  present, there must be frac_digits() digits.
3786132720Skan       *
3787132720Skan       *  @return  Number of digits in amount fraction.
3788132720Skan      */
3789132720Skan      int
379097403Sobrien      frac_digits() const
379197403Sobrien      { return this->do_frac_digits(); }
379297403Sobrien
3793132720Skan      //@{
3794132720Skan      /**
3795132720Skan       *  @brief  Return pattern for money values.
3796132720Skan       *
3797132720Skan       *  This function returns a pattern describing the formatting of a
3798132720Skan       *  positive or negative valued money amount.  It does so by returning
3799132720Skan       *  returning moneypunct<char_type>::do_pos_format() or
3800132720Skan       *  moneypunct<char_type>::do_neg_format().
3801132720Skan       *
3802132720Skan       *  The pattern has 4 fields describing the ordering of symbol, sign,
3803132720Skan       *  value, and none or space.  There must be one of each in the pattern.
3804132720Skan       *  The none and space enums may not appear in the first field and space
3805132720Skan       *  may not appear in the final field.
3806132720Skan       *
3807132720Skan       *  The parts of a money string must appear in the order indicated by
3808132720Skan       *  the fields of the pattern.  The symbol field indicates that the
3809132720Skan       *  value of curr_symbol() may be present.  The sign field indicates
3810132720Skan       *  that the value of positive_sign() or negative_sign() must be
3811132720Skan       *  present.  The value field indicates that the absolute value of the
3812132720Skan       *  money amount is present.  none indicates 0 or more whitespace
3813132720Skan       *  characters, except at the end, where it permits no whitespace.
3814132720Skan       *  space indicates that 1 or more whitespace characters must be
3815132720Skan       *  present.
3816132720Skan       *
3817132720Skan       *  For example, for the US locale and pos_format() pattern
3818132720Skan       *  {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() ==
3819132720Skan       *  '+', and value 10.01, and options set to force the symbol, the
3820132720Skan       *  corresponding string is "$+10.01".
3821132720Skan       *
3822132720Skan       *  @return  Pattern for money values.
3823132720Skan      */
3824132720Skan      pattern
382597403Sobrien      pos_format() const
382697403Sobrien      { return this->do_pos_format(); }
382797403Sobrien
3828132720Skan      pattern
382997403Sobrien      neg_format() const
383097403Sobrien      { return this->do_neg_format(); }
3831132720Skan      //@}
383297403Sobrien
383397403Sobrien    protected:
3834132720Skan      /// Destructor.
3835132720Skan      virtual
383697403Sobrien      ~moneypunct();
383797403Sobrien
3838132720Skan      /**
3839132720Skan       *  @brief  Return decimal point character.
3840132720Skan       *
3841132720Skan       *  Returns a char_type to use as a decimal point.  This function is a
3842132720Skan       *  hook for derived classes to change the value returned.
3843132720Skan       *
3844132720Skan       *  @return  @a char_type representing a decimal point.
3845132720Skan      */
384697403Sobrien      virtual char_type
384797403Sobrien      do_decimal_point() const
3848132720Skan      { return _M_data->_M_decimal_point; }
3849132720Skan
3850132720Skan      /**
3851132720Skan       *  @brief  Return thousands separator character.
3852132720Skan       *
3853132720Skan       *  Returns a char_type to use as a thousands separator.  This function
3854132720Skan       *  is a hook for derived classes to change the value returned.
3855132720Skan       *
3856132720Skan       *  @return  @a char_type representing a thousands separator.
3857132720Skan      */
385897403Sobrien      virtual char_type
385997403Sobrien      do_thousands_sep() const
3860132720Skan      { return _M_data->_M_thousands_sep; }
3861132720Skan
3862132720Skan      /**
3863132720Skan       *  @brief  Return grouping specification.
3864132720Skan       *
3865132720Skan       *  Returns a string representing groupings for the integer part of a
3866132720Skan       *  number.  This function is a hook for derived classes to change the
3867132720Skan       *  value returned.  @see grouping() for details.
3868132720Skan       *
3869132720Skan       *  @return  String representing grouping specification.
3870132720Skan      */
3871132720Skan      virtual string
387297403Sobrien      do_grouping() const
3873132720Skan      { return _M_data->_M_grouping; }
387497403Sobrien
3875132720Skan      /**
3876132720Skan       *  @brief  Return currency symbol string.
3877132720Skan       *
3878132720Skan       *  This function returns a string_type to use as a currency symbol.
3879132720Skan       *  This function is a hook for derived classes to change the value
3880132720Skan       *  returned.  @see curr_symbol() for details.
3881132720Skan       *
3882132720Skan       *  @return  @a string_type representing a currency symbol.
3883132720Skan      */
3884132720Skan      virtual string_type
388597403Sobrien      do_curr_symbol()   const
3886132720Skan      { return _M_data->_M_curr_symbol; }
388797403Sobrien
3888132720Skan      /**
3889132720Skan       *  @brief  Return positive sign string.
3890132720Skan       *
3891132720Skan       *  This function returns a string_type to use as a sign for positive
3892132720Skan       *  amounts.  This function is a hook for derived classes to change the
3893132720Skan       *  value returned.  @see positive_sign() for details.
3894132720Skan       *
3895132720Skan       *  @return  @a string_type representing a positive sign.
3896132720Skan      */
3897132720Skan      virtual string_type
389897403Sobrien      do_positive_sign() const
3899132720Skan      { return _M_data->_M_positive_sign; }
390097403Sobrien
3901132720Skan      /**
3902132720Skan       *  @brief  Return negative sign string.
3903132720Skan       *
3904132720Skan       *  This function returns a string_type to use as a sign for negative
3905132720Skan       *  amounts.  This function is a hook for derived classes to change the
3906132720Skan       *  value returned.  @see negative_sign() for details.
3907132720Skan       *
3908132720Skan       *  @return  @a string_type representing a negative sign.
3909132720Skan      */
3910132720Skan      virtual string_type
391197403Sobrien      do_negative_sign() const
3912132720Skan      { return _M_data->_M_negative_sign; }
391397403Sobrien
3914132720Skan      /**
3915132720Skan       *  @brief  Return number of digits in fraction.
3916132720Skan       *
3917132720Skan       *  This function returns the exact number of digits that make up the
3918132720Skan       *  fractional part of a money amount.  This function is a hook for
3919132720Skan       *  derived classes to change the value returned.  @see frac_digits()
3920132720Skan       *  for details.
3921132720Skan       *
3922132720Skan       *  @return  Number of digits in amount fraction.
3923132720Skan      */
3924132720Skan      virtual int
392597403Sobrien      do_frac_digits() const
3926132720Skan      { return _M_data->_M_frac_digits; }
392797403Sobrien
3928132720Skan      /**
3929132720Skan       *  @brief  Return pattern for money values.
3930132720Skan       *
3931132720Skan       *  This function returns a pattern describing the formatting of a
3932132720Skan       *  positive valued money amount.  This function is a hook for derived
3933132720Skan       *  classes to change the value returned.  @see pos_format() for
3934132720Skan       *  details.
3935132720Skan       *
3936132720Skan       *  @return  Pattern for money values.
3937132720Skan      */
3938132720Skan      virtual pattern
393997403Sobrien      do_pos_format() const
3940132720Skan      { return _M_data->_M_pos_format; }
394197403Sobrien
3942132720Skan      /**
3943132720Skan       *  @brief  Return pattern for money values.
3944132720Skan       *
3945132720Skan       *  This function returns a pattern describing the formatting of a
3946132720Skan       *  negative valued money amount.  This function is a hook for derived
3947132720Skan       *  classes to change the value returned.  @see neg_format() for
3948132720Skan       *  details.
3949132720Skan       *
3950132720Skan       *  @return  Pattern for money values.
3951132720Skan      */
3952132720Skan      virtual pattern
395397403Sobrien      do_neg_format() const
3954132720Skan      { return _M_data->_M_neg_format; }
395597403Sobrien
395697403Sobrien      // For use at construction time only.
3957132720Skan       void
3958132720Skan       _M_initialize_moneypunct(__c_locale __cloc = NULL,
3959102782Skan				const char* __name = NULL);
396097403Sobrien    };
396197403Sobrien
396297403Sobrien  template<typename _CharT, bool _Intl>
396397403Sobrien    locale::id moneypunct<_CharT, _Intl>::id;
396497403Sobrien
396597403Sobrien  template<typename _CharT, bool _Intl>
396697403Sobrien    const bool moneypunct<_CharT, _Intl>::intl;
396797403Sobrien
396897403Sobrien  template<>
396997403Sobrien    moneypunct<char, true>::~moneypunct();
397097403Sobrien
397197403Sobrien  template<>
397297403Sobrien    moneypunct<char, false>::~moneypunct();
397397403Sobrien
3974132720Skan  template<>
397597403Sobrien    void
3976102782Skan    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
397797403Sobrien
3978132720Skan  template<>
397997403Sobrien    void
3980102782Skan    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
398197403Sobrien
3982132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
398397403Sobrien  template<>
398497403Sobrien    moneypunct<wchar_t, true>::~moneypunct();
398597403Sobrien
398697403Sobrien  template<>
398797403Sobrien    moneypunct<wchar_t, false>::~moneypunct();
398897403Sobrien
3989132720Skan  template<>
399097403Sobrien    void
3991132720Skan    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
3992102782Skan							const char*);
399397403Sobrien
3994132720Skan  template<>
399597403Sobrien    void
3996132720Skan    moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
3997102782Skan							 const char*);
399897403Sobrien#endif
399997403Sobrien
4000169691Skan  /// @brief  class moneypunct_byname [22.2.6.4].
400197403Sobrien  template<typename _CharT, bool _Intl>
400297403Sobrien    class moneypunct_byname : public moneypunct<_CharT, _Intl>
400397403Sobrien    {
400497403Sobrien    public:
4005132720Skan      typedef _CharT			char_type;
4006132720Skan      typedef basic_string<_CharT>	string_type;
400797403Sobrien
400897403Sobrien      static const bool intl = _Intl;
400997403Sobrien
4010132720Skan      explicit
401197403Sobrien      moneypunct_byname(const char* __s, size_t __refs = 0)
401297403Sobrien      : moneypunct<_CharT, _Intl>(__refs)
401397403Sobrien      {
4014132720Skan	if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
4015132720Skan	  {
4016132720Skan	    __c_locale __tmp;
4017132720Skan	    this->_S_create_c_locale(__tmp, __s);
4018132720Skan	    this->_M_initialize_moneypunct(__tmp);
4019132720Skan	    this->_S_destroy_c_locale(__tmp);
4020132720Skan	  }
402197403Sobrien      }
402297403Sobrien
402397403Sobrien    protected:
4024132720Skan      virtual
4025132720Skan      ~moneypunct_byname() { }
402697403Sobrien    };
402797403Sobrien
402897403Sobrien  template<typename _CharT, bool _Intl>
402997403Sobrien    const bool moneypunct_byname<_CharT, _Intl>::intl;
403097403Sobrien
4031169691Skan_GLIBCXX_BEGIN_LDBL_NAMESPACE
4032132720Skan  /**
4033132720Skan   *  @brief  Facet for parsing monetary amounts.
4034132720Skan   *
4035132720Skan   *  This facet encapsulates the code to parse and return a monetary
4036132720Skan   *  amount from a string.
4037132720Skan   *
4038132720Skan   *  The money_get template uses protected virtual functions to
4039132720Skan   *  provide the actual results.  The public accessors forward the
4040132720Skan   *  call to the virtual functions.  These virtual functions are
4041132720Skan   *  hooks for developers to implement the behavior they require from
4042132720Skan   *  the money_get facet.
4043132720Skan  */
404497403Sobrien  template<typename _CharT, typename _InIter>
404597403Sobrien    class money_get : public locale::facet
404697403Sobrien    {
404797403Sobrien    public:
404897403Sobrien      // Types:
4049132720Skan      //@{
4050132720Skan      /// Public typedefs
4051132720Skan      typedef _CharT			char_type;
4052132720Skan      typedef _InIter			iter_type;
4053132720Skan      typedef basic_string<_CharT>	string_type;
4054132720Skan      //@}
405597403Sobrien
4056132720Skan      /// Numpunct facet id.
4057132720Skan      static locale::id			id;
405897403Sobrien
4059132720Skan      /**
4060132720Skan       *  @brief  Constructor performs initialization.
4061132720Skan       *
4062132720Skan       *  This is the constructor provided by the standard.
4063132720Skan       *
4064132720Skan       *  @param refs  Passed to the base facet class.
4065132720Skan      */
4066132720Skan      explicit
4067132720Skan      money_get(size_t __refs = 0) : facet(__refs) { }
406897403Sobrien
4069132720Skan      /**
4070132720Skan       *  @brief  Read and parse a monetary value.
4071132720Skan       *
4072132720Skan       *  This function reads characters from @a s, interprets them as a
4073132720Skan       *  monetary value according to moneypunct and ctype facets retrieved
4074132720Skan       *  from io.getloc(), and returns the result in @a units as an integral
4075132720Skan       *  value moneypunct::frac_digits() * the actual amount.  For example,
4076132720Skan       *  the string $10.01 in a US locale would store 1001 in @a units.
4077132720Skan       *
4078132720Skan       *  Any characters not part of a valid money amount are not consumed.
4079132720Skan       *
4080132720Skan       *  If a money value cannot be parsed from the input stream, sets
4081132720Skan       *  err=(err|io.failbit).  If the stream is consumed before finishing
4082132720Skan       *  parsing,  sets err=(err|io.failbit|io.eofbit).  @a units is
4083132720Skan       *  unchanged if parsing fails.
4084132720Skan       *
4085132720Skan       *  This function works by returning the result of do_get().
4086132720Skan       *
4087132720Skan       *  @param  s  Start of characters to parse.
4088132720Skan       *  @param  end  End of characters to parse.
4089132720Skan       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
4090132720Skan       *  @param  io  Source of facets and io state.
4091132720Skan       *  @param  err  Error field to set if parsing fails.
4092132720Skan       *  @param  units  Place to store result of parsing.
4093132720Skan       *  @return  Iterator referencing first character beyond valid money
4094132720Skan       *	   amount.
4095132720Skan       */
4096132720Skan      iter_type
4097132720Skan      get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
409897403Sobrien	  ios_base::iostate& __err, long double& __units) const
409997403Sobrien      { return this->do_get(__s, __end, __intl, __io, __err, __units); }
410097403Sobrien
4101132720Skan      /**
4102132720Skan       *  @brief  Read and parse a monetary value.
4103132720Skan       *
4104132720Skan       *  This function reads characters from @a s, interprets them as a
4105132720Skan       *  monetary value according to moneypunct and ctype facets retrieved
4106132720Skan       *  from io.getloc(), and returns the result in @a digits.  For example,
4107132720Skan       *  the string $10.01 in a US locale would store "1001" in @a digits.
4108132720Skan       *
4109132720Skan       *  Any characters not part of a valid money amount are not consumed.
4110132720Skan       *
4111132720Skan       *  If a money value cannot be parsed from the input stream, sets
4112132720Skan       *  err=(err|io.failbit).  If the stream is consumed before finishing
4113132720Skan       *  parsing,  sets err=(err|io.failbit|io.eofbit).
4114132720Skan       *
4115132720Skan       *  This function works by returning the result of do_get().
4116132720Skan       *
4117132720Skan       *  @param  s  Start of characters to parse.
4118132720Skan       *  @param  end  End of characters to parse.
4119132720Skan       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
4120132720Skan       *  @param  io  Source of facets and io state.
4121132720Skan       *  @param  err  Error field to set if parsing fails.
4122132720Skan       *  @param  digits  Place to store result of parsing.
4123132720Skan       *  @return  Iterator referencing first character beyond valid money
4124132720Skan       *	   amount.
4125132720Skan       */
4126132720Skan      iter_type
4127132720Skan      get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
412897403Sobrien	  ios_base::iostate& __err, string_type& __digits) const
412997403Sobrien      { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
413097403Sobrien
413197403Sobrien    protected:
4132132720Skan      /// Destructor.
4133132720Skan      virtual
413497403Sobrien      ~money_get() { }
413597403Sobrien
4136132720Skan      /**
4137132720Skan       *  @brief  Read and parse a monetary value.
4138132720Skan       *
4139132720Skan       *  This function reads and parses characters representing a monetary
4140132720Skan       *  value.  This function is a hook for derived classes to change the
4141132720Skan       *  value returned.  @see get() for details.
4142132720Skan       */
4143169691Skan      // XXX GLIBCXX_ABI Deprecated
4144169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
4145132720Skan      virtual iter_type
4146169691Skan      __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
4147169691Skan	       ios_base::iostate& __err, double& __units) const;
4148169691Skan#else
4149169691Skan      virtual iter_type
4150132720Skan      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
415197403Sobrien	     ios_base::iostate& __err, long double& __units) const;
4152169691Skan#endif
415397403Sobrien
4154132720Skan      /**
4155132720Skan       *  @brief  Read and parse a monetary value.
4156132720Skan       *
4157132720Skan       *  This function reads and parses characters representing a monetary
4158132720Skan       *  value.  This function is a hook for derived classes to change the
4159132720Skan       *  value returned.  @see get() for details.
4160132720Skan       */
4161132720Skan      virtual iter_type
4162132720Skan      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
416397403Sobrien	     ios_base::iostate& __err, string_type& __digits) const;
4164132720Skan
4165169691Skan      // XXX GLIBCXX_ABI Deprecated
4166169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
4167169691Skan      virtual iter_type
4168169691Skan      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
4169169691Skan	     ios_base::iostate& __err, long double& __units) const;
4170169691Skan#endif
4171169691Skan
4172132720Skan      template<bool _Intl>
4173132720Skan        iter_type
4174132720Skan        _M_extract(iter_type __s, iter_type __end, ios_base& __io,
4175132720Skan		   ios_base::iostate& __err, string& __digits) const;
417697403Sobrien    };
417797403Sobrien
417897403Sobrien  template<typename _CharT, typename _InIter>
417997403Sobrien    locale::id money_get<_CharT, _InIter>::id;
418097403Sobrien
4181132720Skan  /**
4182132720Skan   *  @brief  Facet for outputting monetary amounts.
4183132720Skan   *
4184132720Skan   *  This facet encapsulates the code to format and output a monetary
4185132720Skan   *  amount.
4186132720Skan   *
4187132720Skan   *  The money_put template uses protected virtual functions to
4188132720Skan   *  provide the actual results.  The public accessors forward the
4189132720Skan   *  call to the virtual functions.  These virtual functions are
4190132720Skan   *  hooks for developers to implement the behavior they require from
4191132720Skan   *  the money_put facet.
4192132720Skan  */
419397403Sobrien  template<typename _CharT, typename _OutIter>
419497403Sobrien    class money_put : public locale::facet
419597403Sobrien    {
419697403Sobrien    public:
4197132720Skan      //@{
4198132720Skan      /// Public typedefs
4199132720Skan      typedef _CharT			char_type;
4200132720Skan      typedef _OutIter			iter_type;
420197403Sobrien      typedef basic_string<_CharT>	string_type;
4202132720Skan      //@}
420397403Sobrien
4204132720Skan      /// Numpunct facet id.
4205132720Skan      static locale::id			id;
420697403Sobrien
4207132720Skan      /**
4208132720Skan       *  @brief  Constructor performs initialization.
4209132720Skan       *
4210132720Skan       *  This is the constructor provided by the standard.
4211132720Skan       *
4212132720Skan       *  @param refs  Passed to the base facet class.
4213132720Skan      */
4214132720Skan      explicit
4215132720Skan      money_put(size_t __refs = 0) : facet(__refs) { }
421697403Sobrien
4217132720Skan      /**
4218132720Skan       *  @brief  Format and output a monetary value.
4219132720Skan       *
4220132720Skan       *  This function formats @a units as a monetary value according to
4221132720Skan       *  moneypunct and ctype facets retrieved from io.getloc(), and writes
4222132720Skan       *  the resulting characters to @a s.  For example, the value 1001 in a
4223132720Skan       *  US locale would write "$10.01" to @a s.
4224132720Skan       *
4225132720Skan       *  This function works by returning the result of do_put().
4226132720Skan       *
4227132720Skan       *  @param  s  The stream to write to.
4228132720Skan       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
4229132720Skan       *  @param  io  Source of facets and io state.
4230132720Skan       *  @param  fill  char_type to use for padding.
4231132720Skan       *  @param  units  Place to store result of parsing.
4232132720Skan       *  @return  Iterator after writing.
4233132720Skan       */
4234132720Skan      iter_type
423597403Sobrien      put(iter_type __s, bool __intl, ios_base& __io,
423697403Sobrien	  char_type __fill, long double __units) const
423797403Sobrien      { return this->do_put(__s, __intl, __io, __fill, __units); }
423897403Sobrien
4239132720Skan      /**
4240132720Skan       *  @brief  Format and output a monetary value.
4241132720Skan       *
4242132720Skan       *  This function formats @a digits as a monetary value according to
4243132720Skan       *  moneypunct and ctype facets retrieved from io.getloc(), and writes
4244132720Skan       *  the resulting characters to @a s.  For example, the string "1001" in
4245132720Skan       *  a US locale would write "$10.01" to @a s.
4246132720Skan       *
4247132720Skan       *  This function works by returning the result of do_put().
4248132720Skan       *
4249132720Skan       *  @param  s  The stream to write to.
4250132720Skan       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
4251132720Skan       *  @param  io  Source of facets and io state.
4252132720Skan       *  @param  fill  char_type to use for padding.
4253132720Skan       *  @param  units  Place to store result of parsing.
4254132720Skan       *  @return  Iterator after writing.
4255132720Skan       */
4256132720Skan      iter_type
425797403Sobrien      put(iter_type __s, bool __intl, ios_base& __io,
425897403Sobrien	  char_type __fill, const string_type& __digits) const
425997403Sobrien      { return this->do_put(__s, __intl, __io, __fill, __digits); }
426097403Sobrien
426197403Sobrien    protected:
4262132720Skan      /// Destructor.
4263132720Skan      virtual
426497403Sobrien      ~money_put() { }
426597403Sobrien
4266132720Skan      /**
4267132720Skan       *  @brief  Format and output a monetary value.
4268132720Skan       *
4269132720Skan       *  This function formats @a units as a monetary value according to
4270132720Skan       *  moneypunct and ctype facets retrieved from io.getloc(), and writes
4271132720Skan       *  the resulting characters to @a s.  For example, the value 1001 in a
4272132720Skan       *  US locale would write "$10.01" to @a s.
4273132720Skan       *
4274132720Skan       *  This function is a hook for derived classes to change the value
4275132720Skan       *  returned.  @see put().
4276132720Skan       *
4277132720Skan       *  @param  s  The stream to write to.
4278132720Skan       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
4279132720Skan       *  @param  io  Source of facets and io state.
4280132720Skan       *  @param  fill  char_type to use for padding.
4281132720Skan       *  @param  units  Place to store result of parsing.
4282132720Skan       *  @return  Iterator after writing.
4283132720Skan       */
4284169691Skan      // XXX GLIBCXX_ABI Deprecated
4285169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
428697403Sobrien      virtual iter_type
4287169691Skan      __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
4288169691Skan	       double __units) const;
4289169691Skan#else
4290169691Skan      virtual iter_type
429197403Sobrien      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
429297403Sobrien	     long double __units) const;
4293169691Skan#endif
429497403Sobrien
4295132720Skan      /**
4296132720Skan       *  @brief  Format and output a monetary value.
4297132720Skan       *
4298132720Skan       *  This function formats @a digits as a monetary value according to
4299132720Skan       *  moneypunct and ctype facets retrieved from io.getloc(), and writes
4300132720Skan       *  the resulting characters to @a s.  For example, the string "1001" in
4301132720Skan       *  a US locale would write "$10.01" to @a s.
4302132720Skan       *
4303132720Skan       *  This function is a hook for derived classes to change the value
4304132720Skan       *  returned.  @see put().
4305132720Skan       *
4306132720Skan       *  @param  s  The stream to write to.
4307132720Skan       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.
4308132720Skan       *  @param  io  Source of facets and io state.
4309132720Skan       *  @param  fill  char_type to use for padding.
4310132720Skan       *  @param  units  Place to store result of parsing.
4311132720Skan       *  @return  Iterator after writing.
4312132720Skan       */
431397403Sobrien      virtual iter_type
431497403Sobrien      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
431597403Sobrien	     const string_type& __digits) const;
4316132720Skan
4317169691Skan      // XXX GLIBCXX_ABI Deprecated
4318169691Skan#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
4319169691Skan      virtual iter_type
4320169691Skan      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
4321169691Skan	     long double __units) const;
4322169691Skan#endif
4323169691Skan
4324132720Skan      template<bool _Intl>
4325132720Skan        iter_type
4326132720Skan        _M_insert(iter_type __s, ios_base& __io, char_type __fill,
4327132720Skan		  const string_type& __digits) const;
432897403Sobrien    };
432997403Sobrien
433097403Sobrien  template<typename _CharT, typename _OutIter>
433197403Sobrien    locale::id money_put<_CharT, _OutIter>::id;
433297403Sobrien
4333169691Skan_GLIBCXX_END_LDBL_NAMESPACE
4334169691Skan
4335132720Skan  /**
4336132720Skan   *  @brief  Messages facet base class providing catalog typedef.
4337132720Skan   */
4338241957Sdim  class messages_base
433997403Sobrien  {
4340241957Sdim  public:
434197403Sobrien    typedef int catalog;
434297403Sobrien  };
434397403Sobrien
4344132720Skan  /**
4345132720Skan   *  @brief  Facet for handling message catalogs
4346132720Skan   *
4347132720Skan   *  This facet encapsulates the code to retrieve messages from
4348132720Skan   *  message catalogs.  The only thing defined by the standard for this facet
4349132720Skan   *  is the interface.  All underlying functionality is
4350132720Skan   *  implementation-defined.
4351132720Skan   *
4352132720Skan   *  This library currently implements 3 versions of the message facet.  The
4353132720Skan   *  first version (gnu) is a wrapper around gettext, provided by libintl.
4354132720Skan   *  The second version (ieee) is a wrapper around catgets.  The final
4355132720Skan   *  version (default) does no actual translation.  These implementations are
4356132720Skan   *  only provided for char and wchar_t instantiations.
4357132720Skan   *
4358132720Skan   *  The messages template uses protected virtual functions to
4359132720Skan   *  provide the actual results.  The public accessors forward the
4360132720Skan   *  call to the virtual functions.  These virtual functions are
4361132720Skan   *  hooks for developers to implement the behavior they require from
4362132720Skan   *  the messages facet.
4363132720Skan  */
436497403Sobrien  template<typename _CharT>
436597403Sobrien    class messages : public locale::facet, public messages_base
436697403Sobrien    {
436797403Sobrien    public:
436897403Sobrien      // Types:
4369132720Skan      //@{
4370132720Skan      /// Public typedefs
4371132720Skan      typedef _CharT			char_type;
4372132720Skan      typedef basic_string<_CharT>	string_type;
4373132720Skan      //@}
437497403Sobrien
437597403Sobrien    protected:
437697403Sobrien      // Underlying "C" library locale information saved from
437797403Sobrien      // initialization, needed by messages_byname as well.
437897403Sobrien      __c_locale			_M_c_locale_messages;
4379132720Skan      const char*			_M_name_messages;
438097403Sobrien
438197403Sobrien    public:
4382132720Skan      /// Numpunct facet id.
4383132720Skan      static locale::id			id;
438497403Sobrien
4385132720Skan      /**
4386132720Skan       *  @brief  Constructor performs initialization.
4387132720Skan       *
4388132720Skan       *  This is the constructor provided by the standard.
4389132720Skan       *
4390132720Skan       *  @param refs  Passed to the base facet class.
4391132720Skan      */
4392132720Skan      explicit
4393110614Skan      messages(size_t __refs = 0);
439497403Sobrien
439597403Sobrien      // Non-standard.
4396132720Skan      /**
4397132720Skan       *  @brief  Internal constructor.  Not for general use.
4398132720Skan       *
4399132720Skan       *  This is a constructor for use by the library itself to set up new
4400132720Skan       *  locales.
4401132720Skan       *
4402132720Skan       *  @param  cloc  The "C" locale.
4403132720Skan       *  @param  s  The name of a locale.
4404132720Skan       *  @param  refs  Refcount to pass to the base class.
4405132720Skan       */
4406132720Skan      explicit
4407110614Skan      messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
440897403Sobrien
4409132720Skan      /*
4410132720Skan       *  @brief  Open a message catalog.
4411132720Skan       *
4412132720Skan       *  This function opens and returns a handle to a message catalog by
4413132720Skan       *  returning do_open(s, loc).
4414132720Skan       *
4415132720Skan       *  @param  s  The catalog to open.
4416132720Skan       *  @param  loc  Locale to use for character set conversions.
4417132720Skan       *  @return  Handle to the catalog or value < 0 if open fails.
4418132720Skan      */
4419132720Skan      catalog
442097403Sobrien      open(const basic_string<char>& __s, const locale& __loc) const
442197403Sobrien      { return this->do_open(__s, __loc); }
442297403Sobrien
442397403Sobrien      // Non-standard and unorthodox, yet effective.
4424132720Skan      /*
4425132720Skan       *  @brief  Open a message catalog.
4426132720Skan       *
4427132720Skan       *  This non-standard function opens and returns a handle to a message
4428132720Skan       *  catalog by returning do_open(s, loc).  The third argument provides a
4429132720Skan       *  message catalog root directory for gnu gettext and is ignored
4430132720Skan       *  otherwise.
4431132720Skan       *
4432132720Skan       *  @param  s  The catalog to open.
4433132720Skan       *  @param  loc  Locale to use for character set conversions.
4434132720Skan       *  @param  dir  Message catalog root directory.
4435132720Skan       *  @return  Handle to the catalog or value < 0 if open fails.
4436132720Skan      */
4437132720Skan      catalog
443897403Sobrien      open(const basic_string<char>&, const locale&, const char*) const;
443997403Sobrien
4440132720Skan      /*
4441132720Skan       *  @brief  Look up a string in a message catalog.
4442132720Skan       *
4443132720Skan       *  This function retrieves and returns a message from a catalog by
4444132720Skan       *  returning do_get(c, set, msgid, s).
4445132720Skan       *
4446132720Skan       *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
4447132720Skan       *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
4448132720Skan       *
4449132720Skan       *  @param  c  The catalog to access.
4450132720Skan       *  @param  set  Implementation-defined.
4451132720Skan       *  @param  msgid  Implementation-defined.
4452132720Skan       *  @param  s  Default return value if retrieval fails.
4453132720Skan       *  @return  Retrieved message or @a s if get fails.
4454132720Skan      */
4455132720Skan      string_type
445697403Sobrien      get(catalog __c, int __set, int __msgid, const string_type& __s) const
445797403Sobrien      { return this->do_get(__c, __set, __msgid, __s); }
445897403Sobrien
4459132720Skan      /*
4460132720Skan       *  @brief  Close a message catalog.
4461132720Skan       *
4462132720Skan       *  Closes catalog @a c by calling do_close(c).
4463132720Skan       *
4464132720Skan       *  @param  c  The catalog to close.
4465132720Skan      */
4466132720Skan      void
446797403Sobrien      close(catalog __c) const
446897403Sobrien      { return this->do_close(__c); }
446997403Sobrien
447097403Sobrien    protected:
4471132720Skan      /// Destructor.
4472132720Skan      virtual
4473110614Skan      ~messages();
447497403Sobrien
4475132720Skan      /*
4476132720Skan       *  @brief  Open a message catalog.
4477132720Skan       *
4478132720Skan       *  This function opens and returns a handle to a message catalog in an
4479132720Skan       *  implementation-defined manner.  This function is a hook for derived
4480132720Skan       *  classes to change the value returned.
4481132720Skan       *
4482132720Skan       *  @param  s  The catalog to open.
4483132720Skan       *  @param  loc  Locale to use for character set conversions.
4484132720Skan       *  @return  Handle to the opened catalog, value < 0 if open failed.
4485132720Skan      */
4486132720Skan      virtual catalog
448797403Sobrien      do_open(const basic_string<char>&, const locale&) const;
448897403Sobrien
4489132720Skan      /*
4490132720Skan       *  @brief  Look up a string in a message catalog.
4491132720Skan       *
4492132720Skan       *  This function retrieves and returns a message from a catalog in an
4493132720Skan       *  implementation-defined manner.  This function is a hook for derived
4494132720Skan       *  classes to change the value returned.
4495132720Skan       *
4496132720Skan       *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).
4497132720Skan       *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).
4498132720Skan       *
4499132720Skan       *  @param  c  The catalog to access.
4500132720Skan       *  @param  set  Implementation-defined.
4501132720Skan       *  @param  msgid  Implementation-defined.
4502132720Skan       *  @param  s  Default return value if retrieval fails.
4503132720Skan       *  @return  Retrieved message or @a s if get fails.
4504132720Skan      */
4505132720Skan      virtual string_type
450697403Sobrien      do_get(catalog, int, int, const string_type& __dfault) const;
450797403Sobrien
4508132720Skan      /*
4509132720Skan       *  @brief  Close a message catalog.
4510132720Skan       *
4511132720Skan       *  @param  c  The catalog to close.
4512132720Skan      */
4513132720Skan      virtual void
451497403Sobrien      do_close(catalog) const;
451597403Sobrien
451697403Sobrien      // Returns a locale and codeset-converted string, given a char* message.
451797403Sobrien      char*
451897403Sobrien      _M_convert_to_char(const string_type& __msg) const
451997403Sobrien      {
452097403Sobrien	// XXX
452197403Sobrien	return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
452297403Sobrien      }
452397403Sobrien
452497403Sobrien      // Returns a locale and codeset-converted string, given a char* message.
452597403Sobrien      string_type
4526132720Skan      _M_convert_from_char(char*) const
452797403Sobrien      {
4528132720Skan#if 0
452997403Sobrien	// Length of message string without terminating null.
453097403Sobrien	size_t __len = char_traits<char>::length(__msg) - 1;
453197403Sobrien
453297403Sobrien	// "everybody can easily convert the string using
453397403Sobrien	// mbsrtowcs/wcsrtombs or with iconv()"
4534132720Skan
453597403Sobrien	// Convert char* to _CharT in locale used to open catalog.
453697403Sobrien	// XXX need additional template parameter on messages class for this..
453797403Sobrien	// typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
4538132720Skan	typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
453997403Sobrien
454097403Sobrien	__codecvt_type::state_type __state;
454197403Sobrien	// XXX may need to initialize state.
454297403Sobrien	//initialize_state(__state._M_init());
4543132720Skan
454497403Sobrien	char* __from_next;
454597403Sobrien	// XXX what size for this string?
454697403Sobrien	_CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
454797403Sobrien	const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
454897403Sobrien	__cvt.out(__state, __msg, __msg + __len, __from_next,
454997403Sobrien		  __to, __to + __len + 1, __to_next);
455097403Sobrien	return string_type(__to);
455197403Sobrien#endif
455297403Sobrien#if 0
455397403Sobrien	typedef ctype<_CharT> __ctype_type;
455497403Sobrien	// const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
455597403Sobrien	const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
455697403Sobrien	// XXX Again, proper length of converted string an issue here.
455797403Sobrien	// For now, assume the converted length is not larger.
455897403Sobrien	_CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
455997403Sobrien	__cvt.widen(__msg, __msg + __len, __dest);
456097403Sobrien	return basic_string<_CharT>(__dest);
456197403Sobrien#endif
456297403Sobrien	return string_type();
456397403Sobrien      }
456497403Sobrien     };
456597403Sobrien
456697403Sobrien  template<typename _CharT>
456797403Sobrien    locale::id messages<_CharT>::id;
456897403Sobrien
456997403Sobrien  // Specializations for required instantiations.
457097403Sobrien  template<>
457197403Sobrien    string
457297403Sobrien    messages<char>::do_get(catalog, int, int, const string&) const;
457397403Sobrien
4574132720Skan#ifdef _GLIBCXX_USE_WCHAR_T
4575103447Skan  template<>
4576103447Skan    wstring
4577103447Skan    messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
4578103447Skan#endif
4579103447Skan
4580169691Skan   /// @brief class messages_byname [22.2.7.2].
4581169691Skan   template<typename _CharT>
458297403Sobrien    class messages_byname : public messages<_CharT>
458397403Sobrien    {
458497403Sobrien    public:
4585132720Skan      typedef _CharT			char_type;
4586132720Skan      typedef basic_string<_CharT>	string_type;
458797403Sobrien
4588132720Skan      explicit
4589110614Skan      messages_byname(const char* __s, size_t __refs = 0);
459097403Sobrien
459197403Sobrien    protected:
4592132720Skan      virtual
4593132720Skan      ~messages_byname()
459497403Sobrien      { }
459597403Sobrien    };
459697403Sobrien
4597169691Skan_GLIBCXX_END_NAMESPACE
4598169691Skan
4599110614Skan  // Include host and configuration specific messages functions.
4600110614Skan  #include <bits/messages_members.h>
460197403Sobrien
4602169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
4603110614Skan
460497403Sobrien  // Subclause convenience interfaces, inlines.
460597403Sobrien  // NB: These are inline because, when used in a loop, some compilers
460697403Sobrien  // can hoist the body out of the loop; then it's just as fast as the
460797403Sobrien  // C is*() function.
4608169691Skan
4609169691Skan  /// Convenience interface to ctype.is(ctype_base::space, __c).
461097403Sobrien  template<typename _CharT>
4611132720Skan    inline bool
461297403Sobrien    isspace(_CharT __c, const locale& __loc)
461397403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
461497403Sobrien
4615169691Skan  /// Convenience interface to ctype.is(ctype_base::print, __c).
461697403Sobrien  template<typename _CharT>
4617132720Skan    inline bool
461897403Sobrien    isprint(_CharT __c, const locale& __loc)
461997403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
462097403Sobrien
4621169691Skan  /// Convenience interface to ctype.is(ctype_base::cntrl, __c).
462297403Sobrien  template<typename _CharT>
4623132720Skan    inline bool
462497403Sobrien    iscntrl(_CharT __c, const locale& __loc)
462597403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
462697403Sobrien
4627169691Skan  /// Convenience interface to ctype.is(ctype_base::upper, __c).
462897403Sobrien  template<typename _CharT>
4629132720Skan    inline bool
463097403Sobrien    isupper(_CharT __c, const locale& __loc)
463197403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
463297403Sobrien
4633169691Skan  /// Convenience interface to ctype.is(ctype_base::lower, __c).
463497403Sobrien  template<typename _CharT>
4635169691Skan    inline bool
4636169691Skan    islower(_CharT __c, const locale& __loc)
463797403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
463897403Sobrien
4639169691Skan  /// Convenience interface to ctype.is(ctype_base::alpha, __c).
464097403Sobrien  template<typename _CharT>
4641132720Skan    inline bool
464297403Sobrien    isalpha(_CharT __c, const locale& __loc)
464397403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
464497403Sobrien
4645169691Skan  /// Convenience interface to ctype.is(ctype_base::digit, __c).
464697403Sobrien  template<typename _CharT>
4647132720Skan    inline bool
464897403Sobrien    isdigit(_CharT __c, const locale& __loc)
464997403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
465097403Sobrien
4651169691Skan  /// Convenience interface to ctype.is(ctype_base::punct, __c).
465297403Sobrien  template<typename _CharT>
4653132720Skan    inline bool
465497403Sobrien    ispunct(_CharT __c, const locale& __loc)
465597403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
465697403Sobrien
4657169691Skan  /// Convenience interface to ctype.is(ctype_base::xdigit, __c).
465897403Sobrien  template<typename _CharT>
4659132720Skan    inline bool
466097403Sobrien    isxdigit(_CharT __c, const locale& __loc)
466197403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
466297403Sobrien
4663169691Skan  /// Convenience interface to ctype.is(ctype_base::alnum, __c).
466497403Sobrien  template<typename _CharT>
4665132720Skan    inline bool
466697403Sobrien    isalnum(_CharT __c, const locale& __loc)
466797403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
466897403Sobrien
4669169691Skan  /// Convenience interface to ctype.is(ctype_base::graph, __c).
467097403Sobrien  template<typename _CharT>
4671132720Skan    inline bool
467297403Sobrien    isgraph(_CharT __c, const locale& __loc)
467397403Sobrien    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
467497403Sobrien
4675169691Skan  /// Convenience interface to ctype.toupper(__c).
467697403Sobrien  template<typename _CharT>
4677132720Skan    inline _CharT
467897403Sobrien    toupper(_CharT __c, const locale& __loc)
467997403Sobrien    { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
468097403Sobrien
4681169691Skan  /// Convenience interface to ctype.tolower(__c).
468297403Sobrien  template<typename _CharT>
4683132720Skan    inline _CharT
468497403Sobrien    tolower(_CharT __c, const locale& __loc)
468597403Sobrien    { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
468697403Sobrien
4687169691Skan_GLIBCXX_END_NAMESPACE
4688169691Skan
468997403Sobrien#endif
4690