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