1// Locale support -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING.  If not, write to the Free
19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction.  Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License.  This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31//
32// ISO C++ 14882: 22.1  Locales
33//
34
35/** @file locale_facets.h
36 *  This is an internal header file, included by other library headers.
37 *  You should not attempt to use it directly.
38 */
39
40#ifndef _CPP_BITS_LOCFACETS_H
41#define _CPP_BITS_LOCFACETS_H	1
42
43#pragma GCC system_header
44
45#include <ctime>	// For struct tm
46#include <cwctype>	// For wctype_t
47#include <iosfwd>
48#include <bits/ios_base.h>  // For ios_base, ios_base::iostate
49#include <streambuf>
50
51namespace std
52{
53  // NB: Don't instantiate required wchar_t facets if no wchar_t support.
54#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
55# define  _GLIBCPP_NUM_FACETS 28
56#else
57# define  _GLIBCPP_NUM_FACETS 14
58#endif
59
60  // Convert string to numeric value of type _Tv and store results.
61  // NB: This is specialized for all required types, there is no
62  // generic definition.
63  template<typename _Tv>
64    void
65    __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
66		   const __c_locale& __cloc, int __base = 10);
67
68  // Explicit specializations for required types.
69  template<>
70    void
71    __convert_to_v(const char*, long&, ios_base::iostate&,
72		   const __c_locale&, int);
73
74  template<>
75    void
76    __convert_to_v(const char*, unsigned long&, ios_base::iostate&,
77		   const __c_locale&, int);
78
79#ifdef _GLIBCPP_USE_LONG_LONG
80  template<>
81    void
82    __convert_to_v(const char*, long long&, ios_base::iostate&,
83		   const __c_locale&, int);
84
85  template<>
86    void
87    __convert_to_v(const char*, unsigned long long&, ios_base::iostate&,
88		   const __c_locale&, int);
89#endif
90
91  template<>
92    void
93    __convert_to_v(const char*, float&, ios_base::iostate&,
94		   const __c_locale&, int);
95
96  template<>
97    void
98    __convert_to_v(const char*, double&, ios_base::iostate&,
99		   const __c_locale&, int);
100
101 template<>
102    void
103    __convert_to_v(const char*, long double&, ios_base::iostate&,
104		   const __c_locale&, int);
105
106  // NB: __pad is a struct, rather than a function, so it can be
107  // partially-specialized.
108  template<typename _CharT, typename _Traits>
109    struct __pad
110    {
111      static void
112      _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
113	     const _CharT* __olds, const streamsize __newlen,
114	     const streamsize __oldlen, const bool __num);
115    };
116
117  // Used by both numeric and monetary facets.
118  // Check to make sure that the __grouping_tmp string constructed in
119  // money_get or num_get matches the canonical grouping for a given
120  // locale.
121  // __grouping_tmp is parsed L to R
122  // 1,222,444 == __grouping_tmp of "\1\3\3"
123  // __grouping is parsed R to L
124  // 1,222,444 == __grouping of "\3" == "\3\3\3"
125  template<typename _CharT>
126    bool
127    __verify_grouping(const basic_string<_CharT>& __grouping,
128		      basic_string<_CharT>& __grouping_tmp);
129
130  // Used by both numeric and monetary facets.
131  // Inserts "group separator" characters into an array of characters.
132  // It's recursive, one iteration per group.  It moves the characters
133  // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
134  // only with __gbeg != __gend.
135  template<typename _CharT>
136    _CharT*
137    __add_grouping(_CharT* __s, _CharT __sep,
138		   const char* __gbeg, const char* __gend,
139		   const _CharT* __first, const _CharT* __last);
140
141  // This template permits specializing facet output code for
142  // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
143  // significantly more efficient than incrementing iterators.
144  template<typename _CharT>
145    inline
146    ostreambuf_iterator<_CharT>
147    __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
148    {
149      __s._M_put(__ws, __len);
150      return __s;
151    }
152
153  // This is the unspecialized form of the template.
154  template<typename _CharT, typename _OutIter>
155    inline
156    _OutIter
157    __write(_OutIter __s, const _CharT* __ws, int __len)
158    {
159      for (int __j = 0; __j < __len; __j++, ++__s)
160	*__s = __ws[__j];
161      return __s;
162    }
163
164  // 22.2.1.1  Template class ctype
165  // Include host and configuration specific ctype enums for ctype_base.
166  #include <bits/ctype_base.h>
167
168  // Common base for ctype<_CharT>.
169  template<typename _CharT>
170    class __ctype_abstract_base : public locale::facet, public ctype_base
171    {
172    public:
173      // Types:
174      typedef _CharT char_type;
175
176      bool
177      is(mask __m, char_type __c) const
178      { return this->do_is(__m, __c); }
179
180      const char_type*
181      is(const char_type *__lo, const char_type *__hi, mask *__vec) const
182      { return this->do_is(__lo, __hi, __vec); }
183
184      const char_type*
185      scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
186      { return this->do_scan_is(__m, __lo, __hi); }
187
188      const char_type*
189      scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
190      { return this->do_scan_not(__m, __lo, __hi); }
191
192      char_type
193      toupper(char_type __c) const
194      { return this->do_toupper(__c); }
195
196      const char_type*
197      toupper(char_type *__lo, const char_type* __hi) const
198      { return this->do_toupper(__lo, __hi); }
199
200      char_type
201      tolower(char_type __c) const
202      { return this->do_tolower(__c); }
203
204      const char_type*
205      tolower(char_type* __lo, const char_type* __hi) const
206      { return this->do_tolower(__lo, __hi); }
207
208      char_type
209      widen(char __c) const
210      { return this->do_widen(__c); }
211
212      const char*
213      widen(const char* __lo, const char* __hi, char_type* __to) const
214      { return this->do_widen(__lo, __hi, __to); }
215
216      char
217      narrow(char_type __c, char __dfault) const
218      { return this->do_narrow(__c, __dfault); }
219
220      const char_type*
221      narrow(const char_type* __lo, const char_type* __hi,
222	      char __dfault, char *__to) const
223      { return this->do_narrow(__lo, __hi, __dfault, __to); }
224
225    protected:
226      explicit
227      __ctype_abstract_base(size_t __refs = 0): locale::facet(__refs) { }
228
229      virtual
230      ~__ctype_abstract_base() { }
231
232      virtual bool
233      do_is(mask __m, char_type __c) const = 0;
234
235      virtual const char_type*
236      do_is(const char_type* __lo, const char_type* __hi,
237	    mask* __vec) const = 0;
238
239      virtual const char_type*
240      do_scan_is(mask __m, const char_type* __lo,
241		 const char_type* __hi) const = 0;
242
243      virtual const char_type*
244      do_scan_not(mask __m, const char_type* __lo,
245		  const char_type* __hi) const = 0;
246
247      virtual char_type
248      do_toupper(char_type) const = 0;
249
250      virtual const char_type*
251      do_toupper(char_type* __lo, const char_type* __hi) const = 0;
252
253      virtual char_type
254      do_tolower(char_type) const = 0;
255
256      virtual const char_type*
257      do_tolower(char_type* __lo, const char_type* __hi) const = 0;
258
259      virtual char_type
260      do_widen(char) const = 0;
261
262      virtual const char*
263      do_widen(const char* __lo, const char* __hi,
264	       char_type* __dest) const = 0;
265
266      virtual char
267      do_narrow(char_type, char __dfault) const = 0;
268
269      virtual const char_type*
270      do_narrow(const char_type* __lo, const char_type* __hi,
271		 char __dfault, char* __dest) const = 0;
272    };
273
274  // NB: Generic, mostly useless implementation.
275  template<typename _CharT>
276    class ctype : public __ctype_abstract_base<_CharT>
277    {
278    public:
279      // Types:
280      typedef _CharT 		  	char_type;
281      typedef typename ctype::mask 	mask;
282
283      static locale::id 	       	id;
284
285      explicit
286      ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
287
288   protected:
289      virtual
290      ~ctype();
291
292      virtual bool
293      do_is(mask __m, char_type __c) const;
294
295      virtual const char_type*
296      do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
297
298      virtual const char_type*
299      do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
300
301      virtual const char_type*
302      do_scan_not(mask __m, const char_type* __lo,
303		  const char_type* __hi) const;
304
305      virtual char_type
306      do_toupper(char_type __c) const;
307
308      virtual const char_type*
309      do_toupper(char_type* __lo, const char_type* __hi) const;
310
311      virtual char_type
312      do_tolower(char_type __c) const;
313
314      virtual const char_type*
315      do_tolower(char_type* __lo, const char_type* __hi) const;
316
317      virtual char_type
318      do_widen(char __c) const;
319
320      virtual const char*
321      do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
322
323      virtual char
324      do_narrow(char_type, char __dfault) const;
325
326      virtual const char_type*
327      do_narrow(const char_type* __lo, const char_type* __hi,
328		char __dfault, char* __dest) const;
329    };
330
331  template<typename _CharT>
332    locale::id ctype<_CharT>::id;
333
334  // 22.2.1.3  ctype<char> specialization.
335  template<>
336    class ctype<char> : public __ctype_abstract_base<char>
337    {
338    public:
339      // Types:
340      typedef char 	       	char_type;
341
342    protected:
343      // Data Members:
344      __c_locale		_M_c_locale_ctype;
345      bool 		       	_M_del;
346      __to_type 	       	_M_toupper;
347      __to_type  	       	_M_tolower;
348      const mask*              	_M_table;
349
350    public:
351      static locale::id        id;
352      static const size_t      table_size = 1 + static_cast<unsigned char>(-1);
353
354      explicit
355      ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
356
357      explicit
358      ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
359	    size_t __refs = 0);
360
361      inline bool
362      is(mask __m, char __c) const;
363
364      inline const char*
365      is(const char* __lo, const char* __hi, mask* __vec) const;
366
367      inline const char*
368      scan_is(mask __m, const char* __lo, const char* __hi) const;
369
370      inline const char*
371      scan_not(mask __m, const char* __lo, const char* __hi) const;
372
373    protected:
374      const mask*
375      table() const throw()
376      { return _M_table; }
377
378      static const mask*
379      classic_table() throw();
380
381      virtual
382      ~ctype();
383
384      virtual bool
385      do_is(mask __m, char_type __c) const;
386
387      virtual const char_type*
388      do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
389
390      virtual const char_type*
391      do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
392
393      virtual const char_type*
394      do_scan_not(mask __m, const char_type* __lo,
395		  const char_type* __hi) const;
396
397      virtual char_type
398      do_toupper(char_type) const;
399
400      virtual const char_type*
401      do_toupper(char_type* __lo, const char_type* __hi) const;
402
403      virtual char_type
404      do_tolower(char_type) const;
405
406      virtual const char_type*
407      do_tolower(char_type* __lo, const char_type* __hi) const;
408
409      virtual char_type
410      do_widen(char) const;
411
412      virtual const char*
413      do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
414
415      virtual char
416      do_narrow(char_type, char __dfault) const;
417
418      virtual const char_type*
419      do_narrow(const char_type* __lo, const char_type* __hi,
420		char __dfault, char* __dest) const;
421    };
422
423  template<>
424    const ctype<char>&
425    use_facet<ctype<char> >(const locale& __loc);
426
427#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
428  // 22.2.1.3  ctype<wchar_t> specialization
429  template<>
430    class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
431    {
432    public:
433      // Types:
434      typedef wchar_t 	       	char_type;
435      typedef wctype_t	       	__wmask_type;
436
437    protected:
438      __c_locale		_M_c_locale_ctype;
439
440    public:
441      // Data Members:
442      static locale::id        	id;
443
444      explicit
445      ctype(size_t __refs = 0);
446
447      explicit
448      ctype(__c_locale __cloc, size_t __refs = 0);
449
450    protected:
451      __wmask_type
452      _M_convert_to_wmask(const mask __m) const;
453
454      virtual
455      ~ctype();
456
457      virtual bool
458      do_is(mask __m, char_type __c) const;
459
460      virtual const char_type*
461      do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
462
463      virtual const char_type*
464      do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
465
466      virtual const char_type*
467      do_scan_not(mask __m, const char_type* __lo,
468		  const char_type* __hi) const;
469
470      virtual char_type
471      do_toupper(char_type) const;
472
473      virtual const char_type*
474      do_toupper(char_type* __lo, const char_type* __hi) const;
475
476      virtual char_type
477      do_tolower(char_type) const;
478
479      virtual const char_type*
480      do_tolower(char_type* __lo, const char_type* __hi) const;
481
482      virtual char_type
483      do_widen(char) const;
484
485      virtual const char*
486      do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
487
488      virtual char
489      do_narrow(char_type, char __dfault) const;
490
491      virtual const char_type*
492      do_narrow(const char_type* __lo, const char_type* __hi,
493		char __dfault, char* __dest) const;
494
495    };
496
497  template<>
498    const ctype<wchar_t>&
499    use_facet<ctype<wchar_t> >(const locale& __loc);
500#endif //_GLIBCPP_USE_WCHAR_T
501
502  // Include host and configuration specific ctype inlines.
503  #include <bits/ctype_inline.h>
504
505  // 22.2.1.2  Template class ctype_byname
506  template<typename _CharT>
507    class ctype_byname : public ctype<_CharT>
508    {
509    public:
510      typedef _CharT 		char_type;
511
512      explicit
513      ctype_byname(const char* __s, size_t __refs = 0);
514
515    protected:
516      virtual
517      ~ctype_byname() { };
518    };
519
520  // 22.2.1.4  Class ctype_byname specializations.
521  template<>
522    ctype_byname<char>::ctype_byname(const char*, size_t refs);
523
524  template<>
525    ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);
526
527  // 22.2.1.5  Template class codecvt
528  #include <bits/codecvt.h>
529
530  // 22.2.2  The numeric category.
531  class __num_base
532  {
533  public:
534    // NB: Code depends on the order of _S_atoms_out elements.
535    // Below are the indices into _S_atoms_out.
536    enum
537      {
538        _S_minus,
539        _S_plus,
540        _S_x,
541        _S_X,
542        _S_digits,
543        _S_digits_end = _S_digits + 16,
544        _S_udigits = _S_digits_end,
545        _S_udigits_end = _S_udigits + 16,
546        _S_e = _S_digits + 14,  // For scientific notation, 'e'
547        _S_E = _S_udigits + 14, // For scientific notation, 'E'
548	_S_end = _S_udigits_end
549      };
550
551    // A list of valid numeric literals for output.  This array
552    // contains chars that will be passed through the current locale's
553    // ctype<_CharT>.widen() and then used to render numbers.
554    // For the standard "C" locale, this is
555    // "-+xX0123456789abcdef0123456789ABCDEF".
556    static const char* _S_atoms_out;
557
558  protected:
559    // String literal of acceptable (narrow) input, for num_get.
560    // "0123456789eEabcdfABCDF"
561    static const char* _S_atoms_in;
562
563    enum
564    {
565      _M_zero,
566      _M_e = _M_zero + 10,
567      _M_E = _M_zero + 11,
568      _M_size = 21 + 1
569    };
570
571    // num_put
572    // Construct and return valid scanf format for floating point types.
573    static void
574    _S_format_float(const ios_base& __io, char* __fptr, char __mod,
575		    streamsize __prec);
576
577    // Construct and return valid scanf format for integer types.
578    static void
579    _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
580  };
581
582
583  template<typename _CharT>
584    class __locale_cache;
585
586  template<typename _CharT>
587    class numpunct : public locale::facet
588    {
589    public:
590      // Types:
591      typedef _CharT          		char_type;
592      typedef basic_string<_CharT> 	string_type;
593
594      friend class __locale_cache<numpunct<_CharT> >;
595
596      static locale::id 		id;
597
598    private:
599      char_type 			_M_decimal_point;
600      char_type 			_M_thousands_sep;
601      const char* 			_M_grouping;
602      const char_type* 			_M_truename;
603      const char_type*			_M_falsename;
604
605    public:
606      explicit
607      numpunct(size_t __refs = 0) : locale::facet(__refs)
608      { _M_initialize_numpunct(); }
609
610      explicit
611      numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
612      { _M_initialize_numpunct(__cloc); }
613
614      char_type
615      decimal_point() const
616      { return this->do_decimal_point(); }
617
618      char_type
619      thousands_sep() const
620      { return this->do_thousands_sep(); }
621
622      string
623      grouping() const
624      { return this->do_grouping(); }
625
626      string_type
627      truename() const
628      { return this->do_truename(); }
629
630      string_type
631      falsename() const
632      { return this->do_falsename(); }
633
634    protected:
635      virtual
636      ~numpunct();
637
638      virtual char_type
639      do_decimal_point() const
640      { return _M_decimal_point; }
641
642      virtual char_type
643      do_thousands_sep() const
644      { return _M_thousands_sep; }
645
646      virtual string
647      do_grouping() const
648      { return _M_grouping; }
649
650      virtual string_type
651      do_truename() const
652      { return _M_truename; }
653
654      virtual string_type
655      do_falsename() const
656      { return _M_falsename; }
657
658      // For use at construction time only.
659      void
660      _M_initialize_numpunct(__c_locale __cloc = NULL);
661    };
662
663  template<typename _CharT>
664    locale::id numpunct<_CharT>::id;
665
666  template<>
667    numpunct<char>::~numpunct();
668
669  template<>
670    void
671    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
672
673#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
674  template<>
675    numpunct<wchar_t>::~numpunct();
676
677  template<>
678    void
679    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
680#endif
681
682  template<typename _CharT>
683    class numpunct_byname : public numpunct<_CharT>
684    {
685      // Data Member.
686      __c_locale			_M_c_locale_numpunct;
687
688    public:
689      typedef _CharT               	char_type;
690      typedef basic_string<_CharT> 	string_type;
691
692      explicit
693      numpunct_byname(const char* __s, size_t __refs = 0)
694      : numpunct<_CharT>(__refs)
695      {
696	_S_create_c_locale(_M_c_locale_numpunct, __s);
697	_M_initialize_numpunct(_M_c_locale_numpunct);
698      }
699
700    protected:
701      virtual
702      ~numpunct_byname()
703      { _S_destroy_c_locale(_M_c_locale_numpunct); }
704    };
705
706  template<typename _CharT, typename _InIter>
707    class num_get : public locale::facet, public __num_base
708    {
709    public:
710      // Types:
711      typedef _CharT   			char_type;
712      typedef _InIter  			iter_type;
713
714      static locale::id 		id;
715
716      explicit
717      num_get(size_t __refs = 0) : locale::facet(__refs) { }
718
719      iter_type
720      get(iter_type __in, iter_type __end, ios_base& __io,
721	  ios_base::iostate& __err, bool& __v) const
722      { return this->do_get(__in, __end, __io, __err, __v); }
723
724      iter_type
725      get(iter_type __in, iter_type __end, ios_base& __io,
726	  ios_base::iostate& __err, long& __v) const
727      { return this->do_get(__in, __end, __io, __err, __v); }
728
729      iter_type
730      get(iter_type __in, iter_type __end, ios_base& __io,
731	  ios_base::iostate& __err, unsigned short& __v) const
732      { return this->do_get(__in, __end, __io, __err, __v); }
733
734      iter_type
735      get(iter_type __in, iter_type __end, ios_base& __io,
736	  ios_base::iostate& __err, unsigned int& __v)   const
737      { return this->do_get(__in, __end, __io, __err, __v); }
738
739      iter_type
740      get(iter_type __in, iter_type __end, ios_base& __io,
741	  ios_base::iostate& __err, unsigned long& __v)  const
742      { return this->do_get(__in, __end, __io, __err, __v); }
743
744#ifdef _GLIBCPP_USE_LONG_LONG
745      iter_type
746      get(iter_type __in, iter_type __end, ios_base& __io,
747	  ios_base::iostate& __err, long long& __v) const
748      { return this->do_get(__in, __end, __io, __err, __v); }
749
750      iter_type
751      get(iter_type __in, iter_type __end, ios_base& __io,
752	  ios_base::iostate& __err, unsigned long long& __v)  const
753      { return this->do_get(__in, __end, __io, __err, __v); }
754#endif
755
756      iter_type
757      get(iter_type __in, iter_type __end, ios_base& __io,
758	  ios_base::iostate& __err, float& __v) const
759      { return this->do_get(__in, __end, __io, __err, __v); }
760
761      iter_type
762      get(iter_type __in, iter_type __end, ios_base& __io,
763	  ios_base::iostate& __err, double& __v) const
764      { return this->do_get(__in, __end, __io, __err, __v); }
765
766      iter_type
767      get(iter_type __in, iter_type __end, ios_base& __io,
768	  ios_base::iostate& __err, long double& __v) const
769      { return this->do_get(__in, __end, __io, __err, __v); }
770
771      iter_type
772      get(iter_type __in, iter_type __end, ios_base& __io,
773	  ios_base::iostate& __err, void*& __v) const
774      { return this->do_get(__in, __end, __io, __err, __v); }
775
776    protected:
777      virtual ~num_get() { }
778
779      iter_type
780      _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
781		       string& __xtrc) const;
782
783      iter_type
784      _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
785		     string& __xtrc, int& __base) const;
786
787      virtual iter_type
788      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
789
790
791      virtual iter_type
792      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
793
794      virtual iter_type
795      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
796	      unsigned short&) const;
797
798      virtual iter_type
799      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
800	     unsigned int&) const;
801
802      virtual iter_type
803      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
804	     unsigned long&) const;
805
806#ifdef _GLIBCPP_USE_LONG_LONG
807      virtual iter_type
808      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
809	     long long&) const;
810
811      virtual iter_type
812      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
813	     unsigned long long&) const;
814#endif
815
816      virtual iter_type
817      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
818	     float&) const;
819
820      virtual iter_type
821      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
822	     double&) const;
823
824      virtual iter_type
825      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
826	     long double&) const;
827
828      virtual iter_type
829      do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
830	     void*&) const;
831    };
832
833  template<typename _CharT, typename _InIter>
834    locale::id num_get<_CharT, _InIter>::id;
835
836#if 0
837  // Partial specialization for istreambuf_iterator, so can use traits_type.
838  template<typename _CharT>
839    class num_get<_CharT, istreambuf_iterator<_CharT> >;
840
841      iter_type
842      _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
843		       string& __xtrc) const;
844
845      iter_type
846      _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
847		     string& __xtrc, int& __base) const;
848
849      virtual iter_type
850      do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
851#endif
852
853  template<typename _CharT, typename _OutIter>
854    class num_put : public locale::facet, public __num_base
855    {
856    public:
857      // Types:
858      typedef _CharT       	char_type;
859      typedef _OutIter     	iter_type;
860      static locale::id		id;
861
862      explicit
863      num_put(size_t __refs = 0) : locale::facet(__refs) { }
864
865      iter_type
866      put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
867      { return this->do_put(__s, __f, __fill, __v); }
868
869      iter_type
870      put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
871      { return this->do_put(__s, __f, __fill, __v); }
872
873      iter_type
874      put(iter_type __s, ios_base& __f, char_type __fill,
875	  unsigned long __v) const
876      { return this->do_put(__s, __f, __fill, __v); }
877
878#ifdef _GLIBCPP_USE_LONG_LONG
879      iter_type
880      put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
881      { return this->do_put(__s, __f, __fill, __v); }
882
883      iter_type
884      put(iter_type __s, ios_base& __f, char_type __fill,
885	  unsigned long long __v) const
886      { return this->do_put(__s, __f, __fill, __v); }
887#endif
888
889      iter_type
890      put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
891      { return this->do_put(__s, __f, __fill, __v); }
892
893      iter_type
894      put(iter_type __s, ios_base& __f, char_type __fill,
895	  long double __v) const
896      { return this->do_put(__s, __f, __fill, __v); }
897
898      iter_type
899      put(iter_type __s, ios_base& __f, char_type __fill,
900	  const void* __v) const
901      { return this->do_put(__s, __f, __fill, __v); }
902
903    protected:
904      template<typename _ValueT>
905        iter_type
906        _M_convert_float(iter_type, ios_base& __io, char_type __fill,
907			 char __mod, _ValueT __v) const;
908
909      void
910      _M_group_float(const string& __grouping, char_type __sep,
911		     const char_type* __p, char_type* __new, char_type* __cs,
912		     int& __len) const;
913
914      template<typename _ValueT>
915        iter_type
916        _M_convert_int(iter_type, ios_base& __io, char_type __fill,
917		       _ValueT __v) const;
918
919      void
920      _M_group_int(const string& __grouping, char_type __sep,
921		   ios_base& __io, char_type* __new, char_type* __cs,
922		   int& __len) const;
923
924      void
925      _M_pad(char_type __fill, streamsize __w, ios_base& __io,
926	     char_type* __new, const char_type* __cs, int& __len) const;
927
928#if 1
929      // XXX GLIBCXX_ABI Deprecated, compatibility only.
930      template<typename _ValueT>
931        iter_type
932        _M_convert_int(iter_type, ios_base& __io, char_type __fill,
933		       char __mod, char __modl, _ValueT __v) const;
934
935      iter_type
936      _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs,
937		     int __len) const;
938
939      iter_type
940      _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs,
941		   int __len) const;
942
943      iter_type
944      _M_insert(iter_type, ios_base& __io, char_type __fill,
945		const char_type* __ws, int __len) const;
946#endif
947
948     virtual
949      ~num_put() { };
950
951      virtual iter_type
952      do_put(iter_type, ios_base&, char_type __fill, bool __v) const;
953
954      virtual iter_type
955      do_put(iter_type, ios_base&, char_type __fill, long __v) const;
956
957      virtual iter_type
958      do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
959
960#ifdef _GLIBCPP_USE_LONG_LONG
961      virtual iter_type
962      do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
963
964      virtual iter_type
965      do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
966#endif
967
968      virtual iter_type
969      do_put(iter_type, ios_base&, char_type __fill, double __v) const;
970
971      virtual iter_type
972      do_put(iter_type, ios_base&, char_type __fill, long double __v) const;
973
974      virtual iter_type
975      do_put(iter_type, ios_base&, char_type __fill, const void* __v) const;
976    };
977
978  template <typename _CharT, typename _OutIter>
979    locale::id num_put<_CharT, _OutIter>::id;
980
981
982  template<typename _CharT>
983    class collate : public locale::facet
984    {
985    public:
986      // Types:
987      typedef _CharT               	char_type;
988      typedef basic_string<_CharT> 	string_type;
989
990    protected:
991      // Underlying "C" library locale information saved from
992      // initialization, needed by collate_byname as well.
993      __c_locale			_M_c_locale_collate;
994
995    public:
996      static locale::id 		id;
997
998      explicit
999      collate(size_t __refs = 0)
1000      : locale::facet(__refs)
1001      { _M_c_locale_collate = _S_c_locale; }
1002
1003      explicit
1004      collate(__c_locale __cloc, size_t __refs = 0)
1005      : locale::facet(__refs)
1006      { _M_c_locale_collate = _S_clone_c_locale(__cloc); }
1007
1008      int
1009      compare(const _CharT* __lo1, const _CharT* __hi1,
1010	      const _CharT* __lo2, const _CharT* __hi2) const
1011      { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
1012
1013      string_type
1014      transform(const _CharT* __lo, const _CharT* __hi) const
1015      { return this->do_transform(__lo, __hi); }
1016
1017      long
1018      hash(const _CharT* __lo, const _CharT* __hi) const
1019      { return this->do_hash(__lo, __hi); }
1020
1021      // Used to abstract out _CharT bits in virtual member functions, below.
1022      int
1023      _M_compare(const _CharT*, const _CharT*) const;
1024
1025      size_t
1026      _M_transform(_CharT*, const _CharT*, size_t) const;
1027
1028  protected:
1029      virtual
1030      ~collate()
1031      { _S_destroy_c_locale(_M_c_locale_collate); }
1032
1033      virtual int
1034      do_compare(const _CharT* __lo1, const _CharT* __hi1,
1035		 const _CharT* __lo2, const _CharT* __hi2) const;
1036
1037      virtual string_type
1038      do_transform(const _CharT* __lo, const _CharT* __hi) const;
1039
1040      virtual long
1041      do_hash(const _CharT* __lo, const _CharT* __hi) const;
1042    };
1043
1044  template<typename _CharT>
1045    locale::id collate<_CharT>::id;
1046
1047  // Specializations.
1048  template<>
1049    int
1050    collate<char>::_M_compare(const char*, const char*) const;
1051
1052  template<>
1053    size_t
1054    collate<char>::_M_transform(char*, const char*, size_t) const;
1055
1056#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
1057  template<>
1058    int
1059    collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
1060
1061  template<>
1062    size_t
1063    collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
1064#endif
1065
1066  template<typename _CharT>
1067    class collate_byname : public collate<_CharT>
1068    {
1069    public:
1070      typedef _CharT               char_type;
1071      typedef basic_string<_CharT> string_type;
1072
1073      explicit
1074      collate_byname(const char* __s, size_t __refs = 0)
1075      : collate<_CharT>(__refs)
1076      {
1077	_S_destroy_c_locale(_M_c_locale_collate);
1078	_S_create_c_locale(_M_c_locale_collate, __s);
1079      }
1080
1081    protected:
1082      virtual
1083      ~collate_byname() { }
1084    };
1085
1086
1087  class time_base
1088  {
1089  public:
1090    enum dateorder { no_order, dmy, mdy, ymd, ydm };
1091  };
1092
1093  template<typename _CharT>
1094    class __timepunct : public locale::facet
1095    {
1096    public:
1097      // Types:
1098      typedef _CharT          		__char_type;
1099      typedef basic_string<_CharT> 	__string_type;
1100
1101      static locale::id 		id;
1102
1103      // List of all known timezones, with GMT first.
1104      static const _CharT* 		_S_timezones[14];
1105
1106    protected:
1107      __c_locale			_M_c_locale_timepunct;
1108      char*				_M_name_timepunct;
1109      const _CharT* 			_M_date_format;
1110      const _CharT* 			_M_date_era_format;
1111      const _CharT* 			_M_time_format;
1112      const _CharT* 			_M_time_era_format;
1113      const _CharT*			_M_date_time_format;
1114      const _CharT*			_M_date_time_era_format;
1115      const _CharT* 			_M_am;
1116      const _CharT* 			_M_pm;
1117      const _CharT*			_M_am_pm_format;
1118
1119      // Day names, starting with "C"'s Sunday.
1120      const _CharT*  			_M_day1;
1121      const _CharT*  			_M_day2;
1122      const _CharT*  			_M_day3;
1123      const _CharT*  			_M_day4;
1124      const _CharT*  			_M_day5;
1125      const _CharT*  			_M_day6;
1126      const _CharT*  			_M_day7;
1127
1128      // Abbreviated day names, starting with "C"'s Sun.
1129      const _CharT*  			_M_day_a1;
1130      const _CharT*  			_M_day_a2;
1131      const _CharT*  			_M_day_a3;
1132      const _CharT*  			_M_day_a4;
1133      const _CharT*  			_M_day_a5;
1134      const _CharT*  			_M_day_a6;
1135      const _CharT*  			_M_day_a7;
1136
1137      // Month names, starting with "C"'s January.
1138      const _CharT*  			_M_month01;
1139      const _CharT*  			_M_month02;
1140      const _CharT*  			_M_month03;
1141      const _CharT*  			_M_month04;
1142      const _CharT*  			_M_month05;
1143      const _CharT*  			_M_month06;
1144      const _CharT*  			_M_month07;
1145      const _CharT*  			_M_month08;
1146      const _CharT*  			_M_month09;
1147      const _CharT*  			_M_month10;
1148      const _CharT*  			_M_month11;
1149      const _CharT*  			_M_month12;
1150
1151      // Abbreviated month names, starting with "C"'s Jan.
1152      const _CharT*  			_M_month_a01;
1153      const _CharT*  			_M_month_a02;
1154      const _CharT*  			_M_month_a03;
1155      const _CharT*  			_M_month_a04;
1156      const _CharT*  			_M_month_a05;
1157      const _CharT*  			_M_month_a06;
1158      const _CharT*  			_M_month_a07;
1159      const _CharT*  			_M_month_a08;
1160      const _CharT*  			_M_month_a09;
1161      const _CharT*  			_M_month_a10;
1162      const _CharT*  			_M_month_a11;
1163      const _CharT*  			_M_month_a12;
1164
1165    public:
1166      explicit
1167      __timepunct(size_t __refs = 0);
1168
1169      explicit
1170      __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
1171
1172      void
1173      _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
1174	     const tm* __tm) const;
1175
1176      void
1177      _M_date_formats(const _CharT** __date) const
1178      {
1179	// Always have default first.
1180	__date[0] = _M_date_format;
1181	__date[1] = _M_date_era_format;
1182      }
1183
1184      void
1185      _M_time_formats(const _CharT** __time) const
1186      {
1187	// Always have default first.
1188	__time[0] = _M_time_format;
1189	__time[1] = _M_time_era_format;
1190      }
1191
1192      void
1193      _M_ampm(const _CharT** __ampm) const
1194      {
1195	__ampm[0] = _M_am;
1196	__ampm[1] = _M_pm;
1197      }
1198
1199      void
1200      _M_date_time_formats(const _CharT** __dt) const
1201      {
1202	// Always have default first.
1203	__dt[0] = _M_date_time_format;
1204	__dt[1] = _M_date_time_era_format;
1205      }
1206
1207      void
1208      _M_days(const _CharT** __days) const
1209      {
1210	__days[0] = _M_day1;
1211	__days[1] = _M_day2;
1212	__days[2] = _M_day3;
1213	__days[3] = _M_day4;
1214	__days[4] = _M_day5;
1215	__days[5] = _M_day6;
1216	__days[6] = _M_day7;
1217      }
1218
1219      void
1220      _M_days_abbreviated(const _CharT** __days) const
1221      {
1222	__days[0] = _M_day_a1;
1223	__days[1] = _M_day_a2;
1224	__days[2] = _M_day_a3;
1225	__days[3] = _M_day_a4;
1226	__days[4] = _M_day_a5;
1227	__days[5] = _M_day_a6;
1228	__days[6] = _M_day_a7;
1229      }
1230
1231      void
1232      _M_months(const _CharT** __months) const
1233      {
1234	__months[0] = _M_month01;
1235	__months[1] = _M_month02;
1236	__months[2] = _M_month03;
1237	__months[3] = _M_month04;
1238	__months[4] = _M_month05;
1239	__months[5] = _M_month06;
1240	__months[6] = _M_month07;
1241	__months[7] = _M_month08;
1242	__months[8] = _M_month09;
1243	__months[9] = _M_month10;
1244	__months[10] = _M_month11;
1245	__months[11] = _M_month12;
1246      }
1247
1248      void
1249      _M_months_abbreviated(const _CharT** __months) const
1250      {
1251	__months[0] = _M_month_a01;
1252	__months[1] = _M_month_a02;
1253	__months[2] = _M_month_a03;
1254	__months[3] = _M_month_a04;
1255	__months[4] = _M_month_a05;
1256	__months[5] = _M_month_a06;
1257	__months[6] = _M_month_a07;
1258	__months[7] = _M_month_a08;
1259	__months[8] = _M_month_a09;
1260	__months[9] = _M_month_a10;
1261	__months[10] = _M_month_a11;
1262	__months[11] = _M_month_a12;
1263      }
1264
1265    protected:
1266      virtual
1267      ~__timepunct();
1268
1269      // For use at construction time only.
1270      void
1271      _M_initialize_timepunct(__c_locale __cloc = NULL);
1272    };
1273
1274  template<typename _CharT>
1275    locale::id __timepunct<_CharT>::id;
1276
1277  // Specializations.
1278  template<>
1279    const char*
1280    __timepunct<char>::_S_timezones[14];
1281
1282  template<>
1283    void
1284    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);
1285
1286  template<>
1287    void
1288    __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;
1289
1290#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
1291  template<>
1292    const wchar_t*
1293    __timepunct<wchar_t>::_S_timezones[14];
1294
1295  template<>
1296    void
1297    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);
1298
1299  template<>
1300    void
1301    __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,
1302				 const tm*) const;
1303#endif
1304
1305  // Generic.
1306  template<typename _CharT>
1307    const _CharT* __timepunct<_CharT>::_S_timezones[14];
1308
1309  // Include host and configuration specific timepunct functions.
1310  #include <bits/time_members.h>
1311
1312  template<typename _CharT, typename _InIter>
1313    class time_get : public locale::facet, public time_base
1314    {
1315    public:
1316      // Types:
1317      typedef _CharT     		char_type;
1318      typedef _InIter    		iter_type;
1319      typedef basic_string<_CharT> 	__string_type;
1320
1321      static locale::id 		id;
1322
1323      explicit
1324      time_get(size_t __refs = 0)
1325      : locale::facet (__refs) { }
1326
1327      dateorder
1328      date_order()  const
1329      { return this->do_date_order(); }
1330
1331      iter_type
1332      get_time(iter_type __beg, iter_type __end, ios_base& __io,
1333	       ios_base::iostate& __err, tm* __tm)  const
1334      { return this->do_get_time(__beg, __end, __io, __err, __tm); }
1335
1336      iter_type
1337      get_date(iter_type __beg, iter_type __end, ios_base& __io,
1338	       ios_base::iostate& __err, tm* __tm)  const
1339      { return this->do_get_date(__beg, __end, __io, __err, __tm); }
1340
1341      iter_type
1342      get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
1343		  ios_base::iostate& __err, tm* __tm) const
1344      { return this->do_get_weekday(__beg, __end, __io, __err, __tm); }
1345
1346      iter_type
1347      get_monthname(iter_type __beg, iter_type __end, ios_base& __io,
1348		    ios_base::iostate& __err, tm* __tm) const
1349      { return this->do_get_monthname(__beg, __end, __io, __err, __tm); }
1350
1351      iter_type
1352      get_year(iter_type __beg, iter_type __end, ios_base& __io,
1353	       ios_base::iostate& __err, tm* __tm) const
1354      { return this->do_get_year(__beg, __end, __io, __err, __tm); }
1355
1356    protected:
1357      virtual
1358      ~time_get() { }
1359
1360      virtual dateorder
1361      do_date_order() const;
1362
1363      virtual iter_type
1364      do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
1365		  ios_base::iostate& __err, tm* __tm) const;
1366
1367      virtual iter_type
1368      do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
1369		  ios_base::iostate& __err, tm* __tm) const;
1370
1371      virtual iter_type
1372      do_get_weekday(iter_type __beg, iter_type __end, ios_base&,
1373		     ios_base::iostate& __err, tm* __tm) const;
1374
1375      virtual iter_type
1376      do_get_monthname(iter_type __beg, iter_type __end, ios_base&,
1377		       ios_base::iostate& __err, tm* __tm) const;
1378
1379      virtual iter_type
1380      do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
1381		  ios_base::iostate& __err, tm* __tm) const;
1382
1383      // Extract numeric component of length __len.
1384      void
1385      _M_extract_num(iter_type& __beg, iter_type& __end, int& __member,
1386		     int __min, int __max, size_t __len,
1387		     const ctype<_CharT>& __ctype,
1388		     ios_base::iostate& __err) const;
1389
1390      // Extract day or month name, or any unique array of string
1391      // literals in a const _CharT* array.
1392      void
1393      _M_extract_name(iter_type& __beg, iter_type& __end, int& __member,
1394		      const _CharT** __names, size_t __indexlen,
1395		      ios_base::iostate& __err) const;
1396
1397      // Extract on a component-by-component basis, via __format argument.
1398      void
1399      _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io,
1400			    ios_base::iostate& __err, tm* __tm,
1401			    const _CharT* __format) const;
1402    };
1403
1404  template<typename _CharT, typename _InIter>
1405    locale::id time_get<_CharT, _InIter>::id;
1406
1407  template<typename _CharT, typename _InIter>
1408    class time_get_byname : public time_get<_CharT, _InIter>
1409    {
1410    public:
1411      // Types:
1412      typedef _CharT     		char_type;
1413      typedef _InIter    		iter_type;
1414
1415      explicit
1416      time_get_byname(const char*, size_t __refs = 0)
1417      : time_get<_CharT, _InIter>(__refs) { }
1418
1419    protected:
1420      virtual
1421      ~time_get_byname() { }
1422    };
1423
1424  template<typename _CharT, typename _OutIter>
1425    class time_put : public locale::facet, public time_base
1426    {
1427    public:
1428      // Types:
1429      typedef _CharT     		char_type;
1430      typedef _OutIter   		iter_type;
1431
1432      static locale::id 	     	id;
1433
1434      explicit
1435      time_put(size_t __refs = 0)
1436      : locale::facet(__refs) { }
1437
1438      iter_type
1439      put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
1440	  const _CharT* __beg, const _CharT* __end) const;
1441
1442      iter_type
1443      put(iter_type __s, ios_base& __io, char_type __fill,
1444	  const tm* __tm, char __format, char __mod = 0) const
1445      { return this->do_put(__s, __io, __fill, __tm, __format, __mod); }
1446
1447    protected:
1448      virtual
1449      ~time_put()
1450      { }
1451
1452      virtual iter_type
1453      do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
1454	     char __format, char __mod) const;
1455    };
1456
1457  template<typename _CharT, typename _OutIter>
1458    locale::id time_put<_CharT, _OutIter>::id;
1459
1460  template<typename _CharT, typename _OutIter>
1461    class time_put_byname : public time_put<_CharT, _OutIter>
1462    {
1463    public:
1464      // Types:
1465      typedef _CharT     		char_type;
1466      typedef _OutIter   		iter_type;
1467
1468      explicit
1469      time_put_byname(const char* /*__s*/, size_t __refs = 0)
1470      : time_put<_CharT, _OutIter>(__refs)
1471      { };
1472
1473    protected:
1474      virtual
1475      ~time_put_byname() { }
1476    };
1477
1478
1479  class money_base
1480  {
1481  public:
1482    enum part { none, space, symbol, sign, value };
1483    struct pattern { char field[4]; };
1484
1485    static const pattern _S_default_pattern;
1486
1487    // Construct and return valid pattern consisting of some combination of:
1488    // space none symbol sign value
1489    static pattern
1490    _S_construct_pattern(char __precedes, char __space, char __posn);
1491  };
1492
1493  template<typename _CharT, bool _Intl>
1494    class moneypunct : public locale::facet, public money_base
1495    {
1496    public:
1497      // Types:
1498      typedef _CharT 			char_type;
1499      typedef basic_string<_CharT> 	string_type;
1500
1501      static const bool 		intl = _Intl;
1502      static locale::id 		id;
1503
1504    private:
1505      const char* 			_M_grouping;
1506      char_type 			_M_decimal_point;
1507      char_type 			_M_thousands_sep;
1508      const char_type* 			_M_curr_symbol;
1509      const char_type*			_M_positive_sign;
1510      const char_type*			_M_negative_sign;
1511      int 				_M_frac_digits;
1512      pattern 				_M_pos_format;
1513      pattern 				_M_neg_format;
1514
1515    public:
1516      explicit
1517      moneypunct(size_t __refs = 0) : locale::facet(__refs)
1518      { _M_initialize_moneypunct(); }
1519
1520      explicit
1521      moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
1522      : locale::facet(__refs)
1523      { _M_initialize_moneypunct(__cloc, __s); }
1524
1525      char_type
1526      decimal_point() const
1527      { return this->do_decimal_point(); }
1528
1529      char_type
1530      thousands_sep() const
1531      { return this->do_thousands_sep(); }
1532
1533      string
1534      grouping() const
1535      { return this->do_grouping(); }
1536
1537      string_type
1538      curr_symbol() const
1539      { return this->do_curr_symbol(); }
1540
1541      string_type
1542      positive_sign() const
1543      { return this->do_positive_sign(); }
1544
1545      string_type
1546      negative_sign() const
1547      { return this->do_negative_sign(); }
1548
1549      int
1550      frac_digits() const
1551      { return this->do_frac_digits(); }
1552
1553      pattern
1554      pos_format() const
1555      { return this->do_pos_format(); }
1556
1557      pattern
1558      neg_format() const
1559      { return this->do_neg_format(); }
1560
1561    protected:
1562      virtual
1563      ~moneypunct();
1564
1565      virtual char_type
1566      do_decimal_point() const
1567      { return _M_decimal_point; }
1568
1569      virtual char_type
1570      do_thousands_sep() const
1571      { return _M_thousands_sep; }
1572
1573      virtual string
1574      do_grouping() const
1575      { return _M_grouping; }
1576
1577      virtual string_type
1578      do_curr_symbol()   const
1579      { return _M_curr_symbol; }
1580
1581      virtual string_type
1582      do_positive_sign() const
1583      { return _M_positive_sign; }
1584
1585      virtual string_type
1586      do_negative_sign() const
1587      { return _M_negative_sign; }
1588
1589      virtual int
1590      do_frac_digits() const
1591      { return _M_frac_digits; }
1592
1593      virtual pattern
1594      do_pos_format() const
1595      { return _M_pos_format; }
1596
1597      virtual pattern
1598      do_neg_format() const
1599      { return _M_neg_format; }
1600
1601      // For use at construction time only.
1602       void
1603       _M_initialize_moneypunct(__c_locale __cloc = NULL,
1604				const char* __name = NULL);
1605    };
1606
1607  template<typename _CharT, bool _Intl>
1608    locale::id moneypunct<_CharT, _Intl>::id;
1609
1610  template<typename _CharT, bool _Intl>
1611    const bool moneypunct<_CharT, _Intl>::intl;
1612
1613  template<>
1614    moneypunct<char, true>::~moneypunct();
1615
1616  template<>
1617    moneypunct<char, false>::~moneypunct();
1618
1619  template<>
1620    void
1621    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
1622
1623  template<>
1624    void
1625    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
1626
1627#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
1628  template<>
1629    moneypunct<wchar_t, true>::~moneypunct();
1630
1631  template<>
1632    moneypunct<wchar_t, false>::~moneypunct();
1633
1634  template<>
1635    void
1636    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
1637							const char*);
1638
1639  template<>
1640    void
1641    moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
1642							 const char*);
1643#endif
1644
1645  template<typename _CharT, bool _Intl>
1646    class moneypunct_byname : public moneypunct<_CharT, _Intl>
1647    {
1648      __c_locale			_M_c_locale_moneypunct;
1649
1650    public:
1651      typedef _CharT 			char_type;
1652      typedef basic_string<_CharT> 	string_type;
1653
1654      static const bool intl = _Intl;
1655
1656      explicit
1657      moneypunct_byname(const char* __s, size_t __refs = 0)
1658      : moneypunct<_CharT, _Intl>(__refs)
1659      {
1660	_S_create_c_locale(_M_c_locale_moneypunct, __s);
1661	_M_initialize_moneypunct(_M_c_locale_moneypunct);
1662      }
1663
1664    protected:
1665      virtual
1666      ~moneypunct_byname()
1667      { _S_destroy_c_locale(_M_c_locale_moneypunct); }
1668    };
1669
1670  template<typename _CharT, bool _Intl>
1671    const bool moneypunct_byname<_CharT, _Intl>::intl;
1672
1673  template<typename _CharT, typename _InIter>
1674    class money_get : public locale::facet
1675    {
1676    public:
1677      // Types:
1678      typedef _CharT        		char_type;
1679      typedef _InIter       		iter_type;
1680      typedef basic_string<_CharT> 	string_type;
1681
1682      static locale::id 		id;
1683
1684      explicit
1685      money_get(size_t __refs = 0) : locale::facet(__refs) { }
1686
1687      iter_type
1688      get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
1689	  ios_base::iostate& __err, long double& __units) const
1690      { return this->do_get(__s, __end, __intl, __io, __err, __units); }
1691
1692      iter_type
1693      get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
1694	  ios_base::iostate& __err, string_type& __digits) const
1695      { return this->do_get(__s, __end, __intl, __io, __err, __digits); }
1696
1697    protected:
1698      virtual
1699      ~money_get() { }
1700
1701      virtual iter_type
1702      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
1703	     ios_base::iostate& __err, long double& __units) const;
1704
1705      virtual iter_type
1706      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,
1707	     ios_base::iostate& __err, string_type& __digits) const;
1708    };
1709
1710  template<typename _CharT, typename _InIter>
1711    locale::id money_get<_CharT, _InIter>::id;
1712
1713  template<typename _CharT, typename _OutIter>
1714    class money_put : public locale::facet
1715    {
1716    public:
1717      typedef _CharT              	char_type;
1718      typedef _OutIter            	iter_type;
1719      typedef basic_string<_CharT>	string_type;
1720
1721      static locale::id 		id;
1722
1723      explicit
1724      money_put(size_t __refs = 0) : locale::facet(__refs) { }
1725
1726      iter_type
1727      put(iter_type __s, bool __intl, ios_base& __io,
1728	  char_type __fill, long double __units) const
1729      { return this->do_put(__s, __intl, __io, __fill, __units); }
1730
1731      iter_type
1732      put(iter_type __s, bool __intl, ios_base& __io,
1733	  char_type __fill, const string_type& __digits) const
1734      { return this->do_put(__s, __intl, __io, __fill, __digits); }
1735
1736    protected:
1737      virtual
1738      ~money_put() { }
1739
1740      virtual iter_type
1741      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1742	     long double __units) const;
1743
1744      virtual iter_type
1745      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1746	     const string_type& __digits) const;
1747    };
1748
1749  template<typename _CharT, typename _OutIter>
1750    locale::id money_put<_CharT, _OutIter>::id;
1751
1752
1753  struct messages_base
1754  {
1755    typedef int catalog;
1756  };
1757
1758  template<typename _CharT>
1759    class messages : public locale::facet, public messages_base
1760    {
1761    public:
1762      // Types:
1763      typedef _CharT 			char_type;
1764      typedef basic_string<_CharT> 	string_type;
1765
1766    protected:
1767      // Underlying "C" library locale information saved from
1768      // initialization, needed by messages_byname as well.
1769      __c_locale			_M_c_locale_messages;
1770      char*				_M_name_messages;
1771
1772    public:
1773      static locale::id 		id;
1774
1775      explicit
1776      messages(size_t __refs = 0);
1777
1778      // Non-standard.
1779      explicit
1780      messages(__c_locale __cloc, const char* __s, size_t __refs = 0);
1781
1782      catalog
1783      open(const basic_string<char>& __s, const locale& __loc) const
1784      { return this->do_open(__s, __loc); }
1785
1786      // Non-standard and unorthodox, yet effective.
1787      catalog
1788      open(const basic_string<char>&, const locale&, const char*) const;
1789
1790      string_type
1791      get(catalog __c, int __set, int __msgid, const string_type& __s) const
1792      { return this->do_get(__c, __set, __msgid, __s); }
1793
1794      void
1795      close(catalog __c) const
1796      { return this->do_close(__c); }
1797
1798    protected:
1799      virtual
1800      ~messages();
1801
1802      virtual catalog
1803      do_open(const basic_string<char>&, const locale&) const;
1804
1805      virtual string_type
1806      do_get(catalog, int, int, const string_type& __dfault) const;
1807
1808      virtual void
1809      do_close(catalog) const;
1810
1811      // Returns a locale and codeset-converted string, given a char* message.
1812      char*
1813      _M_convert_to_char(const string_type& __msg) const
1814      {
1815	// XXX
1816	return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));
1817      }
1818
1819      // Returns a locale and codeset-converted string, given a char* message.
1820      string_type
1821      _M_convert_from_char(char* __msg) const
1822      {
1823	// Length of message string without terminating null.
1824	size_t __len = char_traits<char>::length(__msg) - 1;
1825
1826	// "everybody can easily convert the string using
1827	// mbsrtowcs/wcsrtombs or with iconv()"
1828#if 0
1829	// Convert char* to _CharT in locale used to open catalog.
1830	// XXX need additional template parameter on messages class for this..
1831	// typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;
1832	typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;
1833
1834	__codecvt_type::state_type __state;
1835	// XXX may need to initialize state.
1836	//initialize_state(__state._M_init());
1837
1838	char* __from_next;
1839	// XXX what size for this string?
1840	_CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));
1841	const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);
1842	__cvt.out(__state, __msg, __msg + __len, __from_next,
1843		  __to, __to + __len + 1, __to_next);
1844	return string_type(__to);
1845#endif
1846#if 0
1847	typedef ctype<_CharT> __ctype_type;
1848	// const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);
1849	const __ctype_type& __cvt = use_facet<__ctype_type>(locale());
1850	// XXX Again, proper length of converted string an issue here.
1851	// For now, assume the converted length is not larger.
1852	_CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));
1853	__cvt.widen(__msg, __msg + __len, __dest);
1854	return basic_string<_CharT>(__dest);
1855#endif
1856	return string_type();
1857      }
1858     };
1859
1860  template<typename _CharT>
1861    locale::id messages<_CharT>::id;
1862
1863  // Specializations for required instantiations.
1864  template<>
1865    string
1866    messages<char>::do_get(catalog, int, int, const string&) const;
1867
1868#if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T)
1869  template<>
1870    wstring
1871    messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;
1872#endif
1873
1874  template<typename _CharT>
1875    class messages_byname : public messages<_CharT>
1876    {
1877    public:
1878      typedef _CharT               	char_type;
1879      typedef basic_string<_CharT> 	string_type;
1880
1881      explicit
1882      messages_byname(const char* __s, size_t __refs = 0);
1883
1884    protected:
1885      virtual
1886      ~messages_byname()
1887      { }
1888    };
1889
1890  // Include host and configuration specific messages functions.
1891  #include <bits/messages_members.h>
1892
1893
1894  // Subclause convenience interfaces, inlines.
1895  // NB: These are inline because, when used in a loop, some compilers
1896  // can hoist the body out of the loop; then it's just as fast as the
1897  // C is*() function.
1898  template<typename _CharT>
1899    inline bool
1900    isspace(_CharT __c, const locale& __loc)
1901    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
1902
1903  template<typename _CharT>
1904    inline bool
1905    isprint(_CharT __c, const locale& __loc)
1906    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
1907
1908  template<typename _CharT>
1909    inline bool
1910    iscntrl(_CharT __c, const locale& __loc)
1911    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
1912
1913  template<typename _CharT>
1914    inline bool
1915    isupper(_CharT __c, const locale& __loc)
1916    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
1917
1918  template<typename _CharT>
1919    inline bool islower(_CharT __c, const locale& __loc)
1920    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
1921
1922  template<typename _CharT>
1923    inline bool
1924    isalpha(_CharT __c, const locale& __loc)
1925    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
1926
1927  template<typename _CharT>
1928    inline bool
1929    isdigit(_CharT __c, const locale& __loc)
1930    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
1931
1932  template<typename _CharT>
1933    inline bool
1934    ispunct(_CharT __c, const locale& __loc)
1935    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
1936
1937  template<typename _CharT>
1938    inline bool
1939    isxdigit(_CharT __c, const locale& __loc)
1940    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
1941
1942  template<typename _CharT>
1943    inline bool
1944    isalnum(_CharT __c, const locale& __loc)
1945    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
1946
1947  template<typename _CharT>
1948    inline bool
1949    isgraph(_CharT __c, const locale& __loc)
1950    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
1951
1952  template<typename _CharT>
1953    inline _CharT
1954    toupper(_CharT __c, const locale& __loc)
1955    { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
1956
1957  template<typename _CharT>
1958    inline _CharT
1959    tolower(_CharT __c, const locale& __loc)
1960    { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
1961
1962  /**
1963   * @if maint
1964   * __locale_cache objects hold information extracted from facets in
1965   * a form optimized for parsing and formatting.  They are stored in
1966   * a locale's facet array and accessed via __use_cache<_Facet>.
1967   *
1968   * The intent twofold: to avoid the costs of creating a locale
1969   * object and to avoid calling the virtual functions in a locale's
1970   * facet to look up data.
1971   * @endif
1972   */
1973  class __locale_cache_base
1974  {
1975    friend class std::locale::_Impl;
1976    friend class locale;
1977
1978  public:
1979    virtual
1980    ~__locale_cache_base() { }
1981
1982  };
1983
1984  // This template doesn't really get used for anything except a
1985  // placeholder for specializations
1986  template<typename _Facet>
1987    class __locale_cache : public __locale_cache_base
1988    {
1989      // ctor
1990      __locale_cache(const locale&) {}
1991    };
1992
1993  template<typename _CharT>
1994    class __locale_cache<numpunct<_CharT> > : public __locale_cache_base
1995    {
1996      // Types:
1997      typedef _CharT               	char_type;
1998      typedef char_traits<_CharT>       traits_type;
1999      typedef basic_string<_CharT>	string_type;
2000
2001    public:
2002      // Data Members:
2003
2004      // The sign used to separate decimal values: for standard US
2005      // locales, this would usually be: "."  Abstracted from
2006      // numpunct::decimal_point().
2007      _CharT                    _M_decimal_point;
2008
2009      // The sign used to separate groups of digits into smaller
2010      // strings that the eye can parse with less difficulty: for
2011      // standard US locales, this would usually be: "," Abstracted
2012      // from numpunct::thousands_sep().
2013      _CharT                    _M_thousands_sep;
2014
2015      // However the US's "false" and "true" are translated.  From
2016      // numpunct::truename() and numpunct::falsename(), respectively.
2017      const _CharT*		_M_truename;
2018      const _CharT*		_M_falsename;
2019
2020      // If we are checking groupings. This should be equivalent to
2021      // numpunct::groupings().size() != 0
2022      bool                      _M_use_grouping;
2023
2024      // If we are using numpunct's groupings, this is the current
2025      // grouping string in effect (from numpunct::grouping()).
2026      const char*               _M_grouping;
2027
2028      // A list of valid numeric literals: for the standard "C"
2029      // locale, this is "-+xX0123456789abcdef0123456789ABCDEF".  This
2030      // array contains the chars after having been passed through the
2031      // current locale's ctype<_CharT>.widen().
2032
2033      // Copied here from __locale_cache<ctype> to save multiple cache
2034      // access in num_put functions.
2035      _CharT                    _M_atoms_out[__num_base::_S_end];
2036
2037      // ctor
2038      __locale_cache(const locale& __loc);
2039      __locale_cache(const locale& __loc, bool);
2040
2041      ~__locale_cache()
2042      {
2043	delete [] _M_truename;
2044	delete [] _M_falsename;
2045	delete [] _M_grouping;
2046      }
2047    };
2048} // namespace std
2049
2050#endif
2051