blob: 3daa1f1b66be8883c34078d6ad8973f2bd9faddc [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 Hinnant8ad70912013-09-17 01:34:47 +000022#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnantae0f80b2011-09-29 20:33:10 +000023# include <support/win32/locale_win32.h>
Marshall Clow2f96ec62014-03-11 17:18:47 +000024#elif defined(_AIX)
Howard Hinnantea382952013-08-14 18:00:20 +000025# include <support/ibm/xlocale.h>
Marshall Clow3477ec92014-07-10 15:20:28 +000026#elif defined(__ANDROID__)
27// Android gained the locale aware functions in L (API level 21)
28# include <android/api-level.h>
29# if __ANDROID_API__ <= 20
30# include <support/android/locale_bionic.h>
31# endif
32#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) \
33 || defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
Howard Hinnantdd0d7022011-09-22 19:10:18 +000034# include <xlocale.h>
Marshall Clow3477ec92014-07-10 15:20:28 +000035#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
Howard Hinnantc51e1022010-05-11 19:42:16 +000036
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000037#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000038#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000039#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000040
41_LIBCPP_BEGIN_NAMESPACE_STD
42
Howard Hinnant8331b762013-03-06 23:30:19 +000043class _LIBCPP_TYPE_VIS locale;
Howard Hinnantc51e1022010-05-11 19:42:16 +000044
Howard Hinnanta54386e2012-09-14 00:39:16 +000045template <class _Facet>
46_LIBCPP_INLINE_VISIBILITY
47bool
48has_facet(const locale&) _NOEXCEPT;
49
50template <class _Facet>
51_LIBCPP_INLINE_VISIBILITY
52const _Facet&
53use_facet(const locale&);
Howard Hinnantc51e1022010-05-11 19:42:16 +000054
Howard Hinnant8331b762013-03-06 23:30:19 +000055class _LIBCPP_TYPE_VIS locale
Howard Hinnantc51e1022010-05-11 19:42:16 +000056{
57public:
58 // types:
Howard Hinnant8331b762013-03-06 23:30:19 +000059 class _LIBCPP_TYPE_VIS facet;
60 class _LIBCPP_TYPE_VIS id;
Howard Hinnantc51e1022010-05-11 19:42:16 +000061
62 typedef int category;
63 static const category // values assigned here are for exposition only
64 none = 0,
65 collate = LC_COLLATE_MASK,
66 ctype = LC_CTYPE_MASK,
67 monetary = LC_MONETARY_MASK,
68 numeric = LC_NUMERIC_MASK,
69 time = LC_TIME_MASK,
70 messages = LC_MESSAGES_MASK,
71 all = collate | ctype | monetary | numeric | time | messages;
72
73 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +000074 locale() _NOEXCEPT;
75 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000076 explicit locale(const char*);
77 explicit locale(const string&);
78 locale(const locale&, const char*, category);
79 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +000080 template <class _Facet>
81 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +000082 locale(const locale&, const locale&, category);
83
Howard Hinnant7c9e5732011-05-31 15:34:58 +000084 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +000085
Howard Hinnant7c9e5732011-05-31 15:34:58 +000086 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +000087
88 template <class _Facet> locale combine(const locale&) const;
89
90 // locale operations:
91 string name() const;
92 bool operator==(const locale&) const;
93 bool operator!=(const locale& __y) const {return !(*this == __y);}
94 template <class _CharT, class _Traits, class _Allocator>
95 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
96 const basic_string<_CharT, _Traits, _Allocator>&) const;
97
98 // global locale objects:
99 static locale global(const locale&);
100 static const locale& classic();
101
102private:
103 class __imp;
104 __imp* __locale_;
105
106 void __install_ctor(const locale&, facet*, long);
107 static locale& __global();
108 bool has_facet(id&) const;
109 const facet* use_facet(id&) const;
110
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000111 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000112 template <class _Facet> friend const _Facet& use_facet(const locale&);
113};
114
Howard Hinnant8331b762013-03-06 23:30:19 +0000115class _LIBCPP_TYPE_VIS locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +0000116 : public __shared_count
117{
118protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000120 explicit facet(size_t __refs = 0)
121 : __shared_count(static_cast<long>(__refs)-1) {}
122
123 virtual ~facet();
124
125// facet(const facet&) = delete; // effectively done in __shared_count
126// void operator=(const facet&) = delete;
127private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000128 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000129};
130
Howard Hinnant8331b762013-03-06 23:30:19 +0000131class _LIBCPP_TYPE_VIS locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000132{
133 once_flag __flag_;
134 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000135
Howard Hinnantc51e1022010-05-11 19:42:16 +0000136 static int32_t __next_id;
137public:
Howard Hinnantac7d9f02012-07-26 16:14:37 +0000138 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000139private:
140 void __init();
141 void operator=(const id&); // = delete;
142 id(const id&); // = delete;
143public: // only needed for tests
144 long __get();
145
146 friend class locale;
147 friend class locale::__imp;
148};
149
150template <class _Facet>
151inline _LIBCPP_INLINE_VISIBILITY
152locale::locale(const locale& __other, _Facet* __f)
153{
154 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
155}
156
157template <class _Facet>
158locale
159locale::combine(const locale& __other) const
160{
Howard Hinnant72f73582010-08-11 17:04:31 +0000161#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000162 if (!_VSTD::has_facet<_Facet>(__other))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000163 throw runtime_error("locale::combine: locale missing facet");
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000164#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000165 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166}
167
168template <class _Facet>
169inline _LIBCPP_INLINE_VISIBILITY
170bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000171has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000172{
173 return __l.has_facet(_Facet::id);
174}
175
176template <class _Facet>
177inline _LIBCPP_INLINE_VISIBILITY
178const _Facet&
179use_facet(const locale& __l)
180{
181 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
182}
183
184// template <class _CharT> class collate;
185
186template <class _CharT>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000187class _LIBCPP_TYPE_VIS_ONLY collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000188 : public locale::facet
189{
190public:
191 typedef _CharT char_type;
192 typedef basic_string<char_type> string_type;
193
Howard Hinnant9833cad2010-09-21 18:58:51 +0000194 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000195 explicit collate(size_t __refs = 0)
196 : locale::facet(__refs) {}
197
Howard Hinnant9833cad2010-09-21 18:58:51 +0000198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000199 int compare(const char_type* __lo1, const char_type* __hi1,
200 const char_type* __lo2, const char_type* __hi2) const
201 {
202 return do_compare(__lo1, __hi1, __lo2, __hi2);
203 }
204
Howard Hinnant9833cad2010-09-21 18:58:51 +0000205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000206 string_type transform(const char_type* __lo, const char_type* __hi) const
207 {
208 return do_transform(__lo, __hi);
209 }
210
Howard Hinnant9833cad2010-09-21 18:58:51 +0000211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000212 long hash(const char_type* __lo, const char_type* __hi) const
213 {
214 return do_hash(__lo, __hi);
215 }
216
217 static locale::id id;
218
219protected:
220 ~collate();
221 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
222 const char_type* __lo2, const char_type* __hi2) const;
223 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
224 {return string_type(__lo, __hi);}
225 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
226};
227
228template <class _CharT> locale::id collate<_CharT>::id;
229
230template <class _CharT>
231collate<_CharT>::~collate()
232{
233}
234
235template <class _CharT>
236int
237collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
238 const char_type* __lo2, const char_type* __hi2) const
239{
240 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
241 {
242 if (__lo1 == __hi1 || *__lo1 < *__lo2)
243 return -1;
244 if (*__lo2 < *__lo1)
245 return 1;
246 }
247 return __lo1 != __hi1;
248}
249
250template <class _CharT>
251long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000252collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000253{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000254 size_t __h = 0;
255 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
256 const size_t __mask = size_t(0xF) << (__sr + 4);
257 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000258 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000259 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000260 size_t __g = __h & __mask;
261 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000263 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264}
265
Howard Hinnant8ea98242013-08-23 17:37:05 +0000266_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
267_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268
269// template <class CharT> class collate_byname;
270
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000271template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000272
273template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000274class _LIBCPP_TYPE_VIS collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000275 : public collate<char>
276{
277 locale_t __l;
278public:
279 typedef char char_type;
280 typedef basic_string<char_type> string_type;
281
282 explicit collate_byname(const char* __n, size_t __refs = 0);
283 explicit collate_byname(const string& __n, size_t __refs = 0);
284
285protected:
286 ~collate_byname();
287 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
288 const char_type* __lo2, const char_type* __hi2) const;
289 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
290};
291
292template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000293class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000294 : public collate<wchar_t>
295{
296 locale_t __l;
297public:
298 typedef wchar_t char_type;
299 typedef basic_string<char_type> string_type;
300
301 explicit collate_byname(const char* __n, size_t __refs = 0);
302 explicit collate_byname(const string& __n, size_t __refs = 0);
303
304protected:
305 ~collate_byname();
306
307 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
308 const char_type* __lo2, const char_type* __hi2) const;
309 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
310};
311
312template <class _CharT, class _Traits, class _Allocator>
313bool
314locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
315 const basic_string<_CharT, _Traits, _Allocator>& __y) const
316{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000317 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000318 __x.data(), __x.data() + __x.size(),
319 __y.data(), __y.data() + __y.size()) < 0;
320}
321
322// template <class charT> class ctype
323
Howard Hinnant8331b762013-03-06 23:30:19 +0000324class _LIBCPP_TYPE_VIS ctype_base
Howard Hinnant9833cad2010-09-21 18:58:51 +0000325{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000326public:
Marshall Clow82378c02013-03-18 19:34:07 +0000327#ifdef __GLIBC__
Alexis Hunt92b0c812011-07-09 00:56:23 +0000328 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000329 static const mask space = _ISspace;
330 static const mask print = _ISprint;
331 static const mask cntrl = _IScntrl;
332 static const mask upper = _ISupper;
333 static const mask lower = _ISlower;
334 static const mask alpha = _ISalpha;
335 static const mask digit = _ISdigit;
336 static const mask punct = _ISpunct;
337 static const mask xdigit = _ISxdigit;
338 static const mask blank = _ISblank;
Marshall Clow1f257322013-03-18 17:04:29 +0000339#elif defined(_WIN32)
Howard Hinnantd7a78632011-09-29 13:33:15 +0000340 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000341 static const mask space = _SPACE;
342 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
343 static const mask cntrl = _CONTROL;
344 static const mask upper = _UPPER;
345 static const mask lower = _LOWER;
346 static const mask alpha = _ALPHA;
347 static const mask digit = _DIGIT;
348 static const mask punct = _PUNCT;
349 static const mask xdigit = _HEX;
350 static const mask blank = _BLANK;
Marshall Clow3477ec92014-07-10 15:20:28 +0000351#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__ANDROID__)
Marshall Clow82378c02013-03-18 19:34:07 +0000352#ifdef __APPLE__
David Chisnall1d581062011-09-21 08:39:44 +0000353 typedef __uint32_t mask;
Marshall Clow82378c02013-03-18 19:34:07 +0000354#elif defined(__FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000355 typedef unsigned long mask;
Marshall Cloweae03f62013-11-19 18:05:03 +0000356#elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
Howard Hinnant942dbd22013-03-29 18:27:28 +0000357 typedef unsigned short mask;
Marshall Clow3477ec92014-07-10 15:20:28 +0000358#elif defined(__ANDROID__)
359 typedef char mask;
David Chisnall1d581062011-09-21 08:39:44 +0000360#endif
361 static const mask space = _CTYPE_S;
362 static const mask print = _CTYPE_R;
363 static const mask cntrl = _CTYPE_C;
364 static const mask upper = _CTYPE_U;
365 static const mask lower = _CTYPE_L;
366 static const mask alpha = _CTYPE_A;
367 static const mask digit = _CTYPE_D;
368 static const mask punct = _CTYPE_P;
369 static const mask xdigit = _CTYPE_X;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000370# if defined(__NetBSD__)
371 static const mask blank = _CTYPE_BL;
372# else
David Chisnall1d581062011-09-21 08:39:44 +0000373 static const mask blank = _CTYPE_B;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000374# endif
Howard Hinnanta47505d2013-08-30 14:42:39 +0000375#elif defined(__sun__) || defined(_AIX)
David Chisnall8074c342012-02-29 13:05:08 +0000376 typedef unsigned int mask;
377 static const mask space = _ISSPACE;
378 static const mask print = _ISPRINT;
379 static const mask cntrl = _ISCNTRL;
380 static const mask upper = _ISUPPER;
381 static const mask lower = _ISLOWER;
382 static const mask alpha = _ISALPHA;
383 static const mask digit = _ISDIGIT;
384 static const mask punct = _ISPUNCT;
385 static const mask xdigit = _ISXDIGIT;
386 static const mask blank = _ISBLANK;
Marshall Cloweae03f62013-11-19 18:05:03 +0000387#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000388 typedef unsigned long mask;
389 static const mask space = 1<<0;
390 static const mask print = 1<<1;
391 static const mask cntrl = 1<<2;
392 static const mask upper = 1<<3;
393 static const mask lower = 1<<4;
394 static const mask alpha = 1<<5;
395 static const mask digit = 1<<6;
396 static const mask punct = 1<<7;
397 static const mask xdigit = 1<<8;
398 static const mask blank = 1<<9;
399#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
Howard Hinnantc51e1022010-05-11 19:42:16 +0000400 static const mask alnum = alpha | digit;
401 static const mask graph = alnum | punct;
402
403 _LIBCPP_ALWAYS_INLINE ctype_base() {}
404};
405
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000406template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407
408template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000409class _LIBCPP_TYPE_VIS ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000410 : public locale::facet,
411 public ctype_base
412{
413public:
414 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000415
Howard Hinnantc51e1022010-05-11 19:42:16 +0000416 _LIBCPP_ALWAYS_INLINE
417 explicit ctype(size_t __refs = 0)
418 : locale::facet(__refs) {}
419
420 _LIBCPP_ALWAYS_INLINE
421 bool is(mask __m, char_type __c) const
422 {
423 return do_is(__m, __c);
424 }
425
426 _LIBCPP_ALWAYS_INLINE
427 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
428 {
429 return do_is(__low, __high, __vec);
430 }
431
432 _LIBCPP_ALWAYS_INLINE
433 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
434 {
435 return do_scan_is(__m, __low, __high);
436 }
437
438 _LIBCPP_ALWAYS_INLINE
439 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
440 {
441 return do_scan_not(__m, __low, __high);
442 }
443
444 _LIBCPP_ALWAYS_INLINE
445 char_type toupper(char_type __c) const
446 {
447 return do_toupper(__c);
448 }
449
450 _LIBCPP_ALWAYS_INLINE
451 const char_type* toupper(char_type* __low, const char_type* __high) const
452 {
453 return do_toupper(__low, __high);
454 }
455
456 _LIBCPP_ALWAYS_INLINE
457 char_type tolower(char_type __c) const
458 {
459 return do_tolower(__c);
460 }
461
462 _LIBCPP_ALWAYS_INLINE
463 const char_type* tolower(char_type* __low, const char_type* __high) const
464 {
465 return do_tolower(__low, __high);
466 }
467
468 _LIBCPP_ALWAYS_INLINE
469 char_type widen(char __c) const
470 {
471 return do_widen(__c);
472 }
473
474 _LIBCPP_ALWAYS_INLINE
475 const char* widen(const char* __low, const char* __high, char_type* __to) const
476 {
477 return do_widen(__low, __high, __to);
478 }
479
480 _LIBCPP_ALWAYS_INLINE
481 char narrow(char_type __c, char __dfault) const
482 {
483 return do_narrow(__c, __dfault);
484 }
485
486 _LIBCPP_ALWAYS_INLINE
487 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
488 {
489 return do_narrow(__low, __high, __dfault, __to);
490 }
491
492 static locale::id id;
493
494protected:
495 ~ctype();
496 virtual bool do_is(mask __m, char_type __c) const;
497 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
498 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
499 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
500 virtual char_type do_toupper(char_type) const;
501 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
502 virtual char_type do_tolower(char_type) const;
503 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
504 virtual char_type do_widen(char) const;
505 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
506 virtual char do_narrow(char_type, char __dfault) const;
507 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
508};
509
510template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000511class _LIBCPP_TYPE_VIS ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000512 : public locale::facet, public ctype_base
513{
514 const mask* __tab_;
515 bool __del_;
516public:
517 typedef char char_type;
518
519 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
520
521 _LIBCPP_ALWAYS_INLINE
522 bool is(mask __m, char_type __c) const
523 {
Marshall Clow11de4872013-10-21 14:41:05 +0000524 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000525 }
526
527 _LIBCPP_ALWAYS_INLINE
528 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
529 {
530 for (; __low != __high; ++__low, ++__vec)
Howard Hinnant28b24882011-12-01 20:21:04 +0000531 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000532 return __low;
533 }
534
535 _LIBCPP_ALWAYS_INLINE
536 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
537 {
538 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000539 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000540 break;
541 return __low;
542 }
543
544 _LIBCPP_ALWAYS_INLINE
545 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
546 {
547 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000548 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000549 break;
550 return __low;
551 }
552
553 _LIBCPP_ALWAYS_INLINE
554 char_type toupper(char_type __c) const
555 {
556 return do_toupper(__c);
557 }
558
559 _LIBCPP_ALWAYS_INLINE
560 const char_type* toupper(char_type* __low, const char_type* __high) const
561 {
562 return do_toupper(__low, __high);
563 }
564
565 _LIBCPP_ALWAYS_INLINE
566 char_type tolower(char_type __c) const
567 {
568 return do_tolower(__c);
569 }
570
571 _LIBCPP_ALWAYS_INLINE
572 const char_type* tolower(char_type* __low, const char_type* __high) const
573 {
574 return do_tolower(__low, __high);
575 }
576
577 _LIBCPP_ALWAYS_INLINE
578 char_type widen(char __c) const
579 {
580 return do_widen(__c);
581 }
582
583 _LIBCPP_ALWAYS_INLINE
584 const char* widen(const char* __low, const char* __high, char_type* __to) const
585 {
586 return do_widen(__low, __high, __to);
587 }
588
589 _LIBCPP_ALWAYS_INLINE
590 char narrow(char_type __c, char __dfault) const
591 {
592 return do_narrow(__c, __dfault);
593 }
594
595 _LIBCPP_ALWAYS_INLINE
596 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
597 {
598 return do_narrow(__low, __high, __dfault, __to);
599 }
600
601 static locale::id id;
602
Howard Hinnant155c2af2010-05-24 17:49:41 +0000603#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000604 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000605#else
606 static const size_t table_size = 256; // FIXME: Don't hardcode this.
607#endif
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000608 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
609 static const mask* classic_table() _NOEXCEPT;
Marshall Cloweae03f62013-11-19 18:05:03 +0000610#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000611 static const int* __classic_upper_table() _NOEXCEPT;
612 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000613#endif
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000614#if defined(__NetBSD__)
615 static const short* __classic_upper_table() _NOEXCEPT;
616 static const short* __classic_lower_table() _NOEXCEPT;
617#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000618
619protected:
620 ~ctype();
621 virtual char_type do_toupper(char_type __c) const;
622 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
623 virtual char_type do_tolower(char_type __c) const;
624 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
625 virtual char_type do_widen(char __c) const;
626 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
627 virtual char do_narrow(char_type __c, char __dfault) const;
628 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
629};
630
631// template <class CharT> class ctype_byname;
632
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000633template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000634
635template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000636class _LIBCPP_TYPE_VIS ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000637 : public ctype<char>
638{
639 locale_t __l;
640
641public:
642 explicit ctype_byname(const char*, size_t = 0);
643 explicit ctype_byname(const string&, size_t = 0);
644
645protected:
646 ~ctype_byname();
647 virtual char_type do_toupper(char_type) const;
648 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
649 virtual char_type do_tolower(char_type) const;
650 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
651};
652
653template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000654class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000655 : public ctype<wchar_t>
656{
657 locale_t __l;
658
659public:
660 explicit ctype_byname(const char*, size_t = 0);
661 explicit ctype_byname(const string&, size_t = 0);
662
663protected:
664 ~ctype_byname();
665 virtual bool do_is(mask __m, char_type __c) const;
666 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
667 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
668 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
669 virtual char_type do_toupper(char_type) const;
670 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
671 virtual char_type do_tolower(char_type) const;
672 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
673 virtual char_type do_widen(char) const;
674 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
675 virtual char do_narrow(char_type, char __dfault) const;
676 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
677};
678
679template <class _CharT>
680inline _LIBCPP_INLINE_VISIBILITY
681bool
682isspace(_CharT __c, const locale& __loc)
683{
684 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
685}
686
687template <class _CharT>
688inline _LIBCPP_INLINE_VISIBILITY
689bool
690isprint(_CharT __c, const locale& __loc)
691{
692 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
693}
694
695template <class _CharT>
696inline _LIBCPP_INLINE_VISIBILITY
697bool
698iscntrl(_CharT __c, const locale& __loc)
699{
700 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
701}
702
703template <class _CharT>
704inline _LIBCPP_INLINE_VISIBILITY
705bool
706isupper(_CharT __c, const locale& __loc)
707{
708 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
709}
710
711template <class _CharT>
712inline _LIBCPP_INLINE_VISIBILITY
713bool
714islower(_CharT __c, const locale& __loc)
715{
716 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
717}
718
719template <class _CharT>
720inline _LIBCPP_INLINE_VISIBILITY
721bool
722isalpha(_CharT __c, const locale& __loc)
723{
724 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
725}
726
727template <class _CharT>
728inline _LIBCPP_INLINE_VISIBILITY
729bool
730isdigit(_CharT __c, const locale& __loc)
731{
732 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
733}
734
735template <class _CharT>
736inline _LIBCPP_INLINE_VISIBILITY
737bool
738ispunct(_CharT __c, const locale& __loc)
739{
740 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
741}
742
743template <class _CharT>
744inline _LIBCPP_INLINE_VISIBILITY
745bool
746isxdigit(_CharT __c, const locale& __loc)
747{
748 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
749}
750
751template <class _CharT>
752inline _LIBCPP_INLINE_VISIBILITY
753bool
754isalnum(_CharT __c, const locale& __loc)
755{
756 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
757}
758
759template <class _CharT>
760inline _LIBCPP_INLINE_VISIBILITY
761bool
762isgraph(_CharT __c, const locale& __loc)
763{
764 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
765}
766
767template <class _CharT>
768inline _LIBCPP_INLINE_VISIBILITY
769_CharT
770toupper(_CharT __c, const locale& __loc)
771{
772 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
773}
774
775template <class _CharT>
776inline _LIBCPP_INLINE_VISIBILITY
777_CharT
778tolower(_CharT __c, const locale& __loc)
779{
780 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
781}
782
783// codecvt_base
784
Howard Hinnant8331b762013-03-06 23:30:19 +0000785class _LIBCPP_TYPE_VIS codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000786{
787public:
788 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
789 enum result {ok, partial, error, noconv};
790};
791
792// template <class internT, class externT, class stateT> class codecvt;
793
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000794template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000795
796// template <> class codecvt<char, char, mbstate_t>
797
798template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000799class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000800 : public locale::facet,
801 public codecvt_base
802{
803public:
804 typedef char intern_type;
805 typedef char extern_type;
806 typedef mbstate_t state_type;
807
808 _LIBCPP_ALWAYS_INLINE
809 explicit codecvt(size_t __refs = 0)
810 : locale::facet(__refs) {}
811
812 _LIBCPP_ALWAYS_INLINE
813 result out(state_type& __st,
814 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
815 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
816 {
817 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
818 }
819
820 _LIBCPP_ALWAYS_INLINE
821 result unshift(state_type& __st,
822 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
823 {
824 return do_unshift(__st, __to, __to_end, __to_nxt);
825 }
826
827 _LIBCPP_ALWAYS_INLINE
828 result in(state_type& __st,
829 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
830 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
831 {
832 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
833 }
834
835 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000836 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000837 {
838 return do_encoding();
839 }
840
841 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000842 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000843 {
844 return do_always_noconv();
845 }
846
847 _LIBCPP_ALWAYS_INLINE
848 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
849 {
850 return do_length(__st, __frm, __end, __mx);
851 }
852
853 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000854 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000855 {
856 return do_max_length();
857 }
858
859 static locale::id id;
860
861protected:
862 _LIBCPP_ALWAYS_INLINE
863 explicit codecvt(const char*, size_t __refs = 0)
864 : locale::facet(__refs) {}
865
866 ~codecvt();
867
868 virtual result do_out(state_type& __st,
869 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
870 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
871 virtual result do_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 virtual result do_unshift(state_type& __st,
875 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000876 virtual int do_encoding() const _NOEXCEPT;
877 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000878 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 +0000879 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000880};
881
882// template <> class codecvt<wchar_t, char, mbstate_t>
883
884template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000885class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000886 : public locale::facet,
887 public codecvt_base
888{
889 locale_t __l;
890public:
891 typedef wchar_t intern_type;
892 typedef char extern_type;
893 typedef mbstate_t state_type;
894
895 explicit codecvt(size_t __refs = 0);
896
897 _LIBCPP_ALWAYS_INLINE
898 result out(state_type& __st,
899 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
900 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
901 {
902 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
903 }
904
905 _LIBCPP_ALWAYS_INLINE
906 result unshift(state_type& __st,
907 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
908 {
909 return do_unshift(__st, __to, __to_end, __to_nxt);
910 }
911
912 _LIBCPP_ALWAYS_INLINE
913 result in(state_type& __st,
914 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
915 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
916 {
917 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
918 }
919
920 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000921 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000922 {
923 return do_encoding();
924 }
925
926 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000927 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000928 {
929 return do_always_noconv();
930 }
931
932 _LIBCPP_ALWAYS_INLINE
933 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
934 {
935 return do_length(__st, __frm, __end, __mx);
936 }
937
938 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000939 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000940 {
941 return do_max_length();
942 }
943
944 static locale::id id;
945
946protected:
947 explicit codecvt(const char*, size_t __refs = 0);
948
949 ~codecvt();
950
951 virtual result do_out(state_type& __st,
952 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
953 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
954 virtual result do_in(state_type& __st,
955 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
956 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
957 virtual result do_unshift(state_type& __st,
958 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000959 virtual int do_encoding() const _NOEXCEPT;
960 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000961 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 +0000962 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000963};
964
965// template <> class codecvt<char16_t, char, mbstate_t>
966
967template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000968class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000969 : public locale::facet,
970 public codecvt_base
971{
972public:
973 typedef char16_t intern_type;
974 typedef char extern_type;
975 typedef mbstate_t state_type;
976
977 _LIBCPP_ALWAYS_INLINE
978 explicit codecvt(size_t __refs = 0)
979 : locale::facet(__refs) {}
980
981 _LIBCPP_ALWAYS_INLINE
982 result out(state_type& __st,
983 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
984 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
985 {
986 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
987 }
988
989 _LIBCPP_ALWAYS_INLINE
990 result unshift(state_type& __st,
991 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
992 {
993 return do_unshift(__st, __to, __to_end, __to_nxt);
994 }
995
996 _LIBCPP_ALWAYS_INLINE
997 result in(state_type& __st,
998 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
999 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1000 {
1001 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1002 }
1003
1004 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001005 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001006 {
1007 return do_encoding();
1008 }
1009
1010 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001011 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001012 {
1013 return do_always_noconv();
1014 }
1015
1016 _LIBCPP_ALWAYS_INLINE
1017 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1018 {
1019 return do_length(__st, __frm, __end, __mx);
1020 }
1021
1022 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001023 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001024 {
1025 return do_max_length();
1026 }
1027
1028 static locale::id id;
1029
1030protected:
1031 _LIBCPP_ALWAYS_INLINE
1032 explicit codecvt(const char*, size_t __refs = 0)
1033 : locale::facet(__refs) {}
1034
1035 ~codecvt();
1036
1037 virtual result do_out(state_type& __st,
1038 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1039 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1040 virtual result do_in(state_type& __st,
1041 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1042 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1043 virtual result do_unshift(state_type& __st,
1044 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001045 virtual int do_encoding() const _NOEXCEPT;
1046 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001047 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 +00001048 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001049};
1050
1051// template <> class codecvt<char32_t, char, mbstate_t>
1052
1053template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001054class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001055 : public locale::facet,
1056 public codecvt_base
1057{
1058public:
1059 typedef char32_t intern_type;
1060 typedef char extern_type;
1061 typedef mbstate_t state_type;
1062
1063 _LIBCPP_ALWAYS_INLINE
1064 explicit codecvt(size_t __refs = 0)
1065 : locale::facet(__refs) {}
1066
1067 _LIBCPP_ALWAYS_INLINE
1068 result out(state_type& __st,
1069 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1070 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1071 {
1072 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1073 }
1074
1075 _LIBCPP_ALWAYS_INLINE
1076 result unshift(state_type& __st,
1077 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1078 {
1079 return do_unshift(__st, __to, __to_end, __to_nxt);
1080 }
1081
1082 _LIBCPP_ALWAYS_INLINE
1083 result in(state_type& __st,
1084 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1085 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1086 {
1087 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1088 }
1089
1090 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001091 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001092 {
1093 return do_encoding();
1094 }
1095
1096 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001097 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001098 {
1099 return do_always_noconv();
1100 }
1101
1102 _LIBCPP_ALWAYS_INLINE
1103 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1104 {
1105 return do_length(__st, __frm, __end, __mx);
1106 }
1107
1108 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001109 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001110 {
1111 return do_max_length();
1112 }
1113
1114 static locale::id id;
1115
1116protected:
1117 _LIBCPP_ALWAYS_INLINE
1118 explicit codecvt(const char*, size_t __refs = 0)
1119 : locale::facet(__refs) {}
1120
1121 ~codecvt();
1122
1123 virtual result do_out(state_type& __st,
1124 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1125 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1126 virtual result do_in(state_type& __st,
1127 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1128 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1129 virtual result do_unshift(state_type& __st,
1130 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001131 virtual int do_encoding() const _NOEXCEPT;
1132 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001133 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 +00001134 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001135};
1136
Howard Hinnantc51e1022010-05-11 19:42:16 +00001137// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1138
1139template <class _InternT, class _ExternT, class _StateT>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001140class _LIBCPP_TYPE_VIS_ONLY codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001141 : public codecvt<_InternT, _ExternT, _StateT>
1142{
1143public:
Howard Hinnant9833cad2010-09-21 18:58:51 +00001144 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001145 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1146 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant9833cad2010-09-21 18:58:51 +00001147 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001148 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1149 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1150protected:
1151 ~codecvt_byname();
1152};
1153
1154template <class _InternT, class _ExternT, class _StateT>
1155codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1156{
1157}
1158
Howard Hinnant8ea98242013-08-23 17:37:05 +00001159_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1160_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1161_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1162_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001163
Howard Hinnant8331b762013-03-06 23:30:19 +00001164_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001165
Howard Hinnantc834c512011-11-29 18:15:50 +00001166template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001167struct __narrow_to_utf8
1168{
1169 template <class _OutputIterator, class _CharT>
1170 _OutputIterator
1171 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1172};
1173
1174template <>
1175struct __narrow_to_utf8<8>
1176{
1177 template <class _OutputIterator, class _CharT>
1178 _LIBCPP_ALWAYS_INLINE
1179 _OutputIterator
1180 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1181 {
1182 for (; __wb < __we; ++__wb, ++__s)
1183 *__s = *__wb;
1184 return __s;
1185 }
1186};
1187
1188template <>
1189struct __narrow_to_utf8<16>
1190 : public codecvt<char16_t, char, mbstate_t>
1191{
1192 _LIBCPP_ALWAYS_INLINE
1193 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1194
1195 ~__narrow_to_utf8();
1196
1197 template <class _OutputIterator, class _CharT>
1198 _LIBCPP_ALWAYS_INLINE
1199 _OutputIterator
1200 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1201 {
1202 result __r = ok;
1203 mbstate_t __mb;
1204 while (__wb < __we && __r != error)
1205 {
1206 const int __sz = 32;
1207 char __buf[__sz];
1208 char* __bn;
1209 const char16_t* __wn = (const char16_t*)__wb;
1210 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1211 __buf, __buf+__sz, __bn);
1212 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1213 __throw_runtime_error("locale not supported");
1214 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1215 *__s = *__p;
1216 __wb = (const _CharT*)__wn;
1217 }
1218 return __s;
1219 }
1220};
1221
1222template <>
1223struct __narrow_to_utf8<32>
1224 : public codecvt<char32_t, char, mbstate_t>
1225{
1226 _LIBCPP_ALWAYS_INLINE
1227 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1228
1229 ~__narrow_to_utf8();
1230
1231 template <class _OutputIterator, class _CharT>
1232 _LIBCPP_ALWAYS_INLINE
1233 _OutputIterator
1234 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1235 {
1236 result __r = ok;
1237 mbstate_t __mb;
1238 while (__wb < __we && __r != error)
1239 {
1240 const int __sz = 32;
1241 char __buf[__sz];
1242 char* __bn;
1243 const char32_t* __wn = (const char32_t*)__wb;
1244 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1245 __buf, __buf+__sz, __bn);
1246 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1247 __throw_runtime_error("locale not supported");
1248 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1249 *__s = *__p;
1250 __wb = (const _CharT*)__wn;
1251 }
1252 return __s;
1253 }
1254};
1255
Howard Hinnantc834c512011-11-29 18:15:50 +00001256template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001257struct __widen_from_utf8
1258{
1259 template <class _OutputIterator>
1260 _OutputIterator
1261 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1262};
1263
1264template <>
1265struct __widen_from_utf8<8>
1266{
1267 template <class _OutputIterator>
1268 _LIBCPP_ALWAYS_INLINE
1269 _OutputIterator
1270 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1271 {
1272 for (; __nb < __ne; ++__nb, ++__s)
1273 *__s = *__nb;
1274 return __s;
1275 }
1276};
1277
1278template <>
1279struct __widen_from_utf8<16>
1280 : public codecvt<char16_t, char, mbstate_t>
1281{
1282 _LIBCPP_ALWAYS_INLINE
1283 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1284
1285 ~__widen_from_utf8();
1286
1287 template <class _OutputIterator>
1288 _LIBCPP_ALWAYS_INLINE
1289 _OutputIterator
1290 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1291 {
1292 result __r = ok;
1293 mbstate_t __mb;
1294 while (__nb < __ne && __r != error)
1295 {
1296 const int __sz = 32;
1297 char16_t __buf[__sz];
1298 char16_t* __bn;
1299 const char* __nn = __nb;
1300 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1301 __buf, __buf+__sz, __bn);
1302 if (__r == codecvt_base::error || __nn == __nb)
1303 __throw_runtime_error("locale not supported");
1304 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1305 *__s = (wchar_t)*__p;
1306 __nb = __nn;
1307 }
1308 return __s;
1309 }
1310};
1311
1312template <>
1313struct __widen_from_utf8<32>
1314 : public codecvt<char32_t, char, mbstate_t>
1315{
1316 _LIBCPP_ALWAYS_INLINE
1317 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1318
1319 ~__widen_from_utf8();
1320
1321 template <class _OutputIterator>
1322 _LIBCPP_ALWAYS_INLINE
1323 _OutputIterator
1324 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1325 {
1326 result __r = ok;
1327 mbstate_t __mb;
1328 while (__nb < __ne && __r != error)
1329 {
1330 const int __sz = 32;
1331 char32_t __buf[__sz];
1332 char32_t* __bn;
1333 const char* __nn = __nb;
1334 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1335 __buf, __buf+__sz, __bn);
1336 if (__r == codecvt_base::error || __nn == __nb)
1337 __throw_runtime_error("locale not supported");
1338 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1339 *__s = (wchar_t)*__p;
1340 __nb = __nn;
1341 }
1342 return __s;
1343 }
1344};
1345
1346// template <class charT> class numpunct
1347
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001348template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001349
1350template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001351class _LIBCPP_TYPE_VIS numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001352 : public locale::facet
1353{
1354public:
1355 typedef char char_type;
1356 typedef basic_string<char_type> string_type;
1357
1358 explicit numpunct(size_t __refs = 0);
1359
1360 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1361 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1362 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1363 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1364 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1365
1366 static locale::id id;
1367
1368protected:
1369 ~numpunct();
1370 virtual char_type do_decimal_point() const;
1371 virtual char_type do_thousands_sep() const;
1372 virtual string do_grouping() const;
1373 virtual string_type do_truename() const;
1374 virtual string_type do_falsename() const;
1375
1376 char_type __decimal_point_;
1377 char_type __thousands_sep_;
1378 string __grouping_;
1379};
1380
1381template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001382class _LIBCPP_TYPE_VIS numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001383 : public locale::facet
1384{
1385public:
1386 typedef wchar_t char_type;
1387 typedef basic_string<char_type> string_type;
1388
1389 explicit numpunct(size_t __refs = 0);
1390
1391 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1392 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1393 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1394 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1395 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1396
1397 static locale::id id;
1398
1399protected:
1400 ~numpunct();
1401 virtual char_type do_decimal_point() const;
1402 virtual char_type do_thousands_sep() const;
1403 virtual string do_grouping() const;
1404 virtual string_type do_truename() const;
1405 virtual string_type do_falsename() const;
1406
1407 char_type __decimal_point_;
1408 char_type __thousands_sep_;
1409 string __grouping_;
1410};
1411
1412// template <class charT> class numpunct_byname
1413
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001414template <class charT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001415
1416template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001417class _LIBCPP_TYPE_VIS numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001418: public numpunct<char>
1419{
1420public:
1421 typedef char char_type;
1422 typedef basic_string<char_type> string_type;
1423
1424 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1425 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1426
1427protected:
1428 ~numpunct_byname();
1429
1430private:
1431 void __init(const char*);
1432};
1433
1434template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001435class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001436: public numpunct<wchar_t>
1437{
1438public:
1439 typedef wchar_t char_type;
1440 typedef basic_string<char_type> string_type;
1441
1442 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1443 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1444
1445protected:
1446 ~numpunct_byname();
1447
1448private:
1449 void __init(const char*);
1450};
1451
1452_LIBCPP_END_NAMESPACE_STD
1453
1454#endif // _LIBCPP___LOCALE