OSDN Git Service

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