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