blob: 521da04926c48c5bedeeb7d551b325abb7ed79a4 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-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 Hinnantc51e1022010-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 Hinnant155c2af2010-05-24 17:49:41 +000021#include <locale.h>
Howard Hinnantc51e1022010-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 Hinnant7c9e5732011-05-31 15:34:58 +000030template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000031template <class _Facet> const _Facet& use_facet(const locale&);
32
Howard Hinnant9833cad2010-09-21 18:58:51 +000033class _LIBCPP_VISIBLE locale
Howard Hinnantc51e1022010-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 Hinnant7c9e5732011-05-31 15:34:58 +000052 locale() _NOEXCEPT;
53 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-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 Hinnantcf823322010-12-17 14:46:43 +000058 template <class _Facet>
59 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +000060 locale(const locale&, const locale&, category);
61
Howard Hinnant7c9e5732011-05-31 15:34:58 +000062 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +000063
Howard Hinnant7c9e5732011-05-31 15:34:58 +000064 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-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 Hinnant7c9e5732011-05-31 15:34:58 +000089 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000090 template <class _Facet> friend const _Facet& use_facet(const locale&);
91};
92
Howard Hinnant9833cad2010-09-21 18:58:51 +000093class _LIBCPP_VISIBLE locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +000094 : public __shared_count
95{
96protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +000097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-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 Hinnant719bda32011-05-28 14:41:13 +0000106 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000107};
108
Howard Hinnant9833cad2010-09-21 18:58:51 +0000109class _LIBCPP_VISIBLE locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000110{
111 once_flag __flag_;
112 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000113
Howard Hinnantc51e1022010-05-11 19:42:16 +0000114 static int32_t __next_id;
115public:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000116 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnantc51e1022010-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 Hinnant72f73582010-08-11 17:04:31 +0000139#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000140 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000141 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000142#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000143 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144}
145
146template <class _Facet>
147inline _LIBCPP_INLINE_VISIBILITY
148bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000149has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-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 Hinnant9833cad2010-09-21 18:58:51 +0000165class _LIBCPP_VISIBLE collate
Howard Hinnantc51e1022010-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 Hinnant9833cad2010-09-21 18:58:51 +0000172 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000173 explicit collate(size_t __refs = 0)
174 : locale::facet(__refs) {}
175
Howard Hinnant9833cad2010-09-21 18:58:51 +0000176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-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 Hinnant9833cad2010-09-21 18:58:51 +0000183 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-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 Hinnant9833cad2010-09-21 18:58:51 +0000189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-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 Hinnant9833cad2010-09-21 18:58:51 +0000244extern template class _LIBCPP_VISIBLE collate<char>;
245extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246
247// template <class CharT> class collate_byname;
248
Howard Hinnant9833cad2010-09-21 18:58:51 +0000249template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000250
251template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000252class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnantc51e1022010-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 Hinnant9833cad2010-09-21 18:58:51 +0000271class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnantc51e1022010-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{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000295 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000296 __x.data(), __x.data() + __x.size(),
297 __y.data(), __y.data() + __y.size()) < 0;
298}
299
300// template <class charT> class ctype
301
Howard Hinnant9833cad2010-09-21 18:58:51 +0000302class _LIBCPP_VISIBLE ctype_base
303{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000304public:
Alexis Hunt92b0c812011-07-09 00:56:23 +0000305#ifdef __GLIBC__
306 typedef unsigned short mask;
307#else
Howard Hinnantc51e1022010-05-11 19:42:16 +0000308 typedef __uint32_t mask;
Alexis Hunt92b0c812011-07-09 00:56:23 +0000309#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310
Howard Hinnant155c2af2010-05-24 17:49:41 +0000311#if __APPLE__
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312 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 Hinnant3b6579a2010-08-22 00:02:43 +0000322#else // __APPLE__
Howard Hinnant155c2af2010-05-24 17:49:41 +0000323 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 Hinnant3b6579a2010-08-22 00:02:43 +0000333#endif // __APPLE__
Howard Hinnantc51e1022010-05-11 19:42:16 +0000334 static const mask alnum = alpha | digit;
335 static const mask graph = alnum | punct;
336
337 _LIBCPP_ALWAYS_INLINE ctype_base() {}
338};
339
Howard Hinnant9833cad2010-09-21 18:58:51 +0000340template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000341
342template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000343class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344 : public locale::facet,
345 public ctype_base
346{
347public:
348 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000349
Howard Hinnantc51e1022010-05-11 19:42:16 +0000350 _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 Hinnant9833cad2010-09-21 18:58:51 +0000445class _LIBCPP_VISIBLE ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000446 : 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 Hinnant155c2af2010-05-24 17:49:41 +0000537#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000538 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000539#else
540 static const size_t table_size = 256; // FIXME: Don't hardcode this.
541#endif
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000542 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
543 static const mask* classic_table() _NOEXCEPT;
Alexis Hunt92b0c812011-07-09 00:56:23 +0000544 static const int* __classic_upper_table() _NOEXCEPT;
545 static const int* __classic_lower_table() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000546
547protected:
548 ~ctype();
549 virtual char_type do_toupper(char_type __c) const;
550 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
551 virtual char_type do_tolower(char_type __c) const;
552 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
553 virtual char_type do_widen(char __c) const;
554 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
555 virtual char do_narrow(char_type __c, char __dfault) const;
556 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
557};
558
559// template <class CharT> class ctype_byname;
560
Howard Hinnant9833cad2010-09-21 18:58:51 +0000561template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000562
563template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000564class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000565 : public ctype<char>
566{
567 locale_t __l;
568
569public:
570 explicit ctype_byname(const char*, size_t = 0);
571 explicit ctype_byname(const string&, size_t = 0);
572
573protected:
574 ~ctype_byname();
575 virtual char_type do_toupper(char_type) const;
576 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
577 virtual char_type do_tolower(char_type) const;
578 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
579};
580
581template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000582class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000583 : public ctype<wchar_t>
584{
585 locale_t __l;
586
587public:
588 explicit ctype_byname(const char*, size_t = 0);
589 explicit ctype_byname(const string&, size_t = 0);
590
591protected:
592 ~ctype_byname();
593 virtual bool do_is(mask __m, char_type __c) const;
594 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
595 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
596 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
597 virtual char_type do_toupper(char_type) const;
598 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
599 virtual char_type do_tolower(char_type) const;
600 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
601 virtual char_type do_widen(char) const;
602 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
603 virtual char do_narrow(char_type, char __dfault) const;
604 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
605};
606
607template <class _CharT>
608inline _LIBCPP_INLINE_VISIBILITY
609bool
610isspace(_CharT __c, const locale& __loc)
611{
612 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
613}
614
615template <class _CharT>
616inline _LIBCPP_INLINE_VISIBILITY
617bool
618isprint(_CharT __c, const locale& __loc)
619{
620 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
621}
622
623template <class _CharT>
624inline _LIBCPP_INLINE_VISIBILITY
625bool
626iscntrl(_CharT __c, const locale& __loc)
627{
628 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
629}
630
631template <class _CharT>
632inline _LIBCPP_INLINE_VISIBILITY
633bool
634isupper(_CharT __c, const locale& __loc)
635{
636 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
637}
638
639template <class _CharT>
640inline _LIBCPP_INLINE_VISIBILITY
641bool
642islower(_CharT __c, const locale& __loc)
643{
644 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
645}
646
647template <class _CharT>
648inline _LIBCPP_INLINE_VISIBILITY
649bool
650isalpha(_CharT __c, const locale& __loc)
651{
652 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
653}
654
655template <class _CharT>
656inline _LIBCPP_INLINE_VISIBILITY
657bool
658isdigit(_CharT __c, const locale& __loc)
659{
660 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
661}
662
663template <class _CharT>
664inline _LIBCPP_INLINE_VISIBILITY
665bool
666ispunct(_CharT __c, const locale& __loc)
667{
668 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
669}
670
671template <class _CharT>
672inline _LIBCPP_INLINE_VISIBILITY
673bool
674isxdigit(_CharT __c, const locale& __loc)
675{
676 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
677}
678
679template <class _CharT>
680inline _LIBCPP_INLINE_VISIBILITY
681bool
682isalnum(_CharT __c, const locale& __loc)
683{
684 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
685}
686
687template <class _CharT>
688inline _LIBCPP_INLINE_VISIBILITY
689bool
690isgraph(_CharT __c, const locale& __loc)
691{
692 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
693}
694
695template <class _CharT>
696inline _LIBCPP_INLINE_VISIBILITY
697_CharT
698toupper(_CharT __c, const locale& __loc)
699{
700 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
701}
702
703template <class _CharT>
704inline _LIBCPP_INLINE_VISIBILITY
705_CharT
706tolower(_CharT __c, const locale& __loc)
707{
708 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
709}
710
711// codecvt_base
712
Howard Hinnant9833cad2010-09-21 18:58:51 +0000713class _LIBCPP_VISIBLE codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000714{
715public:
716 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
717 enum result {ok, partial, error, noconv};
718};
719
720// template <class internT, class externT, class stateT> class codecvt;
721
Howard Hinnant9833cad2010-09-21 18:58:51 +0000722template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000723
724// template <> class codecvt<char, char, mbstate_t>
725
726template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000727class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000728 : public locale::facet,
729 public codecvt_base
730{
731public:
732 typedef char intern_type;
733 typedef char extern_type;
734 typedef mbstate_t state_type;
735
736 _LIBCPP_ALWAYS_INLINE
737 explicit codecvt(size_t __refs = 0)
738 : locale::facet(__refs) {}
739
740 _LIBCPP_ALWAYS_INLINE
741 result out(state_type& __st,
742 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
743 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
744 {
745 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
746 }
747
748 _LIBCPP_ALWAYS_INLINE
749 result unshift(state_type& __st,
750 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
751 {
752 return do_unshift(__st, __to, __to_end, __to_nxt);
753 }
754
755 _LIBCPP_ALWAYS_INLINE
756 result in(state_type& __st,
757 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
758 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
759 {
760 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
761 }
762
763 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000764 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000765 {
766 return do_encoding();
767 }
768
769 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000770 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000771 {
772 return do_always_noconv();
773 }
774
775 _LIBCPP_ALWAYS_INLINE
776 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
777 {
778 return do_length(__st, __frm, __end, __mx);
779 }
780
781 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000782 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000783 {
784 return do_max_length();
785 }
786
787 static locale::id id;
788
789protected:
790 _LIBCPP_ALWAYS_INLINE
791 explicit codecvt(const char*, size_t __refs = 0)
792 : locale::facet(__refs) {}
793
794 ~codecvt();
795
796 virtual result do_out(state_type& __st,
797 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
798 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
799 virtual result do_in(state_type& __st,
800 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
801 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
802 virtual result do_unshift(state_type& __st,
803 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000804 virtual int do_encoding() const _NOEXCEPT;
805 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000806 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000807 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000808};
809
810// template <> class codecvt<wchar_t, char, mbstate_t>
811
812template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000813class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000814 : public locale::facet,
815 public codecvt_base
816{
817 locale_t __l;
818public:
819 typedef wchar_t intern_type;
820 typedef char extern_type;
821 typedef mbstate_t state_type;
822
823 explicit codecvt(size_t __refs = 0);
824
825 _LIBCPP_ALWAYS_INLINE
826 result out(state_type& __st,
827 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
828 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
829 {
830 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
831 }
832
833 _LIBCPP_ALWAYS_INLINE
834 result unshift(state_type& __st,
835 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
836 {
837 return do_unshift(__st, __to, __to_end, __to_nxt);
838 }
839
840 _LIBCPP_ALWAYS_INLINE
841 result in(state_type& __st,
842 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
843 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
844 {
845 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
846 }
847
848 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000849 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000850 {
851 return do_encoding();
852 }
853
854 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000855 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000856 {
857 return do_always_noconv();
858 }
859
860 _LIBCPP_ALWAYS_INLINE
861 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
862 {
863 return do_length(__st, __frm, __end, __mx);
864 }
865
866 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000867 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000868 {
869 return do_max_length();
870 }
871
872 static locale::id id;
873
874protected:
875 explicit codecvt(const char*, size_t __refs = 0);
876
877 ~codecvt();
878
879 virtual result do_out(state_type& __st,
880 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
881 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
882 virtual result do_in(state_type& __st,
883 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
884 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
885 virtual result do_unshift(state_type& __st,
886 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000887 virtual int do_encoding() const _NOEXCEPT;
888 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000889 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000890 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000891};
892
893// template <> class codecvt<char16_t, char, mbstate_t>
894
895template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000896class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000897 : public locale::facet,
898 public codecvt_base
899{
900public:
901 typedef char16_t intern_type;
902 typedef char extern_type;
903 typedef mbstate_t state_type;
904
905 _LIBCPP_ALWAYS_INLINE
906 explicit codecvt(size_t __refs = 0)
907 : locale::facet(__refs) {}
908
909 _LIBCPP_ALWAYS_INLINE
910 result out(state_type& __st,
911 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
912 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
913 {
914 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
915 }
916
917 _LIBCPP_ALWAYS_INLINE
918 result unshift(state_type& __st,
919 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
920 {
921 return do_unshift(__st, __to, __to_end, __to_nxt);
922 }
923
924 _LIBCPP_ALWAYS_INLINE
925 result in(state_type& __st,
926 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
927 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
928 {
929 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
930 }
931
932 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000933 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000934 {
935 return do_encoding();
936 }
937
938 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000939 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000940 {
941 return do_always_noconv();
942 }
943
944 _LIBCPP_ALWAYS_INLINE
945 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
946 {
947 return do_length(__st, __frm, __end, __mx);
948 }
949
950 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000951 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000952 {
953 return do_max_length();
954 }
955
956 static locale::id id;
957
958protected:
959 _LIBCPP_ALWAYS_INLINE
960 explicit codecvt(const char*, size_t __refs = 0)
961 : locale::facet(__refs) {}
962
963 ~codecvt();
964
965 virtual result do_out(state_type& __st,
966 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
967 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
968 virtual result do_in(state_type& __st,
969 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
970 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
971 virtual result do_unshift(state_type& __st,
972 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000973 virtual int do_encoding() const _NOEXCEPT;
974 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000975 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000976 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000977};
978
979// template <> class codecvt<char32_t, char, mbstate_t>
980
981template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000982class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000983 : public locale::facet,
984 public codecvt_base
985{
986public:
987 typedef char32_t intern_type;
988 typedef char extern_type;
989 typedef mbstate_t state_type;
990
991 _LIBCPP_ALWAYS_INLINE
992 explicit codecvt(size_t __refs = 0)
993 : locale::facet(__refs) {}
994
995 _LIBCPP_ALWAYS_INLINE
996 result out(state_type& __st,
997 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
998 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
999 {
1000 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1001 }
1002
1003 _LIBCPP_ALWAYS_INLINE
1004 result unshift(state_type& __st,
1005 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1006 {
1007 return do_unshift(__st, __to, __to_end, __to_nxt);
1008 }
1009
1010 _LIBCPP_ALWAYS_INLINE
1011 result in(state_type& __st,
1012 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1013 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1014 {
1015 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1016 }
1017
1018 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001019 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001020 {
1021 return do_encoding();
1022 }
1023
1024 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001025 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001026 {
1027 return do_always_noconv();
1028 }
1029
1030 _LIBCPP_ALWAYS_INLINE
1031 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1032 {
1033 return do_length(__st, __frm, __end, __mx);
1034 }
1035
1036 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001037 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001038 {
1039 return do_max_length();
1040 }
1041
1042 static locale::id id;
1043
1044protected:
1045 _LIBCPP_ALWAYS_INLINE
1046 explicit codecvt(const char*, size_t __refs = 0)
1047 : locale::facet(__refs) {}
1048
1049 ~codecvt();
1050
1051 virtual result do_out(state_type& __st,
1052 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1053 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1054 virtual result do_in(state_type& __st,
1055 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1056 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1057 virtual result do_unshift(state_type& __st,
1058 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001059 virtual int do_encoding() const _NOEXCEPT;
1060 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001061 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001062 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001063};
1064
Howard Hinnantc51e1022010-05-11 19:42:16 +00001065// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1066
1067template <class _InternT, class _ExternT, class _StateT>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001068class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001069 : public codecvt<_InternT, _ExternT, _StateT>
1070{
1071public:
Howard Hinnant9833cad2010-09-21 18:58:51 +00001072 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001073 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1074 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant9833cad2010-09-21 18:58:51 +00001075 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001076 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1077 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1078protected:
1079 ~codecvt_byname();
1080};
1081
1082template <class _InternT, class _ExternT, class _StateT>
1083codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1084{
1085}
1086
1087extern template class codecvt_byname<char, char, mbstate_t>;
1088extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1089extern template class codecvt_byname<char16_t, char, mbstate_t>;
1090extern template class codecvt_byname<char32_t, char, mbstate_t>;
1091
Howard Hinnant9833cad2010-09-21 18:58:51 +00001092_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001093
1094template <size_t _N>
1095struct __narrow_to_utf8
1096{
1097 template <class _OutputIterator, class _CharT>
1098 _OutputIterator
1099 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1100};
1101
1102template <>
1103struct __narrow_to_utf8<8>
1104{
1105 template <class _OutputIterator, class _CharT>
1106 _LIBCPP_ALWAYS_INLINE
1107 _OutputIterator
1108 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1109 {
1110 for (; __wb < __we; ++__wb, ++__s)
1111 *__s = *__wb;
1112 return __s;
1113 }
1114};
1115
1116template <>
1117struct __narrow_to_utf8<16>
1118 : public codecvt<char16_t, char, mbstate_t>
1119{
1120 _LIBCPP_ALWAYS_INLINE
1121 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1122
1123 ~__narrow_to_utf8();
1124
1125 template <class _OutputIterator, class _CharT>
1126 _LIBCPP_ALWAYS_INLINE
1127 _OutputIterator
1128 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1129 {
1130 result __r = ok;
1131 mbstate_t __mb;
1132 while (__wb < __we && __r != error)
1133 {
1134 const int __sz = 32;
1135 char __buf[__sz];
1136 char* __bn;
1137 const char16_t* __wn = (const char16_t*)__wb;
1138 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1139 __buf, __buf+__sz, __bn);
1140 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1141 __throw_runtime_error("locale not supported");
1142 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1143 *__s = *__p;
1144 __wb = (const _CharT*)__wn;
1145 }
1146 return __s;
1147 }
1148};
1149
1150template <>
1151struct __narrow_to_utf8<32>
1152 : public codecvt<char32_t, char, mbstate_t>
1153{
1154 _LIBCPP_ALWAYS_INLINE
1155 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1156
1157 ~__narrow_to_utf8();
1158
1159 template <class _OutputIterator, class _CharT>
1160 _LIBCPP_ALWAYS_INLINE
1161 _OutputIterator
1162 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1163 {
1164 result __r = ok;
1165 mbstate_t __mb;
1166 while (__wb < __we && __r != error)
1167 {
1168 const int __sz = 32;
1169 char __buf[__sz];
1170 char* __bn;
1171 const char32_t* __wn = (const char32_t*)__wb;
1172 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1173 __buf, __buf+__sz, __bn);
1174 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1175 __throw_runtime_error("locale not supported");
1176 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1177 *__s = *__p;
1178 __wb = (const _CharT*)__wn;
1179 }
1180 return __s;
1181 }
1182};
1183
1184template <size_t _N>
1185struct __widen_from_utf8
1186{
1187 template <class _OutputIterator>
1188 _OutputIterator
1189 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1190};
1191
1192template <>
1193struct __widen_from_utf8<8>
1194{
1195 template <class _OutputIterator>
1196 _LIBCPP_ALWAYS_INLINE
1197 _OutputIterator
1198 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1199 {
1200 for (; __nb < __ne; ++__nb, ++__s)
1201 *__s = *__nb;
1202 return __s;
1203 }
1204};
1205
1206template <>
1207struct __widen_from_utf8<16>
1208 : public codecvt<char16_t, char, mbstate_t>
1209{
1210 _LIBCPP_ALWAYS_INLINE
1211 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1212
1213 ~__widen_from_utf8();
1214
1215 template <class _OutputIterator>
1216 _LIBCPP_ALWAYS_INLINE
1217 _OutputIterator
1218 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1219 {
1220 result __r = ok;
1221 mbstate_t __mb;
1222 while (__nb < __ne && __r != error)
1223 {
1224 const int __sz = 32;
1225 char16_t __buf[__sz];
1226 char16_t* __bn;
1227 const char* __nn = __nb;
1228 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1229 __buf, __buf+__sz, __bn);
1230 if (__r == codecvt_base::error || __nn == __nb)
1231 __throw_runtime_error("locale not supported");
1232 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1233 *__s = (wchar_t)*__p;
1234 __nb = __nn;
1235 }
1236 return __s;
1237 }
1238};
1239
1240template <>
1241struct __widen_from_utf8<32>
1242 : public codecvt<char32_t, char, mbstate_t>
1243{
1244 _LIBCPP_ALWAYS_INLINE
1245 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1246
1247 ~__widen_from_utf8();
1248
1249 template <class _OutputIterator>
1250 _LIBCPP_ALWAYS_INLINE
1251 _OutputIterator
1252 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1253 {
1254 result __r = ok;
1255 mbstate_t __mb;
1256 while (__nb < __ne && __r != error)
1257 {
1258 const int __sz = 32;
1259 char32_t __buf[__sz];
1260 char32_t* __bn;
1261 const char* __nn = __nb;
1262 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1263 __buf, __buf+__sz, __bn);
1264 if (__r == codecvt_base::error || __nn == __nb)
1265 __throw_runtime_error("locale not supported");
1266 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1267 *__s = (wchar_t)*__p;
1268 __nb = __nn;
1269 }
1270 return __s;
1271 }
1272};
1273
1274// template <class charT> class numpunct
1275
Howard Hinnant9833cad2010-09-21 18:58:51 +00001276template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001277
1278template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001279class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001280 : public locale::facet
1281{
1282public:
1283 typedef char char_type;
1284 typedef basic_string<char_type> string_type;
1285
1286 explicit numpunct(size_t __refs = 0);
1287
1288 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1289 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1290 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1291 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1292 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1293
1294 static locale::id id;
1295
1296protected:
1297 ~numpunct();
1298 virtual char_type do_decimal_point() const;
1299 virtual char_type do_thousands_sep() const;
1300 virtual string do_grouping() const;
1301 virtual string_type do_truename() const;
1302 virtual string_type do_falsename() const;
1303
1304 char_type __decimal_point_;
1305 char_type __thousands_sep_;
1306 string __grouping_;
1307};
1308
1309template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001310class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001311 : public locale::facet
1312{
1313public:
1314 typedef wchar_t char_type;
1315 typedef basic_string<char_type> string_type;
1316
1317 explicit numpunct(size_t __refs = 0);
1318
1319 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1320 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1321 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1322 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1323 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1324
1325 static locale::id id;
1326
1327protected:
1328 ~numpunct();
1329 virtual char_type do_decimal_point() const;
1330 virtual char_type do_thousands_sep() const;
1331 virtual string do_grouping() const;
1332 virtual string_type do_truename() const;
1333 virtual string_type do_falsename() const;
1334
1335 char_type __decimal_point_;
1336 char_type __thousands_sep_;
1337 string __grouping_;
1338};
1339
1340// template <class charT> class numpunct_byname
1341
Howard Hinnant9833cad2010-09-21 18:58:51 +00001342template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001343
1344template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001345class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001346: public numpunct<char>
1347{
1348public:
1349 typedef char char_type;
1350 typedef basic_string<char_type> string_type;
1351
1352 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1353 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1354
1355protected:
1356 ~numpunct_byname();
1357
1358private:
1359 void __init(const char*);
1360};
1361
1362template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001363class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001364: public numpunct<wchar_t>
1365{
1366public:
1367 typedef wchar_t char_type;
1368 typedef basic_string<char_type> string_type;
1369
1370 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1371 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1372
1373protected:
1374 ~numpunct_byname();
1375
1376private:
1377 void __init(const char*);
1378};
1379
1380_LIBCPP_END_NAMESPACE_STD
1381
1382#endif // _LIBCPP___LOCALE