blob: a161af90f72dbccf4f6ab7506d6eb81e80ec90ab [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 Hinnantdd0d7022011-09-22 19:10:18 +000022#if _WIN32
Howard Hinnantae0f80b2011-09-29 20:33:10 +000023# include <support/win32/locale_win32.h>
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +000024#elif (__GLIBC__ || __APPLE__ || __FreeBSD__)
Howard Hinnantdd0d7022011-09-22 19:10:18 +000025# include <xlocale.h>
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +000026#endif // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD_
Howard Hinnantc51e1022010-05-11 19:42:16 +000027
28#pragma GCC system_header
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32class locale;
33
Howard Hinnant7c9e5732011-05-31 15:34:58 +000034template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000035template <class _Facet> const _Facet& use_facet(const locale&);
36
Howard Hinnant9833cad2010-09-21 18:58:51 +000037class _LIBCPP_VISIBLE locale
Howard Hinnantc51e1022010-05-11 19:42:16 +000038{
39public:
40 // types:
41 class facet;
42 class id;
43
44 typedef int category;
45 static const category // values assigned here are for exposition only
46 none = 0,
47 collate = LC_COLLATE_MASK,
48 ctype = LC_CTYPE_MASK,
49 monetary = LC_MONETARY_MASK,
50 numeric = LC_NUMERIC_MASK,
51 time = LC_TIME_MASK,
52 messages = LC_MESSAGES_MASK,
53 all = collate | ctype | monetary | numeric | time | messages;
54
55 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +000056 locale() _NOEXCEPT;
57 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000058 explicit locale(const char*);
59 explicit locale(const string&);
60 locale(const locale&, const char*, category);
61 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +000062 template <class _Facet>
63 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +000064 locale(const locale&, const locale&, category);
65
Howard Hinnant7c9e5732011-05-31 15:34:58 +000066 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +000067
Howard Hinnant7c9e5732011-05-31 15:34:58 +000068 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000069
70 template <class _Facet> locale combine(const locale&) const;
71
72 // locale operations:
73 string name() const;
74 bool operator==(const locale&) const;
75 bool operator!=(const locale& __y) const {return !(*this == __y);}
76 template <class _CharT, class _Traits, class _Allocator>
77 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
78 const basic_string<_CharT, _Traits, _Allocator>&) const;
79
80 // global locale objects:
81 static locale global(const locale&);
82 static const locale& classic();
83
84private:
85 class __imp;
86 __imp* __locale_;
87
88 void __install_ctor(const locale&, facet*, long);
89 static locale& __global();
90 bool has_facet(id&) const;
91 const facet* use_facet(id&) const;
92
Howard Hinnant7c9e5732011-05-31 15:34:58 +000093 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000094 template <class _Facet> friend const _Facet& use_facet(const locale&);
95};
96
Howard Hinnant9833cad2010-09-21 18:58:51 +000097class _LIBCPP_VISIBLE locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +000098 : public __shared_count
99{
100protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000101 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000102 explicit facet(size_t __refs = 0)
103 : __shared_count(static_cast<long>(__refs)-1) {}
104
105 virtual ~facet();
106
107// facet(const facet&) = delete; // effectively done in __shared_count
108// void operator=(const facet&) = delete;
109private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000110 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000111};
112
Howard Hinnant9833cad2010-09-21 18:58:51 +0000113class _LIBCPP_VISIBLE locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000114{
115 once_flag __flag_;
116 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000117
Howard Hinnantc51e1022010-05-11 19:42:16 +0000118 static int32_t __next_id;
119public:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000120 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000121private:
122 void __init();
123 void operator=(const id&); // = delete;
124 id(const id&); // = delete;
125public: // only needed for tests
126 long __get();
127
128 friend class locale;
129 friend class locale::__imp;
130};
131
132template <class _Facet>
133inline _LIBCPP_INLINE_VISIBILITY
134locale::locale(const locale& __other, _Facet* __f)
135{
136 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
137}
138
139template <class _Facet>
140locale
141locale::combine(const locale& __other) const
142{
Howard Hinnant72f73582010-08-11 17:04:31 +0000143#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000144 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000146#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000147 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000148}
149
150template <class _Facet>
151inline _LIBCPP_INLINE_VISIBILITY
152bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000153has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154{
155 return __l.has_facet(_Facet::id);
156}
157
158template <class _Facet>
159inline _LIBCPP_INLINE_VISIBILITY
160const _Facet&
161use_facet(const locale& __l)
162{
163 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
164}
165
166// template <class _CharT> class collate;
167
168template <class _CharT>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000169class _LIBCPP_VISIBLE collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000170 : public locale::facet
171{
172public:
173 typedef _CharT char_type;
174 typedef basic_string<char_type> string_type;
175
Howard Hinnant9833cad2010-09-21 18:58:51 +0000176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000177 explicit collate(size_t __refs = 0)
178 : locale::facet(__refs) {}
179
Howard Hinnant9833cad2010-09-21 18:58:51 +0000180 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000181 int compare(const char_type* __lo1, const char_type* __hi1,
182 const char_type* __lo2, const char_type* __hi2) const
183 {
184 return do_compare(__lo1, __hi1, __lo2, __hi2);
185 }
186
Howard Hinnant9833cad2010-09-21 18:58:51 +0000187 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000188 string_type transform(const char_type* __lo, const char_type* __hi) const
189 {
190 return do_transform(__lo, __hi);
191 }
192
Howard Hinnant9833cad2010-09-21 18:58:51 +0000193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000194 long hash(const char_type* __lo, const char_type* __hi) const
195 {
196 return do_hash(__lo, __hi);
197 }
198
199 static locale::id id;
200
201protected:
202 ~collate();
203 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
204 const char_type* __lo2, const char_type* __hi2) const;
205 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
206 {return string_type(__lo, __hi);}
207 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
208};
209
210template <class _CharT> locale::id collate<_CharT>::id;
211
212template <class _CharT>
213collate<_CharT>::~collate()
214{
215}
216
217template <class _CharT>
218int
219collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
220 const char_type* __lo2, const char_type* __hi2) const
221{
222 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
223 {
224 if (__lo1 == __hi1 || *__lo1 < *__lo2)
225 return -1;
226 if (*__lo2 < *__lo1)
227 return 1;
228 }
229 return __lo1 != __hi1;
230}
231
232template <class _CharT>
233long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000234collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000236 size_t __h = 0;
237 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
238 const size_t __mask = size_t(0xF) << (__sr + 4);
239 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240 {
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000241 __h = (__h << 4) + *__p;
242 size_t __g = __h & __mask;
243 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000244 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000245 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246}
247
Howard Hinnant9833cad2010-09-21 18:58:51 +0000248extern template class _LIBCPP_VISIBLE collate<char>;
249extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000250
251// template <class CharT> class collate_byname;
252
Howard Hinnant9833cad2010-09-21 18:58:51 +0000253template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000254
255template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000256class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000257 : public collate<char>
258{
259 locale_t __l;
260public:
261 typedef char char_type;
262 typedef basic_string<char_type> string_type;
263
264 explicit collate_byname(const char* __n, size_t __refs = 0);
265 explicit collate_byname(const string& __n, size_t __refs = 0);
266
267protected:
268 ~collate_byname();
269 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
270 const char_type* __lo2, const char_type* __hi2) const;
271 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
272};
273
274template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000275class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000276 : public collate<wchar_t>
277{
278 locale_t __l;
279public:
280 typedef wchar_t char_type;
281 typedef basic_string<char_type> string_type;
282
283 explicit collate_byname(const char* __n, size_t __refs = 0);
284 explicit collate_byname(const string& __n, size_t __refs = 0);
285
286protected:
287 ~collate_byname();
288
289 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
290 const char_type* __lo2, const char_type* __hi2) const;
291 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
292};
293
294template <class _CharT, class _Traits, class _Allocator>
295bool
296locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
297 const basic_string<_CharT, _Traits, _Allocator>& __y) const
298{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000299 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000300 __x.data(), __x.data() + __x.size(),
301 __y.data(), __y.data() + __y.size()) < 0;
302}
303
304// template <class charT> class ctype
305
Howard Hinnant9833cad2010-09-21 18:58:51 +0000306class _LIBCPP_VISIBLE ctype_base
307{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000308public:
David Chisnall1d581062011-09-21 08:39:44 +0000309#if __GLIBC__
Alexis Hunt92b0c812011-07-09 00:56:23 +0000310 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000311 static const mask space = _ISspace;
312 static const mask print = _ISprint;
313 static const mask cntrl = _IScntrl;
314 static const mask upper = _ISupper;
315 static const mask lower = _ISlower;
316 static const mask alpha = _ISalpha;
317 static const mask digit = _ISdigit;
318 static const mask punct = _ISpunct;
319 static const mask xdigit = _ISxdigit;
320 static const mask blank = _ISblank;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000321#elif _WIN32
Howard Hinnantd7a78632011-09-29 13:33:15 +0000322 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000323 static const mask space = _SPACE;
324 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
325 static const mask cntrl = _CONTROL;
326 static const mask upper = _UPPER;
327 static const mask lower = _LOWER;
328 static const mask alpha = _ALPHA;
329 static const mask digit = _DIGIT;
330 static const mask punct = _PUNCT;
331 static const mask xdigit = _HEX;
332 static const mask blank = _BLANK;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000333#elif (__APPLE__ || __FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000334#if __APPLE__
335 typedef __uint32_t mask;
336#elif __FreeBSD__
337 typedef unsigned long mask;
338#endif
339 static const mask space = _CTYPE_S;
340 static const mask print = _CTYPE_R;
341 static const mask cntrl = _CTYPE_C;
342 static const mask upper = _CTYPE_U;
343 static const mask lower = _CTYPE_L;
344 static const mask alpha = _CTYPE_A;
345 static const mask digit = _CTYPE_D;
346 static const mask punct = _CTYPE_P;
347 static const mask xdigit = _CTYPE_X;
348 static const mask blank = _CTYPE_B;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000349#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
350 typedef unsigned long mask;
351 static const mask space = 1<<0;
352 static const mask print = 1<<1;
353 static const mask cntrl = 1<<2;
354 static const mask upper = 1<<3;
355 static const mask lower = 1<<4;
356 static const mask alpha = 1<<5;
357 static const mask digit = 1<<6;
358 static const mask punct = 1<<7;
359 static const mask xdigit = 1<<8;
360 static const mask blank = 1<<9;
361#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
Howard Hinnantc51e1022010-05-11 19:42:16 +0000362 static const mask alnum = alpha | digit;
363 static const mask graph = alnum | punct;
364
365 _LIBCPP_ALWAYS_INLINE ctype_base() {}
366};
367
Howard Hinnant9833cad2010-09-21 18:58:51 +0000368template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000369
370template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000371class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372 : public locale::facet,
373 public ctype_base
374{
375public:
376 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000377
Howard Hinnantc51e1022010-05-11 19:42:16 +0000378 _LIBCPP_ALWAYS_INLINE
379 explicit ctype(size_t __refs = 0)
380 : locale::facet(__refs) {}
381
382 _LIBCPP_ALWAYS_INLINE
383 bool is(mask __m, char_type __c) const
384 {
385 return do_is(__m, __c);
386 }
387
388 _LIBCPP_ALWAYS_INLINE
389 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
390 {
391 return do_is(__low, __high, __vec);
392 }
393
394 _LIBCPP_ALWAYS_INLINE
395 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
396 {
397 return do_scan_is(__m, __low, __high);
398 }
399
400 _LIBCPP_ALWAYS_INLINE
401 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
402 {
403 return do_scan_not(__m, __low, __high);
404 }
405
406 _LIBCPP_ALWAYS_INLINE
407 char_type toupper(char_type __c) const
408 {
409 return do_toupper(__c);
410 }
411
412 _LIBCPP_ALWAYS_INLINE
413 const char_type* toupper(char_type* __low, const char_type* __high) const
414 {
415 return do_toupper(__low, __high);
416 }
417
418 _LIBCPP_ALWAYS_INLINE
419 char_type tolower(char_type __c) const
420 {
421 return do_tolower(__c);
422 }
423
424 _LIBCPP_ALWAYS_INLINE
425 const char_type* tolower(char_type* __low, const char_type* __high) const
426 {
427 return do_tolower(__low, __high);
428 }
429
430 _LIBCPP_ALWAYS_INLINE
431 char_type widen(char __c) const
432 {
433 return do_widen(__c);
434 }
435
436 _LIBCPP_ALWAYS_INLINE
437 const char* widen(const char* __low, const char* __high, char_type* __to) const
438 {
439 return do_widen(__low, __high, __to);
440 }
441
442 _LIBCPP_ALWAYS_INLINE
443 char narrow(char_type __c, char __dfault) const
444 {
445 return do_narrow(__c, __dfault);
446 }
447
448 _LIBCPP_ALWAYS_INLINE
449 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
450 {
451 return do_narrow(__low, __high, __dfault, __to);
452 }
453
454 static locale::id id;
455
456protected:
457 ~ctype();
458 virtual bool do_is(mask __m, char_type __c) const;
459 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
460 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
461 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
462 virtual char_type do_toupper(char_type) const;
463 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
464 virtual char_type do_tolower(char_type) const;
465 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
466 virtual char_type do_widen(char) const;
467 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
468 virtual char do_narrow(char_type, char __dfault) const;
469 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
470};
471
472template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000473class _LIBCPP_VISIBLE ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474 : public locale::facet, public ctype_base
475{
476 const mask* __tab_;
477 bool __del_;
478public:
479 typedef char char_type;
480
481 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
482
483 _LIBCPP_ALWAYS_INLINE
484 bool is(mask __m, char_type __c) const
485 {
486 return isascii(__c) ? __tab_[__c] & __m : false;
487 }
488
489 _LIBCPP_ALWAYS_INLINE
490 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
491 {
492 for (; __low != __high; ++__low, ++__vec)
493 *__vec = isascii(*__low) ? __tab_[*__low] : 0;
494 return __low;
495 }
496
497 _LIBCPP_ALWAYS_INLINE
498 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
499 {
500 for (; __low != __high; ++__low)
501 if (isascii(*__low) && (__tab_[*__low] & __m))
502 break;
503 return __low;
504 }
505
506 _LIBCPP_ALWAYS_INLINE
507 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
508 {
509 for (; __low != __high; ++__low)
510 if (!(isascii(*__low) && (__tab_[*__low] & __m)))
511 break;
512 return __low;
513 }
514
515 _LIBCPP_ALWAYS_INLINE
516 char_type toupper(char_type __c) const
517 {
518 return do_toupper(__c);
519 }
520
521 _LIBCPP_ALWAYS_INLINE
522 const char_type* toupper(char_type* __low, const char_type* __high) const
523 {
524 return do_toupper(__low, __high);
525 }
526
527 _LIBCPP_ALWAYS_INLINE
528 char_type tolower(char_type __c) const
529 {
530 return do_tolower(__c);
531 }
532
533 _LIBCPP_ALWAYS_INLINE
534 const char_type* tolower(char_type* __low, const char_type* __high) const
535 {
536 return do_tolower(__low, __high);
537 }
538
539 _LIBCPP_ALWAYS_INLINE
540 char_type widen(char __c) const
541 {
542 return do_widen(__c);
543 }
544
545 _LIBCPP_ALWAYS_INLINE
546 const char* widen(const char* __low, const char* __high, char_type* __to) const
547 {
548 return do_widen(__low, __high, __to);
549 }
550
551 _LIBCPP_ALWAYS_INLINE
552 char narrow(char_type __c, char __dfault) const
553 {
554 return do_narrow(__c, __dfault);
555 }
556
557 _LIBCPP_ALWAYS_INLINE
558 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
559 {
560 return do_narrow(__low, __high, __dfault, __to);
561 }
562
563 static locale::id id;
564
Howard Hinnant155c2af2010-05-24 17:49:41 +0000565#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000566 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000567#else
568 static const size_t table_size = 256; // FIXME: Don't hardcode this.
569#endif
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000570 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
571 static const mask* classic_table() _NOEXCEPT;
Howard Hinnantd7a78632011-09-29 13:33:15 +0000572#if defined(__GLIBC__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000573 static const int* __classic_upper_table() _NOEXCEPT;
574 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000575#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000576
577protected:
578 ~ctype();
579 virtual char_type do_toupper(char_type __c) const;
580 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
581 virtual char_type do_tolower(char_type __c) const;
582 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
583 virtual char_type do_widen(char __c) const;
584 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
585 virtual char do_narrow(char_type __c, char __dfault) const;
586 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
587};
588
589// template <class CharT> class ctype_byname;
590
Howard Hinnant9833cad2010-09-21 18:58:51 +0000591template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000592
593template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000594class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000595 : public ctype<char>
596{
597 locale_t __l;
598
599public:
600 explicit ctype_byname(const char*, size_t = 0);
601 explicit ctype_byname(const string&, size_t = 0);
602
603protected:
604 ~ctype_byname();
605 virtual char_type do_toupper(char_type) const;
606 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
607 virtual char_type do_tolower(char_type) const;
608 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
609};
610
611template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000612class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000613 : public ctype<wchar_t>
614{
615 locale_t __l;
616
617public:
618 explicit ctype_byname(const char*, size_t = 0);
619 explicit ctype_byname(const string&, size_t = 0);
620
621protected:
622 ~ctype_byname();
623 virtual bool do_is(mask __m, char_type __c) const;
624 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
625 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
626 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
627 virtual char_type do_toupper(char_type) const;
628 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
629 virtual char_type do_tolower(char_type) const;
630 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
631 virtual char_type do_widen(char) const;
632 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
633 virtual char do_narrow(char_type, char __dfault) const;
634 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
635};
636
637template <class _CharT>
638inline _LIBCPP_INLINE_VISIBILITY
639bool
640isspace(_CharT __c, const locale& __loc)
641{
642 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
643}
644
645template <class _CharT>
646inline _LIBCPP_INLINE_VISIBILITY
647bool
648isprint(_CharT __c, const locale& __loc)
649{
650 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
651}
652
653template <class _CharT>
654inline _LIBCPP_INLINE_VISIBILITY
655bool
656iscntrl(_CharT __c, const locale& __loc)
657{
658 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
659}
660
661template <class _CharT>
662inline _LIBCPP_INLINE_VISIBILITY
663bool
664isupper(_CharT __c, const locale& __loc)
665{
666 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
667}
668
669template <class _CharT>
670inline _LIBCPP_INLINE_VISIBILITY
671bool
672islower(_CharT __c, const locale& __loc)
673{
674 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
675}
676
677template <class _CharT>
678inline _LIBCPP_INLINE_VISIBILITY
679bool
680isalpha(_CharT __c, const locale& __loc)
681{
682 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
683}
684
685template <class _CharT>
686inline _LIBCPP_INLINE_VISIBILITY
687bool
688isdigit(_CharT __c, const locale& __loc)
689{
690 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
691}
692
693template <class _CharT>
694inline _LIBCPP_INLINE_VISIBILITY
695bool
696ispunct(_CharT __c, const locale& __loc)
697{
698 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
699}
700
701template <class _CharT>
702inline _LIBCPP_INLINE_VISIBILITY
703bool
704isxdigit(_CharT __c, const locale& __loc)
705{
706 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
707}
708
709template <class _CharT>
710inline _LIBCPP_INLINE_VISIBILITY
711bool
712isalnum(_CharT __c, const locale& __loc)
713{
714 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
715}
716
717template <class _CharT>
718inline _LIBCPP_INLINE_VISIBILITY
719bool
720isgraph(_CharT __c, const locale& __loc)
721{
722 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
723}
724
725template <class _CharT>
726inline _LIBCPP_INLINE_VISIBILITY
727_CharT
728toupper(_CharT __c, const locale& __loc)
729{
730 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
731}
732
733template <class _CharT>
734inline _LIBCPP_INLINE_VISIBILITY
735_CharT
736tolower(_CharT __c, const locale& __loc)
737{
738 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
739}
740
741// codecvt_base
742
Howard Hinnant9833cad2010-09-21 18:58:51 +0000743class _LIBCPP_VISIBLE codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000744{
745public:
746 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
747 enum result {ok, partial, error, noconv};
748};
749
750// template <class internT, class externT, class stateT> class codecvt;
751
Howard Hinnant9833cad2010-09-21 18:58:51 +0000752template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000753
754// template <> class codecvt<char, char, mbstate_t>
755
756template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000757class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000758 : public locale::facet,
759 public codecvt_base
760{
761public:
762 typedef char intern_type;
763 typedef char extern_type;
764 typedef mbstate_t state_type;
765
766 _LIBCPP_ALWAYS_INLINE
767 explicit codecvt(size_t __refs = 0)
768 : locale::facet(__refs) {}
769
770 _LIBCPP_ALWAYS_INLINE
771 result out(state_type& __st,
772 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
773 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
774 {
775 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
776 }
777
778 _LIBCPP_ALWAYS_INLINE
779 result unshift(state_type& __st,
780 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
781 {
782 return do_unshift(__st, __to, __to_end, __to_nxt);
783 }
784
785 _LIBCPP_ALWAYS_INLINE
786 result in(state_type& __st,
787 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
788 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
789 {
790 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
791 }
792
793 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000794 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000795 {
796 return do_encoding();
797 }
798
799 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000800 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000801 {
802 return do_always_noconv();
803 }
804
805 _LIBCPP_ALWAYS_INLINE
806 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
807 {
808 return do_length(__st, __frm, __end, __mx);
809 }
810
811 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000812 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000813 {
814 return do_max_length();
815 }
816
817 static locale::id id;
818
819protected:
820 _LIBCPP_ALWAYS_INLINE
821 explicit codecvt(const char*, size_t __refs = 0)
822 : locale::facet(__refs) {}
823
824 ~codecvt();
825
826 virtual result do_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 virtual result do_in(state_type& __st,
830 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
831 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
832 virtual result do_unshift(state_type& __st,
833 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000834 virtual int do_encoding() const _NOEXCEPT;
835 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000836 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 +0000837 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000838};
839
840// template <> class codecvt<wchar_t, char, mbstate_t>
841
842template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000843class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000844 : public locale::facet,
845 public codecvt_base
846{
847 locale_t __l;
848public:
849 typedef wchar_t intern_type;
850 typedef char extern_type;
851 typedef mbstate_t state_type;
852
853 explicit codecvt(size_t __refs = 0);
854
855 _LIBCPP_ALWAYS_INLINE
856 result out(state_type& __st,
857 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
858 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
859 {
860 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
861 }
862
863 _LIBCPP_ALWAYS_INLINE
864 result unshift(state_type& __st,
865 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
866 {
867 return do_unshift(__st, __to, __to_end, __to_nxt);
868 }
869
870 _LIBCPP_ALWAYS_INLINE
871 result in(state_type& __st,
872 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
873 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
874 {
875 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
876 }
877
878 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000879 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000880 {
881 return do_encoding();
882 }
883
884 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000885 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000886 {
887 return do_always_noconv();
888 }
889
890 _LIBCPP_ALWAYS_INLINE
891 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
892 {
893 return do_length(__st, __frm, __end, __mx);
894 }
895
896 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000897 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000898 {
899 return do_max_length();
900 }
901
902 static locale::id id;
903
904protected:
905 explicit codecvt(const char*, size_t __refs = 0);
906
907 ~codecvt();
908
909 virtual result do_out(state_type& __st,
910 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
911 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
912 virtual result do_in(state_type& __st,
913 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
914 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
915 virtual result do_unshift(state_type& __st,
916 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000917 virtual int do_encoding() const _NOEXCEPT;
918 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000919 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 +0000920 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000921};
922
923// template <> class codecvt<char16_t, char, mbstate_t>
924
925template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000926class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000927 : public locale::facet,
928 public codecvt_base
929{
930public:
931 typedef char16_t intern_type;
932 typedef char extern_type;
933 typedef mbstate_t state_type;
934
935 _LIBCPP_ALWAYS_INLINE
936 explicit codecvt(size_t __refs = 0)
937 : locale::facet(__refs) {}
938
939 _LIBCPP_ALWAYS_INLINE
940 result out(state_type& __st,
941 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
942 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
943 {
944 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
945 }
946
947 _LIBCPP_ALWAYS_INLINE
948 result unshift(state_type& __st,
949 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
950 {
951 return do_unshift(__st, __to, __to_end, __to_nxt);
952 }
953
954 _LIBCPP_ALWAYS_INLINE
955 result in(state_type& __st,
956 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
957 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
958 {
959 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
960 }
961
962 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000963 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000964 {
965 return do_encoding();
966 }
967
968 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000969 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000970 {
971 return do_always_noconv();
972 }
973
974 _LIBCPP_ALWAYS_INLINE
975 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
976 {
977 return do_length(__st, __frm, __end, __mx);
978 }
979
980 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000981 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000982 {
983 return do_max_length();
984 }
985
986 static locale::id id;
987
988protected:
989 _LIBCPP_ALWAYS_INLINE
990 explicit codecvt(const char*, size_t __refs = 0)
991 : locale::facet(__refs) {}
992
993 ~codecvt();
994
995 virtual result do_out(state_type& __st,
996 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
997 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
998 virtual result do_in(state_type& __st,
999 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1000 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1001 virtual result do_unshift(state_type& __st,
1002 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001003 virtual int do_encoding() const _NOEXCEPT;
1004 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001005 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 +00001006 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001007};
1008
1009// template <> class codecvt<char32_t, char, mbstate_t>
1010
1011template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001012class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001013 : public locale::facet,
1014 public codecvt_base
1015{
1016public:
1017 typedef char32_t intern_type;
1018 typedef char extern_type;
1019 typedef mbstate_t state_type;
1020
1021 _LIBCPP_ALWAYS_INLINE
1022 explicit codecvt(size_t __refs = 0)
1023 : locale::facet(__refs) {}
1024
1025 _LIBCPP_ALWAYS_INLINE
1026 result out(state_type& __st,
1027 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1028 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1029 {
1030 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1031 }
1032
1033 _LIBCPP_ALWAYS_INLINE
1034 result unshift(state_type& __st,
1035 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1036 {
1037 return do_unshift(__st, __to, __to_end, __to_nxt);
1038 }
1039
1040 _LIBCPP_ALWAYS_INLINE
1041 result in(state_type& __st,
1042 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1043 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1044 {
1045 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1046 }
1047
1048 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001049 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001050 {
1051 return do_encoding();
1052 }
1053
1054 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001055 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001056 {
1057 return do_always_noconv();
1058 }
1059
1060 _LIBCPP_ALWAYS_INLINE
1061 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1062 {
1063 return do_length(__st, __frm, __end, __mx);
1064 }
1065
1066 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001067 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001068 {
1069 return do_max_length();
1070 }
1071
1072 static locale::id id;
1073
1074protected:
1075 _LIBCPP_ALWAYS_INLINE
1076 explicit codecvt(const char*, size_t __refs = 0)
1077 : locale::facet(__refs) {}
1078
1079 ~codecvt();
1080
1081 virtual result do_out(state_type& __st,
1082 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1083 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1084 virtual result do_in(state_type& __st,
1085 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1086 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1087 virtual result do_unshift(state_type& __st,
1088 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001089 virtual int do_encoding() const _NOEXCEPT;
1090 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001091 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 +00001092 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001093};
1094
Howard Hinnantc51e1022010-05-11 19:42:16 +00001095// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1096
1097template <class _InternT, class _ExternT, class _StateT>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001098class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001099 : public codecvt<_InternT, _ExternT, _StateT>
1100{
1101public:
Howard Hinnant9833cad2010-09-21 18:58:51 +00001102 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001103 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1104 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant9833cad2010-09-21 18:58:51 +00001105 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001106 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1107 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1108protected:
1109 ~codecvt_byname();
1110};
1111
1112template <class _InternT, class _ExternT, class _StateT>
1113codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1114{
1115}
1116
1117extern template class codecvt_byname<char, char, mbstate_t>;
1118extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1119extern template class codecvt_byname<char16_t, char, mbstate_t>;
1120extern template class codecvt_byname<char32_t, char, mbstate_t>;
1121
Howard Hinnant9833cad2010-09-21 18:58:51 +00001122_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001123
1124template <size_t _N>
1125struct __narrow_to_utf8
1126{
1127 template <class _OutputIterator, class _CharT>
1128 _OutputIterator
1129 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1130};
1131
1132template <>
1133struct __narrow_to_utf8<8>
1134{
1135 template <class _OutputIterator, class _CharT>
1136 _LIBCPP_ALWAYS_INLINE
1137 _OutputIterator
1138 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1139 {
1140 for (; __wb < __we; ++__wb, ++__s)
1141 *__s = *__wb;
1142 return __s;
1143 }
1144};
1145
1146template <>
1147struct __narrow_to_utf8<16>
1148 : public codecvt<char16_t, char, mbstate_t>
1149{
1150 _LIBCPP_ALWAYS_INLINE
1151 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1152
1153 ~__narrow_to_utf8();
1154
1155 template <class _OutputIterator, class _CharT>
1156 _LIBCPP_ALWAYS_INLINE
1157 _OutputIterator
1158 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1159 {
1160 result __r = ok;
1161 mbstate_t __mb;
1162 while (__wb < __we && __r != error)
1163 {
1164 const int __sz = 32;
1165 char __buf[__sz];
1166 char* __bn;
1167 const char16_t* __wn = (const char16_t*)__wb;
1168 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1169 __buf, __buf+__sz, __bn);
1170 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1171 __throw_runtime_error("locale not supported");
1172 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1173 *__s = *__p;
1174 __wb = (const _CharT*)__wn;
1175 }
1176 return __s;
1177 }
1178};
1179
1180template <>
1181struct __narrow_to_utf8<32>
1182 : public codecvt<char32_t, char, mbstate_t>
1183{
1184 _LIBCPP_ALWAYS_INLINE
1185 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1186
1187 ~__narrow_to_utf8();
1188
1189 template <class _OutputIterator, class _CharT>
1190 _LIBCPP_ALWAYS_INLINE
1191 _OutputIterator
1192 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1193 {
1194 result __r = ok;
1195 mbstate_t __mb;
1196 while (__wb < __we && __r != error)
1197 {
1198 const int __sz = 32;
1199 char __buf[__sz];
1200 char* __bn;
1201 const char32_t* __wn = (const char32_t*)__wb;
1202 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1203 __buf, __buf+__sz, __bn);
1204 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1205 __throw_runtime_error("locale not supported");
1206 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1207 *__s = *__p;
1208 __wb = (const _CharT*)__wn;
1209 }
1210 return __s;
1211 }
1212};
1213
1214template <size_t _N>
1215struct __widen_from_utf8
1216{
1217 template <class _OutputIterator>
1218 _OutputIterator
1219 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1220};
1221
1222template <>
1223struct __widen_from_utf8<8>
1224{
1225 template <class _OutputIterator>
1226 _LIBCPP_ALWAYS_INLINE
1227 _OutputIterator
1228 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1229 {
1230 for (; __nb < __ne; ++__nb, ++__s)
1231 *__s = *__nb;
1232 return __s;
1233 }
1234};
1235
1236template <>
1237struct __widen_from_utf8<16>
1238 : public codecvt<char16_t, char, mbstate_t>
1239{
1240 _LIBCPP_ALWAYS_INLINE
1241 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1242
1243 ~__widen_from_utf8();
1244
1245 template <class _OutputIterator>
1246 _LIBCPP_ALWAYS_INLINE
1247 _OutputIterator
1248 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1249 {
1250 result __r = ok;
1251 mbstate_t __mb;
1252 while (__nb < __ne && __r != error)
1253 {
1254 const int __sz = 32;
1255 char16_t __buf[__sz];
1256 char16_t* __bn;
1257 const char* __nn = __nb;
1258 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1259 __buf, __buf+__sz, __bn);
1260 if (__r == codecvt_base::error || __nn == __nb)
1261 __throw_runtime_error("locale not supported");
1262 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1263 *__s = (wchar_t)*__p;
1264 __nb = __nn;
1265 }
1266 return __s;
1267 }
1268};
1269
1270template <>
1271struct __widen_from_utf8<32>
1272 : public codecvt<char32_t, char, mbstate_t>
1273{
1274 _LIBCPP_ALWAYS_INLINE
1275 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1276
1277 ~__widen_from_utf8();
1278
1279 template <class _OutputIterator>
1280 _LIBCPP_ALWAYS_INLINE
1281 _OutputIterator
1282 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1283 {
1284 result __r = ok;
1285 mbstate_t __mb;
1286 while (__nb < __ne && __r != error)
1287 {
1288 const int __sz = 32;
1289 char32_t __buf[__sz];
1290 char32_t* __bn;
1291 const char* __nn = __nb;
1292 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1293 __buf, __buf+__sz, __bn);
1294 if (__r == codecvt_base::error || __nn == __nb)
1295 __throw_runtime_error("locale not supported");
1296 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1297 *__s = (wchar_t)*__p;
1298 __nb = __nn;
1299 }
1300 return __s;
1301 }
1302};
1303
1304// template <class charT> class numpunct
1305
Howard Hinnant9833cad2010-09-21 18:58:51 +00001306template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001307
1308template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001309class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001310 : public locale::facet
1311{
1312public:
1313 typedef char char_type;
1314 typedef basic_string<char_type> string_type;
1315
1316 explicit numpunct(size_t __refs = 0);
1317
1318 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1319 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1320 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1321 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1322 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1323
1324 static locale::id id;
1325
1326protected:
1327 ~numpunct();
1328 virtual char_type do_decimal_point() const;
1329 virtual char_type do_thousands_sep() const;
1330 virtual string do_grouping() const;
1331 virtual string_type do_truename() const;
1332 virtual string_type do_falsename() const;
1333
1334 char_type __decimal_point_;
1335 char_type __thousands_sep_;
1336 string __grouping_;
1337};
1338
1339template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001340class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001341 : public locale::facet
1342{
1343public:
1344 typedef wchar_t char_type;
1345 typedef basic_string<char_type> string_type;
1346
1347 explicit numpunct(size_t __refs = 0);
1348
1349 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1350 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1351 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1352 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1353 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1354
1355 static locale::id id;
1356
1357protected:
1358 ~numpunct();
1359 virtual char_type do_decimal_point() const;
1360 virtual char_type do_thousands_sep() const;
1361 virtual string do_grouping() const;
1362 virtual string_type do_truename() const;
1363 virtual string_type do_falsename() const;
1364
1365 char_type __decimal_point_;
1366 char_type __thousands_sep_;
1367 string __grouping_;
1368};
1369
1370// template <class charT> class numpunct_byname
1371
Howard Hinnant9833cad2010-09-21 18:58:51 +00001372template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001373
1374template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001375class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001376: public numpunct<char>
1377{
1378public:
1379 typedef char char_type;
1380 typedef basic_string<char_type> string_type;
1381
1382 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1383 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1384
1385protected:
1386 ~numpunct_byname();
1387
1388private:
1389 void __init(const char*);
1390};
1391
1392template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001393class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001394: public numpunct<wchar_t>
1395{
1396public:
1397 typedef wchar_t char_type;
1398 typedef basic_string<char_type> string_type;
1399
1400 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1401 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1402
1403protected:
1404 ~numpunct_byname();
1405
1406private:
1407 void __init(const char*);
1408};
1409
1410_LIBCPP_END_NAMESPACE_STD
1411
1412#endif // _LIBCPP___LOCALE