blob: 395cb26821e857166f1ac35a661f48601b42069b [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:161// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnant5b08a8a2010-05-11 21:36:014// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:165//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___LOCALE
12#define _LIBCPP___LOCALE
13
14#include <__config>
15#include <string>
16#include <memory>
17#include <utility>
18#include <mutex>
19#include <cstdint>
20#include <cctype>
Howard Hinnant128ba712010-05-24 17:49:4121#include <locale.h>
Howard Hinnant3e519522010-05-11 19:42:1622#include <xlocale.h>
23
24#pragma GCC system_header
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28class locale;
29
30template <class _Facet> bool has_facet(const locale&) throw();
31template <class _Facet> const _Facet& use_facet(const locale&);
32
33class locale
34{
35public:
36 // types:
37 class facet;
38 class id;
39
40 typedef int category;
41 static const category // values assigned here are for exposition only
42 none = 0,
43 collate = LC_COLLATE_MASK,
44 ctype = LC_CTYPE_MASK,
45 monetary = LC_MONETARY_MASK,
46 numeric = LC_NUMERIC_MASK,
47 time = LC_TIME_MASK,
48 messages = LC_MESSAGES_MASK,
49 all = collate | ctype | monetary | numeric | time | messages;
50
51 // construct/copy/destroy:
52 locale() throw();
53 locale(const locale&) throw();
54 explicit locale(const char*);
55 explicit locale(const string&);
56 locale(const locale&, const char*, category);
57 locale(const locale&, const string&, category);
58 template <class _Facet> locale(const locale&, _Facet*);
59 locale(const locale&, const locale&, category);
60
61 ~locale() throw();
62
63 const locale& operator=(const locale&) throw();
64
65 template <class _Facet> locale combine(const locale&) const;
66
67 // locale operations:
68 string name() const;
69 bool operator==(const locale&) const;
70 bool operator!=(const locale& __y) const {return !(*this == __y);}
71 template <class _CharT, class _Traits, class _Allocator>
72 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
73 const basic_string<_CharT, _Traits, _Allocator>&) const;
74
75 // global locale objects:
76 static locale global(const locale&);
77 static const locale& classic();
78
79private:
80 class __imp;
81 __imp* __locale_;
82
83 void __install_ctor(const locale&, facet*, long);
84 static locale& __global();
85 bool has_facet(id&) const;
86 const facet* use_facet(id&) const;
87
88 template <class _Facet> friend bool has_facet(const locale&) throw();
89 template <class _Facet> friend const _Facet& use_facet(const locale&);
90};
91
92class locale::facet
93 : public __shared_count
94{
95protected:
96 explicit facet(size_t __refs = 0)
97 : __shared_count(static_cast<long>(__refs)-1) {}
98
99 virtual ~facet();
100
101// facet(const facet&) = delete; // effectively done in __shared_count
102// void operator=(const facet&) = delete;
103private:
104 virtual void __on_zero_shared();
105};
106
107class locale::id
108{
109 once_flag __flag_;
110 int32_t __id_;
111
112 static int32_t __next_id;
113public:
114 id() {}
115private:
116 void __init();
117 void operator=(const id&); // = delete;
118 id(const id&); // = delete;
119public: // only needed for tests
120 long __get();
121
122 friend class locale;
123 friend class locale::__imp;
124};
125
126template <class _Facet>
127inline _LIBCPP_INLINE_VISIBILITY
128locale::locale(const locale& __other, _Facet* __f)
129{
130 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
131}
132
133template <class _Facet>
134locale
135locale::combine(const locale& __other) const
136{
137 if (!_STD::has_facet<_Facet>(__other))
138 throw runtime_error("locale::combine: locale missing facet");
139 return locale(*this, &const_cast<_Facet&>(_STD::use_facet<_Facet>(__other)));
140}
141
142template <class _Facet>
143inline _LIBCPP_INLINE_VISIBILITY
144bool
145has_facet(const locale& __l) throw()
146{
147 return __l.has_facet(_Facet::id);
148}
149
150template <class _Facet>
151inline _LIBCPP_INLINE_VISIBILITY
152const _Facet&
153use_facet(const locale& __l)
154{
155 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
156}
157
158// template <class _CharT> class collate;
159
160template <class _CharT>
161class collate
162 : public locale::facet
163{
164public:
165 typedef _CharT char_type;
166 typedef basic_string<char_type> string_type;
167
168 explicit collate(size_t __refs = 0)
169 : locale::facet(__refs) {}
170
171 int compare(const char_type* __lo1, const char_type* __hi1,
172 const char_type* __lo2, const char_type* __hi2) const
173 {
174 return do_compare(__lo1, __hi1, __lo2, __hi2);
175 }
176
177 string_type transform(const char_type* __lo, const char_type* __hi) const
178 {
179 return do_transform(__lo, __hi);
180 }
181
182 long hash(const char_type* __lo, const char_type* __hi) const
183 {
184 return do_hash(__lo, __hi);
185 }
186
187 static locale::id id;
188
189protected:
190 ~collate();
191 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
192 const char_type* __lo2, const char_type* __hi2) const;
193 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
194 {return string_type(__lo, __hi);}
195 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
196};
197
198template <class _CharT> locale::id collate<_CharT>::id;
199
200template <class _CharT>
201collate<_CharT>::~collate()
202{
203}
204
205template <class _CharT>
206int
207collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
208 const char_type* __lo2, const char_type* __hi2) const
209{
210 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
211 {
212 if (__lo1 == __hi1 || *__lo1 < *__lo2)
213 return -1;
214 if (*__lo2 < *__lo1)
215 return 1;
216 }
217 return __lo1 != __hi1;
218}
219
220template <class _CharT>
221long
222collate<_CharT>::do_hash(const char_type* lo, const char_type* hi) const
223{
224 size_t h = 0;
225 const size_t sr = __CHAR_BIT__ * sizeof(size_t) - 8;
226 const size_t mask = size_t(0xF) << (sr + 4);
227 for(const char_type* p = lo; p != hi; ++p)
228 {
229 h = (h << 4) + *p;
230 size_t g = h & mask;
231 h ^= g | (g >> sr);
232 }
233 return static_cast<long>(h);
234}
235
236extern template class collate<char>;
237extern template class collate<wchar_t>;
238
239// template <class CharT> class collate_byname;
240
241template <class _CharT> class collate_byname;
242
243template <>
244class collate_byname<char>
245 : public collate<char>
246{
247 locale_t __l;
248public:
249 typedef char char_type;
250 typedef basic_string<char_type> string_type;
251
252 explicit collate_byname(const char* __n, size_t __refs = 0);
253 explicit collate_byname(const string& __n, size_t __refs = 0);
254
255protected:
256 ~collate_byname();
257 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
258 const char_type* __lo2, const char_type* __hi2) const;
259 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
260};
261
262template <>
263class collate_byname<wchar_t>
264 : public collate<wchar_t>
265{
266 locale_t __l;
267public:
268 typedef wchar_t char_type;
269 typedef basic_string<char_type> string_type;
270
271 explicit collate_byname(const char* __n, size_t __refs = 0);
272 explicit collate_byname(const string& __n, size_t __refs = 0);
273
274protected:
275 ~collate_byname();
276
277 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
278 const char_type* __lo2, const char_type* __hi2) const;
279 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
280};
281
282template <class _CharT, class _Traits, class _Allocator>
283bool
284locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
285 const basic_string<_CharT, _Traits, _Allocator>& __y) const
286{
287 return _STD::use_facet<_STD::collate<_CharT> >(*this).compare(
288 __x.data(), __x.data() + __x.size(),
289 __y.data(), __y.data() + __y.size()) < 0;
290}
291
292// template <class charT> class ctype
293
294class ctype_base {
295public:
296 typedef __uint32_t mask;
297
Howard Hinnant128ba712010-05-24 17:49:41298#if __APPLE__
Howard Hinnant3e519522010-05-11 19:42:16299 static const mask space = _CTYPE_S;
300 static const mask print = _CTYPE_R;
301 static const mask cntrl = _CTYPE_C;
302 static const mask upper = _CTYPE_U;
303 static const mask lower = _CTYPE_L;
304 static const mask alpha = _CTYPE_A;
305 static const mask digit = _CTYPE_D;
306 static const mask punct = _CTYPE_P;
307 static const mask xdigit = _CTYPE_X;
308 static const mask blank = _CTYPE_B;
Howard Hinnant128ba712010-05-24 17:49:41309#else /* !__APPLE__ */
310 static const mask space = _ISspace;
311 static const mask print = _ISprint;
312 static const mask cntrl = _IScntrl;
313 static const mask upper = _ISupper;
314 static const mask lower = _ISlower;
315 static const mask alpha = _ISalpha;
316 static const mask digit = _ISdigit;
317 static const mask punct = _ISpunct;
318 static const mask xdigit = _ISxdigit;
319 static const mask blank = _ISblank;
320#endif /* __APPLE__ */
Howard Hinnant3e519522010-05-11 19:42:16321 static const mask alnum = alpha | digit;
322 static const mask graph = alnum | punct;
323
324 _LIBCPP_ALWAYS_INLINE ctype_base() {}
325};
326
327template <class _CharT> class ctype;
328
329template <>
330class ctype<wchar_t>
331 : public locale::facet,
332 public ctype_base
333{
334public:
335 typedef wchar_t char_type;
336
337 _LIBCPP_ALWAYS_INLINE
338 explicit ctype(size_t __refs = 0)
339 : locale::facet(__refs) {}
340
341 _LIBCPP_ALWAYS_INLINE
342 bool is(mask __m, char_type __c) const
343 {
344 return do_is(__m, __c);
345 }
346
347 _LIBCPP_ALWAYS_INLINE
348 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
349 {
350 return do_is(__low, __high, __vec);
351 }
352
353 _LIBCPP_ALWAYS_INLINE
354 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
355 {
356 return do_scan_is(__m, __low, __high);
357 }
358
359 _LIBCPP_ALWAYS_INLINE
360 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
361 {
362 return do_scan_not(__m, __low, __high);
363 }
364
365 _LIBCPP_ALWAYS_INLINE
366 char_type toupper(char_type __c) const
367 {
368 return do_toupper(__c);
369 }
370
371 _LIBCPP_ALWAYS_INLINE
372 const char_type* toupper(char_type* __low, const char_type* __high) const
373 {
374 return do_toupper(__low, __high);
375 }
376
377 _LIBCPP_ALWAYS_INLINE
378 char_type tolower(char_type __c) const
379 {
380 return do_tolower(__c);
381 }
382
383 _LIBCPP_ALWAYS_INLINE
384 const char_type* tolower(char_type* __low, const char_type* __high) const
385 {
386 return do_tolower(__low, __high);
387 }
388
389 _LIBCPP_ALWAYS_INLINE
390 char_type widen(char __c) const
391 {
392 return do_widen(__c);
393 }
394
395 _LIBCPP_ALWAYS_INLINE
396 const char* widen(const char* __low, const char* __high, char_type* __to) const
397 {
398 return do_widen(__low, __high, __to);
399 }
400
401 _LIBCPP_ALWAYS_INLINE
402 char narrow(char_type __c, char __dfault) const
403 {
404 return do_narrow(__c, __dfault);
405 }
406
407 _LIBCPP_ALWAYS_INLINE
408 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
409 {
410 return do_narrow(__low, __high, __dfault, __to);
411 }
412
413 static locale::id id;
414
415protected:
416 ~ctype();
417 virtual bool do_is(mask __m, char_type __c) const;
418 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
419 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
420 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
421 virtual char_type do_toupper(char_type) const;
422 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
423 virtual char_type do_tolower(char_type) const;
424 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
425 virtual char_type do_widen(char) const;
426 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
427 virtual char do_narrow(char_type, char __dfault) const;
428 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
429};
430
431template <>
432class ctype<char>
433 : public locale::facet, public ctype_base
434{
435 const mask* __tab_;
436 bool __del_;
437public:
438 typedef char char_type;
439
440 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
441
442 _LIBCPP_ALWAYS_INLINE
443 bool is(mask __m, char_type __c) const
444 {
445 return isascii(__c) ? __tab_[__c] & __m : false;
446 }
447
448 _LIBCPP_ALWAYS_INLINE
449 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
450 {
451 for (; __low != __high; ++__low, ++__vec)
452 *__vec = isascii(*__low) ? __tab_[*__low] : 0;
453 return __low;
454 }
455
456 _LIBCPP_ALWAYS_INLINE
457 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
458 {
459 for (; __low != __high; ++__low)
460 if (isascii(*__low) && (__tab_[*__low] & __m))
461 break;
462 return __low;
463 }
464
465 _LIBCPP_ALWAYS_INLINE
466 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
467 {
468 for (; __low != __high; ++__low)
469 if (!(isascii(*__low) && (__tab_[*__low] & __m)))
470 break;
471 return __low;
472 }
473
474 _LIBCPP_ALWAYS_INLINE
475 char_type toupper(char_type __c) const
476 {
477 return do_toupper(__c);
478 }
479
480 _LIBCPP_ALWAYS_INLINE
481 const char_type* toupper(char_type* __low, const char_type* __high) const
482 {
483 return do_toupper(__low, __high);
484 }
485
486 _LIBCPP_ALWAYS_INLINE
487 char_type tolower(char_type __c) const
488 {
489 return do_tolower(__c);
490 }
491
492 _LIBCPP_ALWAYS_INLINE
493 const char_type* tolower(char_type* __low, const char_type* __high) const
494 {
495 return do_tolower(__low, __high);
496 }
497
498 _LIBCPP_ALWAYS_INLINE
499 char_type widen(char __c) const
500 {
501 return do_widen(__c);
502 }
503
504 _LIBCPP_ALWAYS_INLINE
505 const char* widen(const char* __low, const char* __high, char_type* __to) const
506 {
507 return do_widen(__low, __high, __to);
508 }
509
510 _LIBCPP_ALWAYS_INLINE
511 char narrow(char_type __c, char __dfault) const
512 {
513 return do_narrow(__c, __dfault);
514 }
515
516 _LIBCPP_ALWAYS_INLINE
517 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
518 {
519 return do_narrow(__low, __high, __dfault, __to);
520 }
521
522 static locale::id id;
523
Howard Hinnant128ba712010-05-24 17:49:41524#ifdef _CACHED_RUNES
Howard Hinnant3e519522010-05-11 19:42:16525 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant128ba712010-05-24 17:49:41526#else
527 static const size_t table_size = 256; // FIXME: Don't hardcode this.
528#endif
Howard Hinnant3e519522010-05-11 19:42:16529 const mask* table() const throw() {return __tab_;}
530 static const mask* classic_table() throw();
531
532protected:
533 ~ctype();
534 virtual char_type do_toupper(char_type __c) const;
535 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
536 virtual char_type do_tolower(char_type __c) const;
537 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
538 virtual char_type do_widen(char __c) const;
539 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
540 virtual char do_narrow(char_type __c, char __dfault) const;
541 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
542};
543
544// template <class CharT> class ctype_byname;
545
546template <class _CharT> class ctype_byname;
547
548template <>
549class ctype_byname<char>
550 : public ctype<char>
551{
552 locale_t __l;
553
554public:
555 explicit ctype_byname(const char*, size_t = 0);
556 explicit ctype_byname(const string&, size_t = 0);
557
558protected:
559 ~ctype_byname();
560 virtual char_type do_toupper(char_type) const;
561 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
562 virtual char_type do_tolower(char_type) const;
563 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
564};
565
566template <>
567class ctype_byname<wchar_t>
568 : public ctype<wchar_t>
569{
570 locale_t __l;
571
572public:
573 explicit ctype_byname(const char*, size_t = 0);
574 explicit ctype_byname(const string&, size_t = 0);
575
576protected:
577 ~ctype_byname();
578 virtual bool do_is(mask __m, char_type __c) const;
579 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
580 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
581 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
582 virtual char_type do_toupper(char_type) const;
583 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
584 virtual char_type do_tolower(char_type) const;
585 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
586 virtual char_type do_widen(char) const;
587 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
588 virtual char do_narrow(char_type, char __dfault) const;
589 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
590};
591
592template <class _CharT>
593inline _LIBCPP_INLINE_VISIBILITY
594bool
595isspace(_CharT __c, const locale& __loc)
596{
597 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
598}
599
600template <class _CharT>
601inline _LIBCPP_INLINE_VISIBILITY
602bool
603isprint(_CharT __c, const locale& __loc)
604{
605 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
606}
607
608template <class _CharT>
609inline _LIBCPP_INLINE_VISIBILITY
610bool
611iscntrl(_CharT __c, const locale& __loc)
612{
613 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
614}
615
616template <class _CharT>
617inline _LIBCPP_INLINE_VISIBILITY
618bool
619isupper(_CharT __c, const locale& __loc)
620{
621 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
622}
623
624template <class _CharT>
625inline _LIBCPP_INLINE_VISIBILITY
626bool
627islower(_CharT __c, const locale& __loc)
628{
629 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
630}
631
632template <class _CharT>
633inline _LIBCPP_INLINE_VISIBILITY
634bool
635isalpha(_CharT __c, const locale& __loc)
636{
637 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
638}
639
640template <class _CharT>
641inline _LIBCPP_INLINE_VISIBILITY
642bool
643isdigit(_CharT __c, const locale& __loc)
644{
645 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
646}
647
648template <class _CharT>
649inline _LIBCPP_INLINE_VISIBILITY
650bool
651ispunct(_CharT __c, const locale& __loc)
652{
653 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
654}
655
656template <class _CharT>
657inline _LIBCPP_INLINE_VISIBILITY
658bool
659isxdigit(_CharT __c, const locale& __loc)
660{
661 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
662}
663
664template <class _CharT>
665inline _LIBCPP_INLINE_VISIBILITY
666bool
667isalnum(_CharT __c, const locale& __loc)
668{
669 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
670}
671
672template <class _CharT>
673inline _LIBCPP_INLINE_VISIBILITY
674bool
675isgraph(_CharT __c, const locale& __loc)
676{
677 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
678}
679
680template <class _CharT>
681inline _LIBCPP_INLINE_VISIBILITY
682_CharT
683toupper(_CharT __c, const locale& __loc)
684{
685 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
686}
687
688template <class _CharT>
689inline _LIBCPP_INLINE_VISIBILITY
690_CharT
691tolower(_CharT __c, const locale& __loc)
692{
693 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
694}
695
696// codecvt_base
697
698class codecvt_base
699{
700public:
701 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
702 enum result {ok, partial, error, noconv};
703};
704
705// template <class internT, class externT, class stateT> class codecvt;
706
707template <class _InternT, class _ExternT, class _StateT> class codecvt;
708
709// template <> class codecvt<char, char, mbstate_t>
710
711template <>
712class codecvt<char, char, mbstate_t>
713 : public locale::facet,
714 public codecvt_base
715{
716public:
717 typedef char intern_type;
718 typedef char extern_type;
719 typedef mbstate_t state_type;
720
721 _LIBCPP_ALWAYS_INLINE
722 explicit codecvt(size_t __refs = 0)
723 : locale::facet(__refs) {}
724
725 _LIBCPP_ALWAYS_INLINE
726 result out(state_type& __st,
727 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
728 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
729 {
730 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
731 }
732
733 _LIBCPP_ALWAYS_INLINE
734 result unshift(state_type& __st,
735 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
736 {
737 return do_unshift(__st, __to, __to_end, __to_nxt);
738 }
739
740 _LIBCPP_ALWAYS_INLINE
741 result in(state_type& __st,
742 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
743 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
744 {
745 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
746 }
747
748 _LIBCPP_ALWAYS_INLINE
749 int encoding() const throw()
750 {
751 return do_encoding();
752 }
753
754 _LIBCPP_ALWAYS_INLINE
755 bool always_noconv() const throw()
756 {
757 return do_always_noconv();
758 }
759
760 _LIBCPP_ALWAYS_INLINE
761 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
762 {
763 return do_length(__st, __frm, __end, __mx);
764 }
765
766 _LIBCPP_ALWAYS_INLINE
767 int max_length() const throw()
768 {
769 return do_max_length();
770 }
771
772 static locale::id id;
773
774protected:
775 _LIBCPP_ALWAYS_INLINE
776 explicit codecvt(const char*, size_t __refs = 0)
777 : locale::facet(__refs) {}
778
779 ~codecvt();
780
781 virtual result do_out(state_type& __st,
782 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
783 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
784 virtual result do_in(state_type& __st,
785 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
786 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
787 virtual result do_unshift(state_type& __st,
788 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
789 virtual int do_encoding() const throw();
790 virtual bool do_always_noconv() const throw();
791 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
792 virtual int do_max_length() const throw();
793};
794
795// template <> class codecvt<wchar_t, char, mbstate_t>
796
797template <>
798class codecvt<wchar_t, char, mbstate_t>
799 : public locale::facet,
800 public codecvt_base
801{
802 locale_t __l;
803public:
804 typedef wchar_t intern_type;
805 typedef char extern_type;
806 typedef mbstate_t state_type;
807
808 explicit codecvt(size_t __refs = 0);
809
810 _LIBCPP_ALWAYS_INLINE
811 result out(state_type& __st,
812 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
813 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
814 {
815 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
816 }
817
818 _LIBCPP_ALWAYS_INLINE
819 result unshift(state_type& __st,
820 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
821 {
822 return do_unshift(__st, __to, __to_end, __to_nxt);
823 }
824
825 _LIBCPP_ALWAYS_INLINE
826 result in(state_type& __st,
827 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
828 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
829 {
830 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
831 }
832
833 _LIBCPP_ALWAYS_INLINE
834 int encoding() const throw()
835 {
836 return do_encoding();
837 }
838
839 _LIBCPP_ALWAYS_INLINE
840 bool always_noconv() const throw()
841 {
842 return do_always_noconv();
843 }
844
845 _LIBCPP_ALWAYS_INLINE
846 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
847 {
848 return do_length(__st, __frm, __end, __mx);
849 }
850
851 _LIBCPP_ALWAYS_INLINE
852 int max_length() const throw()
853 {
854 return do_max_length();
855 }
856
857 static locale::id id;
858
859protected:
860 explicit codecvt(const char*, size_t __refs = 0);
861
862 ~codecvt();
863
864 virtual result do_out(state_type& __st,
865 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
866 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
867 virtual result do_in(state_type& __st,
868 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
869 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
870 virtual result do_unshift(state_type& __st,
871 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
872 virtual int do_encoding() const throw();
873 virtual bool do_always_noconv() const throw();
874 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
875 virtual int do_max_length() const throw();
876};
877
878// template <> class codecvt<char16_t, char, mbstate_t>
879
880template <>
881class codecvt<char16_t, char, mbstate_t>
882 : public locale::facet,
883 public codecvt_base
884{
885public:
886 typedef char16_t intern_type;
887 typedef char extern_type;
888 typedef mbstate_t state_type;
889
890 _LIBCPP_ALWAYS_INLINE
891 explicit codecvt(size_t __refs = 0)
892 : locale::facet(__refs) {}
893
894 _LIBCPP_ALWAYS_INLINE
895 result out(state_type& __st,
896 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
897 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
898 {
899 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
900 }
901
902 _LIBCPP_ALWAYS_INLINE
903 result unshift(state_type& __st,
904 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
905 {
906 return do_unshift(__st, __to, __to_end, __to_nxt);
907 }
908
909 _LIBCPP_ALWAYS_INLINE
910 result in(state_type& __st,
911 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
912 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
913 {
914 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
915 }
916
917 _LIBCPP_ALWAYS_INLINE
918 int encoding() const throw()
919 {
920 return do_encoding();
921 }
922
923 _LIBCPP_ALWAYS_INLINE
924 bool always_noconv() const throw()
925 {
926 return do_always_noconv();
927 }
928
929 _LIBCPP_ALWAYS_INLINE
930 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
931 {
932 return do_length(__st, __frm, __end, __mx);
933 }
934
935 _LIBCPP_ALWAYS_INLINE
936 int max_length() const throw()
937 {
938 return do_max_length();
939 }
940
941 static locale::id id;
942
943protected:
944 _LIBCPP_ALWAYS_INLINE
945 explicit codecvt(const char*, size_t __refs = 0)
946 : locale::facet(__refs) {}
947
948 ~codecvt();
949
950 virtual result do_out(state_type& __st,
951 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
952 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
953 virtual result do_in(state_type& __st,
954 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
955 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
956 virtual result do_unshift(state_type& __st,
957 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
958 virtual int do_encoding() const throw();
959 virtual bool do_always_noconv() const throw();
960 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
961 virtual int do_max_length() const throw();
962};
963
964// template <> class codecvt<char32_t, char, mbstate_t>
965
966template <>
967class codecvt<char32_t, char, mbstate_t>
968 : public locale::facet,
969 public codecvt_base
970{
971public:
972 typedef char32_t intern_type;
973 typedef char extern_type;
974 typedef mbstate_t state_type;
975
976 _LIBCPP_ALWAYS_INLINE
977 explicit codecvt(size_t __refs = 0)
978 : locale::facet(__refs) {}
979
980 _LIBCPP_ALWAYS_INLINE
981 result out(state_type& __st,
982 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
983 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
984 {
985 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
986 }
987
988 _LIBCPP_ALWAYS_INLINE
989 result unshift(state_type& __st,
990 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
991 {
992 return do_unshift(__st, __to, __to_end, __to_nxt);
993 }
994
995 _LIBCPP_ALWAYS_INLINE
996 result in(state_type& __st,
997 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
998 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
999 {
1000 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1001 }
1002
1003 _LIBCPP_ALWAYS_INLINE
1004 int encoding() const throw()
1005 {
1006 return do_encoding();
1007 }
1008
1009 _LIBCPP_ALWAYS_INLINE
1010 bool always_noconv() const throw()
1011 {
1012 return do_always_noconv();
1013 }
1014
1015 _LIBCPP_ALWAYS_INLINE
1016 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1017 {
1018 return do_length(__st, __frm, __end, __mx);
1019 }
1020
1021 _LIBCPP_ALWAYS_INLINE
1022 int max_length() const throw()
1023 {
1024 return do_max_length();
1025 }
1026
1027 static locale::id id;
1028
1029protected:
1030 _LIBCPP_ALWAYS_INLINE
1031 explicit codecvt(const char*, size_t __refs = 0)
1032 : locale::facet(__refs) {}
1033
1034 ~codecvt();
1035
1036 virtual result do_out(state_type& __st,
1037 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1038 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1039 virtual result do_in(state_type& __st,
1040 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1041 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1042 virtual result do_unshift(state_type& __st,
1043 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1044 virtual int do_encoding() const throw();
1045 virtual bool do_always_noconv() const throw();
1046 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1047 virtual int do_max_length() const throw();
1048};
1049
1050// template <> class codecvt<char32_t, char, mbstate_t>
1051
1052template <>
1053class codecvt<char32_t, char16_t, mbstate_t>
1054 : public locale::facet,
1055 public codecvt_base
1056{
1057public:
1058 typedef char32_t intern_type;
1059 typedef char16_t extern_type;
1060 typedef mbstate_t state_type;
1061
1062 _LIBCPP_ALWAYS_INLINE
1063 explicit codecvt(size_t __refs = 0)
1064 : locale::facet(__refs) {}
1065
1066 _LIBCPP_ALWAYS_INLINE
1067 result out(state_type& __st,
1068 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1069 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1070 {
1071 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1072 }
1073
1074 _LIBCPP_ALWAYS_INLINE
1075 result unshift(state_type& __st,
1076 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1077 {
1078 return do_unshift(__st, __to, __to_end, __to_nxt);
1079 }
1080
1081 _LIBCPP_ALWAYS_INLINE
1082 result in(state_type& __st,
1083 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1084 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1085 {
1086 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1087 }
1088
1089 _LIBCPP_ALWAYS_INLINE
1090 int encoding() const throw()
1091 {
1092 return do_encoding();
1093 }
1094
1095 _LIBCPP_ALWAYS_INLINE
1096 bool always_noconv() const throw()
1097 {
1098 return do_always_noconv();
1099 }
1100
1101 _LIBCPP_ALWAYS_INLINE
1102 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1103 {
1104 return do_length(__st, __frm, __end, __mx);
1105 }
1106
1107 _LIBCPP_ALWAYS_INLINE
1108 int max_length() const throw()
1109 {
1110 return do_max_length();
1111 }
1112
1113 static locale::id id;
1114
1115protected:
1116 _LIBCPP_ALWAYS_INLINE
1117 explicit codecvt(const char*, size_t __refs = 0)
1118 : locale::facet(__refs) {}
1119
1120 ~codecvt();
1121
1122 virtual result do_out(state_type& __st,
1123 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1124 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1125 virtual result do_in(state_type& __st,
1126 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1127 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1128 virtual result do_unshift(state_type& __st,
1129 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1130 virtual int do_encoding() const throw();
1131 virtual bool do_always_noconv() const throw();
1132 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1133 virtual int do_max_length() const throw();
1134};
1135
1136// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1137
1138template <class _InternT, class _ExternT, class _StateT>
1139class codecvt_byname
1140 : public codecvt<_InternT, _ExternT, _StateT>
1141{
1142public:
1143 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1144 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1145 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1146 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1147protected:
1148 ~codecvt_byname();
1149};
1150
1151template <class _InternT, class _ExternT, class _StateT>
1152codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1153{
1154}
1155
1156extern template class codecvt_byname<char, char, mbstate_t>;
1157extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1158extern template class codecvt_byname<char16_t, char, mbstate_t>;
1159extern template class codecvt_byname<char32_t, char, mbstate_t>;
1160
1161void __throw_runtime_error(const char*);
1162
1163template <size_t _N>
1164struct __narrow_to_utf8
1165{
1166 template <class _OutputIterator, class _CharT>
1167 _OutputIterator
1168 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1169};
1170
1171template <>
1172struct __narrow_to_utf8<8>
1173{
1174 template <class _OutputIterator, class _CharT>
1175 _LIBCPP_ALWAYS_INLINE
1176 _OutputIterator
1177 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1178 {
1179 for (; __wb < __we; ++__wb, ++__s)
1180 *__s = *__wb;
1181 return __s;
1182 }
1183};
1184
1185template <>
1186struct __narrow_to_utf8<16>
1187 : public codecvt<char16_t, char, mbstate_t>
1188{
1189 _LIBCPP_ALWAYS_INLINE
1190 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1191
1192 ~__narrow_to_utf8();
1193
1194 template <class _OutputIterator, class _CharT>
1195 _LIBCPP_ALWAYS_INLINE
1196 _OutputIterator
1197 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1198 {
1199 result __r = ok;
1200 mbstate_t __mb;
1201 while (__wb < __we && __r != error)
1202 {
1203 const int __sz = 32;
1204 char __buf[__sz];
1205 char* __bn;
1206 const char16_t* __wn = (const char16_t*)__wb;
1207 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1208 __buf, __buf+__sz, __bn);
1209 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1210 __throw_runtime_error("locale not supported");
1211 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1212 *__s = *__p;
1213 __wb = (const _CharT*)__wn;
1214 }
1215 return __s;
1216 }
1217};
1218
1219template <>
1220struct __narrow_to_utf8<32>
1221 : public codecvt<char32_t, char, mbstate_t>
1222{
1223 _LIBCPP_ALWAYS_INLINE
1224 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1225
1226 ~__narrow_to_utf8();
1227
1228 template <class _OutputIterator, class _CharT>
1229 _LIBCPP_ALWAYS_INLINE
1230 _OutputIterator
1231 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1232 {
1233 result __r = ok;
1234 mbstate_t __mb;
1235 while (__wb < __we && __r != error)
1236 {
1237 const int __sz = 32;
1238 char __buf[__sz];
1239 char* __bn;
1240 const char32_t* __wn = (const char32_t*)__wb;
1241 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1242 __buf, __buf+__sz, __bn);
1243 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1244 __throw_runtime_error("locale not supported");
1245 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1246 *__s = *__p;
1247 __wb = (const _CharT*)__wn;
1248 }
1249 return __s;
1250 }
1251};
1252
1253template <size_t _N>
1254struct __widen_from_utf8
1255{
1256 template <class _OutputIterator>
1257 _OutputIterator
1258 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1259};
1260
1261template <>
1262struct __widen_from_utf8<8>
1263{
1264 template <class _OutputIterator>
1265 _LIBCPP_ALWAYS_INLINE
1266 _OutputIterator
1267 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1268 {
1269 for (; __nb < __ne; ++__nb, ++__s)
1270 *__s = *__nb;
1271 return __s;
1272 }
1273};
1274
1275template <>
1276struct __widen_from_utf8<16>
1277 : public codecvt<char16_t, char, mbstate_t>
1278{
1279 _LIBCPP_ALWAYS_INLINE
1280 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1281
1282 ~__widen_from_utf8();
1283
1284 template <class _OutputIterator>
1285 _LIBCPP_ALWAYS_INLINE
1286 _OutputIterator
1287 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1288 {
1289 result __r = ok;
1290 mbstate_t __mb;
1291 while (__nb < __ne && __r != error)
1292 {
1293 const int __sz = 32;
1294 char16_t __buf[__sz];
1295 char16_t* __bn;
1296 const char* __nn = __nb;
1297 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1298 __buf, __buf+__sz, __bn);
1299 if (__r == codecvt_base::error || __nn == __nb)
1300 __throw_runtime_error("locale not supported");
1301 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1302 *__s = (wchar_t)*__p;
1303 __nb = __nn;
1304 }
1305 return __s;
1306 }
1307};
1308
1309template <>
1310struct __widen_from_utf8<32>
1311 : public codecvt<char32_t, char, mbstate_t>
1312{
1313 _LIBCPP_ALWAYS_INLINE
1314 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1315
1316 ~__widen_from_utf8();
1317
1318 template <class _OutputIterator>
1319 _LIBCPP_ALWAYS_INLINE
1320 _OutputIterator
1321 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1322 {
1323 result __r = ok;
1324 mbstate_t __mb;
1325 while (__nb < __ne && __r != error)
1326 {
1327 const int __sz = 32;
1328 char32_t __buf[__sz];
1329 char32_t* __bn;
1330 const char* __nn = __nb;
1331 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1332 __buf, __buf+__sz, __bn);
1333 if (__r == codecvt_base::error || __nn == __nb)
1334 __throw_runtime_error("locale not supported");
1335 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1336 *__s = (wchar_t)*__p;
1337 __nb = __nn;
1338 }
1339 return __s;
1340 }
1341};
1342
1343// template <class charT> class numpunct
1344
1345template <class _CharT> class numpunct;
1346
1347template <>
1348class numpunct<char>
1349 : public locale::facet
1350{
1351public:
1352 typedef char char_type;
1353 typedef basic_string<char_type> string_type;
1354
1355 explicit numpunct(size_t __refs = 0);
1356
1357 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1358 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1359 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1360 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1361 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1362
1363 static locale::id id;
1364
1365protected:
1366 ~numpunct();
1367 virtual char_type do_decimal_point() const;
1368 virtual char_type do_thousands_sep() const;
1369 virtual string do_grouping() const;
1370 virtual string_type do_truename() const;
1371 virtual string_type do_falsename() const;
1372
1373 char_type __decimal_point_;
1374 char_type __thousands_sep_;
1375 string __grouping_;
1376};
1377
1378template <>
1379class numpunct<wchar_t>
1380 : public locale::facet
1381{
1382public:
1383 typedef wchar_t char_type;
1384 typedef basic_string<char_type> string_type;
1385
1386 explicit numpunct(size_t __refs = 0);
1387
1388 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1389 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1390 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1391 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1392 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1393
1394 static locale::id id;
1395
1396protected:
1397 ~numpunct();
1398 virtual char_type do_decimal_point() const;
1399 virtual char_type do_thousands_sep() const;
1400 virtual string do_grouping() const;
1401 virtual string_type do_truename() const;
1402 virtual string_type do_falsename() const;
1403
1404 char_type __decimal_point_;
1405 char_type __thousands_sep_;
1406 string __grouping_;
1407};
1408
1409// template <class charT> class numpunct_byname
1410
1411template <class charT> class numpunct_byname;
1412
1413template <>
1414class numpunct_byname<char>
1415: public numpunct<char>
1416{
1417public:
1418 typedef char char_type;
1419 typedef basic_string<char_type> string_type;
1420
1421 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1422 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1423
1424protected:
1425 ~numpunct_byname();
1426
1427private:
1428 void __init(const char*);
1429};
1430
1431template <>
1432class numpunct_byname<wchar_t>
1433: public numpunct<wchar_t>
1434{
1435public:
1436 typedef wchar_t char_type;
1437 typedef basic_string<char_type> string_type;
1438
1439 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1440 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1441
1442protected:
1443 ~numpunct_byname();
1444
1445private:
1446 void __init(const char*);
1447};
1448
1449_LIBCPP_END_NAMESPACE_STD
1450
1451#endif // _LIBCPP___LOCALE