OSDN Git Service

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