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