blob: ed48bfb9ae66e946558dd58e620d06b3024cafe4 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___LOCALE
11#define _LIBCPP___LOCALE
12
13#include <__config>
Louis Dionne73912b22020-11-04 15:01:25 -050014#include <__availability>
Howard Hinnantc51e1022010-05-11 19:42:16 +000015#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)
Thomas Anderson094acbc2019-03-27 18:09:30 +000023# include <cstring>
Howard Hinnantae0f80b2011-09-29 20:33:10 +000024# include <support/win32/locale_win32.h>
Muiez Ahmedaf108fb2020-11-10 09:54:03 -050025#elif defined(_AIX) || defined(__MVS__)
Howard Hinnantea382952013-08-14 18:00:20 +000026# include <support/ibm/xlocale.h>
Marshall Clow3477ec92014-07-10 15:20:28 +000027#elif defined(__ANDROID__)
Saleem Abdulrasoolac039f32018-04-13 18:14:57 +000028# include <support/android/locale_bionic.h>
Eric Fiselier7274c652014-11-25 21:57:41 +000029#elif defined(__sun__)
Eric Fiselier90adc202015-01-23 22:22:36 +000030# include <xlocale.h>
Eric Fiselier7274c652014-11-25 21:57:41 +000031# include <support/solaris/xlocale.h>
Sergey Dmitrouk9935bd42014-12-12 08:36:16 +000032#elif defined(_NEWLIB_VERSION)
33# include <support/newlib/xlocale.h>
Eric Fiseliercee57932017-08-03 04:28:10 +000034#elif (defined(__APPLE__) || defined(__FreeBSD__) \
Eric Fiselier7274c652014-11-25 21:57:41 +000035 || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
Howard Hinnantdd0d7022011-09-22 19:10:18 +000036# include <xlocale.h>
Petr Hosekfdb4a872017-04-13 21:29:21 +000037#elif defined(__Fuchsia__)
38# include <support/fuchsia/xlocale.h>
Dan Gohman280fd6b2019-05-01 16:47:30 +000039#elif defined(__wasi__)
40// WASI libc uses musl's locales support.
41# include <support/musl/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) :
Thomas Anderson094acbc2019-03-27 18:09:30 +000071 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
72 // Setting the locale can be expensive even when the locale given is
73 // already the current locale, so do an explicit check to see if the
74 // current locale is already the one we want.
75 const char* __lc = __setlocale(nullptr);
76 // If every category is the same, the locale string will simply be the
77 // locale name, otherwise it will be a semicolon-separated string listing
78 // each category. In the second case, we know at least one category won't
79 // be what we want, so we only have to check the first case.
80 if (strcmp(__l.__get_locale(), __lc) != 0) {
81 __locale_all = _strdup(__lc);
82 if (__locale_all == nullptr)
83 __throw_bad_alloc();
84 __setlocale(__l.__get_locale());
85 }
86 }
Martin Storsjo5482ac62017-11-23 10:38:18 +000087 ~__libcpp_locale_guard() {
Thomas Anderson094acbc2019-03-27 18:09:30 +000088 // The CRT documentation doesn't explicitly say, but setlocale() does the
89 // right thing when given a semicolon-separated list of locale settings
90 // for the different categories in the same format as returned by
91 // setlocale(LC_ALL, nullptr).
92 if (__locale_all != nullptr) {
93 __setlocale(__locale_all);
94 free(__locale_all);
95 }
96 _configthreadlocale(__status);
97 }
98 static const char* __setlocale(const char* __locale) {
99 const char* __new_locale = setlocale(LC_ALL, __locale);
100 if (__new_locale == nullptr)
101 __throw_bad_alloc();
102 return __new_locale;
Martin Storsjo5482ac62017-11-23 10:38:18 +0000103 }
104 int __status;
Thomas Anderson094acbc2019-03-27 18:09:30 +0000105 char* __locale_all = nullptr;
Martin Storsjo5482ac62017-11-23 10:38:18 +0000106};
Eric Fiselierebc2d2c2017-05-08 22:02:43 +0000107#endif
108
109
Howard Hinnant8331b762013-03-06 23:30:19 +0000110class _LIBCPP_TYPE_VIS locale;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000111
Howard Hinnanta54386e2012-09-14 00:39:16 +0000112template <class _Facet>
113_LIBCPP_INLINE_VISIBILITY
114bool
115has_facet(const locale&) _NOEXCEPT;
116
117template <class _Facet>
118_LIBCPP_INLINE_VISIBILITY
119const _Facet&
120use_facet(const locale&);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000121
Howard Hinnant8331b762013-03-06 23:30:19 +0000122class _LIBCPP_TYPE_VIS locale
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123{
124public:
125 // types:
Howard Hinnant8331b762013-03-06 23:30:19 +0000126 class _LIBCPP_TYPE_VIS facet;
127 class _LIBCPP_TYPE_VIS id;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128
129 typedef int category;
Mehdi Amini228053d2017-05-04 17:08:54 +0000130 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000131 static const category // values assigned here are for exposition only
132 none = 0,
133 collate = LC_COLLATE_MASK,
134 ctype = LC_CTYPE_MASK,
135 monetary = LC_MONETARY_MASK,
136 numeric = LC_NUMERIC_MASK,
137 time = LC_TIME_MASK,
138 messages = LC_MESSAGES_MASK,
139 all = collate | ctype | monetary | numeric | time | messages;
140
141 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000142 locale() _NOEXCEPT;
143 locale(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144 explicit locale(const char*);
145 explicit locale(const string&);
146 locale(const locale&, const char*, category);
147 locale(const locale&, const string&, category);
Howard Hinnantcf823322010-12-17 14:46:43 +0000148 template <class _Facet>
149 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000150 locale(const locale&, const locale&, category);
151
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000152 ~locale();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000153
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000154 const locale& operator=(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000156 template <class _Facet>
157 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
158 locale combine(const locale&) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000159
160 // locale operations:
161 string name() const;
162 bool operator==(const locale&) const;
163 bool operator!=(const locale& __y) const {return !(*this == __y);}
164 template <class _CharT, class _Traits, class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000165 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
167 const basic_string<_CharT, _Traits, _Allocator>&) const;
168
169 // global locale objects:
170 static locale global(const locale&);
171 static const locale& classic();
172
173private:
174 class __imp;
175 __imp* __locale_;
176
177 void __install_ctor(const locale&, facet*, long);
178 static locale& __global();
179 bool has_facet(id&) const;
180 const facet* use_facet(id&) const;
181
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000182 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000183 template <class _Facet> friend const _Facet& use_facet(const locale&);
184};
185
Howard Hinnant8331b762013-03-06 23:30:19 +0000186class _LIBCPP_TYPE_VIS locale::facet
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187 : public __shared_count
188{
189protected:
Howard Hinnant9833cad2010-09-21 18:58:51 +0000190 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000191 explicit facet(size_t __refs = 0)
192 : __shared_count(static_cast<long>(__refs)-1) {}
193
194 virtual ~facet();
195
196// facet(const facet&) = delete; // effectively done in __shared_count
197// void operator=(const facet&) = delete;
198private:
Howard Hinnant719bda32011-05-28 14:41:13 +0000199 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000200};
201
Howard Hinnant8331b762013-03-06 23:30:19 +0000202class _LIBCPP_TYPE_VIS locale::id
Howard Hinnantc51e1022010-05-11 19:42:16 +0000203{
204 once_flag __flag_;
205 int32_t __id_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000206
Howard Hinnantc51e1022010-05-11 19:42:16 +0000207 static int32_t __next_id;
208public:
Howard Hinnantac7d9f02012-07-26 16:14:37 +0000209 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000210private:
211 void __init();
212 void operator=(const id&); // = delete;
213 id(const id&); // = delete;
214public: // only needed for tests
215 long __get();
216
217 friend class locale;
218 friend class locale::__imp;
219};
220
221template <class _Facet>
222inline _LIBCPP_INLINE_VISIBILITY
223locale::locale(const locale& __other, _Facet* __f)
224{
225 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
226}
227
228template <class _Facet>
229locale
230locale::combine(const locale& __other) const
231{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000232 if (!_VSTD::has_facet<_Facet>(__other))
Marshall Clow8fea1612016-08-25 15:09:01 +0000233 __throw_runtime_error("locale::combine: locale missing facet");
234
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000235 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000236}
237
238template <class _Facet>
239inline _LIBCPP_INLINE_VISIBILITY
240bool
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000241has_facet(const locale& __l) _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000242{
243 return __l.has_facet(_Facet::id);
244}
245
246template <class _Facet>
247inline _LIBCPP_INLINE_VISIBILITY
248const _Facet&
249use_facet(const locale& __l)
250{
251 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
252}
253
254// template <class _CharT> class collate;
255
256template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000257class _LIBCPP_TEMPLATE_VIS collate
Howard Hinnantc51e1022010-05-11 19:42:16 +0000258 : public locale::facet
259{
260public:
261 typedef _CharT char_type;
262 typedef basic_string<char_type> string_type;
263
Howard Hinnant9833cad2010-09-21 18:58:51 +0000264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 explicit collate(size_t __refs = 0)
266 : locale::facet(__refs) {}
267
Howard Hinnant9833cad2010-09-21 18:58:51 +0000268 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000269 int compare(const char_type* __lo1, const char_type* __hi1,
270 const char_type* __lo2, const char_type* __hi2) const
271 {
272 return do_compare(__lo1, __hi1, __lo2, __hi2);
273 }
274
Eric Fiselier39b86ea2019-03-08 23:59:29 +0000275 // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work
276 // around a dllimport bug that expects an external instantiation.
Howard Hinnant9833cad2010-09-21 18:58:51 +0000277 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier39b86ea2019-03-08 23:59:29 +0000278 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +0000279 string_type transform(const char_type* __lo, const char_type* __hi) const
280 {
281 return do_transform(__lo, __hi);
282 }
283
Howard Hinnant9833cad2010-09-21 18:58:51 +0000284 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000285 long hash(const char_type* __lo, const char_type* __hi) const
286 {
287 return do_hash(__lo, __hi);
288 }
289
290 static locale::id id;
291
292protected:
293 ~collate();
294 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
295 const char_type* __lo2, const char_type* __hi2) const;
296 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
297 {return string_type(__lo, __hi);}
298 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
299};
300
301template <class _CharT> locale::id collate<_CharT>::id;
302
303template <class _CharT>
304collate<_CharT>::~collate()
305{
306}
307
308template <class _CharT>
309int
310collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
311 const char_type* __lo2, const char_type* __hi2) const
312{
313 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
314 {
315 if (__lo1 == __hi1 || *__lo1 < *__lo2)
316 return -1;
317 if (*__lo2 < *__lo1)
318 return 1;
319 }
320 return __lo1 != __hi1;
321}
322
323template <class _CharT>
324long
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000325collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000326{
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000327 size_t __h = 0;
328 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
329 const size_t __mask = size_t(0xF) << (__sr + 4);
330 for(const char_type* __p = __lo; __p != __hi; ++__p)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000331 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000332 __h = (__h << 4) + static_cast<size_t>(*__p);
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000333 size_t __g = __h & __mask;
334 __h ^= __g | (__g >> __sr);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000335 }
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000336 return static_cast<long>(__h);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337}
338
Louis Dionneb5ae3a72020-10-02 14:29:48 -0400339_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
340_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000341
342// template <class CharT> class collate_byname;
343
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000344template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000345
346template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000347class _LIBCPP_TYPE_VIS collate_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000348 : public collate<char>
349{
350 locale_t __l;
351public:
352 typedef char char_type;
353 typedef basic_string<char_type> string_type;
354
355 explicit collate_byname(const char* __n, size_t __refs = 0);
356 explicit collate_byname(const string& __n, size_t __refs = 0);
357
358protected:
359 ~collate_byname();
360 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
361 const char_type* __lo2, const char_type* __hi2) const;
362 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
363};
364
365template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000366class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000367 : public collate<wchar_t>
368{
369 locale_t __l;
370public:
371 typedef wchar_t char_type;
372 typedef basic_string<char_type> string_type;
373
374 explicit collate_byname(const char* __n, size_t __refs = 0);
375 explicit collate_byname(const string& __n, size_t __refs = 0);
376
377protected:
378 ~collate_byname();
379
380 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
381 const char_type* __lo2, const char_type* __hi2) const;
382 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
383};
384
385template <class _CharT, class _Traits, class _Allocator>
386bool
387locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
388 const basic_string<_CharT, _Traits, _Allocator>& __y) const
389{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +0000390 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
Howard Hinnantc51e1022010-05-11 19:42:16 +0000391 __x.data(), __x.data() + __x.size(),
392 __y.data(), __y.data() + __y.size()) < 0;
393}
394
395// template <class charT> class ctype
396
Howard Hinnant8331b762013-03-06 23:30:19 +0000397class _LIBCPP_TYPE_VIS ctype_base
Howard Hinnant9833cad2010-09-21 18:58:51 +0000398{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000399public:
Vasileios Kalintiris281b4cf2015-11-09 10:21:04 +0000400#if defined(__GLIBC__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000401 typedef unsigned short mask;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000402 static const mask space = _ISspace;
403 static const mask print = _ISprint;
404 static const mask cntrl = _IScntrl;
405 static const mask upper = _ISupper;
406 static const mask lower = _ISlower;
407 static const mask alpha = _ISalpha;
408 static const mask digit = _ISdigit;
409 static const mask punct = _ISpunct;
410 static const mask xdigit = _ISxdigit;
411 static const mask blank = _ISblank;
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000412#if defined(__mips__)
Mikhail Maltsev12eb5af2019-08-20 10:19:55 +0000413 static const mask __regex_word = static_cast<mask>(_ISbit(15));
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000414#else
415 static const mask __regex_word = 0x80;
416#endif
Eric Fiselierbb999f92017-05-31 22:14:05 +0000417#elif defined(_LIBCPP_MSVCRT_LIKE)
Howard Hinnantd7a78632011-09-29 13:33:15 +0000418 typedef unsigned short mask;
Howard Hinnantdd0d7022011-09-22 19:10:18 +0000419 static const mask space = _SPACE;
420 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
421 static const mask cntrl = _CONTROL;
422 static const mask upper = _UPPER;
423 static const mask lower = _LOWER;
424 static const mask alpha = _ALPHA;
425 static const mask digit = _DIGIT;
426 static const mask punct = _PUNCT;
427 static const mask xdigit = _HEX;
428 static const mask blank = _BLANK;
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000429 static const mask __regex_word = 0x80;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000430# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
Dan Albertebdf28b2015-03-11 00:51:06 +0000431#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
JF Bastien0c265d82015-02-25 22:16:46 +0000432# ifdef __APPLE__
David Chisnall1d581062011-09-21 08:39:44 +0000433 typedef __uint32_t mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000434# elif defined(__FreeBSD__)
David Chisnall1d581062011-09-21 08:39:44 +0000435 typedef unsigned long mask;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000436# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
Howard Hinnant942dbd22013-03-29 18:27:28 +0000437 typedef unsigned short mask;
JF Bastien0c265d82015-02-25 22:16:46 +0000438# endif
David Chisnall1d581062011-09-21 08:39:44 +0000439 static const mask space = _CTYPE_S;
440 static const mask print = _CTYPE_R;
441 static const mask cntrl = _CTYPE_C;
442 static const mask upper = _CTYPE_U;
443 static const mask lower = _CTYPE_L;
444 static const mask alpha = _CTYPE_A;
445 static const mask digit = _CTYPE_D;
446 static const mask punct = _CTYPE_P;
447 static const mask xdigit = _CTYPE_X;
Dan Albert2dca4072014-07-23 19:32:03 +0000448
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000449# if defined(__NetBSD__)
450 static const mask blank = _CTYPE_BL;
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000451 // NetBSD defines classes up to 0x2000
452 // see sys/ctype_bits.h, _CTYPE_Q
453 static const mask __regex_word = 0x8000;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000454# else
David Chisnall1d581062011-09-21 08:39:44 +0000455 static const mask blank = _CTYPE_B;
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000456 static const mask __regex_word = 0x80;
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000457# endif
Howard Hinnanta47505d2013-08-30 14:42:39 +0000458#elif defined(__sun__) || defined(_AIX)
David Chisnall8074c342012-02-29 13:05:08 +0000459 typedef unsigned int mask;
460 static const mask space = _ISSPACE;
461 static const mask print = _ISPRINT;
462 static const mask cntrl = _ISCNTRL;
463 static const mask upper = _ISUPPER;
464 static const mask lower = _ISLOWER;
465 static const mask alpha = _ISALPHA;
466 static const mask digit = _ISDIGIT;
467 static const mask punct = _ISPUNCT;
468 static const mask xdigit = _ISXDIGIT;
469 static const mask blank = _ISBLANK;
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000470 static const mask __regex_word = 0x80;
JF Bastien0c265d82015-02-25 22:16:46 +0000471#elif defined(_NEWLIB_VERSION)
472 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
473 typedef char mask;
474 static const mask space = _S;
475 static const mask print = _P | _U | _L | _N | _B;
476 static const mask cntrl = _C;
477 static const mask upper = _U;
478 static const mask lower = _L;
479 static const mask alpha = _U | _L;
480 static const mask digit = _N;
481 static const mask punct = _P;
482 static const mask xdigit = _X | _N;
483 static const mask blank = _B;
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000484 static const mask __regex_word = 0x80;
Jonathan Roelofsae9ab252015-03-11 17:00:28 +0000485# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
486# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
487# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
JF Bastien0c265d82015-02-25 22:16:46 +0000488#else
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +0000489 typedef unsigned long mask;
490 static const mask space = 1<<0;
491 static const mask print = 1<<1;
492 static const mask cntrl = 1<<2;
493 static const mask upper = 1<<3;
494 static const mask lower = 1<<4;
495 static const mask alpha = 1<<5;
496 static const mask digit = 1<<6;
497 static const mask punct = 1<<7;
498 static const mask xdigit = 1<<8;
499 static const mask blank = 1<<9;
Dan Albert70ee07e2020-04-06 13:34:27 -0700500#if defined(__BIONIC__)
501 // Historically this was a part of regex_traits rather than ctype_base. The
502 // historical value of the constant is preserved for ABI compatibility.
503 static const mask __regex_word = 0x8000;
504#else
Mikhail Maltsev014ed062019-06-14 09:04:16 +0000505 static const mask __regex_word = 1<<10;
Dan Albert70ee07e2020-04-06 13:34:27 -0700506#endif // defined(__BIONIC__)
JF Bastien0c265d82015-02-25 22:16:46 +0000507#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000508 static const mask alnum = alpha | digit;
509 static const mask graph = alnum | punct;
510
Louis Dionne16fe2952018-07-11 23:14:33 +0000511 _LIBCPP_INLINE_VISIBILITY ctype_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000512};
513
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000514template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000515
516template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000517class _LIBCPP_TYPE_VIS ctype<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000518 : public locale::facet,
519 public ctype_base
520{
521public:
522 typedef wchar_t char_type;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000523
Louis Dionne16fe2952018-07-11 23:14:33 +0000524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000525 explicit ctype(size_t __refs = 0)
526 : locale::facet(__refs) {}
527
Louis Dionne16fe2952018-07-11 23:14:33 +0000528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000529 bool is(mask __m, char_type __c) const
530 {
531 return do_is(__m, __c);
532 }
533
Louis Dionne16fe2952018-07-11 23:14:33 +0000534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000535 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
536 {
537 return do_is(__low, __high, __vec);
538 }
539
Louis Dionne16fe2952018-07-11 23:14:33 +0000540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000541 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
542 {
543 return do_scan_is(__m, __low, __high);
544 }
545
Louis Dionne16fe2952018-07-11 23:14:33 +0000546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000547 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
548 {
549 return do_scan_not(__m, __low, __high);
550 }
551
Louis Dionne16fe2952018-07-11 23:14:33 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000553 char_type toupper(char_type __c) const
554 {
555 return do_toupper(__c);
556 }
557
Louis Dionne16fe2952018-07-11 23:14:33 +0000558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000559 const char_type* toupper(char_type* __low, const char_type* __high) const
560 {
561 return do_toupper(__low, __high);
562 }
563
Louis Dionne16fe2952018-07-11 23:14:33 +0000564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000565 char_type tolower(char_type __c) const
566 {
567 return do_tolower(__c);
568 }
569
Louis Dionne16fe2952018-07-11 23:14:33 +0000570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000571 const char_type* tolower(char_type* __low, const char_type* __high) const
572 {
573 return do_tolower(__low, __high);
574 }
575
Louis Dionne16fe2952018-07-11 23:14:33 +0000576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000577 char_type widen(char __c) const
578 {
579 return do_widen(__c);
580 }
581
Louis Dionne16fe2952018-07-11 23:14:33 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000583 const char* widen(const char* __low, const char* __high, char_type* __to) const
584 {
585 return do_widen(__low, __high, __to);
586 }
587
Louis Dionne16fe2952018-07-11 23:14:33 +0000588 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000589 char narrow(char_type __c, char __dfault) const
590 {
591 return do_narrow(__c, __dfault);
592 }
593
Louis Dionne16fe2952018-07-11 23:14:33 +0000594 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000595 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
596 {
597 return do_narrow(__low, __high, __dfault, __to);
598 }
599
600 static locale::id id;
601
602protected:
603 ~ctype();
604 virtual bool do_is(mask __m, char_type __c) const;
605 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
606 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
607 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
608 virtual char_type do_toupper(char_type) const;
609 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
610 virtual char_type do_tolower(char_type) const;
611 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
612 virtual char_type do_widen(char) const;
613 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
614 virtual char do_narrow(char_type, char __dfault) const;
615 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
616};
617
618template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000619class _LIBCPP_TYPE_VIS ctype<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000620 : public locale::facet, public ctype_base
621{
622 const mask* __tab_;
623 bool __del_;
624public:
625 typedef char char_type;
626
627 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
628
Louis Dionne16fe2952018-07-11 23:14:33 +0000629 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000630 bool is(mask __m, char_type __c) const
631 {
Marshall Clow11de4872013-10-21 14:41:05 +0000632 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000633 }
634
Louis Dionne16fe2952018-07-11 23:14:33 +0000635 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000636 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
637 {
638 for (; __low != __high; ++__low, ++__vec)
Howard Hinnant28b24882011-12-01 20:21:04 +0000639 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000640 return __low;
641 }
642
Louis Dionne16fe2952018-07-11 23:14:33 +0000643 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000644 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
645 {
646 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000647 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000648 break;
649 return __low;
650 }
651
Louis Dionne16fe2952018-07-11 23:14:33 +0000652 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000653 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
654 {
655 for (; __low != __high; ++__low)
Howard Hinnant28b24882011-12-01 20:21:04 +0000656 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000657 break;
658 return __low;
659 }
660
Louis Dionne16fe2952018-07-11 23:14:33 +0000661 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000662 char_type toupper(char_type __c) const
663 {
664 return do_toupper(__c);
665 }
666
Louis Dionne16fe2952018-07-11 23:14:33 +0000667 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000668 const char_type* toupper(char_type* __low, const char_type* __high) const
669 {
670 return do_toupper(__low, __high);
671 }
672
Louis Dionne16fe2952018-07-11 23:14:33 +0000673 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000674 char_type tolower(char_type __c) const
675 {
676 return do_tolower(__c);
677 }
678
Louis Dionne16fe2952018-07-11 23:14:33 +0000679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000680 const char_type* tolower(char_type* __low, const char_type* __high) const
681 {
682 return do_tolower(__low, __high);
683 }
684
Louis Dionne16fe2952018-07-11 23:14:33 +0000685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000686 char_type widen(char __c) const
687 {
688 return do_widen(__c);
689 }
690
Louis Dionne16fe2952018-07-11 23:14:33 +0000691 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000692 const char* widen(const char* __low, const char* __high, char_type* __to) const
693 {
694 return do_widen(__low, __high, __to);
695 }
696
Louis Dionne16fe2952018-07-11 23:14:33 +0000697 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000698 char narrow(char_type __c, char __dfault) const
699 {
700 return do_narrow(__c, __dfault);
701 }
702
Louis Dionne16fe2952018-07-11 23:14:33 +0000703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000704 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
705 {
706 return do_narrow(__low, __high, __dfault, __to);
707 }
708
709 static locale::id id;
710
Howard Hinnant155c2af2010-05-24 17:49:41 +0000711#ifdef _CACHED_RUNES
Howard Hinnantc51e1022010-05-11 19:42:16 +0000712 static const size_t table_size = _CACHED_RUNES;
Howard Hinnant155c2af2010-05-24 17:49:41 +0000713#else
714 static const size_t table_size = 256; // FIXME: Don't hardcode this.
715#endif
Louis Dionne16fe2952018-07-11 23:14:33 +0000716 _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;}
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000717 static const mask* classic_table() _NOEXCEPT;
Vasileios Kalintirisc5dd8942015-11-24 10:24:54 +0000718#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
Alexis Hunt92b0c812011-07-09 00:56:23 +0000719 static const int* __classic_upper_table() _NOEXCEPT;
720 static const int* __classic_lower_table() _NOEXCEPT;
Alexis Hunt5a4dd562011-07-09 01:09:31 +0000721#endif
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000722#if defined(__NetBSD__)
723 static const short* __classic_upper_table() _NOEXCEPT;
724 static const short* __classic_lower_table() _NOEXCEPT;
725#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000726
727protected:
728 ~ctype();
729 virtual char_type do_toupper(char_type __c) const;
730 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
731 virtual char_type do_tolower(char_type __c) const;
732 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
733 virtual char_type do_widen(char __c) const;
734 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
735 virtual char do_narrow(char_type __c, char __dfault) const;
736 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
737};
738
739// template <class CharT> class ctype_byname;
740
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000741template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000742
743template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000744class _LIBCPP_TYPE_VIS ctype_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000745 : public ctype<char>
746{
747 locale_t __l;
748
749public:
750 explicit ctype_byname(const char*, size_t = 0);
751 explicit ctype_byname(const string&, size_t = 0);
752
753protected:
754 ~ctype_byname();
755 virtual char_type do_toupper(char_type) const;
756 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
757 virtual char_type do_tolower(char_type) const;
758 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
759};
760
761template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000762class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000763 : public ctype<wchar_t>
764{
765 locale_t __l;
766
767public:
768 explicit ctype_byname(const char*, size_t = 0);
769 explicit ctype_byname(const string&, size_t = 0);
770
771protected:
772 ~ctype_byname();
773 virtual bool do_is(mask __m, char_type __c) const;
774 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
775 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
776 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
777 virtual char_type do_toupper(char_type) const;
778 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
779 virtual char_type do_tolower(char_type) const;
780 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
781 virtual char_type do_widen(char) const;
782 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
783 virtual char do_narrow(char_type, char __dfault) const;
784 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
785};
786
787template <class _CharT>
788inline _LIBCPP_INLINE_VISIBILITY
789bool
790isspace(_CharT __c, const locale& __loc)
791{
792 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
793}
794
795template <class _CharT>
796inline _LIBCPP_INLINE_VISIBILITY
797bool
798isprint(_CharT __c, const locale& __loc)
799{
800 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
801}
802
803template <class _CharT>
804inline _LIBCPP_INLINE_VISIBILITY
805bool
806iscntrl(_CharT __c, const locale& __loc)
807{
808 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
809}
810
811template <class _CharT>
812inline _LIBCPP_INLINE_VISIBILITY
813bool
814isupper(_CharT __c, const locale& __loc)
815{
816 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
817}
818
819template <class _CharT>
820inline _LIBCPP_INLINE_VISIBILITY
821bool
822islower(_CharT __c, const locale& __loc)
823{
824 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
825}
826
827template <class _CharT>
828inline _LIBCPP_INLINE_VISIBILITY
829bool
830isalpha(_CharT __c, const locale& __loc)
831{
832 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
833}
834
835template <class _CharT>
836inline _LIBCPP_INLINE_VISIBILITY
837bool
838isdigit(_CharT __c, const locale& __loc)
839{
840 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
841}
842
843template <class _CharT>
844inline _LIBCPP_INLINE_VISIBILITY
845bool
846ispunct(_CharT __c, const locale& __loc)
847{
848 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
849}
850
851template <class _CharT>
852inline _LIBCPP_INLINE_VISIBILITY
853bool
854isxdigit(_CharT __c, const locale& __loc)
855{
856 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
857}
858
859template <class _CharT>
860inline _LIBCPP_INLINE_VISIBILITY
861bool
862isalnum(_CharT __c, const locale& __loc)
863{
864 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
865}
866
867template <class _CharT>
868inline _LIBCPP_INLINE_VISIBILITY
869bool
870isgraph(_CharT __c, const locale& __loc)
871{
872 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
873}
874
875template <class _CharT>
876inline _LIBCPP_INLINE_VISIBILITY
877_CharT
878toupper(_CharT __c, const locale& __loc)
879{
880 return use_facet<ctype<_CharT> >(__loc).toupper(__c);
881}
882
883template <class _CharT>
884inline _LIBCPP_INLINE_VISIBILITY
885_CharT
886tolower(_CharT __c, const locale& __loc)
887{
888 return use_facet<ctype<_CharT> >(__loc).tolower(__c);
889}
890
891// codecvt_base
892
Howard Hinnant8331b762013-03-06 23:30:19 +0000893class _LIBCPP_TYPE_VIS codecvt_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000894{
895public:
Louis Dionne16fe2952018-07-11 23:14:33 +0000896 _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000897 enum result {ok, partial, error, noconv};
898};
899
900// template <class internT, class externT, class stateT> class codecvt;
901
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000902template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000903
904// template <> class codecvt<char, char, mbstate_t>
905
906template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000907class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000908 : public locale::facet,
909 public codecvt_base
910{
911public:
912 typedef char intern_type;
913 typedef char extern_type;
914 typedef mbstate_t state_type;
915
Louis Dionne16fe2952018-07-11 23:14:33 +0000916 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000917 explicit codecvt(size_t __refs = 0)
918 : locale::facet(__refs) {}
919
Louis Dionne16fe2952018-07-11 23:14:33 +0000920 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000921 result out(state_type& __st,
922 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
923 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
924 {
925 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
926 }
927
Louis Dionne16fe2952018-07-11 23:14:33 +0000928 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000929 result unshift(state_type& __st,
930 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
931 {
932 return do_unshift(__st, __to, __to_end, __to_nxt);
933 }
934
Louis Dionne16fe2952018-07-11 23:14:33 +0000935 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000936 result in(state_type& __st,
937 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
938 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
939 {
940 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
941 }
942
Louis Dionne16fe2952018-07-11 23:14:33 +0000943 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000944 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000945 {
946 return do_encoding();
947 }
948
Louis Dionne16fe2952018-07-11 23:14:33 +0000949 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000950 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000951 {
952 return do_always_noconv();
953 }
954
Louis Dionne16fe2952018-07-11 23:14:33 +0000955 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000956 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
957 {
958 return do_length(__st, __frm, __end, __mx);
959 }
960
Louis Dionne16fe2952018-07-11 23:14:33 +0000961 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000962 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +0000963 {
964 return do_max_length();
965 }
966
967 static locale::id id;
968
969protected:
Louis Dionne16fe2952018-07-11 23:14:33 +0000970 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000971 explicit codecvt(const char*, size_t __refs = 0)
972 : locale::facet(__refs) {}
973
974 ~codecvt();
975
976 virtual result do_out(state_type& __st,
977 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
978 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
979 virtual result do_in(state_type& __st,
980 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
981 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
982 virtual result do_unshift(state_type& __st,
983 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +0000984 virtual int do_encoding() const _NOEXCEPT;
985 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000986 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 +0000987 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000988};
989
990// template <> class codecvt<wchar_t, char, mbstate_t>
991
992template <>
Howard Hinnant8331b762013-03-06 23:30:19 +0000993class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000994 : public locale::facet,
995 public codecvt_base
996{
997 locale_t __l;
998public:
999 typedef wchar_t intern_type;
1000 typedef char extern_type;
1001 typedef mbstate_t state_type;
1002
1003 explicit codecvt(size_t __refs = 0);
1004
Louis Dionne16fe2952018-07-11 23:14:33 +00001005 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001006 result out(state_type& __st,
1007 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1008 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1009 {
1010 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1011 }
1012
Louis Dionne16fe2952018-07-11 23:14:33 +00001013 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001014 result unshift(state_type& __st,
1015 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1016 {
1017 return do_unshift(__st, __to, __to_end, __to_nxt);
1018 }
1019
Louis Dionne16fe2952018-07-11 23:14:33 +00001020 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001021 result in(state_type& __st,
1022 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1023 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1024 {
1025 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1026 }
1027
Louis Dionne16fe2952018-07-11 23:14:33 +00001028 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001029 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001030 {
1031 return do_encoding();
1032 }
1033
Louis Dionne16fe2952018-07-11 23:14:33 +00001034 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001035 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001036 {
1037 return do_always_noconv();
1038 }
1039
Louis Dionne16fe2952018-07-11 23:14:33 +00001040 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001041 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1042 {
1043 return do_length(__st, __frm, __end, __mx);
1044 }
1045
Louis Dionne16fe2952018-07-11 23:14:33 +00001046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001047 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001048 {
1049 return do_max_length();
1050 }
1051
1052 static locale::id id;
1053
1054protected:
1055 explicit codecvt(const char*, size_t __refs = 0);
1056
1057 ~codecvt();
1058
1059 virtual result do_out(state_type& __st,
1060 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1061 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1062 virtual result do_in(state_type& __st,
1063 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1064 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1065 virtual result do_unshift(state_type& __st,
1066 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001067 virtual int do_encoding() const _NOEXCEPT;
1068 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001069 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 +00001070 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001071};
1072
1073// template <> class codecvt<char16_t, char, mbstate_t>
1074
1075template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001076class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001077 : public locale::facet,
1078 public codecvt_base
1079{
1080public:
1081 typedef char16_t intern_type;
1082 typedef char extern_type;
1083 typedef mbstate_t state_type;
1084
Louis Dionne16fe2952018-07-11 23:14:33 +00001085 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001086 explicit codecvt(size_t __refs = 0)
1087 : locale::facet(__refs) {}
1088
Louis Dionne16fe2952018-07-11 23:14:33 +00001089 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001090 result out(state_type& __st,
1091 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1092 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1093 {
1094 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1095 }
1096
Louis Dionne16fe2952018-07-11 23:14:33 +00001097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001098 result unshift(state_type& __st,
1099 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1100 {
1101 return do_unshift(__st, __to, __to_end, __to_nxt);
1102 }
1103
Louis Dionne16fe2952018-07-11 23:14:33 +00001104 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001105 result in(state_type& __st,
1106 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1107 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1108 {
1109 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1110 }
1111
Louis Dionne16fe2952018-07-11 23:14:33 +00001112 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001113 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001114 {
1115 return do_encoding();
1116 }
1117
Louis Dionne16fe2952018-07-11 23:14:33 +00001118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001119 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001120 {
1121 return do_always_noconv();
1122 }
1123
Louis Dionne16fe2952018-07-11 23:14:33 +00001124 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001125 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1126 {
1127 return do_length(__st, __frm, __end, __mx);
1128 }
1129
Louis Dionne16fe2952018-07-11 23:14:33 +00001130 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001131 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001132 {
1133 return do_max_length();
1134 }
1135
1136 static locale::id id;
1137
1138protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001139 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001140 explicit codecvt(const char*, size_t __refs = 0)
1141 : locale::facet(__refs) {}
1142
1143 ~codecvt();
1144
1145 virtual result do_out(state_type& __st,
1146 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1147 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1148 virtual result do_in(state_type& __st,
1149 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1150 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1151 virtual result do_unshift(state_type& __st,
1152 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001153 virtual int do_encoding() const _NOEXCEPT;
1154 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001155 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 +00001156 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001157};
1158
1159// template <> class codecvt<char32_t, char, mbstate_t>
1160
1161template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001162class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001163 : public locale::facet,
1164 public codecvt_base
1165{
1166public:
1167 typedef char32_t intern_type;
1168 typedef char extern_type;
1169 typedef mbstate_t state_type;
1170
Louis Dionne16fe2952018-07-11 23:14:33 +00001171 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001172 explicit codecvt(size_t __refs = 0)
1173 : locale::facet(__refs) {}
1174
Louis Dionne16fe2952018-07-11 23:14:33 +00001175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001176 result out(state_type& __st,
1177 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1178 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1179 {
1180 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1181 }
1182
Louis Dionne16fe2952018-07-11 23:14:33 +00001183 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001184 result unshift(state_type& __st,
1185 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1186 {
1187 return do_unshift(__st, __to, __to_end, __to_nxt);
1188 }
1189
Louis Dionne16fe2952018-07-11 23:14:33 +00001190 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001191 result in(state_type& __st,
1192 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1193 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1194 {
1195 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1196 }
1197
Louis Dionne16fe2952018-07-11 23:14:33 +00001198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001199 int encoding() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001200 {
1201 return do_encoding();
1202 }
1203
Louis Dionne16fe2952018-07-11 23:14:33 +00001204 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001205 bool always_noconv() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001206 {
1207 return do_always_noconv();
1208 }
1209
Louis Dionne16fe2952018-07-11 23:14:33 +00001210 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001211 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1212 {
1213 return do_length(__st, __frm, __end, __mx);
1214 }
1215
Louis Dionne16fe2952018-07-11 23:14:33 +00001216 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001217 int max_length() const _NOEXCEPT
Howard Hinnantc51e1022010-05-11 19:42:16 +00001218 {
1219 return do_max_length();
1220 }
1221
1222 static locale::id id;
1223
1224protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001226 explicit codecvt(const char*, size_t __refs = 0)
1227 : locale::facet(__refs) {}
1228
1229 ~codecvt();
1230
1231 virtual result do_out(state_type& __st,
1232 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1233 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1234 virtual result do_in(state_type& __st,
1235 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1236 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1237 virtual result do_unshift(state_type& __st,
1238 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
Howard Hinnant7c9e5732011-05-31 15:34:58 +00001239 virtual int do_encoding() const _NOEXCEPT;
1240 virtual bool do_always_noconv() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001241 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 +00001242 virtual int do_max_length() const _NOEXCEPT;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001243};
1244
Howard Hinnantc51e1022010-05-11 19:42:16 +00001245// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1246
1247template <class _InternT, class _ExternT, class _StateT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001248class _LIBCPP_TEMPLATE_VIS codecvt_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00001249 : public codecvt<_InternT, _ExternT, _StateT>
1250{
1251public:
Louis Dionne16fe2952018-07-11 23:14:33 +00001252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001253 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1254 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
Louis Dionne16fe2952018-07-11 23:14:33 +00001255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001256 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1257 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1258protected:
1259 ~codecvt_byname();
1260};
1261
1262template <class _InternT, class _ExternT, class _StateT>
1263codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1264{
1265}
1266
Louis Dionneb5ae3a72020-10-02 14:29:48 -04001267_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
1268_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
1269_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
1270_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001271
Howard Hinnantc834c512011-11-29 18:15:50 +00001272template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001273struct __narrow_to_utf8
1274{
1275 template <class _OutputIterator, class _CharT>
1276 _OutputIterator
1277 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1278};
1279
1280template <>
1281struct __narrow_to_utf8<8>
1282{
1283 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001284 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001285 _OutputIterator
1286 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1287 {
1288 for (; __wb < __we; ++__wb, ++__s)
1289 *__s = *__wb;
1290 return __s;
1291 }
1292};
1293
1294template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001295struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001296 : public codecvt<char16_t, char, mbstate_t>
1297{
Louis Dionne16fe2952018-07-11 23:14:33 +00001298 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001299 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1300
Louis Dionne5254b372018-10-25 12:13:43 +00001301 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001302
1303 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001305 _OutputIterator
1306 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1307 {
1308 result __r = ok;
1309 mbstate_t __mb;
1310 while (__wb < __we && __r != error)
1311 {
1312 const int __sz = 32;
1313 char __buf[__sz];
1314 char* __bn;
1315 const char16_t* __wn = (const char16_t*)__wb;
1316 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1317 __buf, __buf+__sz, __bn);
1318 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1319 __throw_runtime_error("locale not supported");
1320 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1321 *__s = *__p;
1322 __wb = (const _CharT*)__wn;
1323 }
1324 return __s;
1325 }
1326};
1327
1328template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001329struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001330 : public codecvt<char32_t, char, mbstate_t>
1331{
Louis Dionne16fe2952018-07-11 23:14:33 +00001332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001333 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1334
Louis Dionne5254b372018-10-25 12:13:43 +00001335 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001336
1337 template <class _OutputIterator, class _CharT>
Louis Dionne16fe2952018-07-11 23:14:33 +00001338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001339 _OutputIterator
1340 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1341 {
1342 result __r = ok;
1343 mbstate_t __mb;
1344 while (__wb < __we && __r != error)
1345 {
1346 const int __sz = 32;
1347 char __buf[__sz];
1348 char* __bn;
1349 const char32_t* __wn = (const char32_t*)__wb;
1350 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1351 __buf, __buf+__sz, __bn);
1352 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1353 __throw_runtime_error("locale not supported");
1354 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1355 *__s = *__p;
1356 __wb = (const _CharT*)__wn;
1357 }
1358 return __s;
1359 }
1360};
1361
Howard Hinnantc834c512011-11-29 18:15:50 +00001362template <size_t _Np>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001363struct __widen_from_utf8
1364{
1365 template <class _OutputIterator>
1366 _OutputIterator
1367 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1368};
1369
1370template <>
1371struct __widen_from_utf8<8>
1372{
1373 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001375 _OutputIterator
1376 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1377 {
1378 for (; __nb < __ne; ++__nb, ++__s)
1379 *__s = *__nb;
1380 return __s;
1381 }
1382};
1383
1384template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001385struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001386 : public codecvt<char16_t, char, mbstate_t>
1387{
Louis Dionne16fe2952018-07-11 23:14:33 +00001388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001389 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1390
Louis Dionne5254b372018-10-25 12:13:43 +00001391 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001392
1393 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001395 _OutputIterator
1396 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1397 {
1398 result __r = ok;
1399 mbstate_t __mb;
1400 while (__nb < __ne && __r != error)
1401 {
1402 const int __sz = 32;
1403 char16_t __buf[__sz];
1404 char16_t* __bn;
1405 const char* __nn = __nb;
1406 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1407 __buf, __buf+__sz, __bn);
1408 if (__r == codecvt_base::error || __nn == __nb)
1409 __throw_runtime_error("locale not supported");
1410 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
Martin Storsjö971fc1c2020-10-27 13:01:54 +02001411 *__s = *__p;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001412 __nb = __nn;
1413 }
1414 return __s;
1415 }
1416};
1417
1418template <>
Louis Dionne5254b372018-10-25 12:13:43 +00001419struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001420 : public codecvt<char32_t, char, mbstate_t>
1421{
Louis Dionne16fe2952018-07-11 23:14:33 +00001422 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001423 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1424
Louis Dionne5254b372018-10-25 12:13:43 +00001425 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001426
1427 template <class _OutputIterator>
Louis Dionne16fe2952018-07-11 23:14:33 +00001428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001429 _OutputIterator
1430 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1431 {
1432 result __r = ok;
1433 mbstate_t __mb;
1434 while (__nb < __ne && __r != error)
1435 {
1436 const int __sz = 32;
1437 char32_t __buf[__sz];
1438 char32_t* __bn;
1439 const char* __nn = __nb;
1440 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1441 __buf, __buf+__sz, __bn);
1442 if (__r == codecvt_base::error || __nn == __nb)
1443 __throw_runtime_error("locale not supported");
1444 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
Martin Storsjö971fc1c2020-10-27 13:01:54 +02001445 *__s = *__p;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001446 __nb = __nn;
1447 }
1448 return __s;
1449 }
1450};
1451
1452// template <class charT> class numpunct
1453
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001454template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001455
1456template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001457class _LIBCPP_TYPE_VIS numpunct<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001458 : public locale::facet
1459{
1460public:
1461 typedef char char_type;
1462 typedef basic_string<char_type> string_type;
1463
1464 explicit numpunct(size_t __refs = 0);
1465
Louis Dionne16fe2952018-07-11 23:14:33 +00001466 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1467 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1468 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1469 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1470 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001471
1472 static locale::id id;
1473
1474protected:
1475 ~numpunct();
1476 virtual char_type do_decimal_point() const;
1477 virtual char_type do_thousands_sep() const;
1478 virtual string do_grouping() const;
1479 virtual string_type do_truename() const;
1480 virtual string_type do_falsename() const;
1481
1482 char_type __decimal_point_;
1483 char_type __thousands_sep_;
1484 string __grouping_;
1485};
1486
1487template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001488class _LIBCPP_TYPE_VIS numpunct<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001489 : public locale::facet
1490{
1491public:
1492 typedef wchar_t char_type;
1493 typedef basic_string<char_type> string_type;
1494
1495 explicit numpunct(size_t __refs = 0);
1496
Louis Dionne16fe2952018-07-11 23:14:33 +00001497 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1498 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1499 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1500 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1501 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001502
1503 static locale::id id;
1504
1505protected:
1506 ~numpunct();
1507 virtual char_type do_decimal_point() const;
1508 virtual char_type do_thousands_sep() const;
1509 virtual string do_grouping() const;
1510 virtual string_type do_truename() const;
1511 virtual string_type do_falsename() const;
1512
1513 char_type __decimal_point_;
1514 char_type __thousands_sep_;
1515 string __grouping_;
1516};
1517
1518// template <class charT> class numpunct_byname
1519
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001520template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001521
1522template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001523class _LIBCPP_TYPE_VIS numpunct_byname<char>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001524: public numpunct<char>
1525{
1526public:
1527 typedef char char_type;
1528 typedef basic_string<char_type> string_type;
1529
1530 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1531 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1532
1533protected:
1534 ~numpunct_byname();
1535
1536private:
1537 void __init(const char*);
1538};
1539
1540template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001541class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001542: public numpunct<wchar_t>
1543{
1544public:
1545 typedef wchar_t char_type;
1546 typedef basic_string<char_type> string_type;
1547
1548 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1549 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1550
1551protected:
1552 ~numpunct_byname();
1553
1554private:
1555 void __init(const char*);
1556};
1557
1558_LIBCPP_END_NAMESPACE_STD
1559
1560#endif // _LIBCPP___LOCALE