OSDN Git Service

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