OSDN Git Service

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