brintos

brintos / llvm-project-archived public Read only

0
0
Text · 185.0 KiB · aca2117 Raw
5678 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <__utility/no_destroy.h>10#include <algorithm>11#include <clocale>12#include <codecvt>13#include <cstddef>14#include <cstdio>15#include <cstdlib>16#include <cstring>17#include <locale>18#include <new>19#include <string>20#include <type_traits>21#include <typeinfo>22#include <utility>23#include <vector>24 25#if _LIBCPP_HAS_WIDE_CHARACTERS26#  include <cwctype>27#endif28 29#if defined(_AIX)30#  include <sys/localedef.h> // for __lc_ctype_ptr31#endif32 33#if defined(_LIBCPP_MSVCRT)34#  define _CTYPE_DISABLE_MACROS35#endif36 37#include "include/atomic_support.h"38#include "include/sso_allocator.h"39 40// On Linux, wint_t and wchar_t have different signed-ness, and this causes41// lots of noise in the build log, but no bugs that I know of.42_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")43 44_LIBCPP_PUSH_MACROS45#include <__undef_macros>46 47_LIBCPP_BEGIN_NAMESPACE_STD48 49struct __libcpp_unique_locale {50  __libcpp_unique_locale(const char* nm) : __loc_(__locale::__newlocale(_LIBCPP_ALL_MASK, nm, 0)) {}51 52  ~__libcpp_unique_locale() {53    if (__loc_)54      __locale::__freelocale(__loc_);55  }56 57  explicit operator bool() const { return __loc_; }58 59  __locale::__locale_t& get() { return __loc_; }60 61  __locale::__locale_t __loc_;62 63private:64  __libcpp_unique_locale(__libcpp_unique_locale const&);65  __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);66};67 68#ifdef __cloc_defined69__locale::__locale_t __cloc() {70  // In theory this could create a race condition. In practice71  // the race condition is non-fatal since it will just create72  // a little resource leak. Better approach would be appreciated.73  static __locale::__locale_t result = __locale::__newlocale(_LIBCPP_ALL_MASK, "C", 0);74  return result;75}76#endif // __cloc_defined77 78namespace {79 80struct releaser {81  void operator()(locale::facet* p) { p->__release_shared(); }82};83 84template <class T, class... Args>85T& make(Args... args) {86  alignas(T) static std::byte buf[sizeof(T)];87  auto* obj = ::new (&buf) T(args...);88  return *obj;89}90 91template <typename T, size_t N>92inline constexpr size_t countof(const T (&)[N]) {93  return N;94}95 96template <typename T>97inline constexpr size_t countof(const T* const begin, const T* const end) {98  return static_cast<size_t>(end - begin);99}100 101string build_name(const string& other, const string& one, locale::category c) {102  if (other == "*" || one == "*")103    return "*";104  if (c == locale::none || other == one)105    return other;106 107  // FIXME: Handle the more complicated cases, such as when the locale has108  // different names for different categories.109  return "*";110}111 112} // namespace113 114const locale::category locale::none;115const locale::category locale::collate;116const locale::category locale::ctype;117const locale::category locale::monetary;118const locale::category locale::numeric;119const locale::category locale::time;120const locale::category locale::messages;121const locale::category locale::all;122 123class _LIBCPP_HIDDEN locale::__imp : public facet {124  enum { N = 30 };125  vector<facet*, __sso_allocator<facet*, N> > facets_;126  string name_;127 128public:129  explicit __imp(size_t refs = 0);130  explicit __imp(const string& name, size_t refs = 0);131  __imp(const __imp&);132  __imp(const __imp&, const string&, locale::category c);133  __imp(const __imp& other, const __imp& one, locale::category c);134  __imp(const __imp&, facet* f, long id);135  ~__imp();136 137  const string& name() const { return name_; }138  bool has_facet(long id) const { return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)]; }139  const locale::facet* use_facet(long id) const;140 141  void acquire();142  void release();143  static __no_destroy<__imp> classic_locale_imp_;144 145private:146  void install(facet* f, long id);147  template <class F>148  void install(F* f) {149    install(f, f->id.__get());150  }151  template <class F>152  void install_from(const __imp& other);153};154 155locale::__imp::__imp(size_t refs) : facet(refs), facets_(N), name_("C") {156  facets_.clear();157  install(&make<std::collate<char> >(1u));158#if _LIBCPP_HAS_WIDE_CHARACTERS159  install(&make<std::collate<wchar_t> >(1u));160#endif161  install(&make<std::ctype<char> >(nullptr, false, 1u));162#if _LIBCPP_HAS_WIDE_CHARACTERS163  install(&make<std::ctype<wchar_t> >(1u));164#endif165  install(&make<codecvt<char, char, mbstate_t> >(1u));166#if _LIBCPP_HAS_WIDE_CHARACTERS167  install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));168#endif169  _LIBCPP_SUPPRESS_DEPRECATED_PUSH170  install(&make<codecvt<char16_t, char, mbstate_t> >(1u));171  install(&make<codecvt<char32_t, char, mbstate_t> >(1u));172  _LIBCPP_SUPPRESS_DEPRECATED_POP173#if _LIBCPP_HAS_CHAR8_T174  install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));175  install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));176#endif177  install(&make<numpunct<char> >(1u));178#if _LIBCPP_HAS_WIDE_CHARACTERS179  install(&make<numpunct<wchar_t> >(1u));180#endif181  install(&make<num_get<char> >(1u));182#if _LIBCPP_HAS_WIDE_CHARACTERS183  install(&make<num_get<wchar_t> >(1u));184#endif185  install(&make<num_put<char> >(1u));186#if _LIBCPP_HAS_WIDE_CHARACTERS187  install(&make<num_put<wchar_t> >(1u));188#endif189  install(&make<moneypunct<char, false> >(1u));190  install(&make<moneypunct<char, true> >(1u));191#if _LIBCPP_HAS_WIDE_CHARACTERS192  install(&make<moneypunct<wchar_t, false> >(1u));193  install(&make<moneypunct<wchar_t, true> >(1u));194#endif195  install(&make<money_get<char> >(1u));196#if _LIBCPP_HAS_WIDE_CHARACTERS197  install(&make<money_get<wchar_t> >(1u));198#endif199  install(&make<money_put<char> >(1u));200#if _LIBCPP_HAS_WIDE_CHARACTERS201  install(&make<money_put<wchar_t> >(1u));202#endif203  install(&make<time_get<char> >(1u));204#if _LIBCPP_HAS_WIDE_CHARACTERS205  install(&make<time_get<wchar_t> >(1u));206#endif207  install(&make<time_put<char> >(1u));208#if _LIBCPP_HAS_WIDE_CHARACTERS209  install(&make<time_put<wchar_t> >(1u));210#endif211  install(&make<std::messages<char> >(1u));212#if _LIBCPP_HAS_WIDE_CHARACTERS213  install(&make<std::messages<wchar_t> >(1u));214#endif215}216 217locale::__imp::__imp(const string& name, size_t refs) : facet(refs), facets_(N), name_(name) {218  __exception_guard guard([&] {219    for (unsigned i = 0; i < facets_.size(); ++i)220      if (facets_[i])221        facets_[i]->__release_shared();222  });223  facets_ = locale::classic().__locale_->facets_;224  for (unsigned i = 0; i < facets_.size(); ++i)225    if (facets_[i])226      facets_[i]->__add_shared();227  install(new collate_byname<char>(name_));228#if _LIBCPP_HAS_WIDE_CHARACTERS229  install(new collate_byname<wchar_t>(name_));230#endif231  install(new ctype_byname<char>(name_));232#if _LIBCPP_HAS_WIDE_CHARACTERS233  install(new ctype_byname<wchar_t>(name_));234#endif235  install(new codecvt_byname<char, char, mbstate_t>(name_));236#if _LIBCPP_HAS_WIDE_CHARACTERS237  install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));238#endif239  _LIBCPP_SUPPRESS_DEPRECATED_PUSH240  install(new codecvt_byname<char16_t, char, mbstate_t>(name_));241  install(new codecvt_byname<char32_t, char, mbstate_t>(name_));242  _LIBCPP_SUPPRESS_DEPRECATED_POP243#if _LIBCPP_HAS_CHAR8_T244  install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));245  install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));246#endif247  install(new numpunct_byname<char>(name_));248#if _LIBCPP_HAS_WIDE_CHARACTERS249  install(new numpunct_byname<wchar_t>(name_));250#endif251  install(new moneypunct_byname<char, false>(name_));252  install(new moneypunct_byname<char, true>(name_));253#if _LIBCPP_HAS_WIDE_CHARACTERS254  install(new moneypunct_byname<wchar_t, false>(name_));255  install(new moneypunct_byname<wchar_t, true>(name_));256#endif257  install(new time_get_byname<char>(name_));258#if _LIBCPP_HAS_WIDE_CHARACTERS259  install(new time_get_byname<wchar_t>(name_));260#endif261  install(new time_put_byname<char>(name_));262#if _LIBCPP_HAS_WIDE_CHARACTERS263  install(new time_put_byname<wchar_t>(name_));264#endif265  install(new messages_byname<char>(name_));266#if _LIBCPP_HAS_WIDE_CHARACTERS267  install(new messages_byname<wchar_t>(name_));268#endif269  guard.__complete();270}271 272locale::__imp::__imp(const __imp& other) : facets_(max<size_t>(N, other.facets_.size())), name_(other.name_) {273  facets_ = other.facets_;274  for (unsigned i = 0; i < facets_.size(); ++i)275    if (facets_[i])276      facets_[i]->__add_shared();277}278 279locale::__imp::__imp(const __imp& other, const string& name, locale::category c)280    : facets_(N), name_(build_name(other.name_, name, c)) {281  facets_ = other.facets_;282  for (unsigned i = 0; i < facets_.size(); ++i)283    if (facets_[i])284      facets_[i]->__add_shared();285  __exception_guard guard([&] {286    for (unsigned i = 0; i < facets_.size(); ++i)287      if (facets_[i])288        facets_[i]->__release_shared();289  });290  if (c & locale::collate) {291    install(new collate_byname<char>(name));292#if _LIBCPP_HAS_WIDE_CHARACTERS293    install(new collate_byname<wchar_t>(name));294#endif295  }296  if (c & locale::ctype) {297    install(new ctype_byname<char>(name));298#if _LIBCPP_HAS_WIDE_CHARACTERS299    install(new ctype_byname<wchar_t>(name));300#endif301    install(new codecvt_byname<char, char, mbstate_t>(name));302#if _LIBCPP_HAS_WIDE_CHARACTERS303    install(new codecvt_byname<wchar_t, char, mbstate_t>(name));304#endif305    _LIBCPP_SUPPRESS_DEPRECATED_PUSH306    install(new codecvt_byname<char16_t, char, mbstate_t>(name));307    install(new codecvt_byname<char32_t, char, mbstate_t>(name));308    _LIBCPP_SUPPRESS_DEPRECATED_POP309#if _LIBCPP_HAS_CHAR8_T310    install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));311    install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));312#endif313  }314  if (c & locale::monetary) {315    install(new moneypunct_byname<char, false>(name));316    install(new moneypunct_byname<char, true>(name));317#if _LIBCPP_HAS_WIDE_CHARACTERS318    install(new moneypunct_byname<wchar_t, false>(name));319    install(new moneypunct_byname<wchar_t, true>(name));320#endif321  }322  if (c & locale::numeric) {323    install(new numpunct_byname<char>(name));324#if _LIBCPP_HAS_WIDE_CHARACTERS325    install(new numpunct_byname<wchar_t>(name));326#endif327  }328  if (c & locale::time) {329    install(new time_get_byname<char>(name));330#if _LIBCPP_HAS_WIDE_CHARACTERS331    install(new time_get_byname<wchar_t>(name));332#endif333    install(new time_put_byname<char>(name));334#if _LIBCPP_HAS_WIDE_CHARACTERS335    install(new time_put_byname<wchar_t>(name));336#endif337  }338  if (c & locale::messages) {339    install(new messages_byname<char>(name));340#if _LIBCPP_HAS_WIDE_CHARACTERS341    install(new messages_byname<wchar_t>(name));342#endif343  }344  guard.__complete();345}346 347template <class F>348inline void locale::__imp::install_from(const locale::__imp& one) {349  long id = F::id.__get();350  install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);351}352 353locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)354    : facets_(N), name_(build_name(other.name_, one.name_, c)) {355  facets_ = other.facets_;356  for (unsigned i = 0; i < facets_.size(); ++i)357    if (facets_[i])358      facets_[i]->__add_shared();359  __exception_guard guard([&] {360    for (unsigned i = 0; i < facets_.size(); ++i)361      if (facets_[i])362        facets_[i]->__release_shared();363  });364 365  if (c & locale::collate) {366    install_from<std::collate<char> >(one);367#if _LIBCPP_HAS_WIDE_CHARACTERS368    install_from<std::collate<wchar_t> >(one);369#endif370  }371  if (c & locale::ctype) {372    install_from<std::ctype<char> >(one);373#if _LIBCPP_HAS_WIDE_CHARACTERS374    install_from<std::ctype<wchar_t> >(one);375#endif376    install_from<std::codecvt<char, char, mbstate_t> >(one);377    _LIBCPP_SUPPRESS_DEPRECATED_PUSH378    install_from<std::codecvt<char16_t, char, mbstate_t> >(one);379    install_from<std::codecvt<char32_t, char, mbstate_t> >(one);380    _LIBCPP_SUPPRESS_DEPRECATED_POP381#if _LIBCPP_HAS_CHAR8_T382    install_from<std::codecvt<char16_t, char8_t, mbstate_t> >(one);383    install_from<std::codecvt<char32_t, char8_t, mbstate_t> >(one);384#endif385#if _LIBCPP_HAS_WIDE_CHARACTERS386    install_from<std::codecvt<wchar_t, char, mbstate_t> >(one);387#endif388  }389  if (c & locale::monetary) {390    install_from<moneypunct<char, false> >(one);391    install_from<moneypunct<char, true> >(one);392#if _LIBCPP_HAS_WIDE_CHARACTERS393    install_from<moneypunct<wchar_t, false> >(one);394    install_from<moneypunct<wchar_t, true> >(one);395#endif396    install_from<money_get<char> >(one);397#if _LIBCPP_HAS_WIDE_CHARACTERS398    install_from<money_get<wchar_t> >(one);399#endif400    install_from<money_put<char> >(one);401#if _LIBCPP_HAS_WIDE_CHARACTERS402    install_from<money_put<wchar_t> >(one);403#endif404  }405  if (c & locale::numeric) {406    install_from<numpunct<char> >(one);407#if _LIBCPP_HAS_WIDE_CHARACTERS408    install_from<numpunct<wchar_t> >(one);409#endif410    install_from<num_get<char> >(one);411#if _LIBCPP_HAS_WIDE_CHARACTERS412    install_from<num_get<wchar_t> >(one);413#endif414    install_from<num_put<char> >(one);415#if _LIBCPP_HAS_WIDE_CHARACTERS416    install_from<num_put<wchar_t> >(one);417#endif418  }419  if (c & locale::time) {420    install_from<time_get<char> >(one);421#if _LIBCPP_HAS_WIDE_CHARACTERS422    install_from<time_get<wchar_t> >(one);423#endif424    install_from<time_put<char> >(one);425#if _LIBCPP_HAS_WIDE_CHARACTERS426    install_from<time_put<wchar_t> >(one);427#endif428  }429  if (c & locale::messages) {430    install_from<std::messages<char> >(one);431#if _LIBCPP_HAS_WIDE_CHARACTERS432    install_from<std::messages<wchar_t> >(one);433#endif434  }435  guard.__complete();436}437 438locale::__imp::__imp(const __imp& other, facet* f, long id)439    : facets_(max<size_t>(N, other.facets_.size() + 1)), name_("*") {440  f->__add_shared();441  unique_ptr<facet, releaser> hold(f);442  facets_ = other.facets_;443  for (unsigned i = 0; i < other.facets_.size(); ++i)444    if (facets_[i])445      facets_[i]->__add_shared();446  install(hold.get(), id);447}448 449locale::__imp::~__imp() {450  for (unsigned i = 0; i < facets_.size(); ++i)451    if (facets_[i])452      facets_[i]->__release_shared();453}454 455void locale::__imp::install(facet* f, long id) {456  f->__add_shared();457  unique_ptr<facet, releaser> hold(f);458  if (static_cast<size_t>(id) >= facets_.size())459    facets_.resize(static_cast<size_t>(id + 1));460  if (facets_[static_cast<size_t>(id)])461    facets_[static_cast<size_t>(id)]->__release_shared();462  facets_[static_cast<size_t>(id)] = hold.release();463}464 465const locale::facet* locale::__imp::use_facet(long id) const {466  if (!has_facet(id))467    std::__throw_bad_cast();468  return facets_[static_cast<size_t>(id)];469}470 471// locale472 473// We don't do reference counting on the classic locale.474// It's never destroyed anyway, but atomic reference counting may be very475// expensive in parallel applications. The classic locale is used by default476// in all streams. Note: if a new global locale is installed, then we lose477// the benefit of no reference counting.478constinit __no_destroy<locale::__imp>479    locale::__imp::classic_locale_imp_(__uninitialized_tag{}); // initialized below in classic()480 481const locale& locale::classic() {482  static const __no_destroy<locale> classic_locale(__private_constructor_tag{}, [] {483    // executed exactly once on first initialization of `classic_locale`484    locale::__imp::classic_locale_imp_.__emplace(1u);485    return &locale::__imp::classic_locale_imp_.__get();486  }());487  return classic_locale.__get();488}489 490locale& locale::__global() {491  static __no_destroy<locale> g(locale::classic());492  return g.__get();493}494 495void locale::__imp::acquire() {496  if (this != &locale::__imp::classic_locale_imp_.__get())497    __add_shared();498}499 500void locale::__imp::release() {501  if (this != &locale::__imp::classic_locale_imp_.__get())502    __release_shared();503}504 505locale::locale() noexcept : __locale_(__global().__locale_) { __locale_->acquire(); }506 507locale::locale(const locale& l) noexcept : __locale_(l.__locale_) { __locale_->acquire(); }508 509locale::~locale() { __locale_->release(); }510 511const locale& locale::operator=(const locale& other) noexcept {512  other.__locale_->acquire();513  __locale_->release();514  __locale_ = other.__locale_;515  return *this;516}517 518locale::locale(const char* name)519    : __locale_(name ? new __imp(name) : (__throw_runtime_error("locale constructed with null"), nullptr)) {520  __locale_->acquire();521}522 523locale::locale(const string& name) : __locale_(new __imp(name)) { __locale_->acquire(); }524 525locale::locale(const locale& other, const char* name, category c)526    : __locale_(name ? new __imp(*other.__locale_, name, c)527                     : (__throw_runtime_error("locale constructed with null"), nullptr)) {528  __locale_->acquire();529}530 531locale::locale(const locale& other, const string& name, category c) : __locale_(new __imp(*other.__locale_, name, c)) {532  __locale_->acquire();533}534 535locale::locale(const locale& other, const locale& one, category c)536    : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) {537  __locale_->acquire();538}539 540string locale::name() const { return __locale_->name(); }541 542void locale::__install_ctor(const locale& other, facet* f, long facet_id) {543  if (f)544    __locale_ = new __imp(*other.__locale_, f, facet_id);545  else546    __locale_ = other.__locale_;547  __locale_->acquire();548}549 550locale locale::global(const locale& loc) {551  locale& g = __global();552  locale r  = g;553  g         = loc;554  if (g.name() != "*")555    __locale::__setlocale(_LIBCPP_LC_ALL, g.name().c_str());556  return r;557}558 559bool locale::has_facet(id& x) const { return __locale_->has_facet(x.__get()); }560 561const locale::facet* locale::use_facet(id& x) const { return __locale_->use_facet(x.__get()); }562 563bool locale::operator==(const locale& y) const {564  return (__locale_ == y.__locale_) || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());565}566 567// locale::facet568 569locale::facet::~facet() {}570 571void locale::facet::__on_zero_shared() noexcept { delete this; }572 573// locale::id574 575constinit int32_t locale::id::__next_id = 0;576 577long locale::id::__get() {578  call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); });579  return __id_ - 1;580}581 582// template <> class collate_byname<char>583 584collate_byname<char>::collate_byname(const char* n, size_t refs)585    : collate<char>(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, n, 0)) {586  if (__l_ == 0)587    std::__throw_runtime_error(588        ("collate_byname<char>::collate_byname"589         " failed to construct for " +590         string(n))591            .c_str());592}593 594collate_byname<char>::collate_byname(const string& name, size_t refs)595    : collate<char>(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, name.c_str(), 0)) {596  if (__l_ == 0)597    std::__throw_runtime_error(598        ("collate_byname<char>::collate_byname"599         " failed to construct for " +600         name)601            .c_str());602}603 604collate_byname<char>::~collate_byname() { __locale::__freelocale(__l_); }605 606int collate_byname<char>::do_compare(607    const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {608  string_type lhs(__lo1, __hi1);609  string_type rhs(__lo2, __hi2);610  int r = __locale::__strcoll(lhs.c_str(), rhs.c_str(), __l_);611  if (r < 0)612    return -1;613  if (r > 0)614    return 1;615  return r;616}617 618collate_byname<char>::string_type collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const {619  const string_type in(lo, hi);620  string_type out(__locale::__strxfrm(0, in.c_str(), 0, __l_), char());621  __locale::__strxfrm(const_cast<char*>(out.c_str()), in.c_str(), out.size() + 1, __l_);622  return out;623}624 625// template <> class collate_byname<wchar_t>626 627#if _LIBCPP_HAS_WIDE_CHARACTERS628collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)629    : collate<wchar_t>(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, n, 0)) {630  if (__l_ == 0)631    std::__throw_runtime_error(632        ("collate_byname<wchar_t>::collate_byname(size_t refs)"633         " failed to construct for " +634         string(n))635            .c_str());636}637 638collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)639    : collate<wchar_t>(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, name.c_str(), 0)) {640  if (__l_ == 0)641    std::__throw_runtime_error(642        ("collate_byname<wchar_t>::collate_byname(size_t refs)"643         " failed to construct for " +644         name)645            .c_str());646}647 648collate_byname<wchar_t>::~collate_byname() { __locale::__freelocale(__l_); }649 650int collate_byname<wchar_t>::do_compare(651    const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {652  string_type lhs(__lo1, __hi1);653  string_type rhs(__lo2, __hi2);654  int r = __locale::__wcscoll(lhs.c_str(), rhs.c_str(), __l_);655  if (r < 0)656    return -1;657  if (r > 0)658    return 1;659  return r;660}661 662collate_byname<wchar_t>::string_type663collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const {664  const string_type in(lo, hi);665  string_type out(__locale::__wcsxfrm(0, in.c_str(), 0, __l_), wchar_t());666  __locale::__wcsxfrm(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size() + 1, __l_);667  return out;668}669#endif // _LIBCPP_HAS_WIDE_CHARACTERS670 671const ctype_base::mask ctype_base::space;672const ctype_base::mask ctype_base::print;673const ctype_base::mask ctype_base::cntrl;674const ctype_base::mask ctype_base::upper;675const ctype_base::mask ctype_base::lower;676const ctype_base::mask ctype_base::alpha;677const ctype_base::mask ctype_base::digit;678const ctype_base::mask ctype_base::punct;679const ctype_base::mask ctype_base::xdigit;680const ctype_base::mask ctype_base::blank;681const ctype_base::mask ctype_base::alnum;682const ctype_base::mask ctype_base::graph;683 684// template <> class ctype<wchar_t>;685 686template <class CharT>687static CharT to_upper_impl(CharT c) {688  if (c < 'a' || c > 'z')689    return c;690  return c & ~0x20;691}692 693template <class CharT>694static CharT to_lower_impl(CharT c) {695  if (c < 'A' || c > 'Z')696    return c;697  return c | 0x20;698}699 700#if _LIBCPP_HAS_WIDE_CHARACTERS701constinit locale::id ctype<wchar_t>::id;702 703ctype<wchar_t>::~ctype() {}704 705bool ctype<wchar_t>::do_is(mask m, char_type c) const {706  return std::__libcpp_isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;707}708 709const wchar_t* ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {710  for (; low != high; ++low, ++vec)711    *vec = static_cast<mask>(std::__libcpp_isascii(*low) ? ctype<char>::classic_table()[*low] : 0);712  return low;713}714 715const wchar_t* ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {716  for (; low != high; ++low)717    if (std::__libcpp_isascii(*low) && (ctype<char>::classic_table()[*low] & m))718      break;719  return low;720}721 722const wchar_t* ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {723  for (; low != high; ++low)724    if (!(std::__libcpp_isascii(*low) && (ctype<char>::classic_table()[*low] & m)))725      break;726  return low;727}728 729wchar_t ctype<wchar_t>::do_toupper(char_type c) const { return to_upper_impl(c); }730 731const wchar_t* ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const {732  for (; low != high; ++low)733    *low = to_upper_impl(*low);734  return low;735}736 737wchar_t ctype<wchar_t>::do_tolower(char_type c) const { return to_lower_impl(c); }738 739const wchar_t* ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const {740  for (; low != high; ++low)741    *low = to_lower_impl(*low);742  return low;743}744 745wchar_t ctype<wchar_t>::do_widen(char c) const { return c; }746 747const char* ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const {748  for (; low != high; ++low, ++dest)749    *dest = *low;750  return low;751}752 753char ctype<wchar_t>::do_narrow(char_type c, char dfault) const {754  if (std::__libcpp_isascii(c))755    return static_cast<char>(c);756  return dfault;757}758 759const wchar_t* ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {760  for (; low != high; ++low, ++dest)761    if (std::__libcpp_isascii(*low))762      *dest = static_cast<char>(*low);763    else764      *dest = dfault;765  return low;766}767#endif // _LIBCPP_HAS_WIDE_CHARACTERS768 769// template <> class ctype<char>;770 771constinit locale::id ctype<char>::id;772 773const size_t ctype<char>::table_size;774 775ctype<char>::ctype(const mask* tab, bool del, size_t refs) : locale::facet(refs), __tab_(tab), __del_(del) {776  if (__tab_ == 0)777    __tab_ = classic_table();778}779 780ctype<char>::~ctype() {781  if (__tab_ && __del_)782    delete[] __tab_;783}784 785char ctype<char>::do_toupper(char_type c) const { return to_upper_impl(c); }786 787const char* ctype<char>::do_toupper(char_type* low, const char_type* high) const {788  for (; low != high; ++low)789    *low = to_upper_impl(*low);790  return low;791}792 793char ctype<char>::do_tolower(char_type c) const { return to_lower_impl(c); }794 795const char* ctype<char>::do_tolower(char_type* low, const char_type* high) const {796  for (; low != high; ++low)797    *low = to_lower_impl(*low);798  return low;799}800 801char ctype<char>::do_widen(char c) const { return c; }802 803const char* ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const {804  for (; low != high; ++low, ++dest)805    *dest = *low;806  return low;807}808 809char ctype<char>::do_narrow(char_type c, char dfault) const {810  if (std::__libcpp_isascii(c))811    return static_cast<char>(c);812  return dfault;813}814 815const char* ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {816  for (; low != high; ++low, ++dest)817    if (std::__libcpp_isascii(*low))818      *dest = *low;819    else820      *dest = dfault;821  return low;822}823 824#if defined(__EMSCRIPTEN__)825extern "C" const unsigned short** __ctype_b_loc();826extern "C" const int** __ctype_tolower_loc();827extern "C" const int** __ctype_toupper_loc();828#endif829 830#ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE831const ctype<char>::mask* ctype<char>::classic_table() noexcept {832  // clang-format off833    static constexpr const ctype<char>::mask builtin_table[table_size] = {834        cntrl,                          cntrl,835        cntrl,                          cntrl,836        cntrl,                          cntrl,837        cntrl,                          cntrl,838        cntrl,                          cntrl | space | blank,839        cntrl | space,                  cntrl | space,840        cntrl | space,                  cntrl | space,841        cntrl,                          cntrl,842        cntrl,                          cntrl,843        cntrl,                          cntrl,844        cntrl,                          cntrl,845        cntrl,                          cntrl,846        cntrl,                          cntrl,847        cntrl,                          cntrl,848        cntrl,                          cntrl,849        cntrl,                          cntrl,850        space | blank | print,          punct | print,851        punct | print,                  punct | print,852        punct | print,                  punct | print,853        punct | print,                  punct | print,854        punct | print,                  punct | print,855        punct | print,                  punct | print,856        punct | print,                  punct | print,857        punct | print,                  punct | print,858        digit | print | xdigit,         digit | print | xdigit,859        digit | print | xdigit,         digit | print | xdigit,860        digit | print | xdigit,         digit | print | xdigit,861        digit | print | xdigit,         digit | print | xdigit,862        digit | print | xdigit,         digit | print | xdigit,863        punct | print,                  punct | print,864        punct | print,                  punct | print,865        punct | print,                  punct | print,866        punct | print,                  upper | xdigit | print | alpha,867        upper | xdigit | print | alpha, upper | xdigit | print | alpha,868        upper | xdigit | print | alpha, upper | xdigit | print | alpha,869        upper | xdigit | print | alpha, upper | print | alpha,870        upper | print | alpha,          upper | print | alpha,871        upper | print | alpha,          upper | print | alpha,872        upper | print | alpha,          upper | print | alpha,873        upper | print | alpha,          upper | print | alpha,874        upper | print | alpha,          upper | print | alpha,875        upper | print | alpha,          upper | print | alpha,876        upper | print | alpha,          upper | print | alpha,877        upper | print | alpha,          upper | print | alpha,878        upper | print | alpha,          upper | print | alpha,879        upper | print | alpha,          punct | print,880        punct | print,                  punct | print,881        punct | print,                  punct | print,882        punct | print,                  lower | xdigit | print | alpha,883        lower | xdigit | print | alpha, lower | xdigit | print | alpha,884        lower | xdigit | print | alpha, lower | xdigit | print | alpha,885        lower | xdigit | print | alpha, lower | print | alpha,886        lower | print | alpha,          lower | print | alpha,887        lower | print | alpha,          lower | print | alpha,888        lower | print | alpha,          lower | print | alpha,889        lower | print | alpha,          lower | print | alpha,890        lower | print | alpha,          lower | print | alpha,891        lower | print | alpha,          lower | print | alpha,892        lower | print | alpha,          lower | print | alpha,893        lower | print | alpha,          lower | print | alpha,894        lower | print | alpha,          lower | print | alpha,895        lower | print | alpha,          punct | print,896        punct | print,                  punct | print,897        punct | print,                  cntrl,898        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,899        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,900        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,901        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,902        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,903        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,904        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,905        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0906    };907  // clang-format on908  return builtin_table;909}910#else911const ctype<char>::mask* ctype<char>::classic_table() noexcept {912#  if defined(__APPLE__) || defined(__FreeBSD__)913  return _DefaultRuneLocale.__runetype;914#  elif defined(__NetBSD__)915  return _C_ctype_tab_ + 1;916#  elif defined(__GLIBC__)917  return _LIBCPP_GET_C_LOCALE->__ctype_b;918#  elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)919  return __pctype_func();920#  elif defined(__EMSCRIPTEN__)921  return *__ctype_b_loc();922#  elif _LIBCPP_LIBC_NEWLIB923  // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].924  return _ctype_ + 1;925#  elif defined(_AIX)926  return (const unsigned int*)__lc_ctype_ptr->obj->mask;927#  elif defined(__MVS__)928#    if defined(__NATIVE_ASCII_F)929  return const_cast<const ctype<char>::mask*>(__OBJ_DATA(__lc_ctype_a)->mask);930#    else931  return const_cast<const ctype<char>::mask*>(__ctypec);932#    endif933#  else934  // Platform not supported: abort so the person doing the port knows what to935  // fix936#    warning ctype<char>::classic_table() is not implemented937  printf("ctype<char>::classic_table() is not implemented\n");938  abort();939  return nullptr;940#  endif941}942#endif943 944// template <> class ctype_byname<char>945 946ctype_byname<char>::ctype_byname(const char* name, size_t refs)947    : ctype<char>(0, false, refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, name, 0)) {948  if (__l_ == 0)949    std::__throw_runtime_error(950        ("ctype_byname<char>::ctype_byname"951         " failed to construct for " +952         string(name))953            .c_str());954}955 956ctype_byname<char>::ctype_byname(const string& name, size_t refs)957    : ctype<char>(0, false, refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, name.c_str(), 0)) {958  if (__l_ == 0)959    std::__throw_runtime_error(960        ("ctype_byname<char>::ctype_byname"961         " failed to construct for " +962         name)963            .c_str());964}965 966ctype_byname<char>::~ctype_byname() { __locale::__freelocale(__l_); }967 968char ctype_byname<char>::do_toupper(char_type c) const {969  return static_cast<char>(__locale::__toupper(static_cast<unsigned char>(c), __l_));970}971 972const char* ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const {973  for (; low != high; ++low)974    *low = static_cast<char>(__locale::__toupper(static_cast<unsigned char>(*low), __l_));975  return low;976}977 978char ctype_byname<char>::do_tolower(char_type c) const {979  return static_cast<char>(__locale::__tolower(static_cast<unsigned char>(c), __l_));980}981 982const char* ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const {983  for (; low != high; ++low)984    *low = static_cast<char>(__locale::__tolower(static_cast<unsigned char>(*low), __l_));985  return low;986}987 988// template <> class ctype_byname<wchar_t>989 990#if _LIBCPP_HAS_WIDE_CHARACTERS991ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)992    : ctype<wchar_t>(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, name, 0)) {993  if (__l_ == 0)994    std::__throw_runtime_error(995        ("ctype_byname<wchar_t>::ctype_byname"996         " failed to construct for " +997         string(name))998            .c_str());999}1000 1001ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)1002    : ctype<wchar_t>(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, name.c_str(), 0)) {1003  if (__l_ == 0)1004    std::__throw_runtime_error(1005        ("ctype_byname<wchar_t>::ctype_byname"1006         " failed to construct for " +1007         name)1008            .c_str());1009}1010 1011ctype_byname<wchar_t>::~ctype_byname() { __locale::__freelocale(__l_); }1012 1013bool ctype_byname<wchar_t>::do_is(mask m, char_type c) const {1014  wint_t ch = static_cast<wint_t>(c);1015#  ifdef _LIBCPP_WCTYPE_IS_MASK1016  return static_cast<bool>(__locale::__iswctype(ch, m, __l_));1017#  else1018  bool result = false;1019  if ((m & space) == space)1020    result |= (__locale::__iswspace(ch, __l_) != 0);1021  if ((m & print) == print)1022    result |= (__locale::__iswprint(ch, __l_) != 0);1023  if ((m & cntrl) == cntrl)1024    result |= (__locale::__iswcntrl(ch, __l_) != 0);1025  if ((m & upper) == upper)1026    result |= (__locale::__iswupper(ch, __l_) != 0);1027  if ((m & lower) == lower)1028    result |= (__locale::__iswlower(ch, __l_) != 0);1029  if ((m & alpha) == alpha)1030    result |= (__locale::__iswalpha(ch, __l_) != 0);1031  if ((m & digit) == digit)1032    result |= (__locale::__iswdigit(ch, __l_) != 0);1033  if ((m & punct) == punct)1034    result |= (__locale::__iswpunct(ch, __l_) != 0);1035  if ((m & xdigit) == xdigit)1036    result |= (__locale::__iswxdigit(ch, __l_) != 0);1037  if ((m & blank) == blank)1038    result |= (__locale::__iswblank(ch, __l_) != 0);1039  return result;1040#  endif1041}1042 1043const wchar_t* ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {1044  for (; low != high; ++low, ++vec) {1045    if (std::__libcpp_isascii(*low))1046      *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);1047    else {1048      *vec      = 0;1049      wint_t ch = static_cast<wint_t>(*low);1050      if (__locale::__iswspace(ch, __l_))1051        *vec |= space;1052#  ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT1053      if (__locale::__iswprint(ch, __l_))1054        *vec |= print;1055#  endif1056      if (__locale::__iswcntrl(ch, __l_))1057        *vec |= cntrl;1058      if (__locale::__iswupper(ch, __l_))1059        *vec |= upper;1060      if (__locale::__iswlower(ch, __l_))1061        *vec |= lower;1062#  ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA1063      if (__locale::__iswalpha(ch, __l_))1064        *vec |= alpha;1065#  endif1066      if (__locale::__iswdigit(ch, __l_))1067        *vec |= digit;1068      if (__locale::__iswpunct(ch, __l_))1069        *vec |= punct;1070#  ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT1071      if (__locale::__iswxdigit(ch, __l_))1072        *vec |= xdigit;1073#  endif1074      if (__locale::__iswblank(ch, __l_))1075        *vec |= blank;1076    }1077  }1078  return low;1079}1080 1081const wchar_t* ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {1082  for (; low != high; ++low) {1083#  ifdef _LIBCPP_WCTYPE_IS_MASK1084    if (__locale::__iswctype(static_cast<wint_t>(*low), m, __l_))1085      break;1086#  else1087    wint_t ch = static_cast<wint_t>(*low);1088    if ((m & space) == space && __locale::__iswspace(ch, __l_))1089      break;1090    if ((m & print) == print && __locale::__iswprint(ch, __l_))1091      break;1092    if ((m & cntrl) == cntrl && __locale::__iswcntrl(ch, __l_))1093      break;1094    if ((m & upper) == upper && __locale::__iswupper(ch, __l_))1095      break;1096    if ((m & lower) == lower && __locale::__iswlower(ch, __l_))1097      break;1098    if ((m & alpha) == alpha && __locale::__iswalpha(ch, __l_))1099      break;1100    if ((m & digit) == digit && __locale::__iswdigit(ch, __l_))1101      break;1102    if ((m & punct) == punct && __locale::__iswpunct(ch, __l_))1103      break;1104    if ((m & xdigit) == xdigit && __locale::__iswxdigit(ch, __l_))1105      break;1106    if ((m & blank) == blank && __locale::__iswblank(ch, __l_))1107      break;1108#  endif1109  }1110  return low;1111}1112 1113const wchar_t* ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {1114  for (; low != high; ++low) {1115    wint_t ch = static_cast<wint_t>(*low);1116#  ifdef _LIBCPP_WCTYPE_IS_MASK1117    if (!__locale::__iswctype(ch, m, __l_))1118      break;1119#  else1120    if ((m & space) == space && __locale::__iswspace(ch, __l_))1121      continue;1122    if ((m & print) == print && __locale::__iswprint(ch, __l_))1123      continue;1124    if ((m & cntrl) == cntrl && __locale::__iswcntrl(ch, __l_))1125      continue;1126    if ((m & upper) == upper && __locale::__iswupper(ch, __l_))1127      continue;1128    if ((m & lower) == lower && __locale::__iswlower(ch, __l_))1129      continue;1130    if ((m & alpha) == alpha && __locale::__iswalpha(ch, __l_))1131      continue;1132    if ((m & digit) == digit && __locale::__iswdigit(ch, __l_))1133      continue;1134    if ((m & punct) == punct && __locale::__iswpunct(ch, __l_))1135      continue;1136    if ((m & xdigit) == xdigit && __locale::__iswxdigit(ch, __l_))1137      continue;1138    if ((m & blank) == blank && __locale::__iswblank(ch, __l_))1139      continue;1140    break;1141#  endif1142  }1143  return low;1144}1145 1146wchar_t ctype_byname<wchar_t>::do_toupper(char_type c) const { return __locale::__towupper(c, __l_); }1147 1148const wchar_t* ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const {1149  for (; low != high; ++low)1150    *low = __locale::__towupper(*low, __l_);1151  return low;1152}1153 1154wchar_t ctype_byname<wchar_t>::do_tolower(char_type c) const { return __locale::__towlower(c, __l_); }1155 1156const wchar_t* ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const {1157  for (; low != high; ++low)1158    *low = __locale::__towlower(*low, __l_);1159  return low;1160}1161 1162wchar_t ctype_byname<wchar_t>::do_widen(char c) const { return __locale::__btowc(c, __l_); }1163 1164const char* ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const {1165  for (; low != high; ++low, ++dest)1166    *dest = __locale::__btowc(*low, __l_);1167  return low;1168}1169 1170char ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const {1171  int r = __locale::__wctob(c, __l_);1172  return (r != EOF) ? static_cast<char>(r) : dfault;1173}1174 1175const wchar_t*1176ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {1177  for (; low != high; ++low, ++dest) {1178    int r = __locale::__wctob(*low, __l_);1179    *dest = (r != EOF) ? static_cast<char>(r) : dfault;1180  }1181  return low;1182}1183#endif // _LIBCPP_HAS_WIDE_CHARACTERS1184 1185// template <> class codecvt<char, char, mbstate_t>1186 1187constinit locale::id codecvt<char, char, mbstate_t>::id;1188 1189codecvt<char, char, mbstate_t>::~codecvt() {}1190 1191codecvt<char, char, mbstate_t>::result codecvt<char, char, mbstate_t>::do_out(1192    state_type&,1193    const intern_type* frm,1194    const intern_type*,1195    const intern_type*& frm_nxt,1196    extern_type* to,1197    extern_type*,1198    extern_type*& to_nxt) const {1199  frm_nxt = frm;1200  to_nxt  = to;1201  return noconv;1202}1203 1204codecvt<char, char, mbstate_t>::result codecvt<char, char, mbstate_t>::do_in(1205    state_type&,1206    const extern_type* frm,1207    const extern_type*,1208    const extern_type*& frm_nxt,1209    intern_type* to,1210    intern_type*,1211    intern_type*& to_nxt) const {1212  frm_nxt = frm;1213  to_nxt  = to;1214  return noconv;1215}1216 1217codecvt<char, char, mbstate_t>::result1218codecvt<char, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {1219  to_nxt = to;1220  return noconv;1221}1222 1223int codecvt<char, char, mbstate_t>::do_encoding() const noexcept { return 1; }1224 1225bool codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept { return true; }1226 1227int codecvt<char, char, mbstate_t>::do_length(1228    state_type&, const extern_type* frm, const extern_type* end, size_t mx) const {1229  return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end - frm)));1230}1231 1232int codecvt<char, char, mbstate_t>::do_max_length() const noexcept { return 1; }1233 1234// template <> class codecvt<wchar_t, char, mbstate_t>1235 1236#if _LIBCPP_HAS_WIDE_CHARACTERS1237constinit locale::id codecvt<wchar_t, char, mbstate_t>::id;1238 1239codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) : locale::facet(refs), __l_(_LIBCPP_GET_C_LOCALE) {}1240 1241codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)1242    : locale::facet(refs), __l_(__locale::__newlocale(_LIBCPP_ALL_MASK, nm, 0)) {1243  if (__l_ == 0)1244    std::__throw_runtime_error(1245        ("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"1246         " failed to construct for " +1247         string(nm))1248            .c_str());1249}1250 1251codecvt<wchar_t, char, mbstate_t>::~codecvt() {1252  if (__l_ != _LIBCPP_GET_C_LOCALE)1253    __locale::__freelocale(__l_);1254}1255 1256codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_out(1257    state_type& st,1258    const intern_type* frm,1259    const intern_type* frm_end,1260    const intern_type*& frm_nxt,1261    extern_type* to,1262    extern_type* to_end,1263    extern_type*& to_nxt) const {1264  // look for first internal null in frm1265  const intern_type* fend = frm;1266  for (; fend != frm_end; ++fend)1267    if (*fend == 0)1268      break;1269  // loop over all null-terminated sequences in frm1270  to_nxt = to;1271  for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) {1272    // save state in case it is needed to recover to_nxt on error1273    mbstate_t save_state = st;1274    size_t n             = __locale::__wcsnrtombs(1275        to, &frm_nxt, static_cast<size_t>(fend - frm), static_cast<size_t>(to_end - to), &st, __l_);1276    if (n == size_t(-1)) {1277      // need to recover to_nxt1278      for (to_nxt = to; frm != frm_nxt; ++frm) {1279        n = __locale::__wcrtomb(to_nxt, *frm, &save_state, __l_);1280        if (n == size_t(-1))1281          break;1282        to_nxt += n;1283      }1284      frm_nxt = frm;1285      return error;1286    }1287    if (n == 0)1288      return partial;1289    to_nxt += n;1290    if (to_nxt == to_end)1291      break;1292    if (fend != frm_end) // set up next null terminated sequence1293    {1294      // Try to write the terminating null1295      extern_type tmp[MB_LEN_MAX];1296      n = __locale::__wcrtomb(tmp, intern_type(), &st, __l_);1297      if (n == size_t(-1)) // on error1298        return error;1299      if (n > static_cast<size_t>(to_end - to_nxt)) // is there room?1300        return partial;1301      for (extern_type* p = tmp; n; --n) // write it1302        *to_nxt++ = *p++;1303      ++frm_nxt;1304      // look for next null in frm1305      for (fend = frm_nxt; fend != frm_end; ++fend)1306        if (*fend == 0)1307          break;1308    }1309  }1310  return frm_nxt == frm_end ? ok : partial;1311}1312 1313codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_in(1314    state_type& st,1315    const extern_type* frm,1316    const extern_type* frm_end,1317    const extern_type*& frm_nxt,1318    intern_type* to,1319    intern_type* to_end,1320    intern_type*& to_nxt) const {1321  // look for first internal null in frm1322  const extern_type* fend = frm;1323  for (; fend != frm_end; ++fend)1324    if (*fend == 0)1325      break;1326  // loop over all null-terminated sequences in frm1327  to_nxt = to;1328  for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) {1329    // save state in case it is needed to recover to_nxt on error1330    mbstate_t save_state = st;1331    size_t n             = __locale::__mbsnrtowcs(1332        to, &frm_nxt, static_cast<size_t>(fend - frm), static_cast<size_t>(to_end - to), &st, __l_);1333    if (n == size_t(-1)) {1334      // need to recover to_nxt1335      for (to_nxt = to; frm != frm_nxt; ++to_nxt) {1336        n = __locale::__mbrtowc(to_nxt, frm, static_cast<size_t>(fend - frm), &save_state, __l_);1337        switch (n) {1338        case 0:1339          ++frm;1340          break;1341        case size_t(-1):1342          frm_nxt = frm;1343          return error;1344        case size_t(-2):1345          frm_nxt = frm;1346          return partial;1347        default:1348          frm += n;1349          break;1350        }1351      }1352      frm_nxt = frm;1353      return frm_nxt == frm_end ? ok : partial;1354    }1355    if (n == size_t(-1))1356      return error;1357    to_nxt += n;1358    if (to_nxt == to_end)1359      break;1360    if (fend != frm_end) // set up next null terminated sequence1361    {1362      // Try to write the terminating null1363      n = __locale::__mbrtowc(to_nxt, frm_nxt, 1, &st, __l_);1364      if (n != 0) // on error1365        return error;1366      ++to_nxt;1367      ++frm_nxt;1368      // look for next null in frm1369      for (fend = frm_nxt; fend != frm_end; ++fend)1370        if (*fend == 0)1371          break;1372    }1373  }1374  return frm_nxt == frm_end ? ok : partial;1375}1376 1377codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_unshift(1378    state_type& st, extern_type* to, extern_type* to_end, extern_type*& to_nxt) const {1379  to_nxt = to;1380  extern_type tmp[MB_LEN_MAX];1381  size_t n = __locale::__wcrtomb(tmp, intern_type(), &st, __l_);1382  if (n == size_t(-1) || n == 0) // on error1383    return error;1384  --n;1385  if (n > static_cast<size_t>(to_end - to_nxt)) // is there room?1386    return partial;1387  for (extern_type* p = tmp; n; --n) // write it1388    *to_nxt++ = *p++;1389  return ok;1390}1391 1392int codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept {1393  if (__locale::__mbtowc(nullptr, nullptr, MB_LEN_MAX, __l_) != 0)1394    return -1;1395 1396  // stateless encoding1397  if (__l_ == 0 || __locale::__mb_len_max(__l_) == 1) // there are no known constant length encodings1398    return 1;                                         // which take more than 1 char to form a wchar_t1399  return 0;1400}1401 1402bool codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }1403 1404int codecvt<wchar_t, char, mbstate_t>::do_length(1405    state_type& st, const extern_type* frm, const extern_type* frm_end, size_t mx) const {1406  int nbytes = 0;1407  for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) {1408    size_t n = __locale::__mbrlen(frm, static_cast<size_t>(frm_end - frm), &st, __l_);1409    switch (n) {1410    case 0:1411      ++nbytes;1412      ++frm;1413      break;1414    case size_t(-1):1415    case size_t(-2):1416      return nbytes;1417    default:1418      nbytes += n;1419      frm += n;1420      break;1421    }1422  }1423  return nbytes;1424}1425 1426int codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept {1427  return __l_ == 0 ? 1 : static_cast<int>(__locale::__mb_len_max(__l_));1428}1429#endif // _LIBCPP_HAS_WIDE_CHARACTERS1430 1431//                                     Valid UTF ranges1432//     UTF-32               UTF-16                          UTF-8               # of code points1433//                     first      second       first   second    third   fourth1434// 000000 - 00007F  0000 - 007F               00 - 7F                                 1271435// 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       19201436// 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              20481437// 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             491521438// 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              20481439// 00D800 - 00DFFF                invalid1440// 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              81921441// 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   1966081442// 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   7864321443// 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    655361444 1445_LIBCPP_SUPPRESS_DEPRECATED_PUSH1446static codecvt_base::result utf16_to_utf8(1447    const uint16_t* frm,1448    const uint16_t* frm_end,1449    const uint16_t*& frm_nxt,1450    uint8_t* to,1451    uint8_t* to_end,1452    uint8_t*& to_nxt,1453    unsigned long Maxcode = 0x10FFFF,1454    codecvt_mode mode     = codecvt_mode(0)) {1455  frm_nxt = frm;1456  to_nxt  = to;1457  if (mode & generate_header) {1458    if (to_end - to_nxt < 3)1459      return codecvt_base::partial;1460    *to_nxt++ = static_cast<uint8_t>(0xEF);1461    *to_nxt++ = static_cast<uint8_t>(0xBB);1462    *to_nxt++ = static_cast<uint8_t>(0xBF);1463  }1464  for (; frm_nxt < frm_end; ++frm_nxt) {1465    uint16_t wc1 = *frm_nxt;1466    if (wc1 > Maxcode)1467      return codecvt_base::error;1468    if (wc1 < 0x0080) {1469      if (to_end - to_nxt < 1)1470        return codecvt_base::partial;1471      *to_nxt++ = static_cast<uint8_t>(wc1);1472    } else if (wc1 < 0x0800) {1473      if (to_end - to_nxt < 2)1474        return codecvt_base::partial;1475      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));1476      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));1477    } else if (wc1 < 0xD800) {1478      if (to_end - to_nxt < 3)1479        return codecvt_base::partial;1480      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1481      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1482      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1483    } else if (wc1 < 0xDC00) {1484      if (frm_end - frm_nxt < 2)1485        return codecvt_base::partial;1486      uint16_t wc2 = frm_nxt[1];1487      if ((wc2 & 0xFC00) != 0xDC00)1488        return codecvt_base::error;1489      if (to_end - to_nxt < 4)1490        return codecvt_base::partial;1491      if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)1492        return codecvt_base::error;1493      ++frm_nxt;1494      uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;1495      *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));1496      *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));1497      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));1498      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));1499    } else if (wc1 < 0xE000) {1500      return codecvt_base::error;1501    } else {1502      if (to_end - to_nxt < 3)1503        return codecvt_base::partial;1504      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1505      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1506      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1507    }1508  }1509  return codecvt_base::ok;1510}1511 1512static codecvt_base::result utf16_to_utf8(1513    const uint32_t* frm,1514    const uint32_t* frm_end,1515    const uint32_t*& frm_nxt,1516    uint8_t* to,1517    uint8_t* to_end,1518    uint8_t*& to_nxt,1519    unsigned long Maxcode = 0x10FFFF,1520    codecvt_mode mode     = codecvt_mode(0)) {1521  frm_nxt = frm;1522  to_nxt  = to;1523  if (mode & generate_header) {1524    if (to_end - to_nxt < 3)1525      return codecvt_base::partial;1526    *to_nxt++ = static_cast<uint8_t>(0xEF);1527    *to_nxt++ = static_cast<uint8_t>(0xBB);1528    *to_nxt++ = static_cast<uint8_t>(0xBF);1529  }1530  for (; frm_nxt < frm_end; ++frm_nxt) {1531    uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);1532    if (wc1 > Maxcode)1533      return codecvt_base::error;1534    if (wc1 < 0x0080) {1535      if (to_end - to_nxt < 1)1536        return codecvt_base::partial;1537      *to_nxt++ = static_cast<uint8_t>(wc1);1538    } else if (wc1 < 0x0800) {1539      if (to_end - to_nxt < 2)1540        return codecvt_base::partial;1541      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));1542      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));1543    } else if (wc1 < 0xD800) {1544      if (to_end - to_nxt < 3)1545        return codecvt_base::partial;1546      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1547      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1548      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1549    } else if (wc1 < 0xDC00) {1550      if (frm_end - frm_nxt < 2)1551        return codecvt_base::partial;1552      uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);1553      if ((wc2 & 0xFC00) != 0xDC00)1554        return codecvt_base::error;1555      if (to_end - to_nxt < 4)1556        return codecvt_base::partial;1557      if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) + ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)1558        return codecvt_base::error;1559      ++frm_nxt;1560      uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;1561      *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));1562      *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));1563      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));1564      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));1565    } else if (wc1 < 0xE000) {1566      return codecvt_base::error;1567    } else {1568      if (to_end - to_nxt < 3)1569        return codecvt_base::partial;1570      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));1571      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));1572      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));1573    }1574  }1575  return codecvt_base::ok;1576}1577 1578static codecvt_base::result utf8_to_utf16(1579    const uint8_t* frm,1580    const uint8_t* frm_end,1581    const uint8_t*& frm_nxt,1582    uint16_t* to,1583    uint16_t* to_end,1584    uint16_t*& to_nxt,1585    unsigned long Maxcode = 0x10FFFF,1586    codecvt_mode mode     = codecvt_mode(0)) {1587  frm_nxt = frm;1588  to_nxt  = to;1589  if (mode & consume_header) {1590    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1591      frm_nxt += 3;1592  }1593  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {1594    uint8_t c1 = *frm_nxt;1595    if (c1 > Maxcode)1596      return codecvt_base::error;1597    if (c1 < 0x80) {1598      *to_nxt = static_cast<uint16_t>(c1);1599      ++frm_nxt;1600    } else if (c1 < 0xC2) {1601      return codecvt_base::error;1602    } else if (c1 < 0xE0) {1603      if (frm_end - frm_nxt < 2)1604        return codecvt_base::partial;1605      uint8_t c2 = frm_nxt[1];1606      if ((c2 & 0xC0) != 0x80)1607        return codecvt_base::error;1608      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));1609      if (t > Maxcode)1610        return codecvt_base::error;1611      *to_nxt = t;1612      frm_nxt += 2;1613    } else if (c1 < 0xF0) {1614      if (frm_end - frm_nxt < 2)1615        return codecvt_base::partial;1616      uint8_t c2 = frm_nxt[1];1617      switch (c1) {1618      case 0xE0:1619        if ((c2 & 0xE0) != 0xA0)1620          return codecvt_base::error;1621        break;1622      case 0xED:1623        if ((c2 & 0xE0) != 0x80)1624          return codecvt_base::error;1625        break;1626      default:1627        if ((c2 & 0xC0) != 0x80)1628          return codecvt_base::error;1629        break;1630      }1631      if (frm_end - frm_nxt < 3)1632        return codecvt_base::partial;1633      uint8_t c3 = frm_nxt[2];1634      if ((c3 & 0xC0) != 0x80)1635        return codecvt_base::error;1636      uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));1637      if (t > Maxcode)1638        return codecvt_base::error;1639      *to_nxt = t;1640      frm_nxt += 3;1641    } else if (c1 < 0xF5) {1642      if (frm_end - frm_nxt < 2)1643        return codecvt_base::partial;1644      uint8_t c2 = frm_nxt[1];1645      switch (c1) {1646      case 0xF0:1647        if (!(0x90 <= c2 && c2 <= 0xBF))1648          return codecvt_base::error;1649        break;1650      case 0xF4:1651        if ((c2 & 0xF0) != 0x80)1652          return codecvt_base::error;1653        break;1654      default:1655        if ((c2 & 0xC0) != 0x80)1656          return codecvt_base::error;1657        break;1658      }1659      if (frm_end - frm_nxt < 3)1660        return codecvt_base::partial;1661      uint8_t c3 = frm_nxt[2];1662      if ((c3 & 0xC0) != 0x80)1663        return codecvt_base::error;1664      if (frm_end - frm_nxt < 4)1665        return codecvt_base::partial;1666      uint8_t c4 = frm_nxt[3];1667      if ((c4 & 0xC0) != 0x80)1668        return codecvt_base::error;1669      if (to_end - to_nxt < 2)1670        return codecvt_base::partial;1671      if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)1672        return codecvt_base::error;1673      *to_nxt = static_cast<uint16_t>(1674          0xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));1675      *++to_nxt = static_cast<uint16_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));1676      frm_nxt += 4;1677    } else {1678      return codecvt_base::error;1679    }1680  }1681  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;1682}1683 1684static codecvt_base::result utf8_to_utf16(1685    const uint8_t* frm,1686    const uint8_t* frm_end,1687    const uint8_t*& frm_nxt,1688    uint32_t* to,1689    uint32_t* to_end,1690    uint32_t*& to_nxt,1691    unsigned long Maxcode = 0x10FFFF,1692    codecvt_mode mode     = codecvt_mode(0)) {1693  frm_nxt = frm;1694  to_nxt  = to;1695  if (mode & consume_header) {1696    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1697      frm_nxt += 3;1698  }1699  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {1700    uint8_t c1 = *frm_nxt;1701    if (c1 > Maxcode)1702      return codecvt_base::error;1703    if (c1 < 0x80) {1704      *to_nxt = static_cast<uint32_t>(c1);1705      ++frm_nxt;1706    } else if (c1 < 0xC2) {1707      return codecvt_base::error;1708    } else if (c1 < 0xE0) {1709      if (frm_end - frm_nxt < 2)1710        return codecvt_base::partial;1711      uint8_t c2 = frm_nxt[1];1712      if ((c2 & 0xC0) != 0x80)1713        return codecvt_base::error;1714      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));1715      if (t > Maxcode)1716        return codecvt_base::error;1717      *to_nxt = static_cast<uint32_t>(t);1718      frm_nxt += 2;1719    } else if (c1 < 0xF0) {1720      if (frm_end - frm_nxt < 2)1721        return codecvt_base::partial;1722      uint8_t c2 = frm_nxt[1];1723      switch (c1) {1724      case 0xE0:1725        if ((c2 & 0xE0) != 0xA0)1726          return codecvt_base::error;1727        break;1728      case 0xED:1729        if ((c2 & 0xE0) != 0x80)1730          return codecvt_base::error;1731        break;1732      default:1733        if ((c2 & 0xC0) != 0x80)1734          return codecvt_base::error;1735        break;1736      }1737      if (frm_end - frm_nxt < 3)1738        return codecvt_base::partial;1739      uint8_t c3 = frm_nxt[2];1740      if ((c3 & 0xC0) != 0x80)1741        return codecvt_base::error;1742      uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));1743      if (t > Maxcode)1744        return codecvt_base::error;1745      *to_nxt = static_cast<uint32_t>(t);1746      frm_nxt += 3;1747    } else if (c1 < 0xF5) {1748      if (frm_end - frm_nxt < 2)1749        return codecvt_base::partial;1750      uint8_t c2 = frm_nxt[1];1751      switch (c1) {1752      case 0xF0:1753        if (!(0x90 <= c2 && c2 <= 0xBF))1754          return codecvt_base::error;1755        break;1756      case 0xF4:1757        if ((c2 & 0xF0) != 0x80)1758          return codecvt_base::error;1759        break;1760      default:1761        if ((c2 & 0xC0) != 0x80)1762          return codecvt_base::error;1763        break;1764      }1765      if (frm_end - frm_nxt < 3)1766        return codecvt_base::partial;1767      uint8_t c3 = frm_nxt[2];1768      if ((c3 & 0xC0) != 0x80)1769        return codecvt_base::error;1770      if (frm_end - frm_nxt < 4)1771        return codecvt_base::partial;1772      uint8_t c4 = frm_nxt[3];1773      if ((c4 & 0xC0) != 0x80)1774        return codecvt_base::error;1775      if (to_end - to_nxt < 2)1776        return codecvt_base::partial;1777      if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)1778        return codecvt_base::error;1779      *to_nxt = static_cast<uint32_t>(1780          0xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));1781      *++to_nxt = static_cast<uint32_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));1782      frm_nxt += 4;1783    } else {1784      return codecvt_base::error;1785    }1786  }1787  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;1788}1789 1790static int utf8_to_utf16_length(1791    const uint8_t* frm,1792    const uint8_t* frm_end,1793    size_t mx,1794    unsigned long Maxcode = 0x10FFFF,1795    codecvt_mode mode     = codecvt_mode(0)) {1796  const uint8_t* frm_nxt = frm;1797  if (mode & consume_header) {1798    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1799      frm_nxt += 3;1800  }1801  for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) {1802    uint8_t c1 = *frm_nxt;1803    if (c1 > Maxcode)1804      break;1805    if (c1 < 0x80) {1806      ++frm_nxt;1807    } else if (c1 < 0xC2) {1808      break;1809    } else if (c1 < 0xE0) {1810      if ((frm_end - frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)1811        break;1812      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));1813      if (t > Maxcode)1814        break;1815      frm_nxt += 2;1816    } else if (c1 < 0xF0) {1817      if (frm_end - frm_nxt < 3)1818        break;1819      uint8_t c2 = frm_nxt[1];1820      uint8_t c3 = frm_nxt[2];1821      switch (c1) {1822      case 0xE0:1823        if ((c2 & 0xE0) != 0xA0)1824          return static_cast<int>(frm_nxt - frm);1825        break;1826      case 0xED:1827        if ((c2 & 0xE0) != 0x80)1828          return static_cast<int>(frm_nxt - frm);1829        break;1830      default:1831        if ((c2 & 0xC0) != 0x80)1832          return static_cast<int>(frm_nxt - frm);1833        break;1834      }1835      if ((c3 & 0xC0) != 0x80)1836        break;1837      if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)1838        break;1839      frm_nxt += 3;1840    } else if (c1 < 0xF5) {1841      if (frm_end - frm_nxt < 4 || mx - nchar16_t < 2)1842        break;1843      uint8_t c2 = frm_nxt[1];1844      uint8_t c3 = frm_nxt[2];1845      uint8_t c4 = frm_nxt[3];1846      switch (c1) {1847      case 0xF0:1848        if (!(0x90 <= c2 && c2 <= 0xBF))1849          return static_cast<int>(frm_nxt - frm);1850        break;1851      case 0xF4:1852        if ((c2 & 0xF0) != 0x80)1853          return static_cast<int>(frm_nxt - frm);1854        break;1855      default:1856        if ((c2 & 0xC0) != 0x80)1857          return static_cast<int>(frm_nxt - frm);1858        break;1859      }1860      if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)1861        break;1862      if ((((c1 & 7UL) << 18) + ((c2 & 0x3FUL) << 12) + ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)1863        break;1864      ++nchar16_t;1865      frm_nxt += 4;1866    } else {1867      break;1868    }1869  }1870  return static_cast<int>(frm_nxt - frm);1871}1872 1873static codecvt_base::result ucs4_to_utf8(1874    const uint32_t* frm,1875    const uint32_t* frm_end,1876    const uint32_t*& frm_nxt,1877    uint8_t* to,1878    uint8_t* to_end,1879    uint8_t*& to_nxt,1880    unsigned long Maxcode = 0x10FFFF,1881    codecvt_mode mode     = codecvt_mode(0)) {1882  frm_nxt = frm;1883  to_nxt  = to;1884  if (mode & generate_header) {1885    if (to_end - to_nxt < 3)1886      return codecvt_base::partial;1887    *to_nxt++ = static_cast<uint8_t>(0xEF);1888    *to_nxt++ = static_cast<uint8_t>(0xBB);1889    *to_nxt++ = static_cast<uint8_t>(0xBF);1890  }1891  for (; frm_nxt < frm_end; ++frm_nxt) {1892    uint32_t wc = *frm_nxt;1893    if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)1894      return codecvt_base::error;1895    if (wc < 0x000080) {1896      if (to_end - to_nxt < 1)1897        return codecvt_base::partial;1898      *to_nxt++ = static_cast<uint8_t>(wc);1899    } else if (wc < 0x000800) {1900      if (to_end - to_nxt < 2)1901        return codecvt_base::partial;1902      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));1903      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));1904    } else if (wc < 0x010000) {1905      if (to_end - to_nxt < 3)1906        return codecvt_base::partial;1907      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));1908      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));1909      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));1910    } else // if (wc < 0x110000)1911    {1912      if (to_end - to_nxt < 4)1913        return codecvt_base::partial;1914      *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));1915      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));1916      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));1917      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));1918    }1919  }1920  return codecvt_base::ok;1921}1922 1923static codecvt_base::result utf8_to_ucs4(1924    const uint8_t* frm,1925    const uint8_t* frm_end,1926    const uint8_t*& frm_nxt,1927    uint32_t* to,1928    uint32_t* to_end,1929    uint32_t*& to_nxt,1930    unsigned long Maxcode = 0x10FFFF,1931    codecvt_mode mode     = codecvt_mode(0)) {1932  frm_nxt = frm;1933  to_nxt  = to;1934  if (mode & consume_header) {1935    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)1936      frm_nxt += 3;1937  }1938  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {1939    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);1940    if (c1 < 0x80) {1941      if (c1 > Maxcode)1942        return codecvt_base::error;1943      *to_nxt = static_cast<uint32_t>(c1);1944      ++frm_nxt;1945    } else if (c1 < 0xC2) {1946      return codecvt_base::error;1947    } else if (c1 < 0xE0) {1948      if (frm_end - frm_nxt < 2)1949        return codecvt_base::partial;1950      uint8_t c2 = frm_nxt[1];1951      if ((c2 & 0xC0) != 0x80)1952        return codecvt_base::error;1953      uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));1954      if (t > Maxcode)1955        return codecvt_base::error;1956      *to_nxt = t;1957      frm_nxt += 2;1958    } else if (c1 < 0xF0) {1959      if (frm_end - frm_nxt < 2)1960        return codecvt_base::partial;1961      uint8_t c2 = frm_nxt[1];1962      switch (c1) {1963      case 0xE0:1964        if ((c2 & 0xE0) != 0xA0)1965          return codecvt_base::error;1966        break;1967      case 0xED:1968        if ((c2 & 0xE0) != 0x80)1969          return codecvt_base::error;1970        break;1971      default:1972        if ((c2 & 0xC0) != 0x80)1973          return codecvt_base::error;1974        break;1975      }1976      if (frm_end - frm_nxt < 3)1977        return codecvt_base::partial;1978      uint8_t c3 = frm_nxt[2];1979      if ((c3 & 0xC0) != 0x80)1980        return codecvt_base::error;1981      uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));1982      if (t > Maxcode)1983        return codecvt_base::error;1984      *to_nxt = t;1985      frm_nxt += 3;1986    } else if (c1 < 0xF5) {1987      if (frm_end - frm_nxt < 2)1988        return codecvt_base::partial;1989      uint8_t c2 = frm_nxt[1];1990      switch (c1) {1991      case 0xF0:1992        if (!(0x90 <= c2 && c2 <= 0xBF))1993          return codecvt_base::error;1994        break;1995      case 0xF4:1996        if ((c2 & 0xF0) != 0x80)1997          return codecvt_base::error;1998        break;1999      default:2000        if ((c2 & 0xC0) != 0x80)2001          return codecvt_base::error;2002        break;2003      }2004      if (frm_end - frm_nxt < 3)2005        return codecvt_base::partial;2006      uint8_t c3 = frm_nxt[2];2007      if ((c3 & 0xC0) != 0x80)2008        return codecvt_base::error;2009      if (frm_end - frm_nxt < 4)2010        return codecvt_base::partial;2011      uint8_t c4 = frm_nxt[3];2012      if ((c4 & 0xC0) != 0x80)2013        return codecvt_base::error;2014      uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) | ((c3 & 0x3F) << 6) | (c4 & 0x3F));2015      if (t > Maxcode)2016        return codecvt_base::error;2017      *to_nxt = t;2018      frm_nxt += 4;2019    } else {2020      return codecvt_base::error;2021    }2022  }2023  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2024}2025 2026static int utf8_to_ucs4_length(2027    const uint8_t* frm,2028    const uint8_t* frm_end,2029    size_t mx,2030    unsigned long Maxcode = 0x10FFFF,2031    codecvt_mode mode     = codecvt_mode(0)) {2032  const uint8_t* frm_nxt = frm;2033  if (mode & consume_header) {2034    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2035      frm_nxt += 3;2036  }2037  for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) {2038    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2039    if (c1 < 0x80) {2040      if (c1 > Maxcode)2041        break;2042      ++frm_nxt;2043    } else if (c1 < 0xC2) {2044      break;2045    } else if (c1 < 0xE0) {2046      if ((frm_end - frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))2047        break;2048      if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)2049        break;2050      frm_nxt += 2;2051    } else if (c1 < 0xF0) {2052      if (frm_end - frm_nxt < 3)2053        break;2054      uint8_t c2 = frm_nxt[1];2055      uint8_t c3 = frm_nxt[2];2056      switch (c1) {2057      case 0xE0:2058        if ((c2 & 0xE0) != 0xA0)2059          return static_cast<int>(frm_nxt - frm);2060        break;2061      case 0xED:2062        if ((c2 & 0xE0) != 0x80)2063          return static_cast<int>(frm_nxt - frm);2064        break;2065      default:2066        if ((c2 & 0xC0) != 0x80)2067          return static_cast<int>(frm_nxt - frm);2068        break;2069      }2070      if ((c3 & 0xC0) != 0x80)2071        break;2072      if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)2073        break;2074      frm_nxt += 3;2075    } else if (c1 < 0xF5) {2076      if (frm_end - frm_nxt < 4)2077        break;2078      uint8_t c2 = frm_nxt[1];2079      uint8_t c3 = frm_nxt[2];2080      uint8_t c4 = frm_nxt[3];2081      switch (c1) {2082      case 0xF0:2083        if (!(0x90 <= c2 && c2 <= 0xBF))2084          return static_cast<int>(frm_nxt - frm);2085        break;2086      case 0xF4:2087        if ((c2 & 0xF0) != 0x80)2088          return static_cast<int>(frm_nxt - frm);2089        break;2090      default:2091        if ((c2 & 0xC0) != 0x80)2092          return static_cast<int>(frm_nxt - frm);2093        break;2094      }2095      if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)2096        break;2097      if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)2098        break;2099      frm_nxt += 4;2100    } else {2101      break;2102    }2103  }2104  return static_cast<int>(frm_nxt - frm);2105}2106 2107static codecvt_base::result ucs2_to_utf8(2108    const uint16_t* frm,2109    const uint16_t* frm_end,2110    const uint16_t*& frm_nxt,2111    uint8_t* to,2112    uint8_t* to_end,2113    uint8_t*& to_nxt,2114    unsigned long Maxcode = 0x10FFFF,2115    codecvt_mode mode     = codecvt_mode(0)) {2116  frm_nxt = frm;2117  to_nxt  = to;2118  if (mode & generate_header) {2119    if (to_end - to_nxt < 3)2120      return codecvt_base::partial;2121    *to_nxt++ = static_cast<uint8_t>(0xEF);2122    *to_nxt++ = static_cast<uint8_t>(0xBB);2123    *to_nxt++ = static_cast<uint8_t>(0xBF);2124  }2125  for (; frm_nxt < frm_end; ++frm_nxt) {2126    uint16_t wc = *frm_nxt;2127    if ((wc & 0xF800) == 0xD800 || wc > Maxcode)2128      return codecvt_base::error;2129    if (wc < 0x0080) {2130      if (to_end - to_nxt < 1)2131        return codecvt_base::partial;2132      *to_nxt++ = static_cast<uint8_t>(wc);2133    } else if (wc < 0x0800) {2134      if (to_end - to_nxt < 2)2135        return codecvt_base::partial;2136      *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));2137      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));2138    } else // if (wc <= 0xFFFF)2139    {2140      if (to_end - to_nxt < 3)2141        return codecvt_base::partial;2142      *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));2143      *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));2144      *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));2145    }2146  }2147  return codecvt_base::ok;2148}2149 2150static codecvt_base::result utf8_to_ucs2(2151    const uint8_t* frm,2152    const uint8_t* frm_end,2153    const uint8_t*& frm_nxt,2154    uint16_t* to,2155    uint16_t* to_end,2156    uint16_t*& to_nxt,2157    unsigned long Maxcode = 0x10FFFF,2158    codecvt_mode mode     = codecvt_mode(0)) {2159  frm_nxt = frm;2160  to_nxt  = to;2161  if (mode & consume_header) {2162    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2163      frm_nxt += 3;2164  }2165  for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) {2166    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2167    if (c1 < 0x80) {2168      if (c1 > Maxcode)2169        return codecvt_base::error;2170      *to_nxt = static_cast<uint16_t>(c1);2171      ++frm_nxt;2172    } else if (c1 < 0xC2) {2173      return codecvt_base::error;2174    } else if (c1 < 0xE0) {2175      if (frm_end - frm_nxt < 2)2176        return codecvt_base::partial;2177      uint8_t c2 = frm_nxt[1];2178      if ((c2 & 0xC0) != 0x80)2179        return codecvt_base::error;2180      uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));2181      if (t > Maxcode)2182        return codecvt_base::error;2183      *to_nxt = t;2184      frm_nxt += 2;2185    } else if (c1 < 0xF0) {2186      if (frm_end - frm_nxt < 2)2187        return codecvt_base::partial;2188      uint8_t c2 = frm_nxt[1];2189      switch (c1) {2190      case 0xE0:2191        if ((c2 & 0xE0) != 0xA0)2192          return codecvt_base::error;2193        break;2194      case 0xED:2195        if ((c2 & 0xE0) != 0x80)2196          return codecvt_base::error;2197        break;2198      default:2199        if ((c2 & 0xC0) != 0x80)2200          return codecvt_base::error;2201        break;2202      }2203      if (frm_end - frm_nxt < 3)2204        return codecvt_base::partial;2205      uint8_t c3 = frm_nxt[2];2206      if ((c3 & 0xC0) != 0x80)2207        return codecvt_base::error;2208      uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));2209      if (t > Maxcode)2210        return codecvt_base::error;2211      *to_nxt = t;2212      frm_nxt += 3;2213    } else {2214      return codecvt_base::error;2215    }2216  }2217  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2218}2219 2220static int utf8_to_ucs2_length(2221    const uint8_t* frm,2222    const uint8_t* frm_end,2223    size_t mx,2224    unsigned long Maxcode = 0x10FFFF,2225    codecvt_mode mode     = codecvt_mode(0)) {2226  const uint8_t* frm_nxt = frm;2227  if (mode & consume_header) {2228    if (frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)2229      frm_nxt += 3;2230  }2231  for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) {2232    uint8_t c1 = static_cast<uint8_t>(*frm_nxt);2233    if (c1 < 0x80) {2234      if (c1 > Maxcode)2235        break;2236      ++frm_nxt;2237    } else if (c1 < 0xC2) {2238      break;2239    } else if (c1 < 0xE0) {2240      if ((frm_end - frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))2241        break;2242      if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)2243        break;2244      frm_nxt += 2;2245    } else if (c1 < 0xF0) {2246      if (frm_end - frm_nxt < 3)2247        break;2248      uint8_t c2 = frm_nxt[1];2249      uint8_t c3 = frm_nxt[2];2250      switch (c1) {2251      case 0xE0:2252        if ((c2 & 0xE0) != 0xA0)2253          return static_cast<int>(frm_nxt - frm);2254        break;2255      case 0xED:2256        if ((c2 & 0xE0) != 0x80)2257          return static_cast<int>(frm_nxt - frm);2258        break;2259      default:2260        if ((c2 & 0xC0) != 0x80)2261          return static_cast<int>(frm_nxt - frm);2262        break;2263      }2264      if ((c3 & 0xC0) != 0x80)2265        break;2266      if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)2267        break;2268      frm_nxt += 3;2269    } else {2270      break;2271    }2272  }2273  return static_cast<int>(frm_nxt - frm);2274}2275 2276static codecvt_base::result ucs4_to_utf16be(2277    const uint32_t* frm,2278    const uint32_t* frm_end,2279    const uint32_t*& frm_nxt,2280    uint8_t* to,2281    uint8_t* to_end,2282    uint8_t*& to_nxt,2283    unsigned long Maxcode = 0x10FFFF,2284    codecvt_mode mode     = codecvt_mode(0)) {2285  frm_nxt = frm;2286  to_nxt  = to;2287  if (mode & generate_header) {2288    if (to_end - to_nxt < 2)2289      return codecvt_base::partial;2290    *to_nxt++ = static_cast<uint8_t>(0xFE);2291    *to_nxt++ = static_cast<uint8_t>(0xFF);2292  }2293  for (; frm_nxt < frm_end; ++frm_nxt) {2294    uint32_t wc = *frm_nxt;2295    if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)2296      return codecvt_base::error;2297    if (wc < 0x010000) {2298      if (to_end - to_nxt < 2)2299        return codecvt_base::partial;2300      *to_nxt++ = static_cast<uint8_t>(wc >> 8);2301      *to_nxt++ = static_cast<uint8_t>(wc);2302    } else {2303      if (to_end - to_nxt < 4)2304        return codecvt_base::partial;2305      uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));2306      *to_nxt++  = static_cast<uint8_t>(t >> 8);2307      *to_nxt++  = static_cast<uint8_t>(t);2308      t          = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));2309      *to_nxt++  = static_cast<uint8_t>(t >> 8);2310      *to_nxt++  = static_cast<uint8_t>(t);2311    }2312  }2313  return codecvt_base::ok;2314}2315 2316static codecvt_base::result utf16be_to_ucs4(2317    const uint8_t* frm,2318    const uint8_t* frm_end,2319    const uint8_t*& frm_nxt,2320    uint32_t* to,2321    uint32_t* to_end,2322    uint32_t*& to_nxt,2323    unsigned long Maxcode = 0x10FFFF,2324    codecvt_mode mode     = codecvt_mode(0)) {2325  frm_nxt = frm;2326  to_nxt  = to;2327  if (mode & consume_header) {2328    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2329      frm_nxt += 2;2330  }2331  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2332    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2333    if ((c1 & 0xFC00) == 0xDC00)2334      return codecvt_base::error;2335    if ((c1 & 0xFC00) != 0xD800) {2336      if (c1 > Maxcode)2337        return codecvt_base::error;2338      *to_nxt = static_cast<uint32_t>(c1);2339      frm_nxt += 2;2340    } else {2341      if (frm_end - frm_nxt < 4)2342        return codecvt_base::partial;2343      uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);2344      if ((c2 & 0xFC00) != 0xDC00)2345        return codecvt_base::error;2346      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2347      if (t > Maxcode)2348        return codecvt_base::error;2349      *to_nxt = t;2350      frm_nxt += 4;2351    }2352  }2353  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2354}2355 2356static int utf16be_to_ucs4_length(2357    const uint8_t* frm,2358    const uint8_t* frm_end,2359    size_t mx,2360    unsigned long Maxcode = 0x10FFFF,2361    codecvt_mode mode     = codecvt_mode(0)) {2362  const uint8_t* frm_nxt = frm;2363  if (mode & consume_header) {2364    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2365      frm_nxt += 2;2366  }2367  for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) {2368    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2369    if ((c1 & 0xFC00) == 0xDC00)2370      break;2371    if ((c1 & 0xFC00) != 0xD800) {2372      if (c1 > Maxcode)2373        break;2374      frm_nxt += 2;2375    } else {2376      if (frm_end - frm_nxt < 4)2377        break;2378      uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);2379      if ((c2 & 0xFC00) != 0xDC00)2380        break;2381      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2382      if (t > Maxcode)2383        break;2384      frm_nxt += 4;2385    }2386  }2387  return static_cast<int>(frm_nxt - frm);2388}2389 2390static codecvt_base::result ucs4_to_utf16le(2391    const uint32_t* frm,2392    const uint32_t* frm_end,2393    const uint32_t*& frm_nxt,2394    uint8_t* to,2395    uint8_t* to_end,2396    uint8_t*& to_nxt,2397    unsigned long Maxcode = 0x10FFFF,2398    codecvt_mode mode     = codecvt_mode(0)) {2399  frm_nxt = frm;2400  to_nxt  = to;2401  if (mode & generate_header) {2402    if (to_end - to_nxt < 2)2403      return codecvt_base::partial;2404    *to_nxt++ = static_cast<uint8_t>(0xFF);2405    *to_nxt++ = static_cast<uint8_t>(0xFE);2406  }2407  for (; frm_nxt < frm_end; ++frm_nxt) {2408    uint32_t wc = *frm_nxt;2409    if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)2410      return codecvt_base::error;2411    if (wc < 0x010000) {2412      if (to_end - to_nxt < 2)2413        return codecvt_base::partial;2414      *to_nxt++ = static_cast<uint8_t>(wc);2415      *to_nxt++ = static_cast<uint8_t>(wc >> 8);2416    } else {2417      if (to_end - to_nxt < 4)2418        return codecvt_base::partial;2419      uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));2420      *to_nxt++  = static_cast<uint8_t>(t);2421      *to_nxt++  = static_cast<uint8_t>(t >> 8);2422      t          = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));2423      *to_nxt++  = static_cast<uint8_t>(t);2424      *to_nxt++  = static_cast<uint8_t>(t >> 8);2425    }2426  }2427  return codecvt_base::ok;2428}2429 2430static codecvt_base::result utf16le_to_ucs4(2431    const uint8_t* frm,2432    const uint8_t* frm_end,2433    const uint8_t*& frm_nxt,2434    uint32_t* to,2435    uint32_t* to_end,2436    uint32_t*& to_nxt,2437    unsigned long Maxcode = 0x10FFFF,2438    codecvt_mode mode     = codecvt_mode(0)) {2439  frm_nxt = frm;2440  to_nxt  = to;2441  if (mode & consume_header) {2442    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2443      frm_nxt += 2;2444  }2445  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2446    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2447    if ((c1 & 0xFC00) == 0xDC00)2448      return codecvt_base::error;2449    if ((c1 & 0xFC00) != 0xD800) {2450      if (c1 > Maxcode)2451        return codecvt_base::error;2452      *to_nxt = static_cast<uint32_t>(c1);2453      frm_nxt += 2;2454    } else {2455      if (frm_end - frm_nxt < 4)2456        return codecvt_base::partial;2457      uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);2458      if ((c2 & 0xFC00) != 0xDC00)2459        return codecvt_base::error;2460      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2461      if (t > Maxcode)2462        return codecvt_base::error;2463      *to_nxt = t;2464      frm_nxt += 4;2465    }2466  }2467  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2468}2469 2470static int utf16le_to_ucs4_length(2471    const uint8_t* frm,2472    const uint8_t* frm_end,2473    size_t mx,2474    unsigned long Maxcode = 0x10FFFF,2475    codecvt_mode mode     = codecvt_mode(0)) {2476  const uint8_t* frm_nxt = frm;2477  if (mode & consume_header) {2478    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2479      frm_nxt += 2;2480  }2481  for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) {2482    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2483    if ((c1 & 0xFC00) == 0xDC00)2484      break;2485    if ((c1 & 0xFC00) != 0xD800) {2486      if (c1 > Maxcode)2487        break;2488      frm_nxt += 2;2489    } else {2490      if (frm_end - frm_nxt < 4)2491        break;2492      uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);2493      if ((c2 & 0xFC00) != 0xDC00)2494        break;2495      uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));2496      if (t > Maxcode)2497        break;2498      frm_nxt += 4;2499    }2500  }2501  return static_cast<int>(frm_nxt - frm);2502}2503 2504static codecvt_base::result ucs2_to_utf16be(2505    const uint16_t* frm,2506    const uint16_t* frm_end,2507    const uint16_t*& frm_nxt,2508    uint8_t* to,2509    uint8_t* to_end,2510    uint8_t*& to_nxt,2511    unsigned long Maxcode = 0x10FFFF,2512    codecvt_mode mode     = codecvt_mode(0)) {2513  frm_nxt = frm;2514  to_nxt  = to;2515  if (mode & generate_header) {2516    if (to_end - to_nxt < 2)2517      return codecvt_base::partial;2518    *to_nxt++ = static_cast<uint8_t>(0xFE);2519    *to_nxt++ = static_cast<uint8_t>(0xFF);2520  }2521  for (; frm_nxt < frm_end; ++frm_nxt) {2522    uint16_t wc = *frm_nxt;2523    if ((wc & 0xF800) == 0xD800 || wc > Maxcode)2524      return codecvt_base::error;2525    if (to_end - to_nxt < 2)2526      return codecvt_base::partial;2527    *to_nxt++ = static_cast<uint8_t>(wc >> 8);2528    *to_nxt++ = static_cast<uint8_t>(wc);2529  }2530  return codecvt_base::ok;2531}2532 2533static codecvt_base::result utf16be_to_ucs2(2534    const uint8_t* frm,2535    const uint8_t* frm_end,2536    const uint8_t*& frm_nxt,2537    uint16_t* to,2538    uint16_t* to_end,2539    uint16_t*& to_nxt,2540    unsigned long Maxcode = 0x10FFFF,2541    codecvt_mode mode     = codecvt_mode(0)) {2542  frm_nxt = frm;2543  to_nxt  = to;2544  if (mode & consume_header) {2545    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2546      frm_nxt += 2;2547  }2548  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2549    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2550    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2551      return codecvt_base::error;2552    *to_nxt = c1;2553    frm_nxt += 2;2554  }2555  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2556}2557 2558static int utf16be_to_ucs2_length(2559    const uint8_t* frm,2560    const uint8_t* frm_end,2561    size_t mx,2562    unsigned long Maxcode = 0x10FFFF,2563    codecvt_mode mode     = codecvt_mode(0)) {2564  const uint8_t* frm_nxt = frm;2565  if (mode & consume_header) {2566    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)2567      frm_nxt += 2;2568  }2569  for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) {2570    uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);2571    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2572      break;2573    frm_nxt += 2;2574  }2575  return static_cast<int>(frm_nxt - frm);2576}2577 2578static codecvt_base::result ucs2_to_utf16le(2579    const uint16_t* frm,2580    const uint16_t* frm_end,2581    const uint16_t*& frm_nxt,2582    uint8_t* to,2583    uint8_t* to_end,2584    uint8_t*& to_nxt,2585    unsigned long Maxcode = 0x10FFFF,2586    codecvt_mode mode     = codecvt_mode(0)) {2587  frm_nxt = frm;2588  to_nxt  = to;2589  if (mode & generate_header) {2590    if (to_end - to_nxt < 2)2591      return codecvt_base::partial;2592    *to_nxt++ = static_cast<uint8_t>(0xFF);2593    *to_nxt++ = static_cast<uint8_t>(0xFE);2594  }2595  for (; frm_nxt < frm_end; ++frm_nxt) {2596    uint16_t wc = *frm_nxt;2597    if ((wc & 0xF800) == 0xD800 || wc > Maxcode)2598      return codecvt_base::error;2599    if (to_end - to_nxt < 2)2600      return codecvt_base::partial;2601    *to_nxt++ = static_cast<uint8_t>(wc);2602    *to_nxt++ = static_cast<uint8_t>(wc >> 8);2603  }2604  return codecvt_base::ok;2605}2606 2607static codecvt_base::result utf16le_to_ucs2(2608    const uint8_t* frm,2609    const uint8_t* frm_end,2610    const uint8_t*& frm_nxt,2611    uint16_t* to,2612    uint16_t* to_end,2613    uint16_t*& to_nxt,2614    unsigned long Maxcode = 0x10FFFF,2615    codecvt_mode mode     = codecvt_mode(0)) {2616  frm_nxt = frm;2617  to_nxt  = to;2618  if (mode & consume_header) {2619    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2620      frm_nxt += 2;2621  }2622  for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) {2623    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2624    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2625      return codecvt_base::error;2626    *to_nxt = c1;2627    frm_nxt += 2;2628  }2629  return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;2630}2631 2632static int utf16le_to_ucs2_length(2633    const uint8_t* frm,2634    const uint8_t* frm_end,2635    size_t mx,2636    unsigned long Maxcode = 0x10FFFF,2637    codecvt_mode mode     = codecvt_mode(0)) {2638  const uint8_t* frm_nxt = frm;2639  frm_nxt                = frm;2640  if (mode & consume_header) {2641    if (frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)2642      frm_nxt += 2;2643  }2644  for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) {2645    uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);2646    if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)2647      break;2648    frm_nxt += 2;2649  }2650  return static_cast<int>(frm_nxt - frm);2651}2652 2653_LIBCPP_SUPPRESS_DEPRECATED_POP2654 2655// template <> class codecvt<char16_t, char, mbstate_t>2656 2657constinit locale::id codecvt<char16_t, char, mbstate_t>::id;2658 2659codecvt<char16_t, char, mbstate_t>::~codecvt() {}2660 2661codecvt<char16_t, char, mbstate_t>::result codecvt<char16_t, char, mbstate_t>::do_out(2662    state_type&,2663    const intern_type* frm,2664    const intern_type* frm_end,2665    const intern_type*& frm_nxt,2666    extern_type* to,2667    extern_type* to_end,2668    extern_type*& to_nxt) const {2669  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);2670  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);2671  const uint16_t* _frm_nxt = _frm;2672  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);2673  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);2674  uint8_t* _to_nxt         = _to;2675  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2676  frm_nxt                  = frm + (_frm_nxt - _frm);2677  to_nxt                   = to + (_to_nxt - _to);2678  return r;2679}2680 2681codecvt<char16_t, char, mbstate_t>::result codecvt<char16_t, char, mbstate_t>::do_in(2682    state_type&,2683    const extern_type* frm,2684    const extern_type* frm_end,2685    const extern_type*& frm_nxt,2686    intern_type* to,2687    intern_type* to_end,2688    intern_type*& to_nxt) const {2689  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2690  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2691  const uint8_t* _frm_nxt = _frm;2692  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);2693  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);2694  uint16_t* _to_nxt       = _to;2695  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2696  frm_nxt                 = frm + (_frm_nxt - _frm);2697  to_nxt                  = to + (_to_nxt - _to);2698  return r;2699}2700 2701codecvt<char16_t, char, mbstate_t>::result2702codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2703  to_nxt = to;2704  return noconv;2705}2706 2707int codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept { return 0; }2708 2709bool codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }2710 2711int codecvt<char16_t, char, mbstate_t>::do_length(2712    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2713  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2714  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2715  return utf8_to_utf16_length(_frm, _frm_end, mx);2716}2717 2718int codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept { return 4; }2719 2720#if _LIBCPP_HAS_CHAR8_T2721 2722// template <> class codecvt<char16_t, char8_t, mbstate_t>2723 2724constinit locale::id codecvt<char16_t, char8_t, mbstate_t>::id;2725 2726codecvt<char16_t, char8_t, mbstate_t>::~codecvt() {}2727 2728codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_out(2729    state_type&,2730    const intern_type* frm,2731    const intern_type* frm_end,2732    const intern_type*& frm_nxt,2733    extern_type* to,2734    extern_type* to_end,2735    extern_type*& to_nxt) const {2736  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);2737  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);2738  const uint16_t* _frm_nxt = _frm;2739  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);2740  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);2741  uint8_t* _to_nxt         = _to;2742  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2743  frm_nxt                  = frm + (_frm_nxt - _frm);2744  to_nxt                   = to + (_to_nxt - _to);2745  return r;2746}2747 2748codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_in(2749    state_type&,2750    const extern_type* frm,2751    const extern_type* frm_end,2752    const extern_type*& frm_nxt,2753    intern_type* to,2754    intern_type* to_end,2755    intern_type*& to_nxt) const {2756  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2757  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2758  const uint8_t* _frm_nxt = _frm;2759  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);2760  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);2761  uint16_t* _to_nxt       = _to;2762  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2763  frm_nxt                 = frm + (_frm_nxt - _frm);2764  to_nxt                  = to + (_to_nxt - _to);2765  return r;2766}2767 2768codecvt<char16_t, char8_t, mbstate_t>::result codecvt<char16_t, char8_t, mbstate_t>::do_unshift(2769    state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2770  to_nxt = to;2771  return noconv;2772}2773 2774int codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept { return 0; }2775 2776bool codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept { return false; }2777 2778int codecvt<char16_t, char8_t, mbstate_t>::do_length(2779    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2780  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2781  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2782  return utf8_to_utf16_length(_frm, _frm_end, mx);2783}2784 2785int codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept { return 4; }2786 2787#endif2788 2789// template <> class codecvt<char32_t, char, mbstate_t>2790 2791constinit locale::id codecvt<char32_t, char, mbstate_t>::id;2792 2793codecvt<char32_t, char, mbstate_t>::~codecvt() {}2794 2795codecvt<char32_t, char, mbstate_t>::result codecvt<char32_t, char, mbstate_t>::do_out(2796    state_type&,2797    const intern_type* frm,2798    const intern_type* frm_end,2799    const intern_type*& frm_nxt,2800    extern_type* to,2801    extern_type* to_end,2802    extern_type*& to_nxt) const {2803  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);2804  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);2805  const uint32_t* _frm_nxt = _frm;2806  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);2807  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);2808  uint8_t* _to_nxt         = _to;2809  result r                 = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2810  frm_nxt                  = frm + (_frm_nxt - _frm);2811  to_nxt                   = to + (_to_nxt - _to);2812  return r;2813}2814 2815codecvt<char32_t, char, mbstate_t>::result codecvt<char32_t, char, mbstate_t>::do_in(2816    state_type&,2817    const extern_type* frm,2818    const extern_type* frm_end,2819    const extern_type*& frm_nxt,2820    intern_type* to,2821    intern_type* to_end,2822    intern_type*& to_nxt) const {2823  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2824  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2825  const uint8_t* _frm_nxt = _frm;2826  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);2827  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);2828  uint32_t* _to_nxt       = _to;2829  result r                = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2830  frm_nxt                 = frm + (_frm_nxt - _frm);2831  to_nxt                  = to + (_to_nxt - _to);2832  return r;2833}2834 2835codecvt<char32_t, char, mbstate_t>::result2836codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2837  to_nxt = to;2838  return noconv;2839}2840 2841int codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept { return 0; }2842 2843bool codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept { return false; }2844 2845int codecvt<char32_t, char, mbstate_t>::do_length(2846    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2847  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2848  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2849  return utf8_to_ucs4_length(_frm, _frm_end, mx);2850}2851 2852int codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept { return 4; }2853 2854#if _LIBCPP_HAS_CHAR8_T2855 2856// template <> class codecvt<char32_t, char8_t, mbstate_t>2857 2858constinit locale::id codecvt<char32_t, char8_t, mbstate_t>::id;2859 2860codecvt<char32_t, char8_t, mbstate_t>::~codecvt() {}2861 2862codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_out(2863    state_type&,2864    const intern_type* frm,2865    const intern_type* frm_end,2866    const intern_type*& frm_nxt,2867    extern_type* to,2868    extern_type* to_end,2869    extern_type*& to_nxt) const {2870  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);2871  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);2872  const uint32_t* _frm_nxt = _frm;2873  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);2874  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);2875  uint8_t* _to_nxt         = _to;2876  result r                 = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2877  frm_nxt                  = frm + (_frm_nxt - _frm);2878  to_nxt                   = to + (_to_nxt - _to);2879  return r;2880}2881 2882codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_in(2883    state_type&,2884    const extern_type* frm,2885    const extern_type* frm_end,2886    const extern_type*& frm_nxt,2887    intern_type* to,2888    intern_type* to_end,2889    intern_type*& to_nxt) const {2890  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2891  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2892  const uint8_t* _frm_nxt = _frm;2893  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);2894  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);2895  uint32_t* _to_nxt       = _to;2896  result r                = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);2897  frm_nxt                 = frm + (_frm_nxt - _frm);2898  to_nxt                  = to + (_to_nxt - _to);2899  return r;2900}2901 2902codecvt<char32_t, char8_t, mbstate_t>::result codecvt<char32_t, char8_t, mbstate_t>::do_unshift(2903    state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2904  to_nxt = to;2905  return noconv;2906}2907 2908int codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept { return 0; }2909 2910bool codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept { return false; }2911 2912int codecvt<char32_t, char8_t, mbstate_t>::do_length(2913    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2914  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2915  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2916  return utf8_to_ucs4_length(_frm, _frm_end, mx);2917}2918 2919int codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept { return 4; }2920 2921#endif2922 2923// __codecvt_utf8<wchar_t>2924 2925#if _LIBCPP_HAS_WIDE_CHARACTERS2926__codecvt_utf8<wchar_t>::result __codecvt_utf8<wchar_t>::do_out(2927    state_type&,2928    const intern_type* frm,2929    const intern_type* frm_end,2930    const intern_type*& frm_nxt,2931    extern_type* to,2932    extern_type* to_end,2933    extern_type*& to_nxt) const {2934#  if defined(_LIBCPP_SHORT_WCHAR)2935  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);2936  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);2937  const uint16_t* _frm_nxt = _frm;2938#  else2939  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);2940  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);2941  const uint32_t* _frm_nxt = _frm;2942#  endif2943  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);2944  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);2945  uint8_t* _to_nxt = _to;2946#  if defined(_LIBCPP_SHORT_WCHAR)2947  result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);2948#  else2949  result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);2950#  endif2951  frm_nxt = frm + (_frm_nxt - _frm);2952  to_nxt  = to + (_to_nxt - _to);2953  return r;2954}2955 2956__codecvt_utf8<wchar_t>::result __codecvt_utf8<wchar_t>::do_in(2957    state_type&,2958    const extern_type* frm,2959    const extern_type* frm_end,2960    const extern_type*& frm_nxt,2961    intern_type* to,2962    intern_type* to_end,2963    intern_type*& to_nxt) const {2964  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2965  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2966  const uint8_t* _frm_nxt = _frm;2967#  if defined(_LIBCPP_SHORT_WCHAR)2968  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);2969  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);2970  uint16_t* _to_nxt = _to;2971  result r          = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);2972#  else2973  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);2974  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);2975  uint32_t* _to_nxt = _to;2976  result r          = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);2977#  endif2978  frm_nxt = frm + (_frm_nxt - _frm);2979  to_nxt  = to + (_to_nxt - _to);2980  return r;2981}2982 2983__codecvt_utf8<wchar_t>::result2984__codecvt_utf8<wchar_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {2985  to_nxt = to;2986  return noconv;2987}2988 2989int __codecvt_utf8<wchar_t>::do_encoding() const noexcept { return 0; }2990 2991bool __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept { return false; }2992 2993int __codecvt_utf8<wchar_t>::do_length(2994    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {2995  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);2996  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);2997#  if defined(_LIBCPP_SHORT_WCHAR)2998  return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);2999#  else3000  return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3001#  endif3002}3003 3004_LIBCPP_SUPPRESS_DEPRECATED_PUSH3005int __codecvt_utf8<wchar_t>::do_max_length() const noexcept {3006#  if defined(_LIBCPP_SHORT_WCHAR)3007  if (__mode_ & consume_header)3008    return 6;3009  return 3;3010#  else3011  if (__mode_ & consume_header)3012    return 7;3013  return 4;3014#  endif3015}3016#endif // _LIBCPP_HAS_WIDE_CHARACTERS3017 3018// __codecvt_utf8<char16_t>3019 3020__codecvt_utf8<char16_t>::result __codecvt_utf8<char16_t>::do_out(3021    state_type&,3022    const intern_type* frm,3023    const intern_type* frm_end,3024    const intern_type*& frm_nxt,3025    extern_type* to,3026    extern_type* to_end,3027    extern_type*& to_nxt) const {3028  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3029  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3030  const uint16_t* _frm_nxt = _frm;3031  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3032  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3033  uint8_t* _to_nxt         = _to;3034  result r                 = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3035  frm_nxt                  = frm + (_frm_nxt - _frm);3036  to_nxt                   = to + (_to_nxt - _to);3037  return r;3038}3039 3040__codecvt_utf8<char16_t>::result __codecvt_utf8<char16_t>::do_in(3041    state_type&,3042    const extern_type* frm,3043    const extern_type* frm_end,3044    const extern_type*& frm_nxt,3045    intern_type* to,3046    intern_type* to_end,3047    intern_type*& to_nxt) const {3048  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3049  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3050  const uint8_t* _frm_nxt = _frm;3051  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);3052  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);3053  uint16_t* _to_nxt       = _to;3054  result r                = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3055  frm_nxt                 = frm + (_frm_nxt - _frm);3056  to_nxt                  = to + (_to_nxt - _to);3057  return r;3058}3059 3060__codecvt_utf8<char16_t>::result3061__codecvt_utf8<char16_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3062  to_nxt = to;3063  return noconv;3064}3065 3066int __codecvt_utf8<char16_t>::do_encoding() const noexcept { return 0; }3067 3068bool __codecvt_utf8<char16_t>::do_always_noconv() const noexcept { return false; }3069 3070int __codecvt_utf8<char16_t>::do_length(3071    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3072  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3073  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3074  return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3075}3076 3077_LIBCPP_SUPPRESS_DEPRECATED_PUSH3078int __codecvt_utf8<char16_t>::do_max_length() const noexcept {3079  if (__mode_ & consume_header)3080    return 6;3081  return 3;3082}3083_LIBCPP_SUPPRESS_DEPRECATED_POP3084 3085// __codecvt_utf8<char32_t>3086 3087__codecvt_utf8<char32_t>::result __codecvt_utf8<char32_t>::do_out(3088    state_type&,3089    const intern_type* frm,3090    const intern_type* frm_end,3091    const intern_type*& frm_nxt,3092    extern_type* to,3093    extern_type* to_end,3094    extern_type*& to_nxt) const {3095  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3096  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3097  const uint32_t* _frm_nxt = _frm;3098  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3099  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3100  uint8_t* _to_nxt         = _to;3101  result r                 = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3102  frm_nxt                  = frm + (_frm_nxt - _frm);3103  to_nxt                   = to + (_to_nxt - _to);3104  return r;3105}3106 3107__codecvt_utf8<char32_t>::result __codecvt_utf8<char32_t>::do_in(3108    state_type&,3109    const extern_type* frm,3110    const extern_type* frm_end,3111    const extern_type*& frm_nxt,3112    intern_type* to,3113    intern_type* to_end,3114    intern_type*& to_nxt) const {3115  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3116  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3117  const uint8_t* _frm_nxt = _frm;3118  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);3119  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);3120  uint32_t* _to_nxt       = _to;3121  result r                = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3122  frm_nxt                 = frm + (_frm_nxt - _frm);3123  to_nxt                  = to + (_to_nxt - _to);3124  return r;3125}3126 3127__codecvt_utf8<char32_t>::result3128__codecvt_utf8<char32_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3129  to_nxt = to;3130  return noconv;3131}3132 3133int __codecvt_utf8<char32_t>::do_encoding() const noexcept { return 0; }3134 3135bool __codecvt_utf8<char32_t>::do_always_noconv() const noexcept { return false; }3136 3137int __codecvt_utf8<char32_t>::do_length(3138    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3139  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3140  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3141  return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3142}3143 3144_LIBCPP_SUPPRESS_DEPRECATED_PUSH3145int __codecvt_utf8<char32_t>::do_max_length() const noexcept {3146  if (__mode_ & consume_header)3147    return 7;3148  return 4;3149}3150_LIBCPP_SUPPRESS_DEPRECATED_POP3151 3152// __codecvt_utf16<wchar_t, false>3153 3154#if _LIBCPP_HAS_WIDE_CHARACTERS3155__codecvt_utf16<wchar_t, false>::result __codecvt_utf16<wchar_t, false>::do_out(3156    state_type&,3157    const intern_type* frm,3158    const intern_type* frm_end,3159    const intern_type*& frm_nxt,3160    extern_type* to,3161    extern_type* to_end,3162    extern_type*& to_nxt) const {3163#  if defined(_LIBCPP_SHORT_WCHAR)3164  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3165  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3166  const uint16_t* _frm_nxt = _frm;3167#  else3168  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3169  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3170  const uint32_t* _frm_nxt = _frm;3171#  endif3172  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);3173  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3174  uint8_t* _to_nxt = _to;3175#  if defined(_LIBCPP_SHORT_WCHAR)3176  result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3177#  else3178  result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3179#  endif3180  frm_nxt = frm + (_frm_nxt - _frm);3181  to_nxt  = to + (_to_nxt - _to);3182  return r;3183}3184 3185__codecvt_utf16<wchar_t, false>::result __codecvt_utf16<wchar_t, false>::do_in(3186    state_type&,3187    const extern_type* frm,3188    const extern_type* frm_end,3189    const extern_type*& frm_nxt,3190    intern_type* to,3191    intern_type* to_end,3192    intern_type*& to_nxt) const {3193  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3194  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3195  const uint8_t* _frm_nxt = _frm;3196#  if defined(_LIBCPP_SHORT_WCHAR)3197  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);3198  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3199  uint16_t* _to_nxt = _to;3200  result r          = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3201#  else3202  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);3203  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3204  uint32_t* _to_nxt = _to;3205  result r          = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3206#  endif3207  frm_nxt = frm + (_frm_nxt - _frm);3208  to_nxt  = to + (_to_nxt - _to);3209  return r;3210}3211 3212__codecvt_utf16<wchar_t, false>::result3213__codecvt_utf16<wchar_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3214  to_nxt = to;3215  return noconv;3216}3217 3218int __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept { return 0; }3219 3220bool __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept { return false; }3221 3222int __codecvt_utf16<wchar_t, false>::do_length(3223    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3224  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3225  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3226#  if defined(_LIBCPP_SHORT_WCHAR)3227  return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3228#  else3229  return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3230#  endif3231}3232 3233int __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept {3234#  if defined(_LIBCPP_SHORT_WCHAR)3235  if (__mode_ & consume_header)3236    return 4;3237  return 2;3238#  else3239  if (__mode_ & consume_header)3240    return 6;3241  return 4;3242#  endif3243}3244 3245// __codecvt_utf16<wchar_t, true>3246 3247__codecvt_utf16<wchar_t, true>::result __codecvt_utf16<wchar_t, true>::do_out(3248    state_type&,3249    const intern_type* frm,3250    const intern_type* frm_end,3251    const intern_type*& frm_nxt,3252    extern_type* to,3253    extern_type* to_end,3254    extern_type*& to_nxt) const {3255#  if defined(_LIBCPP_SHORT_WCHAR)3256  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3257  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3258  const uint16_t* _frm_nxt = _frm;3259#  else3260  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3261  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3262  const uint32_t* _frm_nxt = _frm;3263#  endif3264  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);3265  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3266  uint8_t* _to_nxt = _to;3267#  if defined(_LIBCPP_SHORT_WCHAR)3268  result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3269#  else3270  result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3271#  endif3272  frm_nxt = frm + (_frm_nxt - _frm);3273  to_nxt  = to + (_to_nxt - _to);3274  return r;3275}3276 3277__codecvt_utf16<wchar_t, true>::result __codecvt_utf16<wchar_t, true>::do_in(3278    state_type&,3279    const extern_type* frm,3280    const extern_type* frm_end,3281    const extern_type*& frm_nxt,3282    intern_type* to,3283    intern_type* to_end,3284    intern_type*& to_nxt) const {3285  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3286  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3287  const uint8_t* _frm_nxt = _frm;3288#  if defined(_LIBCPP_SHORT_WCHAR)3289  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);3290  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3291  uint16_t* _to_nxt = _to;3292  result r          = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3293#  else3294  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);3295  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3296  uint32_t* _to_nxt = _to;3297  result r          = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3298#  endif3299  frm_nxt = frm + (_frm_nxt - _frm);3300  to_nxt  = to + (_to_nxt - _to);3301  return r;3302}3303 3304__codecvt_utf16<wchar_t, true>::result3305__codecvt_utf16<wchar_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3306  to_nxt = to;3307  return noconv;3308}3309 3310int __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept { return 0; }3311 3312bool __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept { return false; }3313 3314int __codecvt_utf16<wchar_t, true>::do_length(3315    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3316  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3317  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3318#  if defined(_LIBCPP_SHORT_WCHAR)3319  return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3320#  else3321  return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3322#  endif3323}3324 3325int __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept {3326#  if defined(_LIBCPP_SHORT_WCHAR)3327  if (__mode_ & consume_header)3328    return 4;3329  return 2;3330#  else3331  if (__mode_ & consume_header)3332    return 6;3333  return 4;3334#  endif3335}3336#endif // _LIBCPP_HAS_WIDE_CHARACTERS3337 3338// __codecvt_utf16<char16_t, false>3339 3340__codecvt_utf16<char16_t, false>::result __codecvt_utf16<char16_t, false>::do_out(3341    state_type&,3342    const intern_type* frm,3343    const intern_type* frm_end,3344    const intern_type*& frm_nxt,3345    extern_type* to,3346    extern_type* to_end,3347    extern_type*& to_nxt) const {3348  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3349  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3350  const uint16_t* _frm_nxt = _frm;3351  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3352  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3353  uint8_t* _to_nxt         = _to;3354  result r                 = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3355  frm_nxt                  = frm + (_frm_nxt - _frm);3356  to_nxt                   = to + (_to_nxt - _to);3357  return r;3358}3359 3360__codecvt_utf16<char16_t, false>::result __codecvt_utf16<char16_t, false>::do_in(3361    state_type&,3362    const extern_type* frm,3363    const extern_type* frm_end,3364    const extern_type*& frm_nxt,3365    intern_type* to,3366    intern_type* to_end,3367    intern_type*& to_nxt) const {3368  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3369  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3370  const uint8_t* _frm_nxt = _frm;3371  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);3372  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);3373  uint16_t* _to_nxt       = _to;3374  result r                = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3375  frm_nxt                 = frm + (_frm_nxt - _frm);3376  to_nxt                  = to + (_to_nxt - _to);3377  return r;3378}3379 3380__codecvt_utf16<char16_t, false>::result3381__codecvt_utf16<char16_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3382  to_nxt = to;3383  return noconv;3384}3385 3386int __codecvt_utf16<char16_t, false>::do_encoding() const noexcept { return 0; }3387 3388bool __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept { return false; }3389 3390int __codecvt_utf16<char16_t, false>::do_length(3391    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3392  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3393  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3394  return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3395}3396 3397_LIBCPP_SUPPRESS_DEPRECATED_PUSH3398int __codecvt_utf16<char16_t, false>::do_max_length() const noexcept {3399  if (__mode_ & consume_header)3400    return 4;3401  return 2;3402}3403_LIBCPP_SUPPRESS_DEPRECATED_POP3404 3405// __codecvt_utf16<char16_t, true>3406 3407__codecvt_utf16<char16_t, true>::result __codecvt_utf16<char16_t, true>::do_out(3408    state_type&,3409    const intern_type* frm,3410    const intern_type* frm_end,3411    const intern_type*& frm_nxt,3412    extern_type* to,3413    extern_type* to_end,3414    extern_type*& to_nxt) const {3415  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3416  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3417  const uint16_t* _frm_nxt = _frm;3418  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3419  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3420  uint8_t* _to_nxt         = _to;3421  result r                 = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3422  frm_nxt                  = frm + (_frm_nxt - _frm);3423  to_nxt                   = to + (_to_nxt - _to);3424  return r;3425}3426 3427__codecvt_utf16<char16_t, true>::result __codecvt_utf16<char16_t, true>::do_in(3428    state_type&,3429    const extern_type* frm,3430    const extern_type* frm_end,3431    const extern_type*& frm_nxt,3432    intern_type* to,3433    intern_type* to_end,3434    intern_type*& to_nxt) const {3435  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3436  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3437  const uint8_t* _frm_nxt = _frm;3438  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);3439  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);3440  uint16_t* _to_nxt       = _to;3441  result r                = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3442  frm_nxt                 = frm + (_frm_nxt - _frm);3443  to_nxt                  = to + (_to_nxt - _to);3444  return r;3445}3446 3447__codecvt_utf16<char16_t, true>::result3448__codecvt_utf16<char16_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3449  to_nxt = to;3450  return noconv;3451}3452 3453int __codecvt_utf16<char16_t, true>::do_encoding() const noexcept { return 0; }3454 3455bool __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept { return false; }3456 3457int __codecvt_utf16<char16_t, true>::do_length(3458    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3459  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3460  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3461  return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);3462}3463 3464_LIBCPP_SUPPRESS_DEPRECATED_PUSH3465int __codecvt_utf16<char16_t, true>::do_max_length() const noexcept {3466  if (__mode_ & consume_header)3467    return 4;3468  return 2;3469}3470_LIBCPP_SUPPRESS_DEPRECATED_POP3471 3472// __codecvt_utf16<char32_t, false>3473 3474__codecvt_utf16<char32_t, false>::result __codecvt_utf16<char32_t, false>::do_out(3475    state_type&,3476    const intern_type* frm,3477    const intern_type* frm_end,3478    const intern_type*& frm_nxt,3479    extern_type* to,3480    extern_type* to_end,3481    extern_type*& to_nxt) const {3482  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3483  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3484  const uint32_t* _frm_nxt = _frm;3485  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3486  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3487  uint8_t* _to_nxt         = _to;3488  result r                 = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3489  frm_nxt                  = frm + (_frm_nxt - _frm);3490  to_nxt                   = to + (_to_nxt - _to);3491  return r;3492}3493 3494__codecvt_utf16<char32_t, false>::result __codecvt_utf16<char32_t, false>::do_in(3495    state_type&,3496    const extern_type* frm,3497    const extern_type* frm_end,3498    const extern_type*& frm_nxt,3499    intern_type* to,3500    intern_type* to_end,3501    intern_type*& to_nxt) const {3502  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3503  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3504  const uint8_t* _frm_nxt = _frm;3505  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);3506  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);3507  uint32_t* _to_nxt       = _to;3508  result r                = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3509  frm_nxt                 = frm + (_frm_nxt - _frm);3510  to_nxt                  = to + (_to_nxt - _to);3511  return r;3512}3513 3514__codecvt_utf16<char32_t, false>::result3515__codecvt_utf16<char32_t, false>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3516  to_nxt = to;3517  return noconv;3518}3519 3520int __codecvt_utf16<char32_t, false>::do_encoding() const noexcept { return 0; }3521 3522bool __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept { return false; }3523 3524int __codecvt_utf16<char32_t, false>::do_length(3525    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3526  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3527  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3528  return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3529}3530 3531_LIBCPP_SUPPRESS_DEPRECATED_PUSH3532int __codecvt_utf16<char32_t, false>::do_max_length() const noexcept {3533  if (__mode_ & consume_header)3534    return 6;3535  return 4;3536}3537_LIBCPP_SUPPRESS_DEPRECATED_POP3538 3539// __codecvt_utf16<char32_t, true>3540 3541__codecvt_utf16<char32_t, true>::result __codecvt_utf16<char32_t, true>::do_out(3542    state_type&,3543    const intern_type* frm,3544    const intern_type* frm_end,3545    const intern_type*& frm_nxt,3546    extern_type* to,3547    extern_type* to_end,3548    extern_type*& to_nxt) const {3549  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3550  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3551  const uint32_t* _frm_nxt = _frm;3552  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3553  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3554  uint8_t* _to_nxt         = _to;3555  result r                 = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3556  frm_nxt                  = frm + (_frm_nxt - _frm);3557  to_nxt                   = to + (_to_nxt - _to);3558  return r;3559}3560 3561__codecvt_utf16<char32_t, true>::result __codecvt_utf16<char32_t, true>::do_in(3562    state_type&,3563    const extern_type* frm,3564    const extern_type* frm_end,3565    const extern_type*& frm_nxt,3566    intern_type* to,3567    intern_type* to_end,3568    intern_type*& to_nxt) const {3569  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3570  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3571  const uint8_t* _frm_nxt = _frm;3572  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);3573  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);3574  uint32_t* _to_nxt       = _to;3575  result r                = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3576  frm_nxt                 = frm + (_frm_nxt - _frm);3577  to_nxt                  = to + (_to_nxt - _to);3578  return r;3579}3580 3581__codecvt_utf16<char32_t, true>::result3582__codecvt_utf16<char32_t, true>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3583  to_nxt = to;3584  return noconv;3585}3586 3587int __codecvt_utf16<char32_t, true>::do_encoding() const noexcept { return 0; }3588 3589bool __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept { return false; }3590 3591int __codecvt_utf16<char32_t, true>::do_length(3592    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3593  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3594  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3595  return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);3596}3597 3598_LIBCPP_SUPPRESS_DEPRECATED_PUSH3599int __codecvt_utf16<char32_t, true>::do_max_length() const noexcept {3600  if (__mode_ & consume_header)3601    return 6;3602  return 4;3603}3604_LIBCPP_SUPPRESS_DEPRECATED_POP3605 3606// __codecvt_utf8_utf16<wchar_t>3607 3608#if _LIBCPP_HAS_WIDE_CHARACTERS3609__codecvt_utf8_utf16<wchar_t>::result __codecvt_utf8_utf16<wchar_t>::do_out(3610    state_type&,3611    const intern_type* frm,3612    const intern_type* frm_end,3613    const intern_type*& frm_nxt,3614    extern_type* to,3615    extern_type* to_end,3616    extern_type*& to_nxt) const {3617#  if defined(_LIBCPP_SHORT_WCHAR)3618  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3619  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3620  const uint16_t* _frm_nxt = _frm;3621#  else3622  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3623  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3624  const uint32_t* _frm_nxt = _frm;3625#  endif3626  uint8_t* _to     = reinterpret_cast<uint8_t*>(to);3627  uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);3628  uint8_t* _to_nxt = _to;3629  result r         = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3630  frm_nxt          = frm + (_frm_nxt - _frm);3631  to_nxt           = to + (_to_nxt - _to);3632  return r;3633}3634 3635__codecvt_utf8_utf16<wchar_t>::result __codecvt_utf8_utf16<wchar_t>::do_in(3636    state_type&,3637    const extern_type* frm,3638    const extern_type* frm_end,3639    const extern_type*& frm_nxt,3640    intern_type* to,3641    intern_type* to_end,3642    intern_type*& to_nxt) const {3643  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3644  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3645  const uint8_t* _frm_nxt = _frm;3646#  if defined(_LIBCPP_SHORT_WCHAR)3647  uint16_t* _to     = reinterpret_cast<uint16_t*>(to);3648  uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);3649  uint16_t* _to_nxt = _to;3650#  else3651  uint32_t* _to     = reinterpret_cast<uint32_t*>(to);3652  uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);3653  uint32_t* _to_nxt = _to;3654#  endif3655  result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3656  frm_nxt  = frm + (_frm_nxt - _frm);3657  to_nxt   = to + (_to_nxt - _to);3658  return r;3659}3660 3661__codecvt_utf8_utf16<wchar_t>::result3662__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3663  to_nxt = to;3664  return noconv;3665}3666 3667int __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept { return 0; }3668 3669bool __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept { return false; }3670 3671int __codecvt_utf8_utf16<wchar_t>::do_length(3672    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3673  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3674  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3675  return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);3676}3677 3678int __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept {3679  if (__mode_ & consume_header)3680    return 7;3681  return 4;3682}3683#endif // _LIBCPP_HAS_WIDE_CHARACTERS3684 3685// __codecvt_utf8_utf16<char16_t>3686 3687__codecvt_utf8_utf16<char16_t>::result __codecvt_utf8_utf16<char16_t>::do_out(3688    state_type&,3689    const intern_type* frm,3690    const intern_type* frm_end,3691    const intern_type*& frm_nxt,3692    extern_type* to,3693    extern_type* to_end,3694    extern_type*& to_nxt) const {3695  const uint16_t* _frm     = reinterpret_cast<const uint16_t*>(frm);3696  const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);3697  const uint16_t* _frm_nxt = _frm;3698  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3699  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3700  uint8_t* _to_nxt         = _to;3701  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3702  frm_nxt                  = frm + (_frm_nxt - _frm);3703  to_nxt                   = to + (_to_nxt - _to);3704  return r;3705}3706 3707__codecvt_utf8_utf16<char16_t>::result __codecvt_utf8_utf16<char16_t>::do_in(3708    state_type&,3709    const extern_type* frm,3710    const extern_type* frm_end,3711    const extern_type*& frm_nxt,3712    intern_type* to,3713    intern_type* to_end,3714    intern_type*& to_nxt) const {3715  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3716  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3717  const uint8_t* _frm_nxt = _frm;3718  uint16_t* _to           = reinterpret_cast<uint16_t*>(to);3719  uint16_t* _to_end       = reinterpret_cast<uint16_t*>(to_end);3720  uint16_t* _to_nxt       = _to;3721  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3722  frm_nxt                 = frm + (_frm_nxt - _frm);3723  to_nxt                  = to + (_to_nxt - _to);3724  return r;3725}3726 3727__codecvt_utf8_utf16<char16_t>::result3728__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3729  to_nxt = to;3730  return noconv;3731}3732 3733int __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept { return 0; }3734 3735bool __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept { return false; }3736 3737int __codecvt_utf8_utf16<char16_t>::do_length(3738    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3739  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3740  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3741  return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);3742}3743 3744_LIBCPP_SUPPRESS_DEPRECATED_PUSH3745int __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept {3746  if (__mode_ & consume_header)3747    return 7;3748  return 4;3749}3750_LIBCPP_SUPPRESS_DEPRECATED_POP3751 3752// __codecvt_utf8_utf16<char32_t>3753 3754__codecvt_utf8_utf16<char32_t>::result __codecvt_utf8_utf16<char32_t>::do_out(3755    state_type&,3756    const intern_type* frm,3757    const intern_type* frm_end,3758    const intern_type*& frm_nxt,3759    extern_type* to,3760    extern_type* to_end,3761    extern_type*& to_nxt) const {3762  const uint32_t* _frm     = reinterpret_cast<const uint32_t*>(frm);3763  const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);3764  const uint32_t* _frm_nxt = _frm;3765  uint8_t* _to             = reinterpret_cast<uint8_t*>(to);3766  uint8_t* _to_end         = reinterpret_cast<uint8_t*>(to_end);3767  uint8_t* _to_nxt         = _to;3768  result r                 = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3769  frm_nxt                  = frm + (_frm_nxt - _frm);3770  to_nxt                   = to + (_to_nxt - _to);3771  return r;3772}3773 3774__codecvt_utf8_utf16<char32_t>::result __codecvt_utf8_utf16<char32_t>::do_in(3775    state_type&,3776    const extern_type* frm,3777    const extern_type* frm_end,3778    const extern_type*& frm_nxt,3779    intern_type* to,3780    intern_type* to_end,3781    intern_type*& to_nxt) const {3782  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3783  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3784  const uint8_t* _frm_nxt = _frm;3785  uint32_t* _to           = reinterpret_cast<uint32_t*>(to);3786  uint32_t* _to_end       = reinterpret_cast<uint32_t*>(to_end);3787  uint32_t* _to_nxt       = _to;3788  result r                = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_);3789  frm_nxt                 = frm + (_frm_nxt - _frm);3790  to_nxt                  = to + (_to_nxt - _to);3791  return r;3792}3793 3794__codecvt_utf8_utf16<char32_t>::result3795__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&, extern_type* to, extern_type*, extern_type*& to_nxt) const {3796  to_nxt = to;3797  return noconv;3798}3799 3800int __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept { return 0; }3801 3802bool __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept { return false; }3803 3804int __codecvt_utf8_utf16<char32_t>::do_length(3805    state_type&, const extern_type* frm, const extern_type* frm_end, size_t mx) const {3806  const uint8_t* _frm     = reinterpret_cast<const uint8_t*>(frm);3807  const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);3808  return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);3809}3810 3811_LIBCPP_SUPPRESS_DEPRECATED_PUSH3812int __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept {3813  if (__mode_ & consume_header)3814    return 7;3815  return 4;3816}3817_LIBCPP_SUPPRESS_DEPRECATED_POP3818 3819// __narrow_to_utf8<16>3820 3821__narrow_to_utf8<16>::~__narrow_to_utf8() {}3822 3823// __narrow_to_utf8<32>3824 3825__narrow_to_utf8<32>::~__narrow_to_utf8() {}3826 3827// __widen_from_utf8<16>3828 3829__widen_from_utf8<16>::~__widen_from_utf8() {}3830 3831// __widen_from_utf8<32>3832 3833__widen_from_utf8<32>::~__widen_from_utf8() {}3834 3835#if _LIBCPP_HAS_WIDE_CHARACTERS3836static bool checked_string_to_wchar_convert(wchar_t& dest, const char* ptr, __locale::__locale_t loc) {3837  if (*ptr == '\0')3838    return false;3839  mbstate_t mb = {};3840  wchar_t out;3841  size_t ret = __locale::__mbrtowc(&out, ptr, strlen(ptr), &mb, loc);3842  if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {3843    return false;3844  }3845  dest = out;3846  return true;3847}3848#endif // _LIBCPP_HAS_WIDE_CHARACTERS3849 3850#if !_LIBCPP_HAS_WIDE_CHARACTERS3851static bool is_narrow_non_breaking_space(const char* ptr) {3852  // https://www.fileformat.info/info/unicode/char/202f/index.htm3853  return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';3854}3855 3856static bool is_non_breaking_space(const char* ptr) {3857  // https://www.fileformat.info/info/unicode/char/a0/index.htm3858  return ptr[0] == '\xc2' && ptr[1] == '\xa0';3859}3860#endif // _LIBCPP_HAS_WIDE_CHARACTERS3861 3862static bool checked_string_to_char_convert(char& dest, const char* ptr, __locale::__locale_t __loc) {3863  if (*ptr == '\0')3864    return false;3865  if (!ptr[1]) {3866    dest = *ptr;3867    return true;3868  }3869 3870#if _LIBCPP_HAS_WIDE_CHARACTERS3871  // First convert the MBS into a wide char then attempt to narrow it using3872  // wctob_l.3873  wchar_t wout;3874  if (!checked_string_to_wchar_convert(wout, ptr, __loc))3875    return false;3876  int res;3877  if ((res = __locale::__wctob(wout, __loc)) != char_traits<char>::eof()) {3878    dest = res;3879    return true;3880  }3881  // FIXME: Work around specific multibyte sequences that we can reasonably3882  // translate into a different single byte.3883  switch (wout) {3884  case L'\u202F': // narrow non-breaking space3885  case L'\u00A0': // non-breaking space3886    dest = ' ';3887    return true;3888  default:3889    return false;3890  }3891#else  // _LIBCPP_HAS_WIDE_CHARACTERS3892  // FIXME: Work around specific multibyte sequences that we can reasonably3893  // translate into a different single byte.3894  if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {3895    dest = ' ';3896    return true;3897  }3898 3899  return false;3900#endif // _LIBCPP_HAS_WIDE_CHARACTERS3901  __libcpp_unreachable();3902}3903 3904// numpunct<char> && numpunct<wchar_t>3905 3906constinit locale::id numpunct<char>::id;3907#if _LIBCPP_HAS_WIDE_CHARACTERS3908constinit locale::id numpunct<wchar_t>::id;3909#endif3910 3911numpunct<char>::numpunct(size_t refs) : locale::facet(refs), __decimal_point_('.'), __thousands_sep_(',') {}3912 3913#if _LIBCPP_HAS_WIDE_CHARACTERS3914numpunct<wchar_t>::numpunct(size_t refs) : locale::facet(refs), __decimal_point_(L'.'), __thousands_sep_(L',') {}3915#endif3916 3917numpunct<char>::~numpunct() {}3918 3919#if _LIBCPP_HAS_WIDE_CHARACTERS3920numpunct<wchar_t>::~numpunct() {}3921#endif3922 3923char numpunct< char >::do_decimal_point() const { return __decimal_point_; }3924#if _LIBCPP_HAS_WIDE_CHARACTERS3925wchar_t numpunct<wchar_t>::do_decimal_point() const { return __decimal_point_; }3926#endif3927 3928char numpunct< char >::do_thousands_sep() const { return __thousands_sep_; }3929#if _LIBCPP_HAS_WIDE_CHARACTERS3930wchar_t numpunct<wchar_t>::do_thousands_sep() const { return __thousands_sep_; }3931#endif3932 3933string numpunct< char >::do_grouping() const { return __grouping_; }3934#if _LIBCPP_HAS_WIDE_CHARACTERS3935string numpunct<wchar_t>::do_grouping() const { return __grouping_; }3936#endif3937 3938string numpunct< char >::do_truename() const { return "true"; }3939#if _LIBCPP_HAS_WIDE_CHARACTERS3940wstring numpunct<wchar_t>::do_truename() const { return L"true"; }3941#endif3942 3943string numpunct< char >::do_falsename() const { return "false"; }3944#if _LIBCPP_HAS_WIDE_CHARACTERS3945wstring numpunct<wchar_t>::do_falsename() const { return L"false"; }3946#endif3947 3948// numpunct_byname<char>3949 3950numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) : numpunct<char>(refs) { __init(nm); }3951 3952numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) : numpunct<char>(refs) { __init(nm.c_str()); }3953 3954numpunct_byname<char>::~numpunct_byname() {}3955 3956void numpunct_byname<char>::__init(const char* nm) {3957  typedef numpunct<char> base;3958  if (strcmp(nm, "C") != 0) {3959    __libcpp_unique_locale loc(nm);3960    if (!loc)3961      std::__throw_runtime_error(3962          ("numpunct_byname<char>::numpunct_byname"3963           " failed to construct for " +3964           string(nm))3965              .c_str());3966 3967    __locale::__lconv_t* lc = __locale::__localeconv(loc.get());3968    if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point, loc.get()))3969      __decimal_point_ = base::do_decimal_point();3970    if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep, loc.get()))3971      __thousands_sep_ = base::do_thousands_sep();3972    __grouping_ = lc->grouping;3973    // localization for truename and falsename is not available3974  }3975}3976 3977// numpunct_byname<wchar_t>3978 3979#if _LIBCPP_HAS_WIDE_CHARACTERS3980numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) : numpunct<wchar_t>(refs) { __init(nm); }3981 3982numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) : numpunct<wchar_t>(refs) {3983  __init(nm.c_str());3984}3985 3986numpunct_byname<wchar_t>::~numpunct_byname() {}3987 3988void numpunct_byname<wchar_t>::__init(const char* nm) {3989  if (strcmp(nm, "C") != 0) {3990    __libcpp_unique_locale loc(nm);3991    if (!loc)3992      std::__throw_runtime_error(3993          ("numpunct_byname<wchar_t>::numpunct_byname"3994           " failed to construct for " +3995           string(nm))3996              .c_str());3997 3998    __locale::__lconv_t* lc = __locale::__localeconv(loc.get());3999    checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point, loc.get());4000    checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep, loc.get());4001    __grouping_ = lc->grouping;4002    // localization for truename and falsename is not available4003  }4004}4005#endif // _LIBCPP_HAS_WIDE_CHARACTERS4006 4007// num_get helpers4008 4009int __num_get_base::__get_base(ios_base& iob) {4010  ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;4011  if (__basefield == ios_base::oct)4012    return 8;4013  else if (__basefield == ios_base::hex)4014    return 16;4015  else if (__basefield == 0)4016    return 0;4017  return 10;4018}4019 4020const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";4021 4022void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, ios_base::iostate& __err) {4023  //  if the grouping pattern is empty _or_ there are no grouping bits, then do nothing4024  //  we always have at least a single entry in [__g, __g_end); the end of the input sequence4025  if (__grouping.size() != 0 && __g_end - __g > 1) {4026    reverse(__g, __g_end);4027    const char* __ig = __grouping.data();4028    const char* __eg = __ig + __grouping.size();4029    for (unsigned* __r = __g; __r < __g_end - 1; ++__r) {4030      if (0 < *__ig && *__ig < numeric_limits<char>::max()) {4031        if (static_cast<unsigned>(*__ig) != *__r) {4032          __err = ios_base::failbit;4033          return;4034        }4035      }4036      if (__eg - __ig > 1)4037        ++__ig;4038    }4039    if (0 < *__ig && *__ig < numeric_limits<char>::max()) {4040      if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)4041        __err = ios_base::failbit;4042    }4043  }4044}4045 4046void __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, ios_base::fmtflags __flags) {4047  if ((__flags & ios_base::showpos) && (__flags & ios_base::basefield) != ios_base::oct &&4048      (__flags & ios_base::basefield) != ios_base::hex && __signd)4049    *__fmtp++ = '+';4050  if (__flags & ios_base::showbase)4051    *__fmtp++ = '#';4052  while (*__len)4053    *__fmtp++ = *__len++;4054  if ((__flags & ios_base::basefield) == ios_base::oct)4055    *__fmtp = 'o';4056  else if ((__flags & ios_base::basefield) == ios_base::hex) {4057    if (__flags & ios_base::uppercase)4058      *__fmtp = 'X';4059    else4060      *__fmtp = 'x';4061  } else if (__signd)4062    *__fmtp = 'd';4063  else4064    *__fmtp = 'u';4065}4066 4067bool __num_put_base::__format_float(char* __fmtp, const char* __len, ios_base::fmtflags __flags) {4068  bool specify_precision = true;4069  if (__flags & ios_base::showpos)4070    *__fmtp++ = '+';4071  if (__flags & ios_base::showpoint)4072    *__fmtp++ = '#';4073  ios_base::fmtflags floatfield = __flags & ios_base::floatfield;4074  bool uppercase                = (__flags & ios_base::uppercase) != 0;4075  if (floatfield == (ios_base::fixed | ios_base::scientific))4076    specify_precision = false;4077  else {4078    *__fmtp++ = '.';4079    *__fmtp++ = '*';4080  }4081  while (*__len)4082    *__fmtp++ = *__len++;4083  if (floatfield == ios_base::fixed) {4084    if (uppercase)4085      *__fmtp = 'F';4086    else4087      *__fmtp = 'f';4088  } else if (floatfield == ios_base::scientific) {4089    if (uppercase)4090      *__fmtp = 'E';4091    else4092      *__fmtp = 'e';4093  } else if (floatfield == (ios_base::fixed | ios_base::scientific)) {4094    if (uppercase)4095      *__fmtp = 'A';4096    else4097      *__fmtp = 'a';4098  } else {4099    if (uppercase)4100      *__fmtp = 'G';4101    else4102      *__fmtp = 'g';4103  }4104  return specify_precision;4105}4106 4107char* __num_put_base::__identify_padding(char* __nb, char* __ne, const ios_base& __iob) {4108  switch (__iob.flags() & ios_base::adjustfield) {4109  case ios_base::internal:4110    if (__nb[0] == '-' || __nb[0] == '+')4111      return __nb + 1;4112    if (__ne - __nb >= 2 && __nb[0] == '0' && (__nb[1] == 'x' || __nb[1] == 'X'))4113      return __nb + 2;4114    break;4115  case ios_base::left:4116    return __ne;4117  case ios_base::right:4118  default:4119    break;4120  }4121  return __nb;4122}4123 4124// time_get4125 4126static string* init_weeks() {4127  static string weeks[14];4128  weeks[0]  = "Sunday";4129  weeks[1]  = "Monday";4130  weeks[2]  = "Tuesday";4131  weeks[3]  = "Wednesday";4132  weeks[4]  = "Thursday";4133  weeks[5]  = "Friday";4134  weeks[6]  = "Saturday";4135  weeks[7]  = "Sun";4136  weeks[8]  = "Mon";4137  weeks[9]  = "Tue";4138  weeks[10] = "Wed";4139  weeks[11] = "Thu";4140  weeks[12] = "Fri";4141  weeks[13] = "Sat";4142  return weeks;4143}4144 4145#if _LIBCPP_HAS_WIDE_CHARACTERS4146static wstring* init_wweeks() {4147  static wstring weeks[14];4148  weeks[0]  = L"Sunday";4149  weeks[1]  = L"Monday";4150  weeks[2]  = L"Tuesday";4151  weeks[3]  = L"Wednesday";4152  weeks[4]  = L"Thursday";4153  weeks[5]  = L"Friday";4154  weeks[6]  = L"Saturday";4155  weeks[7]  = L"Sun";4156  weeks[8]  = L"Mon";4157  weeks[9]  = L"Tue";4158  weeks[10] = L"Wed";4159  weeks[11] = L"Thu";4160  weeks[12] = L"Fri";4161  weeks[13] = L"Sat";4162  return weeks;4163}4164#endif4165 4166template <>4167const string* __time_get_c_storage<char>::__weeks() const {4168  static const string* weeks = init_weeks();4169  return weeks;4170}4171 4172#if _LIBCPP_HAS_WIDE_CHARACTERS4173template <>4174const wstring* __time_get_c_storage<wchar_t>::__weeks() const {4175  static const wstring* weeks = init_wweeks();4176  return weeks;4177}4178#endif4179 4180static string* init_months() {4181  static string months[24];4182  months[0]  = "January";4183  months[1]  = "February";4184  months[2]  = "March";4185  months[3]  = "April";4186  months[4]  = "May";4187  months[5]  = "June";4188  months[6]  = "July";4189  months[7]  = "August";4190  months[8]  = "September";4191  months[9]  = "October";4192  months[10] = "November";4193  months[11] = "December";4194  months[12] = "Jan";4195  months[13] = "Feb";4196  months[14] = "Mar";4197  months[15] = "Apr";4198  months[16] = "May";4199  months[17] = "Jun";4200  months[18] = "Jul";4201  months[19] = "Aug";4202  months[20] = "Sep";4203  months[21] = "Oct";4204  months[22] = "Nov";4205  months[23] = "Dec";4206  return months;4207}4208 4209#if _LIBCPP_HAS_WIDE_CHARACTERS4210static wstring* init_wmonths() {4211  static wstring months[24];4212  months[0]  = L"January";4213  months[1]  = L"February";4214  months[2]  = L"March";4215  months[3]  = L"April";4216  months[4]  = L"May";4217  months[5]  = L"June";4218  months[6]  = L"July";4219  months[7]  = L"August";4220  months[8]  = L"September";4221  months[9]  = L"October";4222  months[10] = L"November";4223  months[11] = L"December";4224  months[12] = L"Jan";4225  months[13] = L"Feb";4226  months[14] = L"Mar";4227  months[15] = L"Apr";4228  months[16] = L"May";4229  months[17] = L"Jun";4230  months[18] = L"Jul";4231  months[19] = L"Aug";4232  months[20] = L"Sep";4233  months[21] = L"Oct";4234  months[22] = L"Nov";4235  months[23] = L"Dec";4236  return months;4237}4238#endif4239 4240template <>4241const string* __time_get_c_storage<char>::__months() const {4242  static const string* months = init_months();4243  return months;4244}4245 4246#if _LIBCPP_HAS_WIDE_CHARACTERS4247template <>4248const wstring* __time_get_c_storage<wchar_t>::__months() const {4249  static const wstring* months = init_wmonths();4250  return months;4251}4252#endif4253 4254static string* init_am_pm() {4255  static string am_pm[2];4256  am_pm[0] = "AM";4257  am_pm[1] = "PM";4258  return am_pm;4259}4260 4261#if _LIBCPP_HAS_WIDE_CHARACTERS4262static wstring* init_wam_pm() {4263  static wstring am_pm[2];4264  am_pm[0] = L"AM";4265  am_pm[1] = L"PM";4266  return am_pm;4267}4268#endif4269 4270template <>4271const string* __time_get_c_storage<char>::__am_pm() const {4272  static const string* am_pm = init_am_pm();4273  return am_pm;4274}4275 4276#if _LIBCPP_HAS_WIDE_CHARACTERS4277template <>4278const wstring* __time_get_c_storage<wchar_t>::__am_pm() const {4279  static const wstring* am_pm = init_wam_pm();4280  return am_pm;4281}4282#endif4283 4284template <>4285const string& __time_get_c_storage<char>::__x() const {4286  static string s("%m/%d/%y");4287  return s;4288}4289 4290#if _LIBCPP_HAS_WIDE_CHARACTERS4291template <>4292const wstring& __time_get_c_storage<wchar_t>::__x() const {4293  static wstring s(L"%m/%d/%y");4294  return s;4295}4296#endif4297 4298template <>4299const string& __time_get_c_storage<char>::__X() const {4300  static string s("%H:%M:%S");4301  return s;4302}4303 4304#if _LIBCPP_HAS_WIDE_CHARACTERS4305template <>4306const wstring& __time_get_c_storage<wchar_t>::__X() const {4307  static wstring s(L"%H:%M:%S");4308  return s;4309}4310#endif4311 4312template <>4313const string& __time_get_c_storage<char>::__c() const {4314  static string s("%a %b %d %H:%M:%S %Y");4315  return s;4316}4317 4318#if _LIBCPP_HAS_WIDE_CHARACTERS4319template <>4320const wstring& __time_get_c_storage<wchar_t>::__c() const {4321  static wstring s(L"%a %b %d %H:%M:%S %Y");4322  return s;4323}4324#endif4325 4326template <>4327const string& __time_get_c_storage<char>::__r() const {4328  static string s("%I:%M:%S %p");4329  return s;4330}4331 4332#if _LIBCPP_HAS_WIDE_CHARACTERS4333template <>4334const wstring& __time_get_c_storage<wchar_t>::__r() const {4335  static wstring s(L"%I:%M:%S %p");4336  return s;4337}4338#endif4339 4340// time_get_byname4341 4342__time_get::__time_get(const char* nm) : __loc_(__locale::__newlocale(_LIBCPP_ALL_MASK, nm, 0)) {4343  if (__loc_ == 0)4344    std::__throw_runtime_error(("time_get_byname failed to construct for " + string(nm)).c_str());4345}4346 4347__time_get::__time_get(const string& nm) : __loc_(__locale::__newlocale(_LIBCPP_ALL_MASK, nm.c_str(), 0)) {4348  if (__loc_ == 0)4349    std::__throw_runtime_error(("time_get_byname failed to construct for " + nm).c_str());4350}4351 4352__time_get::~__time_get() { __locale::__freelocale(__loc_); }4353 4354_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")4355 4356template <>4357string __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) {4358  tm t       = {0};4359  t.tm_sec   = 59;4360  t.tm_min   = 55;4361  t.tm_hour  = 23;4362  t.tm_mday  = 31;4363  t.tm_mon   = 11;4364  t.tm_year  = 161;4365  t.tm_wday  = 6;4366  t.tm_yday  = 364;4367  t.tm_isdst = -1;4368  char buf[100];4369  char f[3] = {0};4370  f[0]      = '%';4371  f[1]      = fmt;4372  size_t n  = __locale::__strftime(buf, countof(buf), f, &t, __loc_);4373  char* bb  = buf;4374  char* be  = buf + n;4375  string result;4376  while (bb != be) {4377    if (ct.is(ctype_base::space, *bb)) {4378      result.push_back(' ');4379      for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)4380        ;4381      continue;4382    }4383    char* w               = bb;4384    ios_base::iostate err = ios_base::goodbit;4385    ptrdiff_t i           = __scan_keyword(w, be, this->__weeks_, this->__weeks_ + 14, ct, err, false) - this->__weeks_;4386    if (i < 14) {4387      result.push_back('%');4388      if (i < 7)4389        result.push_back('A');4390      else4391        result.push_back('a');4392      bb = w;4393      continue;4394    }4395    w = bb;4396    i = __scan_keyword(w, be, this->__months_, this->__months_ + 24, ct, err, false) - this->__months_;4397    if (i < 24) {4398      result.push_back('%');4399      if (i < 12)4400        result.push_back('B');4401      else4402        result.push_back('b');4403      if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))4404        result.back() = 'm';4405      bb = w;4406      continue;4407    }4408    if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) {4409      w = bb;4410      i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_ + 2, ct, err, false) - this->__am_pm_;4411      if (i < 2) {4412        result.push_back('%');4413        result.push_back('p');4414        bb = w;4415        continue;4416      }4417    }4418    w = bb;4419    if (ct.is(ctype_base::digit, *bb)) {4420      switch (__get_up_to_n_digits(bb, be, err, ct, 4)) {4421      case 6:4422        result.push_back('%');4423        result.push_back('w');4424        break;4425      case 7:4426        result.push_back('%');4427        result.push_back('u');4428        break;4429      case 11:4430        result.push_back('%');4431        result.push_back('I');4432        break;4433      case 12:4434        result.push_back('%');4435        result.push_back('m');4436        break;4437      case 23:4438        result.push_back('%');4439        result.push_back('H');4440        break;4441      case 31:4442        result.push_back('%');4443        result.push_back('d');4444        break;4445      case 55:4446        result.push_back('%');4447        result.push_back('M');4448        break;4449      case 59:4450        result.push_back('%');4451        result.push_back('S');4452        break;4453      case 61:4454        result.push_back('%');4455        result.push_back('y');4456        break;4457      case 364:4458        result.push_back('%');4459        result.push_back('j');4460        break;4461      case 2061:4462        result.push_back('%');4463        result.push_back('Y');4464        break;4465      default:4466        for (; w != bb; ++w)4467          result.push_back(*w);4468        break;4469      }4470      continue;4471    }4472    if (*bb == '%') {4473      result.push_back('%');4474      result.push_back('%');4475      ++bb;4476      continue;4477    }4478    result.push_back(*bb);4479    ++bb;4480  }4481  return result;4482}4483 4484_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")4485 4486#if _LIBCPP_HAS_WIDE_CHARACTERS4487template <>4488wstring __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) {4489  tm t       = {0};4490  t.tm_sec   = 59;4491  t.tm_min   = 55;4492  t.tm_hour  = 23;4493  t.tm_mday  = 31;4494  t.tm_mon   = 11;4495  t.tm_year  = 161;4496  t.tm_wday  = 6;4497  t.tm_yday  = 364;4498  t.tm_isdst = -1;4499  char buf[100];4500  char f[3] = {0};4501  f[0]      = '%';4502  f[1]      = fmt;4503  __locale::__strftime(buf, countof(buf), f, &t, __loc_);4504  wchar_t wbuf[100];4505  wchar_t* wbb   = wbuf;4506  mbstate_t mb   = {0};4507  const char* bb = buf;4508  size_t j       = __locale::__mbsrtowcs(wbb, &bb, countof(wbuf), &mb, __loc_);4509  if (j == size_t(-1))4510    std::__throw_runtime_error("locale not supported");4511  wchar_t* wbe = wbb + j;4512  wstring result;4513  while (wbb != wbe) {4514    if (ct.is(ctype_base::space, *wbb)) {4515      result.push_back(L' ');4516      for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)4517        ;4518      continue;4519    }4520    wchar_t* w            = wbb;4521    ios_base::iostate err = ios_base::goodbit;4522    ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_ + 14, ct, err, false) - this->__weeks_;4523    if (i < 14) {4524      result.push_back(L'%');4525      if (i < 7)4526        result.push_back(L'A');4527      else4528        result.push_back(L'a');4529      wbb = w;4530      continue;4531    }4532    w = wbb;4533    i = __scan_keyword(w, wbe, this->__months_, this->__months_ + 24, ct, err, false) - this->__months_;4534    if (i < 24) {4535      result.push_back(L'%');4536      if (i < 12)4537        result.push_back(L'B');4538      else4539        result.push_back(L'b');4540      if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))4541        result.back() = L'm';4542      wbb = w;4543      continue;4544    }4545    if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) {4546      w = wbb;4547      i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_ + 2, ct, err, false) - this->__am_pm_;4548      if (i < 2) {4549        result.push_back(L'%');4550        result.push_back(L'p');4551        wbb = w;4552        continue;4553      }4554    }4555    w = wbb;4556    if (ct.is(ctype_base::digit, *wbb)) {4557      switch (__get_up_to_n_digits(wbb, wbe, err, ct, 4)) {4558      case 6:4559        result.push_back(L'%');4560        result.push_back(L'w');4561        break;4562      case 7:4563        result.push_back(L'%');4564        result.push_back(L'u');4565        break;4566      case 11:4567        result.push_back(L'%');4568        result.push_back(L'I');4569        break;4570      case 12:4571        result.push_back(L'%');4572        result.push_back(L'm');4573        break;4574      case 23:4575        result.push_back(L'%');4576        result.push_back(L'H');4577        break;4578      case 31:4579        result.push_back(L'%');4580        result.push_back(L'd');4581        break;4582      case 55:4583        result.push_back(L'%');4584        result.push_back(L'M');4585        break;4586      case 59:4587        result.push_back(L'%');4588        result.push_back(L'S');4589        break;4590      case 61:4591        result.push_back(L'%');4592        result.push_back(L'y');4593        break;4594      case 364:4595        result.push_back(L'%');4596        result.push_back(L'j');4597        break;4598      case 2061:4599        result.push_back(L'%');4600        result.push_back(L'Y');4601        break;4602      default:4603        for (; w != wbb; ++w)4604          result.push_back(*w);4605        break;4606      }4607      continue;4608    }4609    if (ct.narrow(*wbb, 0) == '%') {4610      result.push_back(L'%');4611      result.push_back(L'%');4612      ++wbb;4613      continue;4614    }4615    result.push_back(*wbb);4616    ++wbb;4617  }4618  return result;4619}4620#endif // _LIBCPP_HAS_WIDE_CHARACTERS4621 4622template <>4623void __time_get_storage<char>::init(const ctype<char>& ct) {4624  tm t = {0};4625  char buf[100];4626  // __weeks_4627  for (int i = 0; i < 7; ++i) {4628    t.tm_wday = i;4629    __locale::__strftime(buf, countof(buf), "%A", &t, __loc_);4630    __weeks_[i] = buf;4631    __locale::__strftime(buf, countof(buf), "%a", &t, __loc_);4632    __weeks_[i + 7] = buf;4633  }4634  // __months_4635  for (int i = 0; i < 12; ++i) {4636    t.tm_mon = i;4637    __locale::__strftime(buf, countof(buf), "%B", &t, __loc_);4638    __months_[i] = buf;4639    __locale::__strftime(buf, countof(buf), "%b", &t, __loc_);4640    __months_[i + 12] = buf;4641  }4642  // __am_pm_4643  t.tm_hour = 1;4644  __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);4645  __am_pm_[0] = buf;4646  t.tm_hour   = 13;4647  __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);4648  __am_pm_[1] = buf;4649  __c_        = __analyze('c', ct);4650  __r_        = __analyze('r', ct);4651  __x_        = __analyze('x', ct);4652  __X_        = __analyze('X', ct);4653}4654 4655#if _LIBCPP_HAS_WIDE_CHARACTERS4656template <>4657void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) {4658  tm t = {0};4659  char buf[100];4660  wchar_t wbuf[100];4661  wchar_t* wbe;4662  mbstate_t mb = {0};4663  // __weeks_4664  for (int i = 0; i < 7; ++i) {4665    t.tm_wday = i;4666    __locale::__strftime(buf, countof(buf), "%A", &t, __loc_);4667    mb             = mbstate_t();4668    const char* bb = buf;4669    size_t j       = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);4670    if (j == size_t(-1) || j == 0)4671      std::__throw_runtime_error("locale not supported");4672    wbe = wbuf + j;4673    __weeks_[i].assign(wbuf, wbe);4674    __locale::__strftime(buf, countof(buf), "%a", &t, __loc_);4675    mb = mbstate_t();4676    bb = buf;4677    j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);4678    if (j == size_t(-1) || j == 0)4679      std::__throw_runtime_error("locale not supported");4680    wbe = wbuf + j;4681    __weeks_[i + 7].assign(wbuf, wbe);4682  }4683  // __months_4684  for (int i = 0; i < 12; ++i) {4685    t.tm_mon = i;4686    __locale::__strftime(buf, countof(buf), "%B", &t, __loc_);4687    mb             = mbstate_t();4688    const char* bb = buf;4689    size_t j       = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);4690    if (j == size_t(-1) || j == 0)4691      std::__throw_runtime_error("locale not supported");4692    wbe = wbuf + j;4693    __months_[i].assign(wbuf, wbe);4694    __locale::__strftime(buf, countof(buf), "%b", &t, __loc_);4695    mb = mbstate_t();4696    bb = buf;4697    j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);4698    if (j == size_t(-1) || j == 0)4699      std::__throw_runtime_error("locale not supported");4700    wbe = wbuf + j;4701    __months_[i + 12].assign(wbuf, wbe);4702  }4703  // __am_pm_4704  t.tm_hour = 1;4705  __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);4706  mb             = mbstate_t();4707  const char* bb = buf;4708  size_t j       = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);4709  if (j == size_t(-1))4710    std::__throw_runtime_error("locale not supported");4711  wbe = wbuf + j;4712  __am_pm_[0].assign(wbuf, wbe);4713  t.tm_hour = 13;4714  __locale::__strftime(buf, countof(buf), "%p", &t, __loc_);4715  mb = mbstate_t();4716  bb = buf;4717  j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, __loc_);4718  if (j == size_t(-1))4719    std::__throw_runtime_error("locale not supported");4720  wbe = wbuf + j;4721  __am_pm_[1].assign(wbuf, wbe);4722  __c_ = __analyze('c', ct);4723  __r_ = __analyze('r', ct);4724  __x_ = __analyze('x', ct);4725  __X_ = __analyze('X', ct);4726}4727#endif // _LIBCPP_HAS_WIDE_CHARACTERS4728 4729template <class CharT>4730struct _LIBCPP_HIDDEN __time_get_temp : public ctype_byname<CharT> {4731  explicit __time_get_temp(const char* nm) : ctype_byname<CharT>(nm, 1) {}4732  explicit __time_get_temp(const string& nm) : ctype_byname<CharT>(nm, 1) {}4733};4734 4735template <>4736__time_get_storage<char>::__time_get_storage(const char* __nm) : __time_get(__nm) {4737  const __time_get_temp<char> ct(__nm);4738  init(ct);4739}4740 4741template <>4742__time_get_storage<char>::__time_get_storage(const string& __nm) : __time_get(__nm) {4743  const __time_get_temp<char> ct(__nm);4744  init(ct);4745}4746 4747#if _LIBCPP_HAS_WIDE_CHARACTERS4748template <>4749__time_get_storage<wchar_t>::__time_get_storage(const char* __nm) : __time_get(__nm) {4750  const __time_get_temp<wchar_t> ct(__nm);4751  init(ct);4752}4753 4754template <>4755__time_get_storage<wchar_t>::__time_get_storage(const string& __nm) : __time_get(__nm) {4756  const __time_get_temp<wchar_t> ct(__nm);4757  init(ct);4758}4759#endif // _LIBCPP_HAS_WIDE_CHARACTERS4760 4761template <>4762time_base::dateorder __time_get_storage<char>::__do_date_order() const {4763  unsigned i;4764  for (i = 0; i < __x_.size(); ++i)4765    if (__x_[i] == '%')4766      break;4767  ++i;4768  switch (__x_[i]) {4769  case 'y':4770  case 'Y':4771    for (++i; i < __x_.size(); ++i)4772      if (__x_[i] == '%')4773        break;4774    if (i == __x_.size())4775      break;4776    ++i;4777    switch (__x_[i]) {4778    case 'm':4779      for (++i; i < __x_.size(); ++i)4780        if (__x_[i] == '%')4781          break;4782      if (i == __x_.size())4783        break;4784      ++i;4785      if (__x_[i] == 'd')4786        return time_base::ymd;4787      break;4788    case 'd':4789      for (++i; i < __x_.size(); ++i)4790        if (__x_[i] == '%')4791          break;4792      if (i == __x_.size())4793        break;4794      ++i;4795      if (__x_[i] == 'm')4796        return time_base::ydm;4797      break;4798    }4799    break;4800  case 'm':4801    for (++i; i < __x_.size(); ++i)4802      if (__x_[i] == '%')4803        break;4804    if (i == __x_.size())4805      break;4806    ++i;4807    if (__x_[i] == 'd') {4808      for (++i; i < __x_.size(); ++i)4809        if (__x_[i] == '%')4810          break;4811      if (i == __x_.size())4812        break;4813      ++i;4814      if (__x_[i] == 'y' || __x_[i] == 'Y')4815        return time_base::mdy;4816      break;4817    }4818    break;4819  case 'd':4820    for (++i; i < __x_.size(); ++i)4821      if (__x_[i] == '%')4822        break;4823    if (i == __x_.size())4824      break;4825    ++i;4826    if (__x_[i] == 'm') {4827      for (++i; i < __x_.size(); ++i)4828        if (__x_[i] == '%')4829          break;4830      if (i == __x_.size())4831        break;4832      ++i;4833      if (__x_[i] == 'y' || __x_[i] == 'Y')4834        return time_base::dmy;4835      break;4836    }4837    break;4838  }4839  return time_base::no_order;4840}4841 4842#if _LIBCPP_HAS_WIDE_CHARACTERS4843template <>4844time_base::dateorder __time_get_storage<wchar_t>::__do_date_order() const {4845  unsigned i;4846  for (i = 0; i < __x_.size(); ++i)4847    if (__x_[i] == L'%')4848      break;4849  ++i;4850  switch (__x_[i]) {4851  case L'y':4852  case L'Y':4853    for (++i; i < __x_.size(); ++i)4854      if (__x_[i] == L'%')4855        break;4856    if (i == __x_.size())4857      break;4858    ++i;4859    switch (__x_[i]) {4860    case L'm':4861      for (++i; i < __x_.size(); ++i)4862        if (__x_[i] == L'%')4863          break;4864      if (i == __x_.size())4865        break;4866      ++i;4867      if (__x_[i] == L'd')4868        return time_base::ymd;4869      break;4870    case L'd':4871      for (++i; i < __x_.size(); ++i)4872        if (__x_[i] == L'%')4873          break;4874      if (i == __x_.size())4875        break;4876      ++i;4877      if (__x_[i] == L'm')4878        return time_base::ydm;4879      break;4880    }4881    break;4882  case L'm':4883    for (++i; i < __x_.size(); ++i)4884      if (__x_[i] == L'%')4885        break;4886    if (i == __x_.size())4887      break;4888    ++i;4889    if (__x_[i] == L'd') {4890      for (++i; i < __x_.size(); ++i)4891        if (__x_[i] == L'%')4892          break;4893      if (i == __x_.size())4894        break;4895      ++i;4896      if (__x_[i] == L'y' || __x_[i] == L'Y')4897        return time_base::mdy;4898      break;4899    }4900    break;4901  case L'd':4902    for (++i; i < __x_.size(); ++i)4903      if (__x_[i] == L'%')4904        break;4905    if (i == __x_.size())4906      break;4907    ++i;4908    if (__x_[i] == L'm') {4909      for (++i; i < __x_.size(); ++i)4910        if (__x_[i] == L'%')4911          break;4912      if (i == __x_.size())4913        break;4914      ++i;4915      if (__x_[i] == L'y' || __x_[i] == L'Y')4916        return time_base::dmy;4917      break;4918    }4919    break;4920  }4921  return time_base::no_order;4922}4923#endif // _LIBCPP_HAS_WIDE_CHARACTERS4924 4925// time_put4926 4927__time_put::__time_put(const char* nm) : __loc_(__locale::__newlocale(_LIBCPP_ALL_MASK, nm, 0)) {4928  if (__loc_ == 0)4929    std::__throw_runtime_error(("time_put_byname failed to construct for " + string(nm)).c_str());4930}4931 4932__time_put::__time_put(const string& nm) : __loc_(__locale::__newlocale(_LIBCPP_ALL_MASK, nm.c_str(), 0)) {4933  if (__loc_ == 0)4934    std::__throw_runtime_error(("time_put_byname failed to construct for " + nm).c_str());4935}4936 4937__time_put::~__time_put() {4938  if (__loc_ != _LIBCPP_GET_C_LOCALE)4939    __locale::__freelocale(__loc_);4940}4941 4942void __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const {4943  char fmt[] = {'%', __fmt, __mod, 0};4944  if (__mod != 0)4945    swap(fmt[1], fmt[2]);4946  size_t n = __locale::__strftime(__nb, countof(__nb, __ne), fmt, __tm, __loc_);4947  __ne     = __nb + n;4948}4949 4950#if _LIBCPP_HAS_WIDE_CHARACTERS4951void __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const {4952  char __nar[100];4953  char* __ne = __nar + 100;4954  __do_put(__nar, __ne, __tm, __fmt, __mod);4955  mbstate_t mb     = {0};4956  const char* __nb = __nar;4957  size_t j         = __locale::__mbsrtowcs(__wb, &__nb, countof(__wb, __we), &mb, __loc_);4958  if (j == size_t(-1))4959    std::__throw_runtime_error("locale not supported");4960  __we = __wb + j;4961}4962#endif // _LIBCPP_HAS_WIDE_CHARACTERS4963 4964// moneypunct_byname4965 4966template <class charT>4967static void __init_pat(4968    money_base::pattern& pat,4969    basic_string<charT>& __curr_symbol_,4970    bool intl,4971    char cs_precedes,4972    char sep_by_space,4973    char sign_posn,4974    charT space_char) {4975  const char sign                = static_cast<char>(money_base::sign);4976  const char space               = static_cast<char>(money_base::space);4977  const char none                = static_cast<char>(money_base::none);4978  const char symbol              = static_cast<char>(money_base::symbol);4979  const char value               = static_cast<char>(money_base::value);4980  const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;4981 4982  // Comments on case branches reflect 'C11 7.11.2.1 The localeconv4983  // function'. "Space between sign and symbol or value" means that4984  // if the sign is adjacent to the symbol, there's a space between4985  // them, and otherwise there's a space between the sign and value.4986  //4987  // C11's localeconv specifies that the fourth character of an4988  // international curr_symbol is used to separate the sign and4989  // value when sep_by_space says to do so. C++ can't represent4990  // that, so we just use a space.  When sep_by_space says to4991  // separate the symbol and value-or-sign with a space, we rearrange the4992  // curr_symbol to put its spacing character on the correct side of4993  // the symbol.4994  //4995  // We also need to avoid adding an extra space between the sign4996  // and value when the currency symbol is suppressed (by not4997  // setting showbase).  We match glibc's strfmon by interpreting4998  // sep_by_space==1 as "omit the space when the currency symbol is4999  // absent".5000  //5001  // Users who want to get this right should use ICU instead.5002 5003  switch (cs_precedes) {5004  case 0: // value before curr_symbol5005    if (symbol_contains_sep) {5006      // Move the separator to before the symbol, to place it5007      // between the value and symbol.5008      rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, __curr_symbol_.end());5009    }5010    switch (sign_posn) {5011    case 0: // Parentheses surround the quantity and currency symbol.5012      pat.field[0] = sign;5013      pat.field[1] = value;5014      pat.field[2] = none; // Any space appears in the symbol.5015      pat.field[3] = symbol;5016      switch (sep_by_space) {5017      case 0: // No space separates the currency symbol and value.5018              // This case may have changed between C99 and C11;5019              // assume the currency symbol matches the intention.5020      case 2: // Space between sign and currency or value.5021        // The "sign" is two parentheses, so no space here either.5022        return;5023      case 1: // Space between currency-and-sign or currency and value.5024        if (!symbol_contains_sep) {5025          // We insert the space into the symbol instead of5026          // setting pat.field[2]=space so that when5027          // showbase is not set, the space goes away too.5028          __curr_symbol_.insert(0, 1, space_char);5029        }5030        return;5031      default:5032        break;5033      }5034      break;5035    case 1: // The sign string precedes the quantity and currency symbol.5036      pat.field[0] = sign;5037      pat.field[3] = symbol;5038      switch (sep_by_space) {5039      case 0: // No space separates the currency symbol and value.5040        pat.field[1] = value;5041        pat.field[2] = none;5042        return;5043      case 1: // Space between currency-and-sign or currency and value.5044        pat.field[1] = value;5045        pat.field[2] = none;5046        if (!symbol_contains_sep) {5047          // We insert the space into the symbol instead of5048          // setting pat.field[2]=space so that when5049          // showbase is not set, the space goes away too.5050          __curr_symbol_.insert(0, 1, space_char);5051        }5052        return;5053      case 2: // Space between sign and currency or value.5054        pat.field[1] = space;5055        pat.field[2] = value;5056        if (symbol_contains_sep) {5057          // Remove the separator from the symbol, since it5058          // has already appeared after the sign.5059          __curr_symbol_.erase(__curr_symbol_.begin());5060        }5061        return;5062      default:5063        break;5064      }5065      break;5066    case 2: // The sign string succeeds the quantity and currency symbol.5067      pat.field[0] = value;5068      pat.field[3] = sign;5069      switch (sep_by_space) {5070      case 0: // No space separates the currency symbol and value.5071        pat.field[1] = none;5072        pat.field[2] = symbol;5073        return;5074      case 1: // Space between currency-and-sign or currency and value.5075        if (!symbol_contains_sep) {5076          // We insert the space into the symbol instead of5077          // setting pat.field[1]=space so that when5078          // showbase is not set, the space goes away too.5079          __curr_symbol_.insert(0, 1, space_char);5080        }5081        pat.field[1] = none;5082        pat.field[2] = symbol;5083        return;5084      case 2: // Space between sign and currency or value.5085        pat.field[1] = symbol;5086        pat.field[2] = space;5087        if (symbol_contains_sep) {5088          // Remove the separator from the symbol, since it5089          // should not be removed if showbase is absent.5090          __curr_symbol_.erase(__curr_symbol_.begin());5091        }5092        return;5093      default:5094        break;5095      }5096      break;5097    case 3: // The sign string immediately precedes the currency symbol.5098      pat.field[0] = value;5099      pat.field[3] = symbol;5100      switch (sep_by_space) {5101      case 0: // No space separates the currency symbol and value.5102        pat.field[1] = none;5103        pat.field[2] = sign;5104        return;5105      case 1: // Space between currency-and-sign or currency and value.5106        pat.field[1] = space;5107        pat.field[2] = sign;5108        if (symbol_contains_sep) {5109          // Remove the separator from the symbol, since it5110          // has already appeared before the sign.5111          __curr_symbol_.erase(__curr_symbol_.begin());5112        }5113        return;5114      case 2: // Space between sign and currency or value.5115        pat.field[1] = sign;5116        pat.field[2] = none;5117        if (!symbol_contains_sep) {5118          // We insert the space into the symbol instead of5119          // setting pat.field[2]=space so that when5120          // showbase is not set, the space goes away too.5121          __curr_symbol_.insert(0, 1, space_char);5122        }5123        return;5124      default:5125        break;5126      }5127      break;5128    case 4: // The sign string immediately succeeds the currency symbol.5129      pat.field[0] = value;5130      pat.field[3] = sign;5131      switch (sep_by_space) {5132      case 0: // No space separates the currency symbol and value.5133        pat.field[1] = none;5134        pat.field[2] = symbol;5135        return;5136      case 1: // Space between currency-and-sign or currency and value.5137        pat.field[1] = none;5138        pat.field[2] = symbol;5139        if (!symbol_contains_sep) {5140          // We insert the space into the symbol instead of5141          // setting pat.field[1]=space so that when5142          // showbase is not set, the space goes away too.5143          __curr_symbol_.insert(0, 1, space_char);5144        }5145        return;5146      case 2: // Space between sign and currency or value.5147        pat.field[1] = symbol;5148        pat.field[2] = space;5149        if (symbol_contains_sep) {5150          // Remove the separator from the symbol, since it5151          // should not disappear when showbase is absent.5152          __curr_symbol_.erase(__curr_symbol_.begin());5153        }5154        return;5155      default:5156        break;5157      }5158      break;5159    default:5160      break;5161    }5162    break;5163  case 1: // curr_symbol before value5164    switch (sign_posn) {5165    case 0: // Parentheses surround the quantity and currency symbol.5166      pat.field[0] = sign;5167      pat.field[1] = symbol;5168      pat.field[2] = none; // Any space appears in the symbol.5169      pat.field[3] = value;5170      switch (sep_by_space) {5171      case 0: // No space separates the currency symbol and value.5172              // This case may have changed between C99 and C11;5173              // assume the currency symbol matches the intention.5174      case 2: // Space between sign and currency or value.5175        // The "sign" is two parentheses, so no space here either.5176        return;5177      case 1: // Space between currency-and-sign or currency and value.5178        if (!symbol_contains_sep) {5179          // We insert the space into the symbol instead of5180          // setting pat.field[2]=space so that when5181          // showbase is not set, the space goes away too.5182          __curr_symbol_.insert(0, 1, space_char);5183        }5184        return;5185      default:5186        break;5187      }5188      break;5189    case 1: // The sign string precedes the quantity and currency symbol.5190      pat.field[0] = sign;5191      pat.field[3] = value;5192      switch (sep_by_space) {5193      case 0: // No space separates the currency symbol and value.5194        pat.field[1] = symbol;5195        pat.field[2] = none;5196        return;5197      case 1: // Space between currency-and-sign or currency and value.5198        pat.field[1] = symbol;5199        pat.field[2] = none;5200        if (!symbol_contains_sep) {5201          // We insert the space into the symbol instead of5202          // setting pat.field[2]=space so that when5203          // showbase is not set, the space goes away too.5204          __curr_symbol_.push_back(space_char);5205        }5206        return;5207      case 2: // Space between sign and currency or value.5208        pat.field[1] = space;5209        pat.field[2] = symbol;5210        if (symbol_contains_sep) {5211          // Remove the separator from the symbol, since it5212          // has already appeared after the sign.5213          __curr_symbol_.pop_back();5214        }5215        return;5216      default:5217        break;5218      }5219      break;5220    case 2: // The sign string succeeds the quantity and currency symbol.5221      pat.field[0] = symbol;5222      pat.field[3] = sign;5223      switch (sep_by_space) {5224      case 0: // No space separates the currency symbol and value.5225        pat.field[1] = none;5226        pat.field[2] = value;5227        return;5228      case 1: // Space between currency-and-sign or currency and value.5229        pat.field[1] = none;5230        pat.field[2] = value;5231        if (!symbol_contains_sep) {5232          // We insert the space into the symbol instead of5233          // setting pat.field[1]=space so that when5234          // showbase is not set, the space goes away too.5235          __curr_symbol_.push_back(space_char);5236        }5237        return;5238      case 2: // Space between sign and currency or value.5239        pat.field[1] = value;5240        pat.field[2] = space;5241        if (symbol_contains_sep) {5242          // Remove the separator from the symbol, since it5243          // will appear before the sign.5244          __curr_symbol_.pop_back();5245        }5246        return;5247      default:5248        break;5249      }5250      break;5251    case 3: // The sign string immediately precedes the currency symbol.5252      pat.field[0] = sign;5253      pat.field[3] = value;5254      switch (sep_by_space) {5255      case 0: // No space separates the currency symbol and value.5256        pat.field[1] = symbol;5257        pat.field[2] = none;5258        return;5259      case 1: // Space between currency-and-sign or currency and value.5260        pat.field[1] = symbol;5261        pat.field[2] = none;5262        if (!symbol_contains_sep) {5263          // We insert the space into the symbol instead of5264          // setting pat.field[2]=space so that when5265          // showbase is not set, the space goes away too.5266          __curr_symbol_.push_back(space_char);5267        }5268        return;5269      case 2: // Space between sign and currency or value.5270        pat.field[1] = space;5271        pat.field[2] = symbol;5272        if (symbol_contains_sep) {5273          // Remove the separator from the symbol, since it5274          // has already appeared after the sign.5275          __curr_symbol_.pop_back();5276        }5277        return;5278      default:5279        break;5280      }5281      break;5282    case 4: // The sign string immediately succeeds the currency symbol.5283      pat.field[0] = symbol;5284      pat.field[3] = value;5285      switch (sep_by_space) {5286      case 0: // No space separates the currency symbol and value.5287        pat.field[1] = sign;5288        pat.field[2] = none;5289        return;5290      case 1: // Space between currency-and-sign or currency and value.5291        pat.field[1] = sign;5292        pat.field[2] = space;5293        if (symbol_contains_sep) {5294          // Remove the separator from the symbol, since it5295          // should not disappear when showbase is absent.5296          __curr_symbol_.pop_back();5297        }5298        return;5299      case 2: // Space between sign and currency or value.5300        pat.field[1] = none;5301        pat.field[2] = sign;5302        if (!symbol_contains_sep) {5303          // We insert the space into the symbol instead of5304          // setting pat.field[1]=space so that when5305          // showbase is not set, the space goes away too.5306          __curr_symbol_.push_back(space_char);5307        }5308        return;5309      default:5310        break;5311      }5312      break;5313    default:5314      break;5315    }5316    break;5317  default:5318    break;5319  }5320  pat.field[0] = symbol;5321  pat.field[1] = sign;5322  pat.field[2] = none;5323  pat.field[3] = value;5324}5325 5326template <>5327void moneypunct_byname<char, false>::init(const char* nm) {5328  typedef moneypunct<char, false> base;5329  __libcpp_unique_locale loc(nm);5330  if (!loc)5331    std::__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());5332 5333  __locale::__lconv_t* lc = __locale::__localeconv(loc.get());5334  if (!checked_string_to_char_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5335    __decimal_point_ = base::do_decimal_point();5336  if (!checked_string_to_char_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5337    __thousands_sep_ = base::do_thousands_sep();5338 5339  __grouping_    = lc->mon_grouping;5340  __curr_symbol_ = lc->currency_symbol;5341  if (lc->frac_digits != CHAR_MAX)5342    __frac_digits_ = lc->frac_digits;5343  else5344    __frac_digits_ = base::do_frac_digits();5345  if (lc->p_sign_posn == 0)5346    __positive_sign_ = "()";5347  else5348    __positive_sign_ = lc->positive_sign;5349  if (lc->n_sign_posn == 0)5350    __negative_sign_ = "()";5351  else5352    __negative_sign_ = lc->negative_sign;5353  // Assume the positive and negative formats will want spaces in5354  // the same places in curr_symbol since there's no way to5355  // represent anything else.5356  string_type __dummy_curr_symbol = __curr_symbol_;5357  __init_pat(__pos_format_, __dummy_curr_symbol, false, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');5358  __init_pat(__neg_format_, __curr_symbol_, false, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');5359}5360 5361template <>5362void moneypunct_byname<char, true>::init(const char* nm) {5363  typedef moneypunct<char, true> base;5364  __libcpp_unique_locale loc(nm);5365  if (!loc)5366    std::__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());5367 5368  __locale::__lconv_t* lc = __locale::__localeconv(loc.get());5369  if (!checked_string_to_char_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5370    __decimal_point_ = base::do_decimal_point();5371  if (!checked_string_to_char_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5372    __thousands_sep_ = base::do_thousands_sep();5373  __grouping_    = lc->mon_grouping;5374  __curr_symbol_ = lc->int_curr_symbol;5375  if (lc->int_frac_digits != CHAR_MAX)5376    __frac_digits_ = lc->int_frac_digits;5377  else5378    __frac_digits_ = base::do_frac_digits();5379#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5380  if (lc->p_sign_posn == 0)5381#else  // _LIBCPP_MSVCRT5382  if (lc->int_p_sign_posn == 0)5383#endif // !_LIBCPP_MSVCRT5384    __positive_sign_ = "()";5385  else5386    __positive_sign_ = lc->positive_sign;5387#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5388  if (lc->n_sign_posn == 0)5389#else  // _LIBCPP_MSVCRT5390  if (lc->int_n_sign_posn == 0)5391#endif // !_LIBCPP_MSVCRT5392    __negative_sign_ = "()";5393  else5394    __negative_sign_ = lc->negative_sign;5395  // Assume the positive and negative formats will want spaces in5396  // the same places in curr_symbol since there's no way to5397  // represent anything else.5398  string_type __dummy_curr_symbol = __curr_symbol_;5399#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5400  __init_pat(__pos_format_, __dummy_curr_symbol, true, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');5401  __init_pat(__neg_format_, __curr_symbol_, true, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');5402#else  // _LIBCPP_MSVCRT5403  __init_pat(5404      __pos_format_,5405      __dummy_curr_symbol,5406      true,5407      lc->int_p_cs_precedes,5408      lc->int_p_sep_by_space,5409      lc->int_p_sign_posn,5410      ' ');5411  __init_pat(5412      __neg_format_, __curr_symbol_, true, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn, ' ');5413#endif // !_LIBCPP_MSVCRT5414}5415 5416#if _LIBCPP_HAS_WIDE_CHARACTERS5417template <>5418void moneypunct_byname<wchar_t, false>::init(const char* nm) {5419  typedef moneypunct<wchar_t, false> base;5420  __libcpp_unique_locale loc(nm);5421  if (!loc)5422    std::__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());5423  __locale::__lconv_t* lc = __locale::__localeconv(loc.get());5424  if (!checked_string_to_wchar_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5425    __decimal_point_ = base::do_decimal_point();5426  if (!checked_string_to_wchar_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5427    __thousands_sep_ = base::do_thousands_sep();5428  __grouping_ = lc->mon_grouping;5429  wchar_t wbuf[100];5430  mbstate_t mb   = {0};5431  const char* bb = lc->currency_symbol;5432  size_t j       = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());5433  if (j == size_t(-1))5434    std::__throw_runtime_error("locale not supported");5435  wchar_t* wbe = wbuf + j;5436  __curr_symbol_.assign(wbuf, wbe);5437  if (lc->frac_digits != CHAR_MAX)5438    __frac_digits_ = lc->frac_digits;5439  else5440    __frac_digits_ = base::do_frac_digits();5441  if (lc->p_sign_posn == 0)5442    __positive_sign_ = L"()";5443  else {5444    mb = mbstate_t();5445    bb = lc->positive_sign;5446    j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());5447    if (j == size_t(-1))5448      std::__throw_runtime_error("locale not supported");5449    wbe = wbuf + j;5450    __positive_sign_.assign(wbuf, wbe);5451  }5452  if (lc->n_sign_posn == 0)5453    __negative_sign_ = L"()";5454  else {5455    mb = mbstate_t();5456    bb = lc->negative_sign;5457    j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());5458    if (j == size_t(-1))5459      std::__throw_runtime_error("locale not supported");5460    wbe = wbuf + j;5461    __negative_sign_.assign(wbuf, wbe);5462  }5463  // Assume the positive and negative formats will want spaces in5464  // the same places in curr_symbol since there's no way to5465  // represent anything else.5466  string_type __dummy_curr_symbol = __curr_symbol_;5467  __init_pat(__pos_format_, __dummy_curr_symbol, false, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');5468  __init_pat(__neg_format_, __curr_symbol_, false, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');5469}5470 5471template <>5472void moneypunct_byname<wchar_t, true>::init(const char* nm) {5473  typedef moneypunct<wchar_t, true> base;5474  __libcpp_unique_locale loc(nm);5475  if (!loc)5476    std::__throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm)).c_str());5477 5478  __locale::__lconv_t* lc = __locale::__localeconv(loc.get());5479  if (!checked_string_to_wchar_convert(__decimal_point_, lc->mon_decimal_point, loc.get()))5480    __decimal_point_ = base::do_decimal_point();5481  if (!checked_string_to_wchar_convert(__thousands_sep_, lc->mon_thousands_sep, loc.get()))5482    __thousands_sep_ = base::do_thousands_sep();5483  __grouping_ = lc->mon_grouping;5484  wchar_t wbuf[100];5485  mbstate_t mb   = {0};5486  const char* bb = lc->int_curr_symbol;5487  size_t j       = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());5488  if (j == size_t(-1))5489    std::__throw_runtime_error("locale not supported");5490  wchar_t* wbe = wbuf + j;5491  __curr_symbol_.assign(wbuf, wbe);5492  if (lc->int_frac_digits != CHAR_MAX)5493    __frac_digits_ = lc->int_frac_digits;5494  else5495    __frac_digits_ = base::do_frac_digits();5496#  if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5497  if (lc->p_sign_posn == 0)5498#  else  // _LIBCPP_MSVCRT5499  if (lc->int_p_sign_posn == 0)5500#  endif // !_LIBCPP_MSVCRT5501    __positive_sign_ = L"()";5502  else {5503    mb = mbstate_t();5504    bb = lc->positive_sign;5505    j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());5506    if (j == size_t(-1))5507      std::__throw_runtime_error("locale not supported");5508    wbe = wbuf + j;5509    __positive_sign_.assign(wbuf, wbe);5510  }5511#  if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5512  if (lc->n_sign_posn == 0)5513#  else  // _LIBCPP_MSVCRT5514  if (lc->int_n_sign_posn == 0)5515#  endif // !_LIBCPP_MSVCRT5516    __negative_sign_ = L"()";5517  else {5518    mb = mbstate_t();5519    bb = lc->negative_sign;5520    j  = __locale::__mbsrtowcs(wbuf, &bb, countof(wbuf), &mb, loc.get());5521    if (j == size_t(-1))5522      std::__throw_runtime_error("locale not supported");5523    wbe = wbuf + j;5524    __negative_sign_.assign(wbuf, wbe);5525  }5526  // Assume the positive and negative formats will want spaces in5527  // the same places in curr_symbol since there's no way to5528  // represent anything else.5529  string_type __dummy_curr_symbol = __curr_symbol_;5530#  if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)5531  __init_pat(__pos_format_, __dummy_curr_symbol, true, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');5532  __init_pat(__neg_format_, __curr_symbol_, true, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');5533#  else  // _LIBCPP_MSVCRT5534  __init_pat(5535      __pos_format_,5536      __dummy_curr_symbol,5537      true,5538      lc->int_p_cs_precedes,5539      lc->int_p_sep_by_space,5540      lc->int_p_sign_posn,5541      L' ');5542  __init_pat(5543      __neg_format_, __curr_symbol_, true, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn, L' ');5544#  endif // !_LIBCPP_MSVCRT5545}5546#endif // _LIBCPP_HAS_WIDE_CHARACTERS5547 5548void __do_nothing(void*) {}5549 5550// Legacy ABI __num_get functions - the new ones are _LIBCPP_HIDE_FROM_ABI5551template <class _CharT>5552string __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) {5553  locale __loc = __iob.getloc();5554  std::use_facet<ctype<_CharT> >(__loc).widen(__src, __src + __int_chr_cnt, __atoms);5555  const numpunct<_CharT>& __np = std::use_facet<numpunct<_CharT> >(__loc);5556  __thousands_sep              = __np.thousands_sep();5557  return __np.grouping();5558}5559 5560template <class _CharT>5561int __num_get<_CharT>::__stage2_int_loop(5562    _CharT __ct,5563    int __base,5564    char* __a,5565    char*& __a_end,5566    unsigned& __dc,5567    _CharT __thousands_sep,5568    const string& __grouping,5569    unsigned* __g,5570    unsigned*& __g_end,5571    _CharT* __atoms) {5572  if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) {5573    *__a_end++ = __ct == __atoms[24] ? '+' : '-';5574    __dc       = 0;5575    return 0;5576  }5577  if (__grouping.size() != 0 && __ct == __thousands_sep) {5578    if (__g_end - __g < __num_get_buf_sz) {5579      *__g_end++ = __dc;5580      __dc       = 0;5581    }5582    return 0;5583  }5584  ptrdiff_t __f = __atoms_offset(__atoms, __ct);5585  if (__f >= 24)5586    return -1;5587  switch (__base) {5588  case 8:5589  case 10:5590    if (__f >= __base)5591      return -1;5592    break;5593  case 16:5594    if (__f < 22)5595      break;5596    if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') {5597      __dc       = 0;5598      *__a_end++ = __src[__f];5599      return 0;5600    }5601    return -1;5602  }5603  *__a_end++ = __src[__f];5604  ++__dc;5605  return 0;5606}5607 5608template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;5609_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)5610 5611template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;5612_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)5613 5614template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;5615_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)5616 5617template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;5618_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)5619 5620template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;5621_LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)5622 5623template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;5624_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)5625 5626template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;5627_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)5628 5629template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;5630_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)5631 5632template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;5633_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)5634 5635template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;5636template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;5637_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)5638_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)5639 5640template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;5641template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;5642_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)5643_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)5644 5645template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;5646_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)5647 5648template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;5649_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)5650 5651template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;5652_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)5653 5654template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;5655_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)5656 5657template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;5658_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)5659 5660template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;5661_LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)5662 5663template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;5664_LIBCPP_IF_WIDE_CHARACTERS(5665    template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)5666template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS5667    codecvt_byname<char16_t, char, mbstate_t>;5668template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS5669    codecvt_byname<char32_t, char, mbstate_t>;5670#if _LIBCPP_HAS_CHAR8_T5671template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;5672template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;5673#endif5674 5675_LIBCPP_END_NAMESPACE_STD5676 5677_LIBCPP_POP_MACROS5678