blob: 790d37ab5b4a9a26761ed2373df1f65d664c736e [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//
Howard Hinnant412dbeb2010-11-16 22:09:026// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:168//
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
Howard Hinnant35ae4a22010-09-21 18:58:5133class _LIBCPP_VISIBLE locale
Howard Hinnant3e519522010-05-11 19:42:1634{
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
Howard Hinnant35ae4a22010-09-21 18:58:5192class _LIBCPP_VISIBLE locale::facet
Howard Hinnant3e519522010-05-11 19:42:1693 : public __shared_count
94{
95protected:
Howard Hinnant35ae4a22010-09-21 18:58:5196 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:1697 explicit facet(size_t __refs = 0)
98 : __shared_count(static_cast<long>(__refs)-1) {}
99
100 virtual ~facet();
101
102// facet(const facet&) = delete; // effectively done in __shared_count
103// void operator=(const facet&) = delete;
104private:
105 virtual void __on_zero_shared();
106};
107
Howard Hinnant35ae4a22010-09-21 18:58:51108class _LIBCPP_VISIBLE locale::id
Howard Hinnant3e519522010-05-11 19:42:16109{
110 once_flag __flag_;
111 int32_t __id_;
Howard Hinnantb3371f62010-08-22 00:02:43112
Howard Hinnant3e519522010-05-11 19:42:16113 static int32_t __next_id;
114public:
Howard Hinnant35ae4a22010-09-21 18:58:51115 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnant3e519522010-05-11 19:42:16116private:
117 void __init();
118 void operator=(const id&); // = delete;
119 id(const id&); // = delete;
120public: // only needed for tests
121 long __get();
122
123 friend class locale;
124 friend class locale::__imp;
125};
126
127template <class _Facet>
128inline _LIBCPP_INLINE_VISIBILITY
129locale::locale(const locale& __other, _Facet* __f)
130{
131 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
132}
133
134template <class _Facet>
135locale
136locale::combine(const locale& __other) const
137{
Howard Hinnant54b409f2010-08-11 17:04:31138#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16139 if (!_STD::has_facet<_Facet>(__other))
140 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnantb3371f62010-08-22 00:02:43141#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16142 return locale(*this, &const_cast<_Facet&>(_STD::use_facet<_Facet>(__other)));
143}
144
145template <class _Facet>
146inline _LIBCPP_INLINE_VISIBILITY
147bool
148has_facet(const locale& __l) throw()
149{
150 return __l.has_facet(_Facet::id);
151}
152
153template <class _Facet>
154inline _LIBCPP_INLINE_VISIBILITY
155const _Facet&
156use_facet(const locale& __l)
157{
158 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
159}
160
161// template <class _CharT> class collate;
162
163template <class _CharT>
Howard Hinnant35ae4a22010-09-21 18:58:51164class _LIBCPP_VISIBLE collate
Howard Hinnant3e519522010-05-11 19:42:16165 : public locale::facet
166{
167public:
168 typedef _CharT char_type;
169 typedef basic_string<char_type> string_type;
170
Howard Hinnant35ae4a22010-09-21 18:58:51171 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16172 explicit collate(size_t __refs = 0)
173 : locale::facet(__refs) {}
174
Howard Hinnant35ae4a22010-09-21 18:58:51175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16176 int compare(const char_type* __lo1, const char_type* __hi1,
177 const char_type* __lo2, const char_type* __hi2) const
178 {
179 return do_compare(__lo1, __hi1, __lo2, __hi2);
180 }
181
Howard Hinnant35ae4a22010-09-21 18:58:51182 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16183 string_type transform(const char_type* __lo, const char_type* __hi) const
184 {
185 return do_transform(__lo, __hi);
186 }
187
Howard Hinnant35ae4a22010-09-21 18:58:51188 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16189 long hash(const char_type* __lo, const char_type* __hi) const
190 {
191 return do_hash(__lo, __hi);
192 }
193
194 static locale::id id;
195
196protected:
197 ~collate();
198 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
199 const char_type* __lo2, const char_type* __hi2) const;
200 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
201 {return string_type(__lo, __hi);}
202 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
203};
204
205template <class _CharT> locale::id collate<_CharT>::id;
206
207template <class _CharT>
208collate<_CharT>::~collate()
209{
210}
211
212template <class _CharT>
213int
214collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
215 const char_type* __lo2, const char_type* __hi2) const
216{
217 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
218 {
219 if (__lo1 == __hi1 || *__lo1 < *__lo2)
220 return -1;
221 if (*__lo2 < *__lo1)
222 return 1;
223 }
224 return __lo1 != __hi1;
225}
226
227template <class _CharT>
228long
229collate<_CharT>::do_hash(const char_type* lo, const char_type* hi) const
230{
231 size_t h = 0;
232 const size_t sr = __CHAR_BIT__ * sizeof(size_t) - 8;
233 const size_t mask = size_t(0xF) << (sr + 4);
234 for(const char_type* p = lo; p != hi; ++p)
235 {
236 h = (h << 4) + *p;
237 size_t g = h & mask;
238 h ^= g | (g >> sr);
239 }
240 return static_cast<long>(h);
241}
242
Howard Hinnant35ae4a22010-09-21 18:58:51243extern template class _LIBCPP_VISIBLE collate<char>;
244extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnant3e519522010-05-11 19:42:16245
246// template <class CharT> class collate_byname;
247
Howard Hinnant35ae4a22010-09-21 18:58:51248template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnant3e519522010-05-11 19:42:16249
250template <>
Howard Hinnant35ae4a22010-09-21 18:58:51251class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnant3e519522010-05-11 19:42:16252 : public collate<char>
253{
254 locale_t __l;
255public:
256 typedef char char_type;
257 typedef basic_string<char_type> string_type;
258
259 explicit collate_byname(const char* __n, size_t __refs = 0);
260 explicit collate_byname(const string& __n, size_t __refs = 0);
261
262protected:
263 ~collate_byname();
264 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
265 const char_type* __lo2, const char_type* __hi2) const;
266 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
267};
268
269template <>
Howard Hinnant35ae4a22010-09-21 18:58:51270class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:16271 : public collate<wchar_t>
272{
273 locale_t __l;
274public:
275 typedef wchar_t char_type;
276 typedef basic_string<char_type> string_type;
277
278 explicit collate_byname(const char* __n, size_t __refs = 0);
279 explicit collate_byname(const string& __n, size_t __refs = 0);
280
281protected:
282 ~collate_byname();
283
284 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
285 const char_type* __lo2, const char_type* __hi2) const;
286 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
287};
288
289template <class _CharT, class _Traits, class _Allocator>
290bool
291locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
292 const basic_string<_CharT, _Traits, _Allocator>& __y) const
293{
294 return _STD::use_facet<_STD::collate<_CharT> >(*this).compare(
295 __x.data(), __x.data() + __x.size(),
296 __y.data(), __y.data() + __y.size()) < 0;
297}
298
299// template <class charT> class ctype
300
Howard Hinnant35ae4a22010-09-21 18:58:51301class _LIBCPP_VISIBLE ctype_base
302{
Howard Hinnant3e519522010-05-11 19:42:16303public:
304 typedef __uint32_t mask;
305
Howard Hinnant128ba712010-05-24 17:49:41306#if __APPLE__
Howard Hinnant3e519522010-05-11 19:42:16307 static const mask space = _CTYPE_S;
308 static const mask print = _CTYPE_R;
309 static const mask cntrl = _CTYPE_C;
310 static const mask upper = _CTYPE_U;
311 static const mask lower = _CTYPE_L;
312 static const mask alpha = _CTYPE_A;
313 static const mask digit = _CTYPE_D;
314 static const mask punct = _CTYPE_P;
315 static const mask xdigit = _CTYPE_X;
316 static const mask blank = _CTYPE_B;
Howard Hinnantb3371f62010-08-22 00:02:43317#else // __APPLE__
Howard Hinnant128ba712010-05-24 17:49:41318 static const mask space = _ISspace;
319 static const mask print = _ISprint;
320 static const mask cntrl = _IScntrl;
321 static const mask upper = _ISupper;
322 static const mask lower = _ISlower;
323 static const mask alpha = _ISalpha;
324 static const mask digit = _ISdigit;
325 static const mask punct = _ISpunct;
326 static const mask xdigit = _ISxdigit;
327 static const mask blank = _ISblank;
Howard Hinnantb3371f62010-08-22 00:02:43328#endif // __APPLE__
Howard Hinnant3e519522010-05-11 19:42:16329 static const mask alnum = alpha | digit;
330 static const mask graph = alnum | punct;
331
332 _LIBCPP_ALWAYS_INLINE ctype_base() {}
333};
334
Howard Hinnant35ae4a22010-09-21 18:58:51335template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnant3e519522010-05-11 19:42:16336
337template <>
Howard Hinnant35ae4a22010-09-21 18:58:51338class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:16339 : public locale::facet,
340 public ctype_base
341{
342public:
343 typedef wchar_t char_type;
Howard Hinnantb3371f62010-08-22 00:02:43344
Howard Hinnant3e519522010-05-11 19:42:16345 _LIBCPP_ALWAYS_INLINE
346 explicit ctype(size_t __refs = 0)
347 : locale::facet(__refs) {}
348
349 _LIBCPP_ALWAYS_INLINE
350 bool is(mask __m, char_type __c) const
351 {
352 return do_is(__m, __c);
353 }
354
355 _LIBCPP_ALWAYS_INLINE
356 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
357 {
358 return do_is(__low, __high, __vec);
359 }
360
361 _LIBCPP_ALWAYS_INLINE
362 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
363 {
364 return do_scan_is(__m, __low, __high);
365 }
366
367 _LIBCPP_ALWAYS_INLINE
368 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
369 {
370 return do_scan_not(__m, __low, __high);
371 }
372
373 _LIBCPP_ALWAYS_INLINE
374 char_type toupper(char_type __c) const
375 {
376 return do_toupper(__c);
377 }
378
379 _LIBCPP_ALWAYS_INLINE
380 const char_type* toupper(char_type* __low, const char_type* __high) const
381 {
382 return do_toupper(__low, __high);
383 }
384
385 _LIBCPP_ALWAYS_INLINE
386 char_type tolower(char_type __c) const
387 {
388 return do_tolower(__c);
389 }
390
391 _LIBCPP_ALWAYS_INLINE
392 const char_type* tolower(char_type* __low, const char_type* __high) const
393 {
394 return do_tolower(__low, __high);
395 }
396
397 _LIBCPP_ALWAYS_INLINE
398 char_type widen(char __c) const
399 {
400 return do_widen(__c);
401 }
402
403 _LIBCPP_ALWAYS_INLINE
404 const char* widen(const char* __low, const char* __high, char_type* __to) const
405 {
406 return do_widen(__low, __high, __to);
407 }
408
409 _LIBCPP_ALWAYS_INLINE
410 char narrow(char_type __c, char __dfault) const
411 {
412 return do_narrow(__c, __dfault);
413 }
414
415 _LIBCPP_ALWAYS_INLINE
416 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
417 {
418 return do_narrow(__low, __high, __dfault, __to);
419 }
420
421 static locale::id id;
422
423protected:
424 ~ctype();
425 virtual bool do_is(mask __m, char_type __c) const;
426 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
427 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
428 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
429 virtual char_type do_toupper(char_type) const;
430 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
431 virtual char_type do_tolower(char_type) const;
432 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
433 virtual char_type do_widen(char) const;
434 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
435 virtual char do_narrow(char_type, char __dfault) const;
436 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
437};
438
439template <>
Howard Hinnant35ae4a22010-09-21 18:58:51440class _LIBCPP_VISIBLE ctype<char>
Howard Hinnant3e519522010-05-11 19:42:16441 : public locale::facet, public ctype_base
442{
443 const mask* __tab_;
444 bool __del_;
445public:
446 typedef char char_type;
447
448 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
449
450 _LIBCPP_ALWAYS_INLINE
451 bool is(mask __m, char_type __c) const
452 {
453 return isascii(__c) ? __tab_[__c] & __m : false;
454 }
455
456 _LIBCPP_ALWAYS_INLINE
457 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
458 {
459 for (; __low != __high; ++__low, ++__vec)
460 *__vec = isascii(*__low) ? __tab_[*__low] : 0;
461 return __low;
462 }
463
464 _LIBCPP_ALWAYS_INLINE
465 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
466 {
467 for (; __low != __high; ++__low)
468 if (isascii(*__low) && (__tab_[*__low] & __m))
469 break;
470 return __low;
471 }
472
473 _LIBCPP_ALWAYS_INLINE
474 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
475 {
476 for (; __low != __high; ++__low)
477 if (!(isascii(*__low) && (__tab_[*__low] & __m)))
478 break;
479 return __low;
480 }
481
482 _LIBCPP_ALWAYS_INLINE
483 char_type toupper(char_type __c) const
484 {
485 return do_toupper(__c);
486 }
487
488 _LIBCPP_ALWAYS_INLINE
489 const char_type* toupper(char_type* __low, const char_type* __high) const
490 {
491 return do_toupper(__low, __high);
492 }
493
494 _LIBCPP_ALWAYS_INLINE
495 char_type tolower(char_type __c) const
496 {
497 return do_tolower(__c);
498 }
499
500 _LIBCPP_ALWAYS_INLINE
501 const char_type* tolower(char_type* __low, const char_type* __high) const
502 {
503 return do_tolower(__low, __high);
504 }
505
506 _LIBCPP_ALWAYS_INLINE
507 char_type widen(char __c) const
508 {
509 return do_widen(__c);
510 }
511
512 _LIBCPP_ALWAYS_INLINE
513 const char* widen(const char* __low, const char* __high, char_type* __to) const
514 {
515 return do_widen(__low, __high, __to);
516 }
517
518 _LIBCPP_ALWAYS_INLINE
519 char narrow(char_type __c, char __dfault) const
520 {
521 return do_narrow(__c, __dfault);
522 }
523
524 _LIBCPP_ALWAYS_INLINE
525 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
526 {
527 return do_narrow(__low, __high, __dfault, __to);
528 }
529
530 static locale::id id;
531
Howard Hinnant128ba712010-05-24 17:49:41532#ifdef _CACHED_RUNES
Howard Hinnant3e519522010-05-11 19:42:16533 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant128ba712010-05-24 17:49:41534#else
535 static const size_t table_size = 256; // FIXME: Don't hardcode this.
536#endif
Howard Hinnant35ae4a22010-09-21 18:58:51537 _LIBCPP_ALWAYS_INLINE const mask* table() const throw() {return __tab_;}
Howard Hinnant3e519522010-05-11 19:42:16538 static const mask* classic_table() throw();
539
540protected:
541 ~ctype();
542 virtual char_type do_toupper(char_type __c) const;
543 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
544 virtual char_type do_tolower(char_type __c) const;
545 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
546 virtual char_type do_widen(char __c) const;
547 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
548 virtual char do_narrow(char_type __c, char __dfault) const;
549 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
550};
551
552// template <class CharT> class ctype_byname;
553
Howard Hinnant35ae4a22010-09-21 18:58:51554template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnant3e519522010-05-11 19:42:16555
556template <>
Howard Hinnant35ae4a22010-09-21 18:58:51557class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnant3e519522010-05-11 19:42:16558 : public ctype<char>
559{
560 locale_t __l;
561
562public:
563 explicit ctype_byname(const char*, size_t = 0);
564 explicit ctype_byname(const string&, size_t = 0);
565
566protected:
567 ~ctype_byname();
568 virtual char_type do_toupper(char_type) const;
569 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
570 virtual char_type do_tolower(char_type) const;
571 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
572};
573
574template <>
Howard Hinnant35ae4a22010-09-21 18:58:51575class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:16576 : public ctype<wchar_t>
577{
578 locale_t __l;
579
580public:
581 explicit ctype_byname(const char*, size_t = 0);
582 explicit ctype_byname(const string&, size_t = 0);
583
584protected:
585 ~ctype_byname();
586 virtual bool do_is(mask __m, char_type __c) const;
587 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
588 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
589 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
590 virtual char_type do_toupper(char_type) const;
591 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
592 virtual char_type do_tolower(char_type) const;
593 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
594 virtual char_type do_widen(char) const;
595 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
596 virtual char do_narrow(char_type, char __dfault) const;
597 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
598};
599
600template <class _CharT>
601inline _LIBCPP_INLINE_VISIBILITY
602bool
603isspace(_CharT __c, const locale& __loc)
604{
605 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
606}
607
608template <class _CharT>
609inline _LIBCPP_INLINE_VISIBILITY
610bool
611isprint(_CharT __c, const locale& __loc)
612{
613 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
614}
615
616template <class _CharT>
617inline _LIBCPP_INLINE_VISIBILITY
618bool
619iscntrl(_CharT __c, const locale& __loc)
620{
621 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
622}
623
624template <class _CharT>
625inline _LIBCPP_INLINE_VISIBILITY
626bool
627isupper(_CharT __c, const locale& __loc)
628{
629 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
630}
631
632template <class _CharT>
633inline _LIBCPP_INLINE_VISIBILITY
634bool
635islower(_CharT __c, const locale& __loc)
636{
637 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
638}
639
640template <class _CharT>
641inline _LIBCPP_INLINE_VISIBILITY
642bool
643isalpha(_CharT __c, const locale& __loc)
644{
645 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
646}
647
648template <class _CharT>
649inline _LIBCPP_INLINE_VISIBILITY
650bool
651isdigit(_CharT __c, const locale& __loc)
652{
653 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
654}
655
656template <class _CharT>
657inline _LIBCPP_INLINE_VISIBILITY
658bool
659ispunct(_CharT __c, const locale& __loc)
660{
661 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
662}
663
664template <class _CharT>
665inline _LIBCPP_INLINE_VISIBILITY
666bool
667isxdigit(_CharT __c, const locale& __loc)
668{
669 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
670}
671
672template <class _CharT>
673inline _LIBCPP_INLINE_VISIBILITY
674bool
675isalnum(_CharT __c, const locale& __loc)
676{
677 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
678}
679
680template <class _CharT>
681inline _LIBCPP_INLINE_VISIBILITY
682bool
683isgraph(_CharT __c, const locale& __loc)
684{
685 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
686}
687
688template <class _CharT>
689inline _LIBCPP_INLINE_VISIBILITY
690_CharT
691toupper(_CharT __c, const locale& __loc)
692{
693 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
694}
695
696template <class _CharT>
697inline _LIBCPP_INLINE_VISIBILITY
698_CharT
699tolower(_CharT __c, const locale& __loc)
700{
701 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
702}
703
704// codecvt_base
705
Howard Hinnant35ae4a22010-09-21 18:58:51706class _LIBCPP_VISIBLE codecvt_base
Howard Hinnant3e519522010-05-11 19:42:16707{
708public:
709 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
710 enum result {ok, partial, error, noconv};
711};
712
713// template <class internT, class externT, class stateT> class codecvt;
714
Howard Hinnant35ae4a22010-09-21 18:58:51715template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnant3e519522010-05-11 19:42:16716
717// template <> class codecvt<char, char, mbstate_t>
718
719template <>
Howard Hinnant35ae4a22010-09-21 18:58:51720class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16721 : public locale::facet,
722 public codecvt_base
723{
724public:
725 typedef char intern_type;
726 typedef char extern_type;
727 typedef mbstate_t state_type;
728
729 _LIBCPP_ALWAYS_INLINE
730 explicit codecvt(size_t __refs = 0)
731 : locale::facet(__refs) {}
732
733 _LIBCPP_ALWAYS_INLINE
734 result out(state_type& __st,
735 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
736 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
737 {
738 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
739 }
740
741 _LIBCPP_ALWAYS_INLINE
742 result unshift(state_type& __st,
743 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
744 {
745 return do_unshift(__st, __to, __to_end, __to_nxt);
746 }
747
748 _LIBCPP_ALWAYS_INLINE
749 result in(state_type& __st,
750 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
751 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
752 {
753 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
754 }
755
756 _LIBCPP_ALWAYS_INLINE
757 int encoding() const throw()
758 {
759 return do_encoding();
760 }
761
762 _LIBCPP_ALWAYS_INLINE
763 bool always_noconv() const throw()
764 {
765 return do_always_noconv();
766 }
767
768 _LIBCPP_ALWAYS_INLINE
769 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
770 {
771 return do_length(__st, __frm, __end, __mx);
772 }
773
774 _LIBCPP_ALWAYS_INLINE
775 int max_length() const throw()
776 {
777 return do_max_length();
778 }
779
780 static locale::id id;
781
782protected:
783 _LIBCPP_ALWAYS_INLINE
784 explicit codecvt(const char*, size_t __refs = 0)
785 : locale::facet(__refs) {}
786
787 ~codecvt();
788
789 virtual result do_out(state_type& __st,
790 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
791 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
792 virtual result do_in(state_type& __st,
793 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
794 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
795 virtual result do_unshift(state_type& __st,
796 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
797 virtual int do_encoding() const throw();
798 virtual bool do_always_noconv() const throw();
799 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
800 virtual int do_max_length() const throw();
801};
802
803// template <> class codecvt<wchar_t, char, mbstate_t>
804
805template <>
Howard Hinnant35ae4a22010-09-21 18:58:51806class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16807 : public locale::facet,
808 public codecvt_base
809{
810 locale_t __l;
811public:
812 typedef wchar_t intern_type;
813 typedef char extern_type;
814 typedef mbstate_t state_type;
815
816 explicit codecvt(size_t __refs = 0);
817
818 _LIBCPP_ALWAYS_INLINE
819 result out(state_type& __st,
820 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
821 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
822 {
823 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
824 }
825
826 _LIBCPP_ALWAYS_INLINE
827 result unshift(state_type& __st,
828 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
829 {
830 return do_unshift(__st, __to, __to_end, __to_nxt);
831 }
832
833 _LIBCPP_ALWAYS_INLINE
834 result in(state_type& __st,
835 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
836 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
837 {
838 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
839 }
840
841 _LIBCPP_ALWAYS_INLINE
842 int encoding() const throw()
843 {
844 return do_encoding();
845 }
846
847 _LIBCPP_ALWAYS_INLINE
848 bool always_noconv() const throw()
849 {
850 return do_always_noconv();
851 }
852
853 _LIBCPP_ALWAYS_INLINE
854 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
855 {
856 return do_length(__st, __frm, __end, __mx);
857 }
858
859 _LIBCPP_ALWAYS_INLINE
860 int max_length() const throw()
861 {
862 return do_max_length();
863 }
864
865 static locale::id id;
866
867protected:
868 explicit codecvt(const char*, size_t __refs = 0);
869
870 ~codecvt();
871
872 virtual result do_out(state_type& __st,
873 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
874 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
875 virtual result do_in(state_type& __st,
876 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
877 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
878 virtual result do_unshift(state_type& __st,
879 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
880 virtual int do_encoding() const throw();
881 virtual bool do_always_noconv() const throw();
882 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
883 virtual int do_max_length() const throw();
884};
885
886// template <> class codecvt<char16_t, char, mbstate_t>
887
888template <>
Howard Hinnant35ae4a22010-09-21 18:58:51889class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16890 : public locale::facet,
891 public codecvt_base
892{
893public:
894 typedef char16_t intern_type;
895 typedef char extern_type;
896 typedef mbstate_t state_type;
897
898 _LIBCPP_ALWAYS_INLINE
899 explicit codecvt(size_t __refs = 0)
900 : locale::facet(__refs) {}
901
902 _LIBCPP_ALWAYS_INLINE
903 result out(state_type& __st,
904 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
905 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
906 {
907 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
908 }
909
910 _LIBCPP_ALWAYS_INLINE
911 result unshift(state_type& __st,
912 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
913 {
914 return do_unshift(__st, __to, __to_end, __to_nxt);
915 }
916
917 _LIBCPP_ALWAYS_INLINE
918 result in(state_type& __st,
919 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
920 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
921 {
922 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
923 }
924
925 _LIBCPP_ALWAYS_INLINE
926 int encoding() const throw()
927 {
928 return do_encoding();
929 }
930
931 _LIBCPP_ALWAYS_INLINE
932 bool always_noconv() const throw()
933 {
934 return do_always_noconv();
935 }
936
937 _LIBCPP_ALWAYS_INLINE
938 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
939 {
940 return do_length(__st, __frm, __end, __mx);
941 }
942
943 _LIBCPP_ALWAYS_INLINE
944 int max_length() const throw()
945 {
946 return do_max_length();
947 }
948
949 static locale::id id;
950
951protected:
952 _LIBCPP_ALWAYS_INLINE
953 explicit codecvt(const char*, size_t __refs = 0)
954 : locale::facet(__refs) {}
955
956 ~codecvt();
957
958 virtual result do_out(state_type& __st,
959 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
960 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
961 virtual result do_in(state_type& __st,
962 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
963 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
964 virtual result do_unshift(state_type& __st,
965 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
966 virtual int do_encoding() const throw();
967 virtual bool do_always_noconv() const throw();
968 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
969 virtual int do_max_length() const throw();
970};
971
972// template <> class codecvt<char32_t, char, mbstate_t>
973
974template <>
Howard Hinnant35ae4a22010-09-21 18:58:51975class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16976 : public locale::facet,
977 public codecvt_base
978{
979public:
980 typedef char32_t intern_type;
981 typedef char extern_type;
982 typedef mbstate_t state_type;
983
984 _LIBCPP_ALWAYS_INLINE
985 explicit codecvt(size_t __refs = 0)
986 : locale::facet(__refs) {}
987
988 _LIBCPP_ALWAYS_INLINE
989 result out(state_type& __st,
990 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
991 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
992 {
993 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
994 }
995
996 _LIBCPP_ALWAYS_INLINE
997 result unshift(state_type& __st,
998 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
999 {
1000 return do_unshift(__st, __to, __to_end, __to_nxt);
1001 }
1002
1003 _LIBCPP_ALWAYS_INLINE
1004 result in(state_type& __st,
1005 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1006 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1007 {
1008 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1009 }
1010
1011 _LIBCPP_ALWAYS_INLINE
1012 int encoding() const throw()
1013 {
1014 return do_encoding();
1015 }
1016
1017 _LIBCPP_ALWAYS_INLINE
1018 bool always_noconv() const throw()
1019 {
1020 return do_always_noconv();
1021 }
1022
1023 _LIBCPP_ALWAYS_INLINE
1024 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1025 {
1026 return do_length(__st, __frm, __end, __mx);
1027 }
1028
1029 _LIBCPP_ALWAYS_INLINE
1030 int max_length() const throw()
1031 {
1032 return do_max_length();
1033 }
1034
1035 static locale::id id;
1036
1037protected:
1038 _LIBCPP_ALWAYS_INLINE
1039 explicit codecvt(const char*, size_t __refs = 0)
1040 : locale::facet(__refs) {}
1041
1042 ~codecvt();
1043
1044 virtual result do_out(state_type& __st,
1045 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1046 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1047 virtual result do_in(state_type& __st,
1048 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1049 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1050 virtual result do_unshift(state_type& __st,
1051 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1052 virtual int do_encoding() const throw();
1053 virtual bool do_always_noconv() const throw();
1054 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1055 virtual int do_max_length() const throw();
1056};
1057
Howard Hinnant3e519522010-05-11 19:42:161058// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1059
1060template <class _InternT, class _ExternT, class _StateT>
Howard Hinnant35ae4a22010-09-21 18:58:511061class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnant3e519522010-05-11 19:42:161062 : public codecvt<_InternT, _ExternT, _StateT>
1063{
1064public:
Howard Hinnant35ae4a22010-09-21 18:58:511065 _LIBCPP_ALWAYS_INLINE
Howard Hinnant3e519522010-05-11 19:42:161066 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1067 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant35ae4a22010-09-21 18:58:511068 _LIBCPP_ALWAYS_INLINE
Howard Hinnant3e519522010-05-11 19:42:161069 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1070 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1071protected:
1072 ~codecvt_byname();
1073};
1074
1075template <class _InternT, class _ExternT, class _StateT>
1076codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1077{
1078}
1079
1080extern template class codecvt_byname<char, char, mbstate_t>;
1081extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1082extern template class codecvt_byname<char16_t, char, mbstate_t>;
1083extern template class codecvt_byname<char32_t, char, mbstate_t>;
1084
Howard Hinnant35ae4a22010-09-21 18:58:511085_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnant3e519522010-05-11 19:42:161086
1087template <size_t _N>
1088struct __narrow_to_utf8
1089{
1090 template <class _OutputIterator, class _CharT>
1091 _OutputIterator
1092 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1093};
1094
1095template <>
1096struct __narrow_to_utf8<8>
1097{
1098 template <class _OutputIterator, class _CharT>
1099 _LIBCPP_ALWAYS_INLINE
1100 _OutputIterator
1101 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1102 {
1103 for (; __wb < __we; ++__wb, ++__s)
1104 *__s = *__wb;
1105 return __s;
1106 }
1107};
1108
1109template <>
1110struct __narrow_to_utf8<16>
1111 : public codecvt<char16_t, char, mbstate_t>
1112{
1113 _LIBCPP_ALWAYS_INLINE
1114 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1115
1116 ~__narrow_to_utf8();
1117
1118 template <class _OutputIterator, class _CharT>
1119 _LIBCPP_ALWAYS_INLINE
1120 _OutputIterator
1121 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1122 {
1123 result __r = ok;
1124 mbstate_t __mb;
1125 while (__wb < __we && __r != error)
1126 {
1127 const int __sz = 32;
1128 char __buf[__sz];
1129 char* __bn;
1130 const char16_t* __wn = (const char16_t*)__wb;
1131 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1132 __buf, __buf+__sz, __bn);
1133 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1134 __throw_runtime_error("locale not supported");
1135 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1136 *__s = *__p;
1137 __wb = (const _CharT*)__wn;
1138 }
1139 return __s;
1140 }
1141};
1142
1143template <>
1144struct __narrow_to_utf8<32>
1145 : public codecvt<char32_t, char, mbstate_t>
1146{
1147 _LIBCPP_ALWAYS_INLINE
1148 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1149
1150 ~__narrow_to_utf8();
1151
1152 template <class _OutputIterator, class _CharT>
1153 _LIBCPP_ALWAYS_INLINE
1154 _OutputIterator
1155 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1156 {
1157 result __r = ok;
1158 mbstate_t __mb;
1159 while (__wb < __we && __r != error)
1160 {
1161 const int __sz = 32;
1162 char __buf[__sz];
1163 char* __bn;
1164 const char32_t* __wn = (const char32_t*)__wb;
1165 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1166 __buf, __buf+__sz, __bn);
1167 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1168 __throw_runtime_error("locale not supported");
1169 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1170 *__s = *__p;
1171 __wb = (const _CharT*)__wn;
1172 }
1173 return __s;
1174 }
1175};
1176
1177template <size_t _N>
1178struct __widen_from_utf8
1179{
1180 template <class _OutputIterator>
1181 _OutputIterator
1182 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1183};
1184
1185template <>
1186struct __widen_from_utf8<8>
1187{
1188 template <class _OutputIterator>
1189 _LIBCPP_ALWAYS_INLINE
1190 _OutputIterator
1191 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1192 {
1193 for (; __nb < __ne; ++__nb, ++__s)
1194 *__s = *__nb;
1195 return __s;
1196 }
1197};
1198
1199template <>
1200struct __widen_from_utf8<16>
1201 : public codecvt<char16_t, char, mbstate_t>
1202{
1203 _LIBCPP_ALWAYS_INLINE
1204 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1205
1206 ~__widen_from_utf8();
1207
1208 template <class _OutputIterator>
1209 _LIBCPP_ALWAYS_INLINE
1210 _OutputIterator
1211 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1212 {
1213 result __r = ok;
1214 mbstate_t __mb;
1215 while (__nb < __ne && __r != error)
1216 {
1217 const int __sz = 32;
1218 char16_t __buf[__sz];
1219 char16_t* __bn;
1220 const char* __nn = __nb;
1221 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1222 __buf, __buf+__sz, __bn);
1223 if (__r == codecvt_base::error || __nn == __nb)
1224 __throw_runtime_error("locale not supported");
1225 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1226 *__s = (wchar_t)*__p;
1227 __nb = __nn;
1228 }
1229 return __s;
1230 }
1231};
1232
1233template <>
1234struct __widen_from_utf8<32>
1235 : public codecvt<char32_t, char, mbstate_t>
1236{
1237 _LIBCPP_ALWAYS_INLINE
1238 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1239
1240 ~__widen_from_utf8();
1241
1242 template <class _OutputIterator>
1243 _LIBCPP_ALWAYS_INLINE
1244 _OutputIterator
1245 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1246 {
1247 result __r = ok;
1248 mbstate_t __mb;
1249 while (__nb < __ne && __r != error)
1250 {
1251 const int __sz = 32;
1252 char32_t __buf[__sz];
1253 char32_t* __bn;
1254 const char* __nn = __nb;
1255 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1256 __buf, __buf+__sz, __bn);
1257 if (__r == codecvt_base::error || __nn == __nb)
1258 __throw_runtime_error("locale not supported");
1259 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1260 *__s = (wchar_t)*__p;
1261 __nb = __nn;
1262 }
1263 return __s;
1264 }
1265};
1266
1267// template <class charT> class numpunct
1268
Howard Hinnant35ae4a22010-09-21 18:58:511269template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnant3e519522010-05-11 19:42:161270
1271template <>
Howard Hinnant35ae4a22010-09-21 18:58:511272class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnant3e519522010-05-11 19:42:161273 : public locale::facet
1274{
1275public:
1276 typedef char char_type;
1277 typedef basic_string<char_type> string_type;
1278
1279 explicit numpunct(size_t __refs = 0);
1280
1281 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1282 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1283 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1284 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1285 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1286
1287 static locale::id id;
1288
1289protected:
1290 ~numpunct();
1291 virtual char_type do_decimal_point() const;
1292 virtual char_type do_thousands_sep() const;
1293 virtual string do_grouping() const;
1294 virtual string_type do_truename() const;
1295 virtual string_type do_falsename() const;
1296
1297 char_type __decimal_point_;
1298 char_type __thousands_sep_;
1299 string __grouping_;
1300};
1301
1302template <>
Howard Hinnant35ae4a22010-09-21 18:58:511303class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:161304 : public locale::facet
1305{
1306public:
1307 typedef wchar_t char_type;
1308 typedef basic_string<char_type> string_type;
1309
1310 explicit numpunct(size_t __refs = 0);
1311
1312 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1313 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1314 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1315 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1316 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1317
1318 static locale::id id;
1319
1320protected:
1321 ~numpunct();
1322 virtual char_type do_decimal_point() const;
1323 virtual char_type do_thousands_sep() const;
1324 virtual string do_grouping() const;
1325 virtual string_type do_truename() const;
1326 virtual string_type do_falsename() const;
1327
1328 char_type __decimal_point_;
1329 char_type __thousands_sep_;
1330 string __grouping_;
1331};
1332
1333// template <class charT> class numpunct_byname
1334
Howard Hinnant35ae4a22010-09-21 18:58:511335template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnant3e519522010-05-11 19:42:161336
1337template <>
Howard Hinnant35ae4a22010-09-21 18:58:511338class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnant3e519522010-05-11 19:42:161339: public numpunct<char>
1340{
1341public:
1342 typedef char char_type;
1343 typedef basic_string<char_type> string_type;
1344
1345 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1346 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1347
1348protected:
1349 ~numpunct_byname();
1350
1351private:
1352 void __init(const char*);
1353};
1354
1355template <>
Howard Hinnant35ae4a22010-09-21 18:58:511356class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:161357: public numpunct<wchar_t>
1358{
1359public:
1360 typedef wchar_t char_type;
1361 typedef basic_string<char_type> string_type;
1362
1363 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1364 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1365
1366protected:
1367 ~numpunct_byname();
1368
1369private:
1370 void __init(const char*);
1371};
1372
1373_LIBCPP_END_NAMESPACE_STD
1374
1375#endif // _LIBCPP___LOCALE