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