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