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