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