OSDN Git Service

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