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