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