locale_facets.h (ctype<char>): Remove throw specs not in base class signature.
[gcc.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;
236
237 inline const char*
238 is(const char* __low, const char* __high, mask* __vec) const;
239
240 inline const char*
241 scan_is(mask __m, const char* __low, const char* __high) const;
242
243 inline const char*
244 scan_not(mask __m, const char* __low, const char* __high) const;
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