blob: 4099aa7e0ffe09e7b862dab9f14235fd19785d34 [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
Howard Hinnantb5d866d2011-05-31 15:34:5830template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:1631template <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:
Howard Hinnantb5d866d2011-05-31 15:34:5852 locale() _NOEXCEPT;
53 locale(const locale&) _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:1654 explicit locale(const char*);
55 explicit locale(const string&);
56 locale(const locale&, const char*, category);
57 locale(const locale&, const string&, category);
Howard Hinnantc950e772010-12-17 14:46:4358 template <class _Facet>
59 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnant3e519522010-05-11 19:42:1660 locale(const locale&, const locale&, category);
61
Howard Hinnantb5d866d2011-05-31 15:34:5862 ~locale();
Howard Hinnant3e519522010-05-11 19:42:1663
Howard Hinnantb5d866d2011-05-31 15:34:5864 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:1665
66 template <class _Facet> locale combine(const locale&) const;
67
68 // locale operations:
69 string name() const;
70 bool operator==(const locale&) const;
71 bool operator!=(const locale& __y) const {return !(*this == __y);}
72 template <class _CharT, class _Traits, class _Allocator>
73 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
74 const basic_string<_CharT, _Traits, _Allocator>&) const;
75
76 // global locale objects:
77 static locale global(const locale&);
78 static const locale& classic();
79
80private:
81 class __imp;
82 __imp* __locale_;
83
84 void __install_ctor(const locale&, facet*, long);
85 static locale& __global();
86 bool has_facet(id&) const;
87 const facet* use_facet(id&) const;
88
Howard Hinnantb5d866d2011-05-31 15:34:5889 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:1690 template <class _Facet> friend const _Facet& use_facet(const locale&);
91};
92
Howard Hinnant35ae4a22010-09-21 18:58:5193class _LIBCPP_VISIBLE locale::facet
Howard Hinnant3e519522010-05-11 19:42:1694 : public __shared_count
95{
96protected:
Howard Hinnant35ae4a22010-09-21 18:58:5197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:1698 explicit facet(size_t __refs = 0)
99 : __shared_count(static_cast<long>(__refs)-1) {}
100
101 virtual ~facet();
102
103// facet(const facet&) = delete; // effectively done in __shared_count
104// void operator=(const facet&) = delete;
105private:
Howard Hinnant3739fe72011-05-28 14:41:13106 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16107};
108
Howard Hinnant35ae4a22010-09-21 18:58:51109class _LIBCPP_VISIBLE locale::id
Howard Hinnant3e519522010-05-11 19:42:16110{
111 once_flag __flag_;
112 int32_t __id_;
Howard Hinnantb3371f62010-08-22 00:02:43113
Howard Hinnant3e519522010-05-11 19:42:16114 static int32_t __next_id;
115public:
Howard Hinnant35ae4a22010-09-21 18:58:51116 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnant3e519522010-05-11 19:42:16117private:
118 void __init();
119 void operator=(const id&); // = delete;
120 id(const id&); // = delete;
121public: // only needed for tests
122 long __get();
123
124 friend class locale;
125 friend class locale::__imp;
126};
127
128template <class _Facet>
129inline _LIBCPP_INLINE_VISIBILITY
130locale::locale(const locale& __other, _Facet* __f)
131{
132 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
133}
134
135template <class _Facet>
136locale
137locale::combine(const locale& __other) const
138{
Howard Hinnant54b409f2010-08-11 17:04:31139#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantce48a112011-06-30 21:18:19140 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnant3e519522010-05-11 19:42:16141 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnantb3371f62010-08-22 00:02:43142#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantce48a112011-06-30 21:18:19143 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnant3e519522010-05-11 19:42:16144}
145
146template <class _Facet>
147inline _LIBCPP_INLINE_VISIBILITY
148bool
Howard Hinnantb5d866d2011-05-31 15:34:58149has_facet(const locale& __l) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16150{
151 return __l.has_facet(_Facet::id);
152}
153
154template <class _Facet>
155inline _LIBCPP_INLINE_VISIBILITY
156const _Facet&
157use_facet(const locale& __l)
158{
159 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
160}
161
162// template <class _CharT> class collate;
163
164template <class _CharT>
Howard Hinnant35ae4a22010-09-21 18:58:51165class _LIBCPP_VISIBLE collate
Howard Hinnant3e519522010-05-11 19:42:16166 : public locale::facet
167{
168public:
169 typedef _CharT char_type;
170 typedef basic_string<char_type> string_type;
171
Howard Hinnant35ae4a22010-09-21 18:58:51172 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16173 explicit collate(size_t __refs = 0)
174 : locale::facet(__refs) {}
175
Howard Hinnant35ae4a22010-09-21 18:58:51176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16177 int compare(const char_type* __lo1, const char_type* __hi1,
178 const char_type* __lo2, const char_type* __hi2) const
179 {
180 return do_compare(__lo1, __hi1, __lo2, __hi2);
181 }
182
Howard Hinnant35ae4a22010-09-21 18:58:51183 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16184 string_type transform(const char_type* __lo, const char_type* __hi) const
185 {
186 return do_transform(__lo, __hi);
187 }
188
Howard Hinnant35ae4a22010-09-21 18:58:51189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16190 long hash(const char_type* __lo, const char_type* __hi) const
191 {
192 return do_hash(__lo, __hi);
193 }
194
195 static locale::id id;
196
197protected:
198 ~collate();
199 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
200 const char_type* __lo2, const char_type* __hi2) const;
201 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
202 {return string_type(__lo, __hi);}
203 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
204};
205
206template <class _CharT> locale::id collate<_CharT>::id;
207
208template <class _CharT>
209collate<_CharT>::~collate()
210{
211}
212
213template <class _CharT>
214int
215collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
216 const char_type* __lo2, const char_type* __hi2) const
217{
218 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
219 {
220 if (__lo1 == __hi1 || *__lo1 < *__lo2)
221 return -1;
222 if (*__lo2 < *__lo1)
223 return 1;
224 }
225 return __lo1 != __hi1;
226}
227
228template <class _CharT>
229long
230collate<_CharT>::do_hash(const char_type* lo, const char_type* hi) const
231{
232 size_t h = 0;
233 const size_t sr = __CHAR_BIT__ * sizeof(size_t) - 8;
234 const size_t mask = size_t(0xF) << (sr + 4);
235 for(const char_type* p = lo; p != hi; ++p)
236 {
237 h = (h << 4) + *p;
238 size_t g = h & mask;
239 h ^= g | (g >> sr);
240 }
241 return static_cast<long>(h);
242}
243
Howard Hinnant35ae4a22010-09-21 18:58:51244extern template class _LIBCPP_VISIBLE collate<char>;
245extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnant3e519522010-05-11 19:42:16246
247// template <class CharT> class collate_byname;
248
Howard Hinnant35ae4a22010-09-21 18:58:51249template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnant3e519522010-05-11 19:42:16250
251template <>
Howard Hinnant35ae4a22010-09-21 18:58:51252class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnant3e519522010-05-11 19:42:16253 : public collate<char>
254{
255 locale_t __l;
256public:
257 typedef char char_type;
258 typedef basic_string<char_type> string_type;
259
260 explicit collate_byname(const char* __n, size_t __refs = 0);
261 explicit collate_byname(const string& __n, size_t __refs = 0);
262
263protected:
264 ~collate_byname();
265 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
266 const char_type* __lo2, const char_type* __hi2) const;
267 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
268};
269
270template <>
Howard Hinnant35ae4a22010-09-21 18:58:51271class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:16272 : public collate<wchar_t>
273{
274 locale_t __l;
275public:
276 typedef wchar_t char_type;
277 typedef basic_string<char_type> string_type;
278
279 explicit collate_byname(const char* __n, size_t __refs = 0);
280 explicit collate_byname(const string& __n, size_t __refs = 0);
281
282protected:
283 ~collate_byname();
284
285 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
286 const char_type* __lo2, const char_type* __hi2) const;
287 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
288};
289
290template <class _CharT, class _Traits, class _Allocator>
291bool
292locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
293 const basic_string<_CharT, _Traits, _Allocator>& __y) const
294{
Howard Hinnantce48a112011-06-30 21:18:19295 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnant3e519522010-05-11 19:42:16296 __x.data(), __x.data() + __x.size(),
297 __y.data(), __y.data() + __y.size()) < 0;
298}
299
300// template <class charT> class ctype
301
Howard Hinnant35ae4a22010-09-21 18:58:51302class _LIBCPP_VISIBLE ctype_base
303{
Howard Hinnant3e519522010-05-11 19:42:16304public:
Alexis Hunt3f60bca2011-07-09 00:56:23305#ifdef __GLIBC__
306 typedef unsigned short mask;
307#else
Howard Hinnant3e519522010-05-11 19:42:16308 typedef __uint32_t mask;
Alexis Hunt3f60bca2011-07-09 00:56:23309#endif
Howard Hinnant3e519522010-05-11 19:42:16310
David Chisnall0a0f5992011-09-18 19:23:04311#if __APPLE__ || __FreeBSD__
Howard Hinnant3e519522010-05-11 19:42:16312 static const mask space = _CTYPE_S;
313 static const mask print = _CTYPE_R;
314 static const mask cntrl = _CTYPE_C;
315 static const mask upper = _CTYPE_U;
316 static const mask lower = _CTYPE_L;
317 static const mask alpha = _CTYPE_A;
318 static const mask digit = _CTYPE_D;
319 static const mask punct = _CTYPE_P;
320 static const mask xdigit = _CTYPE_X;
321 static const mask blank = _CTYPE_B;
Howard Hinnantb3371f62010-08-22 00:02:43322#else // __APPLE__
Howard Hinnant128ba712010-05-24 17:49:41323 static const mask space = _ISspace;
324 static const mask print = _ISprint;
325 static const mask cntrl = _IScntrl;
326 static const mask upper = _ISupper;
327 static const mask lower = _ISlower;
328 static const mask alpha = _ISalpha;
329 static const mask digit = _ISdigit;
330 static const mask punct = _ISpunct;
331 static const mask xdigit = _ISxdigit;
332 static const mask blank = _ISblank;
Howard Hinnantb3371f62010-08-22 00:02:43333#endif // __APPLE__
Howard Hinnant3e519522010-05-11 19:42:16334 static const mask alnum = alpha | digit;
335 static const mask graph = alnum | punct;
336
337 _LIBCPP_ALWAYS_INLINE ctype_base() {}
338};
339
Howard Hinnant35ae4a22010-09-21 18:58:51340template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnant3e519522010-05-11 19:42:16341
342template <>
Howard Hinnant35ae4a22010-09-21 18:58:51343class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:16344 : public locale::facet,
345 public ctype_base
346{
347public:
348 typedef wchar_t char_type;
Howard Hinnantb3371f62010-08-22 00:02:43349
Howard Hinnant3e519522010-05-11 19:42:16350 _LIBCPP_ALWAYS_INLINE
351 explicit ctype(size_t __refs = 0)
352 : locale::facet(__refs) {}
353
354 _LIBCPP_ALWAYS_INLINE
355 bool is(mask __m, char_type __c) const
356 {
357 return do_is(__m, __c);
358 }
359
360 _LIBCPP_ALWAYS_INLINE
361 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
362 {
363 return do_is(__low, __high, __vec);
364 }
365
366 _LIBCPP_ALWAYS_INLINE
367 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
368 {
369 return do_scan_is(__m, __low, __high);
370 }
371
372 _LIBCPP_ALWAYS_INLINE
373 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
374 {
375 return do_scan_not(__m, __low, __high);
376 }
377
378 _LIBCPP_ALWAYS_INLINE
379 char_type toupper(char_type __c) const
380 {
381 return do_toupper(__c);
382 }
383
384 _LIBCPP_ALWAYS_INLINE
385 const char_type* toupper(char_type* __low, const char_type* __high) const
386 {
387 return do_toupper(__low, __high);
388 }
389
390 _LIBCPP_ALWAYS_INLINE
391 char_type tolower(char_type __c) const
392 {
393 return do_tolower(__c);
394 }
395
396 _LIBCPP_ALWAYS_INLINE
397 const char_type* tolower(char_type* __low, const char_type* __high) const
398 {
399 return do_tolower(__low, __high);
400 }
401
402 _LIBCPP_ALWAYS_INLINE
403 char_type widen(char __c) const
404 {
405 return do_widen(__c);
406 }
407
408 _LIBCPP_ALWAYS_INLINE
409 const char* widen(const char* __low, const char* __high, char_type* __to) const
410 {
411 return do_widen(__low, __high, __to);
412 }
413
414 _LIBCPP_ALWAYS_INLINE
415 char narrow(char_type __c, char __dfault) const
416 {
417 return do_narrow(__c, __dfault);
418 }
419
420 _LIBCPP_ALWAYS_INLINE
421 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
422 {
423 return do_narrow(__low, __high, __dfault, __to);
424 }
425
426 static locale::id id;
427
428protected:
429 ~ctype();
430 virtual bool do_is(mask __m, char_type __c) const;
431 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
432 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
433 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
434 virtual char_type do_toupper(char_type) const;
435 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
436 virtual char_type do_tolower(char_type) const;
437 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
438 virtual char_type do_widen(char) const;
439 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
440 virtual char do_narrow(char_type, char __dfault) const;
441 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
442};
443
444template <>
Howard Hinnant35ae4a22010-09-21 18:58:51445class _LIBCPP_VISIBLE ctype<char>
Howard Hinnant3e519522010-05-11 19:42:16446 : public locale::facet, public ctype_base
447{
448 const mask* __tab_;
449 bool __del_;
450public:
451 typedef char char_type;
452
453 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
454
455 _LIBCPP_ALWAYS_INLINE
456 bool is(mask __m, char_type __c) const
457 {
458 return isascii(__c) ? __tab_[__c] & __m : false;
459 }
460
461 _LIBCPP_ALWAYS_INLINE
462 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
463 {
464 for (; __low != __high; ++__low, ++__vec)
465 *__vec = isascii(*__low) ? __tab_[*__low] : 0;
466 return __low;
467 }
468
469 _LIBCPP_ALWAYS_INLINE
470 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
471 {
472 for (; __low != __high; ++__low)
473 if (isascii(*__low) && (__tab_[*__low] & __m))
474 break;
475 return __low;
476 }
477
478 _LIBCPP_ALWAYS_INLINE
479 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
480 {
481 for (; __low != __high; ++__low)
482 if (!(isascii(*__low) && (__tab_[*__low] & __m)))
483 break;
484 return __low;
485 }
486
487 _LIBCPP_ALWAYS_INLINE
488 char_type toupper(char_type __c) const
489 {
490 return do_toupper(__c);
491 }
492
493 _LIBCPP_ALWAYS_INLINE
494 const char_type* toupper(char_type* __low, const char_type* __high) const
495 {
496 return do_toupper(__low, __high);
497 }
498
499 _LIBCPP_ALWAYS_INLINE
500 char_type tolower(char_type __c) const
501 {
502 return do_tolower(__c);
503 }
504
505 _LIBCPP_ALWAYS_INLINE
506 const char_type* tolower(char_type* __low, const char_type* __high) const
507 {
508 return do_tolower(__low, __high);
509 }
510
511 _LIBCPP_ALWAYS_INLINE
512 char_type widen(char __c) const
513 {
514 return do_widen(__c);
515 }
516
517 _LIBCPP_ALWAYS_INLINE
518 const char* widen(const char* __low, const char* __high, char_type* __to) const
519 {
520 return do_widen(__low, __high, __to);
521 }
522
523 _LIBCPP_ALWAYS_INLINE
524 char narrow(char_type __c, char __dfault) const
525 {
526 return do_narrow(__c, __dfault);
527 }
528
529 _LIBCPP_ALWAYS_INLINE
530 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
531 {
532 return do_narrow(__low, __high, __dfault, __to);
533 }
534
535 static locale::id id;
536
Howard Hinnant128ba712010-05-24 17:49:41537#ifdef _CACHED_RUNES
Howard Hinnant3e519522010-05-11 19:42:16538 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant128ba712010-05-24 17:49:41539#else
540 static const size_t table_size = 256; // FIXME: Don't hardcode this.
541#endif
Howard Hinnantb5d866d2011-05-31 15:34:58542 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
543 static const mask* classic_table() _NOEXCEPT;
Alexis Huntf0235192011-07-09 01:09:31544#ifndef _LIBCPP_STABLE_APPLE_ABI
Alexis Hunt3f60bca2011-07-09 00:56:23545 static const int* __classic_upper_table() _NOEXCEPT;
546 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Huntf0235192011-07-09 01:09:31547#endif
Howard Hinnant3e519522010-05-11 19:42:16548
549protected:
550 ~ctype();
551 virtual char_type do_toupper(char_type __c) const;
552 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
553 virtual char_type do_tolower(char_type __c) const;
554 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
555 virtual char_type do_widen(char __c) const;
556 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
557 virtual char do_narrow(char_type __c, char __dfault) const;
558 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
559};
560
561// template <class CharT> class ctype_byname;
562
Howard Hinnant35ae4a22010-09-21 18:58:51563template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnant3e519522010-05-11 19:42:16564
565template <>
Howard Hinnant35ae4a22010-09-21 18:58:51566class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnant3e519522010-05-11 19:42:16567 : public ctype<char>
568{
569 locale_t __l;
570
571public:
572 explicit ctype_byname(const char*, size_t = 0);
573 explicit ctype_byname(const string&, size_t = 0);
574
575protected:
576 ~ctype_byname();
577 virtual char_type do_toupper(char_type) const;
578 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
579 virtual char_type do_tolower(char_type) const;
580 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
581};
582
583template <>
Howard Hinnant35ae4a22010-09-21 18:58:51584class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:16585 : public ctype<wchar_t>
586{
587 locale_t __l;
588
589public:
590 explicit ctype_byname(const char*, size_t = 0);
591 explicit ctype_byname(const string&, size_t = 0);
592
593protected:
594 ~ctype_byname();
595 virtual bool do_is(mask __m, char_type __c) const;
596 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
597 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
598 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
599 virtual char_type do_toupper(char_type) const;
600 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
601 virtual char_type do_tolower(char_type) const;
602 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
603 virtual char_type do_widen(char) const;
604 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
605 virtual char do_narrow(char_type, char __dfault) const;
606 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
607};
608
609template <class _CharT>
610inline _LIBCPP_INLINE_VISIBILITY
611bool
612isspace(_CharT __c, const locale& __loc)
613{
614 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
615}
616
617template <class _CharT>
618inline _LIBCPP_INLINE_VISIBILITY
619bool
620isprint(_CharT __c, const locale& __loc)
621{
622 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
623}
624
625template <class _CharT>
626inline _LIBCPP_INLINE_VISIBILITY
627bool
628iscntrl(_CharT __c, const locale& __loc)
629{
630 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
631}
632
633template <class _CharT>
634inline _LIBCPP_INLINE_VISIBILITY
635bool
636isupper(_CharT __c, const locale& __loc)
637{
638 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
639}
640
641template <class _CharT>
642inline _LIBCPP_INLINE_VISIBILITY
643bool
644islower(_CharT __c, const locale& __loc)
645{
646 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
647}
648
649template <class _CharT>
650inline _LIBCPP_INLINE_VISIBILITY
651bool
652isalpha(_CharT __c, const locale& __loc)
653{
654 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
655}
656
657template <class _CharT>
658inline _LIBCPP_INLINE_VISIBILITY
659bool
660isdigit(_CharT __c, const locale& __loc)
661{
662 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
663}
664
665template <class _CharT>
666inline _LIBCPP_INLINE_VISIBILITY
667bool
668ispunct(_CharT __c, const locale& __loc)
669{
670 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
671}
672
673template <class _CharT>
674inline _LIBCPP_INLINE_VISIBILITY
675bool
676isxdigit(_CharT __c, const locale& __loc)
677{
678 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
679}
680
681template <class _CharT>
682inline _LIBCPP_INLINE_VISIBILITY
683bool
684isalnum(_CharT __c, const locale& __loc)
685{
686 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
687}
688
689template <class _CharT>
690inline _LIBCPP_INLINE_VISIBILITY
691bool
692isgraph(_CharT __c, const locale& __loc)
693{
694 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
695}
696
697template <class _CharT>
698inline _LIBCPP_INLINE_VISIBILITY
699_CharT
700toupper(_CharT __c, const locale& __loc)
701{
702 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
703}
704
705template <class _CharT>
706inline _LIBCPP_INLINE_VISIBILITY
707_CharT
708tolower(_CharT __c, const locale& __loc)
709{
710 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
711}
712
713// codecvt_base
714
Howard Hinnant35ae4a22010-09-21 18:58:51715class _LIBCPP_VISIBLE codecvt_base
Howard Hinnant3e519522010-05-11 19:42:16716{
717public:
718 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
719 enum result {ok, partial, error, noconv};
720};
721
722// template <class internT, class externT, class stateT> class codecvt;
723
Howard Hinnant35ae4a22010-09-21 18:58:51724template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnant3e519522010-05-11 19:42:16725
726// template <> class codecvt<char, char, mbstate_t>
727
728template <>
Howard Hinnant35ae4a22010-09-21 18:58:51729class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16730 : public locale::facet,
731 public codecvt_base
732{
733public:
734 typedef char intern_type;
735 typedef char extern_type;
736 typedef mbstate_t state_type;
737
738 _LIBCPP_ALWAYS_INLINE
739 explicit codecvt(size_t __refs = 0)
740 : locale::facet(__refs) {}
741
742 _LIBCPP_ALWAYS_INLINE
743 result out(state_type& __st,
744 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
745 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
746 {
747 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
748 }
749
750 _LIBCPP_ALWAYS_INLINE
751 result unshift(state_type& __st,
752 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
753 {
754 return do_unshift(__st, __to, __to_end, __to_nxt);
755 }
756
757 _LIBCPP_ALWAYS_INLINE
758 result in(state_type& __st,
759 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
760 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
761 {
762 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
763 }
764
765 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58766 int encoding() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16767 {
768 return do_encoding();
769 }
770
771 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58772 bool always_noconv() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16773 {
774 return do_always_noconv();
775 }
776
777 _LIBCPP_ALWAYS_INLINE
778 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
779 {
780 return do_length(__st, __frm, __end, __mx);
781 }
782
783 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58784 int max_length() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16785 {
786 return do_max_length();
787 }
788
789 static locale::id id;
790
791protected:
792 _LIBCPP_ALWAYS_INLINE
793 explicit codecvt(const char*, size_t __refs = 0)
794 : locale::facet(__refs) {}
795
796 ~codecvt();
797
798 virtual result do_out(state_type& __st,
799 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
800 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
801 virtual result do_in(state_type& __st,
802 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
803 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
804 virtual result do_unshift(state_type& __st,
805 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantb5d866d2011-05-31 15:34:58806 virtual int do_encoding() const _NOEXCEPT;
807 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16808 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantb5d866d2011-05-31 15:34:58809 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16810};
811
812// template <> class codecvt<wchar_t, char, mbstate_t>
813
814template <>
Howard Hinnant35ae4a22010-09-21 18:58:51815class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16816 : public locale::facet,
817 public codecvt_base
818{
819 locale_t __l;
820public:
821 typedef wchar_t intern_type;
822 typedef char extern_type;
823 typedef mbstate_t state_type;
824
825 explicit codecvt(size_t __refs = 0);
826
827 _LIBCPP_ALWAYS_INLINE
828 result out(state_type& __st,
829 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
830 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
831 {
832 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
833 }
834
835 _LIBCPP_ALWAYS_INLINE
836 result unshift(state_type& __st,
837 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
838 {
839 return do_unshift(__st, __to, __to_end, __to_nxt);
840 }
841
842 _LIBCPP_ALWAYS_INLINE
843 result in(state_type& __st,
844 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
845 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
846 {
847 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
848 }
849
850 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58851 int encoding() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16852 {
853 return do_encoding();
854 }
855
856 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58857 bool always_noconv() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16858 {
859 return do_always_noconv();
860 }
861
862 _LIBCPP_ALWAYS_INLINE
863 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
864 {
865 return do_length(__st, __frm, __end, __mx);
866 }
867
868 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58869 int max_length() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16870 {
871 return do_max_length();
872 }
873
874 static locale::id id;
875
876protected:
877 explicit codecvt(const char*, size_t __refs = 0);
878
879 ~codecvt();
880
881 virtual result do_out(state_type& __st,
882 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
883 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
884 virtual result do_in(state_type& __st,
885 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
886 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
887 virtual result do_unshift(state_type& __st,
888 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantb5d866d2011-05-31 15:34:58889 virtual int do_encoding() const _NOEXCEPT;
890 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16891 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantb5d866d2011-05-31 15:34:58892 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16893};
894
895// template <> class codecvt<char16_t, char, mbstate_t>
896
897template <>
Howard Hinnant35ae4a22010-09-21 18:58:51898class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16899 : public locale::facet,
900 public codecvt_base
901{
902public:
903 typedef char16_t intern_type;
904 typedef char extern_type;
905 typedef mbstate_t state_type;
906
907 _LIBCPP_ALWAYS_INLINE
908 explicit codecvt(size_t __refs = 0)
909 : locale::facet(__refs) {}
910
911 _LIBCPP_ALWAYS_INLINE
912 result out(state_type& __st,
913 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
914 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
915 {
916 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
917 }
918
919 _LIBCPP_ALWAYS_INLINE
920 result unshift(state_type& __st,
921 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
922 {
923 return do_unshift(__st, __to, __to_end, __to_nxt);
924 }
925
926 _LIBCPP_ALWAYS_INLINE
927 result in(state_type& __st,
928 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
929 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
930 {
931 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
932 }
933
934 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58935 int encoding() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16936 {
937 return do_encoding();
938 }
939
940 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58941 bool always_noconv() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16942 {
943 return do_always_noconv();
944 }
945
946 _LIBCPP_ALWAYS_INLINE
947 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
948 {
949 return do_length(__st, __frm, __end, __mx);
950 }
951
952 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:58953 int max_length() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16954 {
955 return do_max_length();
956 }
957
958 static locale::id id;
959
960protected:
961 _LIBCPP_ALWAYS_INLINE
962 explicit codecvt(const char*, size_t __refs = 0)
963 : locale::facet(__refs) {}
964
965 ~codecvt();
966
967 virtual result do_out(state_type& __st,
968 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
969 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
970 virtual result do_in(state_type& __st,
971 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
972 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
973 virtual result do_unshift(state_type& __st,
974 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantb5d866d2011-05-31 15:34:58975 virtual int do_encoding() const _NOEXCEPT;
976 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16977 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantb5d866d2011-05-31 15:34:58978 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16979};
980
981// template <> class codecvt<char32_t, char, mbstate_t>
982
983template <>
Howard Hinnant35ae4a22010-09-21 18:58:51984class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnant3e519522010-05-11 19:42:16985 : public locale::facet,
986 public codecvt_base
987{
988public:
989 typedef char32_t intern_type;
990 typedef char extern_type;
991 typedef mbstate_t state_type;
992
993 _LIBCPP_ALWAYS_INLINE
994 explicit codecvt(size_t __refs = 0)
995 : locale::facet(__refs) {}
996
997 _LIBCPP_ALWAYS_INLINE
998 result out(state_type& __st,
999 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1000 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1001 {
1002 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1003 }
1004
1005 _LIBCPP_ALWAYS_INLINE
1006 result unshift(state_type& __st,
1007 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1008 {
1009 return do_unshift(__st, __to, __to_end, __to_nxt);
1010 }
1011
1012 _LIBCPP_ALWAYS_INLINE
1013 result in(state_type& __st,
1014 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1015 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1016 {
1017 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1018 }
1019
1020 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:581021 int encoding() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:161022 {
1023 return do_encoding();
1024 }
1025
1026 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:581027 bool always_noconv() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:161028 {
1029 return do_always_noconv();
1030 }
1031
1032 _LIBCPP_ALWAYS_INLINE
1033 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1034 {
1035 return do_length(__st, __frm, __end, __mx);
1036 }
1037
1038 _LIBCPP_ALWAYS_INLINE
Howard Hinnantb5d866d2011-05-31 15:34:581039 int max_length() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:161040 {
1041 return do_max_length();
1042 }
1043
1044 static locale::id id;
1045
1046protected:
1047 _LIBCPP_ALWAYS_INLINE
1048 explicit codecvt(const char*, size_t __refs = 0)
1049 : locale::facet(__refs) {}
1050
1051 ~codecvt();
1052
1053 virtual result do_out(state_type& __st,
1054 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1055 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1056 virtual result do_in(state_type& __st,
1057 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1058 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1059 virtual result do_unshift(state_type& __st,
1060 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantb5d866d2011-05-31 15:34:581061 virtual int do_encoding() const _NOEXCEPT;
1062 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:161063 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantb5d866d2011-05-31 15:34:581064 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:161065};
1066
Howard Hinnant3e519522010-05-11 19:42:161067// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1068
1069template <class _InternT, class _ExternT, class _StateT>
Howard Hinnant35ae4a22010-09-21 18:58:511070class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnant3e519522010-05-11 19:42:161071 : public codecvt<_InternT, _ExternT, _StateT>
1072{
1073public:
Howard Hinnant35ae4a22010-09-21 18:58:511074 _LIBCPP_ALWAYS_INLINE
Howard Hinnant3e519522010-05-11 19:42:161075 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1076 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant35ae4a22010-09-21 18:58:511077 _LIBCPP_ALWAYS_INLINE
Howard Hinnant3e519522010-05-11 19:42:161078 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1079 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1080protected:
1081 ~codecvt_byname();
1082};
1083
1084template <class _InternT, class _ExternT, class _StateT>
1085codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1086{
1087}
1088
1089extern template class codecvt_byname<char, char, mbstate_t>;
1090extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1091extern template class codecvt_byname<char16_t, char, mbstate_t>;
1092extern template class codecvt_byname<char32_t, char, mbstate_t>;
1093
Howard Hinnant35ae4a22010-09-21 18:58:511094_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnant3e519522010-05-11 19:42:161095
1096template <size_t _N>
1097struct __narrow_to_utf8
1098{
1099 template <class _OutputIterator, class _CharT>
1100 _OutputIterator
1101 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1102};
1103
1104template <>
1105struct __narrow_to_utf8<8>
1106{
1107 template <class _OutputIterator, class _CharT>
1108 _LIBCPP_ALWAYS_INLINE
1109 _OutputIterator
1110 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1111 {
1112 for (; __wb < __we; ++__wb, ++__s)
1113 *__s = *__wb;
1114 return __s;
1115 }
1116};
1117
1118template <>
1119struct __narrow_to_utf8<16>
1120 : public codecvt<char16_t, char, mbstate_t>
1121{
1122 _LIBCPP_ALWAYS_INLINE
1123 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1124
1125 ~__narrow_to_utf8();
1126
1127 template <class _OutputIterator, class _CharT>
1128 _LIBCPP_ALWAYS_INLINE
1129 _OutputIterator
1130 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1131 {
1132 result __r = ok;
1133 mbstate_t __mb;
1134 while (__wb < __we && __r != error)
1135 {
1136 const int __sz = 32;
1137 char __buf[__sz];
1138 char* __bn;
1139 const char16_t* __wn = (const char16_t*)__wb;
1140 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1141 __buf, __buf+__sz, __bn);
1142 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1143 __throw_runtime_error("locale not supported");
1144 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1145 *__s = *__p;
1146 __wb = (const _CharT*)__wn;
1147 }
1148 return __s;
1149 }
1150};
1151
1152template <>
1153struct __narrow_to_utf8<32>
1154 : public codecvt<char32_t, char, mbstate_t>
1155{
1156 _LIBCPP_ALWAYS_INLINE
1157 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1158
1159 ~__narrow_to_utf8();
1160
1161 template <class _OutputIterator, class _CharT>
1162 _LIBCPP_ALWAYS_INLINE
1163 _OutputIterator
1164 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1165 {
1166 result __r = ok;
1167 mbstate_t __mb;
1168 while (__wb < __we && __r != error)
1169 {
1170 const int __sz = 32;
1171 char __buf[__sz];
1172 char* __bn;
1173 const char32_t* __wn = (const char32_t*)__wb;
1174 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1175 __buf, __buf+__sz, __bn);
1176 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1177 __throw_runtime_error("locale not supported");
1178 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1179 *__s = *__p;
1180 __wb = (const _CharT*)__wn;
1181 }
1182 return __s;
1183 }
1184};
1185
1186template <size_t _N>
1187struct __widen_from_utf8
1188{
1189 template <class _OutputIterator>
1190 _OutputIterator
1191 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1192};
1193
1194template <>
1195struct __widen_from_utf8<8>
1196{
1197 template <class _OutputIterator>
1198 _LIBCPP_ALWAYS_INLINE
1199 _OutputIterator
1200 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1201 {
1202 for (; __nb < __ne; ++__nb, ++__s)
1203 *__s = *__nb;
1204 return __s;
1205 }
1206};
1207
1208template <>
1209struct __widen_from_utf8<16>
1210 : public codecvt<char16_t, char, mbstate_t>
1211{
1212 _LIBCPP_ALWAYS_INLINE
1213 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1214
1215 ~__widen_from_utf8();
1216
1217 template <class _OutputIterator>
1218 _LIBCPP_ALWAYS_INLINE
1219 _OutputIterator
1220 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1221 {
1222 result __r = ok;
1223 mbstate_t __mb;
1224 while (__nb < __ne && __r != error)
1225 {
1226 const int __sz = 32;
1227 char16_t __buf[__sz];
1228 char16_t* __bn;
1229 const char* __nn = __nb;
1230 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1231 __buf, __buf+__sz, __bn);
1232 if (__r == codecvt_base::error || __nn == __nb)
1233 __throw_runtime_error("locale not supported");
1234 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1235 *__s = (wchar_t)*__p;
1236 __nb = __nn;
1237 }
1238 return __s;
1239 }
1240};
1241
1242template <>
1243struct __widen_from_utf8<32>
1244 : public codecvt<char32_t, char, mbstate_t>
1245{
1246 _LIBCPP_ALWAYS_INLINE
1247 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1248
1249 ~__widen_from_utf8();
1250
1251 template <class _OutputIterator>
1252 _LIBCPP_ALWAYS_INLINE
1253 _OutputIterator
1254 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1255 {
1256 result __r = ok;
1257 mbstate_t __mb;
1258 while (__nb < __ne && __r != error)
1259 {
1260 const int __sz = 32;
1261 char32_t __buf[__sz];
1262 char32_t* __bn;
1263 const char* __nn = __nb;
1264 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1265 __buf, __buf+__sz, __bn);
1266 if (__r == codecvt_base::error || __nn == __nb)
1267 __throw_runtime_error("locale not supported");
1268 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1269 *__s = (wchar_t)*__p;
1270 __nb = __nn;
1271 }
1272 return __s;
1273 }
1274};
1275
1276// template <class charT> class numpunct
1277
Howard Hinnant35ae4a22010-09-21 18:58:511278template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnant3e519522010-05-11 19:42:161279
1280template <>
Howard Hinnant35ae4a22010-09-21 18:58:511281class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnant3e519522010-05-11 19:42:161282 : public locale::facet
1283{
1284public:
1285 typedef char char_type;
1286 typedef basic_string<char_type> string_type;
1287
1288 explicit numpunct(size_t __refs = 0);
1289
1290 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1291 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1292 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1293 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1294 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1295
1296 static locale::id id;
1297
1298protected:
1299 ~numpunct();
1300 virtual char_type do_decimal_point() const;
1301 virtual char_type do_thousands_sep() const;
1302 virtual string do_grouping() const;
1303 virtual string_type do_truename() const;
1304 virtual string_type do_falsename() const;
1305
1306 char_type __decimal_point_;
1307 char_type __thousands_sep_;
1308 string __grouping_;
1309};
1310
1311template <>
Howard Hinnant35ae4a22010-09-21 18:58:511312class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:161313 : public locale::facet
1314{
1315public:
1316 typedef wchar_t char_type;
1317 typedef basic_string<char_type> string_type;
1318
1319 explicit numpunct(size_t __refs = 0);
1320
1321 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1322 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1323 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1324 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1325 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1326
1327 static locale::id id;
1328
1329protected:
1330 ~numpunct();
1331 virtual char_type do_decimal_point() const;
1332 virtual char_type do_thousands_sep() const;
1333 virtual string do_grouping() const;
1334 virtual string_type do_truename() const;
1335 virtual string_type do_falsename() const;
1336
1337 char_type __decimal_point_;
1338 char_type __thousands_sep_;
1339 string __grouping_;
1340};
1341
1342// template <class charT> class numpunct_byname
1343
Howard Hinnant35ae4a22010-09-21 18:58:511344template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnant3e519522010-05-11 19:42:161345
1346template <>
Howard Hinnant35ae4a22010-09-21 18:58:511347class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnant3e519522010-05-11 19:42:161348: public numpunct<char>
1349{
1350public:
1351 typedef char char_type;
1352 typedef basic_string<char_type> string_type;
1353
1354 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1355 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1356
1357protected:
1358 ~numpunct_byname();
1359
1360private:
1361 void __init(const char*);
1362};
1363
1364template <>
Howard Hinnant35ae4a22010-09-21 18:58:511365class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:161366: public numpunct<wchar_t>
1367{
1368public:
1369 typedef wchar_t char_type;
1370 typedef basic_string<char_type> string_type;
1371
1372 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1373 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1374
1375protected:
1376 ~numpunct_byname();
1377
1378private:
1379 void __init(const char*);
1380};
1381
1382_LIBCPP_END_NAMESPACE_STD
1383
1384#endif // _LIBCPP___LOCALE