blob: e5035bd73157e4c5abc85631e139349e34f59211 [file] [log] [blame]
Louis Dionneeb8650a2021-11-17 21:25:011//===----------------------------------------------------------------------===//
Howard Hinnant3e519522010-05-11 19:42:162//
Chandler Carruth57b08b02019-01-19 10:56:403// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnant3e519522010-05-11 19:42:166//
7//===----------------------------------------------------------------------===//
8
David Chisnall14c25b82012-02-29 13:05:089// On Solaris, we need to define something to make the C99 parts of localeconv
10// visible.
11#ifdef __sun__
12#define _LCONV_C99
13#endif
14
Nikolas Klauser2a8f9a52022-02-14 17:26:0215#include <__utility/unreachable.h>
Arthur O'Dwyerbbb0f2c2022-02-11 18:00:3916#include <algorithm>
17#include <clocale>
18#include <codecvt>
19#include <cstdio>
20#include <cstdlib>
21#include <cstring>
22#include <locale>
23#include <string>
24#include <type_traits>
25#include <typeinfo>
26#include <vector>
Louis Dionne6382ec12021-09-09 17:52:3827
Louis Dionnef4c12582021-08-23 19:32:3628#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Arthur O'Dwyerbbb0f2c2022-02-11 18:00:3929# include <cwctype>
Louis Dionnef4c12582021-08-23 19:32:3630#endif
31
David Tenty1112b7b2021-10-12 15:53:1232#if defined(_AIX)
33# include <sys/localedef.h> // for __lc_ctype_ptr
34#endif
35
Louis Dionne6382ec12021-09-09 17:52:3836#if defined(_LIBCPP_MSVCRT)
37# define _CTYPE_DISABLE_MACROS
Marshall Clowb38f8f02014-07-10 15:20:2838#endif
Louis Dionne6382ec12021-09-09 17:52:3839
40#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
41# include "__support/win32/locale_win32.h"
42#elif !defined(__BIONIC__) && !defined(__NuttX__)
43# include <langinfo.h>
44#endif
45
Weiming Zhaofbfaec72017-09-19 23:18:0346#include "include/atomic_support.h"
Arthur O'Dwyer0b10bb72021-04-26 13:56:5047#include "include/sso_allocator.h"
Howard Hinnant3e519522010-05-11 19:42:1648
Marshall Clowd58e0f52013-02-07 17:20:5649// On Linux, wint_t and wchar_t have different signed-ness, and this causes
Stephan T. Lavavej7c9844b2019-10-23 18:45:3650// lots of noise in the build log, but no bugs that I know of.
Nikolas Klausera7c2a622022-02-14 17:52:2851_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
Marshall Clowd58e0f52013-02-07 17:20:5652
Arthur O'Dwyerbbb0f2c2022-02-11 18:00:3953_LIBCPP_PUSH_MACROS
54#include <__undef_macros>
55
Howard Hinnant3e519522010-05-11 19:42:1656_LIBCPP_BEGIN_NAMESPACE_STD
57
Eric Fiselierb4ddab22017-05-08 22:02:4358struct __libcpp_unique_locale {
59 __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
60
61 ~__libcpp_unique_locale() {
62 if (__loc_)
63 freelocale(__loc_);
64 }
65
66 explicit operator bool() const { return __loc_; }
67
68 locale_t& get() { return __loc_; }
69
70 locale_t __loc_;
71private:
72 __libcpp_unique_locale(__libcpp_unique_locale const&);
73 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
74};
75
Howard Hinnant9978e372011-09-28 23:39:3376#ifdef __cloc_defined
Alexis Hunt3f60bca2011-07-09 00:56:2377locale_t __cloc() {
78 // In theory this could create a race condition. In practice
79 // the race condition is non-fatal since it will just create
80 // a little resource leak. Better approach would be appreciated.
Alexis Hunt3f60bca2011-07-09 00:56:2381 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
82 return result;
Alexis Hunt3f60bca2011-07-09 00:56:2383}
Howard Hinnant9978e372011-09-28 23:39:3384#endif // __cloc_defined
Alexis Hunt3f60bca2011-07-09 00:56:2385
Howard Hinnant3e519522010-05-11 19:42:1686namespace {
87
88struct release
89{
90 void operator()(locale::facet* p) {p->__release_shared();}
91};
92
Louis Dionne706bd122021-08-09 17:26:0493template <class T, class ...Args>
94T& make(Args ...args)
Howard Hinnant3e519522010-05-11 19:42:1695{
96 static typename aligned_storage<sizeof(T)>::type buf;
Louis Dionne706bd122021-08-09 17:26:0497 auto *obj = ::new (&buf) T(args...);
Eric Fiselier807790a2017-05-05 20:32:2698 return *obj;
Howard Hinnant3e519522010-05-11 19:42:1699}
100
Howard Hinnant80a11412012-12-27 21:17:53101template <typename T, size_t N>
Howard Hinnantbd037ab2012-12-28 18:15:01102inline
Howard Hinnant80a11412012-12-27 21:17:53103_LIBCPP_CONSTEXPR
104size_t
105countof(const T (&)[N])
106{
107 return N;
108}
109
110template <typename T>
Howard Hinnantbd037ab2012-12-28 18:15:01111inline
Howard Hinnant80a11412012-12-27 21:17:53112_LIBCPP_CONSTEXPR
113size_t
114countof(const T * const begin, const T * const end)
115{
116 return static_cast<size_t>(end - begin);
117}
118
Marshall Clowd437fa52016-08-25 15:09:01119_LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
120{
121#ifndef _LIBCPP_NO_EXCEPTIONS
122 throw runtime_error(msg);
123#else
124 (void)msg;
125 _VSTD::abort();
126#endif
127}
128
Howard Hinnant3e519522010-05-11 19:42:16129}
130
Howard Hinnant16694b52012-12-12 21:14:28131const locale::category locale::none;
132const locale::category locale::collate;
133const locale::category locale::ctype;
134const locale::category locale::monetary;
135const locale::category locale::numeric;
136const locale::category locale::time;
137const locale::category locale::messages;
138const locale::category locale::all;
139
Howard Hinnant3e519522010-05-11 19:42:16140class _LIBCPP_HIDDEN locale::__imp
141 : public facet
142{
Marek Kurdeja984dca2020-12-02 07:57:02143 enum {N = 30};
Eric Fiselier541f9e22017-01-06 21:42:58144#if defined(_LIBCPP_COMPILER_MSVC)
Marshall Clow520469c2013-10-21 15:07:28145// FIXME: MSVC doesn't support aligned parameters by value.
146// I can't get the __sso_allocator to work here
147// for MSVC I think for this reason.
148 vector<facet*> facets_;
149#else
Howard Hinnant3e519522010-05-11 19:42:16150 vector<facet*, __sso_allocator<facet*, N> > facets_;
Marshall Clow520469c2013-10-21 15:07:28151#endif
Howard Hinnantc2063662011-12-01 20:21:04152 string name_;
Howard Hinnant3e519522010-05-11 19:42:16153public:
154 explicit __imp(size_t refs = 0);
155 explicit __imp(const string& name, size_t refs = 0);
156 __imp(const __imp&);
157 __imp(const __imp&, const string&, locale::category c);
158 __imp(const __imp& other, const __imp& one, locale::category c);
159 __imp(const __imp&, facet* f, long id);
160 ~__imp();
161
162 const string& name() const {return name_;}
Howard Hinnantc2063662011-12-01 20:21:04163 bool has_facet(long id) const
164 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
Howard Hinnant3e519522010-05-11 19:42:16165 const locale::facet* use_facet(long id) const;
166
167 static const locale& make_classic();
168 static locale& make_global();
169private:
170 void install(facet* f, long id);
171 template <class F> void install(F* f) {install(f, f->id.__get());}
172 template <class F> void install_from(const __imp& other);
173};
174
175locale::__imp::__imp(size_t refs)
176 : facet(refs),
Howard Hinnantc2063662011-12-01 20:21:04177 facets_(N),
178 name_("C")
Howard Hinnant3e519522010-05-11 19:42:16179{
180 facets_.clear();
Howard Hinnantc2063662011-12-01 20:21:04181 install(&make<_VSTD::collate<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36182#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04183 install(&make<_VSTD::collate<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36184#endif
Joerg Sonnenberger634b9dd2014-01-04 17:43:00185 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
Louis Dionnef4c12582021-08-23 19:32:36186#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04187 install(&make<_VSTD::ctype<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36188#endif
Howard Hinnantc2063662011-12-01 20:21:04189 install(&make<codecvt<char, char, mbstate_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36190#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04191 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36192#endif
Marek Kurdeja984dca2020-12-02 07:57:02193_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnantc2063662011-12-01 20:21:04194 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
195 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
Marek Kurdeja984dca2020-12-02 07:57:02196_LIBCPP_SUPPRESS_DEPRECATED_POP
Arthur O'Dwyer5c40c992021-04-19 01:47:08197#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:02198 install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
199 install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
200#endif
Howard Hinnantc2063662011-12-01 20:21:04201 install(&make<numpunct<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36202#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04203 install(&make<numpunct<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36204#endif
Howard Hinnantc2063662011-12-01 20:21:04205 install(&make<num_get<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36206#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04207 install(&make<num_get<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36208#endif
Howard Hinnantc2063662011-12-01 20:21:04209 install(&make<num_put<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36210#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04211 install(&make<num_put<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36212#endif
Howard Hinnantc2063662011-12-01 20:21:04213 install(&make<moneypunct<char, false> >(1u));
214 install(&make<moneypunct<char, true> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36215#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04216 install(&make<moneypunct<wchar_t, false> >(1u));
217 install(&make<moneypunct<wchar_t, true> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36218#endif
Howard Hinnantc2063662011-12-01 20:21:04219 install(&make<money_get<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36220#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04221 install(&make<money_get<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36222#endif
Howard Hinnantc2063662011-12-01 20:21:04223 install(&make<money_put<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36224#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04225 install(&make<money_put<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36226#endif
Howard Hinnantc2063662011-12-01 20:21:04227 install(&make<time_get<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36228#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04229 install(&make<time_get<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36230#endif
Howard Hinnantc2063662011-12-01 20:21:04231 install(&make<time_put<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36232#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04233 install(&make<time_put<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36234#endif
Howard Hinnantc2063662011-12-01 20:21:04235 install(&make<_VSTD::messages<char> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36236#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantc2063662011-12-01 20:21:04237 install(&make<_VSTD::messages<wchar_t> >(1u));
Louis Dionnef4c12582021-08-23 19:32:36238#endif
Howard Hinnant3e519522010-05-11 19:42:16239}
240
241locale::__imp::__imp(const string& name, size_t refs)
242 : facet(refs),
Howard Hinnantc2063662011-12-01 20:21:04243 facets_(N),
244 name_(name)
Howard Hinnant3e519522010-05-11 19:42:16245{
Howard Hinnant54b409f2010-08-11 17:04:31246#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16247 try
248 {
Louis Dionne4cd6ca12021-04-20 16:03:32249#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16250 facets_ = locale::classic().__locale_->facets_;
251 for (unsigned i = 0; i < facets_.size(); ++i)
252 if (facets_[i])
253 facets_[i]->__add_shared();
254 install(new collate_byname<char>(name_));
Louis Dionnef4c12582021-08-23 19:32:36255#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16256 install(new collate_byname<wchar_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36257#endif
Howard Hinnant3e519522010-05-11 19:42:16258 install(new ctype_byname<char>(name_));
Louis Dionnef4c12582021-08-23 19:32:36259#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16260 install(new ctype_byname<wchar_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36261#endif
Howard Hinnant3e519522010-05-11 19:42:16262 install(new codecvt_byname<char, char, mbstate_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36263#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16264 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36265#endif
Marek Kurdeja984dca2020-12-02 07:57:02266_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant3e519522010-05-11 19:42:16267 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
268 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
Marek Kurdeja984dca2020-12-02 07:57:02269_LIBCPP_SUPPRESS_DEPRECATED_POP
Arthur O'Dwyer5c40c992021-04-19 01:47:08270#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:02271 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
272 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
273#endif
Howard Hinnant3e519522010-05-11 19:42:16274 install(new numpunct_byname<char>(name_));
Louis Dionnef4c12582021-08-23 19:32:36275#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16276 install(new numpunct_byname<wchar_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36277#endif
Howard Hinnant3e519522010-05-11 19:42:16278 install(new moneypunct_byname<char, false>(name_));
279 install(new moneypunct_byname<char, true>(name_));
Louis Dionnef4c12582021-08-23 19:32:36280#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16281 install(new moneypunct_byname<wchar_t, false>(name_));
282 install(new moneypunct_byname<wchar_t, true>(name_));
Louis Dionnef4c12582021-08-23 19:32:36283#endif
Howard Hinnant3e519522010-05-11 19:42:16284 install(new time_get_byname<char>(name_));
Louis Dionnef4c12582021-08-23 19:32:36285#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16286 install(new time_get_byname<wchar_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36287#endif
Howard Hinnant3e519522010-05-11 19:42:16288 install(new time_put_byname<char>(name_));
Louis Dionnef4c12582021-08-23 19:32:36289#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16290 install(new time_put_byname<wchar_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36291#endif
Howard Hinnant3e519522010-05-11 19:42:16292 install(new messages_byname<char>(name_));
Louis Dionnef4c12582021-08-23 19:32:36293#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16294 install(new messages_byname<wchar_t>(name_));
Louis Dionnef4c12582021-08-23 19:32:36295#endif
Howard Hinnant54b409f2010-08-11 17:04:31296#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16297 }
298 catch (...)
299 {
300 for (unsigned i = 0; i < facets_.size(); ++i)
301 if (facets_[i])
302 facets_[i]->__release_shared();
303 throw;
304 }
Louis Dionne4cd6ca12021-04-20 16:03:32305#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16306}
307
Howard Hinnant3e519522010-05-11 19:42:16308locale::__imp::__imp(const __imp& other)
Howard Hinnantc2063662011-12-01 20:21:04309 : facets_(max<size_t>(N, other.facets_.size())),
310 name_(other.name_)
Howard Hinnant3e519522010-05-11 19:42:16311{
312 facets_ = other.facets_;
313 for (unsigned i = 0; i < facets_.size(); ++i)
314 if (facets_[i])
315 facets_[i]->__add_shared();
316}
317
Howard Hinnant3e519522010-05-11 19:42:16318locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
Howard Hinnantc2063662011-12-01 20:21:04319 : facets_(N),
320 name_("*")
Howard Hinnant3e519522010-05-11 19:42:16321{
322 facets_ = other.facets_;
323 for (unsigned i = 0; i < facets_.size(); ++i)
324 if (facets_[i])
325 facets_[i]->__add_shared();
Howard Hinnant54b409f2010-08-11 17:04:31326#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16327 try
328 {
Louis Dionne4cd6ca12021-04-20 16:03:32329#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16330 if (c & locale::collate)
331 {
332 install(new collate_byname<char>(name));
Louis Dionnef4c12582021-08-23 19:32:36333#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16334 install(new collate_byname<wchar_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36335#endif
Howard Hinnant3e519522010-05-11 19:42:16336 }
337 if (c & locale::ctype)
338 {
339 install(new ctype_byname<char>(name));
Louis Dionnef4c12582021-08-23 19:32:36340#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16341 install(new ctype_byname<wchar_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36342#endif
Howard Hinnant3e519522010-05-11 19:42:16343 install(new codecvt_byname<char, char, mbstate_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36344#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16345 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36346#endif
Marek Kurdeja984dca2020-12-02 07:57:02347_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant3e519522010-05-11 19:42:16348 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
349 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
Marek Kurdeja984dca2020-12-02 07:57:02350_LIBCPP_SUPPRESS_DEPRECATED_POP
Arthur O'Dwyer5c40c992021-04-19 01:47:08351#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:02352 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
353 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
354#endif
Howard Hinnant3e519522010-05-11 19:42:16355 }
356 if (c & locale::monetary)
357 {
358 install(new moneypunct_byname<char, false>(name));
359 install(new moneypunct_byname<char, true>(name));
Louis Dionnef4c12582021-08-23 19:32:36360#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16361 install(new moneypunct_byname<wchar_t, false>(name));
362 install(new moneypunct_byname<wchar_t, true>(name));
Louis Dionnef4c12582021-08-23 19:32:36363#endif
Howard Hinnant3e519522010-05-11 19:42:16364 }
365 if (c & locale::numeric)
366 {
367 install(new numpunct_byname<char>(name));
Louis Dionnef4c12582021-08-23 19:32:36368#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16369 install(new numpunct_byname<wchar_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36370#endif
Howard Hinnant3e519522010-05-11 19:42:16371 }
372 if (c & locale::time)
373 {
374 install(new time_get_byname<char>(name));
Louis Dionnef4c12582021-08-23 19:32:36375#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16376 install(new time_get_byname<wchar_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36377#endif
Howard Hinnant3e519522010-05-11 19:42:16378 install(new time_put_byname<char>(name));
Louis Dionnef4c12582021-08-23 19:32:36379#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16380 install(new time_put_byname<wchar_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36381#endif
Howard Hinnant3e519522010-05-11 19:42:16382 }
383 if (c & locale::messages)
384 {
385 install(new messages_byname<char>(name));
Louis Dionnef4c12582021-08-23 19:32:36386#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16387 install(new messages_byname<wchar_t>(name));
Louis Dionnef4c12582021-08-23 19:32:36388#endif
Howard Hinnant3e519522010-05-11 19:42:16389 }
Howard Hinnant54b409f2010-08-11 17:04:31390#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16391 }
392 catch (...)
393 {
394 for (unsigned i = 0; i < facets_.size(); ++i)
395 if (facets_[i])
396 facets_[i]->__release_shared();
397 throw;
398 }
Louis Dionne4cd6ca12021-04-20 16:03:32399#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16400}
401
402template<class F>
403inline
404void
405locale::__imp::install_from(const locale::__imp& one)
406{
407 long id = F::id.__get();
408 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
409}
410
411locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
Howard Hinnantc2063662011-12-01 20:21:04412 : facets_(N),
413 name_("*")
Howard Hinnant3e519522010-05-11 19:42:16414{
415 facets_ = other.facets_;
416 for (unsigned i = 0; i < facets_.size(); ++i)
417 if (facets_[i])
418 facets_[i]->__add_shared();
Howard Hinnant54b409f2010-08-11 17:04:31419#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16420 try
421 {
Louis Dionne4cd6ca12021-04-20 16:03:32422#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16423 if (c & locale::collate)
424 {
Howard Hinnantce48a112011-06-30 21:18:19425 install_from<_VSTD::collate<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36426#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantce48a112011-06-30 21:18:19427 install_from<_VSTD::collate<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36428#endif
Howard Hinnant3e519522010-05-11 19:42:16429 }
430 if (c & locale::ctype)
431 {
Howard Hinnantce48a112011-06-30 21:18:19432 install_from<_VSTD::ctype<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36433#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantce48a112011-06-30 21:18:19434 install_from<_VSTD::ctype<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36435#endif
Howard Hinnantce48a112011-06-30 21:18:19436 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
Marek Kurdeja984dca2020-12-02 07:57:02437_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnantce48a112011-06-30 21:18:19438 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
439 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
Marek Kurdeja984dca2020-12-02 07:57:02440_LIBCPP_SUPPRESS_DEPRECATED_POP
Arthur O'Dwyer5c40c992021-04-19 01:47:08441#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:02442 install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one);
443 install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one);
444#endif
Louis Dionnef4c12582021-08-23 19:32:36445#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantce48a112011-06-30 21:18:19446 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36447#endif
Howard Hinnant3e519522010-05-11 19:42:16448 }
449 if (c & locale::monetary)
450 {
451 install_from<moneypunct<char, false> >(one);
452 install_from<moneypunct<char, true> >(one);
Louis Dionnef4c12582021-08-23 19:32:36453#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16454 install_from<moneypunct<wchar_t, false> >(one);
455 install_from<moneypunct<wchar_t, true> >(one);
Louis Dionnef4c12582021-08-23 19:32:36456#endif
Howard Hinnant3e519522010-05-11 19:42:16457 install_from<money_get<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36458#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16459 install_from<money_get<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36460#endif
Howard Hinnant3e519522010-05-11 19:42:16461 install_from<money_put<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36462#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16463 install_from<money_put<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36464#endif
Howard Hinnant3e519522010-05-11 19:42:16465 }
466 if (c & locale::numeric)
467 {
468 install_from<numpunct<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36469#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16470 install_from<numpunct<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36471#endif
Howard Hinnant3e519522010-05-11 19:42:16472 install_from<num_get<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36473#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16474 install_from<num_get<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36475#endif
Howard Hinnant3e519522010-05-11 19:42:16476 install_from<num_put<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36477#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16478 install_from<num_put<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36479#endif
Howard Hinnant3e519522010-05-11 19:42:16480 }
481 if (c & locale::time)
482 {
483 install_from<time_get<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36484#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16485 install_from<time_get<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36486#endif
Howard Hinnant3e519522010-05-11 19:42:16487 install_from<time_put<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36488#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16489 install_from<time_put<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36490#endif
Howard Hinnant3e519522010-05-11 19:42:16491 }
492 if (c & locale::messages)
493 {
Howard Hinnantce48a112011-06-30 21:18:19494 install_from<_VSTD::messages<char> >(one);
Louis Dionnef4c12582021-08-23 19:32:36495#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnantce48a112011-06-30 21:18:19496 install_from<_VSTD::messages<wchar_t> >(one);
Louis Dionnef4c12582021-08-23 19:32:36497#endif
Howard Hinnant3e519522010-05-11 19:42:16498 }
Howard Hinnant54b409f2010-08-11 17:04:31499#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16500 }
501 catch (...)
502 {
503 for (unsigned i = 0; i < facets_.size(); ++i)
504 if (facets_[i])
505 facets_[i]->__release_shared();
506 throw;
507 }
Louis Dionne4cd6ca12021-04-20 16:03:32508#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16509}
510
511locale::__imp::__imp(const __imp& other, facet* f, long id)
Howard Hinnantc2063662011-12-01 20:21:04512 : facets_(max<size_t>(N, other.facets_.size()+1)),
513 name_("*")
Howard Hinnant3e519522010-05-11 19:42:16514{
515 f->__add_shared();
516 unique_ptr<facet, release> hold(f);
517 facets_ = other.facets_;
518 for (unsigned i = 0; i < other.facets_.size(); ++i)
519 if (facets_[i])
520 facets_[i]->__add_shared();
521 install(hold.get(), id);
522}
523
524locale::__imp::~__imp()
525{
526 for (unsigned i = 0; i < facets_.size(); ++i)
527 if (facets_[i])
528 facets_[i]->__release_shared();
529}
530
531void
532locale::__imp::install(facet* f, long id)
533{
534 f->__add_shared();
535 unique_ptr<facet, release> hold(f);
Howard Hinnantc2063662011-12-01 20:21:04536 if (static_cast<size_t>(id) >= facets_.size())
537 facets_.resize(static_cast<size_t>(id+1));
538 if (facets_[static_cast<size_t>(id)])
539 facets_[static_cast<size_t>(id)]->__release_shared();
540 facets_[static_cast<size_t>(id)] = hold.release();
Howard Hinnant3e519522010-05-11 19:42:16541}
542
543const locale::facet*
544locale::__imp::use_facet(long id) const
545{
Howard Hinnant3e519522010-05-11 19:42:16546 if (!has_facet(id))
Louis Dionne7232a842019-02-12 16:06:02547 __throw_bad_cast();
Howard Hinnantc2063662011-12-01 20:21:04548 return facets_[static_cast<size_t>(id)];
Howard Hinnant3e519522010-05-11 19:42:16549}
550
551// locale
552
553const locale&
554locale::__imp::make_classic()
555{
556 // only one thread can get in here and it only gets in once
557 static aligned_storage<sizeof(locale)>::type buf;
Joerg Sonnenberger634b9dd2014-01-04 17:43:00558 locale* c = reinterpret_cast<locale*>(&buf);
Howard Hinnantc2063662011-12-01 20:21:04559 c->__locale_ = &make<__imp>(1u);
Howard Hinnant3e519522010-05-11 19:42:16560 return *c;
561}
562
563const locale&
564locale::classic()
565{
566 static const locale& c = __imp::make_classic();
567 return c;
568}
569
570locale&
571locale::__imp::make_global()
572{
573 // only one thread can get in here and it only gets in once
574 static aligned_storage<sizeof(locale)>::type buf;
Eric Fiselier807790a2017-05-05 20:32:26575 auto *obj = ::new (&buf) locale(locale::classic());
576 return *obj;
Howard Hinnant3e519522010-05-11 19:42:16577}
578
579locale&
580locale::__global()
581{
582 static locale& g = __imp::make_global();
583 return g;
584}
585
Louis Dionne56013052021-03-01 17:09:45586locale::locale() noexcept
Howard Hinnant3e519522010-05-11 19:42:16587 : __locale_(__global().__locale_)
588{
589 __locale_->__add_shared();
590}
591
Louis Dionne56013052021-03-01 17:09:45592locale::locale(const locale& l) noexcept
Howard Hinnant3e519522010-05-11 19:42:16593 : __locale_(l.__locale_)
594{
595 __locale_->__add_shared();
596}
597
Howard Hinnantb5d866d2011-05-31 15:34:58598locale::~locale()
Howard Hinnant3e519522010-05-11 19:42:16599{
600 __locale_->__release_shared();
601}
602
603const locale&
Louis Dionne56013052021-03-01 17:09:45604locale::operator=(const locale& other) noexcept
Howard Hinnant3e519522010-05-11 19:42:16605{
606 other.__locale_->__add_shared();
607 __locale_->__release_shared();
608 __locale_ = other.__locale_;
609 return *this;
610}
611
612locale::locale(const char* name)
Howard Hinnant3e519522010-05-11 19:42:16613 : __locale_(name ? new __imp(name)
Joerg Sonnenbergerd42baff2020-01-23 01:20:09614 : (__throw_runtime_error("locale constructed with null"), nullptr))
Howard Hinnant3e519522010-05-11 19:42:16615{
616 __locale_->__add_shared();
617}
618
619locale::locale(const string& name)
620 : __locale_(new __imp(name))
621{
622 __locale_->__add_shared();
623}
624
625locale::locale(const locale& other, const char* name, category c)
Howard Hinnant3e519522010-05-11 19:42:16626 : __locale_(name ? new __imp(*other.__locale_, name, c)
Joerg Sonnenbergerd42baff2020-01-23 01:20:09627 : (__throw_runtime_error("locale constructed with null"), nullptr))
Howard Hinnant3e519522010-05-11 19:42:16628{
629 __locale_->__add_shared();
630}
631
632locale::locale(const locale& other, const string& name, category c)
633 : __locale_(new __imp(*other.__locale_, name, c))
634{
635 __locale_->__add_shared();
636}
637
638locale::locale(const locale& other, const locale& one, category c)
639 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
640{
641 __locale_->__add_shared();
642}
643
644string
645locale::name() const
646{
647 return __locale_->name();
648}
649
650void
651locale::__install_ctor(const locale& other, facet* f, long id)
652{
653 if (f)
654 __locale_ = new __imp(*other.__locale_, f, id);
655 else
656 __locale_ = other.__locale_;
657 __locale_->__add_shared();
658}
659
660locale
661locale::global(const locale& loc)
662{
663 locale& g = __global();
664 locale r = g;
665 g = loc;
666 if (g.name() != "*")
667 setlocale(LC_ALL, g.name().c_str());
668 return r;
669}
670
671bool
672locale::has_facet(id& x) const
673{
674 return __locale_->has_facet(x.__get());
675}
676
677const locale::facet*
678locale::use_facet(id& x) const
679{
680 return __locale_->use_facet(x.__get());
681}
682
683bool
684locale::operator==(const locale& y) const
685{
686 return (__locale_ == y.__locale_)
687 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
688}
689
690// locale::facet
691
692locale::facet::~facet()
693{
694}
695
696void
Louis Dionne56013052021-03-01 17:09:45697locale::facet::__on_zero_shared() noexcept
Howard Hinnant3e519522010-05-11 19:42:16698{
699 delete this;
700}
701
702// locale::id
703
704int32_t locale::id::__next_id = 0;
705
706namespace
707{
708
709class __fake_bind
710{
711 locale::id* id_;
712 void (locale::id::* pmf_)();
713public:
714 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
715 : id_(id), pmf_(pmf) {}
716
717 void operator()() const
718 {
719 (id_->*pmf_)();
720 }
721};
722
723}
724
725long
726locale::id::__get()
727{
728 call_once(__flag_, __fake_bind(&locale::id::__init, this));
729 return __id_ - 1;
730}
731
732void
733locale::id::__init()
734{
Weiming Zhaofbfaec72017-09-19 23:18:03735 __id_ = __libcpp_atomic_add(&__next_id, 1);
Howard Hinnant3e519522010-05-11 19:42:16736}
737
738// template <> class collate_byname<char>
739
740collate_byname<char>::collate_byname(const char* n, size_t refs)
741 : collate<char>(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:07742 __l_(newlocale(LC_ALL_MASK, n, 0))
Howard Hinnant3e519522010-05-11 19:42:16743{
Nikolas Klauser84fc2c32022-09-02 14:19:07744 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:01745 __throw_runtime_error("collate_byname<char>::collate_byname"
Howard Hinnant3e519522010-05-11 19:42:16746 " failed to construct for " + string(n));
747}
748
749collate_byname<char>::collate_byname(const string& name, size_t refs)
750 : collate<char>(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:07751 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
Howard Hinnant3e519522010-05-11 19:42:16752{
Nikolas Klauser84fc2c32022-09-02 14:19:07753 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:01754 __throw_runtime_error("collate_byname<char>::collate_byname"
Howard Hinnant3e519522010-05-11 19:42:16755 " failed to construct for " + name);
756}
757
758collate_byname<char>::~collate_byname()
759{
Nikolas Klauser84fc2c32022-09-02 14:19:07760 freelocale(__l_);
Howard Hinnant3e519522010-05-11 19:42:16761}
762
763int
764collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
765 const char_type* __lo2, const char_type* __hi2) const
766{
767 string_type lhs(__lo1, __hi1);
768 string_type rhs(__lo2, __hi2);
Nikolas Klauser84fc2c32022-09-02 14:19:07769 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l_);
Howard Hinnant3e519522010-05-11 19:42:16770 if (r < 0)
771 return -1;
772 if (r > 0)
773 return 1;
774 return r;
775}
776
777collate_byname<char>::string_type
778collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
779{
780 const string_type in(lo, hi);
Nikolas Klauser84fc2c32022-09-02 14:19:07781 string_type out(strxfrm_l(0, in.c_str(), 0, __l_), char());
782 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l_);
Howard Hinnant3e519522010-05-11 19:42:16783 return out;
784}
785
786// template <> class collate_byname<wchar_t>
787
Louis Dionnef4c12582021-08-23 19:32:36788#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16789collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
790 : collate<wchar_t>(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:07791 __l_(newlocale(LC_ALL_MASK, n, 0))
Howard Hinnant3e519522010-05-11 19:42:16792{
Nikolas Klauser84fc2c32022-09-02 14:19:07793 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:01794 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
Howard Hinnant3e519522010-05-11 19:42:16795 " failed to construct for " + string(n));
796}
797
798collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
799 : collate<wchar_t>(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:07800 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
Howard Hinnant3e519522010-05-11 19:42:16801{
Nikolas Klauser84fc2c32022-09-02 14:19:07802 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:01803 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
Howard Hinnant3e519522010-05-11 19:42:16804 " failed to construct for " + name);
805}
806
807collate_byname<wchar_t>::~collate_byname()
808{
Nikolas Klauser84fc2c32022-09-02 14:19:07809 freelocale(__l_);
Howard Hinnant3e519522010-05-11 19:42:16810}
811
812int
813collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
814 const char_type* __lo2, const char_type* __hi2) const
815{
816 string_type lhs(__lo1, __hi1);
817 string_type rhs(__lo2, __hi2);
Nikolas Klauser84fc2c32022-09-02 14:19:07818 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l_);
Howard Hinnant3e519522010-05-11 19:42:16819 if (r < 0)
820 return -1;
821 if (r > 0)
822 return 1;
823 return r;
824}
825
826collate_byname<wchar_t>::string_type
827collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
828{
829 const string_type in(lo, hi);
Nikolas Klauser84fc2c32022-09-02 14:19:07830 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l_), wchar_t());
831 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l_);
Howard Hinnant3e519522010-05-11 19:42:16832 return out;
833}
Louis Dionnef4c12582021-08-23 19:32:36834#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16835
Howard Hinnant16694b52012-12-12 21:14:28836const ctype_base::mask ctype_base::space;
837const ctype_base::mask ctype_base::print;
838const ctype_base::mask ctype_base::cntrl;
839const ctype_base::mask ctype_base::upper;
840const ctype_base::mask ctype_base::lower;
841const ctype_base::mask ctype_base::alpha;
842const ctype_base::mask ctype_base::digit;
843const ctype_base::mask ctype_base::punct;
844const ctype_base::mask ctype_base::xdigit;
845const ctype_base::mask ctype_base::blank;
846const ctype_base::mask ctype_base::alnum;
847const ctype_base::mask ctype_base::graph;
Stephan T. Lavavej7c9844b2019-10-23 18:45:36848
Louis Dionnef40bba42021-09-09 17:29:24849// template <> class ctype<wchar_t>;
850
Louis Dionnef4c12582021-08-23 19:32:36851#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16852locale::id ctype<wchar_t>::id;
853
854ctype<wchar_t>::~ctype()
855{
856}
857
858bool
859ctype<wchar_t>::do_is(mask m, char_type c) const
860{
Marshall Clow520469c2013-10-21 15:07:28861 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
Howard Hinnant3e519522010-05-11 19:42:16862}
863
864const wchar_t*
865ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
866{
867 for (; low != high; ++low, ++vec)
Alexis Hunt3f60bca2011-07-09 00:56:23868 *vec = static_cast<mask>(isascii(*low) ?
869 ctype<char>::classic_table()[*low] : 0);
Howard Hinnant3e519522010-05-11 19:42:16870 return low;
871}
872
873const wchar_t*
874ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
875{
876 for (; low != high; ++low)
Alexis Hunt3f60bca2011-07-09 00:56:23877 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
Howard Hinnant3e519522010-05-11 19:42:16878 break;
879 return low;
880}
881
882const wchar_t*
883ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
884{
885 for (; low != high; ++low)
Alexis Hunt3f60bca2011-07-09 00:56:23886 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
Howard Hinnant3e519522010-05-11 19:42:16887 break;
888 return low;
889}
890
891wchar_t
892ctype<wchar_t>::do_toupper(char_type c) const
893{
Howard Hinnant0c06e582011-09-29 13:33:15894#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
895 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
Vasileios Kalintiris8c58e922015-11-09 10:21:04896#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
Muiez Ahmeda1da7392022-01-14 16:35:53897 defined(__NetBSD__) || defined(__MVS__)
Alexis Hunt3f60bca2011-07-09 00:56:23898 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
Alexis Huntf0235192011-07-09 01:09:31899#else
Ed Schouten2a7ab622015-07-06 15:37:40900 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
Alexis Huntf0235192011-07-09 01:09:31901#endif
Howard Hinnant3e519522010-05-11 19:42:16902}
903
904const wchar_t*
905ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
906{
907 for (; low != high; ++low)
Howard Hinnant0c06e582011-09-29 13:33:15908#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
909 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
Vasileios Kalintiris8c58e922015-11-09 10:21:04910#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
Muiez Ahmeda1da7392022-01-14 16:35:53911 defined(__NetBSD__) || defined(__MVS__)
Alexis Hunt3f60bca2011-07-09 00:56:23912 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
913 : *low;
Alexis Huntf0235192011-07-09 01:09:31914#else
Ed Schouten2a7ab622015-07-06 15:37:40915 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
Alexis Huntf0235192011-07-09 01:09:31916#endif
Howard Hinnant3e519522010-05-11 19:42:16917 return low;
918}
919
920wchar_t
921ctype<wchar_t>::do_tolower(char_type c) const
922{
Howard Hinnant0c06e582011-09-29 13:33:15923#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
924 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
Vasileios Kalintiris8c58e922015-11-09 10:21:04925#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
Muiez Ahmeda1da7392022-01-14 16:35:53926 defined(__NetBSD__) || defined(__MVS__)
Alexis Hunt3f60bca2011-07-09 00:56:23927 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
Alexis Huntf0235192011-07-09 01:09:31928#else
Ed Schouten2a7ab622015-07-06 15:37:40929 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
Alexis Huntf0235192011-07-09 01:09:31930#endif
Howard Hinnant3e519522010-05-11 19:42:16931}
932
933const wchar_t*
934ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
935{
936 for (; low != high; ++low)
Howard Hinnant0c06e582011-09-29 13:33:15937#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
938 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
Vasileios Kalintiris8c58e922015-11-09 10:21:04939#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
Muiez Ahmeda1da7392022-01-14 16:35:53940 defined(__NetBSD__) || defined(__MVS__)
Alexis Hunt3f60bca2011-07-09 00:56:23941 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
942 : *low;
Alexis Huntf0235192011-07-09 01:09:31943#else
Ed Schouten2a7ab622015-07-06 15:37:40944 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
Alexis Huntf0235192011-07-09 01:09:31945#endif
Howard Hinnant3e519522010-05-11 19:42:16946 return low;
947}
948
949wchar_t
950ctype<wchar_t>::do_widen(char c) const
951{
952 return c;
953}
954
955const char*
956ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
957{
958 for (; low != high; ++low, ++dest)
959 *dest = *low;
960 return low;
961}
962
963char
964ctype<wchar_t>::do_narrow(char_type c, char dfault) const
965{
966 if (isascii(c))
967 return static_cast<char>(c);
968 return dfault;
969}
970
971const wchar_t*
972ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
973{
974 for (; low != high; ++low, ++dest)
975 if (isascii(*low))
Howard Hinnantc2063662011-12-01 20:21:04976 *dest = static_cast<char>(*low);
Howard Hinnant3e519522010-05-11 19:42:16977 else
978 *dest = dfault;
979 return low;
980}
Louis Dionnef4c12582021-08-23 19:32:36981#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:16982
983// template <> class ctype<char>;
984
985locale::id ctype<char>::id;
986
Muiez Ahmed049f6c22021-11-18 20:49:45987const size_t ctype<char>::table_size;
988
Howard Hinnant3e519522010-05-11 19:42:16989ctype<char>::ctype(const mask* tab, bool del, size_t refs)
990 : locale::facet(refs),
991 __tab_(tab),
992 __del_(del)
993{
Alexis Hunt3f60bca2011-07-09 00:56:23994 if (__tab_ == 0)
995 __tab_ = classic_table();
Howard Hinnant3e519522010-05-11 19:42:16996}
997
998ctype<char>::~ctype()
999{
1000 if (__tab_ && __del_)
1001 delete [] __tab_;
1002}
1003
1004char
1005ctype<char>::do_toupper(char_type c) const
1006{
Howard Hinnant0c06e582011-09-29 13:33:151007#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantc2063662011-12-01 20:21:041008 return isascii(c) ?
1009 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
Joerg Sonnenberger50544e72013-05-17 21:17:341010#elif defined(__NetBSD__)
1011 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
Muiez Ahmeda1da7392022-01-14 16:35:531012#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
Vasileios Kalintiris8c58e922015-11-09 10:21:041013 return isascii(c) ?
Joerg Sonnenberger50544e72013-05-17 21:17:341014 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
Alexis Huntf0235192011-07-09 01:09:311015#else
Ed Schouten2a7ab622015-07-06 15:37:401016 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
Alexis Huntf0235192011-07-09 01:09:311017#endif
Howard Hinnant3e519522010-05-11 19:42:161018}
1019
1020const char*
1021ctype<char>::do_toupper(char_type* low, const char_type* high) const
1022{
1023 for (; low != high; ++low)
Howard Hinnant0c06e582011-09-29 13:33:151024#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantc2063662011-12-01 20:21:041025 *low = isascii(*low) ?
1026 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
Joerg Sonnenberger50544e72013-05-17 21:17:341027#elif defined(__NetBSD__)
1028 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
Muiez Ahmeda1da7392022-01-14 16:35:531029#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
Marshall Cloweb159ee2013-02-07 14:22:511030 *low = isascii(*low) ?
1031 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
Alexis Huntf0235192011-07-09 01:09:311032#else
Ed Schouten2a7ab622015-07-06 15:37:401033 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
Alexis Huntf0235192011-07-09 01:09:311034#endif
Howard Hinnant3e519522010-05-11 19:42:161035 return low;
1036}
1037
1038char
1039ctype<char>::do_tolower(char_type c) const
1040{
Howard Hinnant0c06e582011-09-29 13:33:151041#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantc2063662011-12-01 20:21:041042 return isascii(c) ?
1043 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
Joerg Sonnenberger50544e72013-05-17 21:17:341044#elif defined(__NetBSD__)
1045 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
Muiez Ahmeda1da7392022-01-14 16:35:531046#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
Marshall Cloweb159ee2013-02-07 14:22:511047 return isascii(c) ?
1048 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
Alexis Huntf0235192011-07-09 01:09:311049#else
Ed Schouten2a7ab622015-07-06 15:37:401050 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
Alexis Huntf0235192011-07-09 01:09:311051#endif
Howard Hinnant3e519522010-05-11 19:42:161052}
1053
1054const char*
1055ctype<char>::do_tolower(char_type* low, const char_type* high) const
1056{
1057 for (; low != high; ++low)
Howard Hinnant0c06e582011-09-29 13:33:151058#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
Howard Hinnantc2063662011-12-01 20:21:041059 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
Joerg Sonnenberger50544e72013-05-17 21:17:341060#elif defined(__NetBSD__)
1061 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
Muiez Ahmeda1da7392022-01-14 16:35:531062#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
Marshall Cloweb159ee2013-02-07 14:22:511063 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
Alexis Huntf0235192011-07-09 01:09:311064#else
Ed Schouten2a7ab622015-07-06 15:37:401065 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
Alexis Huntf0235192011-07-09 01:09:311066#endif
Howard Hinnant3e519522010-05-11 19:42:161067 return low;
1068}
1069
1070char
1071ctype<char>::do_widen(char c) const
1072{
1073 return c;
1074}
1075
1076const char*
1077ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
1078{
1079 for (; low != high; ++low, ++dest)
1080 *dest = *low;
1081 return low;
1082}
1083
1084char
1085ctype<char>::do_narrow(char_type c, char dfault) const
1086{
1087 if (isascii(c))
1088 return static_cast<char>(c);
1089 return dfault;
1090}
1091
1092const char*
1093ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1094{
1095 for (; low != high; ++low, ++dest)
1096 if (isascii(*low))
1097 *dest = *low;
1098 else
1099 *dest = dfault;
1100 return low;
1101}
1102
Vasileios Kalintiris08010b52015-11-24 10:24:541103#if defined(__EMSCRIPTEN__)
Howard Hinnant9cb97002013-03-29 18:27:281104extern "C" const unsigned short ** __ctype_b_loc();
1105extern "C" const int ** __ctype_tolower_loc();
1106extern "C" const int ** __ctype_toupper_loc();
1107#endif
1108
Marshall Clow7945c8a2015-03-04 16:50:021109#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
Marshall Clow66599d82015-03-04 16:10:141110const ctype<char>::mask*
Louis Dionne56013052021-03-01 17:09:451111ctype<char>::classic_table() noexcept
Marshall Clow66599d82015-03-04 16:10:141112{
1113 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1114 cntrl, cntrl,
1115 cntrl, cntrl,
1116 cntrl, cntrl,
1117 cntrl, cntrl,
1118 cntrl, cntrl | space | blank,
1119 cntrl | space, cntrl | space,
1120 cntrl | space, cntrl | space,
1121 cntrl, cntrl,
1122 cntrl, cntrl,
1123 cntrl, cntrl,
1124 cntrl, cntrl,
1125 cntrl, cntrl,
1126 cntrl, cntrl,
1127 cntrl, cntrl,
1128 cntrl, cntrl,
1129 cntrl, cntrl,
1130 space | blank | print, punct | print,
1131 punct | print, punct | print,
1132 punct | print, punct | print,
1133 punct | print, punct | print,
1134 punct | print, punct | print,
1135 punct | print, punct | print,
1136 punct | print, punct | print,
1137 punct | print, punct | print,
1138 digit | print | xdigit, digit | print | xdigit,
1139 digit | print | xdigit, digit | print | xdigit,
1140 digit | print | xdigit, digit | print | xdigit,
1141 digit | print | xdigit, digit | print | xdigit,
1142 digit | print | xdigit, digit | print | xdigit,
1143 punct | print, punct | print,
1144 punct | print, punct | print,
1145 punct | print, punct | print,
1146 punct | print, upper | xdigit | print | alpha,
1147 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1148 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1149 upper | xdigit | print | alpha, upper | print | alpha,
1150 upper | print | alpha, upper | print | alpha,
1151 upper | print | alpha, upper | print | alpha,
1152 upper | print | alpha, upper | print | alpha,
1153 upper | print | alpha, upper | print | alpha,
1154 upper | print | alpha, upper | print | alpha,
1155 upper | print | alpha, upper | print | alpha,
1156 upper | print | alpha, upper | print | alpha,
1157 upper | print | alpha, upper | print | alpha,
1158 upper | print | alpha, upper | print | alpha,
1159 upper | print | alpha, punct | print,
1160 punct | print, punct | print,
1161 punct | print, punct | print,
1162 punct | print, lower | xdigit | print | alpha,
1163 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1164 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1165 lower | xdigit | print | alpha, lower | print | alpha,
1166 lower | print | alpha, lower | print | alpha,
1167 lower | print | alpha, lower | print | alpha,
1168 lower | print | alpha, lower | print | alpha,
1169 lower | print | alpha, lower | print | alpha,
1170 lower | print | alpha, lower | print | alpha,
1171 lower | print | alpha, lower | print | alpha,
1172 lower | print | alpha, lower | print | alpha,
1173 lower | print | alpha, lower | print | alpha,
1174 lower | print | alpha, lower | print | alpha,
1175 lower | print | alpha, punct | print,
1176 punct | print, punct | print,
1177 punct | print, cntrl,
1178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1186 };
1187 return builtin_table;
1188}
1189#else
Howard Hinnant3e519522010-05-11 19:42:161190const ctype<char>::mask*
Louis Dionne56013052021-03-01 17:09:451191ctype<char>::classic_table() noexcept
Howard Hinnant3e519522010-05-11 19:42:161192{
David Chisnall89728132011-09-21 08:39:441193#if defined(__APPLE__) || defined(__FreeBSD__)
Howard Hinnant3e519522010-05-11 19:42:161194 return _DefaultRuneLocale.__runetype;
Joerg Sonnenberger50544e72013-05-17 21:17:341195#elif defined(__NetBSD__)
1196 return _C_ctype_tab_ + 1;
Alexis Hunt3f60bca2011-07-09 00:56:231197#elif defined(__GLIBC__)
Ed Schouten2a7ab622015-07-06 15:37:401198 return _LIBCPP_GET_C_LOCALE->__ctype_b;
Martin Storsjödafbfb12021-05-06 07:18:411199#elif defined(__sun__)
David Chisnall14c25b82012-02-29 13:05:081200 return __ctype_mask;
Howard Hinnant5f878d42013-09-17 01:34:471201#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Saleem Abdulrasool8bcade52017-01-02 18:41:481202 return __pctype_func();
Vasileios Kalintiris08010b52015-11-24 10:24:541203#elif defined(__EMSCRIPTEN__)
Howard Hinnant9cb97002013-03-29 18:27:281204 return *__ctype_b_loc();
JF Bastiene9401f62015-02-25 22:16:461205#elif defined(_NEWLIB_VERSION)
1206 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1207 return _ctype_ + 1;
Howard Hinnant5d1a7012013-08-14 18:00:201208#elif defined(_AIX)
Marshall Clow028875a2013-11-19 19:16:031209 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
Muiez Ahmeda1da7392022-01-14 16:35:531210#elif defined(__MVS__)
1211# if defined(__NATIVE_ASCII_F)
1212 return const_cast<const ctype<char>::mask*> (__OBJ_DATA(__lc_ctype_a)->mask);
1213# else
1214 return const_cast<const ctype<char>::mask*> (__ctypec);
1215# endif
Alexis Hunt3f60bca2011-07-09 00:56:231216#else
David Chisnall14c25b82012-02-29 13:05:081217 // Platform not supported: abort so the person doing the port knows what to
1218 // fix
Howard Hinnant9e849ad2012-02-29 16:08:571219# warning ctype<char>::classic_table() is not implemented
Howard Hinnant1468d0c2013-07-23 16:05:561220 printf("ctype<char>::classic_table() is not implemented\n");
David Chisnall14c25b82012-02-29 13:05:081221 abort();
Alexis Hunt3f60bca2011-07-09 00:56:231222 return NULL;
1223#endif
1224}
Marshall Clow66599d82015-03-04 16:10:141225#endif
Alexis Hunt3f60bca2011-07-09 00:56:231226
Howard Hinnant0c06e582011-09-29 13:33:151227#if defined(__GLIBC__)
Alexis Hunt3f60bca2011-07-09 00:56:231228const int*
Louis Dionne56013052021-03-01 17:09:451229ctype<char>::__classic_lower_table() noexcept
Alexis Hunt3f60bca2011-07-09 00:56:231230{
Ed Schouten2a7ab622015-07-06 15:37:401231 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
Alexis Hunt3f60bca2011-07-09 00:56:231232}
1233
1234const int*
Louis Dionne56013052021-03-01 17:09:451235ctype<char>::__classic_upper_table() noexcept
Alexis Hunt3f60bca2011-07-09 00:56:231236{
Ed Schouten2a7ab622015-07-06 15:37:401237 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
Howard Hinnant3e519522010-05-11 19:42:161238}
YAMAMOTO Takashiacd7be72020-10-28 19:40:161239#elif defined(__NetBSD__)
Joerg Sonnenberger50544e72013-05-17 21:17:341240const short*
Louis Dionne56013052021-03-01 17:09:451241ctype<char>::__classic_lower_table() noexcept
Joerg Sonnenberger50544e72013-05-17 21:17:341242{
1243 return _C_tolower_tab_ + 1;
1244}
Howard Hinnant3e519522010-05-11 19:42:161245
Joerg Sonnenberger50544e72013-05-17 21:17:341246const short*
Louis Dionne56013052021-03-01 17:09:451247ctype<char>::__classic_upper_table() noexcept
Joerg Sonnenberger50544e72013-05-17 21:17:341248{
1249 return _C_toupper_tab_ + 1;
1250}
1251
Vasileios Kalintiris08010b52015-11-24 10:24:541252#elif defined(__EMSCRIPTEN__)
Howard Hinnant9cb97002013-03-29 18:27:281253const int*
Louis Dionne56013052021-03-01 17:09:451254ctype<char>::__classic_lower_table() noexcept
Howard Hinnant9cb97002013-03-29 18:27:281255{
1256 return *__ctype_tolower_loc();
1257}
1258
1259const int*
Louis Dionne56013052021-03-01 17:09:451260ctype<char>::__classic_upper_table() noexcept
Howard Hinnant9cb97002013-03-29 18:27:281261{
1262 return *__ctype_toupper_loc();
1263}
Muiez Ahmeda1da7392022-01-14 16:35:531264#elif defined(__MVS__)
1265const unsigned short*
1266ctype<char>::__classic_lower_table() _NOEXCEPT
1267{
1268# if defined(__NATIVE_ASCII_F)
1269 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower);
1270# else
1271 return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX);
1272# endif
1273}
1274const unsigned short *
1275ctype<char>::__classic_upper_table() _NOEXCEPT
1276{
1277# if defined(__NATIVE_ASCII_F)
1278 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper);
1279# else
1280 return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX);
1281# endif
1282}
1283#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
Howard Hinnant9cb97002013-03-29 18:27:281284
Howard Hinnant3e519522010-05-11 19:42:161285// template <> class ctype_byname<char>
1286
1287ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1288 : ctype<char>(0, false, refs),
Nikolas Klauser84fc2c32022-09-02 14:19:071289 __l_(newlocale(LC_ALL_MASK, name, 0))
Howard Hinnant3e519522010-05-11 19:42:161290{
Nikolas Klauser84fc2c32022-09-02 14:19:071291 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:011292 __throw_runtime_error("ctype_byname<char>::ctype_byname"
Howard Hinnant3e519522010-05-11 19:42:161293 " failed to construct for " + string(name));
1294}
1295
1296ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1297 : ctype<char>(0, false, refs),
Nikolas Klauser84fc2c32022-09-02 14:19:071298 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
Howard Hinnant3e519522010-05-11 19:42:161299{
Nikolas Klauser84fc2c32022-09-02 14:19:071300 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:011301 __throw_runtime_error("ctype_byname<char>::ctype_byname"
Howard Hinnant3e519522010-05-11 19:42:161302 " failed to construct for " + name);
1303}
1304
1305ctype_byname<char>::~ctype_byname()
1306{
Nikolas Klauser84fc2c32022-09-02 14:19:071307 freelocale(__l_);
Howard Hinnant3e519522010-05-11 19:42:161308}
1309
1310char
1311ctype_byname<char>::do_toupper(char_type c) const
1312{
Nikolas Klauser84fc2c32022-09-02 14:19:071313 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l_));
Howard Hinnant3e519522010-05-11 19:42:161314}
1315
1316const char*
1317ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1318{
1319 for (; low != high; ++low)
Nikolas Klauser84fc2c32022-09-02 14:19:071320 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l_));
Howard Hinnant3e519522010-05-11 19:42:161321 return low;
1322}
1323
1324char
1325ctype_byname<char>::do_tolower(char_type c) const
1326{
Nikolas Klauser84fc2c32022-09-02 14:19:071327 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l_));
Howard Hinnant3e519522010-05-11 19:42:161328}
1329
1330const char*
1331ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1332{
1333 for (; low != high; ++low)
Nikolas Klauser84fc2c32022-09-02 14:19:071334 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l_));
Howard Hinnant3e519522010-05-11 19:42:161335 return low;
1336}
1337
1338// template <> class ctype_byname<wchar_t>
1339
Louis Dionnef4c12582021-08-23 19:32:361340#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:161341ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1342 : ctype<wchar_t>(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:071343 __l_(newlocale(LC_ALL_MASK, name, 0))
Howard Hinnant3e519522010-05-11 19:42:161344{
Nikolas Klauser84fc2c32022-09-02 14:19:071345 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:011346 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
Howard Hinnant3e519522010-05-11 19:42:161347 " failed to construct for " + string(name));
1348}
1349
1350ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1351 : ctype<wchar_t>(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:071352 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
Howard Hinnant3e519522010-05-11 19:42:161353{
Nikolas Klauser84fc2c32022-09-02 14:19:071354 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:011355 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
Howard Hinnant3e519522010-05-11 19:42:161356 " failed to construct for " + name);
1357}
1358
1359ctype_byname<wchar_t>::~ctype_byname()
1360{
Nikolas Klauser84fc2c32022-09-02 14:19:071361 freelocale(__l_);
Howard Hinnant3e519522010-05-11 19:42:161362}
1363
1364bool
1365ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1366{
Alexis Hunt00818922011-07-09 03:40:041367#ifdef _LIBCPP_WCTYPE_IS_MASK
Nikolas Klauser84fc2c32022-09-02 14:19:071368 return static_cast<bool>(iswctype_l(c, m, __l_));
Alexis Hunt00818922011-07-09 03:40:041369#else
Howard Hinnant4df0a6a2012-08-02 18:35:071370 bool result = false;
Marshall Cloweb159ee2013-02-07 14:22:511371 wint_t ch = static_cast<wint_t>(c);
Nikolas Klauser84fc2c32022-09-02 14:19:071372 if ((m & space) == space) result |= (iswspace_l(ch, __l_) != 0);
1373 if ((m & print) == print) result |= (iswprint_l(ch, __l_) != 0);
1374 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l_) != 0);
1375 if ((m & upper) == upper) result |= (iswupper_l(ch, __l_) != 0);
1376 if ((m & lower) == lower) result |= (iswlower_l(ch, __l_) != 0);
1377 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l_) != 0);
1378 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l_) != 0);
1379 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l_) != 0);
1380 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l_) != 0);
1381 if ((m & blank) == blank) result |= (iswblank_l(ch, __l_) != 0);
Howard Hinnant0c06e582011-09-29 13:33:151382 return result;
Alexis Hunt00818922011-07-09 03:40:041383#endif
Howard Hinnant3e519522010-05-11 19:42:161384}
1385
1386const wchar_t*
1387ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1388{
1389 for (; low != high; ++low, ++vec)
1390 {
1391 if (isascii(*low))
Alexis Hunt3f60bca2011-07-09 00:56:231392 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
Howard Hinnant3e519522010-05-11 19:42:161393 else
1394 {
1395 *vec = 0;
Marshall Cloweb159ee2013-02-07 14:22:511396 wint_t ch = static_cast<wint_t>(*low);
Nikolas Klauser84fc2c32022-09-02 14:19:071397 if (iswspace_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161398 *vec |= space;
Jonathan Roelofs29f342c2015-03-11 17:00:281399#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
Nikolas Klauser84fc2c32022-09-02 14:19:071400 if (iswprint_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161401 *vec |= print;
Jonathan Roelofs29f342c2015-03-11 17:00:281402#endif
Nikolas Klauser84fc2c32022-09-02 14:19:071403 if (iswcntrl_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161404 *vec |= cntrl;
Nikolas Klauser84fc2c32022-09-02 14:19:071405 if (iswupper_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161406 *vec |= upper;
Nikolas Klauser84fc2c32022-09-02 14:19:071407 if (iswlower_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161408 *vec |= lower;
Jonathan Roelofs29f342c2015-03-11 17:00:281409#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
Nikolas Klauser84fc2c32022-09-02 14:19:071410 if (iswalpha_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161411 *vec |= alpha;
Jonathan Roelofs29f342c2015-03-11 17:00:281412#endif
Nikolas Klauser84fc2c32022-09-02 14:19:071413 if (iswdigit_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161414 *vec |= digit;
Nikolas Klauser84fc2c32022-09-02 14:19:071415 if (iswpunct_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161416 *vec |= punct;
Jonathan Roelofs29f342c2015-03-11 17:00:281417#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
Nikolas Klauser84fc2c32022-09-02 14:19:071418 if (iswxdigit_l(ch, __l_))
Howard Hinnant3e519522010-05-11 19:42:161419 *vec |= xdigit;
Jonathan Roelofs29f342c2015-03-11 17:00:281420#endif
Jonathan Roelofsf11625d2015-03-13 15:09:421421#if !defined(__sun__)
Nikolas Klauser84fc2c32022-09-02 14:19:071422 if (iswblank_l(ch, __l_))
Jonathan Roelofs29f342c2015-03-11 17:00:281423 *vec |= blank;
Jonathan Roelofsf11625d2015-03-13 15:09:421424#endif
Howard Hinnant3e519522010-05-11 19:42:161425 }
1426 }
1427 return low;
1428}
1429
1430const wchar_t*
1431ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1432{
1433 for (; low != high; ++low)
Alexis Hunt00818922011-07-09 03:40:041434 {
1435#ifdef _LIBCPP_WCTYPE_IS_MASK
Nikolas Klauser84fc2c32022-09-02 14:19:071436 if (iswctype_l(*low, m, __l_))
Howard Hinnant3e519522010-05-11 19:42:161437 break;
Alexis Hunt00818922011-07-09 03:40:041438#else
Marshall Cloweb159ee2013-02-07 14:22:511439 wint_t ch = static_cast<wint_t>(*low);
Nikolas Klauser84fc2c32022-09-02 14:19:071440 if ((m & space) == space && iswspace_l(ch, __l_)) break;
1441 if ((m & print) == print && iswprint_l(ch, __l_)) break;
1442 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_)) break;
1443 if ((m & upper) == upper && iswupper_l(ch, __l_)) break;
1444 if ((m & lower) == lower && iswlower_l(ch, __l_)) break;
1445 if ((m & alpha) == alpha && iswalpha_l(ch, __l_)) break;
1446 if ((m & digit) == digit && iswdigit_l(ch, __l_)) break;
1447 if ((m & punct) == punct && iswpunct_l(ch, __l_)) break;
1448 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_)) break;
1449 if ((m & blank) == blank && iswblank_l(ch, __l_)) break;
Alexis Hunt00818922011-07-09 03:40:041450#endif
1451 }
Howard Hinnant3e519522010-05-11 19:42:161452 return low;
1453}
1454
1455const wchar_t*
1456ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1457{
1458 for (; low != high; ++low)
Alexis Hunt00818922011-07-09 03:40:041459 {
1460#ifdef _LIBCPP_WCTYPE_IS_MASK
Nikolas Klauser84fc2c32022-09-02 14:19:071461 if (!iswctype_l(*low, m, __l_))
Howard Hinnant3e519522010-05-11 19:42:161462 break;
Alexis Hunt00818922011-07-09 03:40:041463#else
Marshall Cloweb159ee2013-02-07 14:22:511464 wint_t ch = static_cast<wint_t>(*low);
Nikolas Klauser84fc2c32022-09-02 14:19:071465 if ((m & space) == space && iswspace_l(ch, __l_)) continue;
1466 if ((m & print) == print && iswprint_l(ch, __l_)) continue;
1467 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_)) continue;
1468 if ((m & upper) == upper && iswupper_l(ch, __l_)) continue;
1469 if ((m & lower) == lower && iswlower_l(ch, __l_)) continue;
1470 if ((m & alpha) == alpha && iswalpha_l(ch, __l_)) continue;
1471 if ((m & digit) == digit && iswdigit_l(ch, __l_)) continue;
1472 if ((m & punct) == punct && iswpunct_l(ch, __l_)) continue;
1473 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_)) continue;
1474 if ((m & blank) == blank && iswblank_l(ch, __l_)) continue;
Alexis Hunt00818922011-07-09 03:40:041475 break;
1476#endif
1477 }
Howard Hinnant3e519522010-05-11 19:42:161478 return low;
1479}
1480
1481wchar_t
1482ctype_byname<wchar_t>::do_toupper(char_type c) const
1483{
Nikolas Klauser84fc2c32022-09-02 14:19:071484 return towupper_l(c, __l_);
Howard Hinnant3e519522010-05-11 19:42:161485}
1486
1487const wchar_t*
1488ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1489{
1490 for (; low != high; ++low)
Nikolas Klauser84fc2c32022-09-02 14:19:071491 *low = towupper_l(*low, __l_);
Howard Hinnant3e519522010-05-11 19:42:161492 return low;
1493}
1494
1495wchar_t
1496ctype_byname<wchar_t>::do_tolower(char_type c) const
1497{
Nikolas Klauser84fc2c32022-09-02 14:19:071498 return towlower_l(c, __l_);
Howard Hinnant3e519522010-05-11 19:42:161499}
1500
1501const wchar_t*
1502ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1503{
1504 for (; low != high; ++low)
Nikolas Klauser84fc2c32022-09-02 14:19:071505 *low = towlower_l(*low, __l_);
Howard Hinnant3e519522010-05-11 19:42:161506 return low;
1507}
1508
1509wchar_t
1510ctype_byname<wchar_t>::do_widen(char c) const
1511{
Nikolas Klauser84fc2c32022-09-02 14:19:071512 return __libcpp_btowc_l(c, __l_);
Howard Hinnant3e519522010-05-11 19:42:161513}
1514
1515const char*
1516ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1517{
1518 for (; low != high; ++low, ++dest)
Nikolas Klauser84fc2c32022-09-02 14:19:071519 *dest = __libcpp_btowc_l(*low, __l_);
Howard Hinnant3e519522010-05-11 19:42:161520 return low;
1521}
1522
1523char
1524ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1525{
Nikolas Klauser84fc2c32022-09-02 14:19:071526 int r = __libcpp_wctob_l(c, __l_);
Martin Storsjö0f5d0d42022-01-20 22:38:521527 return (r != EOF) ? static_cast<char>(r) : dfault;
Howard Hinnant3e519522010-05-11 19:42:161528}
1529
1530const wchar_t*
1531ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1532{
1533 for (; low != high; ++low, ++dest)
1534 {
Nikolas Klauser84fc2c32022-09-02 14:19:071535 int r = __libcpp_wctob_l(*low, __l_);
Martin Storsjö0f5d0d42022-01-20 22:38:521536 *dest = (r != EOF) ? static_cast<char>(r) : dfault;
Howard Hinnant3e519522010-05-11 19:42:161537 }
1538 return low;
1539}
Louis Dionnef4c12582021-08-23 19:32:361540#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:161541
1542// template <> class codecvt<char, char, mbstate_t>
1543
Howard Hinnant940e2112010-08-22 00:03:271544locale::id codecvt<char, char, mbstate_t>::id;
Howard Hinnant3e519522010-05-11 19:42:161545
1546codecvt<char, char, mbstate_t>::~codecvt()
1547{
1548}
1549
1550codecvt<char, char, mbstate_t>::result
Howard Hinnant940e2112010-08-22 00:03:271551codecvt<char, char, mbstate_t>::do_out(state_type&,
1552 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:161553 extern_type* to, extern_type*, extern_type*& to_nxt) const
1554{
1555 frm_nxt = frm;
1556 to_nxt = to;
1557 return noconv;
1558}
1559
1560codecvt<char, char, mbstate_t>::result
Howard Hinnant940e2112010-08-22 00:03:271561codecvt<char, char, mbstate_t>::do_in(state_type&,
1562 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:161563 intern_type* to, intern_type*, intern_type*& to_nxt) const
1564{
1565 frm_nxt = frm;
1566 to_nxt = to;
1567 return noconv;
1568}
1569
1570codecvt<char, char, mbstate_t>::result
Howard Hinnant940e2112010-08-22 00:03:271571codecvt<char, char, mbstate_t>::do_unshift(state_type&,
Howard Hinnant3e519522010-05-11 19:42:161572 extern_type* to, extern_type*, extern_type*& to_nxt) const
1573{
1574 to_nxt = to;
1575 return noconv;
1576}
1577
1578int
Louis Dionne56013052021-03-01 17:09:451579codecvt<char, char, mbstate_t>::do_encoding() const noexcept
Howard Hinnant3e519522010-05-11 19:42:161580{
1581 return 1;
1582}
1583
1584bool
Louis Dionne56013052021-03-01 17:09:451585codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept
Howard Hinnant3e519522010-05-11 19:42:161586{
1587 return true;
1588}
1589
1590int
1591codecvt<char, char, mbstate_t>::do_length(state_type&,
1592 const extern_type* frm, const extern_type* end, size_t mx) const
1593{
Howard Hinnantc2063662011-12-01 20:21:041594 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
Howard Hinnant3e519522010-05-11 19:42:161595}
1596
1597int
Louis Dionne56013052021-03-01 17:09:451598codecvt<char, char, mbstate_t>::do_max_length() const noexcept
Howard Hinnant3e519522010-05-11 19:42:161599{
1600 return 1;
1601}
1602
1603// template <> class codecvt<wchar_t, char, mbstate_t>
1604
Louis Dionnef4c12582021-08-23 19:32:361605#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant940e2112010-08-22 00:03:271606locale::id codecvt<wchar_t, char, mbstate_t>::id;
Howard Hinnant3e519522010-05-11 19:42:161607
1608codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1609 : locale::facet(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:071610 __l_(_LIBCPP_GET_C_LOCALE)
Howard Hinnant3e519522010-05-11 19:42:161611{
1612}
1613
1614codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1615 : locale::facet(refs),
Nikolas Klauser84fc2c32022-09-02 14:19:071616 __l_(newlocale(LC_ALL_MASK, nm, 0))
Howard Hinnant3e519522010-05-11 19:42:161617{
Nikolas Klauser84fc2c32022-09-02 14:19:071618 if (__l_ == 0)
Marshall Clowd437fa52016-08-25 15:09:011619 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
Howard Hinnant3e519522010-05-11 19:42:161620 " failed to construct for " + string(nm));
1621}
1622
1623codecvt<wchar_t, char, mbstate_t>::~codecvt()
1624{
Nikolas Klauser84fc2c32022-09-02 14:19:071625 if (__l_ != _LIBCPP_GET_C_LOCALE)
1626 freelocale(__l_);
Howard Hinnant3e519522010-05-11 19:42:161627}
1628
1629codecvt<wchar_t, char, mbstate_t>::result
1630codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
Howard Hinnant940e2112010-08-22 00:03:271631 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:161632 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1633{
1634 // look for first internal null in frm
1635 const intern_type* fend = frm;
1636 for (; fend != frm_end; ++fend)
1637 if (*fend == 0)
1638 break;
1639 // loop over all null-terminated sequences in frm
1640 to_nxt = to;
1641 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1642 {
Joerg Sonnenbergerf53c3ca2013-04-26 09:40:181643 // save state in case it is needed to recover to_nxt on error
Howard Hinnant3e519522010-05-11 19:42:161644 mbstate_t save_state = st;
Ben Craigd2f15ba2016-03-09 15:39:391645 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
Nikolas Klauser84fc2c32022-09-02 14:19:071646 static_cast<size_t>(to_end-to), &st, __l_);
Howard Hinnant3e519522010-05-11 19:42:161647 if (n == size_t(-1))
1648 {
1649 // need to recover to_nxt
1650 for (to_nxt = to; frm != frm_nxt; ++frm)
1651 {
Nikolas Klauser84fc2c32022-09-02 14:19:071652 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l_);
Howard Hinnant3e519522010-05-11 19:42:161653 if (n == size_t(-1))
1654 break;
1655 to_nxt += n;
1656 }
1657 frm_nxt = frm;
1658 return error;
1659 }
1660 if (n == 0)
1661 return partial;
1662 to_nxt += n;
1663 if (to_nxt == to_end)
1664 break;
1665 if (fend != frm_end) // set up next null terminated sequence
1666 {
1667 // Try to write the terminating null
1668 extern_type tmp[MB_LEN_MAX];
Nikolas Klauser84fc2c32022-09-02 14:19:071669 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);
Howard Hinnant3e519522010-05-11 19:42:161670 if (n == size_t(-1)) // on error
1671 return error;
Howard Hinnantc2063662011-12-01 20:21:041672 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
Howard Hinnant3e519522010-05-11 19:42:161673 return partial;
1674 for (extern_type* p = tmp; n; --n) // write it
1675 *to_nxt++ = *p++;
1676 ++frm_nxt;
1677 // look for next null in frm
1678 for (fend = frm_nxt; fend != frm_end; ++fend)
1679 if (*fend == 0)
1680 break;
1681 }
1682 }
1683 return frm_nxt == frm_end ? ok : partial;
1684}
1685
1686codecvt<wchar_t, char, mbstate_t>::result
1687codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
Howard Hinnant940e2112010-08-22 00:03:271688 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:161689 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1690{
1691 // look for first internal null in frm
1692 const extern_type* fend = frm;
1693 for (; fend != frm_end; ++fend)
1694 if (*fend == 0)
1695 break;
1696 // loop over all null-terminated sequences in frm
1697 to_nxt = to;
1698 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1699 {
Joerg Sonnenbergerf53c3ca2013-04-26 09:40:181700 // save state in case it is needed to recover to_nxt on error
Howard Hinnant3e519522010-05-11 19:42:161701 mbstate_t save_state = st;
Ben Craigd2f15ba2016-03-09 15:39:391702 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
Nikolas Klauser84fc2c32022-09-02 14:19:071703 static_cast<size_t>(to_end-to), &st, __l_);
Howard Hinnant3e519522010-05-11 19:42:161704 if (n == size_t(-1))
1705 {
1706 // need to recover to_nxt
1707 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1708 {
Ben Craigd2f15ba2016-03-09 15:39:391709 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
Nikolas Klauser84fc2c32022-09-02 14:19:071710 &save_state, __l_);
Howard Hinnant3e519522010-05-11 19:42:161711 switch (n)
1712 {
1713 case 0:
1714 ++frm;
1715 break;
Howard Hinnant27c8f622012-02-08 19:15:061716 case size_t(-1):
Howard Hinnant3e519522010-05-11 19:42:161717 frm_nxt = frm;
1718 return error;
Howard Hinnant27c8f622012-02-08 19:15:061719 case size_t(-2):
Howard Hinnant3e519522010-05-11 19:42:161720 frm_nxt = frm;
1721 return partial;
1722 default:
1723 frm += n;
1724 break;
1725 }
1726 }
1727 frm_nxt = frm;
1728 return frm_nxt == frm_end ? ok : partial;
1729 }
Joerg Sonnenberger28444b32015-06-05 15:54:261730 if (n == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:161731 return error;
1732 to_nxt += n;
1733 if (to_nxt == to_end)
1734 break;
1735 if (fend != frm_end) // set up next null terminated sequence
1736 {
1737 // Try to write the terminating null
Nikolas Klauser84fc2c32022-09-02 14:19:071738 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l_);
Howard Hinnant3e519522010-05-11 19:42:161739 if (n != 0) // on error
1740 return error;
1741 ++to_nxt;
1742 ++frm_nxt;
1743 // look for next null in frm
1744 for (fend = frm_nxt; fend != frm_end; ++fend)
1745 if (*fend == 0)
1746 break;
1747 }
1748 }
1749 return frm_nxt == frm_end ? ok : partial;
1750}
1751
1752codecvt<wchar_t, char, mbstate_t>::result
1753codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1754 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1755{
1756 to_nxt = to;
1757 extern_type tmp[MB_LEN_MAX];
Nikolas Klauser84fc2c32022-09-02 14:19:071758 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);
Howard Hinnant3e519522010-05-11 19:42:161759 if (n == size_t(-1) || n == 0) // on error
1760 return error;
1761 --n;
Howard Hinnantc2063662011-12-01 20:21:041762 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
Howard Hinnant3e519522010-05-11 19:42:161763 return partial;
1764 for (extern_type* p = tmp; n; --n) // write it
1765 *to_nxt++ = *p++;
1766 return ok;
1767}
1768
1769int
Louis Dionne56013052021-03-01 17:09:451770codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept
Howard Hinnant3e519522010-05-11 19:42:161771{
Nikolas Klauser84fc2c32022-09-02 14:19:071772 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l_) != 0)
Ed Schouten2a80cab2015-07-06 15:39:361773 return -1;
Ed Schouten2a80cab2015-07-06 15:39:361774
1775 // stateless encoding
Nikolas Klauser84fc2c32022-09-02 14:19:071776 if (__l_ == 0 || __libcpp_mb_cur_max_l(__l_) == 1) // there are no known constant length encodings
Ed Schouten2a80cab2015-07-06 15:39:361777 return 1; // which take more than 1 char to form a wchar_t
1778 return 0;
Howard Hinnant3e519522010-05-11 19:42:161779}
1780
1781bool
Louis Dionne56013052021-03-01 17:09:451782codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
Howard Hinnant3e519522010-05-11 19:42:161783{
1784 return false;
1785}
1786
1787int
1788codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1789 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1790{
1791 int nbytes = 0;
1792 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1793 {
Nikolas Klauser84fc2c32022-09-02 14:19:071794 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l_);
Howard Hinnant3e519522010-05-11 19:42:161795 switch (n)
1796 {
1797 case 0:
1798 ++nbytes;
1799 ++frm;
1800 break;
Howard Hinnant27c8f622012-02-08 19:15:061801 case size_t(-1):
1802 case size_t(-2):
Howard Hinnant3e519522010-05-11 19:42:161803 return nbytes;
1804 default:
1805 nbytes += n;
1806 frm += n;
1807 break;
1808 }
1809 }
1810 return nbytes;
1811}
1812
1813int
Louis Dionne56013052021-03-01 17:09:451814codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept
Howard Hinnant3e519522010-05-11 19:42:161815{
Nikolas Klauser84fc2c32022-09-02 14:19:071816 return __l_ == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_));
Howard Hinnant3e519522010-05-11 19:42:161817}
Louis Dionnef4c12582021-08-23 19:32:361818#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:161819
1820// Valid UTF ranges
1821// UTF-32 UTF-16 UTF-8 # of code points
1822// first second first second third fourth
1823// 000000 - 00007F 0000 - 007F 00 - 7F 127
1824// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1825// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1826// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1827// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1828// 00D800 - 00DFFF invalid
1829// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1830// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1831// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1832// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1833
Nikolas Klauser3ee9a502022-06-30 11:47:261834_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:411835static
1836codecvt_base::result
1837utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1838 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1839 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1840{
1841 frm_nxt = frm;
1842 to_nxt = to;
1843 if (mode & generate_header)
1844 {
1845 if (to_end-to_nxt < 3)
1846 return codecvt_base::partial;
1847 *to_nxt++ = static_cast<uint8_t>(0xEF);
1848 *to_nxt++ = static_cast<uint8_t>(0xBB);
1849 *to_nxt++ = static_cast<uint8_t>(0xBF);
1850 }
1851 for (; frm_nxt < frm_end; ++frm_nxt)
1852 {
1853 uint16_t wc1 = *frm_nxt;
1854 if (wc1 > Maxcode)
1855 return codecvt_base::error;
1856 if (wc1 < 0x0080)
1857 {
1858 if (to_end-to_nxt < 1)
1859 return codecvt_base::partial;
1860 *to_nxt++ = static_cast<uint8_t>(wc1);
1861 }
1862 else if (wc1 < 0x0800)
1863 {
1864 if (to_end-to_nxt < 2)
1865 return codecvt_base::partial;
1866 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1867 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1868 }
1869 else if (wc1 < 0xD800)
1870 {
1871 if (to_end-to_nxt < 3)
1872 return codecvt_base::partial;
1873 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1874 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1875 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1876 }
1877 else if (wc1 < 0xDC00)
1878 {
1879 if (frm_end-frm_nxt < 2)
1880 return codecvt_base::partial;
1881 uint16_t wc2 = frm_nxt[1];
1882 if ((wc2 & 0xFC00) != 0xDC00)
1883 return codecvt_base::error;
1884 if (to_end-to_nxt < 4)
1885 return codecvt_base::partial;
Joerg Sonnenberger634b9dd2014-01-04 17:43:001886 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1887 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:411888 return codecvt_base::error;
1889 ++frm_nxt;
1890 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1891 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1892 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1893 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1894 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1895 }
1896 else if (wc1 < 0xE000)
1897 {
1898 return codecvt_base::error;
1899 }
1900 else
1901 {
1902 if (to_end-to_nxt < 3)
1903 return codecvt_base::partial;
1904 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1905 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1906 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1907 }
1908 }
1909 return codecvt_base::ok;
1910}
1911
1912static
1913codecvt_base::result
1914utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1915 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1916 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1917{
1918 frm_nxt = frm;
1919 to_nxt = to;
1920 if (mode & generate_header)
1921 {
1922 if (to_end-to_nxt < 3)
1923 return codecvt_base::partial;
1924 *to_nxt++ = static_cast<uint8_t>(0xEF);
1925 *to_nxt++ = static_cast<uint8_t>(0xBB);
1926 *to_nxt++ = static_cast<uint8_t>(0xBF);
1927 }
1928 for (; frm_nxt < frm_end; ++frm_nxt)
1929 {
1930 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1931 if (wc1 > Maxcode)
1932 return codecvt_base::error;
1933 if (wc1 < 0x0080)
1934 {
1935 if (to_end-to_nxt < 1)
1936 return codecvt_base::partial;
1937 *to_nxt++ = static_cast<uint8_t>(wc1);
1938 }
1939 else if (wc1 < 0x0800)
1940 {
1941 if (to_end-to_nxt < 2)
1942 return codecvt_base::partial;
1943 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1944 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1945 }
1946 else if (wc1 < 0xD800)
1947 {
1948 if (to_end-to_nxt < 3)
1949 return codecvt_base::partial;
1950 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1951 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1952 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1953 }
1954 else if (wc1 < 0xDC00)
1955 {
1956 if (frm_end-frm_nxt < 2)
1957 return codecvt_base::partial;
1958 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1959 if ((wc2 & 0xFC00) != 0xDC00)
1960 return codecvt_base::error;
1961 if (to_end-to_nxt < 4)
1962 return codecvt_base::partial;
Joerg Sonnenberger634b9dd2014-01-04 17:43:001963 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1964 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:411965 return codecvt_base::error;
1966 ++frm_nxt;
1967 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1968 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1969 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1970 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1971 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1972 }
1973 else if (wc1 < 0xE000)
1974 {
1975 return codecvt_base::error;
1976 }
1977 else
1978 {
1979 if (to_end-to_nxt < 3)
1980 return codecvt_base::partial;
1981 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1982 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1983 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1984 }
1985 }
1986 return codecvt_base::ok;
1987}
1988
1989static
1990codecvt_base::result
1991utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1992 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1993 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1994{
1995 frm_nxt = frm;
1996 to_nxt = to;
1997 if (mode & consume_header)
1998 {
1999 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2000 frm_nxt[2] == 0xBF)
2001 frm_nxt += 3;
2002 }
2003 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2004 {
2005 uint8_t c1 = *frm_nxt;
2006 if (c1 > Maxcode)
2007 return codecvt_base::error;
2008 if (c1 < 0x80)
2009 {
2010 *to_nxt = static_cast<uint16_t>(c1);
2011 ++frm_nxt;
2012 }
2013 else if (c1 < 0xC2)
2014 {
2015 return codecvt_base::error;
2016 }
2017 else if (c1 < 0xE0)
2018 {
2019 if (frm_end-frm_nxt < 2)
2020 return codecvt_base::partial;
2021 uint8_t c2 = frm_nxt[1];
2022 if ((c2 & 0xC0) != 0x80)
2023 return codecvt_base::error;
2024 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2025 if (t > Maxcode)
2026 return codecvt_base::error;
2027 *to_nxt = t;
2028 frm_nxt += 2;
2029 }
2030 else if (c1 < 0xF0)
2031 {
2032 if (frm_end-frm_nxt < 3)
2033 return codecvt_base::partial;
2034 uint8_t c2 = frm_nxt[1];
2035 uint8_t c3 = frm_nxt[2];
2036 switch (c1)
2037 {
2038 case 0xE0:
2039 if ((c2 & 0xE0) != 0xA0)
2040 return codecvt_base::error;
2041 break;
2042 case 0xED:
2043 if ((c2 & 0xE0) != 0x80)
2044 return codecvt_base::error;
2045 break;
2046 default:
2047 if ((c2 & 0xC0) != 0x80)
2048 return codecvt_base::error;
2049 break;
2050 }
2051 if ((c3 & 0xC0) != 0x80)
2052 return codecvt_base::error;
2053 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2054 | ((c2 & 0x3F) << 6)
2055 | (c3 & 0x3F));
2056 if (t > Maxcode)
2057 return codecvt_base::error;
2058 *to_nxt = t;
2059 frm_nxt += 3;
2060 }
2061 else if (c1 < 0xF5)
2062 {
2063 if (frm_end-frm_nxt < 4)
2064 return codecvt_base::partial;
2065 uint8_t c2 = frm_nxt[1];
2066 uint8_t c3 = frm_nxt[2];
2067 uint8_t c4 = frm_nxt[3];
2068 switch (c1)
2069 {
2070 case 0xF0:
2071 if (!(0x90 <= c2 && c2 <= 0xBF))
2072 return codecvt_base::error;
2073 break;
2074 case 0xF4:
2075 if ((c2 & 0xF0) != 0x80)
2076 return codecvt_base::error;
2077 break;
2078 default:
2079 if ((c2 & 0xC0) != 0x80)
2080 return codecvt_base::error;
2081 break;
2082 }
2083 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2084 return codecvt_base::error;
2085 if (to_end-to_nxt < 2)
2086 return codecvt_base::partial;
Joerg Sonnenberger634b9dd2014-01-04 17:43:002087 if ((((c1 & 7UL) << 18) +
2088 ((c2 & 0x3FUL) << 12) +
2089 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412090 return codecvt_base::error;
2091 *to_nxt = static_cast<uint16_t>(
2092 0xD800
2093 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2094 | ((c2 & 0x0F) << 2)
2095 | ((c3 & 0x30) >> 4));
2096 *++to_nxt = static_cast<uint16_t>(
2097 0xDC00
2098 | ((c3 & 0x0F) << 6)
2099 | (c4 & 0x3F));
2100 frm_nxt += 4;
2101 }
2102 else
2103 {
2104 return codecvt_base::error;
2105 }
2106 }
2107 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2108}
2109
2110static
2111codecvt_base::result
2112utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2113 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2114 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2115{
2116 frm_nxt = frm;
2117 to_nxt = to;
2118 if (mode & consume_header)
2119 {
2120 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2121 frm_nxt[2] == 0xBF)
2122 frm_nxt += 3;
2123 }
2124 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2125 {
2126 uint8_t c1 = *frm_nxt;
2127 if (c1 > Maxcode)
2128 return codecvt_base::error;
2129 if (c1 < 0x80)
2130 {
2131 *to_nxt = static_cast<uint32_t>(c1);
2132 ++frm_nxt;
2133 }
2134 else if (c1 < 0xC2)
2135 {
2136 return codecvt_base::error;
2137 }
2138 else if (c1 < 0xE0)
2139 {
2140 if (frm_end-frm_nxt < 2)
2141 return codecvt_base::partial;
2142 uint8_t c2 = frm_nxt[1];
2143 if ((c2 & 0xC0) != 0x80)
2144 return codecvt_base::error;
2145 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2146 if (t > Maxcode)
2147 return codecvt_base::error;
2148 *to_nxt = static_cast<uint32_t>(t);
2149 frm_nxt += 2;
2150 }
2151 else if (c1 < 0xF0)
2152 {
2153 if (frm_end-frm_nxt < 3)
2154 return codecvt_base::partial;
2155 uint8_t c2 = frm_nxt[1];
2156 uint8_t c3 = frm_nxt[2];
2157 switch (c1)
2158 {
2159 case 0xE0:
2160 if ((c2 & 0xE0) != 0xA0)
2161 return codecvt_base::error;
2162 break;
2163 case 0xED:
2164 if ((c2 & 0xE0) != 0x80)
2165 return codecvt_base::error;
2166 break;
2167 default:
2168 if ((c2 & 0xC0) != 0x80)
2169 return codecvt_base::error;
2170 break;
2171 }
2172 if ((c3 & 0xC0) != 0x80)
2173 return codecvt_base::error;
2174 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2175 | ((c2 & 0x3F) << 6)
2176 | (c3 & 0x3F));
2177 if (t > Maxcode)
2178 return codecvt_base::error;
2179 *to_nxt = static_cast<uint32_t>(t);
2180 frm_nxt += 3;
2181 }
2182 else if (c1 < 0xF5)
2183 {
2184 if (frm_end-frm_nxt < 4)
2185 return codecvt_base::partial;
2186 uint8_t c2 = frm_nxt[1];
2187 uint8_t c3 = frm_nxt[2];
2188 uint8_t c4 = frm_nxt[3];
2189 switch (c1)
2190 {
2191 case 0xF0:
2192 if (!(0x90 <= c2 && c2 <= 0xBF))
2193 return codecvt_base::error;
2194 break;
2195 case 0xF4:
2196 if ((c2 & 0xF0) != 0x80)
2197 return codecvt_base::error;
2198 break;
2199 default:
2200 if ((c2 & 0xC0) != 0x80)
2201 return codecvt_base::error;
2202 break;
2203 }
2204 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2205 return codecvt_base::error;
2206 if (to_end-to_nxt < 2)
2207 return codecvt_base::partial;
Joerg Sonnenberger634b9dd2014-01-04 17:43:002208 if ((((c1 & 7UL) << 18) +
2209 ((c2 & 0x3FUL) << 12) +
2210 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412211 return codecvt_base::error;
2212 *to_nxt = static_cast<uint32_t>(
2213 0xD800
2214 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2215 | ((c2 & 0x0F) << 2)
2216 | ((c3 & 0x30) >> 4));
2217 *++to_nxt = static_cast<uint32_t>(
2218 0xDC00
2219 | ((c3 & 0x0F) << 6)
2220 | (c4 & 0x3F));
2221 frm_nxt += 4;
2222 }
2223 else
2224 {
2225 return codecvt_base::error;
2226 }
2227 }
2228 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2229}
2230
2231static
2232int
2233utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2234 size_t mx, unsigned long Maxcode = 0x10FFFF,
2235 codecvt_mode mode = codecvt_mode(0))
2236{
2237 const uint8_t* frm_nxt = frm;
2238 if (mode & consume_header)
2239 {
2240 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2241 frm_nxt[2] == 0xBF)
2242 frm_nxt += 3;
2243 }
2244 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2245 {
2246 uint8_t c1 = *frm_nxt;
2247 if (c1 > Maxcode)
2248 break;
2249 if (c1 < 0x80)
2250 {
2251 ++frm_nxt;
2252 }
2253 else if (c1 < 0xC2)
2254 {
2255 break;
2256 }
2257 else if (c1 < 0xE0)
2258 {
2259 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2260 break;
2261 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2262 if (t > Maxcode)
2263 break;
2264 frm_nxt += 2;
2265 }
2266 else if (c1 < 0xF0)
2267 {
2268 if (frm_end-frm_nxt < 3)
2269 break;
2270 uint8_t c2 = frm_nxt[1];
2271 uint8_t c3 = frm_nxt[2];
Howard Hinnant0c17e322010-05-30 21:39:412272 switch (c1)
2273 {
2274 case 0xE0:
2275 if ((c2 & 0xE0) != 0xA0)
2276 return static_cast<int>(frm_nxt - frm);
2277 break;
2278 case 0xED:
2279 if ((c2 & 0xE0) != 0x80)
2280 return static_cast<int>(frm_nxt - frm);
2281 break;
2282 default:
2283 if ((c2 & 0xC0) != 0x80)
2284 return static_cast<int>(frm_nxt - frm);
2285 break;
2286 }
2287 if ((c3 & 0xC0) != 0x80)
2288 break;
Howard Hinnantc2063662011-12-01 20:21:042289 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412290 break;
2291 frm_nxt += 3;
2292 }
2293 else if (c1 < 0xF5)
2294 {
2295 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2296 break;
2297 uint8_t c2 = frm_nxt[1];
2298 uint8_t c3 = frm_nxt[2];
2299 uint8_t c4 = frm_nxt[3];
2300 switch (c1)
2301 {
2302 case 0xF0:
2303 if (!(0x90 <= c2 && c2 <= 0xBF))
2304 return static_cast<int>(frm_nxt - frm);
2305 break;
2306 case 0xF4:
2307 if ((c2 & 0xF0) != 0x80)
2308 return static_cast<int>(frm_nxt - frm);
2309 break;
2310 default:
2311 if ((c2 & 0xC0) != 0x80)
2312 return static_cast<int>(frm_nxt - frm);
2313 break;
2314 }
2315 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2316 break;
Joerg Sonnenberger634b9dd2014-01-04 17:43:002317 if ((((c1 & 7UL) << 18) +
2318 ((c2 & 0x3FUL) << 12) +
2319 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412320 break;
2321 ++nchar16_t;
2322 frm_nxt += 4;
2323 }
2324 else
2325 {
2326 break;
2327 }
2328 }
2329 return static_cast<int>(frm_nxt - frm);
2330}
2331
2332static
2333codecvt_base::result
2334ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2335 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2336 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2337{
2338 frm_nxt = frm;
2339 to_nxt = to;
2340 if (mode & generate_header)
2341 {
2342 if (to_end-to_nxt < 3)
2343 return codecvt_base::partial;
2344 *to_nxt++ = static_cast<uint8_t>(0xEF);
2345 *to_nxt++ = static_cast<uint8_t>(0xBB);
2346 *to_nxt++ = static_cast<uint8_t>(0xBF);
2347 }
2348 for (; frm_nxt < frm_end; ++frm_nxt)
2349 {
2350 uint32_t wc = *frm_nxt;
2351 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2352 return codecvt_base::error;
2353 if (wc < 0x000080)
2354 {
2355 if (to_end-to_nxt < 1)
2356 return codecvt_base::partial;
2357 *to_nxt++ = static_cast<uint8_t>(wc);
2358 }
2359 else if (wc < 0x000800)
2360 {
2361 if (to_end-to_nxt < 2)
2362 return codecvt_base::partial;
2363 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2364 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2365 }
2366 else if (wc < 0x010000)
2367 {
2368 if (to_end-to_nxt < 3)
2369 return codecvt_base::partial;
2370 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2371 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2372 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2373 }
2374 else // if (wc < 0x110000)
2375 {
2376 if (to_end-to_nxt < 4)
2377 return codecvt_base::partial;
2378 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2379 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2380 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2381 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2382 }
2383 }
2384 return codecvt_base::ok;
2385}
2386
2387static
2388codecvt_base::result
2389utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2390 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2391 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2392{
2393 frm_nxt = frm;
2394 to_nxt = to;
2395 if (mode & consume_header)
2396 {
2397 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2398 frm_nxt[2] == 0xBF)
2399 frm_nxt += 3;
2400 }
2401 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2402 {
2403 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2404 if (c1 < 0x80)
2405 {
2406 if (c1 > Maxcode)
2407 return codecvt_base::error;
2408 *to_nxt = static_cast<uint32_t>(c1);
2409 ++frm_nxt;
2410 }
2411 else if (c1 < 0xC2)
2412 {
2413 return codecvt_base::error;
2414 }
2415 else if (c1 < 0xE0)
2416 {
2417 if (frm_end-frm_nxt < 2)
2418 return codecvt_base::partial;
2419 uint8_t c2 = frm_nxt[1];
2420 if ((c2 & 0xC0) != 0x80)
2421 return codecvt_base::error;
2422 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2423 | (c2 & 0x3F));
2424 if (t > Maxcode)
2425 return codecvt_base::error;
2426 *to_nxt = t;
2427 frm_nxt += 2;
2428 }
2429 else if (c1 < 0xF0)
2430 {
2431 if (frm_end-frm_nxt < 3)
2432 return codecvt_base::partial;
2433 uint8_t c2 = frm_nxt[1];
2434 uint8_t c3 = frm_nxt[2];
2435 switch (c1)
2436 {
2437 case 0xE0:
2438 if ((c2 & 0xE0) != 0xA0)
2439 return codecvt_base::error;
2440 break;
2441 case 0xED:
2442 if ((c2 & 0xE0) != 0x80)
2443 return codecvt_base::error;
2444 break;
2445 default:
2446 if ((c2 & 0xC0) != 0x80)
2447 return codecvt_base::error;
2448 break;
2449 }
2450 if ((c3 & 0xC0) != 0x80)
2451 return codecvt_base::error;
2452 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2453 | ((c2 & 0x3F) << 6)
2454 | (c3 & 0x3F));
2455 if (t > Maxcode)
2456 return codecvt_base::error;
2457 *to_nxt = t;
2458 frm_nxt += 3;
2459 }
2460 else if (c1 < 0xF5)
2461 {
2462 if (frm_end-frm_nxt < 4)
2463 return codecvt_base::partial;
2464 uint8_t c2 = frm_nxt[1];
2465 uint8_t c3 = frm_nxt[2];
2466 uint8_t c4 = frm_nxt[3];
2467 switch (c1)
2468 {
2469 case 0xF0:
2470 if (!(0x90 <= c2 && c2 <= 0xBF))
2471 return codecvt_base::error;
2472 break;
2473 case 0xF4:
2474 if ((c2 & 0xF0) != 0x80)
2475 return codecvt_base::error;
2476 break;
2477 default:
2478 if ((c2 & 0xC0) != 0x80)
2479 return codecvt_base::error;
2480 break;
2481 }
2482 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2483 return codecvt_base::error;
2484 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2485 | ((c2 & 0x3F) << 12)
2486 | ((c3 & 0x3F) << 6)
2487 | (c4 & 0x3F));
2488 if (t > Maxcode)
2489 return codecvt_base::error;
2490 *to_nxt = t;
2491 frm_nxt += 4;
2492 }
2493 else
2494 {
2495 return codecvt_base::error;
2496 }
2497 }
2498 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2499}
2500
2501static
2502int
2503utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2504 size_t mx, unsigned long Maxcode = 0x10FFFF,
2505 codecvt_mode mode = codecvt_mode(0))
2506{
2507 const uint8_t* frm_nxt = frm;
2508 if (mode & consume_header)
2509 {
2510 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2511 frm_nxt[2] == 0xBF)
2512 frm_nxt += 3;
2513 }
2514 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2515 {
2516 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2517 if (c1 < 0x80)
2518 {
2519 if (c1 > Maxcode)
2520 break;
2521 ++frm_nxt;
2522 }
2523 else if (c1 < 0xC2)
2524 {
2525 break;
2526 }
2527 else if (c1 < 0xE0)
2528 {
2529 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2530 break;
Howard Hinnantc2063662011-12-01 20:21:042531 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412532 break;
2533 frm_nxt += 2;
2534 }
2535 else if (c1 < 0xF0)
2536 {
2537 if (frm_end-frm_nxt < 3)
2538 break;
2539 uint8_t c2 = frm_nxt[1];
2540 uint8_t c3 = frm_nxt[2];
2541 switch (c1)
2542 {
2543 case 0xE0:
2544 if ((c2 & 0xE0) != 0xA0)
2545 return static_cast<int>(frm_nxt - frm);
2546 break;
2547 case 0xED:
2548 if ((c2 & 0xE0) != 0x80)
2549 return static_cast<int>(frm_nxt - frm);
2550 break;
2551 default:
2552 if ((c2 & 0xC0) != 0x80)
2553 return static_cast<int>(frm_nxt - frm);
2554 break;
2555 }
2556 if ((c3 & 0xC0) != 0x80)
2557 break;
Howard Hinnantc2063662011-12-01 20:21:042558 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412559 break;
2560 frm_nxt += 3;
2561 }
2562 else if (c1 < 0xF5)
2563 {
2564 if (frm_end-frm_nxt < 4)
2565 break;
2566 uint8_t c2 = frm_nxt[1];
2567 uint8_t c3 = frm_nxt[2];
2568 uint8_t c4 = frm_nxt[3];
2569 switch (c1)
2570 {
2571 case 0xF0:
2572 if (!(0x90 <= c2 && c2 <= 0xBF))
2573 return static_cast<int>(frm_nxt - frm);
2574 break;
2575 case 0xF4:
2576 if ((c2 & 0xF0) != 0x80)
2577 return static_cast<int>(frm_nxt - frm);
2578 break;
2579 default:
2580 if ((c2 & 0xC0) != 0x80)
2581 return static_cast<int>(frm_nxt - frm);
2582 break;
2583 }
2584 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2585 break;
Howard Hinnantc2063662011-12-01 20:21:042586 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2587 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412588 break;
2589 frm_nxt += 4;
2590 }
2591 else
2592 {
2593 break;
2594 }
2595 }
2596 return static_cast<int>(frm_nxt - frm);
2597}
2598
2599static
2600codecvt_base::result
2601ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2602 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2603 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2604{
2605 frm_nxt = frm;
2606 to_nxt = to;
2607 if (mode & generate_header)
2608 {
2609 if (to_end-to_nxt < 3)
2610 return codecvt_base::partial;
2611 *to_nxt++ = static_cast<uint8_t>(0xEF);
2612 *to_nxt++ = static_cast<uint8_t>(0xBB);
2613 *to_nxt++ = static_cast<uint8_t>(0xBF);
2614 }
2615 for (; frm_nxt < frm_end; ++frm_nxt)
2616 {
2617 uint16_t wc = *frm_nxt;
2618 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2619 return codecvt_base::error;
2620 if (wc < 0x0080)
2621 {
2622 if (to_end-to_nxt < 1)
2623 return codecvt_base::partial;
2624 *to_nxt++ = static_cast<uint8_t>(wc);
2625 }
2626 else if (wc < 0x0800)
2627 {
2628 if (to_end-to_nxt < 2)
2629 return codecvt_base::partial;
2630 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2631 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2632 }
2633 else // if (wc <= 0xFFFF)
2634 {
2635 if (to_end-to_nxt < 3)
2636 return codecvt_base::partial;
2637 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2638 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2639 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2640 }
2641 }
2642 return codecvt_base::ok;
2643}
2644
2645static
2646codecvt_base::result
2647utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2648 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2649 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2650{
2651 frm_nxt = frm;
2652 to_nxt = to;
2653 if (mode & consume_header)
2654 {
2655 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2656 frm_nxt[2] == 0xBF)
2657 frm_nxt += 3;
2658 }
2659 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2660 {
2661 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2662 if (c1 < 0x80)
2663 {
2664 if (c1 > Maxcode)
2665 return codecvt_base::error;
2666 *to_nxt = static_cast<uint16_t>(c1);
2667 ++frm_nxt;
2668 }
2669 else if (c1 < 0xC2)
2670 {
2671 return codecvt_base::error;
2672 }
2673 else if (c1 < 0xE0)
2674 {
2675 if (frm_end-frm_nxt < 2)
2676 return codecvt_base::partial;
2677 uint8_t c2 = frm_nxt[1];
2678 if ((c2 & 0xC0) != 0x80)
2679 return codecvt_base::error;
2680 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2681 | (c2 & 0x3F));
2682 if (t > Maxcode)
2683 return codecvt_base::error;
2684 *to_nxt = t;
2685 frm_nxt += 2;
2686 }
2687 else if (c1 < 0xF0)
2688 {
2689 if (frm_end-frm_nxt < 3)
2690 return codecvt_base::partial;
2691 uint8_t c2 = frm_nxt[1];
2692 uint8_t c3 = frm_nxt[2];
2693 switch (c1)
2694 {
2695 case 0xE0:
2696 if ((c2 & 0xE0) != 0xA0)
2697 return codecvt_base::error;
2698 break;
2699 case 0xED:
2700 if ((c2 & 0xE0) != 0x80)
2701 return codecvt_base::error;
2702 break;
2703 default:
2704 if ((c2 & 0xC0) != 0x80)
2705 return codecvt_base::error;
2706 break;
2707 }
2708 if ((c3 & 0xC0) != 0x80)
2709 return codecvt_base::error;
2710 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2711 | ((c2 & 0x3F) << 6)
2712 | (c3 & 0x3F));
2713 if (t > Maxcode)
2714 return codecvt_base::error;
2715 *to_nxt = t;
2716 frm_nxt += 3;
2717 }
2718 else
2719 {
2720 return codecvt_base::error;
2721 }
2722 }
2723 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2724}
2725
2726static
2727int
2728utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2729 size_t mx, unsigned long Maxcode = 0x10FFFF,
2730 codecvt_mode mode = codecvt_mode(0))
2731{
2732 const uint8_t* frm_nxt = frm;
2733 if (mode & consume_header)
2734 {
2735 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2736 frm_nxt[2] == 0xBF)
2737 frm_nxt += 3;
2738 }
2739 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2740 {
2741 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2742 if (c1 < 0x80)
2743 {
2744 if (c1 > Maxcode)
2745 break;
2746 ++frm_nxt;
2747 }
2748 else if (c1 < 0xC2)
2749 {
2750 break;
2751 }
2752 else if (c1 < 0xE0)
2753 {
2754 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2755 break;
Howard Hinnantc2063662011-12-01 20:21:042756 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412757 break;
2758 frm_nxt += 2;
2759 }
2760 else if (c1 < 0xF0)
2761 {
2762 if (frm_end-frm_nxt < 3)
2763 break;
2764 uint8_t c2 = frm_nxt[1];
2765 uint8_t c3 = frm_nxt[2];
2766 switch (c1)
2767 {
2768 case 0xE0:
2769 if ((c2 & 0xE0) != 0xA0)
2770 return static_cast<int>(frm_nxt - frm);
2771 break;
2772 case 0xED:
2773 if ((c2 & 0xE0) != 0x80)
2774 return static_cast<int>(frm_nxt - frm);
2775 break;
2776 default:
2777 if ((c2 & 0xC0) != 0x80)
2778 return static_cast<int>(frm_nxt - frm);
2779 break;
2780 }
2781 if ((c3 & 0xC0) != 0x80)
2782 break;
Howard Hinnantc2063662011-12-01 20:21:042783 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
Howard Hinnant0c17e322010-05-30 21:39:412784 break;
2785 frm_nxt += 3;
2786 }
2787 else
2788 {
2789 break;
2790 }
2791 }
2792 return static_cast<int>(frm_nxt - frm);
2793}
2794
2795static
2796codecvt_base::result
2797ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2798 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2799 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2800{
2801 frm_nxt = frm;
2802 to_nxt = to;
2803 if (mode & generate_header)
2804 {
2805 if (to_end-to_nxt < 2)
2806 return codecvt_base::partial;
2807 *to_nxt++ = static_cast<uint8_t>(0xFE);
2808 *to_nxt++ = static_cast<uint8_t>(0xFF);
2809 }
2810 for (; frm_nxt < frm_end; ++frm_nxt)
2811 {
2812 uint32_t wc = *frm_nxt;
2813 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2814 return codecvt_base::error;
2815 if (wc < 0x010000)
2816 {
2817 if (to_end-to_nxt < 2)
2818 return codecvt_base::partial;
2819 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2820 *to_nxt++ = static_cast<uint8_t>(wc);
2821 }
2822 else
2823 {
2824 if (to_end-to_nxt < 4)
2825 return codecvt_base::partial;
2826 uint16_t t = static_cast<uint16_t>(
2827 0xD800
2828 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2829 | ((wc & 0x00FC00) >> 10));
2830 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2831 *to_nxt++ = static_cast<uint8_t>(t);
2832 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2833 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2834 *to_nxt++ = static_cast<uint8_t>(t);
2835 }
2836 }
2837 return codecvt_base::ok;
2838}
2839
2840static
2841codecvt_base::result
2842utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2843 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2844 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2845{
2846 frm_nxt = frm;
2847 to_nxt = to;
2848 if (mode & consume_header)
2849 {
2850 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2851 frm_nxt += 2;
2852 }
2853 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2854 {
Howard Hinnantc2063662011-12-01 20:21:042855 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant0c17e322010-05-30 21:39:412856 if ((c1 & 0xFC00) == 0xDC00)
2857 return codecvt_base::error;
2858 if ((c1 & 0xFC00) != 0xD800)
2859 {
2860 if (c1 > Maxcode)
2861 return codecvt_base::error;
2862 *to_nxt = static_cast<uint32_t>(c1);
2863 frm_nxt += 2;
2864 }
2865 else
2866 {
2867 if (frm_end-frm_nxt < 4)
2868 return codecvt_base::partial;
Howard Hinnantc2063662011-12-01 20:21:042869 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
Howard Hinnant0c17e322010-05-30 21:39:412870 if ((c2 & 0xFC00) != 0xDC00)
2871 return codecvt_base::error;
2872 uint32_t t = static_cast<uint32_t>(
2873 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2874 | ((c1 & 0x003F) << 10)
2875 | (c2 & 0x03FF));
2876 if (t > Maxcode)
2877 return codecvt_base::error;
2878 *to_nxt = t;
2879 frm_nxt += 4;
2880 }
2881 }
2882 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2883}
2884
2885static
2886int
2887utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2888 size_t mx, unsigned long Maxcode = 0x10FFFF,
2889 codecvt_mode mode = codecvt_mode(0))
2890{
2891 const uint8_t* frm_nxt = frm;
Howard Hinnant0c17e322010-05-30 21:39:412892 if (mode & consume_header)
2893 {
2894 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2895 frm_nxt += 2;
2896 }
2897 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2898 {
Howard Hinnantc2063662011-12-01 20:21:042899 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant0c17e322010-05-30 21:39:412900 if ((c1 & 0xFC00) == 0xDC00)
2901 break;
2902 if ((c1 & 0xFC00) != 0xD800)
2903 {
2904 if (c1 > Maxcode)
2905 break;
2906 frm_nxt += 2;
2907 }
2908 else
2909 {
2910 if (frm_end-frm_nxt < 4)
2911 break;
Howard Hinnantc2063662011-12-01 20:21:042912 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
Howard Hinnant0c17e322010-05-30 21:39:412913 if ((c2 & 0xFC00) != 0xDC00)
2914 break;
2915 uint32_t t = static_cast<uint32_t>(
2916 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2917 | ((c1 & 0x003F) << 10)
2918 | (c2 & 0x03FF));
2919 if (t > Maxcode)
2920 break;
2921 frm_nxt += 4;
2922 }
2923 }
2924 return static_cast<int>(frm_nxt - frm);
2925}
2926
2927static
2928codecvt_base::result
2929ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2930 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2931 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2932{
2933 frm_nxt = frm;
2934 to_nxt = to;
2935 if (mode & generate_header)
2936 {
Eric Fiselier89dd1dd2016-04-21 22:54:212937 if (to_end - to_nxt < 2)
Howard Hinnant0c17e322010-05-30 21:39:412938 return codecvt_base::partial;
Eric Fiselier89dd1dd2016-04-21 22:54:212939 *to_nxt++ = static_cast<uint8_t>(0xFF);
2940 *to_nxt++ = static_cast<uint8_t>(0xFE);
Howard Hinnant0c17e322010-05-30 21:39:412941 }
2942 for (; frm_nxt < frm_end; ++frm_nxt)
2943 {
2944 uint32_t wc = *frm_nxt;
2945 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2946 return codecvt_base::error;
2947 if (wc < 0x010000)
2948 {
2949 if (to_end-to_nxt < 2)
2950 return codecvt_base::partial;
2951 *to_nxt++ = static_cast<uint8_t>(wc);
2952 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2953 }
2954 else
2955 {
2956 if (to_end-to_nxt < 4)
2957 return codecvt_base::partial;
2958 uint16_t t = static_cast<uint16_t>(
2959 0xD800
2960 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2961 | ((wc & 0x00FC00) >> 10));
2962 *to_nxt++ = static_cast<uint8_t>(t);
2963 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2964 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2965 *to_nxt++ = static_cast<uint8_t>(t);
2966 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2967 }
2968 }
2969 return codecvt_base::ok;
2970}
2971
2972static
2973codecvt_base::result
2974utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2975 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2976 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2977{
2978 frm_nxt = frm;
2979 to_nxt = to;
2980 if (mode & consume_header)
2981 {
2982 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2983 frm_nxt += 2;
2984 }
2985 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2986 {
Howard Hinnantc2063662011-12-01 20:21:042987 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant0c17e322010-05-30 21:39:412988 if ((c1 & 0xFC00) == 0xDC00)
2989 return codecvt_base::error;
2990 if ((c1 & 0xFC00) != 0xD800)
2991 {
2992 if (c1 > Maxcode)
2993 return codecvt_base::error;
2994 *to_nxt = static_cast<uint32_t>(c1);
2995 frm_nxt += 2;
2996 }
2997 else
2998 {
2999 if (frm_end-frm_nxt < 4)
3000 return codecvt_base::partial;
Howard Hinnantc2063662011-12-01 20:21:043001 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
Howard Hinnant0c17e322010-05-30 21:39:413002 if ((c2 & 0xFC00) != 0xDC00)
3003 return codecvt_base::error;
3004 uint32_t t = static_cast<uint32_t>(
3005 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3006 | ((c1 & 0x003F) << 10)
3007 | (c2 & 0x03FF));
3008 if (t > Maxcode)
3009 return codecvt_base::error;
3010 *to_nxt = t;
3011 frm_nxt += 4;
3012 }
3013 }
3014 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3015}
3016
3017static
3018int
3019utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
3020 size_t mx, unsigned long Maxcode = 0x10FFFF,
3021 codecvt_mode mode = codecvt_mode(0))
3022{
3023 const uint8_t* frm_nxt = frm;
Howard Hinnant0c17e322010-05-30 21:39:413024 if (mode & consume_header)
3025 {
3026 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3027 frm_nxt += 2;
3028 }
3029 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
3030 {
Howard Hinnantc2063662011-12-01 20:21:043031 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant0c17e322010-05-30 21:39:413032 if ((c1 & 0xFC00) == 0xDC00)
3033 break;
3034 if ((c1 & 0xFC00) != 0xD800)
3035 {
3036 if (c1 > Maxcode)
3037 break;
3038 frm_nxt += 2;
3039 }
3040 else
3041 {
3042 if (frm_end-frm_nxt < 4)
3043 break;
Howard Hinnantc2063662011-12-01 20:21:043044 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
Howard Hinnant0c17e322010-05-30 21:39:413045 if ((c2 & 0xFC00) != 0xDC00)
3046 break;
3047 uint32_t t = static_cast<uint32_t>(
3048 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3049 | ((c1 & 0x003F) << 10)
3050 | (c2 & 0x03FF));
3051 if (t > Maxcode)
3052 break;
3053 frm_nxt += 4;
3054 }
3055 }
3056 return static_cast<int>(frm_nxt - frm);
3057}
3058
3059static
3060codecvt_base::result
3061ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3062 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3063 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3064{
3065 frm_nxt = frm;
3066 to_nxt = to;
3067 if (mode & generate_header)
3068 {
3069 if (to_end-to_nxt < 2)
3070 return codecvt_base::partial;
3071 *to_nxt++ = static_cast<uint8_t>(0xFE);
3072 *to_nxt++ = static_cast<uint8_t>(0xFF);
3073 }
3074 for (; frm_nxt < frm_end; ++frm_nxt)
3075 {
3076 uint16_t wc = *frm_nxt;
3077 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3078 return codecvt_base::error;
3079 if (to_end-to_nxt < 2)
3080 return codecvt_base::partial;
3081 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3082 *to_nxt++ = static_cast<uint8_t>(wc);
3083 }
3084 return codecvt_base::ok;
3085}
3086
3087static
3088codecvt_base::result
3089utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3090 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3091 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3092{
3093 frm_nxt = frm;
3094 to_nxt = to;
3095 if (mode & consume_header)
3096 {
3097 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3098 frm_nxt += 2;
3099 }
3100 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3101 {
Howard Hinnantc2063662011-12-01 20:21:043102 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant0c17e322010-05-30 21:39:413103 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3104 return codecvt_base::error;
3105 *to_nxt = c1;
3106 frm_nxt += 2;
3107 }
3108 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3109}
3110
3111static
3112int
3113utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3114 size_t mx, unsigned long Maxcode = 0x10FFFF,
3115 codecvt_mode mode = codecvt_mode(0))
3116{
3117 const uint8_t* frm_nxt = frm;
Howard Hinnant0c17e322010-05-30 21:39:413118 if (mode & consume_header)
3119 {
3120 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3121 frm_nxt += 2;
3122 }
3123 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3124 {
Howard Hinnantc2063662011-12-01 20:21:043125 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
Howard Hinnant0c17e322010-05-30 21:39:413126 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3127 break;
3128 frm_nxt += 2;
3129 }
3130 return static_cast<int>(frm_nxt - frm);
3131}
3132
3133static
3134codecvt_base::result
3135ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3136 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3137 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3138{
3139 frm_nxt = frm;
3140 to_nxt = to;
3141 if (mode & generate_header)
3142 {
3143 if (to_end-to_nxt < 2)
3144 return codecvt_base::partial;
3145 *to_nxt++ = static_cast<uint8_t>(0xFF);
3146 *to_nxt++ = static_cast<uint8_t>(0xFE);
3147 }
3148 for (; frm_nxt < frm_end; ++frm_nxt)
3149 {
3150 uint16_t wc = *frm_nxt;
3151 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3152 return codecvt_base::error;
3153 if (to_end-to_nxt < 2)
3154 return codecvt_base::partial;
3155 *to_nxt++ = static_cast<uint8_t>(wc);
3156 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3157 }
3158 return codecvt_base::ok;
3159}
3160
3161static
3162codecvt_base::result
3163utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3164 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3165 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3166{
3167 frm_nxt = frm;
3168 to_nxt = to;
3169 if (mode & consume_header)
3170 {
3171 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3172 frm_nxt += 2;
3173 }
3174 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3175 {
Howard Hinnantc2063662011-12-01 20:21:043176 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant0c17e322010-05-30 21:39:413177 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3178 return codecvt_base::error;
3179 *to_nxt = c1;
3180 frm_nxt += 2;
3181 }
3182 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3183}
3184
3185static
3186int
3187utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3188 size_t mx, unsigned long Maxcode = 0x10FFFF,
3189 codecvt_mode mode = codecvt_mode(0))
3190{
3191 const uint8_t* frm_nxt = frm;
3192 frm_nxt = frm;
3193 if (mode & consume_header)
3194 {
3195 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3196 frm_nxt += 2;
3197 }
3198 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3199 {
Howard Hinnantc2063662011-12-01 20:21:043200 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
Howard Hinnant0c17e322010-05-30 21:39:413201 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3202 break;
3203 frm_nxt += 2;
3204 }
3205 return static_cast<int>(frm_nxt - frm);
3206}
3207
Nikolas Klauser3ee9a502022-06-30 11:47:263208_LIBCPP_SUPPRESS_DEPRECATED_POP
3209
Howard Hinnant3e519522010-05-11 19:42:163210// template <> class codecvt<char16_t, char, mbstate_t>
3211
Howard Hinnant940e2112010-08-22 00:03:273212locale::id codecvt<char16_t, char, mbstate_t>::id;
Howard Hinnant3e519522010-05-11 19:42:163213
3214codecvt<char16_t, char, mbstate_t>::~codecvt()
3215{
3216}
3217
3218codecvt<char16_t, char, mbstate_t>::result
3219codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant940e2112010-08-22 00:03:273220 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:163221 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3222{
Howard Hinnant0c17e322010-05-30 21:39:413223 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3224 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3225 const uint16_t* _frm_nxt = _frm;
3226 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3227 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3228 uint8_t* _to_nxt = _to;
3229 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3230 frm_nxt = frm + (_frm_nxt - _frm);
3231 to_nxt = to + (_to_nxt - _to);
3232 return r;
Howard Hinnant3e519522010-05-11 19:42:163233}
3234
3235codecvt<char16_t, char, mbstate_t>::result
3236codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant940e2112010-08-22 00:03:273237 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:163238 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3239{
Howard Hinnant0c17e322010-05-30 21:39:413240 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3241 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3242 const uint8_t* _frm_nxt = _frm;
3243 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3244 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3245 uint16_t* _to_nxt = _to;
3246 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3247 frm_nxt = frm + (_frm_nxt - _frm);
3248 to_nxt = to + (_to_nxt - _to);
3249 return r;
Howard Hinnant3e519522010-05-11 19:42:163250}
3251
3252codecvt<char16_t, char, mbstate_t>::result
3253codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3254 extern_type* to, extern_type*, extern_type*& to_nxt) const
3255{
3256 to_nxt = to;
3257 return noconv;
3258}
3259
3260int
Louis Dionne56013052021-03-01 17:09:453261codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163262{
3263 return 0;
3264}
3265
3266bool
Louis Dionne56013052021-03-01 17:09:453267codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163268{
3269 return false;
3270}
3271
3272int
3273codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3274 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3275{
Howard Hinnant0c17e322010-05-30 21:39:413276 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3277 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3278 return utf8_to_utf16_length(_frm, _frm_end, mx);
Howard Hinnant3e519522010-05-11 19:42:163279}
3280
3281int
Louis Dionne56013052021-03-01 17:09:453282codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163283{
3284 return 4;
3285}
3286
Arthur O'Dwyer5c40c992021-04-19 01:47:083287#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:023288
3289// template <> class codecvt<char16_t, char8_t, mbstate_t>
3290
3291locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
3292
3293codecvt<char16_t, char8_t, mbstate_t>::~codecvt()
3294{
3295}
3296
3297codecvt<char16_t, char8_t, mbstate_t>::result
3298codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&,
3299 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3300 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3301{
3302 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3303 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3304 const uint16_t* _frm_nxt = _frm;
3305 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3306 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3307 uint8_t* _to_nxt = _to;
3308 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3309 frm_nxt = frm + (_frm_nxt - _frm);
3310 to_nxt = to + (_to_nxt - _to);
3311 return r;
3312}
3313
3314codecvt<char16_t, char8_t, mbstate_t>::result
3315codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&,
3316 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3317 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3318{
3319 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3320 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3321 const uint8_t* _frm_nxt = _frm;
3322 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3323 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3324 uint16_t* _to_nxt = _to;
3325 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3326 frm_nxt = frm + (_frm_nxt - _frm);
3327 to_nxt = to + (_to_nxt - _to);
3328 return r;
3329}
3330
3331codecvt<char16_t, char8_t, mbstate_t>::result
3332codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
3333 extern_type* to, extern_type*, extern_type*& to_nxt) const
3334{
3335 to_nxt = to;
3336 return noconv;
3337}
3338
3339int
Louis Dionne56013052021-03-01 17:09:453340codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept
Marek Kurdeja984dca2020-12-02 07:57:023341{
3342 return 0;
3343}
3344
3345bool
Louis Dionne56013052021-03-01 17:09:453346codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
Marek Kurdeja984dca2020-12-02 07:57:023347{
3348 return false;
3349}
3350
3351int
3352codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
3353 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3354{
3355 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3356 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3357 return utf8_to_utf16_length(_frm, _frm_end, mx);
3358}
3359
3360int
Louis Dionne56013052021-03-01 17:09:453361codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept
Marek Kurdeja984dca2020-12-02 07:57:023362{
3363 return 4;
3364}
3365
3366#endif
3367
Howard Hinnant3e519522010-05-11 19:42:163368// template <> class codecvt<char32_t, char, mbstate_t>
3369
Howard Hinnant940e2112010-08-22 00:03:273370locale::id codecvt<char32_t, char, mbstate_t>::id;
Howard Hinnant3e519522010-05-11 19:42:163371
3372codecvt<char32_t, char, mbstate_t>::~codecvt()
3373{
3374}
3375
3376codecvt<char32_t, char, mbstate_t>::result
3377codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
Howard Hinnant940e2112010-08-22 00:03:273378 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:163379 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3380{
Howard Hinnant0c17e322010-05-30 21:39:413381 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3382 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3383 const uint32_t* _frm_nxt = _frm;
3384 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3385 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3386 uint8_t* _to_nxt = _to;
3387 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3388 frm_nxt = frm + (_frm_nxt - _frm);
3389 to_nxt = to + (_to_nxt - _to);
3390 return r;
Howard Hinnant3e519522010-05-11 19:42:163391}
3392
3393codecvt<char32_t, char, mbstate_t>::result
3394codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
Howard Hinnant940e2112010-08-22 00:03:273395 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:163396 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3397{
Howard Hinnant0c17e322010-05-30 21:39:413398 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3399 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3400 const uint8_t* _frm_nxt = _frm;
3401 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3402 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3403 uint32_t* _to_nxt = _to;
3404 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3405 frm_nxt = frm + (_frm_nxt - _frm);
3406 to_nxt = to + (_to_nxt - _to);
3407 return r;
Howard Hinnant3e519522010-05-11 19:42:163408}
3409
3410codecvt<char32_t, char, mbstate_t>::result
3411codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3412 extern_type* to, extern_type*, extern_type*& to_nxt) const
3413{
3414 to_nxt = to;
3415 return noconv;
3416}
3417
3418int
Louis Dionne56013052021-03-01 17:09:453419codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163420{
3421 return 0;
3422}
3423
3424bool
Louis Dionne56013052021-03-01 17:09:453425codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163426{
3427 return false;
3428}
3429
3430int
3431codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3432 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3433{
Howard Hinnant0c17e322010-05-30 21:39:413434 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3435 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3436 return utf8_to_ucs4_length(_frm, _frm_end, mx);
Howard Hinnant3e519522010-05-11 19:42:163437}
3438
3439int
Louis Dionne56013052021-03-01 17:09:453440codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163441{
3442 return 4;
3443}
3444
Arthur O'Dwyer5c40c992021-04-19 01:47:083445#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:023446
3447// template <> class codecvt<char32_t, char8_t, mbstate_t>
3448
3449locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
3450
3451codecvt<char32_t, char8_t, mbstate_t>::~codecvt()
3452{
3453}
3454
3455codecvt<char32_t, char8_t, mbstate_t>::result
3456codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&,
3457 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3458 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3459{
3460 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3461 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3462 const uint32_t* _frm_nxt = _frm;
3463 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3464 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3465 uint8_t* _to_nxt = _to;
3466 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3467 frm_nxt = frm + (_frm_nxt - _frm);
3468 to_nxt = to + (_to_nxt - _to);
3469 return r;
3470}
3471
3472codecvt<char32_t, char8_t, mbstate_t>::result
3473codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&,
3474 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3475 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3476{
3477 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3478 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3479 const uint8_t* _frm_nxt = _frm;
3480 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3481 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3482 uint32_t* _to_nxt = _to;
3483 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3484 frm_nxt = frm + (_frm_nxt - _frm);
3485 to_nxt = to + (_to_nxt - _to);
3486 return r;
3487}
3488
3489codecvt<char32_t, char8_t, mbstate_t>::result
3490codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
3491 extern_type* to, extern_type*, extern_type*& to_nxt) const
3492{
3493 to_nxt = to;
3494 return noconv;
3495}
3496
3497int
Louis Dionne56013052021-03-01 17:09:453498codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept
Marek Kurdeja984dca2020-12-02 07:57:023499{
3500 return 0;
3501}
3502
3503bool
Louis Dionne56013052021-03-01 17:09:453504codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
Marek Kurdeja984dca2020-12-02 07:57:023505{
3506 return false;
3507}
3508
3509int
3510codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
3511 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3512{
3513 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3514 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3515 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3516}
3517
3518int
Louis Dionne56013052021-03-01 17:09:453519codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept
Marek Kurdeja984dca2020-12-02 07:57:023520{
3521 return 4;
3522}
3523
3524#endif
3525
Howard Hinnant0c17e322010-05-30 21:39:413526// __codecvt_utf8<wchar_t>
Howard Hinnant3e519522010-05-11 19:42:163527
Louis Dionnef4c12582021-08-23 19:32:363528#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant0c17e322010-05-30 21:39:413529__codecvt_utf8<wchar_t>::result
3530__codecvt_utf8<wchar_t>::do_out(state_type&,
3531 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:163532 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3533{
Saleem Abdulrasoolb2826a12017-01-03 21:53:513534#if defined(_LIBCPP_SHORT_WCHAR)
Howard Hinnant271426e2013-07-08 19:03:073535 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3536 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3537 const uint16_t* _frm_nxt = _frm;
3538#else
Howard Hinnant0c17e322010-05-30 21:39:413539 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3540 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3541 const uint32_t* _frm_nxt = _frm;
Howard Hinnant271426e2013-07-08 19:03:073542#endif
Howard Hinnant0c17e322010-05-30 21:39:413543 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3544 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3545 uint8_t* _to_nxt = _to;
Saleem Abdulrasoolb2826a12017-01-03 21:53:513546#if defined(_LIBCPP_SHORT_WCHAR)
Howard Hinnant271426e2013-07-08 19:03:073547 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073548 __maxcode_, __mode_);
Howard Hinnant271426e2013-07-08 19:03:073549#else
Howard Hinnant0c17e322010-05-30 21:39:413550 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073551 __maxcode_, __mode_);
Howard Hinnant271426e2013-07-08 19:03:073552#endif
Howard Hinnant0c17e322010-05-30 21:39:413553 frm_nxt = frm + (_frm_nxt - _frm);
3554 to_nxt = to + (_to_nxt - _to);
3555 return r;
Howard Hinnant3e519522010-05-11 19:42:163556}
3557
Howard Hinnant0c17e322010-05-30 21:39:413558__codecvt_utf8<wchar_t>::result
3559__codecvt_utf8<wchar_t>::do_in(state_type&,
3560 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
Howard Hinnant3e519522010-05-11 19:42:163561 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3562{
Howard Hinnant0c17e322010-05-30 21:39:413563 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3564 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3565 const uint8_t* _frm_nxt = _frm;
Saleem Abdulrasoolb2826a12017-01-03 21:53:513566#if defined(_LIBCPP_SHORT_WCHAR)
Howard Hinnant271426e2013-07-08 19:03:073567 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3568 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3569 uint16_t* _to_nxt = _to;
3570 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073571 __maxcode_, __mode_);
Howard Hinnant271426e2013-07-08 19:03:073572#else
Howard Hinnant0c17e322010-05-30 21:39:413573 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3574 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3575 uint32_t* _to_nxt = _to;
3576 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073577 __maxcode_, __mode_);
Howard Hinnant271426e2013-07-08 19:03:073578#endif
Howard Hinnant0c17e322010-05-30 21:39:413579 frm_nxt = frm + (_frm_nxt - _frm);
3580 to_nxt = to + (_to_nxt - _to);
3581 return r;
Howard Hinnant3e519522010-05-11 19:42:163582}
3583
Howard Hinnant0c17e322010-05-30 21:39:413584__codecvt_utf8<wchar_t>::result
3585__codecvt_utf8<wchar_t>::do_unshift(state_type&,
Howard Hinnant3e519522010-05-11 19:42:163586 extern_type* to, extern_type*, extern_type*& to_nxt) const
3587{
3588 to_nxt = to;
3589 return noconv;
3590}
3591
3592int
Louis Dionne56013052021-03-01 17:09:453593__codecvt_utf8<wchar_t>::do_encoding() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163594{
3595 return 0;
3596}
3597
3598bool
Louis Dionne56013052021-03-01 17:09:453599__codecvt_utf8<wchar_t>::do_always_noconv() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163600{
3601 return false;
3602}
3603
3604int
Howard Hinnant0c17e322010-05-30 21:39:413605__codecvt_utf8<wchar_t>::do_length(state_type&,
Howard Hinnant3e519522010-05-11 19:42:163606 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3607{
Howard Hinnant0c17e322010-05-30 21:39:413608 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3609 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Xing Xuef53fafb2021-09-09 20:20:363610#if defined(_LIBCPP_SHORT_WCHAR)
Nikolas Klauser84fc2c32022-09-02 14:19:073611 return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363612#else
Nikolas Klauser84fc2c32022-09-02 14:19:073613 return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363614#endif
Howard Hinnant3e519522010-05-11 19:42:163615}
3616
Nikolas Klauser3ee9a502022-06-30 11:47:263617_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant3e519522010-05-11 19:42:163618int
Louis Dionne56013052021-03-01 17:09:453619__codecvt_utf8<wchar_t>::do_max_length() const noexcept
Howard Hinnant3e519522010-05-11 19:42:163620{
Xing Xuef53fafb2021-09-09 20:20:363621#if defined(_LIBCPP_SHORT_WCHAR)
Nikolas Klauser84fc2c32022-09-02 14:19:073622 if (__mode_ & consume_header)
Xing Xuef53fafb2021-09-09 20:20:363623 return 6;
3624 return 3;
3625#else
Nikolas Klauser84fc2c32022-09-02 14:19:073626 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:413627 return 7;
3628 return 4;
Xing Xuef53fafb2021-09-09 20:20:363629#endif
Howard Hinnant0c17e322010-05-30 21:39:413630}
Louis Dionnef4c12582021-08-23 19:32:363631#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant0c17e322010-05-30 21:39:413632
3633// __codecvt_utf8<char16_t>
3634
3635__codecvt_utf8<char16_t>::result
3636__codecvt_utf8<char16_t>::do_out(state_type&,
3637 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3638 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3639{
3640 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3641 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3642 const uint16_t* _frm_nxt = _frm;
3643 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3644 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3645 uint8_t* _to_nxt = _to;
3646 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073647 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:413648 frm_nxt = frm + (_frm_nxt - _frm);
3649 to_nxt = to + (_to_nxt - _to);
3650 return r;
3651}
3652
3653__codecvt_utf8<char16_t>::result
3654__codecvt_utf8<char16_t>::do_in(state_type&,
3655 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3656 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3657{
3658 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3659 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3660 const uint8_t* _frm_nxt = _frm;
3661 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3662 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3663 uint16_t* _to_nxt = _to;
3664 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073665 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:413666 frm_nxt = frm + (_frm_nxt - _frm);
3667 to_nxt = to + (_to_nxt - _to);
3668 return r;
3669}
3670
3671__codecvt_utf8<char16_t>::result
3672__codecvt_utf8<char16_t>::do_unshift(state_type&,
3673 extern_type* to, extern_type*, extern_type*& to_nxt) const
3674{
3675 to_nxt = to;
3676 return noconv;
3677}
3678
3679int
Louis Dionne56013052021-03-01 17:09:453680__codecvt_utf8<char16_t>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413681{
3682 return 0;
3683}
3684
3685bool
Louis Dionne56013052021-03-01 17:09:453686__codecvt_utf8<char16_t>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413687{
3688 return false;
3689}
3690
3691int
3692__codecvt_utf8<char16_t>::do_length(state_type&,
3693 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3694{
3695 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3696 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:073697 return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:413698}
3699
Nikolas Klauser3ee9a502022-06-30 11:47:263700_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:413701int
Louis Dionne56013052021-03-01 17:09:453702__codecvt_utf8<char16_t>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413703{
Nikolas Klauser84fc2c32022-09-02 14:19:073704 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:413705 return 6;
3706 return 3;
3707}
Nikolas Klauser3ee9a502022-06-30 11:47:263708_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:413709
3710// __codecvt_utf8<char32_t>
3711
3712__codecvt_utf8<char32_t>::result
3713__codecvt_utf8<char32_t>::do_out(state_type&,
3714 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3715 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3716{
3717 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3718 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3719 const uint32_t* _frm_nxt = _frm;
3720 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3721 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3722 uint8_t* _to_nxt = _to;
3723 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073724 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:413725 frm_nxt = frm + (_frm_nxt - _frm);
3726 to_nxt = to + (_to_nxt - _to);
3727 return r;
3728}
3729
3730__codecvt_utf8<char32_t>::result
3731__codecvt_utf8<char32_t>::do_in(state_type&,
3732 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3733 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3734{
3735 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3736 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3737 const uint8_t* _frm_nxt = _frm;
3738 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3739 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3740 uint32_t* _to_nxt = _to;
3741 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073742 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:413743 frm_nxt = frm + (_frm_nxt - _frm);
3744 to_nxt = to + (_to_nxt - _to);
3745 return r;
3746}
3747
3748__codecvt_utf8<char32_t>::result
3749__codecvt_utf8<char32_t>::do_unshift(state_type&,
3750 extern_type* to, extern_type*, extern_type*& to_nxt) const
3751{
3752 to_nxt = to;
3753 return noconv;
3754}
3755
3756int
Louis Dionne56013052021-03-01 17:09:453757__codecvt_utf8<char32_t>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413758{
3759 return 0;
3760}
3761
3762bool
Louis Dionne56013052021-03-01 17:09:453763__codecvt_utf8<char32_t>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413764{
3765 return false;
3766}
3767
3768int
3769__codecvt_utf8<char32_t>::do_length(state_type&,
3770 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3771{
3772 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3773 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:073774 return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:413775}
3776
Nikolas Klauser3ee9a502022-06-30 11:47:263777_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:413778int
Louis Dionne56013052021-03-01 17:09:453779__codecvt_utf8<char32_t>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413780{
Nikolas Klauser84fc2c32022-09-02 14:19:073781 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:413782 return 7;
3783 return 4;
3784}
Nikolas Klauser3ee9a502022-06-30 11:47:263785_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:413786
3787// __codecvt_utf16<wchar_t, false>
3788
Louis Dionnef4c12582021-08-23 19:32:363789#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant0c17e322010-05-30 21:39:413790__codecvt_utf16<wchar_t, false>::result
3791__codecvt_utf16<wchar_t, false>::do_out(state_type&,
3792 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3793 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3794{
Xing Xuef53fafb2021-09-09 20:20:363795#if defined(_LIBCPP_SHORT_WCHAR)
3796 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3797 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3798 const uint16_t* _frm_nxt = _frm;
3799#else
Howard Hinnant0c17e322010-05-30 21:39:413800 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3801 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3802 const uint32_t* _frm_nxt = _frm;
Xing Xuef53fafb2021-09-09 20:20:363803#endif
Howard Hinnant0c17e322010-05-30 21:39:413804 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3805 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3806 uint8_t* _to_nxt = _to;
Xing Xuef53fafb2021-09-09 20:20:363807#if defined(_LIBCPP_SHORT_WCHAR)
3808 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073809 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363810#else
Howard Hinnant0c17e322010-05-30 21:39:413811 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073812 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363813#endif
Howard Hinnant0c17e322010-05-30 21:39:413814 frm_nxt = frm + (_frm_nxt - _frm);
3815 to_nxt = to + (_to_nxt - _to);
3816 return r;
3817}
3818
3819__codecvt_utf16<wchar_t, false>::result
3820__codecvt_utf16<wchar_t, false>::do_in(state_type&,
3821 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3822 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3823{
3824 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3825 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3826 const uint8_t* _frm_nxt = _frm;
Xing Xuef53fafb2021-09-09 20:20:363827#if defined(_LIBCPP_SHORT_WCHAR)
3828 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3829 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3830 uint16_t* _to_nxt = _to;
3831 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073832 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363833#else
Howard Hinnant0c17e322010-05-30 21:39:413834 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3835 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3836 uint32_t* _to_nxt = _to;
3837 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073838 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363839#endif
Howard Hinnant0c17e322010-05-30 21:39:413840 frm_nxt = frm + (_frm_nxt - _frm);
3841 to_nxt = to + (_to_nxt - _to);
3842 return r;
3843}
3844
3845__codecvt_utf16<wchar_t, false>::result
3846__codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3847 extern_type* to, extern_type*, extern_type*& to_nxt) const
3848{
3849 to_nxt = to;
3850 return noconv;
3851}
3852
3853int
Louis Dionne56013052021-03-01 17:09:453854__codecvt_utf16<wchar_t, false>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413855{
3856 return 0;
3857}
3858
3859bool
Louis Dionne56013052021-03-01 17:09:453860__codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413861{
3862 return false;
3863}
3864
3865int
3866__codecvt_utf16<wchar_t, false>::do_length(state_type&,
3867 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3868{
3869 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3870 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Xing Xuef53fafb2021-09-09 20:20:363871#if defined(_LIBCPP_SHORT_WCHAR)
Nikolas Klauser84fc2c32022-09-02 14:19:073872 return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363873#else
Nikolas Klauser84fc2c32022-09-02 14:19:073874 return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363875#endif
Howard Hinnant0c17e322010-05-30 21:39:413876}
3877
3878int
Louis Dionne56013052021-03-01 17:09:453879__codecvt_utf16<wchar_t, false>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413880{
Xing Xuef53fafb2021-09-09 20:20:363881#if defined(_LIBCPP_SHORT_WCHAR)
Nikolas Klauser84fc2c32022-09-02 14:19:073882 if (__mode_ & consume_header)
Xing Xuef53fafb2021-09-09 20:20:363883 return 4;
3884 return 2;
3885#else
Nikolas Klauser84fc2c32022-09-02 14:19:073886 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:413887 return 6;
3888 return 4;
Xing Xuef53fafb2021-09-09 20:20:363889#endif
Howard Hinnant0c17e322010-05-30 21:39:413890}
3891
3892// __codecvt_utf16<wchar_t, true>
3893
3894__codecvt_utf16<wchar_t, true>::result
3895__codecvt_utf16<wchar_t, true>::do_out(state_type&,
3896 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3897 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3898{
Xing Xuef53fafb2021-09-09 20:20:363899#if defined(_LIBCPP_SHORT_WCHAR)
3900 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3901 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3902 const uint16_t* _frm_nxt = _frm;
3903#else
Howard Hinnant0c17e322010-05-30 21:39:413904 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3905 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3906 const uint32_t* _frm_nxt = _frm;
Xing Xuef53fafb2021-09-09 20:20:363907#endif
Howard Hinnant0c17e322010-05-30 21:39:413908 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3909 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3910 uint8_t* _to_nxt = _to;
Xing Xuef53fafb2021-09-09 20:20:363911#if defined(_LIBCPP_SHORT_WCHAR)
3912 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073913 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363914#else
Howard Hinnant0c17e322010-05-30 21:39:413915 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073916 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363917#endif
Howard Hinnant0c17e322010-05-30 21:39:413918 frm_nxt = frm + (_frm_nxt - _frm);
3919 to_nxt = to + (_to_nxt - _to);
3920 return r;
3921}
3922
3923__codecvt_utf16<wchar_t, true>::result
3924__codecvt_utf16<wchar_t, true>::do_in(state_type&,
3925 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3926 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3927{
3928 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3929 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3930 const uint8_t* _frm_nxt = _frm;
Xing Xuef53fafb2021-09-09 20:20:363931#if defined(_LIBCPP_SHORT_WCHAR)
3932 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3933 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3934 uint16_t* _to_nxt = _to;
3935 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073936 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363937#else
Howard Hinnant0c17e322010-05-30 21:39:413938 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3939 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3940 uint32_t* _to_nxt = _to;
3941 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:073942 __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363943#endif
Howard Hinnant0c17e322010-05-30 21:39:413944 frm_nxt = frm + (_frm_nxt - _frm);
3945 to_nxt = to + (_to_nxt - _to);
3946 return r;
3947}
3948
3949__codecvt_utf16<wchar_t, true>::result
3950__codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3951 extern_type* to, extern_type*, extern_type*& to_nxt) const
3952{
3953 to_nxt = to;
3954 return noconv;
3955}
3956
3957int
Louis Dionne56013052021-03-01 17:09:453958__codecvt_utf16<wchar_t, true>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413959{
3960 return 0;
3961}
3962
3963bool
Louis Dionne56013052021-03-01 17:09:453964__codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413965{
Howard Hinnant5d3c1132010-05-31 20:58:543966 return false;
Howard Hinnant0c17e322010-05-30 21:39:413967}
3968
3969int
3970__codecvt_utf16<wchar_t, true>::do_length(state_type&,
3971 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3972{
3973 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3974 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Xing Xuef53fafb2021-09-09 20:20:363975#if defined(_LIBCPP_SHORT_WCHAR)
Nikolas Klauser84fc2c32022-09-02 14:19:073976 return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363977#else
Nikolas Klauser84fc2c32022-09-02 14:19:073978 return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Xing Xuef53fafb2021-09-09 20:20:363979#endif
Howard Hinnant0c17e322010-05-30 21:39:413980}
3981
3982int
Louis Dionne56013052021-03-01 17:09:453983__codecvt_utf16<wchar_t, true>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:413984{
Xing Xuef53fafb2021-09-09 20:20:363985#if defined(_LIBCPP_SHORT_WCHAR)
Nikolas Klauser84fc2c32022-09-02 14:19:073986 if (__mode_ & consume_header)
Xing Xuef53fafb2021-09-09 20:20:363987 return 4;
3988 return 2;
3989#else
Nikolas Klauser84fc2c32022-09-02 14:19:073990 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:413991 return 6;
3992 return 4;
Xing Xuef53fafb2021-09-09 20:20:363993#endif
Howard Hinnant0c17e322010-05-30 21:39:413994}
Louis Dionnef4c12582021-08-23 19:32:363995#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant0c17e322010-05-30 21:39:413996
3997// __codecvt_utf16<char16_t, false>
3998
3999__codecvt_utf16<char16_t, false>::result
4000__codecvt_utf16<char16_t, false>::do_out(state_type&,
4001 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4002 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4003{
4004 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4005 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4006 const uint16_t* _frm_nxt = _frm;
4007 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4008 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4009 uint8_t* _to_nxt = _to;
4010 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074011 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414012 frm_nxt = frm + (_frm_nxt - _frm);
4013 to_nxt = to + (_to_nxt - _to);
4014 return r;
4015}
4016
4017__codecvt_utf16<char16_t, false>::result
4018__codecvt_utf16<char16_t, false>::do_in(state_type&,
4019 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4020 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4021{
4022 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4023 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4024 const uint8_t* _frm_nxt = _frm;
4025 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4026 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4027 uint16_t* _to_nxt = _to;
4028 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074029 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414030 frm_nxt = frm + (_frm_nxt - _frm);
4031 to_nxt = to + (_to_nxt - _to);
4032 return r;
4033}
4034
4035__codecvt_utf16<char16_t, false>::result
4036__codecvt_utf16<char16_t, false>::do_unshift(state_type&,
4037 extern_type* to, extern_type*, extern_type*& to_nxt) const
4038{
4039 to_nxt = to;
4040 return noconv;
4041}
4042
4043int
Louis Dionne56013052021-03-01 17:09:454044__codecvt_utf16<char16_t, false>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414045{
4046 return 0;
4047}
4048
4049bool
Louis Dionne56013052021-03-01 17:09:454050__codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414051{
4052 return false;
4053}
4054
4055int
4056__codecvt_utf16<char16_t, false>::do_length(state_type&,
4057 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4058{
4059 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4060 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074061 return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414062}
4063
Nikolas Klauser3ee9a502022-06-30 11:47:264064_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:414065int
Louis Dionne56013052021-03-01 17:09:454066__codecvt_utf16<char16_t, false>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414067{
Nikolas Klauser84fc2c32022-09-02 14:19:074068 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414069 return 4;
Howard Hinnant3e519522010-05-11 19:42:164070 return 2;
4071}
Nikolas Klauser3ee9a502022-06-30 11:47:264072_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant3e519522010-05-11 19:42:164073
Howard Hinnant0c17e322010-05-30 21:39:414074// __codecvt_utf16<char16_t, true>
4075
4076__codecvt_utf16<char16_t, true>::result
4077__codecvt_utf16<char16_t, true>::do_out(state_type&,
4078 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4079 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4080{
4081 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4082 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4083 const uint16_t* _frm_nxt = _frm;
4084 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4085 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4086 uint8_t* _to_nxt = _to;
4087 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074088 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414089 frm_nxt = frm + (_frm_nxt - _frm);
4090 to_nxt = to + (_to_nxt - _to);
4091 return r;
4092}
4093
4094__codecvt_utf16<char16_t, true>::result
4095__codecvt_utf16<char16_t, true>::do_in(state_type&,
4096 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4097 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4098{
4099 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4100 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4101 const uint8_t* _frm_nxt = _frm;
4102 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4103 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4104 uint16_t* _to_nxt = _to;
4105 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074106 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414107 frm_nxt = frm + (_frm_nxt - _frm);
4108 to_nxt = to + (_to_nxt - _to);
4109 return r;
4110}
4111
4112__codecvt_utf16<char16_t, true>::result
4113__codecvt_utf16<char16_t, true>::do_unshift(state_type&,
4114 extern_type* to, extern_type*, extern_type*& to_nxt) const
4115{
4116 to_nxt = to;
4117 return noconv;
4118}
4119
4120int
Louis Dionne56013052021-03-01 17:09:454121__codecvt_utf16<char16_t, true>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414122{
4123 return 0;
4124}
4125
4126bool
Louis Dionne56013052021-03-01 17:09:454127__codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414128{
Howard Hinnant5d3c1132010-05-31 20:58:544129 return false;
Howard Hinnant0c17e322010-05-30 21:39:414130}
4131
4132int
4133__codecvt_utf16<char16_t, true>::do_length(state_type&,
4134 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4135{
4136 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4137 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074138 return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414139}
4140
Nikolas Klauser3ee9a502022-06-30 11:47:264141_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:414142int
Louis Dionne56013052021-03-01 17:09:454143__codecvt_utf16<char16_t, true>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414144{
Nikolas Klauser84fc2c32022-09-02 14:19:074145 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414146 return 4;
4147 return 2;
4148}
Nikolas Klauser3ee9a502022-06-30 11:47:264149_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:414150
4151// __codecvt_utf16<char32_t, false>
4152
4153__codecvt_utf16<char32_t, false>::result
4154__codecvt_utf16<char32_t, false>::do_out(state_type&,
4155 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4156 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4157{
4158 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4159 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4160 const uint32_t* _frm_nxt = _frm;
4161 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4162 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4163 uint8_t* _to_nxt = _to;
4164 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074165 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414166 frm_nxt = frm + (_frm_nxt - _frm);
4167 to_nxt = to + (_to_nxt - _to);
4168 return r;
4169}
4170
4171__codecvt_utf16<char32_t, false>::result
4172__codecvt_utf16<char32_t, false>::do_in(state_type&,
4173 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4174 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4175{
4176 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4177 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4178 const uint8_t* _frm_nxt = _frm;
4179 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4180 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4181 uint32_t* _to_nxt = _to;
4182 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074183 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414184 frm_nxt = frm + (_frm_nxt - _frm);
4185 to_nxt = to + (_to_nxt - _to);
4186 return r;
4187}
4188
4189__codecvt_utf16<char32_t, false>::result
4190__codecvt_utf16<char32_t, false>::do_unshift(state_type&,
4191 extern_type* to, extern_type*, extern_type*& to_nxt) const
4192{
4193 to_nxt = to;
4194 return noconv;
4195}
4196
4197int
Louis Dionne56013052021-03-01 17:09:454198__codecvt_utf16<char32_t, false>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414199{
4200 return 0;
4201}
4202
4203bool
Louis Dionne56013052021-03-01 17:09:454204__codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414205{
4206 return false;
4207}
4208
4209int
4210__codecvt_utf16<char32_t, false>::do_length(state_type&,
4211 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4212{
4213 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4214 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074215 return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414216}
4217
Nikolas Klauser3ee9a502022-06-30 11:47:264218_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:414219int
Louis Dionne56013052021-03-01 17:09:454220__codecvt_utf16<char32_t, false>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414221{
Nikolas Klauser84fc2c32022-09-02 14:19:074222 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414223 return 6;
4224 return 4;
4225}
Nikolas Klauser3ee9a502022-06-30 11:47:264226_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:414227
4228// __codecvt_utf16<char32_t, true>
4229
4230__codecvt_utf16<char32_t, true>::result
4231__codecvt_utf16<char32_t, true>::do_out(state_type&,
4232 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4233 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4234{
4235 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4236 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4237 const uint32_t* _frm_nxt = _frm;
4238 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4239 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4240 uint8_t* _to_nxt = _to;
4241 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074242 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414243 frm_nxt = frm + (_frm_nxt - _frm);
4244 to_nxt = to + (_to_nxt - _to);
4245 return r;
4246}
4247
4248__codecvt_utf16<char32_t, true>::result
4249__codecvt_utf16<char32_t, true>::do_in(state_type&,
4250 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4251 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4252{
4253 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4254 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4255 const uint8_t* _frm_nxt = _frm;
4256 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4257 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4258 uint32_t* _to_nxt = _to;
4259 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074260 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414261 frm_nxt = frm + (_frm_nxt - _frm);
4262 to_nxt = to + (_to_nxt - _to);
4263 return r;
4264}
4265
4266__codecvt_utf16<char32_t, true>::result
4267__codecvt_utf16<char32_t, true>::do_unshift(state_type&,
4268 extern_type* to, extern_type*, extern_type*& to_nxt) const
4269{
4270 to_nxt = to;
4271 return noconv;
4272}
4273
4274int
Louis Dionne56013052021-03-01 17:09:454275__codecvt_utf16<char32_t, true>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414276{
4277 return 0;
4278}
4279
4280bool
Louis Dionne56013052021-03-01 17:09:454281__codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414282{
Howard Hinnant5d3c1132010-05-31 20:58:544283 return false;
Howard Hinnant0c17e322010-05-30 21:39:414284}
4285
4286int
4287__codecvt_utf16<char32_t, true>::do_length(state_type&,
4288 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4289{
4290 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4291 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074292 return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414293}
4294
Nikolas Klauser3ee9a502022-06-30 11:47:264295_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:414296int
Louis Dionne56013052021-03-01 17:09:454297__codecvt_utf16<char32_t, true>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414298{
Nikolas Klauser84fc2c32022-09-02 14:19:074299 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414300 return 6;
4301 return 4;
4302}
Nikolas Klauser3ee9a502022-06-30 11:47:264303_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:414304
4305// __codecvt_utf8_utf16<wchar_t>
4306
Louis Dionnef4c12582021-08-23 19:32:364307#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant0c17e322010-05-30 21:39:414308__codecvt_utf8_utf16<wchar_t>::result
4309__codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
4310 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4311 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4312{
Xing Xuef53fafb2021-09-09 20:20:364313#if defined(_LIBCPP_SHORT_WCHAR)
4314 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4315 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4316 const uint16_t* _frm_nxt = _frm;
4317#else
Howard Hinnant0c17e322010-05-30 21:39:414318 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4319 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4320 const uint32_t* _frm_nxt = _frm;
Xing Xuef53fafb2021-09-09 20:20:364321#endif
Howard Hinnant0c17e322010-05-30 21:39:414322 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4323 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4324 uint8_t* _to_nxt = _to;
4325 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074326 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414327 frm_nxt = frm + (_frm_nxt - _frm);
4328 to_nxt = to + (_to_nxt - _to);
4329 return r;
4330}
4331
4332__codecvt_utf8_utf16<wchar_t>::result
4333__codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
4334 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4335 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4336{
4337 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4338 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4339 const uint8_t* _frm_nxt = _frm;
Xing Xuef53fafb2021-09-09 20:20:364340#if defined(_LIBCPP_SHORT_WCHAR)
4341 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4342 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4343 uint16_t* _to_nxt = _to;
4344#else
Howard Hinnant0c17e322010-05-30 21:39:414345 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4346 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4347 uint32_t* _to_nxt = _to;
Xing Xuef53fafb2021-09-09 20:20:364348#endif
Howard Hinnant0c17e322010-05-30 21:39:414349 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074350 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414351 frm_nxt = frm + (_frm_nxt - _frm);
4352 to_nxt = to + (_to_nxt - _to);
4353 return r;
4354}
4355
4356__codecvt_utf8_utf16<wchar_t>::result
4357__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
4358 extern_type* to, extern_type*, extern_type*& to_nxt) const
4359{
4360 to_nxt = to;
4361 return noconv;
4362}
4363
4364int
Louis Dionne56013052021-03-01 17:09:454365__codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414366{
4367 return 0;
4368}
4369
4370bool
Louis Dionne56013052021-03-01 17:09:454371__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414372{
4373 return false;
4374}
4375
4376int
4377__codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4378 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4379{
4380 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4381 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074382 return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414383}
4384
4385int
Louis Dionne56013052021-03-01 17:09:454386__codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414387{
Nikolas Klauser84fc2c32022-09-02 14:19:074388 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414389 return 7;
4390 return 4;
4391}
Louis Dionnef4c12582021-08-23 19:32:364392#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant0c17e322010-05-30 21:39:414393
4394// __codecvt_utf8_utf16<char16_t>
4395
4396__codecvt_utf8_utf16<char16_t>::result
4397__codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4398 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4399 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4400{
4401 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4402 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4403 const uint16_t* _frm_nxt = _frm;
4404 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4405 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4406 uint8_t* _to_nxt = _to;
4407 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074408 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414409 frm_nxt = frm + (_frm_nxt - _frm);
4410 to_nxt = to + (_to_nxt - _to);
4411 return r;
4412}
4413
4414__codecvt_utf8_utf16<char16_t>::result
4415__codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4416 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4417 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4418{
4419 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4420 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4421 const uint8_t* _frm_nxt = _frm;
4422 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4423 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4424 uint16_t* _to_nxt = _to;
4425 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074426 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414427 frm_nxt = frm + (_frm_nxt - _frm);
4428 to_nxt = to + (_to_nxt - _to);
4429 return r;
4430}
4431
4432__codecvt_utf8_utf16<char16_t>::result
4433__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4434 extern_type* to, extern_type*, extern_type*& to_nxt) const
4435{
4436 to_nxt = to;
4437 return noconv;
4438}
4439
4440int
Louis Dionne56013052021-03-01 17:09:454441__codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414442{
4443 return 0;
4444}
4445
4446bool
Louis Dionne56013052021-03-01 17:09:454447__codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414448{
4449 return false;
4450}
4451
4452int
4453__codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4454 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4455{
4456 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4457 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074458 return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414459}
4460
Nikolas Klauser3ee9a502022-06-30 11:47:264461_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:414462int
Louis Dionne56013052021-03-01 17:09:454463__codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414464{
Nikolas Klauser84fc2c32022-09-02 14:19:074465 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414466 return 7;
4467 return 4;
4468}
Nikolas Klauser3ee9a502022-06-30 11:47:264469_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:414470
4471// __codecvt_utf8_utf16<char32_t>
4472
4473__codecvt_utf8_utf16<char32_t>::result
4474__codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4475 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4476 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4477{
4478 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4479 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4480 const uint32_t* _frm_nxt = _frm;
4481 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4482 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4483 uint8_t* _to_nxt = _to;
4484 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074485 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414486 frm_nxt = frm + (_frm_nxt - _frm);
4487 to_nxt = to + (_to_nxt - _to);
4488 return r;
4489}
4490
4491__codecvt_utf8_utf16<char32_t>::result
4492__codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4493 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4494 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4495{
4496 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4497 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4498 const uint8_t* _frm_nxt = _frm;
4499 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4500 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4501 uint32_t* _to_nxt = _to;
4502 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
Nikolas Klauser84fc2c32022-09-02 14:19:074503 __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414504 frm_nxt = frm + (_frm_nxt - _frm);
4505 to_nxt = to + (_to_nxt - _to);
4506 return r;
4507}
4508
4509__codecvt_utf8_utf16<char32_t>::result
4510__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4511 extern_type* to, extern_type*, extern_type*& to_nxt) const
4512{
4513 to_nxt = to;
4514 return noconv;
4515}
4516
4517int
Louis Dionne56013052021-03-01 17:09:454518__codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414519{
4520 return 0;
4521}
4522
4523bool
Louis Dionne56013052021-03-01 17:09:454524__codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414525{
4526 return false;
4527}
4528
4529int
4530__codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4531 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4532{
4533 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4534 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
Nikolas Klauser84fc2c32022-09-02 14:19:074535 return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
Howard Hinnant0c17e322010-05-30 21:39:414536}
4537
Nikolas Klauser3ee9a502022-06-30 11:47:264538_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Howard Hinnant0c17e322010-05-30 21:39:414539int
Louis Dionne56013052021-03-01 17:09:454540__codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept
Howard Hinnant0c17e322010-05-30 21:39:414541{
Nikolas Klauser84fc2c32022-09-02 14:19:074542 if (__mode_ & consume_header)
Howard Hinnant0c17e322010-05-30 21:39:414543 return 7;
4544 return 4;
4545}
Nikolas Klauser3ee9a502022-06-30 11:47:264546_LIBCPP_SUPPRESS_DEPRECATED_POP
Howard Hinnant0c17e322010-05-30 21:39:414547
Howard Hinnant3e519522010-05-11 19:42:164548// __narrow_to_utf8<16>
4549
4550__narrow_to_utf8<16>::~__narrow_to_utf8()
4551{
4552}
4553
4554// __narrow_to_utf8<32>
4555
4556__narrow_to_utf8<32>::~__narrow_to_utf8()
4557{
4558}
4559
4560// __widen_from_utf8<16>
4561
4562__widen_from_utf8<16>::~__widen_from_utf8()
4563{
4564}
4565
4566// __widen_from_utf8<32>
4567
4568__widen_from_utf8<32>::~__widen_from_utf8()
4569{
4570}
4571
Louis Dionnef4c12582021-08-23 19:32:364572#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Eric Fiselier0d542d32016-12-11 00:20:594573static bool checked_string_to_wchar_convert(wchar_t& dest,
4574 const char* ptr,
Eric Fiselierb4ddab22017-05-08 22:02:434575 locale_t loc) {
Eric Fiselier0d542d32016-12-11 00:20:594576 if (*ptr == '\0')
4577 return false;
4578 mbstate_t mb = {};
4579 wchar_t out;
4580 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4581 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4582 return false;
4583 }
4584 dest = out;
4585 return true;
4586}
Louis Dionnef4c12582021-08-23 19:32:364587#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Eric Fiselier0d542d32016-12-11 00:20:594588
Mark de Wever5de48642021-11-03 18:25:204589#ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4590static bool is_narrow_non_breaking_space(const char* ptr) {
4591 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4592 return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';
4593}
4594
4595static bool is_non_breaking_space(const char* ptr) {
4596 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4597 return ptr[0] == '\xc2' && ptr[1] == '\xa0';
4598}
4599#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4600
Eric Fiselier0d542d32016-12-11 00:20:594601static bool checked_string_to_char_convert(char& dest,
4602 const char* ptr,
Eric Fiselierb4ddab22017-05-08 22:02:434603 locale_t __loc) {
Eric Fiselier0d542d32016-12-11 00:20:594604 if (*ptr == '\0')
4605 return false;
4606 if (!ptr[1]) {
4607 dest = *ptr;
4608 return true;
4609 }
Louis Dionnef4c12582021-08-23 19:32:364610
4611#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Eric Fiselier0d542d32016-12-11 00:20:594612 // First convert the MBS into a wide char then attempt to narrow it using
4613 // wctob_l.
4614 wchar_t wout;
4615 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4616 return false;
4617 int res;
4618 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4619 dest = res;
4620 return true;
4621 }
Louis Dionnedd662f02021-09-09 18:00:224622 // FIXME: Work around specific multibyte sequences that we can reasonably
Eric Fiselier0d542d32016-12-11 00:20:594623 // translate into a different single byte.
4624 switch (wout) {
Eric Fiselierfcc1e6d2018-04-04 04:00:144625 case L'\u202F': // narrow non-breaking space
Eric Fiselier0d542d32016-12-11 00:20:594626 case L'\u00A0': // non-breaking space
4627 dest = ' ';
4628 return true;
4629 default:
4630 return false;
4631 }
Louis Dionnef4c12582021-08-23 19:32:364632#else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Mark de Wever5de48642021-11-03 18:25:204633 // FIXME: Work around specific multibyte sequences that we can reasonably
4634 // translate into a different single byte.
4635 if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {
4636 dest = ' ';
4637 return true;
4638 }
4639
Louis Dionnef4c12582021-08-23 19:32:364640 return false;
4641#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Nikolas Klauser2a8f9a52022-02-14 17:26:024642 __libcpp_unreachable();
Eric Fiselier0d542d32016-12-11 00:20:594643}
4644
4645
Howard Hinnant3e519522010-05-11 19:42:164646// numpunct<char> && numpunct<wchar_t>
4647
4648locale::id numpunct< char >::id;
Louis Dionnef4c12582021-08-23 19:32:364649#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164650locale::id numpunct<wchar_t>::id;
Louis Dionnef4c12582021-08-23 19:32:364651#endif
Howard Hinnant3e519522010-05-11 19:42:164652
4653numpunct<char>::numpunct(size_t refs)
4654 : locale::facet(refs),
4655 __decimal_point_('.'),
4656 __thousands_sep_(',')
4657{
4658}
4659
Louis Dionnef4c12582021-08-23 19:32:364660#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164661numpunct<wchar_t>::numpunct(size_t refs)
4662 : locale::facet(refs),
4663 __decimal_point_(L'.'),
4664 __thousands_sep_(L',')
4665{
4666}
Louis Dionnef4c12582021-08-23 19:32:364667#endif
Howard Hinnant3e519522010-05-11 19:42:164668
4669numpunct<char>::~numpunct()
4670{
4671}
4672
Louis Dionnef4c12582021-08-23 19:32:364673#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164674numpunct<wchar_t>::~numpunct()
4675{
4676}
Louis Dionnef4c12582021-08-23 19:32:364677#endif
Howard Hinnant3e519522010-05-11 19:42:164678
4679 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
Louis Dionnef4c12582021-08-23 19:32:364680#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164681wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
Louis Dionnef4c12582021-08-23 19:32:364682#endif
Howard Hinnant3e519522010-05-11 19:42:164683
4684 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
Louis Dionnef4c12582021-08-23 19:32:364685#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164686wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
Louis Dionnef4c12582021-08-23 19:32:364687#endif
Howard Hinnant3e519522010-05-11 19:42:164688
4689string numpunct< char >::do_grouping() const {return __grouping_;}
Louis Dionnef4c12582021-08-23 19:32:364690#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164691string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
Louis Dionnef4c12582021-08-23 19:32:364692#endif
Howard Hinnant3e519522010-05-11 19:42:164693
4694 string numpunct< char >::do_truename() const {return "true";}
Louis Dionnef4c12582021-08-23 19:32:364695#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164696wstring numpunct<wchar_t>::do_truename() const {return L"true";}
Louis Dionnef4c12582021-08-23 19:32:364697#endif
Howard Hinnant3e519522010-05-11 19:42:164698
4699 string numpunct< char >::do_falsename() const {return "false";}
Louis Dionnef4c12582021-08-23 19:32:364700#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164701wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
Louis Dionnef4c12582021-08-23 19:32:364702#endif
Howard Hinnant3e519522010-05-11 19:42:164703
4704// numpunct_byname<char>
4705
4706numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4707 : numpunct<char>(refs)
4708{
4709 __init(nm);
4710}
4711
4712numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4713 : numpunct<char>(refs)
4714{
4715 __init(nm.c_str());
4716}
4717
4718numpunct_byname<char>::~numpunct_byname()
4719{
4720}
4721
4722void
4723numpunct_byname<char>::__init(const char* nm)
4724{
Louis Dionnef4c12582021-08-23 19:32:364725 typedef numpunct<char> base;
Howard Hinnant3e519522010-05-11 19:42:164726 if (strcmp(nm, "C") != 0)
4727 {
Eric Fiselierb4ddab22017-05-08 22:02:434728 __libcpp_unique_locale loc(nm);
4729 if (!loc)
Marshall Clowd437fa52016-08-25 15:09:014730 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
Howard Hinnant3e519522010-05-11 19:42:164731 " failed to construct for " + string(nm));
Marshall Clowd437fa52016-08-25 15:09:014732
Ben Craigd2f15ba2016-03-09 15:39:394733 lconv* lc = __libcpp_localeconv_l(loc.get());
Louis Dionnef4c12582021-08-23 19:32:364734 if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4735 loc.get()))
4736 __decimal_point_ = base::do_decimal_point();
4737 if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4738 loc.get()))
4739 __thousands_sep_ = base::do_thousands_sep();
Howard Hinnant3e519522010-05-11 19:42:164740 __grouping_ = lc->grouping;
Alexis Hunte7897552011-07-07 22:45:074741 // localization for truename and falsename is not available
Howard Hinnant3e519522010-05-11 19:42:164742 }
4743}
4744
4745// numpunct_byname<wchar_t>
4746
Louis Dionnef4c12582021-08-23 19:32:364747#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164748numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4749 : numpunct<wchar_t>(refs)
4750{
4751 __init(nm);
4752}
4753
4754numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4755 : numpunct<wchar_t>(refs)
4756{
4757 __init(nm.c_str());
4758}
4759
4760numpunct_byname<wchar_t>::~numpunct_byname()
4761{
4762}
4763
4764void
4765numpunct_byname<wchar_t>::__init(const char* nm)
4766{
4767 if (strcmp(nm, "C") != 0)
4768 {
Eric Fiselierb4ddab22017-05-08 22:02:434769 __libcpp_unique_locale loc(nm);
4770 if (!loc)
Eric Fiselier0d542d32016-12-11 00:20:594771 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
Howard Hinnant3e519522010-05-11 19:42:164772 " failed to construct for " + string(nm));
Marshall Clowd437fa52016-08-25 15:09:014773
Ben Craigd2f15ba2016-03-09 15:39:394774 lconv* lc = __libcpp_localeconv_l(loc.get());
Eric Fiselier0d542d32016-12-11 00:20:594775 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4776 loc.get());
4777 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4778 loc.get());
Howard Hinnant3e519522010-05-11 19:42:164779 __grouping_ = lc->grouping;
Eric Fiselier0d542d32016-12-11 00:20:594780 // localization for truename and falsename is not available
Howard Hinnant3e519522010-05-11 19:42:164781 }
4782}
Louis Dionnef4c12582021-08-23 19:32:364783#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164784
4785// num_get helpers
4786
4787int
4788__num_get_base::__get_base(ios_base& iob)
4789{
4790 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4791 if (__basefield == ios_base::oct)
4792 return 8;
4793 else if (__basefield == ios_base::hex)
4794 return 16;
4795 else if (__basefield == 0)
4796 return 0;
4797 return 10;
4798}
4799
4800const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4801
4802void
4803__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4804 ios_base::iostate& __err)
4805{
Marshall Clow605d62e2019-06-04 15:18:464806// if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4807// we always have at least a single entry in [__g, __g_end); the end of the input sequence
Louis Dionne355e0ce2022-08-18 21:41:134808 if (__grouping.size() != 0 && __g_end - __g > 1)
Howard Hinnant3e519522010-05-11 19:42:164809 {
4810 reverse(__g, __g_end);
4811 const char* __ig = __grouping.data();
4812 const char* __eg = __ig + __grouping.size();
4813 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4814 {
4815 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4816 {
Howard Hinnantc2063662011-12-01 20:21:044817 if (static_cast<unsigned>(*__ig) != *__r)
Howard Hinnant3e519522010-05-11 19:42:164818 {
4819 __err = ios_base::failbit;
4820 return;
4821 }
4822 }
4823 if (__eg - __ig > 1)
4824 ++__ig;
4825 }
4826 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4827 {
Howard Hinnantc2063662011-12-01 20:21:044828 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
Howard Hinnant3e519522010-05-11 19:42:164829 __err = ios_base::failbit;
4830 }
4831 }
4832}
4833
4834void
4835__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4836 ios_base::fmtflags __flags)
4837{
Martin Storsjöb0cc7b52021-06-01 09:04:584838 if ((__flags & ios_base::showpos) &&
4839 (__flags & ios_base::basefield) != ios_base::oct &&
4840 (__flags & ios_base::basefield) != ios_base::hex &&
Louis Dionne355e0ce2022-08-18 21:41:134841 __signd)
Howard Hinnant3e519522010-05-11 19:42:164842 *__fmtp++ = '+';
4843 if (__flags & ios_base::showbase)
4844 *__fmtp++ = '#';
4845 while(*__len)
4846 *__fmtp++ = *__len++;
4847 if ((__flags & ios_base::basefield) == ios_base::oct)
4848 *__fmtp = 'o';
4849 else if ((__flags & ios_base::basefield) == ios_base::hex)
4850 {
4851 if (__flags & ios_base::uppercase)
4852 *__fmtp = 'X';
4853 else
4854 *__fmtp = 'x';
4855 }
4856 else if (__signd)
4857 *__fmtp = 'd';
4858 else
4859 *__fmtp = 'u';
4860}
4861
4862bool
4863__num_put_base::__format_float(char* __fmtp, const char* __len,
4864 ios_base::fmtflags __flags)
4865{
4866 bool specify_precision = true;
4867 if (__flags & ios_base::showpos)
4868 *__fmtp++ = '+';
4869 if (__flags & ios_base::showpoint)
4870 *__fmtp++ = '#';
4871 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
Marshall Clow520469c2013-10-21 15:07:284872 bool uppercase = (__flags & ios_base::uppercase) != 0;
Howard Hinnant3e519522010-05-11 19:42:164873 if (floatfield == (ios_base::fixed | ios_base::scientific))
4874 specify_precision = false;
4875 else
4876 {
4877 *__fmtp++ = '.';
4878 *__fmtp++ = '*';
4879 }
4880 while(*__len)
4881 *__fmtp++ = *__len++;
4882 if (floatfield == ios_base::fixed)
4883 {
4884 if (uppercase)
4885 *__fmtp = 'F';
4886 else
4887 *__fmtp = 'f';
4888 }
4889 else if (floatfield == ios_base::scientific)
4890 {
4891 if (uppercase)
4892 *__fmtp = 'E';
4893 else
4894 *__fmtp = 'e';
4895 }
4896 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4897 {
4898 if (uppercase)
4899 *__fmtp = 'A';
4900 else
4901 *__fmtp = 'a';
4902 }
4903 else
4904 {
4905 if (uppercase)
4906 *__fmtp = 'G';
4907 else
4908 *__fmtp = 'g';
4909 }
4910 return specify_precision;
4911}
4912
4913char*
4914__num_put_base::__identify_padding(char* __nb, char* __ne,
4915 const ios_base& __iob)
4916{
4917 switch (__iob.flags() & ios_base::adjustfield)
4918 {
4919 case ios_base::internal:
4920 if (__nb[0] == '-' || __nb[0] == '+')
4921 return __nb+1;
4922 if (__ne - __nb >= 2 && __nb[0] == '0'
4923 && (__nb[1] == 'x' || __nb[1] == 'X'))
4924 return __nb+2;
4925 break;
4926 case ios_base::left:
4927 return __ne;
4928 case ios_base::right:
4929 default:
4930 break;
4931 }
4932 return __nb;
4933}
4934
4935// time_get
4936
4937static
4938string*
4939init_weeks()
4940{
4941 static string weeks[14];
4942 weeks[0] = "Sunday";
4943 weeks[1] = "Monday";
4944 weeks[2] = "Tuesday";
4945 weeks[3] = "Wednesday";
4946 weeks[4] = "Thursday";
4947 weeks[5] = "Friday";
4948 weeks[6] = "Saturday";
4949 weeks[7] = "Sun";
4950 weeks[8] = "Mon";
4951 weeks[9] = "Tue";
4952 weeks[10] = "Wed";
4953 weeks[11] = "Thu";
4954 weeks[12] = "Fri";
4955 weeks[13] = "Sat";
4956 return weeks;
4957}
4958
Louis Dionnef4c12582021-08-23 19:32:364959#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164960static
4961wstring*
4962init_wweeks()
4963{
4964 static wstring weeks[14];
4965 weeks[0] = L"Sunday";
4966 weeks[1] = L"Monday";
4967 weeks[2] = L"Tuesday";
4968 weeks[3] = L"Wednesday";
4969 weeks[4] = L"Thursday";
4970 weeks[5] = L"Friday";
4971 weeks[6] = L"Saturday";
4972 weeks[7] = L"Sun";
4973 weeks[8] = L"Mon";
4974 weeks[9] = L"Tue";
4975 weeks[10] = L"Wed";
4976 weeks[11] = L"Thu";
4977 weeks[12] = L"Fri";
4978 weeks[13] = L"Sat";
4979 return weeks;
4980}
Louis Dionnef4c12582021-08-23 19:32:364981#endif
Howard Hinnant3e519522010-05-11 19:42:164982
4983template <>
4984const string*
4985__time_get_c_storage<char>::__weeks() const
4986{
4987 static const string* weeks = init_weeks();
4988 return weeks;
4989}
4990
Louis Dionnef4c12582021-08-23 19:32:364991#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:164992template <>
4993const wstring*
4994__time_get_c_storage<wchar_t>::__weeks() const
4995{
4996 static const wstring* weeks = init_wweeks();
4997 return weeks;
4998}
Louis Dionnef4c12582021-08-23 19:32:364999#endif
Howard Hinnant3e519522010-05-11 19:42:165000
5001static
5002string*
5003init_months()
5004{
5005 static string months[24];
5006 months[0] = "January";
5007 months[1] = "February";
5008 months[2] = "March";
5009 months[3] = "April";
5010 months[4] = "May";
5011 months[5] = "June";
5012 months[6] = "July";
5013 months[7] = "August";
5014 months[8] = "September";
5015 months[9] = "October";
5016 months[10] = "November";
5017 months[11] = "December";
5018 months[12] = "Jan";
5019 months[13] = "Feb";
5020 months[14] = "Mar";
5021 months[15] = "Apr";
5022 months[16] = "May";
5023 months[17] = "Jun";
5024 months[18] = "Jul";
5025 months[19] = "Aug";
5026 months[20] = "Sep";
5027 months[21] = "Oct";
5028 months[22] = "Nov";
5029 months[23] = "Dec";
5030 return months;
5031}
5032
Louis Dionnef4c12582021-08-23 19:32:365033#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165034static
5035wstring*
5036init_wmonths()
5037{
5038 static wstring months[24];
5039 months[0] = L"January";
5040 months[1] = L"February";
5041 months[2] = L"March";
5042 months[3] = L"April";
5043 months[4] = L"May";
5044 months[5] = L"June";
5045 months[6] = L"July";
5046 months[7] = L"August";
5047 months[8] = L"September";
5048 months[9] = L"October";
5049 months[10] = L"November";
5050 months[11] = L"December";
5051 months[12] = L"Jan";
5052 months[13] = L"Feb";
5053 months[14] = L"Mar";
5054 months[15] = L"Apr";
5055 months[16] = L"May";
5056 months[17] = L"Jun";
5057 months[18] = L"Jul";
5058 months[19] = L"Aug";
5059 months[20] = L"Sep";
5060 months[21] = L"Oct";
5061 months[22] = L"Nov";
5062 months[23] = L"Dec";
5063 return months;
5064}
Louis Dionnef4c12582021-08-23 19:32:365065#endif
Howard Hinnant3e519522010-05-11 19:42:165066
5067template <>
5068const string*
5069__time_get_c_storage<char>::__months() const
5070{
5071 static const string* months = init_months();
5072 return months;
5073}
5074
Louis Dionnef4c12582021-08-23 19:32:365075#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165076template <>
5077const wstring*
5078__time_get_c_storage<wchar_t>::__months() const
5079{
5080 static const wstring* months = init_wmonths();
5081 return months;
5082}
Louis Dionnef4c12582021-08-23 19:32:365083#endif
Howard Hinnant3e519522010-05-11 19:42:165084
5085static
5086string*
5087init_am_pm()
5088{
Marshall Clow31163f62018-01-11 17:16:525089 static string am_pm[2];
Howard Hinnant3e519522010-05-11 19:42:165090 am_pm[0] = "AM";
5091 am_pm[1] = "PM";
5092 return am_pm;
5093}
5094
Louis Dionnef4c12582021-08-23 19:32:365095#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165096static
5097wstring*
5098init_wam_pm()
5099{
Marshall Clow31163f62018-01-11 17:16:525100 static wstring am_pm[2];
Howard Hinnant3e519522010-05-11 19:42:165101 am_pm[0] = L"AM";
5102 am_pm[1] = L"PM";
5103 return am_pm;
5104}
Louis Dionnef4c12582021-08-23 19:32:365105#endif
Howard Hinnant3e519522010-05-11 19:42:165106
5107template <>
5108const string*
5109__time_get_c_storage<char>::__am_pm() const
5110{
5111 static const string* am_pm = init_am_pm();
5112 return am_pm;
5113}
5114
Louis Dionnef4c12582021-08-23 19:32:365115#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165116template <>
5117const wstring*
5118__time_get_c_storage<wchar_t>::__am_pm() const
5119{
5120 static const wstring* am_pm = init_wam_pm();
5121 return am_pm;
5122}
Louis Dionnef4c12582021-08-23 19:32:365123#endif
Howard Hinnant3e519522010-05-11 19:42:165124
5125template <>
5126const string&
5127__time_get_c_storage<char>::__x() const
5128{
5129 static string s("%m/%d/%y");
5130 return s;
5131}
5132
Louis Dionnef4c12582021-08-23 19:32:365133#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165134template <>
5135const wstring&
5136__time_get_c_storage<wchar_t>::__x() const
5137{
5138 static wstring s(L"%m/%d/%y");
5139 return s;
5140}
Louis Dionnef4c12582021-08-23 19:32:365141#endif
Howard Hinnant3e519522010-05-11 19:42:165142
5143template <>
5144const string&
5145__time_get_c_storage<char>::__X() const
5146{
5147 static string s("%H:%M:%S");
5148 return s;
5149}
5150
Louis Dionnef4c12582021-08-23 19:32:365151#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165152template <>
5153const wstring&
5154__time_get_c_storage<wchar_t>::__X() const
5155{
5156 static wstring s(L"%H:%M:%S");
5157 return s;
5158}
Louis Dionnef4c12582021-08-23 19:32:365159#endif
Howard Hinnant3e519522010-05-11 19:42:165160
5161template <>
5162const string&
5163__time_get_c_storage<char>::__c() const
5164{
5165 static string s("%a %b %d %H:%M:%S %Y");
5166 return s;
5167}
5168
Louis Dionnef4c12582021-08-23 19:32:365169#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165170template <>
5171const wstring&
5172__time_get_c_storage<wchar_t>::__c() const
5173{
5174 static wstring s(L"%a %b %d %H:%M:%S %Y");
5175 return s;
5176}
Louis Dionnef4c12582021-08-23 19:32:365177#endif
Howard Hinnant3e519522010-05-11 19:42:165178
5179template <>
5180const string&
5181__time_get_c_storage<char>::__r() const
5182{
5183 static string s("%I:%M:%S %p");
5184 return s;
5185}
5186
Louis Dionnef4c12582021-08-23 19:32:365187#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165188template <>
5189const wstring&
5190__time_get_c_storage<wchar_t>::__r() const
5191{
5192 static wstring s(L"%I:%M:%S %p");
5193 return s;
5194}
Louis Dionnef4c12582021-08-23 19:32:365195#endif
Howard Hinnant3e519522010-05-11 19:42:165196
5197// time_get_byname
5198
5199__time_get::__time_get(const char* nm)
5200 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5201{
5202 if (__loc_ == 0)
Marshall Clowd437fa52016-08-25 15:09:015203 __throw_runtime_error("time_get_byname"
Howard Hinnant3e519522010-05-11 19:42:165204 " failed to construct for " + string(nm));
5205}
5206
5207__time_get::__time_get(const string& nm)
5208 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5209{
5210 if (__loc_ == 0)
Marshall Clowd437fa52016-08-25 15:09:015211 __throw_runtime_error("time_get_byname"
Howard Hinnant3e519522010-05-11 19:42:165212 " failed to construct for " + nm);
5213}
5214
5215__time_get::~__time_get()
5216{
5217 freelocale(__loc_);
5218}
Nikolas Klausera7c2a622022-02-14 17:52:285219
5220_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
Howard Hinnantf87873b2012-02-20 16:51:435221
Howard Hinnant3e519522010-05-11 19:42:165222template <>
5223string
5224__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
5225{
Howard Hinnant7c24d8e2012-02-19 14:55:325226 tm t = {0};
Howard Hinnant3e519522010-05-11 19:42:165227 t.tm_sec = 59;
5228 t.tm_min = 55;
5229 t.tm_hour = 23;
5230 t.tm_mday = 31;
5231 t.tm_mon = 11;
5232 t.tm_year = 161;
5233 t.tm_wday = 6;
5234 t.tm_yday = 364;
5235 t.tm_isdst = -1;
5236 char buf[100];
5237 char f[3] = {0};
5238 f[0] = '%';
5239 f[1] = fmt;
Howard Hinnant80a11412012-12-27 21:17:535240 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165241 char* bb = buf;
5242 char* be = buf + n;
5243 string result;
5244 while (bb != be)
5245 {
5246 if (ct.is(ctype_base::space, *bb))
5247 {
5248 result.push_back(' ');
5249 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
5250 ;
5251 continue;
5252 }
5253 char* w = bb;
5254 ios_base::iostate err = ios_base::goodbit;
Howard Hinnantc2063662011-12-01 20:21:045255 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
Howard Hinnant3e519522010-05-11 19:42:165256 ct, err, false)
5257 - this->__weeks_;
5258 if (i < 14)
5259 {
5260 result.push_back('%');
5261 if (i < 7)
5262 result.push_back('A');
5263 else
5264 result.push_back('a');
5265 bb = w;
5266 continue;
5267 }
5268 w = bb;
5269 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
5270 ct, err, false)
5271 - this->__months_;
5272 if (i < 24)
5273 {
5274 result.push_back('%');
5275 if (i < 12)
5276 result.push_back('B');
5277 else
5278 result.push_back('b');
5279 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5280 result.back() = 'm';
5281 bb = w;
5282 continue;
5283 }
5284 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5285 {
5286 w = bb;
5287 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
5288 ct, err, false) - this->__am_pm_;
5289 if (i < 2)
5290 {
5291 result.push_back('%');
5292 result.push_back('p');
5293 bb = w;
5294 continue;
5295 }
5296 }
5297 w = bb;
5298 if (ct.is(ctype_base::digit, *bb))
5299 {
5300 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
5301 {
5302 case 6:
5303 result.push_back('%');
5304 result.push_back('w');
5305 break;
5306 case 7:
5307 result.push_back('%');
5308 result.push_back('u');
5309 break;
5310 case 11:
5311 result.push_back('%');
5312 result.push_back('I');
5313 break;
5314 case 12:
5315 result.push_back('%');
5316 result.push_back('m');
5317 break;
5318 case 23:
5319 result.push_back('%');
5320 result.push_back('H');
5321 break;
5322 case 31:
5323 result.push_back('%');
5324 result.push_back('d');
5325 break;
5326 case 55:
5327 result.push_back('%');
5328 result.push_back('M');
5329 break;
5330 case 59:
5331 result.push_back('%');
5332 result.push_back('S');
5333 break;
5334 case 61:
5335 result.push_back('%');
5336 result.push_back('y');
5337 break;
5338 case 364:
5339 result.push_back('%');
5340 result.push_back('j');
5341 break;
5342 case 2061:
5343 result.push_back('%');
5344 result.push_back('Y');
5345 break;
5346 default:
5347 for (; w != bb; ++w)
5348 result.push_back(*w);
5349 break;
5350 }
5351 continue;
5352 }
5353 if (*bb == '%')
5354 {
5355 result.push_back('%');
5356 result.push_back('%');
5357 ++bb;
5358 continue;
5359 }
5360 result.push_back(*bb);
5361 ++bb;
5362 }
5363 return result;
5364}
5365
Nikolas Klausera7c2a622022-02-14 17:52:285366_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
Howard Hinnantc2063662011-12-01 20:21:045367
Louis Dionnef4c12582021-08-23 19:32:365368#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165369template <>
5370wstring
5371__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
5372{
Howard Hinnant7c24d8e2012-02-19 14:55:325373 tm t = {0};
Howard Hinnant3e519522010-05-11 19:42:165374 t.tm_sec = 59;
5375 t.tm_min = 55;
5376 t.tm_hour = 23;
5377 t.tm_mday = 31;
5378 t.tm_mon = 11;
5379 t.tm_year = 161;
5380 t.tm_wday = 6;
5381 t.tm_yday = 364;
5382 t.tm_isdst = -1;
5383 char buf[100];
5384 char f[3] = {0};
5385 f[0] = '%';
5386 f[1] = fmt;
Howard Hinnant80a11412012-12-27 21:17:535387 strftime_l(buf, countof(buf), f, &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165388 wchar_t wbuf[100];
5389 wchar_t* wbb = wbuf;
5390 mbstate_t mb = {0};
5391 const char* bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395392 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
Howard Hinnantc2063662011-12-01 20:21:045393 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:165394 __throw_runtime_error("locale not supported");
Howard Hinnantc2063662011-12-01 20:21:045395 wchar_t* wbe = wbb + j;
Howard Hinnant3e519522010-05-11 19:42:165396 wstring result;
5397 while (wbb != wbe)
5398 {
5399 if (ct.is(ctype_base::space, *wbb))
5400 {
5401 result.push_back(L' ');
5402 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
5403 ;
5404 continue;
5405 }
5406 wchar_t* w = wbb;
5407 ios_base::iostate err = ios_base::goodbit;
Howard Hinnantc2063662011-12-01 20:21:045408 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
Howard Hinnant3e519522010-05-11 19:42:165409 ct, err, false)
5410 - this->__weeks_;
5411 if (i < 14)
5412 {
5413 result.push_back(L'%');
5414 if (i < 7)
5415 result.push_back(L'A');
5416 else
5417 result.push_back(L'a');
5418 wbb = w;
5419 continue;
5420 }
5421 w = wbb;
5422 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
5423 ct, err, false)
5424 - this->__months_;
5425 if (i < 24)
5426 {
5427 result.push_back(L'%');
5428 if (i < 12)
5429 result.push_back(L'B');
5430 else
5431 result.push_back(L'b');
5432 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5433 result.back() = L'm';
5434 wbb = w;
5435 continue;
5436 }
5437 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5438 {
5439 w = wbb;
5440 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5441 ct, err, false) - this->__am_pm_;
5442 if (i < 2)
5443 {
5444 result.push_back(L'%');
5445 result.push_back(L'p');
5446 wbb = w;
5447 continue;
5448 }
5449 }
5450 w = wbb;
5451 if (ct.is(ctype_base::digit, *wbb))
5452 {
5453 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5454 {
5455 case 6:
5456 result.push_back(L'%');
5457 result.push_back(L'w');
5458 break;
5459 case 7:
5460 result.push_back(L'%');
5461 result.push_back(L'u');
5462 break;
5463 case 11:
5464 result.push_back(L'%');
5465 result.push_back(L'I');
5466 break;
5467 case 12:
5468 result.push_back(L'%');
5469 result.push_back(L'm');
5470 break;
5471 case 23:
5472 result.push_back(L'%');
5473 result.push_back(L'H');
5474 break;
5475 case 31:
5476 result.push_back(L'%');
5477 result.push_back(L'd');
5478 break;
5479 case 55:
5480 result.push_back(L'%');
5481 result.push_back(L'M');
5482 break;
5483 case 59:
5484 result.push_back(L'%');
5485 result.push_back(L'S');
5486 break;
5487 case 61:
5488 result.push_back(L'%');
5489 result.push_back(L'y');
5490 break;
5491 case 364:
5492 result.push_back(L'%');
5493 result.push_back(L'j');
5494 break;
5495 case 2061:
5496 result.push_back(L'%');
5497 result.push_back(L'Y');
5498 break;
5499 default:
5500 for (; w != wbb; ++w)
5501 result.push_back(*w);
5502 break;
5503 }
5504 continue;
5505 }
5506 if (ct.narrow(*wbb, 0) == '%')
5507 {
5508 result.push_back(L'%');
5509 result.push_back(L'%');
5510 ++wbb;
5511 continue;
5512 }
5513 result.push_back(*wbb);
5514 ++wbb;
5515 }
5516 return result;
5517}
Louis Dionnef4c12582021-08-23 19:32:365518#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165519
5520template <>
5521void
5522__time_get_storage<char>::init(const ctype<char>& ct)
5523{
Howard Hinnant0cbea7f2012-08-02 18:44:175524 tm t = {0};
Howard Hinnant3e519522010-05-11 19:42:165525 char buf[100];
5526 // __weeks_
5527 for (int i = 0; i < 7; ++i)
5528 {
5529 t.tm_wday = i;
Howard Hinnant80a11412012-12-27 21:17:535530 strftime_l(buf, countof(buf), "%A", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165531 __weeks_[i] = buf;
Howard Hinnant80a11412012-12-27 21:17:535532 strftime_l(buf, countof(buf), "%a", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165533 __weeks_[i+7] = buf;
5534 }
5535 // __months_
5536 for (int i = 0; i < 12; ++i)
5537 {
5538 t.tm_mon = i;
Howard Hinnant80a11412012-12-27 21:17:535539 strftime_l(buf, countof(buf), "%B", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165540 __months_[i] = buf;
Howard Hinnant80a11412012-12-27 21:17:535541 strftime_l(buf, countof(buf), "%b", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165542 __months_[i+12] = buf;
5543 }
5544 // __am_pm_
5545 t.tm_hour = 1;
Howard Hinnant80a11412012-12-27 21:17:535546 strftime_l(buf, countof(buf), "%p", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165547 __am_pm_[0] = buf;
5548 t.tm_hour = 13;
Howard Hinnant80a11412012-12-27 21:17:535549 strftime_l(buf, countof(buf), "%p", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165550 __am_pm_[1] = buf;
5551 __c_ = __analyze('c', ct);
5552 __r_ = __analyze('r', ct);
5553 __x_ = __analyze('x', ct);
5554 __X_ = __analyze('X', ct);
5555}
5556
Louis Dionnef4c12582021-08-23 19:32:365557#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165558template <>
5559void
5560__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5561{
5562 tm t = {0};
5563 char buf[100];
Howard Hinnant3e519522010-05-11 19:42:165564 wchar_t wbuf[100];
5565 wchar_t* wbe;
5566 mbstate_t mb = {0};
5567 // __weeks_
5568 for (int i = 0; i < 7; ++i)
5569 {
5570 t.tm_wday = i;
Howard Hinnant80a11412012-12-27 21:17:535571 strftime_l(buf, countof(buf), "%A", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165572 mb = mbstate_t();
5573 const char* bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395574 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
Martin Storsjö1127ef72019-10-28 21:46:345575 if (j == size_t(-1) || j == 0)
Howard Hinnant3e519522010-05-11 19:42:165576 __throw_runtime_error("locale not supported");
5577 wbe = wbuf + j;
5578 __weeks_[i].assign(wbuf, wbe);
Howard Hinnant80a11412012-12-27 21:17:535579 strftime_l(buf, countof(buf), "%a", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165580 mb = mbstate_t();
5581 bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395582 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
Martin Storsjö1127ef72019-10-28 21:46:345583 if (j == size_t(-1) || j == 0)
Howard Hinnant3e519522010-05-11 19:42:165584 __throw_runtime_error("locale not supported");
5585 wbe = wbuf + j;
5586 __weeks_[i+7].assign(wbuf, wbe);
5587 }
5588 // __months_
5589 for (int i = 0; i < 12; ++i)
5590 {
5591 t.tm_mon = i;
Howard Hinnant80a11412012-12-27 21:17:535592 strftime_l(buf, countof(buf), "%B", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165593 mb = mbstate_t();
5594 const char* bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395595 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
Martin Storsjö1127ef72019-10-28 21:46:345596 if (j == size_t(-1) || j == 0)
Howard Hinnant3e519522010-05-11 19:42:165597 __throw_runtime_error("locale not supported");
5598 wbe = wbuf + j;
5599 __months_[i].assign(wbuf, wbe);
Howard Hinnant80a11412012-12-27 21:17:535600 strftime_l(buf, countof(buf), "%b", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165601 mb = mbstate_t();
5602 bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395603 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
Martin Storsjö1127ef72019-10-28 21:46:345604 if (j == size_t(-1) || j == 0)
Howard Hinnant3e519522010-05-11 19:42:165605 __throw_runtime_error("locale not supported");
5606 wbe = wbuf + j;
5607 __months_[i+12].assign(wbuf, wbe);
5608 }
5609 // __am_pm_
5610 t.tm_hour = 1;
Howard Hinnant80a11412012-12-27 21:17:535611 strftime_l(buf, countof(buf), "%p", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165612 mb = mbstate_t();
5613 const char* bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395614 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
Howard Hinnantc2063662011-12-01 20:21:045615 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:165616 __throw_runtime_error("locale not supported");
5617 wbe = wbuf + j;
5618 __am_pm_[0].assign(wbuf, wbe);
5619 t.tm_hour = 13;
Howard Hinnant80a11412012-12-27 21:17:535620 strftime_l(buf, countof(buf), "%p", &t, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165621 mb = mbstate_t();
5622 bb = buf;
Ben Craigd2f15ba2016-03-09 15:39:395623 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
Howard Hinnantc2063662011-12-01 20:21:045624 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:165625 __throw_runtime_error("locale not supported");
5626 wbe = wbuf + j;
5627 __am_pm_[1].assign(wbuf, wbe);
5628 __c_ = __analyze('c', ct);
5629 __r_ = __analyze('r', ct);
5630 __x_ = __analyze('x', ct);
5631 __X_ = __analyze('X', ct);
5632}
Louis Dionnef4c12582021-08-23 19:32:365633#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165634
5635template <class CharT>
5636struct _LIBCPP_HIDDEN __time_get_temp
5637 : public ctype_byname<CharT>
5638{
5639 explicit __time_get_temp(const char* nm)
5640 : ctype_byname<CharT>(nm, 1) {}
5641 explicit __time_get_temp(const string& nm)
5642 : ctype_byname<CharT>(nm, 1) {}
5643};
5644
5645template <>
5646__time_get_storage<char>::__time_get_storage(const char* __nm)
5647 : __time_get(__nm)
5648{
5649 const __time_get_temp<char> ct(__nm);
5650 init(ct);
5651}
5652
5653template <>
5654__time_get_storage<char>::__time_get_storage(const string& __nm)
5655 : __time_get(__nm)
5656{
5657 const __time_get_temp<char> ct(__nm);
5658 init(ct);
5659}
5660
Louis Dionnef4c12582021-08-23 19:32:365661#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165662template <>
5663__time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5664 : __time_get(__nm)
5665{
5666 const __time_get_temp<wchar_t> ct(__nm);
5667 init(ct);
5668}
5669
5670template <>
5671__time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5672 : __time_get(__nm)
5673{
5674 const __time_get_temp<wchar_t> ct(__nm);
5675 init(ct);
5676}
Louis Dionnef4c12582021-08-23 19:32:365677#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165678
5679template <>
5680time_base::dateorder
5681__time_get_storage<char>::__do_date_order() const
5682{
5683 unsigned i;
5684 for (i = 0; i < __x_.size(); ++i)
5685 if (__x_[i] == '%')
5686 break;
5687 ++i;
5688 switch (__x_[i])
5689 {
5690 case 'y':
5691 case 'Y':
5692 for (++i; i < __x_.size(); ++i)
5693 if (__x_[i] == '%')
5694 break;
5695 if (i == __x_.size())
5696 break;
5697 ++i;
5698 switch (__x_[i])
5699 {
5700 case 'm':
5701 for (++i; i < __x_.size(); ++i)
5702 if (__x_[i] == '%')
5703 break;
5704 if (i == __x_.size())
5705 break;
5706 ++i;
5707 if (__x_[i] == 'd')
5708 return time_base::ymd;
5709 break;
5710 case 'd':
5711 for (++i; i < __x_.size(); ++i)
5712 if (__x_[i] == '%')
5713 break;
5714 if (i == __x_.size())
5715 break;
5716 ++i;
5717 if (__x_[i] == 'm')
5718 return time_base::ydm;
5719 break;
5720 }
5721 break;
5722 case 'm':
5723 for (++i; i < __x_.size(); ++i)
5724 if (__x_[i] == '%')
5725 break;
5726 if (i == __x_.size())
5727 break;
5728 ++i;
5729 if (__x_[i] == 'd')
5730 {
5731 for (++i; i < __x_.size(); ++i)
5732 if (__x_[i] == '%')
5733 break;
5734 if (i == __x_.size())
5735 break;
5736 ++i;
5737 if (__x_[i] == 'y' || __x_[i] == 'Y')
5738 return time_base::mdy;
5739 break;
5740 }
5741 break;
5742 case 'd':
5743 for (++i; i < __x_.size(); ++i)
5744 if (__x_[i] == '%')
5745 break;
5746 if (i == __x_.size())
5747 break;
5748 ++i;
5749 if (__x_[i] == 'm')
5750 {
5751 for (++i; i < __x_.size(); ++i)
5752 if (__x_[i] == '%')
5753 break;
5754 if (i == __x_.size())
5755 break;
5756 ++i;
5757 if (__x_[i] == 'y' || __x_[i] == 'Y')
5758 return time_base::dmy;
5759 break;
5760 }
5761 break;
5762 }
5763 return time_base::no_order;
5764}
5765
Louis Dionnef4c12582021-08-23 19:32:365766#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165767template <>
5768time_base::dateorder
5769__time_get_storage<wchar_t>::__do_date_order() const
5770{
5771 unsigned i;
5772 for (i = 0; i < __x_.size(); ++i)
5773 if (__x_[i] == L'%')
5774 break;
5775 ++i;
5776 switch (__x_[i])
5777 {
5778 case L'y':
5779 case L'Y':
5780 for (++i; i < __x_.size(); ++i)
5781 if (__x_[i] == L'%')
5782 break;
5783 if (i == __x_.size())
5784 break;
5785 ++i;
5786 switch (__x_[i])
5787 {
5788 case L'm':
5789 for (++i; i < __x_.size(); ++i)
5790 if (__x_[i] == L'%')
5791 break;
5792 if (i == __x_.size())
5793 break;
5794 ++i;
5795 if (__x_[i] == L'd')
5796 return time_base::ymd;
5797 break;
5798 case L'd':
5799 for (++i; i < __x_.size(); ++i)
5800 if (__x_[i] == L'%')
5801 break;
5802 if (i == __x_.size())
5803 break;
5804 ++i;
5805 if (__x_[i] == L'm')
5806 return time_base::ydm;
5807 break;
5808 }
5809 break;
5810 case L'm':
5811 for (++i; i < __x_.size(); ++i)
5812 if (__x_[i] == L'%')
5813 break;
5814 if (i == __x_.size())
5815 break;
5816 ++i;
5817 if (__x_[i] == L'd')
5818 {
5819 for (++i; i < __x_.size(); ++i)
5820 if (__x_[i] == L'%')
5821 break;
5822 if (i == __x_.size())
5823 break;
5824 ++i;
5825 if (__x_[i] == L'y' || __x_[i] == L'Y')
5826 return time_base::mdy;
5827 break;
5828 }
5829 break;
5830 case L'd':
5831 for (++i; i < __x_.size(); ++i)
5832 if (__x_[i] == L'%')
5833 break;
5834 if (i == __x_.size())
5835 break;
5836 ++i;
5837 if (__x_[i] == L'm')
5838 {
5839 for (++i; i < __x_.size(); ++i)
5840 if (__x_[i] == L'%')
5841 break;
5842 if (i == __x_.size())
5843 break;
5844 ++i;
5845 if (__x_[i] == L'y' || __x_[i] == L'Y')
5846 return time_base::dmy;
5847 break;
5848 }
5849 break;
5850 }
5851 return time_base::no_order;
5852}
Louis Dionnef4c12582021-08-23 19:32:365853#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165854
5855// time_put
5856
5857__time_put::__time_put(const char* nm)
5858 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5859{
5860 if (__loc_ == 0)
Marshall Clowd437fa52016-08-25 15:09:015861 __throw_runtime_error("time_put_byname"
Howard Hinnant3e519522010-05-11 19:42:165862 " failed to construct for " + string(nm));
5863}
5864
5865__time_put::__time_put(const string& nm)
5866 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5867{
5868 if (__loc_ == 0)
Marshall Clowd437fa52016-08-25 15:09:015869 __throw_runtime_error("time_put_byname"
Howard Hinnant3e519522010-05-11 19:42:165870 " failed to construct for " + nm);
5871}
5872
5873__time_put::~__time_put()
5874{
Joerg Sonnenberger392a1782013-07-02 19:46:185875 if (__loc_ != _LIBCPP_GET_C_LOCALE)
Howard Hinnant3e519522010-05-11 19:42:165876 freelocale(__loc_);
5877}
5878
5879void
5880__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5881 char __fmt, char __mod) const
5882{
5883 char fmt[] = {'%', __fmt, __mod, 0};
5884 if (__mod != 0)
5885 swap(fmt[1], fmt[2]);
Howard Hinnant80a11412012-12-27 21:17:535886 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
Howard Hinnant3e519522010-05-11 19:42:165887 __ne = __nb + n;
5888}
5889
Louis Dionnef4c12582021-08-23 19:32:365890#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165891void
5892__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5893 char __fmt, char __mod) const
5894{
5895 char __nar[100];
5896 char* __ne = __nar + 100;
5897 __do_put(__nar, __ne, __tm, __fmt, __mod);
5898 mbstate_t mb = {0};
5899 const char* __nb = __nar;
Ben Craigd2f15ba2016-03-09 15:39:395900 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
Howard Hinnantc2063662011-12-01 20:21:045901 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:165902 __throw_runtime_error("locale not supported");
5903 __we = __wb + j;
5904}
Louis Dionnef4c12582021-08-23 19:32:365905#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:165906
5907// moneypunct_byname
5908
Jeffrey Yasskin9c95b192012-03-10 18:31:435909template <class charT>
Howard Hinnant3e519522010-05-11 19:42:165910static
5911void
Jeffrey Yasskin9c95b192012-03-10 18:31:435912__init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5913 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5914 charT space_char)
Howard Hinnant3e519522010-05-11 19:42:165915{
5916 const char sign = static_cast<char>(money_base::sign);
5917 const char space = static_cast<char>(money_base::space);
5918 const char none = static_cast<char>(money_base::none);
5919 const char symbol = static_cast<char>(money_base::symbol);
5920 const char value = static_cast<char>(money_base::value);
Jeffrey Yasskin9c95b192012-03-10 18:31:435921 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5922
5923 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5924 // function'. "Space between sign and symbol or value" means that
5925 // if the sign is adjacent to the symbol, there's a space between
5926 // them, and otherwise there's a space between the sign and value.
5927 //
5928 // C11's localeconv specifies that the fourth character of an
5929 // international curr_symbol is used to separate the sign and
5930 // value when sep_by_space says to do so. C++ can't represent
5931 // that, so we just use a space. When sep_by_space says to
5932 // separate the symbol and value-or-sign with a space, we rearrange the
5933 // curr_symbol to put its spacing character on the correct side of
5934 // the symbol.
5935 //
5936 // We also need to avoid adding an extra space between the sign
5937 // and value when the currency symbol is suppressed (by not
5938 // setting showbase). We match glibc's strfmon by interpreting
5939 // sep_by_space==1 as "omit the space when the currency symbol is
5940 // absent".
5941 //
5942 // Users who want to get this right should use ICU instead.
5943
Howard Hinnant3e519522010-05-11 19:42:165944 switch (cs_precedes)
5945 {
Jeffrey Yasskin9c95b192012-03-10 18:31:435946 case 0: // value before curr_symbol
5947 if (symbol_contains_sep) {
5948 // Move the separator to before the symbol, to place it
5949 // between the value and symbol.
5950 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5951 __curr_symbol_.end());
5952 }
Howard Hinnant3e519522010-05-11 19:42:165953 switch (sign_posn)
5954 {
Jeffrey Yasskin9c95b192012-03-10 18:31:435955 case 0: // Parentheses surround the quantity and currency symbol.
Howard Hinnant3e519522010-05-11 19:42:165956 pat.field[0] = sign;
5957 pat.field[1] = value;
Jeffrey Yasskin9c95b192012-03-10 18:31:435958 pat.field[2] = none; // Any space appears in the symbol.
Howard Hinnant3e519522010-05-11 19:42:165959 pat.field[3] = symbol;
5960 switch (sep_by_space)
5961 {
Jeffrey Yasskin9c95b192012-03-10 18:31:435962 case 0: // No space separates the currency symbol and value.
5963 // This case may have changed between C99 and C11;
5964 // assume the currency symbol matches the intention.
5965 case 2: // Space between sign and currency or value.
5966 // The "sign" is two parentheses, so no space here either.
Howard Hinnant3e519522010-05-11 19:42:165967 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:435968 case 1: // Space between currency-and-sign or currency and value.
5969 if (!symbol_contains_sep) {
5970 // We insert the space into the symbol instead of
5971 // setting pat.field[2]=space so that when
5972 // showbase is not set, the space goes away too.
5973 __curr_symbol_.insert(0, 1, space_char);
5974 }
Howard Hinnant3e519522010-05-11 19:42:165975 return;
5976 default:
5977 break;
5978 }
5979 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:435980 case 1: // The sign string precedes the quantity and currency symbol.
Howard Hinnant3e519522010-05-11 19:42:165981 pat.field[0] = sign;
5982 pat.field[3] = symbol;
5983 switch (sep_by_space)
5984 {
Jeffrey Yasskin9c95b192012-03-10 18:31:435985 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:165986 pat.field[1] = value;
5987 pat.field[2] = none;
5988 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:435989 case 1: // Space between currency-and-sign or currency and value.
Howard Hinnant3e519522010-05-11 19:42:165990 pat.field[1] = value;
Jeffrey Yasskin9c95b192012-03-10 18:31:435991 pat.field[2] = none;
5992 if (!symbol_contains_sep) {
5993 // We insert the space into the symbol instead of
5994 // setting pat.field[2]=space so that when
5995 // showbase is not set, the space goes away too.
5996 __curr_symbol_.insert(0, 1, space_char);
5997 }
Howard Hinnant3e519522010-05-11 19:42:165998 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:435999 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166000 pat.field[1] = space;
6001 pat.field[2] = value;
Jeffrey Yasskin9c95b192012-03-10 18:31:436002 if (symbol_contains_sep) {
6003 // Remove the separator from the symbol, since it
6004 // has already appeared after the sign.
6005 __curr_symbol_.erase(__curr_symbol_.begin());
6006 }
Howard Hinnant3e519522010-05-11 19:42:166007 return;
6008 default:
6009 break;
6010 }
6011 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436012 case 2: // The sign string succeeds the quantity and currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166013 pat.field[0] = value;
6014 pat.field[3] = sign;
6015 switch (sep_by_space)
6016 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436017 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166018 pat.field[1] = none;
6019 pat.field[2] = symbol;
6020 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436021 case 1: // Space between currency-and-sign or currency and value.
6022 if (!symbol_contains_sep) {
6023 // We insert the space into the symbol instead of
6024 // setting pat.field[1]=space so that when
6025 // showbase is not set, the space goes away too.
6026 __curr_symbol_.insert(0, 1, space_char);
6027 }
6028 pat.field[1] = none;
Howard Hinnant3e519522010-05-11 19:42:166029 pat.field[2] = symbol;
6030 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436031 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166032 pat.field[1] = symbol;
6033 pat.field[2] = space;
Jeffrey Yasskin9c95b192012-03-10 18:31:436034 if (symbol_contains_sep) {
6035 // Remove the separator from the symbol, since it
6036 // should not be removed if showbase is absent.
6037 __curr_symbol_.erase(__curr_symbol_.begin());
6038 }
Howard Hinnant3e519522010-05-11 19:42:166039 return;
6040 default:
6041 break;
6042 }
6043 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436044 case 3: // The sign string immediately precedes the currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166045 pat.field[0] = value;
6046 pat.field[3] = symbol;
6047 switch (sep_by_space)
6048 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436049 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166050 pat.field[1] = none;
6051 pat.field[2] = sign;
6052 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436053 case 1: // Space between currency-and-sign or currency and value.
Howard Hinnant3e519522010-05-11 19:42:166054 pat.field[1] = space;
6055 pat.field[2] = sign;
Jeffrey Yasskin9c95b192012-03-10 18:31:436056 if (symbol_contains_sep) {
6057 // Remove the separator from the symbol, since it
6058 // has already appeared before the sign.
6059 __curr_symbol_.erase(__curr_symbol_.begin());
6060 }
Howard Hinnant3e519522010-05-11 19:42:166061 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436062 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166063 pat.field[1] = sign;
Jeffrey Yasskin9c95b192012-03-10 18:31:436064 pat.field[2] = none;
6065 if (!symbol_contains_sep) {
6066 // We insert the space into the symbol instead of
6067 // setting pat.field[2]=space so that when
6068 // showbase is not set, the space goes away too.
6069 __curr_symbol_.insert(0, 1, space_char);
6070 }
Howard Hinnant3e519522010-05-11 19:42:166071 return;
6072 default:
6073 break;
6074 }
6075 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436076 case 4: // The sign string immediately succeeds the currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166077 pat.field[0] = value;
6078 pat.field[3] = sign;
6079 switch (sep_by_space)
6080 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436081 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166082 pat.field[1] = none;
6083 pat.field[2] = symbol;
6084 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436085 case 1: // Space between currency-and-sign or currency and value.
6086 pat.field[1] = none;
Howard Hinnant3e519522010-05-11 19:42:166087 pat.field[2] = symbol;
Jeffrey Yasskin9c95b192012-03-10 18:31:436088 if (!symbol_contains_sep) {
6089 // We insert the space into the symbol instead of
6090 // setting pat.field[1]=space so that when
6091 // showbase is not set, the space goes away too.
6092 __curr_symbol_.insert(0, 1, space_char);
6093 }
Howard Hinnant3e519522010-05-11 19:42:166094 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436095 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166096 pat.field[1] = symbol;
6097 pat.field[2] = space;
Jeffrey Yasskin9c95b192012-03-10 18:31:436098 if (symbol_contains_sep) {
6099 // Remove the separator from the symbol, since it
6100 // should not disappear when showbase is absent.
6101 __curr_symbol_.erase(__curr_symbol_.begin());
6102 }
Howard Hinnant3e519522010-05-11 19:42:166103 return;
6104 default:
6105 break;
6106 }
6107 break;
6108 default:
6109 break;
6110 }
6111 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436112 case 1: // curr_symbol before value
Howard Hinnant3e519522010-05-11 19:42:166113 switch (sign_posn)
6114 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436115 case 0: // Parentheses surround the quantity and currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166116 pat.field[0] = sign;
6117 pat.field[1] = symbol;
Jeffrey Yasskin9c95b192012-03-10 18:31:436118 pat.field[2] = none; // Any space appears in the symbol.
Howard Hinnant3e519522010-05-11 19:42:166119 pat.field[3] = value;
6120 switch (sep_by_space)
6121 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436122 case 0: // No space separates the currency symbol and value.
6123 // This case may have changed between C99 and C11;
6124 // assume the currency symbol matches the intention.
6125 case 2: // Space between sign and currency or value.
6126 // The "sign" is two parentheses, so no space here either.
Howard Hinnant3e519522010-05-11 19:42:166127 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436128 case 1: // Space between currency-and-sign or currency and value.
6129 if (!symbol_contains_sep) {
6130 // We insert the space into the symbol instead of
6131 // setting pat.field[2]=space so that when
6132 // showbase is not set, the space goes away too.
6133 __curr_symbol_.insert(0, 1, space_char);
6134 }
Howard Hinnant3e519522010-05-11 19:42:166135 return;
6136 default:
6137 break;
6138 }
6139 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436140 case 1: // The sign string precedes the quantity and currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166141 pat.field[0] = sign;
6142 pat.field[3] = value;
6143 switch (sep_by_space)
6144 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436145 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166146 pat.field[1] = symbol;
6147 pat.field[2] = none;
6148 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436149 case 1: // Space between currency-and-sign or currency and value.
Howard Hinnant3e519522010-05-11 19:42:166150 pat.field[1] = symbol;
Jeffrey Yasskin9c95b192012-03-10 18:31:436151 pat.field[2] = none;
6152 if (!symbol_contains_sep) {
6153 // We insert the space into the symbol instead of
6154 // setting pat.field[2]=space so that when
6155 // showbase is not set, the space goes away too.
6156 __curr_symbol_.push_back(space_char);
6157 }
Howard Hinnant3e519522010-05-11 19:42:166158 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436159 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166160 pat.field[1] = space;
6161 pat.field[2] = symbol;
Jeffrey Yasskin9c95b192012-03-10 18:31:436162 if (symbol_contains_sep) {
6163 // Remove the separator from the symbol, since it
6164 // has already appeared after the sign.
6165 __curr_symbol_.pop_back();
6166 }
Howard Hinnant3e519522010-05-11 19:42:166167 return;
6168 default:
6169 break;
6170 }
6171 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436172 case 2: // The sign string succeeds the quantity and currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166173 pat.field[0] = symbol;
6174 pat.field[3] = sign;
6175 switch (sep_by_space)
6176 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436177 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166178 pat.field[1] = none;
6179 pat.field[2] = value;
6180 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436181 case 1: // Space between currency-and-sign or currency and value.
6182 pat.field[1] = none;
Howard Hinnant3e519522010-05-11 19:42:166183 pat.field[2] = value;
Jeffrey Yasskin9c95b192012-03-10 18:31:436184 if (!symbol_contains_sep) {
6185 // We insert the space into the symbol instead of
6186 // setting pat.field[1]=space so that when
6187 // showbase is not set, the space goes away too.
6188 __curr_symbol_.push_back(space_char);
6189 }
Howard Hinnant3e519522010-05-11 19:42:166190 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436191 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166192 pat.field[1] = value;
6193 pat.field[2] = space;
Jeffrey Yasskin9c95b192012-03-10 18:31:436194 if (symbol_contains_sep) {
6195 // Remove the separator from the symbol, since it
6196 // will appear before the sign.
6197 __curr_symbol_.pop_back();
6198 }
Howard Hinnant3e519522010-05-11 19:42:166199 return;
6200 default:
6201 break;
6202 }
6203 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436204 case 3: // The sign string immediately precedes the currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166205 pat.field[0] = sign;
6206 pat.field[3] = value;
6207 switch (sep_by_space)
6208 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436209 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166210 pat.field[1] = symbol;
6211 pat.field[2] = none;
6212 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436213 case 1: // Space between currency-and-sign or currency and value.
Howard Hinnant3e519522010-05-11 19:42:166214 pat.field[1] = symbol;
Jeffrey Yasskin9c95b192012-03-10 18:31:436215 pat.field[2] = none;
6216 if (!symbol_contains_sep) {
6217 // We insert the space into the symbol instead of
6218 // setting pat.field[2]=space so that when
6219 // showbase is not set, the space goes away too.
6220 __curr_symbol_.push_back(space_char);
6221 }
Howard Hinnant3e519522010-05-11 19:42:166222 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436223 case 2: // Space between sign and currency or value.
Howard Hinnant3e519522010-05-11 19:42:166224 pat.field[1] = space;
6225 pat.field[2] = symbol;
Jeffrey Yasskin9c95b192012-03-10 18:31:436226 if (symbol_contains_sep) {
6227 // Remove the separator from the symbol, since it
6228 // has already appeared after the sign.
6229 __curr_symbol_.pop_back();
6230 }
Howard Hinnant3e519522010-05-11 19:42:166231 return;
6232 default:
6233 break;
6234 }
6235 break;
Jeffrey Yasskin9c95b192012-03-10 18:31:436236 case 4: // The sign string immediately succeeds the currency symbol.
Howard Hinnant3e519522010-05-11 19:42:166237 pat.field[0] = symbol;
6238 pat.field[3] = value;
6239 switch (sep_by_space)
6240 {
Jeffrey Yasskin9c95b192012-03-10 18:31:436241 case 0: // No space separates the currency symbol and value.
Howard Hinnant3e519522010-05-11 19:42:166242 pat.field[1] = sign;
6243 pat.field[2] = none;
6244 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436245 case 1: // Space between currency-and-sign or currency and value.
Howard Hinnant3e519522010-05-11 19:42:166246 pat.field[1] = sign;
6247 pat.field[2] = space;
Jeffrey Yasskin9c95b192012-03-10 18:31:436248 if (symbol_contains_sep) {
6249 // Remove the separator from the symbol, since it
6250 // should not disappear when showbase is absent.
6251 __curr_symbol_.pop_back();
6252 }
Howard Hinnant3e519522010-05-11 19:42:166253 return;
Jeffrey Yasskin9c95b192012-03-10 18:31:436254 case 2: // Space between sign and currency or value.
6255 pat.field[1] = none;
Howard Hinnant3e519522010-05-11 19:42:166256 pat.field[2] = sign;
Jeffrey Yasskin9c95b192012-03-10 18:31:436257 if (!symbol_contains_sep) {
6258 // We insert the space into the symbol instead of
6259 // setting pat.field[1]=space so that when
6260 // showbase is not set, the space goes away too.
6261 __curr_symbol_.push_back(space_char);
6262 }
Howard Hinnant3e519522010-05-11 19:42:166263 return;
6264 default:
6265 break;
6266 }
6267 break;
6268 default:
6269 break;
6270 }
6271 break;
6272 default:
6273 break;
6274 }
6275 pat.field[0] = symbol;
6276 pat.field[1] = sign;
6277 pat.field[2] = none;
6278 pat.field[3] = value;
6279}
6280
6281template<>
6282void
6283moneypunct_byname<char, false>::init(const char* nm)
6284{
6285 typedef moneypunct<char, false> base;
Eric Fiselierb4ddab22017-05-08 22:02:436286 __libcpp_unique_locale loc(nm);
6287 if (!loc)
Marshall Clowd437fa52016-08-25 15:09:016288 __throw_runtime_error("moneypunct_byname"
Howard Hinnant3e519522010-05-11 19:42:166289 " failed to construct for " + string(nm));
Marshall Clowd437fa52016-08-25 15:09:016290
Ben Craigd2f15ba2016-03-09 15:39:396291 lconv* lc = __libcpp_localeconv_l(loc.get());
Eric Fiselier0d542d32016-12-11 00:20:596292 if (!checked_string_to_char_convert(__decimal_point_,
6293 lc->mon_decimal_point,
6294 loc.get()))
6295 __decimal_point_ = base::do_decimal_point();
6296 if (!checked_string_to_char_convert(__thousands_sep_,
6297 lc->mon_thousands_sep,
6298 loc.get()))
6299 __thousands_sep_ = base::do_thousands_sep();
6300
Howard Hinnant3e519522010-05-11 19:42:166301 __grouping_ = lc->mon_grouping;
6302 __curr_symbol_ = lc->currency_symbol;
6303 if (lc->frac_digits != CHAR_MAX)
6304 __frac_digits_ = lc->frac_digits;
6305 else
6306 __frac_digits_ = base::do_frac_digits();
6307 if (lc->p_sign_posn == 0)
6308 __positive_sign_ = "()";
6309 else
6310 __positive_sign_ = lc->positive_sign;
6311 if (lc->n_sign_posn == 0)
6312 __negative_sign_ = "()";
6313 else
6314 __negative_sign_ = lc->negative_sign;
Jeffrey Yasskin9c95b192012-03-10 18:31:436315 // Assume the positive and negative formats will want spaces in
6316 // the same places in curr_symbol since there's no way to
6317 // represent anything else.
6318 string_type __dummy_curr_symbol = __curr_symbol_;
6319 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6320 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6321 __init_pat(__neg_format_, __curr_symbol_, false,
6322 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
Howard Hinnant3e519522010-05-11 19:42:166323}
6324
6325template<>
6326void
6327moneypunct_byname<char, true>::init(const char* nm)
6328{
6329 typedef moneypunct<char, true> base;
Eric Fiselierb4ddab22017-05-08 22:02:436330 __libcpp_unique_locale loc(nm);
6331 if (!loc)
Marshall Clowd437fa52016-08-25 15:09:016332 __throw_runtime_error("moneypunct_byname"
Howard Hinnant3e519522010-05-11 19:42:166333 " failed to construct for " + string(nm));
Marshall Clowd437fa52016-08-25 15:09:016334
Ben Craigd2f15ba2016-03-09 15:39:396335 lconv* lc = __libcpp_localeconv_l(loc.get());
Eric Fiselier0d542d32016-12-11 00:20:596336 if (!checked_string_to_char_convert(__decimal_point_,
6337 lc->mon_decimal_point,
6338 loc.get()))
6339 __decimal_point_ = base::do_decimal_point();
6340 if (!checked_string_to_char_convert(__thousands_sep_,
6341 lc->mon_thousands_sep,
6342 loc.get()))
6343 __thousands_sep_ = base::do_thousands_sep();
Howard Hinnant3e519522010-05-11 19:42:166344 __grouping_ = lc->mon_grouping;
6345 __curr_symbol_ = lc->int_curr_symbol;
6346 if (lc->int_frac_digits != CHAR_MAX)
6347 __frac_digits_ = lc->int_frac_digits;
6348 else
6349 __frac_digits_ = base::do_frac_digits();
Howard Hinnant5f878d42013-09-17 01:34:476350#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnantdbe81112011-09-23 16:11:276351 if (lc->p_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346352#else // _LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166353 if (lc->int_p_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346354#endif // !_LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166355 __positive_sign_ = "()";
6356 else
6357 __positive_sign_ = lc->positive_sign;
Howard Hinnant5f878d42013-09-17 01:34:476358#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnantdbe81112011-09-23 16:11:276359 if(lc->n_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346360#else // _LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166361 if (lc->int_n_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346362#endif // !_LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166363 __negative_sign_ = "()";
6364 else
6365 __negative_sign_ = lc->negative_sign;
Jeffrey Yasskin9c95b192012-03-10 18:31:436366 // Assume the positive and negative formats will want spaces in
6367 // the same places in curr_symbol since there's no way to
6368 // represent anything else.
6369 string_type __dummy_curr_symbol = __curr_symbol_;
Howard Hinnant5f878d42013-09-17 01:34:476370#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Jeffrey Yasskin9c95b192012-03-10 18:31:436371 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6372 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6373 __init_pat(__neg_format_, __curr_symbol_, true,
6374 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
Howard Hinnant0be8f642013-08-01 18:17:346375#else // _LIBCPP_MSVCRT
Jeffrey Yasskin9c95b192012-03-10 18:31:436376 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6377 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6378 lc->int_p_sign_posn, ' ');
6379 __init_pat(__neg_format_, __curr_symbol_, true,
6380 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6381 lc->int_n_sign_posn, ' ');
Howard Hinnant0be8f642013-08-01 18:17:346382#endif // !_LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166383}
6384
Louis Dionnef4c12582021-08-23 19:32:366385#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:166386template<>
6387void
6388moneypunct_byname<wchar_t, false>::init(const char* nm)
6389{
6390 typedef moneypunct<wchar_t, false> base;
Eric Fiselierb4ddab22017-05-08 22:02:436391 __libcpp_unique_locale loc(nm);
6392 if (!loc)
Marshall Clowd437fa52016-08-25 15:09:016393 __throw_runtime_error("moneypunct_byname"
Howard Hinnant3e519522010-05-11 19:42:166394 " failed to construct for " + string(nm));
Ben Craigd2f15ba2016-03-09 15:39:396395 lconv* lc = __libcpp_localeconv_l(loc.get());
Eric Fiselier0d542d32016-12-11 00:20:596396 if (!checked_string_to_wchar_convert(__decimal_point_,
6397 lc->mon_decimal_point,
6398 loc.get()))
6399 __decimal_point_ = base::do_decimal_point();
6400 if (!checked_string_to_wchar_convert(__thousands_sep_,
6401 lc->mon_thousands_sep,
6402 loc.get()))
6403 __thousands_sep_ = base::do_thousands_sep();
Howard Hinnant3e519522010-05-11 19:42:166404 __grouping_ = lc->mon_grouping;
6405 wchar_t wbuf[100];
6406 mbstate_t mb = {0};
6407 const char* bb = lc->currency_symbol;
Ben Craigd2f15ba2016-03-09 15:39:396408 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
Howard Hinnantc2063662011-12-01 20:21:046409 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:166410 __throw_runtime_error("locale not supported");
6411 wchar_t* wbe = wbuf + j;
6412 __curr_symbol_.assign(wbuf, wbe);
6413 if (lc->frac_digits != CHAR_MAX)
6414 __frac_digits_ = lc->frac_digits;
6415 else
6416 __frac_digits_ = base::do_frac_digits();
6417 if (lc->p_sign_posn == 0)
6418 __positive_sign_ = L"()";
6419 else
6420 {
6421 mb = mbstate_t();
6422 bb = lc->positive_sign;
Ben Craigd2f15ba2016-03-09 15:39:396423 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
Howard Hinnantc2063662011-12-01 20:21:046424 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:166425 __throw_runtime_error("locale not supported");
6426 wbe = wbuf + j;
6427 __positive_sign_.assign(wbuf, wbe);
6428 }
6429 if (lc->n_sign_posn == 0)
6430 __negative_sign_ = L"()";
6431 else
6432 {
6433 mb = mbstate_t();
6434 bb = lc->negative_sign;
Ben Craigd2f15ba2016-03-09 15:39:396435 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
Howard Hinnantc2063662011-12-01 20:21:046436 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:166437 __throw_runtime_error("locale not supported");
6438 wbe = wbuf + j;
6439 __negative_sign_.assign(wbuf, wbe);
6440 }
Jeffrey Yasskin9c95b192012-03-10 18:31:436441 // Assume the positive and negative formats will want spaces in
6442 // the same places in curr_symbol since there's no way to
6443 // represent anything else.
6444 string_type __dummy_curr_symbol = __curr_symbol_;
6445 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6446 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6447 __init_pat(__neg_format_, __curr_symbol_, false,
6448 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
Howard Hinnant3e519522010-05-11 19:42:166449}
6450
6451template<>
6452void
6453moneypunct_byname<wchar_t, true>::init(const char* nm)
6454{
6455 typedef moneypunct<wchar_t, true> base;
Eric Fiselierb4ddab22017-05-08 22:02:436456 __libcpp_unique_locale loc(nm);
6457 if (!loc)
Marshall Clowd437fa52016-08-25 15:09:016458 __throw_runtime_error("moneypunct_byname"
Howard Hinnant3e519522010-05-11 19:42:166459 " failed to construct for " + string(nm));
Marshall Clowd437fa52016-08-25 15:09:016460
Ben Craigd2f15ba2016-03-09 15:39:396461 lconv* lc = __libcpp_localeconv_l(loc.get());
Eric Fiselier0d542d32016-12-11 00:20:596462 if (!checked_string_to_wchar_convert(__decimal_point_,
6463 lc->mon_decimal_point,
6464 loc.get()))
6465 __decimal_point_ = base::do_decimal_point();
6466 if (!checked_string_to_wchar_convert(__thousands_sep_,
6467 lc->mon_thousands_sep,
6468 loc.get()))
6469 __thousands_sep_ = base::do_thousands_sep();
Howard Hinnant3e519522010-05-11 19:42:166470 __grouping_ = lc->mon_grouping;
6471 wchar_t wbuf[100];
6472 mbstate_t mb = {0};
6473 const char* bb = lc->int_curr_symbol;
Ben Craigd2f15ba2016-03-09 15:39:396474 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
Howard Hinnantc2063662011-12-01 20:21:046475 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:166476 __throw_runtime_error("locale not supported");
6477 wchar_t* wbe = wbuf + j;
6478 __curr_symbol_.assign(wbuf, wbe);
6479 if (lc->int_frac_digits != CHAR_MAX)
6480 __frac_digits_ = lc->int_frac_digits;
6481 else
6482 __frac_digits_ = base::do_frac_digits();
Howard Hinnant5f878d42013-09-17 01:34:476483#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnantdbe81112011-09-23 16:11:276484 if (lc->p_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346485#else // _LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166486 if (lc->int_p_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346487#endif // !_LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166488 __positive_sign_ = L"()";
6489 else
6490 {
6491 mb = mbstate_t();
6492 bb = lc->positive_sign;
Ben Craigd2f15ba2016-03-09 15:39:396493 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
Howard Hinnantc2063662011-12-01 20:21:046494 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:166495 __throw_runtime_error("locale not supported");
6496 wbe = wbuf + j;
6497 __positive_sign_.assign(wbuf, wbe);
6498 }
Howard Hinnant5f878d42013-09-17 01:34:476499#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnantdbe81112011-09-23 16:11:276500 if (lc->n_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346501#else // _LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166502 if (lc->int_n_sign_posn == 0)
Howard Hinnant0be8f642013-08-01 18:17:346503#endif // !_LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166504 __negative_sign_ = L"()";
6505 else
6506 {
6507 mb = mbstate_t();
6508 bb = lc->negative_sign;
Ben Craigd2f15ba2016-03-09 15:39:396509 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
Howard Hinnantc2063662011-12-01 20:21:046510 if (j == size_t(-1))
Howard Hinnant3e519522010-05-11 19:42:166511 __throw_runtime_error("locale not supported");
6512 wbe = wbuf + j;
6513 __negative_sign_.assign(wbuf, wbe);
6514 }
Jeffrey Yasskin9c95b192012-03-10 18:31:436515 // Assume the positive and negative formats will want spaces in
6516 // the same places in curr_symbol since there's no way to
6517 // represent anything else.
6518 string_type __dummy_curr_symbol = __curr_symbol_;
Howard Hinnant5f878d42013-09-17 01:34:476519#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Jeffrey Yasskin9c95b192012-03-10 18:31:436520 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6521 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6522 __init_pat(__neg_format_, __curr_symbol_, true,
6523 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
Howard Hinnant0be8f642013-08-01 18:17:346524#else // _LIBCPP_MSVCRT
Jeffrey Yasskin9c95b192012-03-10 18:31:436525 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6526 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6527 lc->int_p_sign_posn, L' ');
6528 __init_pat(__neg_format_, __curr_symbol_, true,
6529 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6530 lc->int_n_sign_posn, L' ');
Howard Hinnant0be8f642013-08-01 18:17:346531#endif // !_LIBCPP_MSVCRT
Howard Hinnant3e519522010-05-11 19:42:166532}
Louis Dionnef4c12582021-08-23 19:32:366533#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant3e519522010-05-11 19:42:166534
6535void __do_nothing(void*) {}
6536
6537void __throw_runtime_error(const char* msg)
6538{
Howard Hinnant54b409f2010-08-11 17:04:316539#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:166540 throw runtime_error(msg);
Howard Hinnante00e6f22013-03-28 18:56:266541#else
6542 (void)msg;
Marshall Clowd437fa52016-08-25 15:09:016543 _VSTD::abort();
Howard Hinnant54b409f2010-08-11 17:04:316544#endif
Howard Hinnant3e519522010-05-11 19:42:166545}
6546
Louis Dionnef4c12582021-08-23 19:32:366547 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6548_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166549
Louis Dionnef4c12582021-08-23 19:32:366550 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6551_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166552
Louis Dionnef4c12582021-08-23 19:32:366553 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6554_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166555
Louis Dionnef4c12582021-08-23 19:32:366556 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6557_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166558
Louis Dionnef4c12582021-08-23 19:32:366559 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6560_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166561
Louis Dionnef4c12582021-08-23 19:32:366562 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6563_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166564
Louis Dionnef4c12582021-08-23 19:32:366565 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6566_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166567
Louis Dionnef4c12582021-08-23 19:32:366568 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6569_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166570
Louis Dionnef4c12582021-08-23 19:32:366571 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6572_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166573
Louis Dionnef4c12582021-08-23 19:32:366574 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6575 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6576_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)
6577_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)
Howard Hinnant3e519522010-05-11 19:42:166578
Louis Dionnef4c12582021-08-23 19:32:366579 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6580 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6581_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)
6582_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)
Howard Hinnant3e519522010-05-11 19:42:166583
Louis Dionnef4c12582021-08-23 19:32:366584 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6585_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166586
Louis Dionnef4c12582021-08-23 19:32:366587 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6588_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166589
Louis Dionnef4c12582021-08-23 19:32:366590 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6591_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166592
Louis Dionnef4c12582021-08-23 19:32:366593 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6594_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166595
Louis Dionnef4c12582021-08-23 19:32:366596 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6597_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166598
Louis Dionnef4c12582021-08-23 19:32:366599 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6600_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)
Howard Hinnant3e519522010-05-11 19:42:166601
Louis Dionnef4c12582021-08-23 19:32:366602 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6603_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)
Reid Kleckner4f24d0d2021-01-15 16:56:346604template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6605template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
Arthur O'Dwyer5c40c992021-04-19 01:47:086606#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdeja984dca2020-12-02 07:57:026607template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
6608template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
6609#endif
Howard Hinnant3e519522010-05-11 19:42:166610
Howard Hinnant3e519522010-05-11 19:42:166611_LIBCPP_END_NAMESPACE_STD
Arthur O'Dwyerbbb0f2c2022-02-11 18:00:396612
6613_LIBCPP_POP_MACROS