OSDN Git Service

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