blob: 601f0d1ec32513eaa497b549d10c18ac82c371d2 [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>
Eric Fiselierbb999f92017-05-31 22:14:05 +000022#if defined(_LIBCPP_MSVCRT_LIKE)
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
Eric Fiselier7274c652014-11-25 21:57:41 +000032#elif defined(__sun__)
Eric Fiselier90adc202015-01-23 22:22:36 +000033# include <xlocale.h>
Eric Fiselier7274c652014-11-25 21:57:41 +000034# include <support/solaris/xlocale.h>
Sergey Dmitrouk9935bd42014-12-12 08:36:16 +000035#elif defined(_NEWLIB_VERSION)
36# include <support/newlib/xlocale.h>
Eric Fiseliercee57932017-08-03 04:28:10 +000037#elif (defined(__APPLE__) || defined(__FreeBSD__) \
Eric Fiselier7274c652014-11-25 21:57:41 +000038 || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
Howard Hinnantdd0d7022011-09-22 19:10:18 +000039# include <xlocale.h>
Petr Hosekfdb4a872017-04-13 21:29:21 +000040#elif defined(__Fuchsia__)
41# include <support/fuchsia/xlocale.h>
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +000042#elif defined(_LIBCPP_HAS_MUSL_LIBC)
43# include <support/musl/xlocale.h>
Petr Hosekfdb4a872017-04-13 21:29:21 +000044#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000045
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000046#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +000047#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +000048#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +000049
50_LIBCPP_BEGIN_NAMESPACE_STD
51
Martin Storsjo5482ac62017-11-23 10:38:18 +000052#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
Eric Fiselierebc2d2c2017-05-08 22:02:43 +000053struct __libcpp_locale_guard {
54 _LIBCPP_INLINE_VISIBILITY
55 __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
56
57 _LIBCPP_INLINE_VISIBILITY
58 ~__libcpp_locale_guard() {
59 if (__old_loc_)
60 uselocale(__old_loc_);
61 }
62
63 locale_t __old_loc_;
64private:
65 __libcpp_locale_guard(__libcpp_locale_guard const&);
66 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
67};
Martin Storsjo5482ac62017-11-23 10:38:18 +000068#elif defined(_LIBCPP_MSVCRT_LIKE)
69struct __libcpp_locale_guard {
70 __libcpp_locale_guard(locale_t __l) :
71 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)),
72 __locale_collate(setlocale(LC_COLLATE, __l.__get_locale())),
73 __locale_ctype(setlocale(LC_CTYPE, __l.__get_locale())),
74 __locale_monetary(setlocale(LC_MONETARY, __l.__get_locale())),
75 __locale_numeric(setlocale(LC_NUMERIC, __l.__get_locale())),
76 __locale_time(setlocale(LC_TIME, __l.__get_locale()))
77 // LC_MESSAGES is not supported on Windows.
78 {}
79 ~__libcpp_locale_guard() {
80 setlocale(LC_COLLATE, __locale_collate);
81 setlocale(LC_CTYPE, __locale_ctype);
82 setlocale(LC_MONETARY, __locale_monetary);
83 setlocale(LC_NUMERIC, __locale_numeric);
84 setlocale(LC_TIME, __locale_time);
85 _configthreadlocale(__status);
86 }
87 int __status;
88 char* __locale_collate;
89 char* __locale_ctype;
90 char* __locale_monetary;
91 char* __locale_numeric;
92 char* __locale_time;
93};
Eric Fiselierebc2d2c2017-05-08 22:02:43 +000094#endif
95
96
Howard Hinnant8331b762013-03-06 23:30:19 +000097class _LIBCPP_TYPE_VIS locale;
Howard Hinnantc51e1022010-05-11 19:42:16 +000098
Howard Hinnanta54386e2012-09-14 00:39:16 +000099template <class _Facet>
100_LIBCPP_INLINE_VISIBILITY
101bool
102has_facet(const locale&) _NOEXCEPT;
103
104template <class _Facet>
105_LIBCPP_INLINE_VISIBILITY
106const _Facet&
107use_facet(const locale&);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000108
Howard Hinnant8331b762013-03-06 23:30:19 +0000109class _LIBCPP_TYPE_VIS locale
Howard Hinnantc51e1022010-05-11 19:42:16 +0000110{
111public:
112 // types:
Howard Hinnant8331b762013-03-06 23:30:19 +0000113 class _LIBCPP_TYPE_VIS facet;
114 class _LIBCPP_TYPE_VIS id;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000115
116 typedef int category;
Mehdi Amini228053d2017-05-04 17:08:54 +0000117 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000118 static const category // values assigned here are for exposition only
119 none = 0,
120 collate = LC_COLLATE_MASK,
121 ctype = LC_CTYPE_MASK,
122 monetary = LC_MONETARY_MASK,
123 numeric = LC_NUMERIC_MASK,
124 time = LC_TIME_MASK,
125 messages = LC_MESSAGES_MASK,
126 all = collate | ctype | monetary | numeric | time | messages;
127
128 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000129 locale() _NOEXCEPT;
130 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000131 explicit locale(const char*);
132 explicit locale(const string&);
133 locale(const locale&, const char*, category);
134 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +0000135 template <class _Facet>
136 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000137 locale(const locale&, const locale&, category);
138
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000139 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000140
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000141 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000142
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000143 template <class _Facet>
144 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
145 locale combine(const locale&) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000146
147 // locale operations:
148 string name() const;
149 bool operator==(const locale&) const;
150 bool operator!=(const locale& __y) const {return !(*this == __y);}
151 template <class _CharT, class _Traits, class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000152 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000153 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
154 const basic_string<_CharT, _Traits, _Allocator>&) const;
155
156 // global locale objects:
157 static locale global(const locale&);
158 static const locale& classic();
159
160private:
161 class __imp;
162 __imp* __locale_;
163
164 void __install_ctor(const locale&, facet*, long);
165 static locale& __global();
166 bool has_facet(id&) const;
167 const facet* use_facet(id&) const;
168
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000169 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000170 template <class _Facet> friend const _Facet& use_facet(const locale&);
171};
172
Howard Hinnant8331b762013-03-06 23:30:19 +0000173class _LIBCPP_TYPE_VIS locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +0000174 : public __shared_count
175{
176protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000177 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000178 explicit facet(size_t __refs = 0)
179 : __shared_count(static_cast<long>(__refs)-1) {}
180
181 virtual ~facet();
182
183// facet(const facet&) = delete; // effectively done in __shared_count
184// void operator=(const facet&) = delete;
185private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000186 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187};
188
Howard Hinnant8331b762013-03-06 23:30:19 +0000189class _LIBCPP_TYPE_VIS locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000190{
191 once_flag __flag_;
192 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000193
Howard Hinnantc51e1022010-05-11 19:42:16 +0000194 static int32_t __next_id;
195public:
Howard Hinnantac7d9f02012-07-26 16:14:37 +0000196 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000197private:
198 void __init();
199 void operator=(const id&); // = delete;
200 id(const id&); // = delete;
201public: // only needed for tests
202 long __get();
203
204 friend class locale;
205 friend class locale::__imp;
206};
207
208template <class _Facet>
209inline _LIBCPP_INLINE_VISIBILITY
210locale::locale(const locale& __other, _Facet* __f)
211{
212 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
213}
214
215template <class _Facet>
216locale
217locale::combine(const locale& __other) const
218{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000219 if (!_VSTD::has_facet<_Facet>(__other))
Marshall Clow8fea1612016-08-25 15:09:01 +0000220 __throw_runtime_error("locale::combine: locale missing facet");
221
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000222 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000223}
224
225template <class _Facet>
226inline _LIBCPP_INLINE_VISIBILITY
227bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000228has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000229{
230 return __l.has_facet(_Facet::id);
231}
232
233template <class _Facet>
234inline _LIBCPP_INLINE_VISIBILITY
235const _Facet&
236use_facet(const locale& __l)
237{
238 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
239}
240
241// template <class _CharT> class collate;
242
243template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000244class _LIBCPP_TEMPLATE_VIS collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000245 : public locale::facet
246{
247public:
248 typedef _CharT char_type;
249 typedef basic_string<char_type> string_type;
250
Howard Hinnant9833cad2010-09-21 18:58:51 +0000251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000252 explicit collate(size_t __refs = 0)
253 : locale::facet(__refs) {}
254
Howard Hinnant9833cad2010-09-21 18:58:51 +0000255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000256 int compare(const char_type* __lo1, const char_type* __hi1,
257 const char_type* __lo2, const char_type* __hi2) const
258 {
259 return do_compare(__lo1, __hi1, __lo2, __hi2);
260 }
261
Howard Hinnant9833cad2010-09-21 18:58:51 +0000262 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000263 string_type transform(const char_type* __lo, const char_type* __hi) const
264 {
265 return do_transform(__lo, __hi);
266 }
267
Howard Hinnant9833cad2010-09-21 18:58:51 +0000268 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000269 long hash(const char_type* __lo, const char_type* __hi) const
270 {
271 return do_hash(__lo, __hi);
272 }
273
274 static locale::id id;
275
276protected:
277 ~collate();
278 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
279 const char_type* __lo2, const char_type* __hi2) const;
280 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
281 {return string_type(__lo, __hi);}
282 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
283};
284
285template <class _CharT> locale::id collate<_CharT>::id;
286
287template <class _CharT>
288collate<_CharT>::~collate()
289{
290}
291
292template <class _CharT>
293int
294collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
295 const char_type* __lo2, const char_type* __hi2) const
296{
297 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
298 {
299 if (__lo1 == __hi1 || *__lo1 < *__lo2)
300 return -1;
301 if (*__lo2 < *__lo1)
302 return 1;
303 }
304 return __lo1 != __hi1;
305}
306
307template <class _CharT>
308long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000309collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000311 size_t __h = 0;
312 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
313 const size_t __mask = size_t(0xF) << (__sr + 4);
314 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000315 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000316 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000317 size_t __g = __h & __mask;
318 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000320 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000321}
322
Eric Fiselier1b57fa82016-09-15 22:27:07 +0000323_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
324_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325
326// template <class CharT> class collate_byname;
327
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000328template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329
330template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000331class _LIBCPP_TYPE_VIS collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332 : public collate<char>
333{
334 locale_t __l;
335public:
336 typedef char char_type;
337 typedef basic_string<char_type> string_type;
338
339 explicit collate_byname(const char* __n, size_t __refs = 0);
340 explicit collate_byname(const string& __n, size_t __refs = 0);
341
342protected:
343 ~collate_byname();
344 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
345 const char_type* __lo2, const char_type* __hi2) const;
346 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
347};
348
349template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000350class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000351 : public collate<wchar_t>
352{
353 locale_t __l;
354public:
355 typedef wchar_t char_type;
356 typedef basic_string<char_type> string_type;
357
358 explicit collate_byname(const char* __n, size_t __refs = 0);
359 explicit collate_byname(const string& __n, size_t __refs = 0);
360
361protected:
362 ~collate_byname();
363
364 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
365 const char_type* __lo2, const char_type* __hi2) const;
366 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
367};
368
369template <class _CharT, class _Traits, class _Allocator>
370bool
371locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
372 const basic_string<_CharT, _Traits, _Allocator>& __y) const
373{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000374 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000375 __x.data(), __x.data() + __x.size(),
376 __y.data(), __y.data() + __y.size()) < 0;
377}
378
379// template <class charT> class ctype
380
Howard Hinnant8331b762013-03-06 23:30:19 +0000381class _LIBCPP_TYPE_VIS ctype_base
Howard Hinnant9833cad2010-09-21 18:58:51 +0000382{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000383public:
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +0000384#if defined(__GLIBC__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000385 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000386 static const mask space = _ISspace;
387 static const mask print = _ISprint;
388 static const mask cntrl = _IScntrl;
389 static const mask upper = _ISupper;
390 static const mask lower = _ISlower;
391 static const mask alpha = _ISalpha;
392 static const mask digit = _ISdigit;
393 static const mask punct = _ISpunct;
394 static const mask xdigit = _ISxdigit;
395 static const mask blank = _ISblank;
Eric Fiselierbb999f92017-05-31 22:14:05 +0000396#elif defined(_LIBCPP_MSVCRT_LIKE)
Howard Hinnantd7a78632011-09-29 13:33:15 +0000397 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000398 static const mask space = _SPACE;
399 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
400 static const mask cntrl = _CONTROL;
401 static const mask upper = _UPPER;
402 static const mask lower = _LOWER;
403 static const mask alpha = _ALPHA;
404 static const mask digit = _DIGIT;
405 static const mask punct = _PUNCT;
406 static const mask xdigit = _HEX;
407 static const mask blank = _BLANK;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000408# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
Dan Albertebdf28b2015-03-11 00:51:06 +0000409#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
JF Bastien0c265d82015-02-25 22:16:46 +0000410# ifdef __APPLE__
David Chisnall1d581062011-09-21 08:39:44 +0000411 typedef __uint32_t mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000412# elif defined(__FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000413 typedef unsigned long mask;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000414# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
Howard Hinnant942dbd22013-03-29 18:27:28 +0000415 typedef unsigned short mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000416# endif
David Chisnall1d581062011-09-21 08:39:44 +0000417 static const mask space = _CTYPE_S;
418 static const mask print = _CTYPE_R;
419 static const mask cntrl = _CTYPE_C;
420 static const mask upper = _CTYPE_U;
421 static const mask lower = _CTYPE_L;
422 static const mask alpha = _CTYPE_A;
423 static const mask digit = _CTYPE_D;
424 static const mask punct = _CTYPE_P;
425 static const mask xdigit = _CTYPE_X;
Dan Albert2dca4072014-07-23 19:32:03 +0000426
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000427# if defined(__NetBSD__)
428 static const mask blank = _CTYPE_BL;
429# else
David Chisnall1d581062011-09-21 08:39:44 +0000430 static const mask blank = _CTYPE_B;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000431# endif
Howard Hinnanta47505d2013-08-30 14:42:39 +0000432#elif defined(__sun__) || defined(_AIX)
David Chisnall8074c342012-02-29 13:05:08 +0000433 typedef unsigned int mask;
434 static const mask space = _ISSPACE;
435 static const mask print = _ISPRINT;
436 static const mask cntrl = _ISCNTRL;
437 static const mask upper = _ISUPPER;
438 static const mask lower = _ISLOWER;
439 static const mask alpha = _ISALPHA;
440 static const mask digit = _ISDIGIT;
441 static const mask punct = _ISPUNCT;
442 static const mask xdigit = _ISXDIGIT;
443 static const mask blank = _ISBLANK;
JF Bastien0c265d82015-02-25 22:16:46 +0000444#elif defined(_NEWLIB_VERSION)
445 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
446 typedef char mask;
447 static const mask space = _S;
448 static const mask print = _P | _U | _L | _N | _B;
449 static const mask cntrl = _C;
450 static const mask upper = _U;
451 static const mask lower = _L;
452 static const mask alpha = _U | _L;
453 static const mask digit = _N;
454 static const mask punct = _P;
455 static const mask xdigit = _X | _N;
456 static const mask blank = _B;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000457# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
458# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
459# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
JF Bastien0c265d82015-02-25 22:16:46 +0000460#else
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000461 typedef unsigned long mask;
462 static const mask space = 1<<0;
463 static const mask print = 1<<1;
464 static const mask cntrl = 1<<2;
465 static const mask upper = 1<<3;
466 static const mask lower = 1<<4;
467 static const mask alpha = 1<<5;
468 static const mask digit = 1<<6;
469 static const mask punct = 1<<7;
470 static const mask xdigit = 1<<8;
471 static const mask blank = 1<<9;
JF Bastien0c265d82015-02-25 22:16:46 +0000472#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000473 static const mask alnum = alpha | digit;
474 static const mask graph = alnum | punct;
475
476 _LIBCPP_ALWAYS_INLINE ctype_base() {}
477};
478
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000479template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000480
481template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000482class _LIBCPP_TYPE_VIS ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000483 : public locale::facet,
484 public ctype_base
485{
486public:
487 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000488
Howard Hinnantc51e1022010-05-11 19:42:16 +0000489 _LIBCPP_ALWAYS_INLINE
490 explicit ctype(size_t __refs = 0)
491 : locale::facet(__refs) {}
492
493 _LIBCPP_ALWAYS_INLINE
494 bool is(mask __m, char_type __c) const
495 {
496 return do_is(__m, __c);
497 }
498
499 _LIBCPP_ALWAYS_INLINE
500 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
501 {
502 return do_is(__low, __high, __vec);
503 }
504
505 _LIBCPP_ALWAYS_INLINE
506 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
507 {
508 return do_scan_is(__m, __low, __high);
509 }
510
511 _LIBCPP_ALWAYS_INLINE
512 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
513 {
514 return do_scan_not(__m, __low, __high);
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_type* 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
567protected:
568 ~ctype();
569 virtual bool do_is(mask __m, char_type __c) const;
570 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
571 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
572 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
573 virtual char_type do_toupper(char_type) const;
574 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
575 virtual char_type do_tolower(char_type) const;
576 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
577 virtual char_type do_widen(char) const;
578 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
579 virtual char do_narrow(char_type, char __dfault) const;
580 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
581};
582
583template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000584class _LIBCPP_TYPE_VIS ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000585 : public locale::facet, public ctype_base
586{
587 const mask* __tab_;
588 bool __del_;
589public:
590 typedef char char_type;
591
592 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
593
594 _LIBCPP_ALWAYS_INLINE
595 bool is(mask __m, char_type __c) const
596 {
Marshall Clow11de4872013-10-21 14:41:05 +0000597 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000598 }
599
600 _LIBCPP_ALWAYS_INLINE
601 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
602 {
603 for (; __low != __high; ++__low, ++__vec)
Howard Hinnant28b24882011-12-01 20:21:04 +0000604 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000605 return __low;
606 }
607
608 _LIBCPP_ALWAYS_INLINE
609 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
610 {
611 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000612 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000613 break;
614 return __low;
615 }
616
617 _LIBCPP_ALWAYS_INLINE
618 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
619 {
620 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000621 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000622 break;
623 return __low;
624 }
625
626 _LIBCPP_ALWAYS_INLINE
627 char_type toupper(char_type __c) const
628 {
629 return do_toupper(__c);
630 }
631
632 _LIBCPP_ALWAYS_INLINE
633 const char_type* toupper(char_type* __low, const char_type* __high) const
634 {
635 return do_toupper(__low, __high);
636 }
637
638 _LIBCPP_ALWAYS_INLINE
639 char_type tolower(char_type __c) const
640 {
641 return do_tolower(__c);
642 }
643
644 _LIBCPP_ALWAYS_INLINE
645 const char_type* tolower(char_type* __low, const char_type* __high) const
646 {
647 return do_tolower(__low, __high);
648 }
649
650 _LIBCPP_ALWAYS_INLINE
651 char_type widen(char __c) const
652 {
653 return do_widen(__c);
654 }
655
656 _LIBCPP_ALWAYS_INLINE
657 const char* widen(const char* __low, const char* __high, char_type* __to) const
658 {
659 return do_widen(__low, __high, __to);
660 }
661
662 _LIBCPP_ALWAYS_INLINE
663 char narrow(char_type __c, char __dfault) const
664 {
665 return do_narrow(__c, __dfault);
666 }
667
668 _LIBCPP_ALWAYS_INLINE
669 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
670 {
671 return do_narrow(__low, __high, __dfault, __to);
672 }
673
674 static locale::id id;
675
Howard Hinnant155c2af2010-05-24 17:49:41 +0000676#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000677 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000678#else
679 static const size_t table_size = 256; // FIXME: Don't hardcode this.
680#endif
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000681 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
682 static const mask* classic_table() _NOEXCEPT;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000683#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000684 static const int* __classic_upper_table() _NOEXCEPT;
685 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000686#endif
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000687#if defined(__NetBSD__)
688 static const short* __classic_upper_table() _NOEXCEPT;
689 static const short* __classic_lower_table() _NOEXCEPT;
690#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000691
692protected:
693 ~ctype();
694 virtual char_type do_toupper(char_type __c) const;
695 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
696 virtual char_type do_tolower(char_type __c) const;
697 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
698 virtual char_type do_widen(char __c) const;
699 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
700 virtual char do_narrow(char_type __c, char __dfault) const;
701 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
702};
703
704// template <class CharT> class ctype_byname;
705
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000706template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000707
708template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000709class _LIBCPP_TYPE_VIS ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000710 : public ctype<char>
711{
712 locale_t __l;
713
714public:
715 explicit ctype_byname(const char*, size_t = 0);
716 explicit ctype_byname(const string&, size_t = 0);
717
718protected:
719 ~ctype_byname();
720 virtual char_type do_toupper(char_type) const;
721 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
722 virtual char_type do_tolower(char_type) const;
723 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
724};
725
726template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000727class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000728 : public ctype<wchar_t>
729{
730 locale_t __l;
731
732public:
733 explicit ctype_byname(const char*, size_t = 0);
734 explicit ctype_byname(const string&, size_t = 0);
735
736protected:
737 ~ctype_byname();
738 virtual bool do_is(mask __m, char_type __c) const;
739 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
740 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
741 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
742 virtual char_type do_toupper(char_type) const;
743 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
744 virtual char_type do_tolower(char_type) const;
745 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
746 virtual char_type do_widen(char) const;
747 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
748 virtual char do_narrow(char_type, char __dfault) const;
749 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
750};
751
752template <class _CharT>
753inline _LIBCPP_INLINE_VISIBILITY
754bool
755isspace(_CharT __c, const locale& __loc)
756{
757 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
758}
759
760template <class _CharT>
761inline _LIBCPP_INLINE_VISIBILITY
762bool
763isprint(_CharT __c, const locale& __loc)
764{
765 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
766}
767
768template <class _CharT>
769inline _LIBCPP_INLINE_VISIBILITY
770bool
771iscntrl(_CharT __c, const locale& __loc)
772{
773 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
774}
775
776template <class _CharT>
777inline _LIBCPP_INLINE_VISIBILITY
778bool
779isupper(_CharT __c, const locale& __loc)
780{
781 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
782}
783
784template <class _CharT>
785inline _LIBCPP_INLINE_VISIBILITY
786bool
787islower(_CharT __c, const locale& __loc)
788{
789 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
790}
791
792template <class _CharT>
793inline _LIBCPP_INLINE_VISIBILITY
794bool
795isalpha(_CharT __c, const locale& __loc)
796{
797 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
798}
799
800template <class _CharT>
801inline _LIBCPP_INLINE_VISIBILITY
802bool
803isdigit(_CharT __c, const locale& __loc)
804{
805 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
806}
807
808template <class _CharT>
809inline _LIBCPP_INLINE_VISIBILITY
810bool
811ispunct(_CharT __c, const locale& __loc)
812{
813 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
814}
815
816template <class _CharT>
817inline _LIBCPP_INLINE_VISIBILITY
818bool
819isxdigit(_CharT __c, const locale& __loc)
820{
821 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
822}
823
824template <class _CharT>
825inline _LIBCPP_INLINE_VISIBILITY
826bool
827isalnum(_CharT __c, const locale& __loc)
828{
829 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
830}
831
832template <class _CharT>
833inline _LIBCPP_INLINE_VISIBILITY
834bool
835isgraph(_CharT __c, const locale& __loc)
836{
837 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
838}
839
840template <class _CharT>
841inline _LIBCPP_INLINE_VISIBILITY
842_CharT
843toupper(_CharT __c, const locale& __loc)
844{
845 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
846}
847
848template <class _CharT>
849inline _LIBCPP_INLINE_VISIBILITY
850_CharT
851tolower(_CharT __c, const locale& __loc)
852{
853 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
854}
855
856// codecvt_base
857
Howard Hinnant8331b762013-03-06 23:30:19 +0000858class _LIBCPP_TYPE_VIS codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000859{
860public:
861 _LIBCPP_ALWAYS_INLINE codecvt_base() {}
862 enum result {ok, partial, error, noconv};
863};
864
865// template <class internT, class externT, class stateT> class codecvt;
866
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000867template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000868
869// template <> class codecvt<char, char, mbstate_t>
870
871template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000872class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000873 : public locale::facet,
874 public codecvt_base
875{
876public:
877 typedef char intern_type;
878 typedef char extern_type;
879 typedef mbstate_t state_type;
880
881 _LIBCPP_ALWAYS_INLINE
882 explicit codecvt(size_t __refs = 0)
883 : locale::facet(__refs) {}
884
885 _LIBCPP_ALWAYS_INLINE
886 result out(state_type& __st,
887 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
888 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
889 {
890 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
891 }
892
893 _LIBCPP_ALWAYS_INLINE
894 result unshift(state_type& __st,
895 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
896 {
897 return do_unshift(__st, __to, __to_end, __to_nxt);
898 }
899
900 _LIBCPP_ALWAYS_INLINE
901 result in(state_type& __st,
902 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
903 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
904 {
905 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
906 }
907
908 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000909 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000910 {
911 return do_encoding();
912 }
913
914 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000915 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000916 {
917 return do_always_noconv();
918 }
919
920 _LIBCPP_ALWAYS_INLINE
921 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
922 {
923 return do_length(__st, __frm, __end, __mx);
924 }
925
926 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000927 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000928 {
929 return do_max_length();
930 }
931
932 static locale::id id;
933
934protected:
935 _LIBCPP_ALWAYS_INLINE
936 explicit codecvt(const char*, size_t __refs = 0)
937 : locale::facet(__refs) {}
938
939 ~codecvt();
940
941 virtual result do_out(state_type& __st,
942 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
943 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
944 virtual result do_in(state_type& __st,
945 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
946 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
947 virtual result do_unshift(state_type& __st,
948 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000949 virtual int do_encoding() const _NOEXCEPT;
950 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000951 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 +0000952 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000953};
954
955// template <> class codecvt<wchar_t, char, mbstate_t>
956
957template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000958class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000959 : public locale::facet,
960 public codecvt_base
961{
962 locale_t __l;
963public:
964 typedef wchar_t intern_type;
965 typedef char extern_type;
966 typedef mbstate_t state_type;
967
968 explicit codecvt(size_t __refs = 0);
969
970 _LIBCPP_ALWAYS_INLINE
971 result out(state_type& __st,
972 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
973 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
974 {
975 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
976 }
977
978 _LIBCPP_ALWAYS_INLINE
979 result unshift(state_type& __st,
980 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
981 {
982 return do_unshift(__st, __to, __to_end, __to_nxt);
983 }
984
985 _LIBCPP_ALWAYS_INLINE
986 result in(state_type& __st,
987 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
988 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
989 {
990 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
991 }
992
993 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000994 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000995 {
996 return do_encoding();
997 }
998
999 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001000 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001001 {
1002 return do_always_noconv();
1003 }
1004
1005 _LIBCPP_ALWAYS_INLINE
1006 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1007 {
1008 return do_length(__st, __frm, __end, __mx);
1009 }
1010
1011 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001012 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001013 {
1014 return do_max_length();
1015 }
1016
1017 static locale::id id;
1018
1019protected:
1020 explicit codecvt(const char*, size_t __refs = 0);
1021
1022 ~codecvt();
1023
1024 virtual result do_out(state_type& __st,
1025 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1026 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1027 virtual result do_in(state_type& __st,
1028 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1029 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1030 virtual result do_unshift(state_type& __st,
1031 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001032 virtual int do_encoding() const _NOEXCEPT;
1033 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001034 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 +00001035 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001036};
1037
1038// template <> class codecvt<char16_t, char, mbstate_t>
1039
1040template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001041class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001042 : public locale::facet,
1043 public codecvt_base
1044{
1045public:
1046 typedef char16_t intern_type;
1047 typedef char extern_type;
1048 typedef mbstate_t state_type;
1049
1050 _LIBCPP_ALWAYS_INLINE
1051 explicit codecvt(size_t __refs = 0)
1052 : locale::facet(__refs) {}
1053
1054 _LIBCPP_ALWAYS_INLINE
1055 result out(state_type& __st,
1056 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1057 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1058 {
1059 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1060 }
1061
1062 _LIBCPP_ALWAYS_INLINE
1063 result unshift(state_type& __st,
1064 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1065 {
1066 return do_unshift(__st, __to, __to_end, __to_nxt);
1067 }
1068
1069 _LIBCPP_ALWAYS_INLINE
1070 result in(state_type& __st,
1071 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1072 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1073 {
1074 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1075 }
1076
1077 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001078 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001079 {
1080 return do_encoding();
1081 }
1082
1083 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001084 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001085 {
1086 return do_always_noconv();
1087 }
1088
1089 _LIBCPP_ALWAYS_INLINE
1090 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1091 {
1092 return do_length(__st, __frm, __end, __mx);
1093 }
1094
1095 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001096 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001097 {
1098 return do_max_length();
1099 }
1100
1101 static locale::id id;
1102
1103protected:
1104 _LIBCPP_ALWAYS_INLINE
1105 explicit codecvt(const char*, size_t __refs = 0)
1106 : locale::facet(__refs) {}
1107
1108 ~codecvt();
1109
1110 virtual result do_out(state_type& __st,
1111 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1112 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1113 virtual result do_in(state_type& __st,
1114 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1115 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1116 virtual result do_unshift(state_type& __st,
1117 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001118 virtual int do_encoding() const _NOEXCEPT;
1119 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001120 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 +00001121 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001122};
1123
1124// template <> class codecvt<char32_t, char, mbstate_t>
1125
1126template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001127class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001128 : public locale::facet,
1129 public codecvt_base
1130{
1131public:
1132 typedef char32_t intern_type;
1133 typedef char extern_type;
1134 typedef mbstate_t state_type;
1135
1136 _LIBCPP_ALWAYS_INLINE
1137 explicit codecvt(size_t __refs = 0)
1138 : locale::facet(__refs) {}
1139
1140 _LIBCPP_ALWAYS_INLINE
1141 result out(state_type& __st,
1142 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1143 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1144 {
1145 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1146 }
1147
1148 _LIBCPP_ALWAYS_INLINE
1149 result unshift(state_type& __st,
1150 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1151 {
1152 return do_unshift(__st, __to, __to_end, __to_nxt);
1153 }
1154
1155 _LIBCPP_ALWAYS_INLINE
1156 result in(state_type& __st,
1157 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1158 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1159 {
1160 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1161 }
1162
1163 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001164 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001165 {
1166 return do_encoding();
1167 }
1168
1169 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001170 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001171 {
1172 return do_always_noconv();
1173 }
1174
1175 _LIBCPP_ALWAYS_INLINE
1176 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1177 {
1178 return do_length(__st, __frm, __end, __mx);
1179 }
1180
1181 _LIBCPP_ALWAYS_INLINE
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001182 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001183 {
1184 return do_max_length();
1185 }
1186
1187 static locale::id id;
1188
1189protected:
1190 _LIBCPP_ALWAYS_INLINE
1191 explicit codecvt(const char*, size_t __refs = 0)
1192 : locale::facet(__refs) {}
1193
1194 ~codecvt();
1195
1196 virtual result do_out(state_type& __st,
1197 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1198 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1199 virtual result do_in(state_type& __st,
1200 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1201 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1202 virtual result do_unshift(state_type& __st,
1203 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001204 virtual int do_encoding() const _NOEXCEPT;
1205 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001206 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 +00001207 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001208};
1209
Howard Hinnantc51e1022010-05-11 19:42:16 +00001210// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1211
1212template <class _InternT, class _ExternT, class _StateT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001213class _LIBCPP_TEMPLATE_VIS codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001214 : public codecvt<_InternT, _ExternT, _StateT>
1215{
1216public:
Howard Hinnant9833cad2010-09-21 18:58:51 +00001217 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001218 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1219 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Howard Hinnant9833cad2010-09-21 18:58:51 +00001220 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001221 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1222 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1223protected:
1224 ~codecvt_byname();
1225};
1226
1227template <class _InternT, class _ExternT, class _StateT>
1228codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1229{
1230}
1231
Eric Fiselier1b57fa82016-09-15 22:27:07 +00001232_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1233_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1234_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1235_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001236
Aditya Kumare0f6a142016-08-27 02:26:42 +00001237_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
1238
Howard Hinnantc834c512011-11-29 18:15:50 +00001239template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001240struct __narrow_to_utf8
1241{
1242 template <class _OutputIterator, class _CharT>
1243 _OutputIterator
1244 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1245};
1246
1247template <>
1248struct __narrow_to_utf8<8>
1249{
1250 template <class _OutputIterator, class _CharT>
1251 _LIBCPP_ALWAYS_INLINE
1252 _OutputIterator
1253 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1254 {
1255 for (; __wb < __we; ++__wb, ++__s)
1256 *__s = *__wb;
1257 return __s;
1258 }
1259};
1260
1261template <>
1262struct __narrow_to_utf8<16>
1263 : public codecvt<char16_t, char, mbstate_t>
1264{
1265 _LIBCPP_ALWAYS_INLINE
1266 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1267
1268 ~__narrow_to_utf8();
1269
1270 template <class _OutputIterator, class _CharT>
1271 _LIBCPP_ALWAYS_INLINE
1272 _OutputIterator
1273 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1274 {
1275 result __r = ok;
1276 mbstate_t __mb;
1277 while (__wb < __we && __r != error)
1278 {
1279 const int __sz = 32;
1280 char __buf[__sz];
1281 char* __bn;
1282 const char16_t* __wn = (const char16_t*)__wb;
1283 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1284 __buf, __buf+__sz, __bn);
1285 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1286 __throw_runtime_error("locale not supported");
1287 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1288 *__s = *__p;
1289 __wb = (const _CharT*)__wn;
1290 }
1291 return __s;
1292 }
1293};
1294
1295template <>
1296struct __narrow_to_utf8<32>
1297 : public codecvt<char32_t, char, mbstate_t>
1298{
1299 _LIBCPP_ALWAYS_INLINE
1300 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1301
1302 ~__narrow_to_utf8();
1303
1304 template <class _OutputIterator, class _CharT>
1305 _LIBCPP_ALWAYS_INLINE
1306 _OutputIterator
1307 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1308 {
1309 result __r = ok;
1310 mbstate_t __mb;
1311 while (__wb < __we && __r != error)
1312 {
1313 const int __sz = 32;
1314 char __buf[__sz];
1315 char* __bn;
1316 const char32_t* __wn = (const char32_t*)__wb;
1317 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1318 __buf, __buf+__sz, __bn);
1319 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1320 __throw_runtime_error("locale not supported");
1321 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1322 *__s = *__p;
1323 __wb = (const _CharT*)__wn;
1324 }
1325 return __s;
1326 }
1327};
1328
Howard Hinnantc834c512011-11-29 18:15:50 +00001329template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001330struct __widen_from_utf8
1331{
1332 template <class _OutputIterator>
1333 _OutputIterator
1334 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1335};
1336
1337template <>
1338struct __widen_from_utf8<8>
1339{
1340 template <class _OutputIterator>
1341 _LIBCPP_ALWAYS_INLINE
1342 _OutputIterator
1343 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1344 {
1345 for (; __nb < __ne; ++__nb, ++__s)
1346 *__s = *__nb;
1347 return __s;
1348 }
1349};
1350
1351template <>
1352struct __widen_from_utf8<16>
1353 : public codecvt<char16_t, char, mbstate_t>
1354{
1355 _LIBCPP_ALWAYS_INLINE
1356 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1357
1358 ~__widen_from_utf8();
1359
1360 template <class _OutputIterator>
1361 _LIBCPP_ALWAYS_INLINE
1362 _OutputIterator
1363 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1364 {
1365 result __r = ok;
1366 mbstate_t __mb;
1367 while (__nb < __ne && __r != error)
1368 {
1369 const int __sz = 32;
1370 char16_t __buf[__sz];
1371 char16_t* __bn;
1372 const char* __nn = __nb;
1373 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1374 __buf, __buf+__sz, __bn);
1375 if (__r == codecvt_base::error || __nn == __nb)
1376 __throw_runtime_error("locale not supported");
1377 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1378 *__s = (wchar_t)*__p;
1379 __nb = __nn;
1380 }
1381 return __s;
1382 }
1383};
1384
1385template <>
1386struct __widen_from_utf8<32>
1387 : public codecvt<char32_t, char, mbstate_t>
1388{
1389 _LIBCPP_ALWAYS_INLINE
1390 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1391
1392 ~__widen_from_utf8();
1393
1394 template <class _OutputIterator>
1395 _LIBCPP_ALWAYS_INLINE
1396 _OutputIterator
1397 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1398 {
1399 result __r = ok;
1400 mbstate_t __mb;
1401 while (__nb < __ne && __r != error)
1402 {
1403 const int __sz = 32;
1404 char32_t __buf[__sz];
1405 char32_t* __bn;
1406 const char* __nn = __nb;
1407 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1408 __buf, __buf+__sz, __bn);
1409 if (__r == codecvt_base::error || __nn == __nb)
1410 __throw_runtime_error("locale not supported");
1411 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1412 *__s = (wchar_t)*__p;
1413 __nb = __nn;
1414 }
1415 return __s;
1416 }
1417};
1418
1419// template <class charT> class numpunct
1420
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001421template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001422
1423template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001424class _LIBCPP_TYPE_VIS numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001425 : public locale::facet
1426{
1427public:
1428 typedef char char_type;
1429 typedef basic_string<char_type> string_type;
1430
1431 explicit numpunct(size_t __refs = 0);
1432
1433 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1434 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1435 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1436 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1437 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1438
1439 static locale::id id;
1440
1441protected:
1442 ~numpunct();
1443 virtual char_type do_decimal_point() const;
1444 virtual char_type do_thousands_sep() const;
1445 virtual string do_grouping() const;
1446 virtual string_type do_truename() const;
1447 virtual string_type do_falsename() const;
1448
1449 char_type __decimal_point_;
1450 char_type __thousands_sep_;
1451 string __grouping_;
1452};
1453
1454template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001455class _LIBCPP_TYPE_VIS numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001456 : public locale::facet
1457{
1458public:
1459 typedef wchar_t char_type;
1460 typedef basic_string<char_type> string_type;
1461
1462 explicit numpunct(size_t __refs = 0);
1463
1464 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1465 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1466 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
1467 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();}
1468 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();}
1469
1470 static locale::id id;
1471
1472protected:
1473 ~numpunct();
1474 virtual char_type do_decimal_point() const;
1475 virtual char_type do_thousands_sep() const;
1476 virtual string do_grouping() const;
1477 virtual string_type do_truename() const;
1478 virtual string_type do_falsename() const;
1479
1480 char_type __decimal_point_;
1481 char_type __thousands_sep_;
1482 string __grouping_;
1483};
1484
1485// template <class charT> class numpunct_byname
1486
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001487template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001488
1489template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001490class _LIBCPP_TYPE_VIS numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001491: public numpunct<char>
1492{
1493public:
1494 typedef char char_type;
1495 typedef basic_string<char_type> string_type;
1496
1497 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1498 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1499
1500protected:
1501 ~numpunct_byname();
1502
1503private:
1504 void __init(const char*);
1505};
1506
1507template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001508class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001509: public numpunct<wchar_t>
1510{
1511public:
1512 typedef wchar_t char_type;
1513 typedef basic_string<char_type> string_type;
1514
1515 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1516 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1517
1518protected:
1519 ~numpunct_byname();
1520
1521private:
1522 void __init(const char*);
1523};
1524
1525_LIBCPP_END_NAMESPACE_STD
1526
1527#endif // _LIBCPP___LOCALE