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