OSDN Git Service

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