blob: 21a573473a0a05254c2f311cf2b4d6435fad60f9 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
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 Hinnantadff4892010-05-24 17:49:41 +000021#include <locale.h>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000022#include <xlocale.h>
23
24#pragma GCC system_header
25
26_LIBCPP_BEGIN_NAMESPACE_STD
27
28class locale;
29
Howard Hinnantc9834542011-05-31 15:34:58 +000030template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000031template <class _Facet> const _Facet& use_facet(const locale&);
32
Howard Hinnantb0be42b2010-09-21 18:58:51 +000033class _LIBCPP_VISIBLE locale
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000034{
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 Hinnantc9834542011-05-31 15:34:58 +000052 locale() _NOEXCEPT;
53 locale(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000054 explicit locale(const char*);
55 explicit locale(const string&);
56 locale(const locale&, const char*, category);
57 locale(const locale&, const string&, category);
Howard Hinnant2d72b1e2010-12-17 14:46:43 +000058 template <class _Facet>
59 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000060 locale(const locale&, const locale&, category);
61
Howard Hinnantc9834542011-05-31 15:34:58 +000062 ~locale();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000063
Howard Hinnantc9834542011-05-31 15:34:58 +000064 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000065
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 Hinnantc9834542011-05-31 15:34:58 +000089 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000090 template <class _Facet> friend const _Facet& use_facet(const locale&);
91};
92
Howard Hinnantb0be42b2010-09-21 18:58:51 +000093class _LIBCPP_VISIBLE locale::facet
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000094 : public __shared_count
95{
96protected:
Howard Hinnantb0be42b2010-09-21 18:58:51 +000097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000098 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 Hinnant1694d232011-05-28 14:41:13 +0000106 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000107};
108
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000109class _LIBCPP_VISIBLE locale::id
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000110{
111 once_flag __flag_;
112 int32_t __id_;
Howard Hinnant324bb032010-08-22 00:02:43 +0000113
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000114 static int32_t __next_id;
115public:
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000116 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000117private:
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 Hinnantd4444702010-08-11 17:04:31 +0000139#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000140 if (!_STD::has_facet<_Facet>(__other))
141 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant324bb032010-08-22 00:02:43 +0000142#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000143 return locale(*this, &const_cast<_Facet&>(_STD::use_facet<_Facet>(__other)));
144}
145
146template <class _Facet>
147inline _LIBCPP_INLINE_VISIBILITY
148bool
Howard Hinnantc9834542011-05-31 15:34:58 +0000149has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000150{
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 Hinnantb0be42b2010-09-21 18:58:51 +0000165class _LIBCPP_VISIBLE collate
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000166 : public locale::facet
167{
168public:
169 typedef _CharT char_type;
170 typedef basic_string<char_type> string_type;
171
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000172 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000173 explicit collate(size_t __refs = 0)
174 : locale::facet(__refs) {}
175
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000177 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 Hinnantb0be42b2010-09-21 18:58:51 +0000183 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000184 string_type transform(const char_type* __lo, const char_type* __hi) const
185 {
186 return do_transform(__lo, __hi);
187 }
188
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000190 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 Hinnantb0be42b2010-09-21 18:58:51 +0000244extern template class _LIBCPP_VISIBLE collate<char>;
245extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000246
247// template <class CharT> class collate_byname;
248
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000249template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000250
251template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000252class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000253 : 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 Hinnantb0be42b2010-09-21 18:58:51 +0000271class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000272 : 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{
295 return _STD::use_facet<_STD::collate<_CharT> >(*this).compare(
296 __x.data(), __x.data() + __x.size(),
297 __y.data(), __y.data() + __y.size()) < 0;
298}
299
300// template <class charT> class ctype
301
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000302class _LIBCPP_VISIBLE ctype_base
303{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000304public:
305 typedef __uint32_t mask;
306
Howard Hinnantadff4892010-05-24 17:49:41 +0000307#if __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000308 static const mask space = _CTYPE_S;
309 static const mask print = _CTYPE_R;
310 static const mask cntrl = _CTYPE_C;
311 static const mask upper = _CTYPE_U;
312 static const mask lower = _CTYPE_L;
313 static const mask alpha = _CTYPE_A;
314 static const mask digit = _CTYPE_D;
315 static const mask punct = _CTYPE_P;
316 static const mask xdigit = _CTYPE_X;
317 static const mask blank = _CTYPE_B;
Howard Hinnant324bb032010-08-22 00:02:43 +0000318#else // __APPLE__
Howard Hinnantadff4892010-05-24 17:49:41 +0000319 static const mask space = _ISspace;
320 static const mask print = _ISprint;
321 static const mask cntrl = _IScntrl;
322 static const mask upper = _ISupper;
323 static const mask lower = _ISlower;
324 static const mask alpha = _ISalpha;
325 static const mask digit = _ISdigit;
326 static const mask punct = _ISpunct;
327 static const mask xdigit = _ISxdigit;
328 static const mask blank = _ISblank;
Howard Hinnant324bb032010-08-22 00:02:43 +0000329#endif // __APPLE__
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 static const mask alnum = alpha | digit;
331 static const mask graph = alnum | punct;
332
333 _LIBCPP_ALWAYS_INLINE ctype_base() {}
334};
335
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000336template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000337
338template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000339class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000340 : public locale::facet,
341 public ctype_base
342{
343public:
344 typedef wchar_t char_type;
Howard Hinnant324bb032010-08-22 00:02:43 +0000345
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000346 _LIBCPP_ALWAYS_INLINE
347 explicit ctype(size_t __refs = 0)
348 : locale::facet(__refs) {}
349
350 _LIBCPP_ALWAYS_INLINE
351 bool is(mask __m, char_type __c) const
352 {
353 return do_is(__m, __c);
354 }
355
356 _LIBCPP_ALWAYS_INLINE
357 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
358 {
359 return do_is(__low, __high, __vec);
360 }
361
362 _LIBCPP_ALWAYS_INLINE
363 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
364 {
365 return do_scan_is(__m, __low, __high);
366 }
367
368 _LIBCPP_ALWAYS_INLINE
369 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
370 {
371 return do_scan_not(__m, __low, __high);
372 }
373
374 _LIBCPP_ALWAYS_INLINE
375 char_type toupper(char_type __c) const
376 {
377 return do_toupper(__c);
378 }
379
380 _LIBCPP_ALWAYS_INLINE
381 const char_type* toupper(char_type* __low, const char_type* __high) const
382 {
383 return do_toupper(__low, __high);
384 }
385
386 _LIBCPP_ALWAYS_INLINE
387 char_type tolower(char_type __c) const
388 {
389 return do_tolower(__c);
390 }
391
392 _LIBCPP_ALWAYS_INLINE
393 const char_type* tolower(char_type* __low, const char_type* __high) const
394 {
395 return do_tolower(__low, __high);
396 }
397
398 _LIBCPP_ALWAYS_INLINE
399 char_type widen(char __c) const
400 {
401 return do_widen(__c);
402 }
403
404 _LIBCPP_ALWAYS_INLINE
405 const char* widen(const char* __low, const char* __high, char_type* __to) const
406 {
407 return do_widen(__low, __high, __to);
408 }
409
410 _LIBCPP_ALWAYS_INLINE
411 char narrow(char_type __c, char __dfault) const
412 {
413 return do_narrow(__c, __dfault);
414 }
415
416 _LIBCPP_ALWAYS_INLINE
417 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
418 {
419 return do_narrow(__low, __high, __dfault, __to);
420 }
421
422 static locale::id id;
423
424protected:
425 ~ctype();
426 virtual bool do_is(mask __m, char_type __c) const;
427 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
428 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
429 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
430 virtual char_type do_toupper(char_type) const;
431 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
432 virtual char_type do_tolower(char_type) const;
433 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
434 virtual char_type do_widen(char) const;
435 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
436 virtual char do_narrow(char_type, char __dfault) const;
437 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
438};
439
440template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000441class _LIBCPP_VISIBLE ctype<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000442 : public locale::facet, public ctype_base
443{
444 const mask* __tab_;
445 bool __del_;
446public:
447 typedef char char_type;
448
449 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
450
451 _LIBCPP_ALWAYS_INLINE
452 bool is(mask __m, char_type __c) const
453 {
454 return isascii(__c) ? __tab_[__c] & __m : false;
455 }
456
457 _LIBCPP_ALWAYS_INLINE
458 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
459 {
460 for (; __low != __high; ++__low, ++__vec)
461 *__vec = isascii(*__low) ? __tab_[*__low] : 0;
462 return __low;
463 }
464
465 _LIBCPP_ALWAYS_INLINE
466 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
467 {
468 for (; __low != __high; ++__low)
469 if (isascii(*__low) && (__tab_[*__low] & __m))
470 break;
471 return __low;
472 }
473
474 _LIBCPP_ALWAYS_INLINE
475 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
476 {
477 for (; __low != __high; ++__low)
478 if (!(isascii(*__low) && (__tab_[*__low] & __m)))
479 break;
480 return __low;
481 }
482
483 _LIBCPP_ALWAYS_INLINE
484 char_type toupper(char_type __c) const
485 {
486 return do_toupper(__c);
487 }
488
489 _LIBCPP_ALWAYS_INLINE
490 const char_type* toupper(char_type* __low, const char_type* __high) const
491 {
492 return do_toupper(__low, __high);
493 }
494
495 _LIBCPP_ALWAYS_INLINE
496 char_type tolower(char_type __c) const
497 {
498 return do_tolower(__c);
499 }
500
501 _LIBCPP_ALWAYS_INLINE
502 const char_type* tolower(char_type* __low, const char_type* __high) const
503 {
504 return do_tolower(__low, __high);
505 }
506
507 _LIBCPP_ALWAYS_INLINE
508 char_type widen(char __c) const
509 {
510 return do_widen(__c);
511 }
512
513 _LIBCPP_ALWAYS_INLINE
514 const char* widen(const char* __low, const char* __high, char_type* __to) const
515 {
516 return do_widen(__low, __high, __to);
517 }
518
519 _LIBCPP_ALWAYS_INLINE
520 char narrow(char_type __c, char __dfault) const
521 {
522 return do_narrow(__c, __dfault);
523 }
524
525 _LIBCPP_ALWAYS_INLINE
526 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
527 {
528 return do_narrow(__low, __high, __dfault, __to);
529 }
530
531 static locale::id id;
532
Howard Hinnantadff4892010-05-24 17:49:41 +0000533#ifdef _CACHED_RUNES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000534 static const size_t table_size = _CACHED_RUNES;
Howard Hinnantadff4892010-05-24 17:49:41 +0000535#else
536 static const size_t table_size = 256; // FIXME: Don't hardcode this.
537#endif
Howard Hinnantc9834542011-05-31 15:34:58 +0000538 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
539 static const mask* classic_table() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000540
541protected:
542 ~ctype();
543 virtual char_type do_toupper(char_type __c) const;
544 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
545 virtual char_type do_tolower(char_type __c) const;
546 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
547 virtual char_type do_widen(char __c) const;
548 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
549 virtual char do_narrow(char_type __c, char __dfault) const;
550 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
551};
552
553// template <class CharT> class ctype_byname;
554
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000555template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000556
557template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000558class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000559 : public ctype<char>
560{
561 locale_t __l;
562
563public:
564 explicit ctype_byname(const char*, size_t = 0);
565 explicit ctype_byname(const string&, size_t = 0);
566
567protected:
568 ~ctype_byname();
569 virtual char_type do_toupper(char_type) const;
570 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
571 virtual char_type do_tolower(char_type) const;
572 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
573};
574
575template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000576class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000577 : public ctype<wchar_t>
578{
579 locale_t __l;
580
581public:
582 explicit ctype_byname(const char*, size_t = 0);
583 explicit ctype_byname(const string&, size_t = 0);
584
585protected:
586 ~ctype_byname();
587 virtual bool do_is(mask __m, char_type __c) const;
588 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
589 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
590 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
591 virtual char_type do_toupper(char_type) const;
592 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
593 virtual char_type do_tolower(char_type) const;
594 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
595 virtual char_type do_widen(char) const;
596 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
597 virtual char do_narrow(char_type, char __dfault) const;
598 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
599};
600
601template <class _CharT>
602inline _LIBCPP_INLINE_VISIBILITY
603bool
604isspace(_CharT __c, const locale& __loc)
605{
606 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
607}
608
609template <class _CharT>
610inline _LIBCPP_INLINE_VISIBILITY
611bool
612isprint(_CharT __c, const locale& __loc)
613{
614 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
615}
616
617template <class _CharT>
618inline _LIBCPP_INLINE_VISIBILITY
619bool
620iscntrl(_CharT __c, const locale& __loc)
621{
622 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
623}
624
625template <class _CharT>
626inline _LIBCPP_INLINE_VISIBILITY
627bool
628isupper(_CharT __c, const locale& __loc)
629{
630 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
631}
632
633template <class _CharT>
634inline _LIBCPP_INLINE_VISIBILITY
635bool
636islower(_CharT __c, const locale& __loc)
637{
638 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
639}
640
641template <class _CharT>
642inline _LIBCPP_INLINE_VISIBILITY
643bool
644isalpha(_CharT __c, const locale& __loc)
645{
646 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
647}
648
649template <class _CharT>
650inline _LIBCPP_INLINE_VISIBILITY
651bool
652isdigit(_CharT __c, const locale& __loc)
653{
654 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
655}
656
657template <class _CharT>
658inline _LIBCPP_INLINE_VISIBILITY
659bool
660ispunct(_CharT __c, const locale& __loc)
661{
662 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
663}
664
665template <class _CharT>
666inline _LIBCPP_INLINE_VISIBILITY
667bool
668isxdigit(_CharT __c, const locale& __loc)
669{
670 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
671}
672
673template <class _CharT>
674inline _LIBCPP_INLINE_VISIBILITY
675bool
676isalnum(_CharT __c, const locale& __loc)
677{
678 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
679}
680
681template <class _CharT>
682inline _LIBCPP_INLINE_VISIBILITY
683bool
684isgraph(_CharT __c, const locale& __loc)
685{
686 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
687}
688
689template <class _CharT>
690inline _LIBCPP_INLINE_VISIBILITY
691_CharT
692toupper(_CharT __c, const locale& __loc)
693{
694 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
695}
696
697template <class _CharT>
698inline _LIBCPP_INLINE_VISIBILITY
699_CharT
700tolower(_CharT __c, const locale& __loc)
701{
702 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
703}
704
705// codecvt_base
706
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000707class _LIBCPP_VISIBLE codecvt_base
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000708{
709public:
710 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
711 enum result {ok, partial, error, noconv};
712};
713
714// template <class internT, class externT, class stateT> class codecvt;
715
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000716template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000717
718// template <> class codecvt<char, char, mbstate_t>
719
720template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000721class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000722 : public locale::facet,
723 public codecvt_base
724{
725public:
726 typedef char intern_type;
727 typedef char extern_type;
728 typedef mbstate_t state_type;
729
730 _LIBCPP_ALWAYS_INLINE
731 explicit codecvt(size_t __refs = 0)
732 : locale::facet(__refs) {}
733
734 _LIBCPP_ALWAYS_INLINE
735 result out(state_type& __st,
736 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
737 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
738 {
739 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
740 }
741
742 _LIBCPP_ALWAYS_INLINE
743 result unshift(state_type& __st,
744 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
745 {
746 return do_unshift(__st, __to, __to_end, __to_nxt);
747 }
748
749 _LIBCPP_ALWAYS_INLINE
750 result in(state_type& __st,
751 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
752 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
753 {
754 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
755 }
756
757 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000758 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000759 {
760 return do_encoding();
761 }
762
763 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000764 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000765 {
766 return do_always_noconv();
767 }
768
769 _LIBCPP_ALWAYS_INLINE
770 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
771 {
772 return do_length(__st, __frm, __end, __mx);
773 }
774
775 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000776 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000777 {
778 return do_max_length();
779 }
780
781 static locale::id id;
782
783protected:
784 _LIBCPP_ALWAYS_INLINE
785 explicit codecvt(const char*, size_t __refs = 0)
786 : locale::facet(__refs) {}
787
788 ~codecvt();
789
790 virtual result do_out(state_type& __st,
791 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
792 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
793 virtual result do_in(state_type& __st,
794 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
795 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
796 virtual result do_unshift(state_type& __st,
797 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000798 virtual int do_encoding() const _NOEXCEPT;
799 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000800 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000801 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000802};
803
804// template <> class codecvt<wchar_t, char, mbstate_t>
805
806template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000807class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000808 : public locale::facet,
809 public codecvt_base
810{
811 locale_t __l;
812public:
813 typedef wchar_t intern_type;
814 typedef char extern_type;
815 typedef mbstate_t state_type;
816
817 explicit codecvt(size_t __refs = 0);
818
819 _LIBCPP_ALWAYS_INLINE
820 result out(state_type& __st,
821 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
822 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
823 {
824 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
825 }
826
827 _LIBCPP_ALWAYS_INLINE
828 result unshift(state_type& __st,
829 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
830 {
831 return do_unshift(__st, __to, __to_end, __to_nxt);
832 }
833
834 _LIBCPP_ALWAYS_INLINE
835 result in(state_type& __st,
836 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
837 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
838 {
839 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
840 }
841
842 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000843 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000844 {
845 return do_encoding();
846 }
847
848 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000849 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000850 {
851 return do_always_noconv();
852 }
853
854 _LIBCPP_ALWAYS_INLINE
855 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
856 {
857 return do_length(__st, __frm, __end, __mx);
858 }
859
860 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000861 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000862 {
863 return do_max_length();
864 }
865
866 static locale::id id;
867
868protected:
869 explicit codecvt(const char*, size_t __refs = 0);
870
871 ~codecvt();
872
873 virtual result do_out(state_type& __st,
874 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
875 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
876 virtual result do_in(state_type& __st,
877 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
878 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
879 virtual result do_unshift(state_type& __st,
880 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000881 virtual int do_encoding() const _NOEXCEPT;
882 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000883 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000884 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000885};
886
887// template <> class codecvt<char16_t, char, mbstate_t>
888
889template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000890class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000891 : public locale::facet,
892 public codecvt_base
893{
894public:
895 typedef char16_t intern_type;
896 typedef char extern_type;
897 typedef mbstate_t state_type;
898
899 _LIBCPP_ALWAYS_INLINE
900 explicit codecvt(size_t __refs = 0)
901 : locale::facet(__refs) {}
902
903 _LIBCPP_ALWAYS_INLINE
904 result out(state_type& __st,
905 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
906 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
907 {
908 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
909 }
910
911 _LIBCPP_ALWAYS_INLINE
912 result unshift(state_type& __st,
913 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
914 {
915 return do_unshift(__st, __to, __to_end, __to_nxt);
916 }
917
918 _LIBCPP_ALWAYS_INLINE
919 result in(state_type& __st,
920 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
921 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
922 {
923 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
924 }
925
926 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000927 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000928 {
929 return do_encoding();
930 }
931
932 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000933 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000934 {
935 return do_always_noconv();
936 }
937
938 _LIBCPP_ALWAYS_INLINE
939 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
940 {
941 return do_length(__st, __frm, __end, __mx);
942 }
943
944 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +0000945 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000946 {
947 return do_max_length();
948 }
949
950 static locale::id id;
951
952protected:
953 _LIBCPP_ALWAYS_INLINE
954 explicit codecvt(const char*, size_t __refs = 0)
955 : locale::facet(__refs) {}
956
957 ~codecvt();
958
959 virtual result do_out(state_type& __st,
960 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
961 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
962 virtual result do_in(state_type& __st,
963 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
964 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
965 virtual result do_unshift(state_type& __st,
966 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000967 virtual int do_encoding() const _NOEXCEPT;
968 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000969 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +0000970 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000971};
972
973// template <> class codecvt<char32_t, char, mbstate_t>
974
975template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +0000976class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000977 : public locale::facet,
978 public codecvt_base
979{
980public:
981 typedef char32_t intern_type;
982 typedef char extern_type;
983 typedef mbstate_t state_type;
984
985 _LIBCPP_ALWAYS_INLINE
986 explicit codecvt(size_t __refs = 0)
987 : locale::facet(__refs) {}
988
989 _LIBCPP_ALWAYS_INLINE
990 result out(state_type& __st,
991 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
992 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
993 {
994 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
995 }
996
997 _LIBCPP_ALWAYS_INLINE
998 result unshift(state_type& __st,
999 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1000 {
1001 return do_unshift(__st, __to, __to_end, __to_nxt);
1002 }
1003
1004 _LIBCPP_ALWAYS_INLINE
1005 result in(state_type& __st,
1006 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1007 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1008 {
1009 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1010 }
1011
1012 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001013 int encoding() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001014 {
1015 return do_encoding();
1016 }
1017
1018 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001019 bool always_noconv() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001020 {
1021 return do_always_noconv();
1022 }
1023
1024 _LIBCPP_ALWAYS_INLINE
1025 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1026 {
1027 return do_length(__st, __frm, __end, __mx);
1028 }
1029
1030 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc9834542011-05-31 15:34:58 +00001031 int max_length() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001032 {
1033 return do_max_length();
1034 }
1035
1036 static locale::id id;
1037
1038protected:
1039 _LIBCPP_ALWAYS_INLINE
1040 explicit codecvt(const char*, size_t __refs = 0)
1041 : locale::facet(__refs) {}
1042
1043 ~codecvt();
1044
1045 virtual result do_out(state_type& __st,
1046 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1047 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1048 virtual result do_in(state_type& __st,
1049 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1050 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1051 virtual result do_unshift(state_type& __st,
1052 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001053 virtual int do_encoding() const _NOEXCEPT;
1054 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001055 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnantc9834542011-05-31 15:34:58 +00001056 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057};
1058
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001059// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1060
1061template <class _InternT, class _ExternT, class _StateT>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001062class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001063 : public codecvt<_InternT, _ExternT, _StateT>
1064{
1065public:
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001066 _LIBCPP_ALWAYS_INLINE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001067 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1068 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001069 _LIBCPP_ALWAYS_INLINE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001070 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1071 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1072protected:
1073 ~codecvt_byname();
1074};
1075
1076template <class _InternT, class _ExternT, class _StateT>
1077codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1078{
1079}
1080
1081extern template class codecvt_byname<char, char, mbstate_t>;
1082extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1083extern template class codecvt_byname<char16_t, char, mbstate_t>;
1084extern template class codecvt_byname<char32_t, char, mbstate_t>;
1085
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001086_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001087
1088template <size_t _N>
1089struct __narrow_to_utf8
1090{
1091 template <class _OutputIterator, class _CharT>
1092 _OutputIterator
1093 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1094};
1095
1096template <>
1097struct __narrow_to_utf8<8>
1098{
1099 template <class _OutputIterator, class _CharT>
1100 _LIBCPP_ALWAYS_INLINE
1101 _OutputIterator
1102 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1103 {
1104 for (; __wb < __we; ++__wb, ++__s)
1105 *__s = *__wb;
1106 return __s;
1107 }
1108};
1109
1110template <>
1111struct __narrow_to_utf8<16>
1112 : public codecvt<char16_t, char, mbstate_t>
1113{
1114 _LIBCPP_ALWAYS_INLINE
1115 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1116
1117 ~__narrow_to_utf8();
1118
1119 template <class _OutputIterator, class _CharT>
1120 _LIBCPP_ALWAYS_INLINE
1121 _OutputIterator
1122 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1123 {
1124 result __r = ok;
1125 mbstate_t __mb;
1126 while (__wb < __we && __r != error)
1127 {
1128 const int __sz = 32;
1129 char __buf[__sz];
1130 char* __bn;
1131 const char16_t* __wn = (const char16_t*)__wb;
1132 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1133 __buf, __buf+__sz, __bn);
1134 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1135 __throw_runtime_error("locale not supported");
1136 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1137 *__s = *__p;
1138 __wb = (const _CharT*)__wn;
1139 }
1140 return __s;
1141 }
1142};
1143
1144template <>
1145struct __narrow_to_utf8<32>
1146 : public codecvt<char32_t, char, mbstate_t>
1147{
1148 _LIBCPP_ALWAYS_INLINE
1149 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1150
1151 ~__narrow_to_utf8();
1152
1153 template <class _OutputIterator, class _CharT>
1154 _LIBCPP_ALWAYS_INLINE
1155 _OutputIterator
1156 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1157 {
1158 result __r = ok;
1159 mbstate_t __mb;
1160 while (__wb < __we && __r != error)
1161 {
1162 const int __sz = 32;
1163 char __buf[__sz];
1164 char* __bn;
1165 const char32_t* __wn = (const char32_t*)__wb;
1166 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1167 __buf, __buf+__sz, __bn);
1168 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1169 __throw_runtime_error("locale not supported");
1170 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1171 *__s = *__p;
1172 __wb = (const _CharT*)__wn;
1173 }
1174 return __s;
1175 }
1176};
1177
1178template <size_t _N>
1179struct __widen_from_utf8
1180{
1181 template <class _OutputIterator>
1182 _OutputIterator
1183 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1184};
1185
1186template <>
1187struct __widen_from_utf8<8>
1188{
1189 template <class _OutputIterator>
1190 _LIBCPP_ALWAYS_INLINE
1191 _OutputIterator
1192 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1193 {
1194 for (; __nb < __ne; ++__nb, ++__s)
1195 *__s = *__nb;
1196 return __s;
1197 }
1198};
1199
1200template <>
1201struct __widen_from_utf8<16>
1202 : public codecvt<char16_t, char, mbstate_t>
1203{
1204 _LIBCPP_ALWAYS_INLINE
1205 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1206
1207 ~__widen_from_utf8();
1208
1209 template <class _OutputIterator>
1210 _LIBCPP_ALWAYS_INLINE
1211 _OutputIterator
1212 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1213 {
1214 result __r = ok;
1215 mbstate_t __mb;
1216 while (__nb < __ne && __r != error)
1217 {
1218 const int __sz = 32;
1219 char16_t __buf[__sz];
1220 char16_t* __bn;
1221 const char* __nn = __nb;
1222 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1223 __buf, __buf+__sz, __bn);
1224 if (__r == codecvt_base::error || __nn == __nb)
1225 __throw_runtime_error("locale not supported");
1226 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1227 *__s = (wchar_t)*__p;
1228 __nb = __nn;
1229 }
1230 return __s;
1231 }
1232};
1233
1234template <>
1235struct __widen_from_utf8<32>
1236 : public codecvt<char32_t, char, mbstate_t>
1237{
1238 _LIBCPP_ALWAYS_INLINE
1239 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1240
1241 ~__widen_from_utf8();
1242
1243 template <class _OutputIterator>
1244 _LIBCPP_ALWAYS_INLINE
1245 _OutputIterator
1246 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1247 {
1248 result __r = ok;
1249 mbstate_t __mb;
1250 while (__nb < __ne && __r != error)
1251 {
1252 const int __sz = 32;
1253 char32_t __buf[__sz];
1254 char32_t* __bn;
1255 const char* __nn = __nb;
1256 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1257 __buf, __buf+__sz, __bn);
1258 if (__r == codecvt_base::error || __nn == __nb)
1259 __throw_runtime_error("locale not supported");
1260 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1261 *__s = (wchar_t)*__p;
1262 __nb = __nn;
1263 }
1264 return __s;
1265 }
1266};
1267
1268// template <class charT> class numpunct
1269
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001270template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001271
1272template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001273class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001274 : public locale::facet
1275{
1276public:
1277 typedef char char_type;
1278 typedef basic_string<char_type> string_type;
1279
1280 explicit numpunct(size_t __refs = 0);
1281
1282 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1283 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1284 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1285 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1286 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1287
1288 static locale::id id;
1289
1290protected:
1291 ~numpunct();
1292 virtual char_type do_decimal_point() const;
1293 virtual char_type do_thousands_sep() const;
1294 virtual string do_grouping() const;
1295 virtual string_type do_truename() const;
1296 virtual string_type do_falsename() const;
1297
1298 char_type __decimal_point_;
1299 char_type __thousands_sep_;
1300 string __grouping_;
1301};
1302
1303template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001304class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001305 : public locale::facet
1306{
1307public:
1308 typedef wchar_t char_type;
1309 typedef basic_string<char_type> string_type;
1310
1311 explicit numpunct(size_t __refs = 0);
1312
1313 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1314 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1315 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1316 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1317 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1318
1319 static locale::id id;
1320
1321protected:
1322 ~numpunct();
1323 virtual char_type do_decimal_point() const;
1324 virtual char_type do_thousands_sep() const;
1325 virtual string do_grouping() const;
1326 virtual string_type do_truename() const;
1327 virtual string_type do_falsename() const;
1328
1329 char_type __decimal_point_;
1330 char_type __thousands_sep_;
1331 string __grouping_;
1332};
1333
1334// template <class charT> class numpunct_byname
1335
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001336template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001337
1338template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001339class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001340: public numpunct<char>
1341{
1342public:
1343 typedef char char_type;
1344 typedef basic_string<char_type> string_type;
1345
1346 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1347 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1348
1349protected:
1350 ~numpunct_byname();
1351
1352private:
1353 void __init(const char*);
1354};
1355
1356template <>
Howard Hinnantb0be42b2010-09-21 18:58:51 +00001357class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001358: public numpunct<wchar_t>
1359{
1360public:
1361 typedef wchar_t char_type;
1362 typedef basic_string<char_type> string_type;
1363
1364 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1365 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1366
1367protected:
1368 ~numpunct_byname();
1369
1370private:
1371 void __init(const char*);
1372};
1373
1374_LIBCPP_END_NAMESPACE_STD
1375
1376#endif // _LIBCPP___LOCALE