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