OSDN Git Service

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