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