Path: blob/main/contrib/llvm-project/libcxx/src/locale.cpp
35147 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <__utility/no_destroy.h>9#include <algorithm>10#include <clocale>11#include <codecvt>12#include <cstddef>13#include <cstdio>14#include <cstdlib>15#include <cstring>16#include <locale>17#include <new>18#include <string>19#include <type_traits>20#include <typeinfo>21#include <utility>22#include <vector>2324#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS25# include <cwctype>26#endif2728#if defined(_AIX)29# include <sys/localedef.h> // for __lc_ctype_ptr30#endif3132#if defined(_LIBCPP_MSVCRT)33# define _CTYPE_DISABLE_MACROS34#endif3536#if !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__) && !defined(__BIONIC__) && !defined(__NuttX__)37# include <langinfo.h>38#endif3940#include "include/atomic_support.h"41#include "include/sso_allocator.h"4243// On Linux, wint_t and wchar_t have different signed-ness, and this causes44// lots of noise in the build log, but no bugs that I know of.45_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")4647_LIBCPP_PUSH_MACROS48#include <__undef_macros>4950_LIBCPP_BEGIN_NAMESPACE_STD5152struct __libcpp_unique_locale {53__libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}5455~__libcpp_unique_locale() {56if (__loc_)57freelocale(__loc_);58}5960explicit operator bool() const { return __loc_; }6162locale_t& get() { return __loc_; }6364locale_t __loc_;6566private:67__libcpp_unique_locale(__libcpp_unique_locale const&);68__libcpp_unique_locale& operator=(__libcpp_unique_locale const&);69};7071#ifdef __cloc_defined72locale_t __cloc() {73// In theory this could create a race condition. In practice74// the race condition is non-fatal since it will just create75// a little resource leak. Better approach would be appreciated.76static locale_t result = newlocale(LC_ALL_MASK, "C", 0);77return result;78}79#endif // __cloc_defined8081namespace {8283struct releaser {84void operator()(locale::facet* p) { p->__release_shared(); }85};8687template <class T, class... Args>88T& make(Args... args) {89alignas(T) static std::byte buf[sizeof(T)];90auto* obj = ::new (&buf) T(args...);91return *obj;92}9394template <typename T, size_t N>95inline constexpr size_t countof(const T (&)[N]) {96return N;97}9899template <typename T>100inline constexpr size_t countof(const T* const begin, const T* const end) {101return static_cast<size_t>(end - begin);102}103104string build_name(const string& other, const string& one, locale::category c) {105if (other == "*" || one == "*")106return "*";107if (c == locale::none || other == one)108return other;109110// FIXME: Handle the more complicated cases, such as when the locale has111// different names for different categories.112return "*";113}114115} // namespace116117const locale::category locale::none;118const locale::category locale::collate;119const locale::category locale::ctype;120const locale::category locale::monetary;121const locale::category locale::numeric;122const locale::category locale::time;123const locale::category locale::messages;124const locale::category locale::all;125126class _LIBCPP_HIDDEN locale::__imp : public facet {127enum { N = 30 };128vector<facet*, __sso_allocator<facet*, N> > facets_;129string name_;130131public:132explicit __imp(size_t refs = 0);133explicit __imp(const string& name, size_t refs = 0);134__imp(const __imp&);135__imp(const __imp&, const string&, locale::category c);136__imp(const __imp& other, const __imp& one, locale::category c);137__imp(const __imp&, facet* f, long id);138~__imp();139140const string& name() const { return name_; }141bool has_facet(long id) const { return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)]; }142const locale::facet* use_facet(long id) const;143144void acquire();145void release();146static __no_destroy<__imp> classic_locale_imp_;147148private:149void install(facet* f, long id);150template <class F>151void install(F* f) {152install(f, f->id.__get());153}154template <class F>155void install_from(const __imp& other);156};157158locale::__imp::__imp(size_t refs) : facet(refs), facets_(N), name_("C") {159facets_.clear();160install(&make<std::collate<char> >(1u));161#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS162install(&make<std::collate<wchar_t> >(1u));163#endif164install(&make<std::ctype<char> >(nullptr, false, 1u));165#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS166install(&make<std::ctype<wchar_t> >(1u));167#endif168install(&make<codecvt<char, char, mbstate_t> >(1u));169#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS170install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));171#endif172_LIBCPP_SUPPRESS_DEPRECATED_PUSH173install(&make<codecvt<char16_t, char, mbstate_t> >(1u));174install(&make<codecvt<char32_t, char, mbstate_t> >(1u));175_LIBCPP_SUPPRESS_DEPRECATED_POP176#ifndef _LIBCPP_HAS_NO_CHAR8_T177install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));178install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));179#endif180install(&make<numpunct<char> >(1u));181#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS182install(&make<numpunct<wchar_t> >(1u));183#endif184install(&make<num_get<char> >(1u));185#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS186install(&make<num_get<wchar_t> >(1u));187#endif188install(&make<num_put<char> >(1u));189#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS190install(&make<num_put<wchar_t> >(1u));191#endif192install(&make<moneypunct<char, false> >(1u));193install(&make<moneypunct<char, true> >(1u));194#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS195install(&make<moneypunct<wchar_t, false> >(1u));196install(&make<moneypunct<wchar_t, true> >(1u));197#endif198install(&make<money_get<char> >(1u));199#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS200install(&make<money_get<wchar_t> >(1u));201#endif202install(&make<money_put<char> >(1u));203#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS204install(&make<money_put<wchar_t> >(1u));205#endif206install(&make<time_get<char> >(1u));207#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS208install(&make<time_get<wchar_t> >(1u));209#endif210install(&make<time_put<char> >(1u));211#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS212install(&make<time_put<wchar_t> >(1u));213#endif214install(&make<std::messages<char> >(1u));215#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS216install(&make<std::messages<wchar_t> >(1u));217#endif218}219220locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N), name_(name) {221#ifndef _LIBCPP_HAS_NO_EXCEPTIONS222try {223#endif // _LIBCPP_HAS_NO_EXCEPTIONS224facets_ = locale::classic().__locale_->facets_;225for (unsigned i = 0; i < facets_.size(); ++i)226if (facets_[i])227facets_[i]->__add_shared();228install(new collate_byname<char>(name_));229#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS230install(new collate_byname<wchar_t>(name_));231#endif232install(new ctype_byname<char>(name_));233#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS234install(new ctype_byname<wchar_t>(name_));235#endif236install(new codecvt_byname<char, char, mbstate_t>(name_));237#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS238install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));239#endif240_LIBCPP_SUPPRESS_DEPRECATED_PUSH241install(new codecvt_byname<char16_t, char, mbstate_t>(name_));242install(new codecvt_byname<char32_t, char, mbstate_t>(name_));243_LIBCPP_SUPPRESS_DEPRECATED_POP244#ifndef _LIBCPP_HAS_NO_CHAR8_T245install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));246install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));247#endif248install(new numpunct_byname<char>(name_));249#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS250install(new numpunct_byname<wchar_t>(name_));251#endif252install(new moneypunct_byname<char, false>(name_));253install(new moneypunct_byname<char, true>(name_));254#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS255install(new moneypunct_byname<wchar_t, false>(name_));256install(new moneypunct_byname<wchar_t, true>(name_));257#endif258install(new time_get_byname<char>(name_));259#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS260install(new time_get_byname<wchar_t>(name_));261#endif262install(new time_put_byname<char>(name_));263#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS264install(new time_put_byname<wchar_t>(name_));265#endif266install(new messages_byname<char>(name_));267#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS268install(new messages_byname<wchar_t>(name_));269#endif270#ifndef _LIBCPP_HAS_NO_EXCEPTIONS271} catch (...) {272for (unsigned i = 0; i < facets_.size(); ++i)273if (facets_[i])274facets_[i]->__release_shared();275throw;276}277#endif // _LIBCPP_HAS_NO_EXCEPTIONS278}279280locale::__imp::__imp(const __imp& other) : facets_(max<size_t>(N, other.facets_.size())), name_(other.name_) {281facets_ = other.facets_;282for (unsigned i = 0; i < facets_.size(); ++i)283if (facets_[i])284facets_[i]->__add_shared();285}286287locale::__imp::__imp(const __imp& other, const string& name, locale::category c)288: facets_(N), name_(build_name(other.name_, name, c)) {289facets_ = other.facets_;290for (unsigned i = 0; i < facets_.size(); ++i)291if (facets_[i])292facets_[i]->__add_shared();293#ifndef _LIBCPP_HAS_NO_EXCEPTIONS294try {295#endif // _LIBCPP_HAS_NO_EXCEPTIONS296if (c & locale::collate) {297install(new collate_byname<char>(name));298#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS299install(new collate_byname<wchar_t>(name));300#endif301}302if (c & locale::ctype) {303install(new ctype_byname<char>(name));304#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS305install(new ctype_byname<wchar_t>(name));306#endif307install(new codecvt_byname<char, char, mbstate_t>(name));308#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS309install(new codecvt_byname<wchar_t, char, mbstate_t>(name));310#endif311_LIBCPP_SUPPRESS_DEPRECATED_PUSH312install(new codecvt_byname<char16_t, char, mbstate_t>(name));313install(new codecvt_byname<char32_t, char, mbstate_t>(name));314_LIBCPP_SUPPRESS_DEPRECATED_POP315#ifndef _LIBCPP_HAS_NO_CHAR8_T316install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));317install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));318#endif319}320if (c & locale::monetary) {321install(new moneypunct_byname<char, false>(name));322install(new moneypunct_byname<char, true>(name));323#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS324install(new moneypunct_byname<wchar_t, false>(name));325install(new moneypunct_byname<wchar_t, true>(name));326#endif327}328if (c & locale::numeric) {329install(new numpunct_byname<char>(name));330#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS331install(new numpunct_byname<wchar_t>(name));332#endif333}334if (c & locale::time) {335install(new time_get_byname<char>(name));336#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS337install(new time_get_byname<wchar_t>(name));338#endif339install(new time_put_byname<char>(name));340#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS341install(new time_put_byname<wchar_t>(name));342#endif343}344if (c & locale::messages) {345install(new messages_byname<char>(name));346#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS347install(new messages_byname<wchar_t>(name));348#endif349}350#ifndef _LIBCPP_HAS_NO_EXCEPTIONS351} catch (...) {352for (unsigned i = 0; i < facets_.size(); ++i)353if (facets_[i])354facets_[i]->__release_shared();355throw;356}357#endif // _LIBCPP_HAS_NO_EXCEPTIONS358}359360template <class F>361inline void locale::__imp::install_from(const locale::__imp& one) {362long id = F::id.__get();363install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);364}365366locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)367: facets_(N), name_(build_name(other.name_, one.name_, c)) {368facets_ = other.facets_;369for (unsigned i = 0; i < facets_.size(); ++i)370if (facets_[i])371facets_[i]->__add_shared();372#ifndef _LIBCPP_HAS_NO_EXCEPTIONS373try {374#endif // _LIBCPP_HAS_NO_EXCEPTIONS375if (c & locale::collate) {376install_from<std::collate<char> >(one);377#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS378install_from<std::collate<wchar_t> >(one);379#endif380}381if (c & locale::ctype) {382install_from<std::ctype<char> >(one);383#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS384install_from<std::ctype<wchar_t> >(one);385#endif386install_from<std::codecvt<char, char, mbstate_t> >(one);387_LIBCPP_SUPPRESS_DEPRECATED_PUSH388install_from<std::codecvt<char16_t, char, mbstate_t> >(one);389install_from<std::codecvt<char32_t, char, mbstate_t> >(one);390_LIBCPP_SUPPRESS_DEPRECATED_POP391#ifndef _LIBCPP_HAS_NO_CHAR8_T392install_from<std::codecvt<char16_t, char8_t, mbstate_t> >(one);393install_from<std::codecvt<char32_t, char8_t, mbstate_t> >(one);394#endif395#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS396install_from<std::codecvt<wchar_t, char, mbstate_t> >(one);397#endif398}399if (c & locale::monetary) {400install_from<moneypunct<char, false> >(one);401install_from<moneypunct<char, true> >(one);402#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS403install_from<moneypunct<wchar_t, false> >(one);404install_from<moneypunct<wchar_t, true> >(one);405#endif406install_from<money_get<char> >(one);407#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS408install_from<money_get<wchar_t> >(one);409#endif410install_from<money_put<char> >(one);411#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS412install_from<money_put<wchar_t> >(one);413#endif414}415if (c & locale::numeric) {416install_from<numpunct<char> >(one);417#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS418install_from<numpunct<wchar_t> >(one);419#endif420install_from<num_get<char> >(one);421#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS422install_from<num_get<wchar_t> >(one);423#endif424install_from<num_put<char> >(one);425#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS426install_from<num_put<wchar_t> >(one);427#endif428}429if (c & locale::time) {430install_from<time_get<char> >(one);431#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS432install_from<time_get<wchar_t> >(one);433#endif434install_from<time_put<char> >(one);435#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS436install_from<time_put<wchar_t> >(one);437#endif438}439if (c & locale::messages) {440install_from<std::messages<char> >(one);441#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS442install_from<std::messages<wchar_t> >(one);443#endif444}445#ifndef _LIBCPP_HAS_NO_EXCEPTIONS446} catch (...) {447for (unsigned i = 0; i < facets_.size(); ++i)448if (facets_[i])449facets_[i]->__release_shared();450throw;451}452#endif // _LIBCPP_HAS_NO_EXCEPTIONS453}454455locale::__imp::__imp(const __imp& other, facet* f, long id)456: facets_(max<size_t>(N, other.facets_.size() + 1)), name_("*") {457f->__add_shared();458unique_ptr<facet, releaser> hold(f);459facets_ = other.facets_;460for (unsigned i = 0; i < other.facets_.size(); ++i)461if (facets_[i])462facets_[i]->__add_shared();463install(hold.get(), id);464}465466locale::__imp::~__imp() {467for (unsigned i = 0; i < facets_.size(); ++i)468if (facets_[i])469facets_[i]->__release_shared();470}471472void locale::__imp::install(facet* f, long id) {473f->__add_shared();474unique_ptr<facet, releaser> hold(f);475if (static_cast<size_t>(id) >= facets_.size())476facets_.resize(static_cast<size_t>(id + 1));477if (facets_[static_cast<size_t>(id)])478facets_[static_cast<size_t>(id)]->__release_shared();479facets_[static_cast<size_t>(id)] = hold.release();480}481482const locale::facet* locale::__imp::use_facet(long id) const {483if (!has_facet(id))484__throw_bad_cast();485return facets_[static_cast<size_t>(id)];486}487488// locale489490// We don't do reference counting on the classic locale.491// It's never destroyed anyway, but atomic reference counting may be very492// expensive in parallel applications. The classic locale is used by default493// in all streams. Note: if a new global locale is installed, then we lose494// the benefit of no reference counting.495constinit __no_destroy<locale::__imp>496locale::__imp::classic_locale_imp_(__uninitialized_tag{}); // initialized below in classic()497498const locale& locale::classic() {499static const __no_destroy<locale> classic_locale(__private_constructor_tag{}, [] {500// executed exactly once on first initialization of `classic_locale`501locale::__imp::classic_locale_imp_.__emplace(1u);502return &locale::__imp::classic_locale_imp_.__get();503}());504return classic_locale.__get();505}506507locale& locale::__global() {508static __no_destroy<locale> g(locale::classic());509return g.__get();510}511512void locale::__imp::acquire() {513if (this != &locale::__imp::classic_locale_imp_.__get())514__add_shared();515}516517void locale::__imp::release() {518if (this != &locale::__imp::classic_locale_imp_.__get())519__release_shared();520}521522locale::locale() noexcept : __locale_(__global().__locale_) { __locale_->acquire(); }523524locale::locale(const locale& l) noexcept : __locale_(l.__locale_) { __locale_->acquire(); }525526locale::~locale() { __locale_->release(); }527528const locale& locale::operator=(const locale& other) noexcept {529other.__locale_->acquire();530__locale_->release();531__locale_ = other.__locale_;532return *this;533}534535locale::locale(const char* name)536: __locale_(name ? new __imp(name) : (__throw_runtime_error("locale constructed with null"), nullptr)) {537__locale_->acquire();538}539540locale::locale(const string& name) : __locale_(new __imp(name)) { __locale_->acquire(); }541542locale::locale(const locale& other, const char* name, category c)543: __locale_(name ? new __imp(*other.__locale_, name, c)544: (__throw_runtime_error("locale constructed with null"), nullptr)) {545__locale_->acquire();546}547548locale::locale(const locale& other, const string& name, category c) : __locale_(new __imp(*other.__locale_, name, c)) {549__locale_->acquire();550}551552locale::locale(const locale& other, const locale& one, category c)553: __locale_(new __imp(*other.__locale_, *one.__locale_, c)) {554__locale_->acquire();555}556557string locale::name() const { return __locale_->name(); }558559void locale::__install_ctor(const locale& other, facet* f, long facet_id) {560if (f)561__locale_ = new __imp(*other.__locale_, f, facet_id);562else563__locale_ = other.__locale_;564__locale_->acquire();565}566567locale locale::global(const locale& loc) {568locale& g = __global();569locale r = g;570g = loc;571if (g.name() != "*")572setlocale(LC_ALL, g.name().c_str());573return r;574}575576bool locale::has_facet(id& x) const { return __locale_->has_facet(x.__get()); }577578const locale::facet* locale::use_facet(id& x) const { return __locale_->use_facet(x.__get()); }579580bool locale::operator==(const locale& y) const {581return (__locale_ == y.__locale_) || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());582}583584// locale::facet585586locale::facet::~facet() {}587588void locale::facet::__on_zero_shared() noexcept { delete this; }589590// locale::id591592constinit int32_t locale::id::__next_id = 0;593594long locale::id::__get() {595call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); });596return __id_ - 1;597}598599// template <> class collate_byname<char>600601collate_byname<char>::collate_byname(const char* n, size_t refs)602: collate<char>(refs), __l_(newlocale(LC_ALL_MASK, n, 0)) {603if (__l_ == 0)604__throw_runtime_error(605("collate_byname<char>::collate_byname"606" failed to construct for " +607string(n))608.c_str());609}610611collate_byname<char>::collate_byname(const string& name, size_t refs)612: collate<char>(refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {613if (__l_ == 0)614__throw_runtime_error(615("collate_byname<char>::collate_byname"616" failed to construct for " +617name)618.c_str());619}620621collate_byname<char>::~collate_byname() { freelocale(__l_); }622623int collate_byname<char>::do_compare(624const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {625string_type lhs(__lo1, __hi1);626string_type rhs(__lo2, __hi2);627int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l_);628if (r < 0)629return -1;630if (r > 0)631return 1;632return r;633}634635collate_byname<char>::string_type collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const {636const string_type in(lo, hi);637string_type out(strxfrm_l(0, in.c_str(), 0, __l_), char());638strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size() + 1, __l_);639return out;640}641642// template <> class collate_byname<wchar_t>643644#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS645collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)646: collate<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, n, 0)) {647if (__l_ == 0)648__throw_runtime_error(649("collate_byname<wchar_t>::collate_byname(size_t refs)"650" failed to construct for " +651string(n))652.c_str());653}654655collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)656: collate<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {657if (__l_ == 0)658__throw_runtime_error(659("collate_byname<wchar_t>::collate_byname(size_t refs)"660" failed to construct for " +661name)662.c_str());663}664665collate_byname<wchar_t>::~collate_byname() { freelocale(__l_); }666667int collate_byname<wchar_t>::do_compare(668const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {669string_type lhs(__lo1, __hi1);670string_type rhs(__lo2, __hi2);671int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l_);672if (r < 0)673return -1;674if (r > 0)675return 1;676return r;677}678679collate_byname<wchar_t>::string_type680collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const {681const string_type in(lo, hi);682string_type out(wcsxfrm_l(0, in.c_str(), 0, __l_), wchar_t());683wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size() + 1, __l_);684return out;685}686#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS687688const ctype_base::mask ctype_base::space;689const ctype_base::mask ctype_base::print;690const ctype_base::mask ctype_base::cntrl;691const ctype_base::mask ctype_base::upper;692const ctype_base::mask ctype_base::lower;693const ctype_base::mask ctype_base::alpha;694const ctype_base::mask ctype_base::digit;695const ctype_base::mask ctype_base::punct;696const ctype_base::mask ctype_base::xdigit;697const ctype_base::mask ctype_base::blank;698const ctype_base::mask ctype_base::alnum;699const ctype_base::mask ctype_base::graph;700701// template <> class ctype<wchar_t>;702703#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS704constinit locale::id ctype<wchar_t>::id;705706ctype<wchar_t>::~ctype() {}707708bool ctype<wchar_t>::do_is(mask m, char_type c) const {709return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;710}711712const wchar_t* ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {713for (; low != high; ++low, ++vec)714*vec = static_cast<mask>(isascii(*low) ? ctype<char>::classic_table()[*low] : 0);715return low;716}717718const wchar_t* ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {719for (; low != high; ++low)720if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))721break;722return low;723}724725const wchar_t* ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {726for (; low != high; ++low)727if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))728break;729return low;730}731732wchar_t ctype<wchar_t>::do_toupper(char_type c) const {733# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE734return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;735# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)736return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;737# else738return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c - L'a' + L'A' : c;739# endif740}741742const wchar_t* ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const {743for (; low != high; ++low)744# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE745*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;746# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)747*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] : *low;748# else749*low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low - L'a' + L'A') : *low;750# endif751return low;752}753754wchar_t ctype<wchar_t>::do_tolower(char_type c) const {755# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE756return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;757# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)758return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;759# else760return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c - L'A' + 'a' : c;761# endif762}763764const wchar_t* ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const {765for (; low != high; ++low)766# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE767*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;768# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)769*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] : *low;770# else771*low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low - L'A' + L'a' : *low;772# endif773return low;774}775776wchar_t ctype<wchar_t>::do_widen(char c) const { return c; }777778const char* ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const {779for (; low != high; ++low, ++dest)780*dest = *low;781return low;782}783784char ctype<wchar_t>::do_narrow(char_type c, char dfault) const {785if (isascii(c))786return static_cast<char>(c);787return dfault;788}789790const wchar_t* ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {791for (; low != high; ++low, ++dest)792if (isascii(*low))793*dest = static_cast<char>(*low);794else795*dest = dfault;796return low;797}798#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS799800// template <> class ctype<char>;801802constinit locale::id ctype<char>::id;803804const size_t ctype<char>::table_size;805806ctype<char>::ctype(const mask* tab, bool del, size_t refs) : locale::facet(refs), __tab_(tab), __del_(del) {807if (__tab_ == 0)808__tab_ = classic_table();809}810811ctype<char>::~ctype() {812if (__tab_ && __del_)813delete[] __tab_;814}815816char ctype<char>::do_toupper(char_type c) const {817#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE818return isascii(c) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;819#elif defined(__NetBSD__)820return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);821#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)822return isascii(c) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;823#else824return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c - 'a' + 'A' : c;825#endif826}827828const char* ctype<char>::do_toupper(char_type* low, const char_type* high) const {829for (; low != high; ++low)830#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE831*low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;832#elif defined(__NetBSD__)833*low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);834#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)835*low = isascii(*low) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;836#else837*low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'a' + 'A' : *low;838#endif839return low;840}841842char ctype<char>::do_tolower(char_type c) const {843#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE844return isascii(c) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;845#elif defined(__NetBSD__)846return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);847#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)848return isascii(c) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;849#else850return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c - 'A' + 'a' : c;851#endif852}853854const char* ctype<char>::do_tolower(char_type* low, const char_type* high) const {855for (; low != high; ++low)856#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE857*low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;858#elif defined(__NetBSD__)859*low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);860#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)861*low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;862#else863*low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'A' + 'a' : *low;864#endif865return low;866}867868char ctype<char>::do_widen(char c) const { return c; }869870const char* ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const {871for (; low != high; ++low, ++dest)872*dest = *low;873return low;874}875876char ctype<char>::do_narrow(char_type c, char dfault) const {877if (isascii(c))878return static_cast<char>(c);879return dfault;880}881882const char* ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {883for (; low != high; ++low, ++dest)884if (isascii(*low))885*dest = *low;886else887*dest = dfault;888return low;889}890891#if defined(__EMSCRIPTEN__)892extern "C" const unsigned short** __ctype_b_loc();893extern "C" const int** __ctype_tolower_loc();894extern "C" const int** __ctype_toupper_loc();895#endif896897#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE898const ctype<char>::mask* ctype<char>::classic_table() noexcept {899// clang-format off900static constexpr const ctype<char>::mask builtin_table[table_size] = {901cntrl, cntrl,902cntrl, cntrl,903cntrl, cntrl,904cntrl, cntrl,905cntrl, cntrl | space | blank,906cntrl | space, cntrl | space,907cntrl | space, cntrl | space,908cntrl, cntrl,909cntrl, cntrl,910cntrl, cntrl,911cntrl, cntrl,912cntrl, cntrl,913cntrl, cntrl,914cntrl, cntrl,915cntrl, cntrl,916cntrl, cntrl,917space | blank | print, punct | print,918punct | print, punct | print,919punct | print, punct | print,920punct | print, punct | print,921punct | print, punct | print,922punct | print, punct | print,923punct | print, punct | print,924punct | print, punct | print,925digit | print | xdigit, digit | print | xdigit,926digit | print | xdigit, digit | print | xdigit,927digit | print | xdigit, digit | print | xdigit,928digit | print | xdigit, digit | print | xdigit,929digit | print | xdigit, digit | print | xdigit,930punct | print, punct | print,931punct | print, punct | print,932punct | print, punct | print,933punct | print, upper | xdigit | print | alpha,934upper | xdigit | print | alpha, upper | xdigit | print | alpha,935upper | xdigit | print | alpha, upper | xdigit | print | alpha,936upper | xdigit | print | alpha, upper | print | alpha,937upper | print | alpha, upper | print | alpha,938upper | print | alpha, upper | print | alpha,939upper | print | alpha, upper | print | alpha,940upper | print | alpha, upper | print | alpha,941upper | print | alpha, upper | print | alpha,942upper | print | alpha, upper | print | alpha,943upper | print | alpha, upper | print | alpha,944upper | print | alpha, upper | print | alpha,945upper | print | alpha, upper | print | alpha,946upper | print | alpha, punct | print,947punct | print, punct | print,948punct | print, punct | print,949punct | print, lower | xdigit | print | alpha,950lower | xdigit | print | alpha, lower | xdigit | print | alpha,951lower | xdigit | print | alpha, lower | xdigit | print | alpha,952lower | xdigit | print | alpha, lower | print | alpha,953lower | print | alpha, lower | print | alpha,954lower | print | alpha, lower | print | alpha,955lower | print | alpha, lower | print | alpha,956lower | print | alpha, lower | print | alpha,957lower | print | alpha, lower | print | alpha,958lower | print | alpha, lower | print | alpha,959lower | print | alpha, lower | print | alpha,960lower | print | alpha, lower | print | alpha,961lower | print | alpha, lower | print | alpha,962lower | print | alpha, punct | print,963punct | print, punct | print,964punct | print, cntrl,9650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9690, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9710, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0973};974// clang-format on975return builtin_table;976}977#else978const ctype<char>::mask* ctype<char>::classic_table() noexcept {979# if defined(__APPLE__) || defined(__FreeBSD__)980return _DefaultRuneLocale.__runetype;981# elif defined(__NetBSD__)982return _C_ctype_tab_ + 1;983# elif defined(__GLIBC__)984return _LIBCPP_GET_C_LOCALE->__ctype_b;985# elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)986return __pctype_func();987# elif defined(__EMSCRIPTEN__)988return *__ctype_b_loc();989# elif defined(_NEWLIB_VERSION)990// Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].991return _ctype_ + 1;992# elif defined(_AIX)993return (const unsigned int*)__lc_ctype_ptr->obj->mask;994# elif defined(__MVS__)995# if defined(__NATIVE_ASCII_F)996return const_cast<const ctype<char>::mask*>(__OBJ_DATA(__lc_ctype_a)->mask);997# else998return const_cast<const ctype<char>::mask*>(__ctypec);999# endif1000# else1001// Platform not supported: abort so the person doing the port knows what to1002// fix1003# warning ctype<char>::classic_table() is not implemented1004printf("ctype<char>::classic_table() is not implemented\n");1005abort();1006return NULL;1007# endif1008}1009#endif10101011#if defined(__GLIBC__)1012const int* ctype<char>::__classic_lower_table() noexcept { return _LIBCPP_GET_C_LOCALE->__ctype_tolower; }10131014const int* ctype<char>::__classic_upper_table() noexcept { return _LIBCPP_GET_C_LOCALE->__ctype_toupper; }1015#elif defined(__NetBSD__)1016const short* ctype<char>::__classic_lower_table() noexcept { return _C_tolower_tab_ + 1; }10171018const short* ctype<char>::__classic_upper_table() noexcept { return _C_toupper_tab_ + 1; }10191020#elif defined(__EMSCRIPTEN__)1021const int* ctype<char>::__classic_lower_table() noexcept { return *__ctype_tolower_loc(); }10221023const int* ctype<char>::__classic_upper_table() noexcept { return *__ctype_toupper_loc(); }1024#elif defined(__MVS__)1025const unsigned short* ctype<char>::__classic_lower_table() _NOEXCEPT {1026# if defined(__NATIVE_ASCII_F)1027return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower);1028# else1029return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX);1030# endif1031}1032const unsigned short* ctype<char>::__classic_upper_table() _NOEXCEPT {1033# if defined(__NATIVE_ASCII_F)1034return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper);1035# else1036return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX);1037# endif1038}1039#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__10401041// template <> class ctype_byname<char>10421043ctype_byname<char>::ctype_byname(const char* name, size_t refs)1044: ctype<char>(0, false, refs), __l_(newlocale(LC_ALL_MASK, name, 0)) {1045if (__l_ == 0)1046__throw_runtime_error(1047("ctype_byname<char>::ctype_byname"1048" failed to construct for " +1049string(name))1050.c_str());1051}10521053ctype_byname<char>::ctype_byname(const string& name, size_t refs)1054: ctype<char>(0, false, refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {1055if (__l_ == 0)1056__throw_runtime_error(1057("ctype_byname<char>::ctype_byname"1058" failed to construct for " +1059name)1060.c_str());1061}10621063ctype_byname<char>::~ctype_byname() { freelocale(__l_); }10641065char ctype_byname<char>::do_toupper(char_type c) const {1066return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l_));1067}10681069const char* ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const {1070for (; low != high; ++low)1071*low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l_));1072return low;1073}10741075char ctype_byname<char>::do_tolower(char_type c) const {1076return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l_));1077}10781079const char* ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const {1080for (; low != high; ++low)1081*low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l_));1082return low;1083}10841085// template <> class ctype_byname<wchar_t>10861087#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS1088ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)1089: ctype<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, name, 0)) {1090if (__l_ == 0)1091__throw_runtime_error(1092("ctype_byname<wchar_t>::ctype_byname"1093" failed to construct for " +1094string(name))1095.c_str());1096}10971098ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)1099: ctype<wchar_t>(refs), __l_(newlocale(LC_ALL_MASK, name.c_str(), 0)) {1100if (__l_ == 0)1101__throw_runtime_error(1102("ctype_byname<wchar_t>::ctype_byname"1103" failed to construct for " +1104name)1105.c_str());1106}11071108ctype_byname<wchar_t>::~ctype_byname() { freelocale(__l_); }11091110bool ctype_byname<wchar_t>::do_is(mask m, char_type c) const {1111# ifdef _LIBCPP_WCTYPE_IS_MASK1112return static_cast<bool>(iswctype_l(c, m, __l_));1113# else1114bool result = false;1115wint_t ch = static_cast<wint_t>(c);1116if ((m & space) == space)1117result |= (iswspace_l(ch, __l_) != 0);1118if ((m & print) == print)1119result |= (iswprint_l(ch, __l_) != 0);1120if ((m & cntrl) == cntrl)1121result |= (iswcntrl_l(ch, __l_) != 0);1122if ((m & upper) == upper)1123result |= (iswupper_l(ch, __l_) != 0);1124if ((m & lower) == lower)1125result |= (iswlower_l(ch, __l_) != 0);1126if ((m & alpha) == alpha)1127result |= (iswalpha_l(ch, __l_) != 0);1128if ((m & digit) == digit)1129result |= (iswdigit_l(ch, __l_) != 0);1130if ((m & punct) == punct)1131result |= (iswpunct_l(ch, __l_) != 0);1132if ((m & xdigit) == xdigit)1133result |= (iswxdigit_l(ch, __l_) != 0);1134if ((m & blank) == blank)1135result |= (iswblank_l(ch, __l_) != 0);1136return result;1137# endif1138}11391140const wchar_t* ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {1141for (; low != high; ++low, ++vec) {1142if (isascii(*low))1143*vec = static_cast<mask>(ctype<char>::classic_table()[*low]);1144else {1145*vec = 0;1146wint_t ch = static_cast<wint_t>(*low);1147if (iswspace_l(ch, __l_))1148*vec |= space;1149# ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT1150if (iswprint_l(ch, __l_))1151*vec |= print;1152# endif1153if (iswcntrl_l(ch, __l_))1154*vec |= cntrl;1155if (iswupper_l(ch, __l_))1156*vec |= upper;1157if (iswlower_l(ch, __l_))1158*vec |= lower;1159# ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA1160if (iswalpha_l(ch, __l_))1161*vec |= alpha;1162# endif1163if (iswdigit_l(ch, __l_))1164*vec |= digit;1165if (iswpunct_l(ch, __l_))1166*vec |= punct;1167# ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT1168if (iswxdigit_l(ch, __l_))1169*vec |= xdigit;1170# endif1171if (iswblank_l(ch, __l_))1172*vec |= blank;1173}1174}1175return low;1176}11771178const wchar_t* ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {1179for (; low != high; ++low) {1180# ifdef _LIBCPP_WCTYPE_IS_MASK1181if (iswctype_l(*low, m, __l_))1182break;1183# else1184wint_t ch = static_cast<wint_t>(*low);1185if ((m & space) == space && iswspace_l(ch, __l_))1186break;1187if ((m & print) == print && iswprint_l(ch, __l_))1188break;1189if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_))1190break;1191if ((m & upper) == upper && iswupper_l(ch, __l_))1192break;1193if ((m & lower) == lower && iswlower_l(ch, __l_))1194break;1195if ((m & alpha) == alpha && iswalpha_l(ch, __l_))1196break;1197if ((m & digit) == digit && iswdigit_l(ch, __l_))1198break;1199if ((m & punct) == punct && iswpunct_l(ch, __l_))1200break;1201if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_))1202break;1203if ((m & blank) == blank && iswblank_l(ch, __l_))1204break;1205# endif1206}1207return low;1208}12091210const wchar_t* ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {1211for (; low != high; ++low) {1212# ifdef _LIBCPP_WCTYPE_IS_MASK1213if (!iswctype_l(*low, m, __l_))1214break;1215# else1216wint_t ch = static_cast<wint_t>(*low);1217if ((m & space) == space && iswspace_l(ch, __l_))1218continue;1219if ((m & print) == print && iswprint_l(ch, __l_))1220continue;1221if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_))1222continue;1223if ((m & upper) == upper && iswupper_l(ch, __l_))1224continue;1225if ((m & lower) == lower && iswlower_l(ch, __l_))1226continue;1227if ((m & alpha) == alpha && iswalpha_l(ch, __l_))1228continue;1229if ((m & digit) == digit && iswdigit_l(ch, __l_))1230continue;1231if ((m & punct) == punct && iswpunct_l(ch, __l_))1232continue;1233if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_))1234continue;1235if ((m & blank) == blank && iswblank_l(ch, __l_))1236continue;1237break;1238# endif1239}1240return low;1241}12421243wchar_t ctype_byname<wchar_t>::do_toupper(char_type c) const { return towupper_l(c, __l_); }12441245const wchar_t* ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const {1246for (; low != high; ++low)1247*low = towupper_l(*low, __l_);1248return low;1249}12501251wchar_t ctype_byname<wchar_t>::do_tolower(char_type c) const { return towlower_l(c, __l_); }12521253const wchar_t* ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const {1254for (; low != high; ++low)1255*low = towlower_l(*low, __l_);1256return low;1257}12581259wchar_t ctype_byname<wchar_t>::do_widen(char c) const { return __libcpp_btowc_l(c, __l_); }12601261const char* ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const {1262for (; low != high; ++low, ++dest)1263*dest = __libcpp_btowc_l(*low, __l_);1264return low;1265}12661267char ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const {1268int r = __libcpp_wctob_l(c, __l_);1269return (r != EOF) ? static_cast<char>(r) : dfault;1270}12711272const wchar_t*1273ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {1274for (; low != high; ++low, ++dest) {1275int r = __libcpp_wctob_l(*low, __l_);1276*dest = (r != EOF) ? static_cast<char>(r) : dfault;1277}1278return low;1279}1280#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS12811282// template <> class codecvt<char, char, mbstate_t>12831284constinit locale::id codecvt<char, char, mbstate_t>::id;12851286codecvt<char, char, mbstate_t>::~codecvt() {}12871288codecvt<char, char, mbstate_t>::result codecvt<char, char, mbstate_t>::do_out(1289state_type&,1290const intern_type* frm,1291const intern_type*,1292const intern_type*& frm_nxt,1293extern_type* to,1294extern_type*,1295extern_type*& to_nxt) const {1296frm_nxt = frm;1297to_nxt = to;1298return noconv;1299}13001301codecvt<char, char, mbstate_t>::result codecvt<char, char, mbstate_t>::do_in(1302state_type&,1303const extern_type* frm,1304const extern_type*,1305const extern_type*& frm_nxt,1306intern_type* to,1307intern_type*,1308intern_type*& to_nxt) const {1309frm_nxt = frm;1310to_nxt = to;1311return noconv;1312}13131314codecvt<char, char, mbstate_t>::result1315codecvt<char, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {1316to_nxt = to;1317return noconv;1318}13191320int codecvt<char, char, mbstate_t>::do_encoding() const noexcept { return 1; }13211322bool codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept { return true; }13231324int codecvt<char, char, mbstate_t>::do_length(1325state_type&, const extern_type* frm, const extern_type* end, size_t mx) const {1326return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end - frm)));1327}13281329int codecvt<char, char, mbstate_t>::do_max_length() const noexcept { return 1; }13301331// template <> class codecvt<wchar_t, char, mbstate_t>13321333#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS1334constinit locale::id codecvt<wchar_t, char, mbstate_t>::id;13351336codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) : locale::facet(refs), __l_(_LIBCPP_GET_C_LOCALE) {}13371338codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)1339: locale::facet(refs), __l_(newlocale(LC_ALL_MASK, nm, 0)) {1340if (__l_ == 0)1341__throw_runtime_error(1342("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"1343" failed to construct for " +1344string(nm))1345.c_str());1346}13471348codecvt<wchar_t, char, mbstate_t>::~codecvt() {1349if (__l_ != _LIBCPP_GET_C_LOCALE)1350freelocale(__l_);1351}13521353codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_out(1354state_type& st,1355const intern_type* frm,1356const intern_type* frm_end,1357const intern_type*& frm_nxt,1358extern_type* to,1359extern_type* to_end,1360extern_type*& to_nxt) const {1361// look for first internal null in frm1362const intern_type* fend = frm;1363for (; fend != frm_end; ++fend)1364if (*fend == 0)1365break;1366// loop over all null-terminated sequences in frm1367to_nxt = to;1368for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) {1369// save state in case it is needed to recover to_nxt on error1370mbstate_t save_state = st;1371size_t n = __libcpp_wcsnrtombs_l(1372to, &frm_nxt, static_cast<size_t>(fend - frm), static_cast<size_t>(to_end - to), &st, __l_);1373if (n == size_t(-1)) {1374// need to recover to_nxt1375for (to_nxt = to; frm != frm_nxt; ++frm) {1376n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l_);1377if (n == size_t(-1))1378break;1379to_nxt += n;1380}1381frm_nxt = frm;1382return error;1383}1384if (n == 0)1385return partial;1386to_nxt += n;1387if (to_nxt == to_end)1388break;1389if (fend != frm_end) // set up next null terminated sequence1390{1391// Try to write the terminating null1392extern_type tmp[MB_LEN_MAX];1393n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);1394if (n == size_t(-1)) // on error1395return error;1396if (n > static_cast<size_t>(to_end - to_nxt)) // is there room?1397return partial;1398for (extern_type* p = tmp; n; --n) // write it1399*to_nxt++ = *p++;1400++frm_nxt;1401// look for next null in frm1402for (fend = frm_nxt; fend != frm_end; ++fend)1403if (*fend == 0)1404break;1405}1406}1407return frm_nxt == frm_end ? ok : partial;1408}14091410codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_in(1411state_type& st,1412const extern_type* frm,1413const extern_type* frm_end,1414const extern_type*& frm_nxt,1415intern_type* to,1416intern_type* to_end,1417intern_type*& to_nxt) const {1418// look for first internal null in frm1419const extern_type* fend = frm;1420for (; fend != frm_end; ++fend)1421if (*fend == 0)1422break;1423// loop over all null-terminated sequences in frm1424to_nxt = to;1425for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) {1426// save state in case it is needed to recover to_nxt on error1427mbstate_t save_state = st;1428size_t n = __libcpp_mbsnrtowcs_l(1429to, &frm_nxt, static_cast<size_t>(fend - frm), static_cast<size_t>(to_end - to), &st, __l_);1430if (n == size_t(-1)) {1431// need to recover to_nxt1432for (to_nxt = to; frm != frm_nxt; ++to_nxt) {1433n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend - frm), &save_state, __l_);1434switch (n) {1435case 0:1436++frm;1437break;1438case size_t(-1):1439frm_nxt = frm;1440return error;1441case size_t(-2):1442frm_nxt = frm;1443return partial;1444default:1445frm += n;1446break;1447}1448}1449frm_nxt = frm;1450return frm_nxt == frm_end ? ok : partial;1451}1452if (n == size_t(-1))1453return error;1454to_nxt += n;1455if (to_nxt == to_end)1456break;1457if (fend != frm_end) // set up next null terminated sequence1458{1459// Try to write the terminating null1460n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l_);1461if (n != 0) // on error1462return error;1463++to_nxt;1464++frm_nxt;1465// look for next null in frm1466for (fend = frm_nxt; fend != frm_end; ++fend)1467if (*fend == 0)1468break;1469}1470}1471return frm_nxt == frm_end ? ok : partial;1472}14731474codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_unshift(1475state_type& st, extern_type* to, extern_type* to_end, extern_type*& to_nxt) const {1476to_nxt = to;1477extern_type tmp[MB_LEN_MAX];1478size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);1479if (n == size_t(-1) || n == 0) // on error1480return error;1481--n;1482if (n > static_cast<size_t>(to_end - to_nxt)) // is there room?1483return partial;1484for (extern_type* p = tmp; n; --n) // write it1485*to_nxt++ = *p++;1486return ok;1487}14881489int codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept {1490if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l_) != 0)1491return -1;14921493// stateless encoding1494if (__l_ == 0 || __libcpp_mb_cur_max_l(__l_) == 1) // there are no known constant length encodings1495return 1; // which take more than 1 char to form a wchar_t1496return 0;1497}14981499bool codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }15001501int codecvt<wchar_t, char, mbstate_t>::do_length(1502state_type& st, const extern_type* frm, const extern_type* frm_end, size_t mx) const {1503int nbytes = 0;1504for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) {1505size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end - frm), &st, __l_);1506switch (n) {1507case 0:1508++nbytes;1509++frm;1510break;1511case size_t(-1):1512case size_t(-2):1513return nbytes;1514default:1515nbytes += n;1516frm += n;1517break;1518}1519}1520return nbytes;1521}15221523int codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept {1524return __l_ == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_));1525}1526#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS15271528// Valid UTF ranges1529// UTF-32 UTF-16 UTF-8 # of code points1530// first second first second third fourth1531// 000000 - 00007F 0000 - 007F 00 - 7F 1271532// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 19201533// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 20481534// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 491521535// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 20481536// 00D800 - 00DFFF invalid1537// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 81921538// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 1966081539// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 7864321540// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 6553615411542_LIBCPP_SUPPRESS_DEPRECATED_PUSH1543static codecvt_base::result utf16_to_utf8(1544const uint16_t* frm,1545const uint16_t* frm_end,1546const uint16_t*& frm_nxt,1547uint8_t* to,1548uint8_t* to_end,1549uint8_t*& to_nxt,1550unsigned long Maxcode = 0x10FFFF,1551codecvt_mode mode = codecvt_mode(0)) {1552frm_nxt = frm;1553to_nxt = to;1554if (mode & generate_header) {1555if (to_end - to_nxt < 3)1556return codecvt_base::partial;1557*to_nxt++ = static_cast<uint8_t>(0xEF);1558*to_nxt++ = static_cast<uint8_t>(0xBB);1559*to_nxt++ = static_cast<uint8_t>(0xBF);1560}1561for (; frm_nxt < frm_end; ++frm_nxt) {1562uint16_t wc1 = *frm_nxt;1563if (wc1 > Maxcode)1564return codecvt_base::error;1565if (wc1 < 0x0080) {1566if (to_end - to_nxt < 1)1567return codecvt_base::partial;1568*to_nxt++ = static_cast<uint8_t>(wc1);1569} else if (wc1 < 0x0800) {1570if (to_end - to_nxt < 2)1571return codecvt_base::partial;1572*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));1573*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));1574} else if (wc1 < 0xD800) {1575if (to_end - to_nxt < 3)1576return codecvt_base::partial;1577*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1578*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1579*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1580} else if (wc1 < 0xDC00) {1581if (frm_end - frm_nxt < 2)1582return codecvt_base::partial;1583uint16_t wc2 = frm_nxt[1];1584if ((wc2 & 0xFC00) != 0xDC00)1585return codecvt_base::error;1586if (to_end - to_nxt < 4)1587return codecvt_base::partial;1588if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)1589return codecvt_base::error;1590++frm_nxt;1591uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;1592*to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));1593*to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));1594*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));1595*to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));1596} else if (wc1 < 0xE000) {1597return codecvt_base::error;1598} else {1599if (to_end - to_nxt < 3)1600return codecvt_base::partial;1601*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1602*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1603*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1604}1605}1606return codecvt_base::ok;1607}16081609static codecvt_base::result utf16_to_utf8(1610const uint32_t* frm,1611const uint32_t* frm_end,1612const uint32_t*& frm_nxt,1613uint8_t* to,1614uint8_t* to_end,1615uint8_t*& to_nxt,1616unsigned long Maxcode = 0x10FFFF,1617codecvt_mode mode = codecvt_mode(0)) {1618frm_nxt = frm;1619to_nxt = to;1620if (mode & generate_header) {1621if (to_end - to_nxt < 3)1622return codecvt_base::partial;1623*to_nxt++ = static_cast<uint8_t>(0xEF);1624*to_nxt++ = static_cast<uint8_t>(0xBB);1625*to_nxt++ = static_cast<uint8_t>(0xBF);1626}1627for (; frm_nxt < frm_end; ++frm_nxt) {1628uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);1629if (wc1 > Maxcode)1630return codecvt_base::error;1631if (wc1 < 0x0080) {1632if (to_end - to_nxt < 1)1633return codecvt_base::partial;1634*to_nxt++ = static_cast<uint8_t>(wc1);1635} else if (wc1 < 0x0800) {1636if (to_end - to_nxt < 2)1637return codecvt_base::partial;1638*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));1639*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));1640} else if (wc1 < 0xD800) {1641if (to_end - to_nxt < 3)1642return codecvt_base::partial;1643*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1644*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1645*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1646} else if (wc1 < 0xDC00) {1647if (frm_end - frm_nxt < 2)1648return codecvt_base::partial;1649uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);1650if ((wc2 & 0xFC00) != 0xDC00)1651return codecvt_base::error;1652if (to_end - to_nxt < 4)1653return codecvt_base::partial;1654if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)1655return codecvt_base::error;1656++frm_nxt;1657uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;1658*to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));1659*to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));1660*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));1661*to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));1662} else if (wc1 < 0xE000) {1663return codecvt_base::error;1664} else {1665if (to_end - to_nxt < 3)1666return codecvt_base::partial;1667*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1668*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1669*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1670}1671}1672return codecvt_base::ok;1673}16741675static codecvt_base::result utf8_to_utf16(1676const uint8_t* frm,1677const uint8_t* frm_end,1678const uint8_t*& frm_nxt,1679uint16_t* to,1680uint16_t* to_end,1681uint16_t*& to_nxt,1682unsigned long Maxcode = 0x10FFFF,1683codecvt_mode mode = codecvt_mode(0)) {1684frm_nxt = frm;1685to_nxt = to;1686if (mode & consume_header) {1687if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1688frm_nxt += 3;1689}1690for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {1691uint8_t c1 = *frm_nxt;1692if (c1 > Maxcode)1693return codecvt_base::error;1694if (c1 < 0x80) {1695*to_nxt = static_cast<uint16_t>(c1);1696++frm_nxt;1697} else if (c1 < 0xC2) {1698return codecvt_base::error;1699} else if (c1 < 0xE0) {1700if (frm_end - frm_nxt < 2)1701return codecvt_base::partial;1702uint8_t c2 = frm_nxt[1];1703if ((c2 & 0xC0) != 0x80)1704return codecvt_base::error;1705uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));1706if (t > Maxcode)1707return codecvt_base::error;1708*to_nxt = t;1709frm_nxt += 2;1710} else if (c1 < 0xF0) {1711if (frm_end - frm_nxt < 2)1712return codecvt_base::partial;1713uint8_t c2 = frm_nxt[1];1714switch (c1) {1715case 0xE0:1716if ((c2 & 0xE0) != 0xA0)1717return codecvt_base::error;1718break;1719case 0xED:1720if ((c2 & 0xE0) != 0x80)1721return codecvt_base::error;1722break;1723default:1724if ((c2 & 0xC0) != 0x80)1725return codecvt_base::error;1726break;1727}1728if (frm_end - frm_nxt < 3)1729return codecvt_base::partial;1730uint8_t c3 = frm_nxt[2];1731if ((c3 & 0xC0) != 0x80)1732return codecvt_base::error;1733uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));1734if (t > Maxcode)1735return codecvt_base::error;1736*to_nxt = t;1737frm_nxt += 3;1738} else if (c1 < 0xF5) {1739if (frm_end - frm_nxt < 2)1740return codecvt_base::partial;1741uint8_t c2 = frm_nxt[1];1742switch (c1) {1743case 0xF0:1744if (!(0x90 <= c2 && c2 <= 0xBF))1745return codecvt_base::error;1746break;1747case 0xF4:1748if ((c2 & 0xF0) != 0x80)1749return codecvt_base::error;1750break;1751default:1752if ((c2 & 0xC0) != 0x80)1753return codecvt_base::error;1754break;1755}1756if (frm_end - frm_nxt < 3)1757return codecvt_base::partial;1758uint8_t c3 = frm_nxt[2];1759if ((c3 & 0xC0) != 0x80)1760return codecvt_base::error;1761if (frm_end - frm_nxt < 4)1762return codecvt_base::partial;1763uint8_t c4 = frm_nxt[3];1764if ((c4 & 0xC0) != 0x80)1765return codecvt_base::error;1766if (to_end - to_nxt < 2)1767return codecvt_base::partial;1768if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)1769return codecvt_base::error;1770*to_nxt = static_cast<uint16_t>(17710xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));1772*++to_nxt = static_cast<uint16_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));1773frm_nxt += 4;1774} else {1775return codecvt_base::error;1776}1777}1778return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;1779}17801781static codecvt_base::result utf8_to_utf16(1782const uint8_t* frm,1783const uint8_t* frm_end,1784const uint8_t*& frm_nxt,1785uint32_t* to,1786uint32_t* to_end,1787uint32_t*& to_nxt,1788unsigned long Maxcode = 0x10FFFF,1789codecvt_mode mode = codecvt_mode(0)) {1790frm_nxt = frm;1791to_nxt = to;1792if (mode & consume_header) {1793if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1794frm_nxt += 3;1795}1796for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {1797uint8_t c1 = *frm_nxt;1798if (c1 > Maxcode)1799return codecvt_base::error;1800if (c1 < 0x80) {1801*to_nxt = static_cast<uint32_t>(c1);1802++frm_nxt;1803} else if (c1 < 0xC2) {1804return codecvt_base::error;1805} else if (c1 < 0xE0) {1806if (frm_end - frm_nxt < 2)1807return codecvt_base::partial;1808uint8_t c2 = frm_nxt[1];1809if ((c2 & 0xC0) != 0x80)1810return codecvt_base::error;1811uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));1812if (t > Maxcode)1813return codecvt_base::error;1814*to_nxt = static_cast<uint32_t>(t);1815frm_nxt += 2;1816} else if (c1 < 0xF0) {1817if (frm_end - frm_nxt < 2)1818return codecvt_base::partial;1819uint8_t c2 = frm_nxt[1];1820switch (c1) {1821case 0xE0:1822if ((c2 & 0xE0) != 0xA0)1823return codecvt_base::error;1824break;1825case 0xED:1826if ((c2 & 0xE0) != 0x80)1827return codecvt_base::error;1828break;1829default:1830if ((c2 & 0xC0) != 0x80)1831return codecvt_base::error;1832break;1833}1834if (frm_end - frm_nxt < 3)1835return codecvt_base::partial;1836uint8_t c3 = frm_nxt[2];1837if ((c3 & 0xC0) != 0x80)1838return codecvt_base::error;1839uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));1840if (t > Maxcode)1841return codecvt_base::error;1842*to_nxt = static_cast<uint32_t>(t);1843frm_nxt += 3;1844} else if (c1 < 0xF5) {1845if (frm_end - frm_nxt < 2)1846return codecvt_base::partial;1847uint8_t c2 = frm_nxt[1];1848switch (c1) {1849case 0xF0:1850if (!(0x90 <= c2 && c2 <= 0xBF))1851return codecvt_base::error;1852break;1853case 0xF4:1854if ((c2 & 0xF0) != 0x80)1855return codecvt_base::error;1856break;1857default:1858if ((c2 & 0xC0) != 0x80)1859return codecvt_base::error;1860break;1861}1862if (frm_end - frm_nxt < 3)1863return codecvt_base::partial;1864uint8_t c3 = frm_nxt[2];1865if ((c3 & 0xC0) != 0x80)1866return codecvt_base::error;1867if (frm_end - frm_nxt < 4)1868return codecvt_base::partial;1869uint8_t c4 = frm_nxt[3];1870if ((c4 & 0xC0) != 0x80)1871return codecvt_base::error;1872if (to_end - to_nxt < 2)1873return codecvt_base::partial;1874if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)1875return codecvt_base::error;1876*to_nxt = static_cast<uint32_t>(18770xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));1878*++to_nxt = static_cast<uint32_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));1879frm_nxt += 4;1880} else {1881return codecvt_base::error;1882}1883}1884return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;1885}18861887static int utf8_to_utf16_length(1888const uint8_t* frm,1889const uint8_t* frm_end,1890size_t mx,1891unsigned long Maxcode = 0x10FFFF,1892codecvt_mode mode = codecvt_mode(0)) {1893const uint8_t* frm_nxt = frm;1894if (mode & consume_header) {1895if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1896frm_nxt += 3;1897}1898for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) {1899uint8_t c1 = *frm_nxt;1900if (c1 > Maxcode)1901break;1902if (c1 < 0x80) {1903++frm_nxt;1904} else if (c1 < 0xC2) {1905break;1906} else if (c1 < 0xE0) {1907if ((frm_end - frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)1908break;1909uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));1910if (t > Maxcode)1911break;1912frm_nxt += 2;1913} else if (c1 < 0xF0) {1914if (frm_end - frm_nxt < 3)1915break;1916uint8_t c2 = frm_nxt[1];1917uint8_t c3 = frm_nxt[2];1918switch (c1) {1919case 0xE0:1920if ((c2 & 0xE0) != 0xA0)1921return static_cast<int>(frm_nxt - frm);1922break;1923case 0xED:1924if ((c2 & 0xE0) != 0x80)1925return static_cast<int>(frm_nxt - frm);1926break;1927default:1928if ((c2 & 0xC0) != 0x80)1929return static_cast<int>(frm_nxt - frm);1930break;1931}1932if ((c3 & 0xC0) != 0x80)1933break;1934if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)1935break;1936frm_nxt += 3;1937} else if (c1 < 0xF5) {1938if (frm_end - frm_nxt < 4 || mx - nchar16_t < 2)1939break;1940uint8_t c2 = frm_nxt[1];1941uint8_t c3 = frm_nxt[2];1942uint8_t c4 = frm_nxt[3];1943switch (c1) {1944case 0xF0:1945if (!(0x90 <= c2 && c2 <= 0xBF))1946return static_cast<int>(frm_nxt - frm);1947break;1948case 0xF4:1949if ((c2 & 0xF0) != 0x80)1950return static_cast<int>(frm_nxt - frm);1951break;1952default:1953if ((c2 & 0xC0) != 0x80)1954return static_cast<int>(frm_nxt - frm);1955break;1956}1957if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)1958break;1959if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)1960break;1961++nchar16_t;1962frm_nxt += 4;1963} else {1964break;1965}1966}1967return static_cast<int>(frm_nxt - frm);1968}19691970static codecvt_base::result ucs4_to_utf8(1971const uint32_t* frm,1972const uint32_t* frm_end,1973const uint32_t*& frm_nxt,1974uint8_t* to,1975uint8_t* to_end,1976uint8_t*& to_nxt,1977unsigned long Maxcode = 0x10FFFF,1978codecvt_mode mode = codecvt_mode(0)) {1979frm_nxt = frm;1980to_nxt = to;1981if (mode & generate_header) {1982if (to_end - to_nxt < 3)1983return codecvt_base::partial;1984*to_nxt++ = static_cast<uint8_t>(0xEF);1985*to_nxt++ = static_cast<uint8_t>(0xBB);1986*to_nxt++ = static_cast<uint8_t>(0xBF);1987}1988for (; frm_nxt < frm_end; ++frm_nxt) {1989uint32_t wc = *frm_nxt;1990if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)1991return codecvt_base::error;1992if (wc < 0x000080) {1993if (to_end - to_nxt < 1)1994return codecvt_base::partial;1995*to_nxt++ = static_cast<uint8_t>(wc);1996} else if (wc < 0x000800) {1997if (to_end - to_nxt < 2)1998return codecvt_base::partial;1999*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));2000*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));2001} else if (wc < 0x010000) {2002if (to_end - to_nxt < 3)2003return codecvt_base::partial;2004*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));2005*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));2006*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));2007} else // if (wc < 0x110000)2008{2009if (to_end - to_nxt < 4)2010return codecvt_base::partial;2011*to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));2012*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));2013*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));2014*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));2015}2016}2017return codecvt_base::ok;2018}20192020static codecvt_base::result utf8_to_ucs4(2021const uint8_t* frm,2022const uint8_t* frm_end,2023const uint8_t*& frm_nxt,2024uint32_t* to,2025uint32_t* to_end,2026uint32_t*& to_nxt,2027unsigned long Maxcode = 0x10FFFF,2028codecvt_mode mode = codecvt_mode(0)) {2029frm_nxt = frm;2030to_nxt = to;2031if (mode & consume_header) {2032if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2033frm_nxt += 3;2034}2035for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {2036uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2037if (c1 < 0x80) {2038if (c1 > Maxcode)2039return codecvt_base::error;2040*to_nxt = static_cast<uint32_t>(c1);2041++frm_nxt;2042} else if (c1 < 0xC2) {2043return codecvt_base::error;2044} else if (c1 < 0xE0) {2045if (frm_end - frm_nxt < 2)2046return codecvt_base::partial;2047uint8_t c2 = frm_nxt[1];2048if ((c2 & 0xC0) != 0x80)2049return codecvt_base::error;2050uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));2051if (t > Maxcode)2052return codecvt_base::error;2053*to_nxt = t;2054frm_nxt += 2;2055} else if (c1 < 0xF0) {2056if (frm_end - frm_nxt < 2)2057return codecvt_base::partial;2058uint8_t c2 = frm_nxt[1];2059switch (c1) {2060case 0xE0:2061if ((c2 & 0xE0) != 0xA0)2062return codecvt_base::error;2063break;2064case 0xED:2065if ((c2 & 0xE0) != 0x80)2066return codecvt_base::error;2067break;2068default:2069if ((c2 & 0xC0) != 0x80)2070return codecvt_base::error;2071break;2072}2073if (frm_end - frm_nxt < 3)2074return codecvt_base::partial;2075uint8_t c3 = frm_nxt[2];2076if ((c3 & 0xC0) != 0x80)2077return codecvt_base::error;2078uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));2079if (t > Maxcode)2080return codecvt_base::error;2081*to_nxt = t;2082frm_nxt += 3;2083} else if (c1 < 0xF5) {2084if (frm_end - frm_nxt < 2)2085return codecvt_base::partial;2086uint8_t c2 = frm_nxt[1];2087switch (c1) {2088case 0xF0:2089if (!(0x90 <= c2 && c2 <= 0xBF))2090return codecvt_base::error;2091break;2092case 0xF4:2093if ((c2 & 0xF0) != 0x80)2094return codecvt_base::error;2095break;2096default:2097if ((c2 & 0xC0) != 0x80)2098return codecvt_base::error;2099break;2100}2101if (frm_end - frm_nxt < 3)2102return codecvt_base::partial;2103uint8_t c3 = frm_nxt[2];2104if ((c3 & 0xC0) != 0x80)2105return codecvt_base::error;2106if (frm_end - frm_nxt < 4)2107return codecvt_base::partial;2108uint8_t c4 = frm_nxt[3];2109if ((c4 & 0xC0) != 0x80)2110return codecvt_base::error;2111uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) | ((c3 & 0x3F) << 6) | (c4 & 0x3F));2112if (t > Maxcode)2113return codecvt_base::error;2114*to_nxt = t;2115frm_nxt += 4;2116} else {2117return codecvt_base::error;2118}2119}2120return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2121}21222123static int utf8_to_ucs4_length(2124const uint8_t* frm,2125const uint8_t* frm_end,2126size_t mx,2127unsigned long Maxcode = 0x10FFFF,2128codecvt_mode mode = codecvt_mode(0)) {2129const uint8_t* frm_nxt = frm;2130if (mode & consume_header) {2131if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2132frm_nxt += 3;2133}2134for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) {2135uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2136if (c1 < 0x80) {2137if (c1 > Maxcode)2138break;2139++frm_nxt;2140} else if (c1 < 0xC2) {2141break;2142} else if (c1 < 0xE0) {2143if ((frm_end - frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))2144break;2145if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)2146break;2147frm_nxt += 2;2148} else if (c1 < 0xF0) {2149if (frm_end - frm_nxt < 3)2150break;2151uint8_t c2 = frm_nxt[1];2152uint8_t c3 = frm_nxt[2];2153switch (c1) {2154case 0xE0:2155if ((c2 & 0xE0) != 0xA0)2156return static_cast<int>(frm_nxt - frm);2157break;2158case 0xED:2159if ((c2 & 0xE0) != 0x80)2160return static_cast<int>(frm_nxt - frm);2161break;2162default:2163if ((c2 & 0xC0) != 0x80)2164return static_cast<int>(frm_nxt - frm);2165break;2166}2167if ((c3 & 0xC0) != 0x80)2168break;2169if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)2170break;2171frm_nxt += 3;2172} else if (c1 < 0xF5) {2173if (frm_end - frm_nxt < 4)2174break;2175uint8_t c2 = frm_nxt[1];2176uint8_t c3 = frm_nxt[2];2177uint8_t c4 = frm_nxt[3];2178switch (c1) {2179case 0xF0:2180if (!(0x90 <= c2 && c2 <= 0xBF))2181return static_cast<int>(frm_nxt - frm);2182break;2183case 0xF4:2184if ((c2 & 0xF0) != 0x80)2185return static_cast<int>(frm_nxt - frm);2186break;2187default:2188if ((c2 & 0xC0) != 0x80)2189return static_cast<int>(frm_nxt - frm);2190break;2191}2192if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)2193break;2194if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)2195break;2196frm_nxt += 4;2197} else {2198break;2199}2200}2201return static_cast<int>(frm_nxt - frm);2202}22032204static codecvt_base::result ucs2_to_utf8(2205const uint16_t* frm,2206const uint16_t* frm_end,2207const uint16_t*& frm_nxt,2208uint8_t* to,2209uint8_t* to_end,2210uint8_t*& to_nxt,2211unsigned long Maxcode = 0x10FFFF,2212codecvt_mode mode = codecvt_mode(0)) {2213frm_nxt = frm;2214to_nxt = to;2215if (mode & generate_header) {2216if (to_end - to_nxt < 3)2217return codecvt_base::partial;2218*to_nxt++ = static_cast<uint8_t>(0xEF);2219*to_nxt++ = static_cast<uint8_t>(0xBB);2220*to_nxt++ = static_cast<uint8_t>(0xBF);2221}2222for (; frm_nxt < frm_end; ++frm_nxt) {2223uint16_t wc = *frm_nxt;2224if ((wc & 0xF800) == 0xD800 || wc > Maxcode)2225return codecvt_base::error;2226if (wc < 0x0080) {2227if (to_end - to_nxt < 1)2228return codecvt_base::partial;2229*to_nxt++ = static_cast<uint8_t>(wc);2230} else if (wc < 0x0800) {2231if (to_end - to_nxt < 2)2232return codecvt_base::partial;2233*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));2234*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));2235} else // if (wc <= 0xFFFF)2236{2237if (to_end - to_nxt < 3)2238return codecvt_base::partial;2239*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));2240*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));2241*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));2242}2243}2244return codecvt_base::ok;2245}22462247static codecvt_base::result utf8_to_ucs2(2248const uint8_t* frm,2249const uint8_t* frm_end,2250const uint8_t*& frm_nxt,2251uint16_t* to,2252uint16_t* to_end,2253uint16_t*& to_nxt,2254unsigned long Maxcode = 0x10FFFF,2255codecvt_mode mode = codecvt_mode(0)) {2256frm_nxt = frm;2257to_nxt = to;2258if (mode & consume_header) {2259if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2260frm_nxt += 3;2261}2262for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {2263uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2264if (c1 < 0x80) {2265if (c1 > Maxcode)2266return codecvt_base::error;2267*to_nxt = static_cast<uint16_t>(c1);2268++frm_nxt;2269} else if (c1 < 0xC2) {2270return codecvt_base::error;2271} else if (c1 < 0xE0) {2272if (frm_end - frm_nxt < 2)2273return codecvt_base::partial;2274uint8_t c2 = frm_nxt[1];2275if ((c2 & 0xC0) != 0x80)2276return codecvt_base::error;2277uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));2278if (t > Maxcode)2279return codecvt_base::error;2280*to_nxt = t;2281frm_nxt += 2;2282} else if (c1 < 0xF0) {2283if (frm_end - frm_nxt < 2)2284return codecvt_base::partial;2285uint8_t c2 = frm_nxt[1];2286switch (c1) {2287case 0xE0:2288if ((c2 & 0xE0) != 0xA0)2289return codecvt_base::error;2290break;2291case 0xED:2292if ((c2 & 0xE0) != 0x80)2293return codecvt_base::error;2294break;2295default:2296if ((c2 & 0xC0) != 0x80)2297return codecvt_base::error;2298break;2299}2300if (frm_end - frm_nxt < 3)2301return codecvt_base::partial;2302uint8_t c3 = frm_nxt[2];2303if ((c3 & 0xC0) != 0x80)2304return codecvt_base::error;2305uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));2306if (t > Maxcode)2307return codecvt_base::error;2308*to_nxt = t;2309frm_nxt += 3;2310} else {2311return codecvt_base::error;2312}2313}2314return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2315}23162317static int utf8_to_ucs2_length(2318const uint8_t* frm,2319const uint8_t* frm_end,2320size_t mx,2321unsigned long Maxcode = 0x10FFFF,2322codecvt_mode mode = codecvt_mode(0)) {2323const uint8_t* frm_nxt = frm;2324if (mode & consume_header) {2325if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2326frm_nxt += 3;2327}2328for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) {2329uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2330if (c1 < 0x80) {2331if (c1 > Maxcode)2332break;2333++frm_nxt;2334} else if (c1 < 0xC2) {2335break;2336} else if (c1 < 0xE0) {2337if ((frm_end - frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))2338break;2339if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)2340break;2341frm_nxt += 2;2342} else if (c1 < 0xF0) {2343if (frm_end - frm_nxt < 3)2344break;2345uint8_t c2 = frm_nxt[1];2346uint8_t c3 = frm_nxt[2];2347switch (c1) {2348case 0xE0:2349if ((c2 & 0xE0) != 0xA0)2350return static_cast<int>(frm_nxt - frm);2351break;2352case 0xED:2353if ((c2 & 0xE0) != 0x80)2354return static_cast<int>(frm_nxt - frm);2355break;2356default:2357if ((c2 & 0xC0) != 0x80)2358return static_cast<int>(frm_nxt - frm);2359break;2360}2361if ((c3 & 0xC0) != 0x80)2362break;2363if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)2364break;2365frm_nxt += 3;2366} else {2367break;2368}2369}2370return static_cast<int>(frm_nxt - frm);2371}23722373static codecvt_base::result ucs4_to_utf16be(2374const uint32_t* frm,2375const uint32_t* frm_end,2376const uint32_t*& frm_nxt,2377uint8_t* to,2378uint8_t* to_end,2379uint8_t*& to_nxt,2380unsigned long Maxcode = 0x10FFFF,2381codecvt_mode mode = codecvt_mode(0)) {2382frm_nxt = frm;2383to_nxt = to;2384if (mode & generate_header) {2385if (to_end - to_nxt < 2)2386return codecvt_base::partial;2387*to_nxt++ = static_cast<uint8_t>(0xFE);2388*to_nxt++ = static_cast<uint8_t>(0xFF);2389}2390for (; frm_nxt < frm_end; ++frm_nxt) {2391uint32_t wc = *frm_nxt;2392if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)2393return codecvt_base::error;2394if (wc < 0x010000) {2395if (to_end - to_nxt < 2)2396return codecvt_base::partial;2397*to_nxt++ = static_cast<uint8_t>(wc >> 8);2398*to_nxt++ = static_cast<uint8_t>(wc);2399} else {2400if (to_end - to_nxt < 4)2401return codecvt_base::partial;2402uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));2403*to_nxt++ = static_cast<uint8_t>(t >> 8);2404*to_nxt++ = static_cast<uint8_t>(t);2405t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));2406*to_nxt++ = static_cast<uint8_t>(t >> 8);2407*to_nxt++ = static_cast<uint8_t>(t);2408}2409}2410return codecvt_base::ok;2411}24122413static codecvt_base::result utf16be_to_ucs4(2414const uint8_t* frm,2415const uint8_t* frm_end,2416const uint8_t*& frm_nxt,2417uint32_t* to,2418uint32_t* to_end,2419uint32_t*& to_nxt,2420unsigned long Maxcode = 0x10FFFF,2421codecvt_mode mode = codecvt_mode(0)) {2422frm_nxt = frm;2423to_nxt = to;2424if (mode & consume_header) {2425if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2426frm_nxt += 2;2427}2428for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2429uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2430if ((c1 & 0xFC00) == 0xDC00)2431return codecvt_base::error;2432if ((c1 & 0xFC00) != 0xD800) {2433if (c1 > Maxcode)2434return codecvt_base::error;2435*to_nxt = static_cast<uint32_t>(c1);2436frm_nxt += 2;2437} else {2438if (frm_end - frm_nxt < 4)2439return codecvt_base::partial;2440uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);2441if ((c2 & 0xFC00) != 0xDC00)2442return codecvt_base::error;2443uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2444if (t > Maxcode)2445return codecvt_base::error;2446*to_nxt = t;2447frm_nxt += 4;2448}2449}2450return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2451}24522453static int utf16be_to_ucs4_length(2454const uint8_t* frm,2455const uint8_t* frm_end,2456size_t mx,2457unsigned long Maxcode = 0x10FFFF,2458codecvt_mode mode = codecvt_mode(0)) {2459const uint8_t* frm_nxt = frm;2460if (mode & consume_header) {2461if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2462frm_nxt += 2;2463}2464for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) {2465uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2466if ((c1 & 0xFC00) == 0xDC00)2467break;2468if ((c1 & 0xFC00) != 0xD800) {2469if (c1 > Maxcode)2470break;2471frm_nxt += 2;2472} else {2473if (frm_end - frm_nxt < 4)2474break;2475uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);2476if ((c2 & 0xFC00) != 0xDC00)2477break;2478uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2479if (t > Maxcode)2480break;2481frm_nxt += 4;2482}2483}2484return static_cast<int>(frm_nxt - frm);2485}24862487static codecvt_base::result ucs4_to_utf16le(2488const uint32_t* frm,2489const uint32_t* frm_end,2490const uint32_t*& frm_nxt,2491uint8_t* to,2492uint8_t* to_end,2493uint8_t*& to_nxt,2494unsigned long Maxcode = 0x10FFFF,2495codecvt_mode mode = codecvt_mode(0)) {2496frm_nxt = frm;2497to_nxt = to;2498if (mode & generate_header) {2499if (to_end - to_nxt < 2)2500return codecvt_base::partial;2501*to_nxt++ = static_cast<uint8_t>(0xFF);2502*to_nxt++ = static_cast<uint8_t>(0xFE);2503}2504for (; frm_nxt < frm_end; ++frm_nxt) {2505uint32_t wc = *frm_nxt;2506if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)2507return codecvt_base::error;2508if (wc < 0x010000) {2509if (to_end - to_nxt < 2)2510return codecvt_base::partial;2511*to_nxt++ = static_cast<uint8_t>(wc);2512*to_nxt++ = static_cast<uint8_t>(wc >> 8);2513} else {2514if (to_end - to_nxt < 4)2515return codecvt_base::partial;2516uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));2517*to_nxt++ = static_cast<uint8_t>(t);2518*to_nxt++ = static_cast<uint8_t>(t >> 8);2519t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));2520*to_nxt++ = static_cast<uint8_t>(t);2521*to_nxt++ = static_cast<uint8_t>(t >> 8);2522}2523}2524return codecvt_base::ok;2525}25262527static codecvt_base::result utf16le_to_ucs4(2528const uint8_t* frm,2529const uint8_t* frm_end,2530const uint8_t*& frm_nxt,2531uint32_t* to,2532uint32_t* to_end,2533uint32_t*& to_nxt,2534unsigned long Maxcode = 0x10FFFF,2535codecvt_mode mode = codecvt_mode(0)) {2536frm_nxt = frm;2537to_nxt = to;2538if (mode & consume_header) {2539if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2540frm_nxt += 2;2541}2542for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2543uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2544if ((c1 & 0xFC00) == 0xDC00)2545return codecvt_base::error;2546if ((c1 & 0xFC00) != 0xD800) {2547if (c1 > Maxcode)2548return codecvt_base::error;2549*to_nxt = static_cast<uint32_t>(c1);2550frm_nxt += 2;2551} else {2552if (frm_end - frm_nxt < 4)2553return codecvt_base::partial;2554uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);2555if ((c2 & 0xFC00) != 0xDC00)2556return codecvt_base::error;2557uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2558if (t > Maxcode)2559return codecvt_base::error;2560*to_nxt = t;2561frm_nxt += 4;2562}2563}2564return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2565}25662567static int utf16le_to_ucs4_length(2568const uint8_t* frm,2569const uint8_t* frm_end,2570size_t mx,2571unsigned long Maxcode = 0x10FFFF,2572codecvt_mode mode = codecvt_mode(0)) {2573const uint8_t* frm_nxt = frm;2574if (mode & consume_header) {2575if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2576frm_nxt += 2;2577}2578for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) {2579uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2580if ((c1 & 0xFC00) == 0xDC00)2581break;2582if ((c1 & 0xFC00) != 0xD800) {2583if (c1 > Maxcode)2584break;2585frm_nxt += 2;2586} else {2587if (frm_end - frm_nxt < 4)2588break;2589uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);2590if ((c2 & 0xFC00) != 0xDC00)2591break;2592uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2593if (t > Maxcode)2594break;2595frm_nxt += 4;2596}2597}2598return static_cast<int>(frm_nxt - frm);2599}26002601static codecvt_base::result ucs2_to_utf16be(2602const uint16_t* frm,2603const uint16_t* frm_end,2604const uint16_t*& frm_nxt,2605uint8_t* to,2606uint8_t* to_end,2607uint8_t*& to_nxt,2608unsigned long Maxcode = 0x10FFFF,2609codecvt_mode mode = codecvt_mode(0)) {2610frm_nxt = frm;2611to_nxt = to;2612if (mode & generate_header) {2613if (to_end - to_nxt < 2)2614return codecvt_base::partial;2615*to_nxt++ = static_cast<uint8_t>(0xFE);2616*to_nxt++ = static_cast<uint8_t>(0xFF);2617}2618for (; frm_nxt < frm_end; ++frm_nxt) {2619uint16_t wc = *frm_nxt;2620if ((wc & 0xF800) == 0xD800 || wc > Maxcode)2621return codecvt_base::error;2622if (to_end - to_nxt < 2)2623return codecvt_base::partial;2624*to_nxt++ = static_cast<uint8_t>(wc >> 8);2625*to_nxt++ = static_cast<uint8_t>(wc);2626}2627return codecvt_base::ok;2628}26292630static codecvt_base::result utf16be_to_ucs2(2631const uint8_t* frm,2632const uint8_t* frm_end,2633const uint8_t*& frm_nxt,2634uint16_t* to,2635uint16_t* to_end,2636uint16_t*& to_nxt,2637unsigned long Maxcode = 0x10FFFF,2638codecvt_mode mode = codecvt_mode(0)) {2639frm_nxt = frm;2640to_nxt = to;2641if (mode & consume_header) {2642if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2643frm_nxt += 2;2644}2645for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2646uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2647if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2648return codecvt_base::error;2649*to_nxt = c1;2650frm_nxt += 2;2651}2652return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2653}26542655static int utf16be_to_ucs2_length(2656const uint8_t* frm,2657const uint8_t* frm_end,2658size_t mx,2659unsigned long Maxcode = 0x10FFFF,2660codecvt_mode mode = codecvt_mode(0)) {2661const uint8_t* frm_nxt = frm;2662if (mode & consume_header) {2663if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2664frm_nxt += 2;2665}2666for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) {2667uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2668if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2669break;2670frm_nxt += 2;2671}2672return static_cast<int>(frm_nxt - frm);2673}26742675static codecvt_base::result ucs2_to_utf16le(2676const uint16_t* frm,2677const uint16_t* frm_end,2678const uint16_t*& frm_nxt,2679uint8_t* to,2680uint8_t* to_end,2681uint8_t*& to_nxt,2682unsigned long Maxcode = 0x10FFFF,2683codecvt_mode mode = codecvt_mode(0)) {2684frm_nxt = frm;2685to_nxt = to;2686if (mode & generate_header) {2687if (to_end - to_nxt < 2)2688return codecvt_base::partial;2689*to_nxt++ = static_cast<uint8_t>(0xFF);2690*to_nxt++ = static_cast<uint8_t>(0xFE);2691}2692for (; frm_nxt < frm_end; ++frm_nxt) {2693uint16_t wc = *frm_nxt;2694if ((wc & 0xF800) == 0xD800 || wc > Maxcode)2695return codecvt_base::error;2696if (to_end - to_nxt < 2)2697return codecvt_base::partial;2698*to_nxt++ = static_cast<uint8_t>(wc);2699*to_nxt++ = static_cast<uint8_t>(wc >> 8);2700}2701return codecvt_base::ok;2702}27032704static codecvt_base::result utf16le_to_ucs2(2705const uint8_t* frm,2706const uint8_t* frm_end,2707const uint8_t*& frm_nxt,2708uint16_t* to,2709uint16_t* to_end,2710uint16_t*& to_nxt,2711unsigned long Maxcode = 0x10FFFF,2712codecvt_mode mode = codecvt_mode(0)) {2713frm_nxt = frm;2714to_nxt = to;2715if (mode & consume_header) {2716if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2717frm_nxt += 2;2718}2719for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2720uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2721if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2722return codecvt_base::error;2723*to_nxt = c1;2724frm_nxt += 2;2725}2726return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2727}27282729static int utf16le_to_ucs2_length(2730const uint8_t* frm,2731const uint8_t* frm_end,2732size_t mx,2733unsigned long Maxcode = 0x10FFFF,2734codecvt_mode mode = codecvt_mode(0)) {2735const uint8_t* frm_nxt = frm;2736frm_nxt = frm;2737if (mode & consume_header) {2738if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2739frm_nxt += 2;2740}2741for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) {2742uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2743if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2744break;2745frm_nxt += 2;2746}2747return static_cast<int>(frm_nxt - frm);2748}27492750_LIBCPP_SUPPRESS_DEPRECATED_POP27512752// template <> class codecvt<char16_t, char, mbstate_t>27532754constinit locale::id codecvt<char16_t, char, mbstate_t>::id;27552756codecvt<char16_t, char, mbstate_t>::~codecvt() {}27572758codecvt<char16_t, char, mbstate_t>::result codecvt<char16_t, char, mbstate_t>::do_out(2759state_type&,2760const intern_type* frm,2761const intern_type* frm_end,2762const intern_type*& frm_nxt,2763extern_type* to,2764extern_type* to_end,2765extern_type*& to_nxt) const {2766const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);2767const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);2768const uint16_t* _frm_nxt = _frm;2769uint8_t* _to = reinterpret_cast<uint8_t*>(to);2770uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);2771uint8_t* _to_nxt = _to;2772result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2773frm_nxt = frm + (_frm_nxt - _frm);2774to_nxt = to + (_to_nxt - _to);2775return r;2776}27772778codecvt<char16_t, char, mbstate_t>::result codecvt<char16_t, char, mbstate_t>::do_in(2779state_type&,2780const extern_type* frm,2781const extern_type* frm_end,2782const extern_type*& frm_nxt,2783intern_type* to,2784intern_type* to_end,2785intern_type*& to_nxt) const {2786const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2787const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2788const uint8_t* _frm_nxt = _frm;2789uint16_t* _to = reinterpret_cast<uint16_t*>(to);2790uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);2791uint16_t* _to_nxt = _to;2792result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2793frm_nxt = frm + (_frm_nxt - _frm);2794to_nxt = to + (_to_nxt - _to);2795return r;2796}27972798codecvt<char16_t, char, mbstate_t>::result2799codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2800to_nxt = to;2801return noconv;2802}28032804int codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept { return 0; }28052806bool codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }28072808int codecvt<char16_t, char, mbstate_t>::do_length(2809state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2810const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2811const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2812return utf8_to_utf16_length(_frm, _frm_end, mx);2813}28142815int codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept { return 4; }28162817#ifndef _LIBCPP_HAS_NO_CHAR8_T28182819// template <> class codecvt<char16_t, char8_t, mbstate_t>28202821constinit locale::id codecvt<char16_t, char8_t, mbstate_t>::id;28222823codecvt<char16_t, char8_t, mbstate_t>::~codecvt() {}28242825codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_out(2826state_type&,2827const intern_type* frm,2828const intern_type* frm_end,2829const intern_type*& frm_nxt,2830extern_type* to,2831extern_type* to_end,2832extern_type*& to_nxt) const {2833const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);2834const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);2835const uint16_t* _frm_nxt = _frm;2836uint8_t* _to = reinterpret_cast<uint8_t*>(to);2837uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);2838uint8_t* _to_nxt = _to;2839result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2840frm_nxt = frm + (_frm_nxt - _frm);2841to_nxt = to + (_to_nxt - _to);2842return r;2843}28442845codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_in(2846state_type&,2847const extern_type* frm,2848const extern_type* frm_end,2849const extern_type*& frm_nxt,2850intern_type* to,2851intern_type* to_end,2852intern_type*& to_nxt) const {2853const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2854const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2855const uint8_t* _frm_nxt = _frm;2856uint16_t* _to = reinterpret_cast<uint16_t*>(to);2857uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);2858uint16_t* _to_nxt = _to;2859result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2860frm_nxt = frm + (_frm_nxt - _frm);2861to_nxt = to + (_to_nxt - _to);2862return r;2863}28642865codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_unshift(2866state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2867to_nxt = to;2868return noconv;2869}28702871int codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept { return 0; }28722873bool codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept { return false; }28742875int codecvt<char16_t, char8_t, mbstate_t>::do_length(2876state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2877const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2878const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2879return utf8_to_utf16_length(_frm, _frm_end, mx);2880}28812882int codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept { return 4; }28832884#endif28852886// template <> class codecvt<char32_t, char, mbstate_t>28872888constinit locale::id codecvt<char32_t, char, mbstate_t>::id;28892890codecvt<char32_t, char, mbstate_t>::~codecvt() {}28912892codecvt<char32_t, char, mbstate_t>::result codecvt<char32_t, char, mbstate_t>::do_out(2893state_type&,2894const intern_type* frm,2895const intern_type* frm_end,2896const intern_type*& frm_nxt,2897extern_type* to,2898extern_type* to_end,2899extern_type*& to_nxt) const {2900const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);2901const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);2902const uint32_t* _frm_nxt = _frm;2903uint8_t* _to = reinterpret_cast<uint8_t*>(to);2904uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);2905uint8_t* _to_nxt = _to;2906result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2907frm_nxt = frm + (_frm_nxt - _frm);2908to_nxt = to + (_to_nxt - _to);2909return r;2910}29112912codecvt<char32_t, char, mbstate_t>::result codecvt<char32_t, char, mbstate_t>::do_in(2913state_type&,2914const extern_type* frm,2915const extern_type* frm_end,2916const extern_type*& frm_nxt,2917intern_type* to,2918intern_type* to_end,2919intern_type*& to_nxt) const {2920const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2921const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2922const uint8_t* _frm_nxt = _frm;2923uint32_t* _to = reinterpret_cast<uint32_t*>(to);2924uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);2925uint32_t* _to_nxt = _to;2926result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2927frm_nxt = frm + (_frm_nxt - _frm);2928to_nxt = to + (_to_nxt - _to);2929return r;2930}29312932codecvt<char32_t, char, mbstate_t>::result2933codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2934to_nxt = to;2935return noconv;2936}29372938int codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept { return 0; }29392940bool codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }29412942int codecvt<char32_t, char, mbstate_t>::do_length(2943state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2944const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2945const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2946return utf8_to_ucs4_length(_frm, _frm_end, mx);2947}29482949int codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept { return 4; }29502951#ifndef _LIBCPP_HAS_NO_CHAR8_T29522953// template <> class codecvt<char32_t, char8_t, mbstate_t>29542955constinit locale::id codecvt<char32_t, char8_t, mbstate_t>::id;29562957codecvt<char32_t, char8_t, mbstate_t>::~codecvt() {}29582959codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_out(2960state_type&,2961const intern_type* frm,2962const intern_type* frm_end,2963const intern_type*& frm_nxt,2964extern_type* to,2965extern_type* to_end,2966extern_type*& to_nxt) const {2967const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);2968const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);2969const uint32_t* _frm_nxt = _frm;2970uint8_t* _to = reinterpret_cast<uint8_t*>(to);2971uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);2972uint8_t* _to_nxt = _to;2973result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2974frm_nxt = frm + (_frm_nxt - _frm);2975to_nxt = to + (_to_nxt - _to);2976return r;2977}29782979codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_in(2980state_type&,2981const extern_type* frm,2982const extern_type* frm_end,2983const extern_type*& frm_nxt,2984intern_type* to,2985intern_type* to_end,2986intern_type*& to_nxt) const {2987const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);2988const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2989const uint8_t* _frm_nxt = _frm;2990uint32_t* _to = reinterpret_cast<uint32_t*>(to);2991uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);2992uint32_t* _to_nxt = _to;2993result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2994frm_nxt = frm + (_frm_nxt - _frm);2995to_nxt = to + (_to_nxt - _to);2996return r;2997}29982999codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_unshift(3000state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3001to_nxt = to;3002return noconv;3003}30043005int codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept { return 0; }30063007bool codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept { return false; }30083009int codecvt<char32_t, char8_t, mbstate_t>::do_length(3010state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3011const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3012const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3013return utf8_to_ucs4_length(_frm, _frm_end, mx);3014}30153016int codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept { return 4; }30173018#endif30193020// __codecvt_utf8<wchar_t>30213022#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3023__codecvt_utf8<wchar_t>::result __codecvt_utf8<wchar_t>::do_out(3024state_type&,3025const intern_type* frm,3026const intern_type* frm_end,3027const intern_type*& frm_nxt,3028extern_type* to,3029extern_type* to_end,3030extern_type*& to_nxt) const {3031# if defined(_LIBCPP_SHORT_WCHAR)3032const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3033const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3034const uint16_t* _frm_nxt = _frm;3035# else3036const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3037const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3038const uint32_t* _frm_nxt = _frm;3039# endif3040uint8_t* _to = reinterpret_cast<uint8_t*>(to);3041uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3042uint8_t* _to_nxt = _to;3043# if defined(_LIBCPP_SHORT_WCHAR)3044result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3045# else3046result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3047# endif3048frm_nxt = frm + (_frm_nxt - _frm);3049to_nxt = to + (_to_nxt - _to);3050return r;3051}30523053__codecvt_utf8<wchar_t>::result __codecvt_utf8<wchar_t>::do_in(3054state_type&,3055const extern_type* frm,3056const extern_type* frm_end,3057const extern_type*& frm_nxt,3058intern_type* to,3059intern_type* to_end,3060intern_type*& to_nxt) const {3061const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3062const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3063const uint8_t* _frm_nxt = _frm;3064# if defined(_LIBCPP_SHORT_WCHAR)3065uint16_t* _to = reinterpret_cast<uint16_t*>(to);3066uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3067uint16_t* _to_nxt = _to;3068result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3069# else3070uint32_t* _to = reinterpret_cast<uint32_t*>(to);3071uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3072uint32_t* _to_nxt = _to;3073result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3074# endif3075frm_nxt = frm + (_frm_nxt - _frm);3076to_nxt = to + (_to_nxt - _to);3077return r;3078}30793080__codecvt_utf8<wchar_t>::result3081__codecvt_utf8<wchar_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3082to_nxt = to;3083return noconv;3084}30853086int __codecvt_utf8<wchar_t>::do_encoding() const noexcept { return 0; }30873088bool __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept { return false; }30893090int __codecvt_utf8<wchar_t>::do_length(3091state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3092const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3093const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3094# if defined(_LIBCPP_SHORT_WCHAR)3095return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3096# else3097return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3098# endif3099}31003101_LIBCPP_SUPPRESS_DEPRECATED_PUSH3102int __codecvt_utf8<wchar_t>::do_max_length() const noexcept {3103# if defined(_LIBCPP_SHORT_WCHAR)3104if (__mode_ & consume_header)3105return 6;3106return 3;3107# else3108if (__mode_ & consume_header)3109return 7;3110return 4;3111# endif3112}3113#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS31143115// __codecvt_utf8<char16_t>31163117__codecvt_utf8<char16_t>::result __codecvt_utf8<char16_t>::do_out(3118state_type&,3119const intern_type* frm,3120const intern_type* frm_end,3121const intern_type*& frm_nxt,3122extern_type* to,3123extern_type* to_end,3124extern_type*& to_nxt) const {3125const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3126const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3127const uint16_t* _frm_nxt = _frm;3128uint8_t* _to = reinterpret_cast<uint8_t*>(to);3129uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3130uint8_t* _to_nxt = _to;3131result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3132frm_nxt = frm + (_frm_nxt - _frm);3133to_nxt = to + (_to_nxt - _to);3134return r;3135}31363137__codecvt_utf8<char16_t>::result __codecvt_utf8<char16_t>::do_in(3138state_type&,3139const extern_type* frm,3140const extern_type* frm_end,3141const extern_type*& frm_nxt,3142intern_type* to,3143intern_type* to_end,3144intern_type*& to_nxt) const {3145const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3146const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3147const uint8_t* _frm_nxt = _frm;3148uint16_t* _to = reinterpret_cast<uint16_t*>(to);3149uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3150uint16_t* _to_nxt = _to;3151result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3152frm_nxt = frm + (_frm_nxt - _frm);3153to_nxt = to + (_to_nxt - _to);3154return r;3155}31563157__codecvt_utf8<char16_t>::result3158__codecvt_utf8<char16_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3159to_nxt = to;3160return noconv;3161}31623163int __codecvt_utf8<char16_t>::do_encoding() const noexcept { return 0; }31643165bool __codecvt_utf8<char16_t>::do_always_noconv() const noexcept { return false; }31663167int __codecvt_utf8<char16_t>::do_length(3168state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3169const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3170const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3171return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3172}31733174_LIBCPP_SUPPRESS_DEPRECATED_PUSH3175int __codecvt_utf8<char16_t>::do_max_length() const noexcept {3176if (__mode_ & consume_header)3177return 6;3178return 3;3179}3180_LIBCPP_SUPPRESS_DEPRECATED_POP31813182// __codecvt_utf8<char32_t>31833184__codecvt_utf8<char32_t>::result __codecvt_utf8<char32_t>::do_out(3185state_type&,3186const intern_type* frm,3187const intern_type* frm_end,3188const intern_type*& frm_nxt,3189extern_type* to,3190extern_type* to_end,3191extern_type*& to_nxt) const {3192const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3193const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3194const uint32_t* _frm_nxt = _frm;3195uint8_t* _to = reinterpret_cast<uint8_t*>(to);3196uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3197uint8_t* _to_nxt = _to;3198result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3199frm_nxt = frm + (_frm_nxt - _frm);3200to_nxt = to + (_to_nxt - _to);3201return r;3202}32033204__codecvt_utf8<char32_t>::result __codecvt_utf8<char32_t>::do_in(3205state_type&,3206const extern_type* frm,3207const extern_type* frm_end,3208const extern_type*& frm_nxt,3209intern_type* to,3210intern_type* to_end,3211intern_type*& to_nxt) const {3212const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3213const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3214const uint8_t* _frm_nxt = _frm;3215uint32_t* _to = reinterpret_cast<uint32_t*>(to);3216uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3217uint32_t* _to_nxt = _to;3218result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3219frm_nxt = frm + (_frm_nxt - _frm);3220to_nxt = to + (_to_nxt - _to);3221return r;3222}32233224__codecvt_utf8<char32_t>::result3225__codecvt_utf8<char32_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3226to_nxt = to;3227return noconv;3228}32293230int __codecvt_utf8<char32_t>::do_encoding() const noexcept { return 0; }32313232bool __codecvt_utf8<char32_t>::do_always_noconv() const noexcept { return false; }32333234int __codecvt_utf8<char32_t>::do_length(3235state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3236const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3237const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3238return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3239}32403241_LIBCPP_SUPPRESS_DEPRECATED_PUSH3242int __codecvt_utf8<char32_t>::do_max_length() const noexcept {3243if (__mode_ & consume_header)3244return 7;3245return 4;3246}3247_LIBCPP_SUPPRESS_DEPRECATED_POP32483249// __codecvt_utf16<wchar_t, false>32503251#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3252__codecvt_utf16<wchar_t, false>::result __codecvt_utf16<wchar_t, false>::do_out(3253state_type&,3254const intern_type* frm,3255const intern_type* frm_end,3256const intern_type*& frm_nxt,3257extern_type* to,3258extern_type* to_end,3259extern_type*& to_nxt) const {3260# if defined(_LIBCPP_SHORT_WCHAR)3261const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3262const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3263const uint16_t* _frm_nxt = _frm;3264# else3265const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3266const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3267const uint32_t* _frm_nxt = _frm;3268# endif3269uint8_t* _to = reinterpret_cast<uint8_t*>(to);3270uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3271uint8_t* _to_nxt = _to;3272# if defined(_LIBCPP_SHORT_WCHAR)3273result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3274# else3275result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3276# endif3277frm_nxt = frm + (_frm_nxt - _frm);3278to_nxt = to + (_to_nxt - _to);3279return r;3280}32813282__codecvt_utf16<wchar_t, false>::result __codecvt_utf16<wchar_t, false>::do_in(3283state_type&,3284const extern_type* frm,3285const extern_type* frm_end,3286const extern_type*& frm_nxt,3287intern_type* to,3288intern_type* to_end,3289intern_type*& to_nxt) const {3290const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3291const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3292const uint8_t* _frm_nxt = _frm;3293# if defined(_LIBCPP_SHORT_WCHAR)3294uint16_t* _to = reinterpret_cast<uint16_t*>(to);3295uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3296uint16_t* _to_nxt = _to;3297result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3298# else3299uint32_t* _to = reinterpret_cast<uint32_t*>(to);3300uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3301uint32_t* _to_nxt = _to;3302result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3303# endif3304frm_nxt = frm + (_frm_nxt - _frm);3305to_nxt = to + (_to_nxt - _to);3306return r;3307}33083309__codecvt_utf16<wchar_t, false>::result3310__codecvt_utf16<wchar_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3311to_nxt = to;3312return noconv;3313}33143315int __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept { return 0; }33163317bool __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept { return false; }33183319int __codecvt_utf16<wchar_t, false>::do_length(3320state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3321const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3322const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3323# if defined(_LIBCPP_SHORT_WCHAR)3324return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3325# else3326return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3327# endif3328}33293330int __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept {3331# if defined(_LIBCPP_SHORT_WCHAR)3332if (__mode_ & consume_header)3333return 4;3334return 2;3335# else3336if (__mode_ & consume_header)3337return 6;3338return 4;3339# endif3340}33413342// __codecvt_utf16<wchar_t, true>33433344__codecvt_utf16<wchar_t, true>::result __codecvt_utf16<wchar_t, true>::do_out(3345state_type&,3346const intern_type* frm,3347const intern_type* frm_end,3348const intern_type*& frm_nxt,3349extern_type* to,3350extern_type* to_end,3351extern_type*& to_nxt) const {3352# if defined(_LIBCPP_SHORT_WCHAR)3353const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3354const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3355const uint16_t* _frm_nxt = _frm;3356# else3357const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3358const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3359const uint32_t* _frm_nxt = _frm;3360# endif3361uint8_t* _to = reinterpret_cast<uint8_t*>(to);3362uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3363uint8_t* _to_nxt = _to;3364# if defined(_LIBCPP_SHORT_WCHAR)3365result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3366# else3367result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3368# endif3369frm_nxt = frm + (_frm_nxt - _frm);3370to_nxt = to + (_to_nxt - _to);3371return r;3372}33733374__codecvt_utf16<wchar_t, true>::result __codecvt_utf16<wchar_t, true>::do_in(3375state_type&,3376const extern_type* frm,3377const extern_type* frm_end,3378const extern_type*& frm_nxt,3379intern_type* to,3380intern_type* to_end,3381intern_type*& to_nxt) const {3382const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3383const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3384const uint8_t* _frm_nxt = _frm;3385# if defined(_LIBCPP_SHORT_WCHAR)3386uint16_t* _to = reinterpret_cast<uint16_t*>(to);3387uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3388uint16_t* _to_nxt = _to;3389result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3390# else3391uint32_t* _to = reinterpret_cast<uint32_t*>(to);3392uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3393uint32_t* _to_nxt = _to;3394result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3395# endif3396frm_nxt = frm + (_frm_nxt - _frm);3397to_nxt = to + (_to_nxt - _to);3398return r;3399}34003401__codecvt_utf16<wchar_t, true>::result3402__codecvt_utf16<wchar_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3403to_nxt = to;3404return noconv;3405}34063407int __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept { return 0; }34083409bool __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept { return false; }34103411int __codecvt_utf16<wchar_t, true>::do_length(3412state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3413const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3414const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3415# if defined(_LIBCPP_SHORT_WCHAR)3416return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3417# else3418return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3419# endif3420}34213422int __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept {3423# if defined(_LIBCPP_SHORT_WCHAR)3424if (__mode_ & consume_header)3425return 4;3426return 2;3427# else3428if (__mode_ & consume_header)3429return 6;3430return 4;3431# endif3432}3433#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS34343435// __codecvt_utf16<char16_t, false>34363437__codecvt_utf16<char16_t, false>::result __codecvt_utf16<char16_t, false>::do_out(3438state_type&,3439const intern_type* frm,3440const intern_type* frm_end,3441const intern_type*& frm_nxt,3442extern_type* to,3443extern_type* to_end,3444extern_type*& to_nxt) const {3445const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3446const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3447const uint16_t* _frm_nxt = _frm;3448uint8_t* _to = reinterpret_cast<uint8_t*>(to);3449uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3450uint8_t* _to_nxt = _to;3451result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3452frm_nxt = frm + (_frm_nxt - _frm);3453to_nxt = to + (_to_nxt - _to);3454return r;3455}34563457__codecvt_utf16<char16_t, false>::result __codecvt_utf16<char16_t, false>::do_in(3458state_type&,3459const extern_type* frm,3460const extern_type* frm_end,3461const extern_type*& frm_nxt,3462intern_type* to,3463intern_type* to_end,3464intern_type*& to_nxt) const {3465const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3466const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3467const uint8_t* _frm_nxt = _frm;3468uint16_t* _to = reinterpret_cast<uint16_t*>(to);3469uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3470uint16_t* _to_nxt = _to;3471result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3472frm_nxt = frm + (_frm_nxt - _frm);3473to_nxt = to + (_to_nxt - _to);3474return r;3475}34763477__codecvt_utf16<char16_t, false>::result3478__codecvt_utf16<char16_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3479to_nxt = to;3480return noconv;3481}34823483int __codecvt_utf16<char16_t, false>::do_encoding() const noexcept { return 0; }34843485bool __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept { return false; }34863487int __codecvt_utf16<char16_t, false>::do_length(3488state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3489const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3490const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3491return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3492}34933494_LIBCPP_SUPPRESS_DEPRECATED_PUSH3495int __codecvt_utf16<char16_t, false>::do_max_length() const noexcept {3496if (__mode_ & consume_header)3497return 4;3498return 2;3499}3500_LIBCPP_SUPPRESS_DEPRECATED_POP35013502// __codecvt_utf16<char16_t, true>35033504__codecvt_utf16<char16_t, true>::result __codecvt_utf16<char16_t, true>::do_out(3505state_type&,3506const intern_type* frm,3507const intern_type* frm_end,3508const intern_type*& frm_nxt,3509extern_type* to,3510extern_type* to_end,3511extern_type*& to_nxt) const {3512const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3513const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3514const uint16_t* _frm_nxt = _frm;3515uint8_t* _to = reinterpret_cast<uint8_t*>(to);3516uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3517uint8_t* _to_nxt = _to;3518result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3519frm_nxt = frm + (_frm_nxt - _frm);3520to_nxt = to + (_to_nxt - _to);3521return r;3522}35233524__codecvt_utf16<char16_t, true>::result __codecvt_utf16<char16_t, true>::do_in(3525state_type&,3526const extern_type* frm,3527const extern_type* frm_end,3528const extern_type*& frm_nxt,3529intern_type* to,3530intern_type* to_end,3531intern_type*& to_nxt) const {3532const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3533const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3534const uint8_t* _frm_nxt = _frm;3535uint16_t* _to = reinterpret_cast<uint16_t*>(to);3536uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3537uint16_t* _to_nxt = _to;3538result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3539frm_nxt = frm + (_frm_nxt - _frm);3540to_nxt = to + (_to_nxt - _to);3541return r;3542}35433544__codecvt_utf16<char16_t, true>::result3545__codecvt_utf16<char16_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3546to_nxt = to;3547return noconv;3548}35493550int __codecvt_utf16<char16_t, true>::do_encoding() const noexcept { return 0; }35513552bool __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept { return false; }35533554int __codecvt_utf16<char16_t, true>::do_length(3555state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3556const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3557const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3558return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3559}35603561_LIBCPP_SUPPRESS_DEPRECATED_PUSH3562int __codecvt_utf16<char16_t, true>::do_max_length() const noexcept {3563if (__mode_ & consume_header)3564return 4;3565return 2;3566}3567_LIBCPP_SUPPRESS_DEPRECATED_POP35683569// __codecvt_utf16<char32_t, false>35703571__codecvt_utf16<char32_t, false>::result __codecvt_utf16<char32_t, false>::do_out(3572state_type&,3573const intern_type* frm,3574const intern_type* frm_end,3575const intern_type*& frm_nxt,3576extern_type* to,3577extern_type* to_end,3578extern_type*& to_nxt) const {3579const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3580const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3581const uint32_t* _frm_nxt = _frm;3582uint8_t* _to = reinterpret_cast<uint8_t*>(to);3583uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3584uint8_t* _to_nxt = _to;3585result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3586frm_nxt = frm + (_frm_nxt - _frm);3587to_nxt = to + (_to_nxt - _to);3588return r;3589}35903591__codecvt_utf16<char32_t, false>::result __codecvt_utf16<char32_t, false>::do_in(3592state_type&,3593const extern_type* frm,3594const extern_type* frm_end,3595const extern_type*& frm_nxt,3596intern_type* to,3597intern_type* to_end,3598intern_type*& to_nxt) const {3599const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3600const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3601const uint8_t* _frm_nxt = _frm;3602uint32_t* _to = reinterpret_cast<uint32_t*>(to);3603uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3604uint32_t* _to_nxt = _to;3605result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3606frm_nxt = frm + (_frm_nxt - _frm);3607to_nxt = to + (_to_nxt - _to);3608return r;3609}36103611__codecvt_utf16<char32_t, false>::result3612__codecvt_utf16<char32_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3613to_nxt = to;3614return noconv;3615}36163617int __codecvt_utf16<char32_t, false>::do_encoding() const noexcept { return 0; }36183619bool __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept { return false; }36203621int __codecvt_utf16<char32_t, false>::do_length(3622state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3623const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3624const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3625return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3626}36273628_LIBCPP_SUPPRESS_DEPRECATED_PUSH3629int __codecvt_utf16<char32_t, false>::do_max_length() const noexcept {3630if (__mode_ & consume_header)3631return 6;3632return 4;3633}3634_LIBCPP_SUPPRESS_DEPRECATED_POP36353636// __codecvt_utf16<char32_t, true>36373638__codecvt_utf16<char32_t, true>::result __codecvt_utf16<char32_t, true>::do_out(3639state_type&,3640const intern_type* frm,3641const intern_type* frm_end,3642const intern_type*& frm_nxt,3643extern_type* to,3644extern_type* to_end,3645extern_type*& to_nxt) const {3646const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3647const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3648const uint32_t* _frm_nxt = _frm;3649uint8_t* _to = reinterpret_cast<uint8_t*>(to);3650uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3651uint8_t* _to_nxt = _to;3652result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3653frm_nxt = frm + (_frm_nxt - _frm);3654to_nxt = to + (_to_nxt - _to);3655return r;3656}36573658__codecvt_utf16<char32_t, true>::result __codecvt_utf16<char32_t, true>::do_in(3659state_type&,3660const extern_type* frm,3661const extern_type* frm_end,3662const extern_type*& frm_nxt,3663intern_type* to,3664intern_type* to_end,3665intern_type*& to_nxt) const {3666const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3667const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3668const uint8_t* _frm_nxt = _frm;3669uint32_t* _to = reinterpret_cast<uint32_t*>(to);3670uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3671uint32_t* _to_nxt = _to;3672result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3673frm_nxt = frm + (_frm_nxt - _frm);3674to_nxt = to + (_to_nxt - _to);3675return r;3676}36773678__codecvt_utf16<char32_t, true>::result3679__codecvt_utf16<char32_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3680to_nxt = to;3681return noconv;3682}36833684int __codecvt_utf16<char32_t, true>::do_encoding() const noexcept { return 0; }36853686bool __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept { return false; }36873688int __codecvt_utf16<char32_t, true>::do_length(3689state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3690const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3691const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3692return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3693}36943695_LIBCPP_SUPPRESS_DEPRECATED_PUSH3696int __codecvt_utf16<char32_t, true>::do_max_length() const noexcept {3697if (__mode_ & consume_header)3698return 6;3699return 4;3700}3701_LIBCPP_SUPPRESS_DEPRECATED_POP37023703// __codecvt_utf8_utf16<wchar_t>37043705#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3706__codecvt_utf8_utf16<wchar_t>::result __codecvt_utf8_utf16<wchar_t>::do_out(3707state_type&,3708const intern_type* frm,3709const intern_type* frm_end,3710const intern_type*& frm_nxt,3711extern_type* to,3712extern_type* to_end,3713extern_type*& to_nxt) const {3714# if defined(_LIBCPP_SHORT_WCHAR)3715const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3716const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3717const uint16_t* _frm_nxt = _frm;3718# else3719const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3720const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3721const uint32_t* _frm_nxt = _frm;3722# endif3723uint8_t* _to = reinterpret_cast<uint8_t*>(to);3724uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3725uint8_t* _to_nxt = _to;3726result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3727frm_nxt = frm + (_frm_nxt - _frm);3728to_nxt = to + (_to_nxt - _to);3729return r;3730}37313732__codecvt_utf8_utf16<wchar_t>::result __codecvt_utf8_utf16<wchar_t>::do_in(3733state_type&,3734const extern_type* frm,3735const extern_type* frm_end,3736const extern_type*& frm_nxt,3737intern_type* to,3738intern_type* to_end,3739intern_type*& to_nxt) const {3740const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3741const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3742const uint8_t* _frm_nxt = _frm;3743# if defined(_LIBCPP_SHORT_WCHAR)3744uint16_t* _to = reinterpret_cast<uint16_t*>(to);3745uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3746uint16_t* _to_nxt = _to;3747# else3748uint32_t* _to = reinterpret_cast<uint32_t*>(to);3749uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3750uint32_t* _to_nxt = _to;3751# endif3752result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3753frm_nxt = frm + (_frm_nxt - _frm);3754to_nxt = to + (_to_nxt - _to);3755return r;3756}37573758__codecvt_utf8_utf16<wchar_t>::result3759__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3760to_nxt = to;3761return noconv;3762}37633764int __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept { return 0; }37653766bool __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept { return false; }37673768int __codecvt_utf8_utf16<wchar_t>::do_length(3769state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3770const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3771const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3772return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);3773}37743775int __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept {3776if (__mode_ & consume_header)3777return 7;3778return 4;3779}3780#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS37813782// __codecvt_utf8_utf16<char16_t>37833784__codecvt_utf8_utf16<char16_t>::result __codecvt_utf8_utf16<char16_t>::do_out(3785state_type&,3786const intern_type* frm,3787const intern_type* frm_end,3788const intern_type*& frm_nxt,3789extern_type* to,3790extern_type* to_end,3791extern_type*& to_nxt) const {3792const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);3793const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3794const uint16_t* _frm_nxt = _frm;3795uint8_t* _to = reinterpret_cast<uint8_t*>(to);3796uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3797uint8_t* _to_nxt = _to;3798result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3799frm_nxt = frm + (_frm_nxt - _frm);3800to_nxt = to + (_to_nxt - _to);3801return r;3802}38033804__codecvt_utf8_utf16<char16_t>::result __codecvt_utf8_utf16<char16_t>::do_in(3805state_type&,3806const extern_type* frm,3807const extern_type* frm_end,3808const extern_type*& frm_nxt,3809intern_type* to,3810intern_type* to_end,3811intern_type*& to_nxt) const {3812const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3813const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3814const uint8_t* _frm_nxt = _frm;3815uint16_t* _to = reinterpret_cast<uint16_t*>(to);3816uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3817uint16_t* _to_nxt = _to;3818result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3819frm_nxt = frm + (_frm_nxt - _frm);3820to_nxt = to + (_to_nxt - _to);3821return r;3822}38233824__codecvt_utf8_utf16<char16_t>::result3825__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3826to_nxt = to;3827return noconv;3828}38293830int __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept { return 0; }38313832bool __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept { return false; }38333834int __codecvt_utf8_utf16<char16_t>::do_length(3835state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3836const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3837const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3838return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);3839}38403841_LIBCPP_SUPPRESS_DEPRECATED_PUSH3842int __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept {3843if (__mode_ & consume_header)3844return 7;3845return 4;3846}3847_LIBCPP_SUPPRESS_DEPRECATED_POP38483849// __codecvt_utf8_utf16<char32_t>38503851__codecvt_utf8_utf16<char32_t>::result __codecvt_utf8_utf16<char32_t>::do_out(3852state_type&,3853const intern_type* frm,3854const intern_type* frm_end,3855const intern_type*& frm_nxt,3856extern_type* to,3857extern_type* to_end,3858extern_type*& to_nxt) const {3859const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);3860const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3861const uint32_t* _frm_nxt = _frm;3862uint8_t* _to = reinterpret_cast<uint8_t*>(to);3863uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3864uint8_t* _to_nxt = _to;3865result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3866frm_nxt = frm + (_frm_nxt - _frm);3867to_nxt = to + (_to_nxt - _to);3868return r;3869}38703871__codecvt_utf8_utf16<char32_t>::result __codecvt_utf8_utf16<char32_t>::do_in(3872state_type&,3873const extern_type* frm,3874const extern_type* frm_end,3875const extern_type*& frm_nxt,3876intern_type* to,3877intern_type* to_end,3878intern_type*& to_nxt) const {3879const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3880const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3881const uint8_t* _frm_nxt = _frm;3882uint32_t* _to = reinterpret_cast<uint32_t*>(to);3883uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3884uint32_t* _to_nxt = _to;3885result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3886frm_nxt = frm + (_frm_nxt - _frm);3887to_nxt = to + (_to_nxt - _to);3888return r;3889}38903891__codecvt_utf8_utf16<char32_t>::result3892__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3893to_nxt = to;3894return noconv;3895}38963897int __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept { return 0; }38983899bool __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept { return false; }39003901int __codecvt_utf8_utf16<char32_t>::do_length(3902state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3903const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);3904const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3905return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);3906}39073908_LIBCPP_SUPPRESS_DEPRECATED_PUSH3909int __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept {3910if (__mode_ & consume_header)3911return 7;3912return 4;3913}3914_LIBCPP_SUPPRESS_DEPRECATED_POP39153916// __narrow_to_utf8<16>39173918__narrow_to_utf8<16>::~__narrow_to_utf8() {}39193920// __narrow_to_utf8<32>39213922__narrow_to_utf8<32>::~__narrow_to_utf8() {}39233924// __widen_from_utf8<16>39253926__widen_from_utf8<16>::~__widen_from_utf8() {}39273928// __widen_from_utf8<32>39293930__widen_from_utf8<32>::~__widen_from_utf8() {}39313932#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3933static bool checked_string_to_wchar_convert(wchar_t& dest, const char* ptr, locale_t loc) {3934if (*ptr == '\0')3935return false;3936mbstate_t mb = {};3937wchar_t out;3938size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);3939if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {3940return false;3941}3942dest = out;3943return true;3944}3945#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS39463947#ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS3948static bool is_narrow_non_breaking_space(const char* ptr) {3949// https://www.fileformat.info/info/unicode/char/202f/index.htm3950return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';3951}39523953static bool is_non_breaking_space(const char* ptr) {3954// https://www.fileformat.info/info/unicode/char/0a/index.htm3955return ptr[0] == '\xc2' && ptr[1] == '\xa0';3956}3957#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS39583959static bool checked_string_to_char_convert(char& dest, const char* ptr, locale_t __loc) {3960if (*ptr == '\0')3961return false;3962if (!ptr[1]) {3963dest = *ptr;3964return true;3965}39663967#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS3968// First convert the MBS into a wide char then attempt to narrow it using3969// wctob_l.3970wchar_t wout;3971if (!checked_string_to_wchar_convert(wout, ptr, __loc))3972return false;3973int res;3974if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {3975dest = res;3976return true;3977}3978// FIXME: Work around specific multibyte sequences that we can reasonably3979// translate into a different single byte.3980switch (wout) {3981case L'\u202F': // narrow non-breaking space3982case L'\u00A0': // non-breaking space3983dest = ' ';3984return true;3985default:3986return false;3987}3988#else // _LIBCPP_HAS_NO_WIDE_CHARACTERS3989// FIXME: Work around specific multibyte sequences that we can reasonably3990// translate into a different single byte.3991if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {3992dest = ' ';3993return true;3994}39953996return false;3997#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS3998__libcpp_unreachable();3999}40004001// numpunct<char> && numpunct<wchar_t>40024003constinit locale::id numpunct<char>::id;4004#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4005constinit locale::id numpunct<wchar_t>::id;4006#endif40074008numpunct<char>::numpunct(size_t refs) : locale::facet(refs), __decimal_point_('.'), __thousands_sep_(',') {}40094010#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4011numpunct<wchar_t>::numpunct(size_t refs) : locale::facet(refs), __decimal_point_(L'.'), __thousands_sep_(L',') {}4012#endif40134014numpunct<char>::~numpunct() {}40154016#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4017numpunct<wchar_t>::~numpunct() {}4018#endif40194020char numpunct< char >::do_decimal_point() const { return __decimal_point_; }4021#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4022wchar_t numpunct<wchar_t>::do_decimal_point() const { return __decimal_point_; }4023#endif40244025char numpunct< char >::do_thousands_sep() const { return __thousands_sep_; }4026#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4027wchar_t numpunct<wchar_t>::do_thousands_sep() const { return __thousands_sep_; }4028#endif40294030string numpunct< char >::do_grouping() const { return __grouping_; }4031#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4032string numpunct<wchar_t>::do_grouping() const { return __grouping_; }4033#endif40344035string numpunct< char >::do_truename() const { return "true"; }4036#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4037wstring numpunct<wchar_t>::do_truename() const { return L"true"; }4038#endif40394040string numpunct< char >::do_falsename() const { return "false"; }4041#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4042wstring numpunct<wchar_t>::do_falsename() const { return L"false"; }4043#endif40444045// numpunct_byname<char>40464047numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) : numpunct<char>(refs) { __init(nm); }40484049numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) : numpunct<char>(refs) { __init(nm.c_str()); }40504051numpunct_byname<char>::~numpunct_byname() {}40524053void numpunct_byname<char>::__init(const char* nm) {4054typedef numpunct<char> base;4055if (strcmp(nm, "C") != 0) {4056__libcpp_unique_locale loc(nm);4057if (!loc)4058__throw_runtime_error(4059("numpunct_byname<char>::numpunct_byname"4060" failed to construct for " +4061string(nm))4062.c_str());40634064lconv* lc = __libcpp_localeconv_l(loc.get());4065if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point, loc.get()))4066__decimal_point_ = base::do_decimal_point();4067if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep, loc.get()))4068__thousands_sep_ = base::do_thousands_sep();4069__grouping_ = lc->grouping;4070// localization for truename and falsename is not available4071}4072}40734074// numpunct_byname<wchar_t>40754076#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4077numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) : numpunct<wchar_t>(refs) { __init(nm); }40784079numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) : numpunct<wchar_t>(refs) {4080__init(nm.c_str());4081}40824083numpunct_byname<wchar_t>::~numpunct_byname() {}40844085void numpunct_byname<wchar_t>::__init(const char* nm) {4086if (strcmp(nm, "C") != 0) {4087__libcpp_unique_locale loc(nm);4088if (!loc)4089__throw_runtime_error(4090("numpunct_byname<wchar_t>::numpunct_byname"4091" failed to construct for " +4092string(nm))4093.c_str());40944095lconv* lc = __libcpp_localeconv_l(loc.get());4096checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point, loc.get());4097checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep, loc.get());4098__grouping_ = lc->grouping;4099// localization for truename and falsename is not available4100}4101}4102#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS41034104// num_get helpers41054106int __num_get_base::__get_base(ios_base& iob) {4107ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;4108if (__basefield == ios_base::oct)4109return 8;4110else if (__basefield == ios_base::hex)4111return 16;4112else if (__basefield == 0)4113return 0;4114return 10;4115}41164117const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";41184119void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, ios_base::iostate& __err) {4120// if the grouping pattern is empty _or_ there are no grouping bits, then do nothing4121// we always have at least a single entry in [__g, __g_end); the end of the input sequence4122if (__grouping.size() != 0 && __g_end - __g > 1) {4123reverse(__g, __g_end);4124const char* __ig = __grouping.data();4125const char* __eg = __ig + __grouping.size();4126for (unsigned* __r = __g; __r < __g_end - 1; ++__r) {4127if (0 < *__ig && *__ig < numeric_limits<char>::max()) {4128if (static_cast<unsigned>(*__ig) != *__r) {4129__err = ios_base::failbit;4130return;4131}4132}4133if (__eg - __ig > 1)4134++__ig;4135}4136if (0 < *__ig && *__ig < numeric_limits<char>::max()) {4137if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)4138__err = ios_base::failbit;4139}4140}4141}41424143void __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, ios_base::fmtflags __flags) {4144if ((__flags & ios_base::showpos) && (__flags & ios_base::basefield) != ios_base::oct &&4145(__flags & ios_base::basefield) != ios_base::hex && __signd)4146*__fmtp++ = '+';4147if (__flags & ios_base::showbase)4148*__fmtp++ = '#';4149while (*__len)4150*__fmtp++ = *__len++;4151if ((__flags & ios_base::basefield) == ios_base::oct)4152*__fmtp = 'o';4153else if ((__flags & ios_base::basefield) == ios_base::hex) {4154if (__flags & ios_base::uppercase)4155*__fmtp = 'X';4156else4157*__fmtp = 'x';4158} else if (__signd)4159*__fmtp = 'd';4160else4161*__fmtp = 'u';4162}41634164bool __num_put_base::__format_float(char* __fmtp, const char* __len, ios_base::fmtflags __flags) {4165bool specify_precision = true;4166if (__flags & ios_base::showpos)4167*__fmtp++ = '+';4168if (__flags & ios_base::showpoint)4169*__fmtp++ = '#';4170ios_base::fmtflags floatfield = __flags & ios_base::floatfield;4171bool uppercase = (__flags & ios_base::uppercase) != 0;4172if (floatfield == (ios_base::fixed | ios_base::scientific))4173specify_precision = false;4174else {4175*__fmtp++ = '.';4176*__fmtp++ = '*';4177}4178while (*__len)4179*__fmtp++ = *__len++;4180if (floatfield == ios_base::fixed) {4181if (uppercase)4182*__fmtp = 'F';4183else4184*__fmtp = 'f';4185} else if (floatfield == ios_base::scientific) {4186if (uppercase)4187*__fmtp = 'E';4188else4189*__fmtp = 'e';4190} else if (floatfield == (ios_base::fixed | ios_base::scientific)) {4191if (uppercase)4192*__fmtp = 'A';4193else4194*__fmtp = 'a';4195} else {4196if (uppercase)4197*__fmtp = 'G';4198else4199*__fmtp = 'g';4200}4201return specify_precision;4202}42034204char* __num_put_base::__identify_padding(char* __nb, char* __ne, const ios_base& __iob) {4205switch (__iob.flags() & ios_base::adjustfield) {4206case ios_base::internal:4207if (__nb[0] == '-' || __nb[0] == '+')4208return __nb + 1;4209if (__ne - __nb >= 2 && __nb[0] == '0' && (__nb[1] == 'x' || __nb[1] == 'X'))4210return __nb + 2;4211break;4212case ios_base::left:4213return __ne;4214case ios_base::right:4215default:4216break;4217}4218return __nb;4219}42204221// time_get42224223static string* init_weeks() {4224static string weeks[14];4225weeks[0] = "Sunday";4226weeks[1] = "Monday";4227weeks[2] = "Tuesday";4228weeks[3] = "Wednesday";4229weeks[4] = "Thursday";4230weeks[5] = "Friday";4231weeks[6] = "Saturday";4232weeks[7] = "Sun";4233weeks[8] = "Mon";4234weeks[9] = "Tue";4235weeks[10] = "Wed";4236weeks[11] = "Thu";4237weeks[12] = "Fri";4238weeks[13] = "Sat";4239return weeks;4240}42414242#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4243static wstring* init_wweeks() {4244static wstring weeks[14];4245weeks[0] = L"Sunday";4246weeks[1] = L"Monday";4247weeks[2] = L"Tuesday";4248weeks[3] = L"Wednesday";4249weeks[4] = L"Thursday";4250weeks[5] = L"Friday";4251weeks[6] = L"Saturday";4252weeks[7] = L"Sun";4253weeks[8] = L"Mon";4254weeks[9] = L"Tue";4255weeks[10] = L"Wed";4256weeks[11] = L"Thu";4257weeks[12] = L"Fri";4258weeks[13] = L"Sat";4259return weeks;4260}4261#endif42624263template <>4264const string* __time_get_c_storage<char>::__weeks() const {4265static const string* weeks = init_weeks();4266return weeks;4267}42684269#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4270template <>4271const wstring* __time_get_c_storage<wchar_t>::__weeks() const {4272static const wstring* weeks = init_wweeks();4273return weeks;4274}4275#endif42764277static string* init_months() {4278static string months[24];4279months[0] = "January";4280months[1] = "February";4281months[2] = "March";4282months[3] = "April";4283months[4] = "May";4284months[5] = "June";4285months[6] = "July";4286months[7] = "August";4287months[8] = "September";4288months[9] = "October";4289months[10] = "November";4290months[11] = "December";4291months[12] = "Jan";4292months[13] = "Feb";4293months[14] = "Mar";4294months[15] = "Apr";4295months[16] = "May";4296months[17] = "Jun";4297months[18] = "Jul";4298months[19] = "Aug";4299months[20] = "Sep";4300months[21] = "Oct";4301months[22] = "Nov";4302months[23] = "Dec";4303return months;4304}43054306#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4307static wstring* init_wmonths() {4308static wstring months[24];4309months[0] = L"January";4310months[1] = L"February";4311months[2] = L"March";4312months[3] = L"April";4313months[4] = L"May";4314months[5] = L"June";4315months[6] = L"July";4316months[7] = L"August";4317months[8] = L"September";4318months[9] = L"October";4319months[10] = L"November";4320months[11] = L"December";4321months[12] = L"Jan";4322months[13] = L"Feb";4323months[14] = L"Mar";4324months[15] = L"Apr";4325months[16] = L"May";4326months[17] = L"Jun";4327months[18] = L"Jul";4328months[19] = L"Aug";4329months[20] = L"Sep";4330months[21] = L"Oct";4331months[22] = L"Nov";4332months[23] = L"Dec";4333return months;4334}4335#endif43364337template <>4338const string* __time_get_c_storage<char>::__months() const {4339static const string* months = init_months();4340return months;4341}43424343#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4344template <>4345const wstring* __time_get_c_storage<wchar_t>::__months() const {4346static const wstring* months = init_wmonths();4347return months;4348}4349#endif43504351static string* init_am_pm() {4352static string am_pm[2];4353am_pm[0] = "AM";4354am_pm[1] = "PM";4355return am_pm;4356}43574358#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4359static wstring* init_wam_pm() {4360static wstring am_pm[2];4361am_pm[0] = L"AM";4362am_pm[1] = L"PM";4363return am_pm;4364}4365#endif43664367template <>4368const string* __time_get_c_storage<char>::__am_pm() const {4369static const string* am_pm = init_am_pm();4370return am_pm;4371}43724373#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4374template <>4375const wstring* __time_get_c_storage<wchar_t>::__am_pm() const {4376static const wstring* am_pm = init_wam_pm();4377return am_pm;4378}4379#endif43804381template <>4382const string& __time_get_c_storage<char>::__x() const {4383static string s("%m/%d/%y");4384return s;4385}43864387#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4388template <>4389const wstring& __time_get_c_storage<wchar_t>::__x() const {4390static wstring s(L"%m/%d/%y");4391return s;4392}4393#endif43944395template <>4396const string& __time_get_c_storage<char>::__X() const {4397static string s("%H:%M:%S");4398return s;4399}44004401#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4402template <>4403const wstring& __time_get_c_storage<wchar_t>::__X() const {4404static wstring s(L"%H:%M:%S");4405return s;4406}4407#endif44084409template <>4410const string& __time_get_c_storage<char>::__c() const {4411static string s("%a %b %d %H:%M:%S %Y");4412return s;4413}44144415#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4416template <>4417const wstring& __time_get_c_storage<wchar_t>::__c() const {4418static wstring s(L"%a %b %d %H:%M:%S %Y");4419return s;4420}4421#endif44224423template <>4424const string& __time_get_c_storage<char>::__r() const {4425static string s("%I:%M:%S %p");4426return s;4427}44284429#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4430template <>4431const wstring& __time_get_c_storage<wchar_t>::__r() const {4432static wstring s(L"%I:%M:%S %p");4433return s;4434}4435#endif44364437// time_get_byname44384439__time_get::__time_get(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {4440if (__loc_ == 0)4441__throw_runtime_error(("time_get_byname failed to construct for " + string(nm)).c_str());4442}44434444__time_get::__time_get(const string& nm) : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) {4445if (__loc_ == 0)4446__throw_runtime_error(("time_get_byname failed to construct for " + nm).c_str());4447}44484449__time_get::~__time_get() { freelocale(__loc_); }44504451_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")44524453template <>4454string __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) {4455tm t = {0};4456t.tm_sec = 59;4457t.tm_min = 55;4458t.tm_hour = 23;4459t.tm_mday = 31;4460t.tm_mon = 11;4461t.tm_year = 161;4462t.tm_wday = 6;4463t.tm_yday = 364;4464t.tm_isdst = -1;4465char buf[100];4466char f[3] = {0};4467f[0] = '%';4468f[1] = fmt;4469size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);4470char* bb = buf;4471char* be = buf + n;4472string result;4473while (bb != be) {4474if (ct.is(ctype_base::space, *bb)) {4475result.push_back(' ');4476for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)4477;4478continue;4479}4480char* w = bb;4481ios_base::iostate err = ios_base::goodbit;4482ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_ + 14, ct, err, false) - this->__weeks_;4483if (i < 14) {4484result.push_back('%');4485if (i < 7)4486result.push_back('A');4487else4488result.push_back('a');4489bb = w;4490continue;4491}4492w = bb;4493i = __scan_keyword(w, be, this->__months_, this->__months_ + 24, ct, err, false) - this->__months_;4494if (i < 24) {4495result.push_back('%');4496if (i < 12)4497result.push_back('B');4498else4499result.push_back('b');4500if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))4501result.back() = 'm';4502bb = w;4503continue;4504}4505if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) {4506w = bb;4507i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_ + 2, ct, err, false) - this->__am_pm_;4508if (i < 2) {4509result.push_back('%');4510result.push_back('p');4511bb = w;4512continue;4513}4514}4515w = bb;4516if (ct.is(ctype_base::digit, *bb)) {4517switch (__get_up_to_n_digits(bb, be, err, ct, 4)) {4518case 6:4519result.push_back('%');4520result.push_back('w');4521break;4522case 7:4523result.push_back('%');4524result.push_back('u');4525break;4526case 11:4527result.push_back('%');4528result.push_back('I');4529break;4530case 12:4531result.push_back('%');4532result.push_back('m');4533break;4534case 23:4535result.push_back('%');4536result.push_back('H');4537break;4538case 31:4539result.push_back('%');4540result.push_back('d');4541break;4542case 55:4543result.push_back('%');4544result.push_back('M');4545break;4546case 59:4547result.push_back('%');4548result.push_back('S');4549break;4550case 61:4551result.push_back('%');4552result.push_back('y');4553break;4554case 364:4555result.push_back('%');4556result.push_back('j');4557break;4558case 2061:4559result.push_back('%');4560result.push_back('Y');4561break;4562default:4563for (; w != bb; ++w)4564result.push_back(*w);4565break;4566}4567continue;4568}4569if (*bb == '%') {4570result.push_back('%');4571result.push_back('%');4572++bb;4573continue;4574}4575result.push_back(*bb);4576++bb;4577}4578return result;4579}45804581_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")45824583#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4584template <>4585wstring __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) {4586tm t = {0};4587t.tm_sec = 59;4588t.tm_min = 55;4589t.tm_hour = 23;4590t.tm_mday = 31;4591t.tm_mon = 11;4592t.tm_year = 161;4593t.tm_wday = 6;4594t.tm_yday = 364;4595t.tm_isdst = -1;4596char buf[100];4597char f[3] = {0};4598f[0] = '%';4599f[1] = fmt;4600strftime_l(buf, countof(buf), f, &t, __loc_);4601wchar_t wbuf[100];4602wchar_t* wbb = wbuf;4603mbstate_t mb = {0};4604const char* bb = buf;4605size_t j = __libcpp_mbsrtowcs_l(wbb, &bb, countof(wbuf), &mb, __loc_);4606if (j == size_t(-1))4607__throw_runtime_error("locale not supported");4608wchar_t* wbe = wbb + j;4609wstring result;4610while (wbb != wbe) {4611if (ct.is(ctype_base::space, *wbb)) {4612result.push_back(L' ');4613for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)4614;4615continue;4616}4617wchar_t* w = wbb;4618ios_base::iostate err = ios_base::goodbit;4619ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_ + 14, ct, err, false) - this->__weeks_;4620if (i < 14) {4621result.push_back(L'%');4622if (i < 7)4623result.push_back(L'A');4624else4625result.push_back(L'a');4626wbb = w;4627continue;4628}4629w = wbb;4630i = __scan_keyword(w, wbe, this->__months_, this->__months_ + 24, ct, err, false) - this->__months_;4631if (i < 24) {4632result.push_back(L'%');4633if (i < 12)4634result.push_back(L'B');4635else4636result.push_back(L'b');4637if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))4638result.back() = L'm';4639wbb = w;4640continue;4641}4642if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) {4643w = wbb;4644i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_ + 2, ct, err, false) - this->__am_pm_;4645if (i < 2) {4646result.push_back(L'%');4647result.push_back(L'p');4648wbb = w;4649continue;4650}4651}4652w = wbb;4653if (ct.is(ctype_base::digit, *wbb)) {4654switch (__get_up_to_n_digits(wbb, wbe, err, ct, 4)) {4655case 6:4656result.push_back(L'%');4657result.push_back(L'w');4658break;4659case 7:4660result.push_back(L'%');4661result.push_back(L'u');4662break;4663case 11:4664result.push_back(L'%');4665result.push_back(L'I');4666break;4667case 12:4668result.push_back(L'%');4669result.push_back(L'm');4670break;4671case 23:4672result.push_back(L'%');4673result.push_back(L'H');4674break;4675case 31:4676result.push_back(L'%');4677result.push_back(L'd');4678break;4679case 55:4680result.push_back(L'%');4681result.push_back(L'M');4682break;4683case 59:4684result.push_back(L'%');4685result.push_back(L'S');4686break;4687case 61:4688result.push_back(L'%');4689result.push_back(L'y');4690break;4691case 364:4692result.push_back(L'%');4693result.push_back(L'j');4694break;4695case 2061:4696result.push_back(L'%');4697result.push_back(L'Y');4698break;4699default:4700for (; w != wbb; ++w)4701result.push_back(*w);4702break;4703}4704continue;4705}4706if (ct.narrow(*wbb, 0) == '%') {4707result.push_back(L'%');4708result.push_back(L'%');4709++wbb;4710continue;4711}4712result.push_back(*wbb);4713++wbb;4714}4715return result;4716}4717#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS47184719template <>4720void __time_get_storage<char>::init(const ctype<char>& ct) {4721tm t = {0};4722char buf[100];4723// __weeks_4724for (int i = 0; i < 7; ++i) {4725t.tm_wday = i;4726strftime_l(buf, countof(buf), "%A", &t, __loc_);4727__weeks_[i] = buf;4728strftime_l(buf, countof(buf), "%a", &t, __loc_);4729__weeks_[i + 7] = buf;4730}4731// __months_4732for (int i = 0; i < 12; ++i) {4733t.tm_mon = i;4734strftime_l(buf, countof(buf), "%B", &t, __loc_);4735__months_[i] = buf;4736strftime_l(buf, countof(buf), "%b", &t, __loc_);4737__months_[i + 12] = buf;4738}4739// __am_pm_4740t.tm_hour = 1;4741strftime_l(buf, countof(buf), "%p", &t, __loc_);4742__am_pm_[0] = buf;4743t.tm_hour = 13;4744strftime_l(buf, countof(buf), "%p", &t, __loc_);4745__am_pm_[1] = buf;4746__c_ = __analyze('c', ct);4747__r_ = __analyze('r', ct);4748__x_ = __analyze('x', ct);4749__X_ = __analyze('X', ct);4750}47514752#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4753template <>4754void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) {4755tm t = {0};4756char buf[100];4757wchar_t wbuf[100];4758wchar_t* wbe;4759mbstate_t mb = {0};4760// __weeks_4761for (int i = 0; i < 7; ++i) {4762t.tm_wday = i;4763strftime_l(buf, countof(buf), "%A", &t, __loc_);4764mb = mbstate_t();4765const char* bb = buf;4766size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);4767if (j == size_t(-1) || j == 0)4768__throw_runtime_error("locale not supported");4769wbe = wbuf + j;4770__weeks_[i].assign(wbuf, wbe);4771strftime_l(buf, countof(buf), "%a", &t, __loc_);4772mb = mbstate_t();4773bb = buf;4774j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);4775if (j == size_t(-1) || j == 0)4776__throw_runtime_error("locale not supported");4777wbe = wbuf + j;4778__weeks_[i + 7].assign(wbuf, wbe);4779}4780// __months_4781for (int i = 0; i < 12; ++i) {4782t.tm_mon = i;4783strftime_l(buf, countof(buf), "%B", &t, __loc_);4784mb = mbstate_t();4785const char* bb = buf;4786size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);4787if (j == size_t(-1) || j == 0)4788__throw_runtime_error("locale not supported");4789wbe = wbuf + j;4790__months_[i].assign(wbuf, wbe);4791strftime_l(buf, countof(buf), "%b", &t, __loc_);4792mb = mbstate_t();4793bb = buf;4794j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);4795if (j == size_t(-1) || j == 0)4796__throw_runtime_error("locale not supported");4797wbe = wbuf + j;4798__months_[i + 12].assign(wbuf, wbe);4799}4800// __am_pm_4801t.tm_hour = 1;4802strftime_l(buf, countof(buf), "%p", &t, __loc_);4803mb = mbstate_t();4804const char* bb = buf;4805size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);4806if (j == size_t(-1))4807__throw_runtime_error("locale not supported");4808wbe = wbuf + j;4809__am_pm_[0].assign(wbuf, wbe);4810t.tm_hour = 13;4811strftime_l(buf, countof(buf), "%p", &t, __loc_);4812mb = mbstate_t();4813bb = buf;4814j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);4815if (j == size_t(-1))4816__throw_runtime_error("locale not supported");4817wbe = wbuf + j;4818__am_pm_[1].assign(wbuf, wbe);4819__c_ = __analyze('c', ct);4820__r_ = __analyze('r', ct);4821__x_ = __analyze('x', ct);4822__X_ = __analyze('X', ct);4823}4824#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS48254826template <class CharT>4827struct _LIBCPP_HIDDEN __time_get_temp : public ctype_byname<CharT> {4828explicit __time_get_temp(const char* nm) : ctype_byname<CharT>(nm, 1) {}4829explicit __time_get_temp(const string& nm) : ctype_byname<CharT>(nm, 1) {}4830};48314832template <>4833__time_get_storage<char>::__time_get_storage(const char* __nm) : __time_get(__nm) {4834const __time_get_temp<char> ct(__nm);4835init(ct);4836}48374838template <>4839__time_get_storage<char>::__time_get_storage(const string& __nm) : __time_get(__nm) {4840const __time_get_temp<char> ct(__nm);4841init(ct);4842}48434844#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4845template <>4846__time_get_storage<wchar_t>::__time_get_storage(const char* __nm) : __time_get(__nm) {4847const __time_get_temp<wchar_t> ct(__nm);4848init(ct);4849}48504851template <>4852__time_get_storage<wchar_t>::__time_get_storage(const string& __nm) : __time_get(__nm) {4853const __time_get_temp<wchar_t> ct(__nm);4854init(ct);4855}4856#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS48574858template <>4859time_base::dateorder __time_get_storage<char>::__do_date_order() const {4860unsigned i;4861for (i = 0; i < __x_.size(); ++i)4862if (__x_[i] == '%')4863break;4864++i;4865switch (__x_[i]) {4866case 'y':4867case 'Y':4868for (++i; i < __x_.size(); ++i)4869if (__x_[i] == '%')4870break;4871if (i == __x_.size())4872break;4873++i;4874switch (__x_[i]) {4875case 'm':4876for (++i; i < __x_.size(); ++i)4877if (__x_[i] == '%')4878break;4879if (i == __x_.size())4880break;4881++i;4882if (__x_[i] == 'd')4883return time_base::ymd;4884break;4885case 'd':4886for (++i; i < __x_.size(); ++i)4887if (__x_[i] == '%')4888break;4889if (i == __x_.size())4890break;4891++i;4892if (__x_[i] == 'm')4893return time_base::ydm;4894break;4895}4896break;4897case 'm':4898for (++i; i < __x_.size(); ++i)4899if (__x_[i] == '%')4900break;4901if (i == __x_.size())4902break;4903++i;4904if (__x_[i] == 'd') {4905for (++i; i < __x_.size(); ++i)4906if (__x_[i] == '%')4907break;4908if (i == __x_.size())4909break;4910++i;4911if (__x_[i] == 'y' || __x_[i] == 'Y')4912return time_base::mdy;4913break;4914}4915break;4916case 'd':4917for (++i; i < __x_.size(); ++i)4918if (__x_[i] == '%')4919break;4920if (i == __x_.size())4921break;4922++i;4923if (__x_[i] == 'm') {4924for (++i; i < __x_.size(); ++i)4925if (__x_[i] == '%')4926break;4927if (i == __x_.size())4928break;4929++i;4930if (__x_[i] == 'y' || __x_[i] == 'Y')4931return time_base::dmy;4932break;4933}4934break;4935}4936return time_base::no_order;4937}49384939#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS4940template <>4941time_base::dateorder __time_get_storage<wchar_t>::__do_date_order() const {4942unsigned i;4943for (i = 0; i < __x_.size(); ++i)4944if (__x_[i] == L'%')4945break;4946++i;4947switch (__x_[i]) {4948case L'y':4949case L'Y':4950for (++i; i < __x_.size(); ++i)4951if (__x_[i] == L'%')4952break;4953if (i == __x_.size())4954break;4955++i;4956switch (__x_[i]) {4957case L'm':4958for (++i; i < __x_.size(); ++i)4959if (__x_[i] == L'%')4960break;4961if (i == __x_.size())4962break;4963++i;4964if (__x_[i] == L'd')4965return time_base::ymd;4966break;4967case L'd':4968for (++i; i < __x_.size(); ++i)4969if (__x_[i] == L'%')4970break;4971if (i == __x_.size())4972break;4973++i;4974if (__x_[i] == L'm')4975return time_base::ydm;4976break;4977}4978break;4979case L'm':4980for (++i; i < __x_.size(); ++i)4981if (__x_[i] == L'%')4982break;4983if (i == __x_.size())4984break;4985++i;4986if (__x_[i] == L'd') {4987for (++i; i < __x_.size(); ++i)4988if (__x_[i] == L'%')4989break;4990if (i == __x_.size())4991break;4992++i;4993if (__x_[i] == L'y' || __x_[i] == L'Y')4994return time_base::mdy;4995break;4996}4997break;4998case L'd':4999for (++i; i < __x_.size(); ++i)5000if (__x_[i] == L'%')5001break;5002if (i == __x_.size())5003break;5004++i;5005if (__x_[i] == L'm') {5006for (++i; i < __x_.size(); ++i)5007if (__x_[i] == L'%')5008break;5009if (i == __x_.size())5010break;5011++i;5012if (__x_[i] == L'y' || __x_[i] == L'Y')5013return time_base::dmy;5014break;5015}5016break;5017}5018return time_base::no_order;5019}5020#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS50215022// time_put50235024__time_put::__time_put(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {5025if (__loc_ == 0)5026__throw_runtime_error(("time_put_byname failed to construct for " + string(nm)).c_str());5027}50285029__time_put::__time_put(const string& nm) : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) {5030if (__loc_ == 0)5031__throw_runtime_error(("time_put_byname failed to construct for " + nm).c_str());5032}50335034__time_put::~__time_put() {5035if (__loc_ != _LIBCPP_GET_C_LOCALE)5036freelocale(__loc_);5037}50385039void __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const {5040char fmt[] = {'%', __fmt, __mod, 0};5041if (__mod != 0)5042swap(fmt[1], fmt[2]);5043size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);5044__ne = __nb + n;5045}50465047#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS5048void __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const {5049char __nar[100];5050char* __ne = __nar + 100;5051__do_put(__nar, __ne, __tm, __fmt, __mod);5052mbstate_t mb = {0};5053const char* __nb = __nar;5054size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);5055if (j == size_t(-1))5056__throw_runtime_error("locale not supported");5057__we = __wb + j;5058}5059#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS50605061// moneypunct_byname50625063template <class charT>5064static void __init_pat(5065money_base::pattern& pat,5066basic_string<charT>& __curr_symbol_,5067bool intl,5068char cs_precedes,5069char sep_by_space,5070char sign_posn,5071charT space_char) {5072const char sign = static_cast<char>(money_base::sign);5073const char space = static_cast<char>(money_base::space);5074const char none = static_cast<char>(money_base::none);5075const char symbol = static_cast<char>(money_base::symbol);5076const char value = static_cast<char>(money_base::value);5077const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;50785079// Comments on case branches reflect 'C11 7.11.2.1 The localeconv5080// function'. "Space between sign and symbol or value" means that5081// if the sign is adjacent to the symbol, there's a space between5082// them, and otherwise there's a space between the sign and value.5083//5084// C11's localeconv specifies that the fourth character of an5085// international curr_symbol is used to separate the sign and5086// value when sep_by_space says to do so. C++ can't represent5087// that, so we just use a space. When sep_by_space says to5088// separate the symbol and value-or-sign with a space, we rearrange the5089// curr_symbol to put its spacing character on the correct side of5090// the symbol.5091//5092// We also need to avoid adding an extra space between the sign5093// and value when the currency symbol is suppressed (by not5094// setting showbase). We match glibc's strfmon by interpreting5095// sep_by_space==1 as "omit the space when the currency symbol is5096// absent".5097//5098// Users who want to get this right should use ICU instead.50995100switch (cs_precedes) {5101case 0: // value before curr_symbol5102if (symbol_contains_sep) {5103// Move the separator to before the symbol, to place it5104// between the value and symbol.5105rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, __curr_symbol_.end());5106}5107switch (sign_posn) {5108case 0: // Parentheses surround the quantity and currency symbol.5109pat.field[0] = sign;5110pat.field[1] = value;5111pat.field[2] = none; // Any space appears in the symbol.5112pat.field[3] = symbol;5113switch (sep_by_space) {5114case 0: // No space separates the currency symbol and value.5115// This case may have changed between C99 and C11;5116// assume the currency symbol matches the intention.5117case 2: // Space between sign and currency or value.5118// The "sign" is two parentheses, so no space here either.5119return;5120case 1: // Space between currency-and-sign or currency and value.5121if (!symbol_contains_sep) {5122// We insert the space into the symbol instead of5123// setting pat.field[2]=space so that when5124// showbase is not set, the space goes away too.5125__curr_symbol_.insert(0, 1, space_char);5126}5127return;5128default:5129break;5130}5131break;5132case 1: // The sign string precedes the quantity and currency symbol.5133pat.field[0] = sign;5134pat.field[3] = symbol;5135switch (sep_by_space) {5136case 0: // No space separates the currency symbol and value.5137pat.field[1] = value;5138pat.field[2] = none;5139return;5140case 1: // Space between currency-and-sign or currency and value.5141pat.field[1] = value;5142pat.field[2] = none;5143if (!symbol_contains_sep) {5144// We insert the space into the symbol instead of5145// setting pat.field[2]=space so that when5146// showbase is not set, the space goes away too.5147__curr_symbol_.insert(0, 1, space_char);5148}5149return;5150case 2: // Space between sign and currency or value.5151pat.field[1] = space;5152pat.field[2] = value;5153if (symbol_contains_sep) {5154// Remove the separator from the symbol, since it5155// has already appeared after the sign.5156__curr_symbol_.erase(__curr_symbol_.begin());5157}5158return;5159default:5160break;5161}5162break;5163case 2: // The sign string succeeds the quantity and currency symbol.5164pat.field[0] = value;5165pat.field[3] = sign;5166switch (sep_by_space) {5167case 0: // No space separates the currency symbol and value.5168pat.field[1] = none;5169pat.field[2] = symbol;5170return;5171case 1: // Space between currency-and-sign or currency and value.5172if (!symbol_contains_sep) {5173// We insert the space into the symbol instead of5174// setting pat.field[1]=space so that when5175// showbase is not set, the space goes away too.5176__curr_symbol_.insert(0, 1, space_char);5177}5178pat.field[1] = none;5179pat.field[2] = symbol;5180return;5181case 2: // Space between sign and currency or value.5182pat.field[1] = symbol;5183pat.field[2] = space;5184if (symbol_contains_sep) {5185// Remove the separator from the symbol, since it5186// should not be removed if showbase is absent.5187__curr_symbol_.erase(__curr_symbol_.begin());5188}5189return;5190default:5191break;5192}5193break;5194case 3: // The sign string immediately precedes the currency symbol.5195pat.field[0] = value;5196pat.field[3] = symbol;5197switch (sep_by_space) {5198case 0: // No space separates the currency symbol and value.5199pat.field[1] = none;5200pat.field[2] = sign;5201return;5202case 1: // Space between currency-and-sign or currency and value.5203pat.field[1] = space;5204pat.field[2] = sign;5205if (symbol_contains_sep) {5206// Remove the separator from the symbol, since it5207// has already appeared before the sign.5208__curr_symbol_.erase(__curr_symbol_.begin());5209}5210return;5211case 2: // Space between sign and currency or value.5212pat.field[1] = sign;5213pat.field[2] = none;5214if (!symbol_contains_sep) {5215// We insert the space into the symbol instead of5216// setting pat.field[2]=space so that when5217// showbase is not set, the space goes away too.5218__curr_symbol_.insert(0, 1, space_char);5219}5220return;5221default:5222break;5223}5224break;5225case 4: // The sign string immediately succeeds the currency symbol.5226pat.field[0] = value;5227pat.field[3] = sign;5228switch (sep_by_space) {5229case 0: // No space separates the currency symbol and value.5230pat.field[1] = none;5231pat.field[2] = symbol;5232return;5233case 1: // Space between currency-and-sign or currency and value.5234pat.field[1] = none;5235pat.field[2] = symbol;5236if (!symbol_contains_sep) {5237// We insert the space into the symbol instead of5238// setting pat.field[1]=space so that when5239// showbase is not set, the space goes away too.5240__curr_symbol_.insert(0, 1, space_char);5241}5242return;5243case 2: // Space between sign and currency or value.5244pat.field[1] = symbol;5245pat.field[2] = space;5246if (symbol_contains_sep) {5247// Remove the separator from the symbol, since it5248// should not disappear when showbase is absent.5249__curr_symbol_.erase(__curr_symbol_.begin());5250}5251return;5252default:5253break;5254}5255break;5256default:5257break;5258}5259break;5260case 1: // curr_symbol before value5261switch (sign_posn) {5262case 0: // Parentheses surround the quantity and currency symbol.5263pat.field[0] = sign;5264pat.field[1] = symbol;5265pat.field[2] = none; // Any space appears in the symbol.5266pat.field[3] = value;5267switch (sep_by_space) {5268case 0: // No space separates the currency symbol and value.5269// This case may have changed between C99 and C11;5270// assume the currency symbol matches the intention.5271case 2: // Space between sign and currency or value.5272// The "sign" is two parentheses, so no space here either.5273return;5274case 1: // Space between currency-and-sign or currency and value.5275if (!symbol_contains_sep) {5276// We insert the space into the symbol instead of5277// setting pat.field[2]=space so that when5278// showbase is not set, the space goes away too.5279__curr_symbol_.insert(0, 1, space_char);5280}5281return;5282default:5283break;5284}5285break;5286case 1: // The sign string precedes the quantity and currency symbol.5287pat.field[0] = sign;5288pat.field[3] = value;5289switch (sep_by_space) {5290case 0: // No space separates the currency symbol and value.5291pat.field[1] = symbol;5292pat.field[2] = none;5293return;5294case 1: // Space between currency-and-sign or currency and value.5295pat.field[1] = symbol;5296pat.field[2] = none;5297if (!symbol_contains_sep) {5298// We insert the space into the symbol instead of5299// setting pat.field[2]=space so that when5300// showbase is not set, the space goes away too.5301__curr_symbol_.push_back(space_char);5302}5303return;5304case 2: // Space between sign and currency or value.5305pat.field[1] = space;5306pat.field[2] = symbol;5307if (symbol_contains_sep) {5308// Remove the separator from the symbol, since it5309// has already appeared after the sign.5310__curr_symbol_.pop_back();5311}5312return;5313default:5314break;5315}5316break;5317case 2: // The sign string succeeds the quantity and currency symbol.5318pat.field[0] = symbol;5319pat.field[3] = sign;5320switch (sep_by_space) {5321case 0: // No space separates the currency symbol and value.5322pat.field[1] = none;5323pat.field[2] = value;5324return;5325case 1: // Space between currency-and-sign or currency and value.5326pat.field[1] = none;5327pat.field[2] = value;5328if (!symbol_contains_sep) {5329// We insert the space into the symbol instead of5330// setting pat.field[1]=space so that when5331// showbase is not set, the space goes away too.5332__curr_symbol_.push_back(space_char);5333}5334return;5335case 2: // Space between sign and currency or value.5336pat.field[1] = value;5337pat.field[2] = space;5338if (symbol_contains_sep) {5339// Remove the separator from the symbol, since it5340// will appear before the sign.5341__curr_symbol_.pop_back();5342}5343return;5344default:5345break;5346}5347break;5348case 3: // The sign string immediately precedes the currency symbol.5349pat.field[0] = sign;5350pat.field[3] = value;5351switch (sep_by_space) {5352case 0: // No space separates the currency symbol and value.5353pat.field[1] = symbol;5354pat.field[2] = none;5355return;5356case 1: // Space between currency-and-sign or currency and value.5357pat.field[1] = symbol;5358pat.field[2] = none;5359if (!symbol_contains_sep) {5360// We insert the space into the symbol instead of5361// setting pat.field[2]=space so that when5362// showbase is not set, the space goes away too.5363__curr_symbol_.push_back(space_char);5364}5365return;5366case 2: // Space between sign and currency or value.5367pat.field[1] = space;5368pat.field[2] = symbol;5369if (symbol_contains_sep) {5370// Remove the separator from the symbol, since it5371// has already appeared after the sign.5372__curr_symbol_.pop_back();5373}5374return;5375default:5376break;5377}5378break;5379case 4: // The sign string immediately succeeds the currency symbol.5380pat.field[0] = symbol;5381pat.field[3] = value;5382switch (sep_by_space) {5383case 0: // No space separates the currency symbol and value.5384pat.field[1] = sign;5385pat.field[2] = none;5386return;5387case 1: // Space between currency-and-sign or currency and value.5388pat.field[1] = sign;5389pat.field[2] = space;5390if (symbol_contains_sep) {5391// Remove the separator from the symbol, since it5392// should not disappear when showbase is absent.5393__curr_symbol_.pop_back();5394}5395return;5396case 2: // Space between sign and currency or value.5397pat.field[1] = none;5398pat.field[2] = sign;5399if (!symbol_contains_sep) {5400// We insert the space into the symbol instead of5401// setting pat.field[1]=space so that when5402// showbase is not set, the space goes away too.5403__curr_symbol_.push_back(space_char);5404}5405return;5406default:5407break;5408}5409break;5410default:5411break;5412}5413break;5414default:5415break;5416}5417pat.field[0] = symbol;5418pat.field[1] = sign;5419pat.field[2] = none;5420pat.field[3] = value;5421}54225423template <>5424void moneypunct_byname<char, false>::init(const char* nm) {5425typedef moneypunct<char, false> base;5426__libcpp_unique_locale loc(nm);5427if (!loc)5428__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());54295430lconv* lc = __libcpp_localeconv_l(loc.get());5431if (!checked_string_to_char_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5432__decimal_point_ = base::do_decimal_point();5433if (!checked_string_to_char_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5434__thousands_sep_ = base::do_thousands_sep();54355436__grouping_ = lc->mon_grouping;5437__curr_symbol_ = lc->currency_symbol;5438if (lc->frac_digits != CHAR_MAX)5439__frac_digits_ = lc->frac_digits;5440else5441__frac_digits_ = base::do_frac_digits();5442if (lc->p_sign_posn == 0)5443__positive_sign_ = "()";5444else5445__positive_sign_ = lc->positive_sign;5446if (lc->n_sign_posn == 0)5447__negative_sign_ = "()";5448else5449__negative_sign_ = lc->negative_sign;5450// Assume the positive and negative formats will want spaces in5451// the same places in curr_symbol since there's no way to5452// represent anything else.5453string_type __dummy_curr_symbol = __curr_symbol_;5454__init_pat(__pos_format_, __dummy_curr_symbol, false, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');5455__init_pat(__neg_format_, __curr_symbol_, false, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');5456}54575458template <>5459void moneypunct_byname<char, true>::init(const char* nm) {5460typedef moneypunct<char, true> base;5461__libcpp_unique_locale loc(nm);5462if (!loc)5463__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());54645465lconv* lc = __libcpp_localeconv_l(loc.get());5466if (!checked_string_to_char_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5467__decimal_point_ = base::do_decimal_point();5468if (!checked_string_to_char_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5469__thousands_sep_ = base::do_thousands_sep();5470__grouping_ = lc->mon_grouping;5471__curr_symbol_ = lc->int_curr_symbol;5472if (lc->int_frac_digits != CHAR_MAX)5473__frac_digits_ = lc->int_frac_digits;5474else5475__frac_digits_ = base::do_frac_digits();5476#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5477if (lc->p_sign_posn == 0)5478#else // _LIBCPP_MSVCRT5479if (lc->int_p_sign_posn == 0)5480#endif // !_LIBCPP_MSVCRT5481__positive_sign_ = "()";5482else5483__positive_sign_ = lc->positive_sign;5484#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5485if (lc->n_sign_posn == 0)5486#else // _LIBCPP_MSVCRT5487if (lc->int_n_sign_posn == 0)5488#endif // !_LIBCPP_MSVCRT5489__negative_sign_ = "()";5490else5491__negative_sign_ = lc->negative_sign;5492// Assume the positive and negative formats will want spaces in5493// the same places in curr_symbol since there's no way to5494// represent anything else.5495string_type __dummy_curr_symbol = __curr_symbol_;5496#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5497__init_pat(__pos_format_, __dummy_curr_symbol, true, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');5498__init_pat(__neg_format_, __curr_symbol_, true, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');5499#else // _LIBCPP_MSVCRT5500__init_pat(5501__pos_format_,5502__dummy_curr_symbol,5503true,5504lc->int_p_cs_precedes,5505lc->int_p_sep_by_space,5506lc->int_p_sign_posn,5507' ');5508__init_pat(5509__neg_format_, __curr_symbol_, true, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn, ' ');5510#endif // !_LIBCPP_MSVCRT5511}55125513#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS5514template <>5515void moneypunct_byname<wchar_t, false>::init(const char* nm) {5516typedef moneypunct<wchar_t, false> base;5517__libcpp_unique_locale loc(nm);5518if (!loc)5519__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());5520lconv* lc = __libcpp_localeconv_l(loc.get());5521if (!checked_string_to_wchar_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5522__decimal_point_ = base::do_decimal_point();5523if (!checked_string_to_wchar_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5524__thousands_sep_ = base::do_thousands_sep();5525__grouping_ = lc->mon_grouping;5526wchar_t wbuf[100];5527mbstate_t mb = {0};5528const char* bb = lc->currency_symbol;5529size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());5530if (j == size_t(-1))5531__throw_runtime_error("locale not supported");5532wchar_t* wbe = wbuf + j;5533__curr_symbol_.assign(wbuf, wbe);5534if (lc->frac_digits != CHAR_MAX)5535__frac_digits_ = lc->frac_digits;5536else5537__frac_digits_ = base::do_frac_digits();5538if (lc->p_sign_posn == 0)5539__positive_sign_ = L"()";5540else {5541mb = mbstate_t();5542bb = lc->positive_sign;5543j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());5544if (j == size_t(-1))5545__throw_runtime_error("locale not supported");5546wbe = wbuf + j;5547__positive_sign_.assign(wbuf, wbe);5548}5549if (lc->n_sign_posn == 0)5550__negative_sign_ = L"()";5551else {5552mb = mbstate_t();5553bb = lc->negative_sign;5554j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());5555if (j == size_t(-1))5556__throw_runtime_error("locale not supported");5557wbe = wbuf + j;5558__negative_sign_.assign(wbuf, wbe);5559}5560// Assume the positive and negative formats will want spaces in5561// the same places in curr_symbol since there's no way to5562// represent anything else.5563string_type __dummy_curr_symbol = __curr_symbol_;5564__init_pat(__pos_format_, __dummy_curr_symbol, false, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');5565__init_pat(__neg_format_, __curr_symbol_, false, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');5566}55675568template <>5569void moneypunct_byname<wchar_t, true>::init(const char* nm) {5570typedef moneypunct<wchar_t, true> base;5571__libcpp_unique_locale loc(nm);5572if (!loc)5573__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());55745575lconv* lc = __libcpp_localeconv_l(loc.get());5576if (!checked_string_to_wchar_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5577__decimal_point_ = base::do_decimal_point();5578if (!checked_string_to_wchar_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5579__thousands_sep_ = base::do_thousands_sep();5580__grouping_ = lc->mon_grouping;5581wchar_t wbuf[100];5582mbstate_t mb = {0};5583const char* bb = lc->int_curr_symbol;5584size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());5585if (j == size_t(-1))5586__throw_runtime_error("locale not supported");5587wchar_t* wbe = wbuf + j;5588__curr_symbol_.assign(wbuf, wbe);5589if (lc->int_frac_digits != CHAR_MAX)5590__frac_digits_ = lc->int_frac_digits;5591else5592__frac_digits_ = base::do_frac_digits();5593# if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5594if (lc->p_sign_posn == 0)5595# else // _LIBCPP_MSVCRT5596if (lc->int_p_sign_posn == 0)5597# endif // !_LIBCPP_MSVCRT5598__positive_sign_ = L"()";5599else {5600mb = mbstate_t();5601bb = lc->positive_sign;5602j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());5603if (j == size_t(-1))5604__throw_runtime_error("locale not supported");5605wbe = wbuf + j;5606__positive_sign_.assign(wbuf, wbe);5607}5608# if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5609if (lc->n_sign_posn == 0)5610# else // _LIBCPP_MSVCRT5611if (lc->int_n_sign_posn == 0)5612# endif // !_LIBCPP_MSVCRT5613__negative_sign_ = L"()";5614else {5615mb = mbstate_t();5616bb = lc->negative_sign;5617j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());5618if (j == size_t(-1))5619__throw_runtime_error("locale not supported");5620wbe = wbuf + j;5621__negative_sign_.assign(wbuf, wbe);5622}5623// Assume the positive and negative formats will want spaces in5624// the same places in curr_symbol since there's no way to5625// represent anything else.5626string_type __dummy_curr_symbol = __curr_symbol_;5627# if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5628__init_pat(__pos_format_, __dummy_curr_symbol, true, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');5629__init_pat(__neg_format_, __curr_symbol_, true, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');5630# else // _LIBCPP_MSVCRT5631__init_pat(5632__pos_format_,5633__dummy_curr_symbol,5634true,5635lc->int_p_cs_precedes,5636lc->int_p_sep_by_space,5637lc->int_p_sign_posn,5638L' ');5639__init_pat(5640__neg_format_, __curr_symbol_, true, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn, L' ');5641# endif // !_LIBCPP_MSVCRT5642}5643#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS56445645void __do_nothing(void*) {}56465647template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;5648_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)56495650template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;5651_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)56525653template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;5654_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)56555656template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;5657_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)56585659template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;5660_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)56615662template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;5663_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)56645665template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;5666_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)56675668template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;5669_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)56705671template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;5672_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)56735674template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;5675template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;5676_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)5677_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)56785679template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;5680template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;5681_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)5682_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)56835684template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;5685_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)56865687template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;5688_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)56895690template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;5691_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)56925693template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;5694_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)56955696template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;5697_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)56985699template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;5700_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)57015702template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;5703_LIBCPP_IF_WIDE_CHARACTERS(5704template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)5705template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS5706codecvt_byname<char16_t, char, mbstate_t>;5707template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS5708codecvt_byname<char32_t, char, mbstate_t>;5709#ifndef _LIBCPP_HAS_NO_CHAR8_T5710template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;5711template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;5712#endif57135714_LIBCPP_END_NAMESPACE_STD57155716_LIBCPP_POP_MACROS571757185719