OSDN Git Service

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