blob: b461831a9979e3c0e501d9d73e9faf2ceb0914a2 [file] [log] [blame]
Andrew Top61a84952019-04-30 15:07:33 -07001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Kaido Kert788710a2023-06-05 07:50:22 -07004// 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
Andrew Top61a84952019-04-30 15:07:33 -07007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___LOCALE
11#define _LIBCPP___LOCALE
12
Kaido Kert788710a2023-06-05 07:50:22 -070013#include <__availability>
Andrew Top61a84952019-04-30 15:07:33 -070014#include <__config>
Andrew Top61a84952019-04-30 15:07:33 -070015#include <cctype>
Kaido Kert788710a2023-06-05 07:50:22 -070016#include <cstdint>
Kaido Kert56d7c4e2024-04-13 12:59:27 -070017#include <cstdlib>
Andrew Top61a84952019-04-30 15:07:33 -070018#include <locale.h>
Kaido Kert788710a2023-06-05 07:50:22 -070019#include <mutex>
20#include <string>
21
22// Some platforms require more includes than others. Keep the includes on all plaforms for now.
23#include <cstddef>
24#include <cstring>
25
Andrew Top61a84952019-04-30 15:07:33 -070026#if defined(_LIBCPP_MSVCRT_LIKE)
Kaido Kert788710a2023-06-05 07:50:22 -070027# include <__support/win32/locale_win32.h>
28#elif defined(_AIX) || defined(__MVS__)
29# include <__support/ibm/xlocale.h>
Andrew Top61a84952019-04-30 15:07:33 -070030#elif defined(__ANDROID__)
Kaido Kert788710a2023-06-05 07:50:22 -070031# include <__support/android/locale_bionic.h>
Andrew Top61a84952019-04-30 15:07:33 -070032#elif defined(__sun__)
Kaido Kert788710a2023-06-05 07:50:22 -070033# include <__support/solaris/xlocale.h>
Andrew Top61a84952019-04-30 15:07:33 -070034# include <xlocale.h>
Andrew Top61a84952019-04-30 15:07:33 -070035#elif defined(_NEWLIB_VERSION)
Kaido Kert788710a2023-06-05 07:50:22 -070036# include <__support/newlib/xlocale.h>
37#elif defined(__OpenBSD__)
38# include <__support/openbsd/xlocale.h>
39#elif (defined(__APPLE__) || defined(__FreeBSD__))
Andrew Top61a84952019-04-30 15:07:33 -070040# include <xlocale.h>
41#elif defined(__Fuchsia__)
Kaido Kert788710a2023-06-05 07:50:22 -070042# include <__support/fuchsia/xlocale.h>
43#elif defined(__wasi__)
44// WASI libc uses musl's locales support.
45# include <__support/musl/xlocale.h>
Andrew Top61a84952019-04-30 15:07:33 -070046#elif defined(_LIBCPP_HAS_MUSL_LIBC)
Kaido Kert788710a2023-06-05 07:50:22 -070047# include <__support/musl/xlocale.h>
Andrew Top61a84952019-04-30 15:07:33 -070048#endif
49
50#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Kaido Kert788710a2023-06-05 07:50:22 -070051# pragma GCC system_header
Andrew Top61a84952019-04-30 15:07:33 -070052#endif
53
54_LIBCPP_BEGIN_NAMESPACE_STD
55
56#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
57struct __libcpp_locale_guard {
58 _LIBCPP_INLINE_VISIBILITY
59 __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
60
61 _LIBCPP_INLINE_VISIBILITY
62 ~__libcpp_locale_guard() {
63 if (__old_loc_)
64 uselocale(__old_loc_);
65 }
66
67 locale_t __old_loc_;
68private:
69 __libcpp_locale_guard(__libcpp_locale_guard const&);
70 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
71};
72#elif defined(_LIBCPP_MSVCRT_LIKE)
73struct __libcpp_locale_guard {
74 __libcpp_locale_guard(locale_t __l) :
Kaido Kert788710a2023-06-05 07:50:22 -070075 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) {
76 // Setting the locale can be expensive even when the locale given is
77 // already the current locale, so do an explicit check to see if the
78 // current locale is already the one we want.
79 const char* __lc = __setlocale(nullptr);
80 // If every category is the same, the locale string will simply be the
81 // locale name, otherwise it will be a semicolon-separated string listing
82 // each category. In the second case, we know at least one category won't
83 // be what we want, so we only have to check the first case.
84 if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) {
85 __locale_all = _strdup(__lc);
86 if (__locale_all == nullptr)
87 __throw_bad_alloc();
88 __setlocale(__l.__get_locale());
89 }
90 }
Andrew Top61a84952019-04-30 15:07:33 -070091 ~__libcpp_locale_guard() {
Kaido Kert788710a2023-06-05 07:50:22 -070092 // The CRT documentation doesn't explicitly say, but setlocale() does the
93 // right thing when given a semicolon-separated list of locale settings
94 // for the different categories in the same format as returned by
95 // setlocale(LC_ALL, nullptr).
96 if (__locale_all != nullptr) {
97 __setlocale(__locale_all);
98 free(__locale_all);
99 }
100 _configthreadlocale(__status);
101 }
102 static const char* __setlocale(const char* __locale) {
103 const char* __new_locale = setlocale(LC_ALL, __locale);
104 if (__new_locale == nullptr)
105 __throw_bad_alloc();
106 return __new_locale;
Andrew Top61a84952019-04-30 15:07:33 -0700107 }
108 int __status;
Kaido Kert788710a2023-06-05 07:50:22 -0700109 char* __locale_all = nullptr;
Andrew Top61a84952019-04-30 15:07:33 -0700110};
111#endif
112
Andrew Top61a84952019-04-30 15:07:33 -0700113class _LIBCPP_TYPE_VIS locale;
114
115template <class _Facet>
116_LIBCPP_INLINE_VISIBILITY
117bool
118has_facet(const locale&) _NOEXCEPT;
119
120template <class _Facet>
121_LIBCPP_INLINE_VISIBILITY
122const _Facet&
123use_facet(const locale&);
124
125class _LIBCPP_TYPE_VIS locale
126{
127public:
128 // types:
129 class _LIBCPP_TYPE_VIS facet;
130 class _LIBCPP_TYPE_VIS id;
131
132 typedef int category;
133 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
134 static const category // values assigned here are for exposition only
135 none = 0,
136 collate = LC_COLLATE_MASK,
137 ctype = LC_CTYPE_MASK,
138 monetary = LC_MONETARY_MASK,
139 numeric = LC_NUMERIC_MASK,
140 time = LC_TIME_MASK,
141 messages = LC_MESSAGES_MASK,
142 all = collate | ctype | monetary | numeric | time | messages;
143
144 // construct/copy/destroy:
145 locale() _NOEXCEPT;
146 locale(const locale&) _NOEXCEPT;
147 explicit locale(const char*);
148 explicit locale(const string&);
149 locale(const locale&, const char*, category);
150 locale(const locale&, const string&, category);
151 template <class _Facet>
152 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
153 locale(const locale&, const locale&, category);
154
155 ~locale();
156
157 const locale& operator=(const locale&) _NOEXCEPT;
158
159 template <class _Facet>
160 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
161 locale combine(const locale&) const;
162
163 // locale operations:
164 string name() const;
165 bool operator==(const locale&) const;
166 bool operator!=(const locale& __y) const {return !(*this == __y);}
167 template <class _CharT, class _Traits, class _Allocator>
168 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
169 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
170 const basic_string<_CharT, _Traits, _Allocator>&) const;
171
172 // global locale objects:
173 static locale global(const locale&);
174 static const locale& classic();
175
176private:
177 class __imp;
178 __imp* __locale_;
179
180 void __install_ctor(const locale&, facet*, long);
181 static locale& __global();
182 bool has_facet(id&) const;
183 const facet* use_facet(id&) const;
184
185 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT;
186 template <class _Facet> friend const _Facet& use_facet(const locale&);
187};
188
189class _LIBCPP_TYPE_VIS locale::facet
190 : public __shared_count
191{
192protected:
193 _LIBCPP_INLINE_VISIBILITY
194 explicit facet(size_t __refs = 0)
195 : __shared_count(static_cast<long>(__refs)-1) {}
196
Kaido Kert788710a2023-06-05 07:50:22 -0700197 ~facet() override;
Andrew Top61a84952019-04-30 15:07:33 -0700198
199// facet(const facet&) = delete; // effectively done in __shared_count
200// void operator=(const facet&) = delete;
201private:
Kaido Kert788710a2023-06-05 07:50:22 -0700202 void __on_zero_shared() _NOEXCEPT override;
Andrew Top61a84952019-04-30 15:07:33 -0700203};
204
205class _LIBCPP_TYPE_VIS locale::id
206{
207 once_flag __flag_;
208 int32_t __id_;
209
210 static int32_t __next_id;
211public:
212 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
Kaido Kert788710a2023-06-05 07:50:22 -0700213 void operator=(const id&) = delete;
214 id(const id&) = delete;
215
Andrew Top61a84952019-04-30 15:07:33 -0700216private:
217 void __init();
Andrew Top61a84952019-04-30 15:07:33 -0700218public: // only needed for tests
219 long __get();
220
221 friend class locale;
222 friend class locale::__imp;
223};
224
225template <class _Facet>
226inline _LIBCPP_INLINE_VISIBILITY
227locale::locale(const locale& __other, _Facet* __f)
228{
229 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
230}
231
232template <class _Facet>
233locale
234locale::combine(const locale& __other) const
235{
236 if (!_VSTD::has_facet<_Facet>(__other))
237 __throw_runtime_error("locale::combine: locale missing facet");
238
239 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
240}
241
242template <class _Facet>
243inline _LIBCPP_INLINE_VISIBILITY
244bool
245has_facet(const locale& __l) _NOEXCEPT
246{
247 return __l.has_facet(_Facet::id);
248}
249
250template <class _Facet>
251inline _LIBCPP_INLINE_VISIBILITY
252const _Facet&
253use_facet(const locale& __l)
254{
255 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
256}
257
258// template <class _CharT> class collate;
259
260template <class _CharT>
261class _LIBCPP_TEMPLATE_VIS collate
262 : public locale::facet
263{
264public:
265 typedef _CharT char_type;
266 typedef basic_string<char_type> string_type;
267
268 _LIBCPP_INLINE_VISIBILITY
269 explicit collate(size_t __refs = 0)
270 : locale::facet(__refs) {}
271
272 _LIBCPP_INLINE_VISIBILITY
273 int compare(const char_type* __lo1, const char_type* __hi1,
274 const char_type* __lo2, const char_type* __hi2) const
275 {
276 return do_compare(__lo1, __hi1, __lo2, __hi2);
277 }
278
Kaido Kert788710a2023-06-05 07:50:22 -0700279 // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work
280 // around a dllimport bug that expects an external instantiation.
Andrew Top61a84952019-04-30 15:07:33 -0700281 _LIBCPP_INLINE_VISIBILITY
Kaido Kert788710a2023-06-05 07:50:22 -0700282 _LIBCPP_ALWAYS_INLINE
Andrew Top61a84952019-04-30 15:07:33 -0700283 string_type transform(const char_type* __lo, const char_type* __hi) const
284 {
285 return do_transform(__lo, __hi);
286 }
287
288 _LIBCPP_INLINE_VISIBILITY
289 long hash(const char_type* __lo, const char_type* __hi) const
290 {
291 return do_hash(__lo, __hi);
292 }
293
294 static locale::id id;
295
296protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700297 ~collate() override;
Andrew Top61a84952019-04-30 15:07:33 -0700298 virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
299 const char_type* __lo2, const char_type* __hi2) const;
300 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
301 {return string_type(__lo, __hi);}
302 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
303};
304
305template <class _CharT> locale::id collate<_CharT>::id;
306
307template <class _CharT>
308collate<_CharT>::~collate()
309{
310}
311
312template <class _CharT>
313int
314collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
315 const char_type* __lo2, const char_type* __hi2) const
316{
317 for (; __lo2 != __hi2; ++__lo1, ++__lo2)
318 {
319 if (__lo1 == __hi1 || *__lo1 < *__lo2)
320 return -1;
321 if (*__lo2 < *__lo1)
322 return 1;
323 }
324 return __lo1 != __hi1;
325}
326
327template <class _CharT>
328long
329collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
330{
331 size_t __h = 0;
332 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
333 const size_t __mask = size_t(0xF) << (__sr + 4);
334 for(const char_type* __p = __lo; __p != __hi; ++__p)
335 {
336 __h = (__h << 4) + static_cast<size_t>(*__p);
337 size_t __g = __h & __mask;
338 __h ^= __g | (__g >> __sr);
339 }
340 return static_cast<long>(__h);
341}
342
Kaido Kert788710a2023-06-05 07:50:22 -0700343extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>;
344#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
345extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>;
346#endif
Andrew Top61a84952019-04-30 15:07:33 -0700347
348// template <class CharT> class collate_byname;
349
350template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
351
352template <>
353class _LIBCPP_TYPE_VIS collate_byname<char>
354 : public collate<char>
355{
Kaido Kert788710a2023-06-05 07:50:22 -0700356 locale_t __l_;
Andrew Top61a84952019-04-30 15:07:33 -0700357public:
358 typedef char char_type;
359 typedef basic_string<char_type> string_type;
360
361 explicit collate_byname(const char* __n, size_t __refs = 0);
362 explicit collate_byname(const string& __n, size_t __refs = 0);
363
364protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700365 ~collate_byname() override;
366 int do_compare(const char_type* __lo1, const char_type* __hi1,
367 const char_type* __lo2, const char_type* __hi2) const override;
368 string_type do_transform(const char_type* __lo, const char_type* __hi) const override;
Andrew Top61a84952019-04-30 15:07:33 -0700369};
370
Kaido Kert788710a2023-06-05 07:50:22 -0700371#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -0700372template <>
373class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
374 : public collate<wchar_t>
375{
Kaido Kert788710a2023-06-05 07:50:22 -0700376 locale_t __l_;
Andrew Top61a84952019-04-30 15:07:33 -0700377public:
378 typedef wchar_t char_type;
379 typedef basic_string<char_type> string_type;
380
381 explicit collate_byname(const char* __n, size_t __refs = 0);
382 explicit collate_byname(const string& __n, size_t __refs = 0);
383
384protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700385 ~collate_byname() override;
Andrew Top61a84952019-04-30 15:07:33 -0700386
Kaido Kert788710a2023-06-05 07:50:22 -0700387 int do_compare(const char_type* __lo1, const char_type* __hi1,
388 const char_type* __lo2, const char_type* __hi2) const override;
389 string_type do_transform(const char_type* __lo, const char_type* __hi) const override;
Andrew Top61a84952019-04-30 15:07:33 -0700390};
Kaido Kert788710a2023-06-05 07:50:22 -0700391#endif
Andrew Top61a84952019-04-30 15:07:33 -0700392
393template <class _CharT, class _Traits, class _Allocator>
394bool
395locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
396 const basic_string<_CharT, _Traits, _Allocator>& __y) const
397{
398 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
399 __x.data(), __x.data() + __x.size(),
400 __y.data(), __y.data() + __y.size()) < 0;
401}
402
403// template <class charT> class ctype
404
405class _LIBCPP_TYPE_VIS ctype_base
406{
407public:
Kaido Kert788710a2023-06-05 07:50:22 -0700408#if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE)
409 typedef unsigned long mask;
410 static const mask space = 1<<0;
411 static const mask print = 1<<1;
412 static const mask cntrl = 1<<2;
413 static const mask upper = 1<<3;
414 static const mask lower = 1<<4;
415 static const mask alpha = 1<<5;
416 static const mask digit = 1<<6;
417 static const mask punct = 1<<7;
418 static const mask xdigit = 1<<8;
419 static const mask blank = 1<<9;
420#if defined(__BIONIC__)
421 // Historically this was a part of regex_traits rather than ctype_base. The
422 // historical value of the constant is preserved for ABI compatibility.
423 static const mask __regex_word = 0x8000;
424#else
425 static const mask __regex_word = 1<<10;
426#endif // defined(__BIONIC__)
427#elif defined(__GLIBC__)
Andrew Top61a84952019-04-30 15:07:33 -0700428 typedef unsigned short mask;
429 static const mask space = _ISspace;
430 static const mask print = _ISprint;
431 static const mask cntrl = _IScntrl;
432 static const mask upper = _ISupper;
433 static const mask lower = _ISlower;
434 static const mask alpha = _ISalpha;
435 static const mask digit = _ISdigit;
436 static const mask punct = _ISpunct;
437 static const mask xdigit = _ISxdigit;
438 static const mask blank = _ISblank;
Kaido Kert788710a2023-06-05 07:50:22 -0700439#if defined(__mips__)
440 static const mask __regex_word = static_cast<mask>(_ISbit(15));
441#else
442 static const mask __regex_word = 0x80;
443#endif
Andrew Top61a84952019-04-30 15:07:33 -0700444#elif defined(_LIBCPP_MSVCRT_LIKE)
445 typedef unsigned short mask;
446 static const mask space = _SPACE;
447 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT;
448 static const mask cntrl = _CONTROL;
449 static const mask upper = _UPPER;
450 static const mask lower = _LOWER;
451 static const mask alpha = _ALPHA;
452 static const mask digit = _DIGIT;
453 static const mask punct = _PUNCT;
454 static const mask xdigit = _HEX;
455 static const mask blank = _BLANK;
Kaido Kert788710a2023-06-05 07:50:22 -0700456 static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used
Andrew Top61a84952019-04-30 15:07:33 -0700457# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
Kaido Kert788710a2023-06-05 07:50:22 -0700458# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
Andrew Top61a84952019-04-30 15:07:33 -0700459#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
460# ifdef __APPLE__
461 typedef __uint32_t mask;
462# elif defined(__FreeBSD__)
463 typedef unsigned long mask;
464# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
465 typedef unsigned short mask;
466# endif
467 static const mask space = _CTYPE_S;
468 static const mask print = _CTYPE_R;
469 static const mask cntrl = _CTYPE_C;
470 static const mask upper = _CTYPE_U;
471 static const mask lower = _CTYPE_L;
472 static const mask alpha = _CTYPE_A;
473 static const mask digit = _CTYPE_D;
474 static const mask punct = _CTYPE_P;
475 static const mask xdigit = _CTYPE_X;
476
477# if defined(__NetBSD__)
478 static const mask blank = _CTYPE_BL;
Kaido Kert788710a2023-06-05 07:50:22 -0700479 // NetBSD defines classes up to 0x2000
480 // see sys/ctype_bits.h, _CTYPE_Q
481 static const mask __regex_word = 0x8000;
Andrew Top61a84952019-04-30 15:07:33 -0700482# else
483 static const mask blank = _CTYPE_B;
Kaido Kert788710a2023-06-05 07:50:22 -0700484 static const mask __regex_word = 0x80;
Andrew Top61a84952019-04-30 15:07:33 -0700485# endif
486#elif defined(__sun__) || defined(_AIX)
487 typedef unsigned int mask;
488 static const mask space = _ISSPACE;
489 static const mask print = _ISPRINT;
490 static const mask cntrl = _ISCNTRL;
491 static const mask upper = _ISUPPER;
492 static const mask lower = _ISLOWER;
493 static const mask alpha = _ISALPHA;
494 static const mask digit = _ISDIGIT;
495 static const mask punct = _ISPUNCT;
496 static const mask xdigit = _ISXDIGIT;
497 static const mask blank = _ISBLANK;
Kaido Kert788710a2023-06-05 07:50:22 -0700498# if defined(_AIX)
499 static const mask __regex_word = 0x8000;
500# else
501 static const mask __regex_word = 0x80;
502# endif
Andrew Top61a84952019-04-30 15:07:33 -0700503#elif defined(_NEWLIB_VERSION)
504 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
505 typedef char mask;
506 static const mask space = _S;
507 static const mask print = _P | _U | _L | _N | _B;
508 static const mask cntrl = _C;
509 static const mask upper = _U;
510 static const mask lower = _L;
511 static const mask alpha = _U | _L;
512 static const mask digit = _N;
513 static const mask punct = _P;
514 static const mask xdigit = _X | _N;
515 static const mask blank = _B;
Kaido Kert788710a2023-06-05 07:50:22 -0700516 // mask is already fully saturated, use a different type in regex_type_traits.
517 static const unsigned short __regex_word = 0x100;
Andrew Top61a84952019-04-30 15:07:33 -0700518# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
519# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
520# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
Kaido Kert788710a2023-06-05 07:50:22 -0700521#elif defined(__MVS__)
522# if defined(__NATIVE_ASCII_F)
523 typedef unsigned int mask;
524 static const mask space = _ISSPACE_A;
525 static const mask print = _ISPRINT_A;
526 static const mask cntrl = _ISCNTRL_A;
527 static const mask upper = _ISUPPER_A;
528 static const mask lower = _ISLOWER_A;
529 static const mask alpha = _ISALPHA_A;
530 static const mask digit = _ISDIGIT_A;
531 static const mask punct = _ISPUNCT_A;
532 static const mask xdigit = _ISXDIGIT_A;
533 static const mask blank = _ISBLANK_A;
534# else
535 typedef unsigned short mask;
536 static const mask space = __ISSPACE;
537 static const mask print = __ISPRINT;
538 static const mask cntrl = __ISCNTRL;
539 static const mask upper = __ISUPPER;
540 static const mask lower = __ISLOWER;
541 static const mask alpha = __ISALPHA;
542 static const mask digit = __ISDIGIT;
543 static const mask punct = __ISPUNCT;
544 static const mask xdigit = __ISXDIGIT;
545 static const mask blank = __ISBLANK;
546# endif
547 static const mask __regex_word = 0x8000;
Andrew Top61a84952019-04-30 15:07:33 -0700548#else
Kaido Kert788710a2023-06-05 07:50:22 -0700549# error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE?
Andrew Top61a84952019-04-30 15:07:33 -0700550#endif
551 static const mask alnum = alpha | digit;
552 static const mask graph = alnum | punct;
553
554 _LIBCPP_INLINE_VISIBILITY ctype_base() {}
Kaido Kert788710a2023-06-05 07:50:22 -0700555
556 static_assert((__regex_word & ~(std::make_unsigned<mask>::type)(space | print | cntrl | upper | lower | alpha |
557 digit | punct | xdigit | blank)) == __regex_word,
558 "__regex_word can't overlap other bits");
Andrew Top61a84952019-04-30 15:07:33 -0700559};
560
561template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
562
Kaido Kert788710a2023-06-05 07:50:22 -0700563#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -0700564template <>
565class _LIBCPP_TYPE_VIS ctype<wchar_t>
566 : public locale::facet,
567 public ctype_base
568{
569public:
570 typedef wchar_t char_type;
571
572 _LIBCPP_INLINE_VISIBILITY
573 explicit ctype(size_t __refs = 0)
574 : locale::facet(__refs) {}
575
576 _LIBCPP_INLINE_VISIBILITY
577 bool is(mask __m, char_type __c) const
578 {
579 return do_is(__m, __c);
580 }
581
582 _LIBCPP_INLINE_VISIBILITY
583 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
584 {
585 return do_is(__low, __high, __vec);
586 }
587
588 _LIBCPP_INLINE_VISIBILITY
589 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
590 {
591 return do_scan_is(__m, __low, __high);
592 }
593
594 _LIBCPP_INLINE_VISIBILITY
595 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
596 {
597 return do_scan_not(__m, __low, __high);
598 }
599
600 _LIBCPP_INLINE_VISIBILITY
601 char_type toupper(char_type __c) const
602 {
603 return do_toupper(__c);
604 }
605
606 _LIBCPP_INLINE_VISIBILITY
607 const char_type* toupper(char_type* __low, const char_type* __high) const
608 {
609 return do_toupper(__low, __high);
610 }
611
612 _LIBCPP_INLINE_VISIBILITY
613 char_type tolower(char_type __c) const
614 {
615 return do_tolower(__c);
616 }
617
618 _LIBCPP_INLINE_VISIBILITY
619 const char_type* tolower(char_type* __low, const char_type* __high) const
620 {
621 return do_tolower(__low, __high);
622 }
623
624 _LIBCPP_INLINE_VISIBILITY
625 char_type widen(char __c) const
626 {
627 return do_widen(__c);
628 }
629
630 _LIBCPP_INLINE_VISIBILITY
631 const char* widen(const char* __low, const char* __high, char_type* __to) const
632 {
633 return do_widen(__low, __high, __to);
634 }
635
636 _LIBCPP_INLINE_VISIBILITY
637 char narrow(char_type __c, char __dfault) const
638 {
639 return do_narrow(__c, __dfault);
640 }
641
642 _LIBCPP_INLINE_VISIBILITY
643 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
644 {
645 return do_narrow(__low, __high, __dfault, __to);
646 }
647
648 static locale::id id;
649
650protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700651 ~ctype() override;
Andrew Top61a84952019-04-30 15:07:33 -0700652 virtual bool do_is(mask __m, char_type __c) const;
653 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
654 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
655 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
656 virtual char_type do_toupper(char_type) const;
657 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
658 virtual char_type do_tolower(char_type) const;
659 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
660 virtual char_type do_widen(char) const;
661 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
662 virtual char do_narrow(char_type, char __dfault) const;
663 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
664};
Kaido Kert788710a2023-06-05 07:50:22 -0700665#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -0700666
667template <>
668class _LIBCPP_TYPE_VIS ctype<char>
669 : public locale::facet, public ctype_base
670{
671 const mask* __tab_;
672 bool __del_;
673public:
674 typedef char char_type;
675
Kaido Kert788710a2023-06-05 07:50:22 -0700676 explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0);
Andrew Top61a84952019-04-30 15:07:33 -0700677
678 _LIBCPP_INLINE_VISIBILITY
679 bool is(mask __m, char_type __c) const
680 {
681 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
682 }
683
684 _LIBCPP_INLINE_VISIBILITY
685 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
686 {
687 for (; __low != __high; ++__low, ++__vec)
688 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
689 return __low;
690 }
691
692 _LIBCPP_INLINE_VISIBILITY
693 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
694 {
695 for (; __low != __high; ++__low)
696 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
697 break;
698 return __low;
699 }
700
701 _LIBCPP_INLINE_VISIBILITY
702 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
703 {
704 for (; __low != __high; ++__low)
Kaido Kert788710a2023-06-05 07:50:22 -0700705 if (!isascii(*__low) || !(__tab_[static_cast<int>(*__low)] & __m))
Andrew Top61a84952019-04-30 15:07:33 -0700706 break;
707 return __low;
708 }
709
710 _LIBCPP_INLINE_VISIBILITY
711 char_type toupper(char_type __c) const
712 {
713 return do_toupper(__c);
714 }
715
716 _LIBCPP_INLINE_VISIBILITY
717 const char_type* toupper(char_type* __low, const char_type* __high) const
718 {
719 return do_toupper(__low, __high);
720 }
721
722 _LIBCPP_INLINE_VISIBILITY
723 char_type tolower(char_type __c) const
724 {
725 return do_tolower(__c);
726 }
727
728 _LIBCPP_INLINE_VISIBILITY
729 const char_type* tolower(char_type* __low, const char_type* __high) const
730 {
731 return do_tolower(__low, __high);
732 }
733
734 _LIBCPP_INLINE_VISIBILITY
735 char_type widen(char __c) const
736 {
737 return do_widen(__c);
738 }
739
740 _LIBCPP_INLINE_VISIBILITY
741 const char* widen(const char* __low, const char* __high, char_type* __to) const
742 {
743 return do_widen(__low, __high, __to);
744 }
745
746 _LIBCPP_INLINE_VISIBILITY
747 char narrow(char_type __c, char __dfault) const
748 {
749 return do_narrow(__c, __dfault);
750 }
751
752 _LIBCPP_INLINE_VISIBILITY
753 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
754 {
755 return do_narrow(__low, __high, __dfault, __to);
756 }
757
758 static locale::id id;
759
760#ifdef _CACHED_RUNES
761 static const size_t table_size = _CACHED_RUNES;
762#else
763 static const size_t table_size = 256; // FIXME: Don't hardcode this.
764#endif
765 _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;}
766 static const mask* classic_table() _NOEXCEPT;
767#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
768 static const int* __classic_upper_table() _NOEXCEPT;
769 static const int* __classic_lower_table() _NOEXCEPT;
770#endif
771#if defined(__NetBSD__)
772 static const short* __classic_upper_table() _NOEXCEPT;
773 static const short* __classic_lower_table() _NOEXCEPT;
774#endif
Kaido Kert788710a2023-06-05 07:50:22 -0700775#if defined(__MVS__)
776 static const unsigned short* __classic_upper_table() _NOEXCEPT;
777 static const unsigned short* __classic_lower_table() _NOEXCEPT;
778#endif
Andrew Top61a84952019-04-30 15:07:33 -0700779
780protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700781 ~ctype() override;
Andrew Top61a84952019-04-30 15:07:33 -0700782 virtual char_type do_toupper(char_type __c) const;
783 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
784 virtual char_type do_tolower(char_type __c) const;
785 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
786 virtual char_type do_widen(char __c) const;
787 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
788 virtual char do_narrow(char_type __c, char __dfault) const;
789 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
790};
791
792// template <class CharT> class ctype_byname;
793
794template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
795
796template <>
797class _LIBCPP_TYPE_VIS ctype_byname<char>
798 : public ctype<char>
799{
Kaido Kert788710a2023-06-05 07:50:22 -0700800 locale_t __l_;
Andrew Top61a84952019-04-30 15:07:33 -0700801
802public:
803 explicit ctype_byname(const char*, size_t = 0);
804 explicit ctype_byname(const string&, size_t = 0);
805
806protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700807 ~ctype_byname() override;
808 char_type do_toupper(char_type) const override;
809 const char_type* do_toupper(char_type* __low, const char_type* __high) const override;
810 char_type do_tolower(char_type) const override;
811 const char_type* do_tolower(char_type* __low, const char_type* __high) const override;
Andrew Top61a84952019-04-30 15:07:33 -0700812};
813
Kaido Kert788710a2023-06-05 07:50:22 -0700814#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -0700815template <>
816class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
817 : public ctype<wchar_t>
818{
Kaido Kert788710a2023-06-05 07:50:22 -0700819 locale_t __l_;
Andrew Top61a84952019-04-30 15:07:33 -0700820
821public:
822 explicit ctype_byname(const char*, size_t = 0);
823 explicit ctype_byname(const string&, size_t = 0);
824
825protected:
Kaido Kert788710a2023-06-05 07:50:22 -0700826 ~ctype_byname() override;
827 bool do_is(mask __m, char_type __c) const override;
828 const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const override;
829 const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const override;
830 const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const override;
831 char_type do_toupper(char_type) const override;
832 const char_type* do_toupper(char_type* __low, const char_type* __high) const override;
833 char_type do_tolower(char_type) const override;
834 const char_type* do_tolower(char_type* __low, const char_type* __high) const override;
835 char_type do_widen(char) const override;
836 const char* do_widen(const char* __low, const char* __high, char_type* __dest) const override;
837 char do_narrow(char_type, char __dfault) const override;
838 const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const override;
Andrew Top61a84952019-04-30 15:07:33 -0700839};
Kaido Kert788710a2023-06-05 07:50:22 -0700840#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -0700841
842template <class _CharT>
843inline _LIBCPP_INLINE_VISIBILITY
844bool
845isspace(_CharT __c, const locale& __loc)
846{
Kaido Kert788710a2023-06-05 07:50:22 -0700847 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700848}
849
850template <class _CharT>
851inline _LIBCPP_INLINE_VISIBILITY
852bool
853isprint(_CharT __c, const locale& __loc)
854{
Kaido Kert788710a2023-06-05 07:50:22 -0700855 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700856}
857
858template <class _CharT>
859inline _LIBCPP_INLINE_VISIBILITY
860bool
861iscntrl(_CharT __c, const locale& __loc)
862{
Kaido Kert788710a2023-06-05 07:50:22 -0700863 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700864}
865
866template <class _CharT>
867inline _LIBCPP_INLINE_VISIBILITY
868bool
869isupper(_CharT __c, const locale& __loc)
870{
Kaido Kert788710a2023-06-05 07:50:22 -0700871 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700872}
873
874template <class _CharT>
875inline _LIBCPP_INLINE_VISIBILITY
876bool
877islower(_CharT __c, const locale& __loc)
878{
Kaido Kert788710a2023-06-05 07:50:22 -0700879 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700880}
881
882template <class _CharT>
883inline _LIBCPP_INLINE_VISIBILITY
884bool
885isalpha(_CharT __c, const locale& __loc)
886{
Kaido Kert788710a2023-06-05 07:50:22 -0700887 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700888}
889
890template <class _CharT>
891inline _LIBCPP_INLINE_VISIBILITY
892bool
893isdigit(_CharT __c, const locale& __loc)
894{
Kaido Kert788710a2023-06-05 07:50:22 -0700895 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700896}
897
898template <class _CharT>
899inline _LIBCPP_INLINE_VISIBILITY
900bool
901ispunct(_CharT __c, const locale& __loc)
902{
Kaido Kert788710a2023-06-05 07:50:22 -0700903 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700904}
905
906template <class _CharT>
907inline _LIBCPP_INLINE_VISIBILITY
908bool
909isxdigit(_CharT __c, const locale& __loc)
910{
Kaido Kert788710a2023-06-05 07:50:22 -0700911 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700912}
913
914template <class _CharT>
915inline _LIBCPP_INLINE_VISIBILITY
916bool
917isalnum(_CharT __c, const locale& __loc)
918{
Kaido Kert788710a2023-06-05 07:50:22 -0700919 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700920}
921
922template <class _CharT>
923inline _LIBCPP_INLINE_VISIBILITY
924bool
925isgraph(_CharT __c, const locale& __loc)
926{
Kaido Kert788710a2023-06-05 07:50:22 -0700927 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
Andrew Top61a84952019-04-30 15:07:33 -0700928}
929
930template <class _CharT>
Kaido Kert56d7c4e2024-04-13 12:59:27 -0700931_LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) {
932 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c);
933}
934
935template <class _CharT>
Andrew Top61a84952019-04-30 15:07:33 -0700936inline _LIBCPP_INLINE_VISIBILITY
937_CharT
938toupper(_CharT __c, const locale& __loc)
939{
Kaido Kert788710a2023-06-05 07:50:22 -0700940 return std::use_facet<ctype<_CharT> >(__loc).toupper(__c);
Andrew Top61a84952019-04-30 15:07:33 -0700941}
942
943template <class _CharT>
944inline _LIBCPP_INLINE_VISIBILITY
945_CharT
946tolower(_CharT __c, const locale& __loc)
947{
Kaido Kert788710a2023-06-05 07:50:22 -0700948 return std::use_facet<ctype<_CharT> >(__loc).tolower(__c);
Andrew Top61a84952019-04-30 15:07:33 -0700949}
950
951// codecvt_base
952
953class _LIBCPP_TYPE_VIS codecvt_base
954{
955public:
956 _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
957 enum result {ok, partial, error, noconv};
958};
959
960// template <class internT, class externT, class stateT> class codecvt;
961
962template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
963
964// template <> class codecvt<char, char, mbstate_t>
965
966template <>
967class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
968 : public locale::facet,
969 public codecvt_base
970{
971public:
972 typedef char intern_type;
973 typedef char extern_type;
974 typedef mbstate_t state_type;
975
976 _LIBCPP_INLINE_VISIBILITY
977 explicit codecvt(size_t __refs = 0)
978 : locale::facet(__refs) {}
979
980 _LIBCPP_INLINE_VISIBILITY
981 result out(state_type& __st,
982 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
983 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
984 {
985 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
986 }
987
988 _LIBCPP_INLINE_VISIBILITY
989 result unshift(state_type& __st,
990 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
991 {
992 return do_unshift(__st, __to, __to_end, __to_nxt);
993 }
994
995 _LIBCPP_INLINE_VISIBILITY
996 result in(state_type& __st,
997 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
998 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
999 {
1000 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1001 }
1002
1003 _LIBCPP_INLINE_VISIBILITY
1004 int encoding() const _NOEXCEPT
1005 {
1006 return do_encoding();
1007 }
1008
1009 _LIBCPP_INLINE_VISIBILITY
1010 bool always_noconv() const _NOEXCEPT
1011 {
1012 return do_always_noconv();
1013 }
1014
1015 _LIBCPP_INLINE_VISIBILITY
1016 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1017 {
1018 return do_length(__st, __frm, __end, __mx);
1019 }
1020
1021 _LIBCPP_INLINE_VISIBILITY
1022 int max_length() const _NOEXCEPT
1023 {
1024 return do_max_length();
1025 }
1026
1027 static locale::id id;
1028
1029protected:
1030 _LIBCPP_INLINE_VISIBILITY
1031 explicit codecvt(const char*, size_t __refs = 0)
1032 : locale::facet(__refs) {}
1033
Kaido Kert788710a2023-06-05 07:50:22 -07001034 ~codecvt() override;
Andrew Top61a84952019-04-30 15:07:33 -07001035
1036 virtual result do_out(state_type& __st,
1037 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1038 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1039 virtual result do_in(state_type& __st,
1040 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1041 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1042 virtual result do_unshift(state_type& __st,
1043 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1044 virtual int do_encoding() const _NOEXCEPT;
1045 virtual bool do_always_noconv() const _NOEXCEPT;
1046 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1047 virtual int do_max_length() const _NOEXCEPT;
1048};
1049
1050// template <> class codecvt<wchar_t, char, mbstate_t>
1051
Kaido Kert788710a2023-06-05 07:50:22 -07001052#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -07001053template <>
1054class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
1055 : public locale::facet,
1056 public codecvt_base
1057{
Kaido Kert788710a2023-06-05 07:50:22 -07001058 locale_t __l_;
Andrew Top61a84952019-04-30 15:07:33 -07001059public:
1060 typedef wchar_t intern_type;
1061 typedef char extern_type;
1062 typedef mbstate_t state_type;
1063
1064 explicit codecvt(size_t __refs = 0);
1065
1066 _LIBCPP_INLINE_VISIBILITY
1067 result out(state_type& __st,
1068 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1069 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1070 {
1071 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1072 }
1073
1074 _LIBCPP_INLINE_VISIBILITY
1075 result unshift(state_type& __st,
1076 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1077 {
1078 return do_unshift(__st, __to, __to_end, __to_nxt);
1079 }
1080
1081 _LIBCPP_INLINE_VISIBILITY
1082 result in(state_type& __st,
1083 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1084 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1085 {
1086 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1087 }
1088
1089 _LIBCPP_INLINE_VISIBILITY
1090 int encoding() const _NOEXCEPT
1091 {
1092 return do_encoding();
1093 }
1094
1095 _LIBCPP_INLINE_VISIBILITY
1096 bool always_noconv() const _NOEXCEPT
1097 {
1098 return do_always_noconv();
1099 }
1100
1101 _LIBCPP_INLINE_VISIBILITY
1102 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1103 {
1104 return do_length(__st, __frm, __end, __mx);
1105 }
1106
1107 _LIBCPP_INLINE_VISIBILITY
1108 int max_length() const _NOEXCEPT
1109 {
1110 return do_max_length();
1111 }
1112
1113 static locale::id id;
1114
1115protected:
1116 explicit codecvt(const char*, size_t __refs = 0);
1117
Kaido Kert788710a2023-06-05 07:50:22 -07001118 ~codecvt() override;
Andrew Top61a84952019-04-30 15:07:33 -07001119
1120 virtual result do_out(state_type& __st,
1121 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1122 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1123 virtual result do_in(state_type& __st,
1124 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1125 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1126 virtual result do_unshift(state_type& __st,
1127 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1128 virtual int do_encoding() const _NOEXCEPT;
1129 virtual bool do_always_noconv() const _NOEXCEPT;
1130 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1131 virtual int do_max_length() const _NOEXCEPT;
1132};
Kaido Kert788710a2023-06-05 07:50:22 -07001133#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -07001134
Kaido Kert788710a2023-06-05 07:50:22 -07001135// template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
Andrew Top61a84952019-04-30 15:07:33 -07001136
1137template <>
Kaido Kert788710a2023-06-05 07:50:22 -07001138class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
Andrew Top61a84952019-04-30 15:07:33 -07001139 : public locale::facet,
1140 public codecvt_base
1141{
1142public:
1143 typedef char16_t intern_type;
1144 typedef char extern_type;
1145 typedef mbstate_t state_type;
1146
1147 _LIBCPP_INLINE_VISIBILITY
1148 explicit codecvt(size_t __refs = 0)
1149 : locale::facet(__refs) {}
1150
1151 _LIBCPP_INLINE_VISIBILITY
1152 result out(state_type& __st,
1153 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1154 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1155 {
1156 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1157 }
1158
1159 _LIBCPP_INLINE_VISIBILITY
1160 result unshift(state_type& __st,
1161 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1162 {
1163 return do_unshift(__st, __to, __to_end, __to_nxt);
1164 }
1165
1166 _LIBCPP_INLINE_VISIBILITY
1167 result in(state_type& __st,
1168 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1169 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1170 {
1171 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1172 }
1173
1174 _LIBCPP_INLINE_VISIBILITY
1175 int encoding() const _NOEXCEPT
1176 {
1177 return do_encoding();
1178 }
1179
1180 _LIBCPP_INLINE_VISIBILITY
1181 bool always_noconv() const _NOEXCEPT
1182 {
1183 return do_always_noconv();
1184 }
1185
1186 _LIBCPP_INLINE_VISIBILITY
1187 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1188 {
1189 return do_length(__st, __frm, __end, __mx);
1190 }
1191
1192 _LIBCPP_INLINE_VISIBILITY
1193 int max_length() const _NOEXCEPT
1194 {
1195 return do_max_length();
1196 }
1197
1198 static locale::id id;
1199
1200protected:
1201 _LIBCPP_INLINE_VISIBILITY
1202 explicit codecvt(const char*, size_t __refs = 0)
1203 : locale::facet(__refs) {}
1204
Kaido Kert788710a2023-06-05 07:50:22 -07001205 ~codecvt() override;
Andrew Top61a84952019-04-30 15:07:33 -07001206
1207 virtual result do_out(state_type& __st,
1208 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1209 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1210 virtual result do_in(state_type& __st,
1211 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1212 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1213 virtual result do_unshift(state_type& __st,
1214 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1215 virtual int do_encoding() const _NOEXCEPT;
1216 virtual bool do_always_noconv() const _NOEXCEPT;
1217 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1218 virtual int do_max_length() const _NOEXCEPT;
1219};
1220
Kaido Kert788710a2023-06-05 07:50:22 -07001221#ifndef _LIBCPP_HAS_NO_CHAR8_T
1222
1223// template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
Andrew Top61a84952019-04-30 15:07:33 -07001224
1225template <>
Kaido Kert788710a2023-06-05 07:50:22 -07001226class _LIBCPP_TYPE_VIS codecvt<char16_t, char8_t, mbstate_t>
1227 : public locale::facet,
1228 public codecvt_base
1229{
1230public:
1231 typedef char16_t intern_type;
1232 typedef char8_t extern_type;
1233 typedef mbstate_t state_type;
1234
1235 _LIBCPP_INLINE_VISIBILITY
1236 explicit codecvt(size_t __refs = 0)
1237 : locale::facet(__refs) {}
1238
1239 _LIBCPP_INLINE_VISIBILITY
1240 result out(state_type& __st,
1241 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1242 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1243 {
1244 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1245 }
1246
1247 _LIBCPP_INLINE_VISIBILITY
1248 result unshift(state_type& __st,
1249 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1250 {
1251 return do_unshift(__st, __to, __to_end, __to_nxt);
1252 }
1253
1254 _LIBCPP_INLINE_VISIBILITY
1255 result in(state_type& __st,
1256 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1257 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1258 {
1259 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1260 }
1261
1262 _LIBCPP_INLINE_VISIBILITY
1263 int encoding() const _NOEXCEPT
1264 {
1265 return do_encoding();
1266 }
1267
1268 _LIBCPP_INLINE_VISIBILITY
1269 bool always_noconv() const _NOEXCEPT
1270 {
1271 return do_always_noconv();
1272 }
1273
1274 _LIBCPP_INLINE_VISIBILITY
1275 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1276 {
1277 return do_length(__st, __frm, __end, __mx);
1278 }
1279
1280 _LIBCPP_INLINE_VISIBILITY
1281 int max_length() const _NOEXCEPT
1282 {
1283 return do_max_length();
1284 }
1285
1286 static locale::id id;
1287
1288protected:
1289 _LIBCPP_INLINE_VISIBILITY
1290 explicit codecvt(const char*, size_t __refs = 0)
1291 : locale::facet(__refs) {}
1292
1293 ~codecvt() override;
1294
1295 virtual result do_out(state_type& __st,
1296 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1297 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1298 virtual result do_in(state_type& __st,
1299 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1300 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1301 virtual result do_unshift(state_type& __st,
1302 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1303 virtual int do_encoding() const _NOEXCEPT;
1304 virtual bool do_always_noconv() const _NOEXCEPT;
1305 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1306 virtual int do_max_length() const _NOEXCEPT;
1307};
1308
1309#endif
1310
1311// template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
1312
1313template <>
1314class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
Andrew Top61a84952019-04-30 15:07:33 -07001315 : public locale::facet,
1316 public codecvt_base
1317{
1318public:
1319 typedef char32_t intern_type;
1320 typedef char extern_type;
1321 typedef mbstate_t state_type;
1322
1323 _LIBCPP_INLINE_VISIBILITY
1324 explicit codecvt(size_t __refs = 0)
1325 : locale::facet(__refs) {}
1326
1327 _LIBCPP_INLINE_VISIBILITY
1328 result out(state_type& __st,
1329 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1330 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1331 {
1332 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1333 }
1334
1335 _LIBCPP_INLINE_VISIBILITY
1336 result unshift(state_type& __st,
1337 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1338 {
1339 return do_unshift(__st, __to, __to_end, __to_nxt);
1340 }
1341
1342 _LIBCPP_INLINE_VISIBILITY
1343 result in(state_type& __st,
1344 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1345 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1346 {
1347 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1348 }
1349
1350 _LIBCPP_INLINE_VISIBILITY
1351 int encoding() const _NOEXCEPT
1352 {
1353 return do_encoding();
1354 }
1355
1356 _LIBCPP_INLINE_VISIBILITY
1357 bool always_noconv() const _NOEXCEPT
1358 {
1359 return do_always_noconv();
1360 }
1361
1362 _LIBCPP_INLINE_VISIBILITY
1363 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1364 {
1365 return do_length(__st, __frm, __end, __mx);
1366 }
1367
1368 _LIBCPP_INLINE_VISIBILITY
1369 int max_length() const _NOEXCEPT
1370 {
1371 return do_max_length();
1372 }
1373
1374 static locale::id id;
1375
1376protected:
1377 _LIBCPP_INLINE_VISIBILITY
1378 explicit codecvt(const char*, size_t __refs = 0)
1379 : locale::facet(__refs) {}
1380
Kaido Kert788710a2023-06-05 07:50:22 -07001381 ~codecvt() override;
Andrew Top61a84952019-04-30 15:07:33 -07001382
1383 virtual result do_out(state_type& __st,
1384 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1385 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1386 virtual result do_in(state_type& __st,
1387 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1388 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1389 virtual result do_unshift(state_type& __st,
1390 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1391 virtual int do_encoding() const _NOEXCEPT;
1392 virtual bool do_always_noconv() const _NOEXCEPT;
1393 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1394 virtual int do_max_length() const _NOEXCEPT;
1395};
1396
Kaido Kert788710a2023-06-05 07:50:22 -07001397#ifndef _LIBCPP_HAS_NO_CHAR8_T
1398
1399// template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
1400
1401template <>
1402class _LIBCPP_TYPE_VIS codecvt<char32_t, char8_t, mbstate_t>
1403 : public locale::facet,
1404 public codecvt_base
1405{
1406public:
1407 typedef char32_t intern_type;
1408 typedef char8_t extern_type;
1409 typedef mbstate_t state_type;
1410
1411 _LIBCPP_INLINE_VISIBILITY
1412 explicit codecvt(size_t __refs = 0)
1413 : locale::facet(__refs) {}
1414
1415 _LIBCPP_INLINE_VISIBILITY
1416 result out(state_type& __st,
1417 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1418 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1419 {
1420 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1421 }
1422
1423 _LIBCPP_INLINE_VISIBILITY
1424 result unshift(state_type& __st,
1425 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1426 {
1427 return do_unshift(__st, __to, __to_end, __to_nxt);
1428 }
1429
1430 _LIBCPP_INLINE_VISIBILITY
1431 result in(state_type& __st,
1432 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1433 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1434 {
1435 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1436 }
1437
1438 _LIBCPP_INLINE_VISIBILITY
1439 int encoding() const _NOEXCEPT
1440 {
1441 return do_encoding();
1442 }
1443
1444 _LIBCPP_INLINE_VISIBILITY
1445 bool always_noconv() const _NOEXCEPT
1446 {
1447 return do_always_noconv();
1448 }
1449
1450 _LIBCPP_INLINE_VISIBILITY
1451 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1452 {
1453 return do_length(__st, __frm, __end, __mx);
1454 }
1455
1456 _LIBCPP_INLINE_VISIBILITY
1457 int max_length() const _NOEXCEPT
1458 {
1459 return do_max_length();
1460 }
1461
1462 static locale::id id;
1463
1464protected:
1465 _LIBCPP_INLINE_VISIBILITY
1466 explicit codecvt(const char*, size_t __refs = 0)
1467 : locale::facet(__refs) {}
1468
1469 ~codecvt() override;
1470
1471 virtual result do_out(state_type& __st,
1472 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1473 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1474 virtual result do_in(state_type& __st,
1475 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1476 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1477 virtual result do_unshift(state_type& __st,
1478 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1479 virtual int do_encoding() const _NOEXCEPT;
1480 virtual bool do_always_noconv() const _NOEXCEPT;
1481 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1482 virtual int do_max_length() const _NOEXCEPT;
1483};
1484
1485#endif
1486
Andrew Top61a84952019-04-30 15:07:33 -07001487// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1488
1489template <class _InternT, class _ExternT, class _StateT>
1490class _LIBCPP_TEMPLATE_VIS codecvt_byname
1491 : public codecvt<_InternT, _ExternT, _StateT>
1492{
1493public:
1494 _LIBCPP_INLINE_VISIBILITY
1495 explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1496 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1497 _LIBCPP_INLINE_VISIBILITY
1498 explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1499 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1500protected:
Kaido Kert788710a2023-06-05 07:50:22 -07001501 ~codecvt_byname() override;
Andrew Top61a84952019-04-30 15:07:33 -07001502};
1503
Kaido Kert788710a2023-06-05 07:50:22 -07001504_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Andrew Top61a84952019-04-30 15:07:33 -07001505template <class _InternT, class _ExternT, class _StateT>
1506codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1507{
1508}
Kaido Kert788710a2023-06-05 07:50:22 -07001509_LIBCPP_SUPPRESS_DEPRECATED_POP
Andrew Top61a84952019-04-30 15:07:33 -07001510
Kaido Kert788710a2023-06-05 07:50:22 -07001511extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>;
1512#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1513extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>;
1514#endif
1515extern template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20
1516extern template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20
1517#ifndef _LIBCPP_HAS_NO_CHAR8_T
1518extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20
1519extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20
1520#endif
Andrew Top61a84952019-04-30 15:07:33 -07001521
1522template <size_t _Np>
1523struct __narrow_to_utf8
1524{
1525 template <class _OutputIterator, class _CharT>
1526 _OutputIterator
1527 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1528};
1529
1530template <>
1531struct __narrow_to_utf8<8>
1532{
1533 template <class _OutputIterator, class _CharT>
1534 _LIBCPP_INLINE_VISIBILITY
1535 _OutputIterator
1536 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1537 {
1538 for (; __wb < __we; ++__wb, ++__s)
1539 *__s = *__wb;
1540 return __s;
1541 }
1542};
1543
Kaido Kert788710a2023-06-05 07:50:22 -07001544_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Andrew Top61a84952019-04-30 15:07:33 -07001545template <>
Kaido Kert788710a2023-06-05 07:50:22 -07001546struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16>
Andrew Top61a84952019-04-30 15:07:33 -07001547 : public codecvt<char16_t, char, mbstate_t>
1548{
1549 _LIBCPP_INLINE_VISIBILITY
1550 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
Kaido Kert788710a2023-06-05 07:50:22 -07001551_LIBCPP_SUPPRESS_DEPRECATED_POP
Andrew Top61a84952019-04-30 15:07:33 -07001552
Kaido Kert788710a2023-06-05 07:50:22 -07001553 ~__narrow_to_utf8() override;
Andrew Top61a84952019-04-30 15:07:33 -07001554
1555 template <class _OutputIterator, class _CharT>
1556 _LIBCPP_INLINE_VISIBILITY
1557 _OutputIterator
1558 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1559 {
1560 result __r = ok;
1561 mbstate_t __mb;
1562 while (__wb < __we && __r != error)
1563 {
1564 const int __sz = 32;
1565 char __buf[__sz];
1566 char* __bn;
1567 const char16_t* __wn = (const char16_t*)__wb;
1568 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1569 __buf, __buf+__sz, __bn);
1570 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1571 __throw_runtime_error("locale not supported");
1572 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1573 *__s = *__p;
1574 __wb = (const _CharT*)__wn;
1575 }
1576 return __s;
1577 }
1578};
1579
Kaido Kert788710a2023-06-05 07:50:22 -07001580_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Andrew Top61a84952019-04-30 15:07:33 -07001581template <>
Kaido Kert788710a2023-06-05 07:50:22 -07001582struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32>
Andrew Top61a84952019-04-30 15:07:33 -07001583 : public codecvt<char32_t, char, mbstate_t>
1584{
1585 _LIBCPP_INLINE_VISIBILITY
1586 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
Kaido Kert788710a2023-06-05 07:50:22 -07001587_LIBCPP_SUPPRESS_DEPRECATED_POP
Andrew Top61a84952019-04-30 15:07:33 -07001588
Kaido Kert788710a2023-06-05 07:50:22 -07001589 ~__narrow_to_utf8() override;
Andrew Top61a84952019-04-30 15:07:33 -07001590
1591 template <class _OutputIterator, class _CharT>
1592 _LIBCPP_INLINE_VISIBILITY
1593 _OutputIterator
1594 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1595 {
1596 result __r = ok;
1597 mbstate_t __mb;
1598 while (__wb < __we && __r != error)
1599 {
1600 const int __sz = 32;
1601 char __buf[__sz];
1602 char* __bn;
1603 const char32_t* __wn = (const char32_t*)__wb;
1604 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1605 __buf, __buf+__sz, __bn);
1606 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1607 __throw_runtime_error("locale not supported");
1608 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1609 *__s = *__p;
1610 __wb = (const _CharT*)__wn;
1611 }
1612 return __s;
1613 }
1614};
1615
1616template <size_t _Np>
1617struct __widen_from_utf8
1618{
1619 template <class _OutputIterator>
1620 _OutputIterator
1621 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1622};
1623
1624template <>
1625struct __widen_from_utf8<8>
1626{
1627 template <class _OutputIterator>
1628 _LIBCPP_INLINE_VISIBILITY
1629 _OutputIterator
1630 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1631 {
1632 for (; __nb < __ne; ++__nb, ++__s)
1633 *__s = *__nb;
1634 return __s;
1635 }
1636};
1637
Kaido Kert788710a2023-06-05 07:50:22 -07001638_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Andrew Top61a84952019-04-30 15:07:33 -07001639template <>
Kaido Kert788710a2023-06-05 07:50:22 -07001640struct _LIBCPP_TYPE_VIS __widen_from_utf8<16>
Andrew Top61a84952019-04-30 15:07:33 -07001641 : public codecvt<char16_t, char, mbstate_t>
1642{
1643 _LIBCPP_INLINE_VISIBILITY
1644 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
Kaido Kert788710a2023-06-05 07:50:22 -07001645_LIBCPP_SUPPRESS_DEPRECATED_POP
Andrew Top61a84952019-04-30 15:07:33 -07001646
Kaido Kert788710a2023-06-05 07:50:22 -07001647 ~__widen_from_utf8() override;
Andrew Top61a84952019-04-30 15:07:33 -07001648
1649 template <class _OutputIterator>
1650 _LIBCPP_INLINE_VISIBILITY
1651 _OutputIterator
1652 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1653 {
1654 result __r = ok;
1655 mbstate_t __mb;
1656 while (__nb < __ne && __r != error)
1657 {
1658 const int __sz = 32;
1659 char16_t __buf[__sz];
1660 char16_t* __bn;
1661 const char* __nn = __nb;
1662 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1663 __buf, __buf+__sz, __bn);
1664 if (__r == codecvt_base::error || __nn == __nb)
1665 __throw_runtime_error("locale not supported");
1666 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
Kaido Kert788710a2023-06-05 07:50:22 -07001667 *__s = *__p;
Andrew Top61a84952019-04-30 15:07:33 -07001668 __nb = __nn;
1669 }
1670 return __s;
1671 }
1672};
1673
Kaido Kert788710a2023-06-05 07:50:22 -07001674_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Andrew Top61a84952019-04-30 15:07:33 -07001675template <>
Kaido Kert788710a2023-06-05 07:50:22 -07001676struct _LIBCPP_TYPE_VIS __widen_from_utf8<32>
Andrew Top61a84952019-04-30 15:07:33 -07001677 : public codecvt<char32_t, char, mbstate_t>
1678{
1679 _LIBCPP_INLINE_VISIBILITY
1680 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
Kaido Kert788710a2023-06-05 07:50:22 -07001681_LIBCPP_SUPPRESS_DEPRECATED_POP
Andrew Top61a84952019-04-30 15:07:33 -07001682
Kaido Kert788710a2023-06-05 07:50:22 -07001683 ~__widen_from_utf8() override;
Andrew Top61a84952019-04-30 15:07:33 -07001684
1685 template <class _OutputIterator>
1686 _LIBCPP_INLINE_VISIBILITY
1687 _OutputIterator
1688 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1689 {
1690 result __r = ok;
1691 mbstate_t __mb;
1692 while (__nb < __ne && __r != error)
1693 {
1694 const int __sz = 32;
1695 char32_t __buf[__sz];
1696 char32_t* __bn;
1697 const char* __nn = __nb;
1698 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1699 __buf, __buf+__sz, __bn);
1700 if (__r == codecvt_base::error || __nn == __nb)
1701 __throw_runtime_error("locale not supported");
1702 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
Kaido Kert788710a2023-06-05 07:50:22 -07001703 *__s = *__p;
Andrew Top61a84952019-04-30 15:07:33 -07001704 __nb = __nn;
1705 }
1706 return __s;
1707 }
1708};
1709
1710// template <class charT> class numpunct
1711
1712template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
1713
1714template <>
1715class _LIBCPP_TYPE_VIS numpunct<char>
1716 : public locale::facet
1717{
1718public:
1719 typedef char char_type;
1720 typedef basic_string<char_type> string_type;
1721
1722 explicit numpunct(size_t __refs = 0);
1723
1724 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1725 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1726 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1727 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1728 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
1729
1730 static locale::id id;
1731
1732protected:
Kaido Kert788710a2023-06-05 07:50:22 -07001733 ~numpunct() override;
Andrew Top61a84952019-04-30 15:07:33 -07001734 virtual char_type do_decimal_point() const;
1735 virtual char_type do_thousands_sep() const;
1736 virtual string do_grouping() const;
1737 virtual string_type do_truename() const;
1738 virtual string_type do_falsename() const;
1739
1740 char_type __decimal_point_;
1741 char_type __thousands_sep_;
1742 string __grouping_;
1743};
1744
Kaido Kert788710a2023-06-05 07:50:22 -07001745#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -07001746template <>
1747class _LIBCPP_TYPE_VIS numpunct<wchar_t>
1748 : public locale::facet
1749{
1750public:
1751 typedef wchar_t char_type;
1752 typedef basic_string<char_type> string_type;
1753
1754 explicit numpunct(size_t __refs = 0);
1755
1756 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
1757 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
1758 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
1759 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();}
1760 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();}
1761
1762 static locale::id id;
1763
1764protected:
Kaido Kert788710a2023-06-05 07:50:22 -07001765 ~numpunct() override;
Andrew Top61a84952019-04-30 15:07:33 -07001766 virtual char_type do_decimal_point() const;
1767 virtual char_type do_thousands_sep() const;
1768 virtual string do_grouping() const;
1769 virtual string_type do_truename() const;
1770 virtual string_type do_falsename() const;
1771
1772 char_type __decimal_point_;
1773 char_type __thousands_sep_;
1774 string __grouping_;
1775};
Kaido Kert788710a2023-06-05 07:50:22 -07001776#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -07001777
1778// template <class charT> class numpunct_byname
1779
1780template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
1781
1782template <>
1783class _LIBCPP_TYPE_VIS numpunct_byname<char>
1784: public numpunct<char>
1785{
1786public:
1787 typedef char char_type;
1788 typedef basic_string<char_type> string_type;
1789
1790 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1791 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1792
1793protected:
Kaido Kert788710a2023-06-05 07:50:22 -07001794 ~numpunct_byname() override;
Andrew Top61a84952019-04-30 15:07:33 -07001795
1796private:
1797 void __init(const char*);
1798};
1799
Kaido Kert788710a2023-06-05 07:50:22 -07001800#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -07001801template <>
1802class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
1803: public numpunct<wchar_t>
1804{
1805public:
1806 typedef wchar_t char_type;
1807 typedef basic_string<char_type> string_type;
1808
1809 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1810 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1811
1812protected:
Kaido Kert788710a2023-06-05 07:50:22 -07001813 ~numpunct_byname() override;
Andrew Top61a84952019-04-30 15:07:33 -07001814
1815private:
1816 void __init(const char*);
1817};
Kaido Kert788710a2023-06-05 07:50:22 -07001818#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Andrew Top61a84952019-04-30 15:07:33 -07001819
1820_LIBCPP_END_NAMESPACE_STD
1821
Kaido Kert788710a2023-06-05 07:50:22 -07001822#endif // _LIBCPP___LOCALE