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