blob: 28cb3ef65292af7deae088ab522d8f8b34363720 [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
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000028#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000029#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000030#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000031
32_LIBCPP_BEGIN_NAMESPACE_STD
33
34class locale;
35
Howard Hinnant7c9e5732011-05-31 15:34:58 +000036template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000037template <class _Facet> const _Facet& use_facet(const locale&);
38
Howard Hinnant9833cad2010-09-21 18:58:51 +000039class _LIBCPP_VISIBLE locale
Howard Hinnantc51e1022010-05-11 19:42:16 +000040{
41public:
42 // types:
43 class facet;
44 class id;
45
46 typedef int category;
47 static const category // values assigned here are for exposition only
48 none = 0,
49 collate = LC_COLLATE_MASK,
50 ctype = LC_CTYPE_MASK,
51 monetary = LC_MONETARY_MASK,
52 numeric = LC_NUMERIC_MASK,
53 time = LC_TIME_MASK,
54 messages = LC_MESSAGES_MASK,
55 all = collate | ctype | monetary | numeric | time | messages;
56
57 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +000058 locale() _NOEXCEPT;
59 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000060 explicit locale(const char*);
61 explicit locale(const string&);
62 locale(const locale&, const char*, category);
63 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +000064 template <class _Facet>
65 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +000066 locale(const locale&, const locale&, category);
67
Howard Hinnant7c9e5732011-05-31 15:34:58 +000068 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +000069
Howard Hinnant7c9e5732011-05-31 15:34:58 +000070 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000071
72 template <class _Facet> locale combine(const locale&) const;
73
74 // locale operations:
75 string name() const;
76 bool operator==(const locale&) const;
77 bool operator!=(const locale& __y) const {return !(*this == __y);}
78 template <class _CharT, class _Traits, class _Allocator>
79 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
80 const basic_string<_CharT, _Traits, _Allocator>&) const;
81
82 // global locale objects:
83 static locale global(const locale&);
84 static const locale& classic();
85
86private:
87 class __imp;
88 __imp* __locale_;
89
90 void __install_ctor(const locale&, facet*, long);
91 static locale& __global();
92 bool has_facet(id&) const;
93 const facet* use_facet(id&) const;
94
Howard Hinnant7c9e5732011-05-31 15:34:58 +000095 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000096 template <class _Facet> friend const _Facet& use_facet(const locale&);
97};
98
Howard Hinnant9833cad2010-09-21 18:58:51 +000099class _LIBCPP_VISIBLE locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +0000100 : public __shared_count
101{
102protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000103 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000104 explicit facet(size_t __refs = 0)
105 : __shared_count(static_cast<long>(__refs)-1) {}
106
107 virtual ~facet();
108
109// facet(const facet&) = delete; // effectively done in __shared_count
110// void operator=(const facet&) = delete;
111private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000112 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000113};
114
Howard Hinnant9833cad2010-09-21 18:58:51 +0000115class _LIBCPP_VISIBLE locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000116{
117 once_flag __flag_;
118 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000119
Howard Hinnantc51e1022010-05-11 19:42:16 +0000120 static int32_t __next_id;
121public:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000122 _LIBCPP_INLINE_VISIBILITY id() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123private:
124 void __init();
125 void operator=(const id&); // = delete;
126 id(const id&); // = delete;
127public: // only needed for tests
128 long __get();
129
130 friend class locale;
131 friend class locale::__imp;
132};
133
134template <class _Facet>
135inline _LIBCPP_INLINE_VISIBILITY
136locale::locale(const locale& __other, _Facet* __f)
137{
138 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
139}
140
141template <class _Facet>
142locale
143locale::combine(const locale& __other) const
144{
Howard Hinnant72f73582010-08-11 17:04:31 +0000145#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000146 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000147 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000148#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000149 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000150}
151
152template <class _Facet>
153inline _LIBCPP_INLINE_VISIBILITY
154bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000155has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000156{
157 return __l.has_facet(_Facet::id);
158}
159
160template <class _Facet>
161inline _LIBCPP_INLINE_VISIBILITY
162const _Facet&
163use_facet(const locale& __l)
164{
165 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
166}
167
168// template <class _CharT> class collate;
169
170template <class _CharT>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000171class _LIBCPP_VISIBLE collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000172 : public locale::facet
173{
174public:
175 typedef _CharT char_type;
176 typedef basic_string<char_type> string_type;
177
Howard Hinnant9833cad2010-09-21 18:58:51 +0000178 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000179 explicit collate(size_t __refs = 0)
180 : locale::facet(__refs) {}
181
Howard Hinnant9833cad2010-09-21 18:58:51 +0000182 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000183 int compare(const char_type* __lo1, const char_type* __hi1,
184 const char_type* __lo2, const char_type* __hi2) const
185 {
186 return do_compare(__lo1, __hi1, __lo2, __hi2);
187 }
188
Howard Hinnant9833cad2010-09-21 18:58:51 +0000189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000190 string_type transform(const char_type* __lo, const char_type* __hi) const
191 {
192 return do_transform(__lo, __hi);
193 }
194
Howard Hinnant9833cad2010-09-21 18:58:51 +0000195 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000196 long hash(const char_type* __lo, const char_type* __hi) const
197 {
198 return do_hash(__lo, __hi);
199 }
200
201 static locale::id id;
202
203protected:
204 ~collate();
205 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
206 const char_type* __lo2, const char_type* __hi2) const;
207 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
208 {return string_type(__lo, __hi);}
209 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
210};
211
212template <class _CharT> locale::id collate<_CharT>::id;
213
214template <class _CharT>
215collate<_CharT>::~collate()
216{
217}
218
219template <class _CharT>
220int
221collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
222 const char_type* __lo2, const char_type* __hi2) const
223{
224 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
225 {
226 if (__lo1 == __hi1 || *__lo1 < *__lo2)
227 return -1;
228 if (*__lo2 < *__lo1)
229 return 1;
230 }
231 return __lo1 != __hi1;
232}
233
234template <class _CharT>
235long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000236collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000237{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000238 size_t __h = 0;
239 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
240 const size_t __mask = size_t(0xF) << (__sr + 4);
241 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000242 {
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000243 __h = (__h << 4) + *__p;
244 size_t __g = __h & __mask;
245 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000247 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000248}
249
Howard Hinnant9833cad2010-09-21 18:58:51 +0000250extern template class _LIBCPP_VISIBLE collate<char>;
251extern template class _LIBCPP_VISIBLE collate<wchar_t>;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000252
253// template <class CharT> class collate_byname;
254
Howard Hinnant9833cad2010-09-21 18:58:51 +0000255template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000256
257template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000258class _LIBCPP_VISIBLE collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000259 : public collate<char>
260{
261 locale_t __l;
262public:
263 typedef char char_type;
264 typedef basic_string<char_type> string_type;
265
266 explicit collate_byname(const char* __n, size_t __refs = 0);
267 explicit collate_byname(const string& __n, size_t __refs = 0);
268
269protected:
270 ~collate_byname();
271 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
272 const char_type* __lo2, const char_type* __hi2) const;
273 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
274};
275
276template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000277class _LIBCPP_VISIBLE collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000278 : public collate<wchar_t>
279{
280 locale_t __l;
281public:
282 typedef wchar_t char_type;
283 typedef basic_string<char_type> string_type;
284
285 explicit collate_byname(const char* __n, size_t __refs = 0);
286 explicit collate_byname(const string& __n, size_t __refs = 0);
287
288protected:
289 ~collate_byname();
290
291 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
292 const char_type* __lo2, const char_type* __hi2) const;
293 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
294};
295
296template <class _CharT, class _Traits, class _Allocator>
297bool
298locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
299 const basic_string<_CharT, _Traits, _Allocator>& __y) const
300{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000301 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000302 __x.data(), __x.data() + __x.size(),
303 __y.data(), __y.data() + __y.size()) < 0;
304}
305
306// template <class charT> class ctype
307
Howard Hinnant9833cad2010-09-21 18:58:51 +0000308class _LIBCPP_VISIBLE ctype_base
309{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310public:
David Chisnall1d581062011-09-21 08:39:44 +0000311#if __GLIBC__
Alexis Hunt92b0c812011-07-09 00:56:23 +0000312 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000313 static const mask space = _ISspace;
314 static const mask print = _ISprint;
315 static const mask cntrl = _IScntrl;
316 static const mask upper = _ISupper;
317 static const mask lower = _ISlower;
318 static const mask alpha = _ISalpha;
319 static const mask digit = _ISdigit;
320 static const mask punct = _ISpunct;
321 static const mask xdigit = _ISxdigit;
322 static const mask blank = _ISblank;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000323#elif _WIN32
Howard Hinnantd7a78632011-09-29 13:33:15 +0000324 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000325 static const mask space = _SPACE;
326 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
327 static const mask cntrl = _CONTROL;
328 static const mask upper = _UPPER;
329 static const mask lower = _LOWER;
330 static const mask alpha = _ALPHA;
331 static const mask digit = _DIGIT;
332 static const mask punct = _PUNCT;
333 static const mask xdigit = _HEX;
334 static const mask blank = _BLANK;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000335#elif (__APPLE__ || __FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000336#if __APPLE__
337 typedef __uint32_t mask;
338#elif __FreeBSD__
339 typedef unsigned long mask;
340#endif
341 static const mask space = _CTYPE_S;
342 static const mask print = _CTYPE_R;
343 static const mask cntrl = _CTYPE_C;
344 static const mask upper = _CTYPE_U;
345 static const mask lower = _CTYPE_L;
346 static const mask alpha = _CTYPE_A;
347 static const mask digit = _CTYPE_D;
348 static const mask punct = _CTYPE_P;
349 static const mask xdigit = _CTYPE_X;
350 static const mask blank = _CTYPE_B;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000351#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
352 typedef unsigned long mask;
353 static const mask space = 1<<0;
354 static const mask print = 1<<1;
355 static const mask cntrl = 1<<2;
356 static const mask upper = 1<<3;
357 static const mask lower = 1<<4;
358 static const mask alpha = 1<<5;
359 static const mask digit = 1<<6;
360 static const mask punct = 1<<7;
361 static const mask xdigit = 1<<8;
362 static const mask blank = 1<<9;
363#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
Howard Hinnantc51e1022010-05-11 19:42:16 +0000364 static const mask alnum = alpha | digit;
365 static const mask graph = alnum | punct;
366
367 _LIBCPP_ALWAYS_INLINE ctype_base() {}
368};
369
Howard Hinnant9833cad2010-09-21 18:58:51 +0000370template <class _CharT> class _LIBCPP_VISIBLE ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000371
372template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000373class _LIBCPP_VISIBLE ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374 : public locale::facet,
375 public ctype_base
376{
377public:
378 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000379
Howard Hinnantc51e1022010-05-11 19:42:16 +0000380 _LIBCPP_ALWAYS_INLINE
381 explicit ctype(size_t __refs = 0)
382 : locale::facet(__refs) {}
383
384 _LIBCPP_ALWAYS_INLINE
385 bool is(mask __m, char_type __c) const
386 {
387 return do_is(__m, __c);
388 }
389
390 _LIBCPP_ALWAYS_INLINE
391 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
392 {
393 return do_is(__low, __high, __vec);
394 }
395
396 _LIBCPP_ALWAYS_INLINE
397 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
398 {
399 return do_scan_is(__m, __low, __high);
400 }
401
402 _LIBCPP_ALWAYS_INLINE
403 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
404 {
405 return do_scan_not(__m, __low, __high);
406 }
407
408 _LIBCPP_ALWAYS_INLINE
409 char_type toupper(char_type __c) const
410 {
411 return do_toupper(__c);
412 }
413
414 _LIBCPP_ALWAYS_INLINE
415 const char_type* toupper(char_type* __low, const char_type* __high) const
416 {
417 return do_toupper(__low, __high);
418 }
419
420 _LIBCPP_ALWAYS_INLINE
421 char_type tolower(char_type __c) const
422 {
423 return do_tolower(__c);
424 }
425
426 _LIBCPP_ALWAYS_INLINE
427 const char_type* tolower(char_type* __low, const char_type* __high) const
428 {
429 return do_tolower(__low, __high);
430 }
431
432 _LIBCPP_ALWAYS_INLINE
433 char_type widen(char __c) const
434 {
435 return do_widen(__c);
436 }
437
438 _LIBCPP_ALWAYS_INLINE
439 const char* widen(const char* __low, const char* __high, char_type* __to) const
440 {
441 return do_widen(__low, __high, __to);
442 }
443
444 _LIBCPP_ALWAYS_INLINE
445 char narrow(char_type __c, char __dfault) const
446 {
447 return do_narrow(__c, __dfault);
448 }
449
450 _LIBCPP_ALWAYS_INLINE
451 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
452 {
453 return do_narrow(__low, __high, __dfault, __to);
454 }
455
456 static locale::id id;
457
458protected:
459 ~ctype();
460 virtual bool do_is(mask __m, char_type __c) const;
461 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
462 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
463 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
464 virtual char_type do_toupper(char_type) const;
465 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
466 virtual char_type do_tolower(char_type) const;
467 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
468 virtual char_type do_widen(char) const;
469 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
470 virtual char do_narrow(char_type, char __dfault) const;
471 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
472};
473
474template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000475class _LIBCPP_VISIBLE ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000476 : public locale::facet, public ctype_base
477{
478 const mask* __tab_;
479 bool __del_;
480public:
481 typedef char char_type;
482
483 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
484
485 _LIBCPP_ALWAYS_INLINE
486 bool is(mask __m, char_type __c) const
487 {
488 return isascii(__c) ? __tab_[__c] & __m : false;
489 }
490
491 _LIBCPP_ALWAYS_INLINE
492 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
493 {
494 for (; __low != __high; ++__low, ++__vec)
495 *__vec = isascii(*__low) ? __tab_[*__low] : 0;
496 return __low;
497 }
498
499 _LIBCPP_ALWAYS_INLINE
500 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
501 {
502 for (; __low != __high; ++__low)
503 if (isascii(*__low) && (__tab_[*__low] & __m))
504 break;
505 return __low;
506 }
507
508 _LIBCPP_ALWAYS_INLINE
509 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
510 {
511 for (; __low != __high; ++__low)
512 if (!(isascii(*__low) && (__tab_[*__low] & __m)))
513 break;
514 return __low;
515 }
516
517 _LIBCPP_ALWAYS_INLINE
518 char_type toupper(char_type __c) const
519 {
520 return do_toupper(__c);
521 }
522
523 _LIBCPP_ALWAYS_INLINE
524 const char_type* toupper(char_type* __low, const char_type* __high) const
525 {
526 return do_toupper(__low, __high);
527 }
528
529 _LIBCPP_ALWAYS_INLINE
530 char_type tolower(char_type __c) const
531 {
532 return do_tolower(__c);
533 }
534
535 _LIBCPP_ALWAYS_INLINE
536 const char_type* tolower(char_type* __low, const char_type* __high) const
537 {
538 return do_tolower(__low, __high);
539 }
540
541 _LIBCPP_ALWAYS_INLINE
542 char_type widen(char __c) const
543 {
544 return do_widen(__c);
545 }
546
547 _LIBCPP_ALWAYS_INLINE
548 const char* widen(const char* __low, const char* __high, char_type* __to) const
549 {
550 return do_widen(__low, __high, __to);
551 }
552
553 _LIBCPP_ALWAYS_INLINE
554 char narrow(char_type __c, char __dfault) const
555 {
556 return do_narrow(__c, __dfault);
557 }
558
559 _LIBCPP_ALWAYS_INLINE
560 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
561 {
562 return do_narrow(__low, __high, __dfault, __to);
563 }
564
565 static locale::id id;
566
Howard Hinnant155c2af2010-05-24 17:49:41 +0000567#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000568 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000569#else
570 static const size_t table_size = 256; // FIXME: Don't hardcode this.
571#endif
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000572 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
573 static const mask* classic_table() _NOEXCEPT;
Howard Hinnantd7a78632011-09-29 13:33:15 +0000574#if defined(__GLIBC__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000575 static const int* __classic_upper_table() _NOEXCEPT;
576 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000577#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000578
579protected:
580 ~ctype();
581 virtual char_type do_toupper(char_type __c) const;
582 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
583 virtual char_type do_tolower(char_type __c) const;
584 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
585 virtual char_type do_widen(char __c) const;
586 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
587 virtual char do_narrow(char_type __c, char __dfault) const;
588 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
589};
590
591// template <class CharT> class ctype_byname;
592
Howard Hinnant9833cad2010-09-21 18:58:51 +0000593template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000594
595template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000596class _LIBCPP_VISIBLE ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000597 : public ctype<char>
598{
599 locale_t __l;
600
601public:
602 explicit ctype_byname(const char*, size_t = 0);
603 explicit ctype_byname(const string&, size_t = 0);
604
605protected:
606 ~ctype_byname();
607 virtual char_type do_toupper(char_type) const;
608 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
609 virtual char_type do_tolower(char_type) const;
610 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
611};
612
613template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000614class _LIBCPP_VISIBLE ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000615 : public ctype<wchar_t>
616{
617 locale_t __l;
618
619public:
620 explicit ctype_byname(const char*, size_t = 0);
621 explicit ctype_byname(const string&, size_t = 0);
622
623protected:
624 ~ctype_byname();
625 virtual bool do_is(mask __m, char_type __c) const;
626 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
627 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
628 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
629 virtual char_type do_toupper(char_type) const;
630 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
631 virtual char_type do_tolower(char_type) const;
632 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
633 virtual char_type do_widen(char) const;
634 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
635 virtual char do_narrow(char_type, char __dfault) const;
636 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
637};
638
639template <class _CharT>
640inline _LIBCPP_INLINE_VISIBILITY
641bool
642isspace(_CharT __c, const locale& __loc)
643{
644 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
645}
646
647template <class _CharT>
648inline _LIBCPP_INLINE_VISIBILITY
649bool
650isprint(_CharT __c, const locale& __loc)
651{
652 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
653}
654
655template <class _CharT>
656inline _LIBCPP_INLINE_VISIBILITY
657bool
658iscntrl(_CharT __c, const locale& __loc)
659{
660 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
661}
662
663template <class _CharT>
664inline _LIBCPP_INLINE_VISIBILITY
665bool
666isupper(_CharT __c, const locale& __loc)
667{
668 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
669}
670
671template <class _CharT>
672inline _LIBCPP_INLINE_VISIBILITY
673bool
674islower(_CharT __c, const locale& __loc)
675{
676 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
677}
678
679template <class _CharT>
680inline _LIBCPP_INLINE_VISIBILITY
681bool
682isalpha(_CharT __c, const locale& __loc)
683{
684 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
685}
686
687template <class _CharT>
688inline _LIBCPP_INLINE_VISIBILITY
689bool
690isdigit(_CharT __c, const locale& __loc)
691{
692 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
693}
694
695template <class _CharT>
696inline _LIBCPP_INLINE_VISIBILITY
697bool
698ispunct(_CharT __c, const locale& __loc)
699{
700 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
701}
702
703template <class _CharT>
704inline _LIBCPP_INLINE_VISIBILITY
705bool
706isxdigit(_CharT __c, const locale& __loc)
707{
708 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
709}
710
711template <class _CharT>
712inline _LIBCPP_INLINE_VISIBILITY
713bool
714isalnum(_CharT __c, const locale& __loc)
715{
716 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
717}
718
719template <class _CharT>
720inline _LIBCPP_INLINE_VISIBILITY
721bool
722isgraph(_CharT __c, const locale& __loc)
723{
724 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
725}
726
727template <class _CharT>
728inline _LIBCPP_INLINE_VISIBILITY
729_CharT
730toupper(_CharT __c, const locale& __loc)
731{
732 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
733}
734
735template <class _CharT>
736inline _LIBCPP_INLINE_VISIBILITY
737_CharT
738tolower(_CharT __c, const locale& __loc)
739{
740 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
741}
742
743// codecvt_base
744
Howard Hinnant9833cad2010-09-21 18:58:51 +0000745class _LIBCPP_VISIBLE codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000746{
747public:
748 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
749 enum result {ok, partial, error, noconv};
750};
751
752// template <class internT, class externT, class stateT> class codecvt;
753
Howard Hinnant9833cad2010-09-21 18:58:51 +0000754template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000755
756// template <> class codecvt<char, char, mbstate_t>
757
758template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000759class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000760 : public locale::facet,
761 public codecvt_base
762{
763public:
764 typedef char intern_type;
765 typedef char extern_type;
766 typedef mbstate_t state_type;
767
768 _LIBCPP_ALWAYS_INLINE
769 explicit codecvt(size_t __refs = 0)
770 : locale::facet(__refs) {}
771
772 _LIBCPP_ALWAYS_INLINE
773 result out(state_type& __st,
774 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
775 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
776 {
777 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
778 }
779
780 _LIBCPP_ALWAYS_INLINE
781 result unshift(state_type& __st,
782 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
783 {
784 return do_unshift(__st, __to, __to_end, __to_nxt);
785 }
786
787 _LIBCPP_ALWAYS_INLINE
788 result in(state_type& __st,
789 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
790 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
791 {
792 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
793 }
794
795 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000796 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000797 {
798 return do_encoding();
799 }
800
801 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000802 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000803 {
804 return do_always_noconv();
805 }
806
807 _LIBCPP_ALWAYS_INLINE
808 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
809 {
810 return do_length(__st, __frm, __end, __mx);
811 }
812
813 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000814 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000815 {
816 return do_max_length();
817 }
818
819 static locale::id id;
820
821protected:
822 _LIBCPP_ALWAYS_INLINE
823 explicit codecvt(const char*, size_t __refs = 0)
824 : locale::facet(__refs) {}
825
826 ~codecvt();
827
828 virtual result do_out(state_type& __st,
829 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
830 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
831 virtual result do_in(state_type& __st,
832 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
833 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
834 virtual result do_unshift(state_type& __st,
835 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000836 virtual int do_encoding() const _NOEXCEPT;
837 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000838 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 +0000839 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000840};
841
842// template <> class codecvt<wchar_t, char, mbstate_t>
843
844template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000845class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000846 : public locale::facet,
847 public codecvt_base
848{
849 locale_t __l;
850public:
851 typedef wchar_t intern_type;
852 typedef char extern_type;
853 typedef mbstate_t state_type;
854
855 explicit codecvt(size_t __refs = 0);
856
857 _LIBCPP_ALWAYS_INLINE
858 result out(state_type& __st,
859 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
860 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
861 {
862 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
863 }
864
865 _LIBCPP_ALWAYS_INLINE
866 result unshift(state_type& __st,
867 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
868 {
869 return do_unshift(__st, __to, __to_end, __to_nxt);
870 }
871
872 _LIBCPP_ALWAYS_INLINE
873 result in(state_type& __st,
874 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
875 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
876 {
877 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
878 }
879
880 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000881 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000882 {
883 return do_encoding();
884 }
885
886 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000887 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000888 {
889 return do_always_noconv();
890 }
891
892 _LIBCPP_ALWAYS_INLINE
893 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
894 {
895 return do_length(__st, __frm, __end, __mx);
896 }
897
898 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000899 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000900 {
901 return do_max_length();
902 }
903
904 static locale::id id;
905
906protected:
907 explicit codecvt(const char*, size_t __refs = 0);
908
909 ~codecvt();
910
911 virtual result do_out(state_type& __st,
912 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
913 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
914 virtual result do_in(state_type& __st,
915 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
916 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
917 virtual result do_unshift(state_type& __st,
918 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000919 virtual int do_encoding() const _NOEXCEPT;
920 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000921 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 +0000922 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000923};
924
925// template <> class codecvt<char16_t, char, mbstate_t>
926
927template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +0000928class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000929 : public locale::facet,
930 public codecvt_base
931{
932public:
933 typedef char16_t intern_type;
934 typedef char extern_type;
935 typedef mbstate_t state_type;
936
937 _LIBCPP_ALWAYS_INLINE
938 explicit codecvt(size_t __refs = 0)
939 : locale::facet(__refs) {}
940
941 _LIBCPP_ALWAYS_INLINE
942 result out(state_type& __st,
943 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
944 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
945 {
946 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
947 }
948
949 _LIBCPP_ALWAYS_INLINE
950 result unshift(state_type& __st,
951 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
952 {
953 return do_unshift(__st, __to, __to_end, __to_nxt);
954 }
955
956 _LIBCPP_ALWAYS_INLINE
957 result in(state_type& __st,
958 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
959 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
960 {
961 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
962 }
963
964 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000965 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000966 {
967 return do_encoding();
968 }
969
970 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000971 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000972 {
973 return do_always_noconv();
974 }
975
976 _LIBCPP_ALWAYS_INLINE
977 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
978 {
979 return do_length(__st, __frm, __end, __mx);
980 }
981
982 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000983 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000984 {
985 return do_max_length();
986 }
987
988 static locale::id id;
989
990protected:
991 _LIBCPP_ALWAYS_INLINE
992 explicit codecvt(const char*, size_t __refs = 0)
993 : locale::facet(__refs) {}
994
995 ~codecvt();
996
997 virtual result do_out(state_type& __st,
998 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
999 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1000 virtual result do_in(state_type& __st,
1001 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1002 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1003 virtual result do_unshift(state_type& __st,
1004 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001005 virtual int do_encoding() const _NOEXCEPT;
1006 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001007 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 +00001008 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001009};
1010
1011// template <> class codecvt<char32_t, char, mbstate_t>
1012
1013template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001014class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001015 : public locale::facet,
1016 public codecvt_base
1017{
1018public:
1019 typedef char32_t intern_type;
1020 typedef char extern_type;
1021 typedef mbstate_t state_type;
1022
1023 _LIBCPP_ALWAYS_INLINE
1024 explicit codecvt(size_t __refs = 0)
1025 : locale::facet(__refs) {}
1026
1027 _LIBCPP_ALWAYS_INLINE
1028 result out(state_type& __st,
1029 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1030 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1031 {
1032 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1033 }
1034
1035 _LIBCPP_ALWAYS_INLINE
1036 result unshift(state_type& __st,
1037 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1038 {
1039 return do_unshift(__st, __to, __to_end, __to_nxt);
1040 }
1041
1042 _LIBCPP_ALWAYS_INLINE
1043 result in(state_type& __st,
1044 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1045 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1046 {
1047 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1048 }
1049
1050 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001051 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001052 {
1053 return do_encoding();
1054 }
1055
1056 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001057 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001058 {
1059 return do_always_noconv();
1060 }
1061
1062 _LIBCPP_ALWAYS_INLINE
1063 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1064 {
1065 return do_length(__st, __frm, __end, __mx);
1066 }
1067
1068 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001069 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001070 {
1071 return do_max_length();
1072 }
1073
1074 static locale::id id;
1075
1076protected:
1077 _LIBCPP_ALWAYS_INLINE
1078 explicit codecvt(const char*, size_t __refs = 0)
1079 : locale::facet(__refs) {}
1080
1081 ~codecvt();
1082
1083 virtual result do_out(state_type& __st,
1084 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1085 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1086 virtual result do_in(state_type& __st,
1087 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1088 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1089 virtual result do_unshift(state_type& __st,
1090 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001091 virtual int do_encoding() const _NOEXCEPT;
1092 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001093 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 +00001094 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001095};
1096
Howard Hinnantc51e1022010-05-11 19:42:16 +00001097// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1098
1099template <class _InternT, class _ExternT, class _StateT>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001100class _LIBCPP_VISIBLE codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001101 : public codecvt<_InternT, _ExternT, _StateT>
1102{
1103public:
Howard Hinnant9833cad2010-09-21 18:58:51 +00001104 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001105 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1106 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant9833cad2010-09-21 18:58:51 +00001107 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001108 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1109 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1110protected:
1111 ~codecvt_byname();
1112};
1113
1114template <class _InternT, class _ExternT, class _StateT>
1115codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1116{
1117}
1118
1119extern template class codecvt_byname<char, char, mbstate_t>;
1120extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1121extern template class codecvt_byname<char16_t, char, mbstate_t>;
1122extern template class codecvt_byname<char32_t, char, mbstate_t>;
1123
Howard Hinnant9833cad2010-09-21 18:58:51 +00001124_LIBCPP_VISIBLE void __throw_runtime_error(const char*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001125
1126template <size_t _N>
1127struct __narrow_to_utf8
1128{
1129 template <class _OutputIterator, class _CharT>
1130 _OutputIterator
1131 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1132};
1133
1134template <>
1135struct __narrow_to_utf8<8>
1136{
1137 template <class _OutputIterator, class _CharT>
1138 _LIBCPP_ALWAYS_INLINE
1139 _OutputIterator
1140 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1141 {
1142 for (; __wb < __we; ++__wb, ++__s)
1143 *__s = *__wb;
1144 return __s;
1145 }
1146};
1147
1148template <>
1149struct __narrow_to_utf8<16>
1150 : public codecvt<char16_t, char, mbstate_t>
1151{
1152 _LIBCPP_ALWAYS_INLINE
1153 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1154
1155 ~__narrow_to_utf8();
1156
1157 template <class _OutputIterator, class _CharT>
1158 _LIBCPP_ALWAYS_INLINE
1159 _OutputIterator
1160 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1161 {
1162 result __r = ok;
1163 mbstate_t __mb;
1164 while (__wb < __we && __r != error)
1165 {
1166 const int __sz = 32;
1167 char __buf[__sz];
1168 char* __bn;
1169 const char16_t* __wn = (const char16_t*)__wb;
1170 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1171 __buf, __buf+__sz, __bn);
1172 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1173 __throw_runtime_error("locale not supported");
1174 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1175 *__s = *__p;
1176 __wb = (const _CharT*)__wn;
1177 }
1178 return __s;
1179 }
1180};
1181
1182template <>
1183struct __narrow_to_utf8<32>
1184 : public codecvt<char32_t, char, mbstate_t>
1185{
1186 _LIBCPP_ALWAYS_INLINE
1187 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1188
1189 ~__narrow_to_utf8();
1190
1191 template <class _OutputIterator, class _CharT>
1192 _LIBCPP_ALWAYS_INLINE
1193 _OutputIterator
1194 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1195 {
1196 result __r = ok;
1197 mbstate_t __mb;
1198 while (__wb < __we && __r != error)
1199 {
1200 const int __sz = 32;
1201 char __buf[__sz];
1202 char* __bn;
1203 const char32_t* __wn = (const char32_t*)__wb;
1204 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1205 __buf, __buf+__sz, __bn);
1206 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1207 __throw_runtime_error("locale not supported");
1208 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1209 *__s = *__p;
1210 __wb = (const _CharT*)__wn;
1211 }
1212 return __s;
1213 }
1214};
1215
1216template <size_t _N>
1217struct __widen_from_utf8
1218{
1219 template <class _OutputIterator>
1220 _OutputIterator
1221 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1222};
1223
1224template <>
1225struct __widen_from_utf8<8>
1226{
1227 template <class _OutputIterator>
1228 _LIBCPP_ALWAYS_INLINE
1229 _OutputIterator
1230 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1231 {
1232 for (; __nb < __ne; ++__nb, ++__s)
1233 *__s = *__nb;
1234 return __s;
1235 }
1236};
1237
1238template <>
1239struct __widen_from_utf8<16>
1240 : public codecvt<char16_t, char, mbstate_t>
1241{
1242 _LIBCPP_ALWAYS_INLINE
1243 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1244
1245 ~__widen_from_utf8();
1246
1247 template <class _OutputIterator>
1248 _LIBCPP_ALWAYS_INLINE
1249 _OutputIterator
1250 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1251 {
1252 result __r = ok;
1253 mbstate_t __mb;
1254 while (__nb < __ne && __r != error)
1255 {
1256 const int __sz = 32;
1257 char16_t __buf[__sz];
1258 char16_t* __bn;
1259 const char* __nn = __nb;
1260 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1261 __buf, __buf+__sz, __bn);
1262 if (__r == codecvt_base::error || __nn == __nb)
1263 __throw_runtime_error("locale not supported");
1264 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1265 *__s = (wchar_t)*__p;
1266 __nb = __nn;
1267 }
1268 return __s;
1269 }
1270};
1271
1272template <>
1273struct __widen_from_utf8<32>
1274 : public codecvt<char32_t, char, mbstate_t>
1275{
1276 _LIBCPP_ALWAYS_INLINE
1277 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1278
1279 ~__widen_from_utf8();
1280
1281 template <class _OutputIterator>
1282 _LIBCPP_ALWAYS_INLINE
1283 _OutputIterator
1284 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1285 {
1286 result __r = ok;
1287 mbstate_t __mb;
1288 while (__nb < __ne && __r != error)
1289 {
1290 const int __sz = 32;
1291 char32_t __buf[__sz];
1292 char32_t* __bn;
1293 const char* __nn = __nb;
1294 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1295 __buf, __buf+__sz, __bn);
1296 if (__r == codecvt_base::error || __nn == __nb)
1297 __throw_runtime_error("locale not supported");
1298 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1299 *__s = (wchar_t)*__p;
1300 __nb = __nn;
1301 }
1302 return __s;
1303 }
1304};
1305
1306// template <class charT> class numpunct
1307
Howard Hinnant9833cad2010-09-21 18:58:51 +00001308template <class _CharT> class _LIBCPP_VISIBLE numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001309
1310template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001311class _LIBCPP_VISIBLE numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001312 : public locale::facet
1313{
1314public:
1315 typedef char char_type;
1316 typedef basic_string<char_type> string_type;
1317
1318 explicit numpunct(size_t __refs = 0);
1319
1320 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1321 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1322 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1323 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1324 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1325
1326 static locale::id id;
1327
1328protected:
1329 ~numpunct();
1330 virtual char_type do_decimal_point() const;
1331 virtual char_type do_thousands_sep() const;
1332 virtual string do_grouping() const;
1333 virtual string_type do_truename() const;
1334 virtual string_type do_falsename() const;
1335
1336 char_type __decimal_point_;
1337 char_type __thousands_sep_;
1338 string __grouping_;
1339};
1340
1341template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001342class _LIBCPP_VISIBLE numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001343 : public locale::facet
1344{
1345public:
1346 typedef wchar_t char_type;
1347 typedef basic_string<char_type> string_type;
1348
1349 explicit numpunct(size_t __refs = 0);
1350
1351 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1352 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1353 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1354 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1355 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1356
1357 static locale::id id;
1358
1359protected:
1360 ~numpunct();
1361 virtual char_type do_decimal_point() const;
1362 virtual char_type do_thousands_sep() const;
1363 virtual string do_grouping() const;
1364 virtual string_type do_truename() const;
1365 virtual string_type do_falsename() const;
1366
1367 char_type __decimal_point_;
1368 char_type __thousands_sep_;
1369 string __grouping_;
1370};
1371
1372// template <class charT> class numpunct_byname
1373
Howard Hinnant9833cad2010-09-21 18:58:51 +00001374template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001375
1376template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001377class _LIBCPP_VISIBLE numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001378: public numpunct<char>
1379{
1380public:
1381 typedef char char_type;
1382 typedef basic_string<char_type> string_type;
1383
1384 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1385 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1386
1387protected:
1388 ~numpunct_byname();
1389
1390private:
1391 void __init(const char*);
1392};
1393
1394template <>
Howard Hinnant9833cad2010-09-21 18:58:51 +00001395class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001396: public numpunct<wchar_t>
1397{
1398public:
1399 typedef wchar_t char_type;
1400 typedef basic_string<char_type> string_type;
1401
1402 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1403 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1404
1405protected:
1406 ~numpunct_byname();
1407
1408private:
1409 void __init(const char*);
1410};
1411
1412_LIBCPP_END_NAMESPACE_STD
1413
1414#endif // _LIBCPP___LOCALE