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