locale.cpp revision 249998
1227825Stheraven//===------------------------- locale.cpp ---------------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10232950Stheraven// On Solaris, we need to define something to make the C99 parts of localeconv 11232950Stheraven// visible. 12232950Stheraven#ifdef __sun__ 13232950Stheraven#define _LCONV_C99 14232950Stheraven#endif 15232950Stheraven 16227825Stheraven#include "string" 17227825Stheraven#include "locale" 18227825Stheraven#include "codecvt" 19227825Stheraven#include "vector" 20227825Stheraven#include "algorithm" 21227825Stheraven#include "algorithm" 22227825Stheraven#include "typeinfo" 23227825Stheraven#include "type_traits" 24227825Stheraven#include "clocale" 25227825Stheraven#include "cstring" 26227825Stheraven#include "cwctype" 27227825Stheraven#include "__sso_allocator" 28249998Sdim#ifdef _WIN32 29227825Stheraven#include <support/win32/locale_win32.h> 30227825Stheraven#else // _WIN32 31227825Stheraven#include <langinfo.h> 32227825Stheraven#endif // _!WIN32 33227825Stheraven#include <stdlib.h> 34227825Stheraven 35249998Sdim// On Linux, wint_t and wchar_t have different signed-ness, and this causes 36249998Sdim// lots of noise in the build log, but no bugs that I know of. 37249998Sdim#pragma clang diagnostic ignored "-Wsign-conversion" 38249998Sdim 39227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 40227825Stheraven 41227825Stheraven#ifdef __cloc_defined 42227825Stheravenlocale_t __cloc() { 43227825Stheraven // In theory this could create a race condition. In practice 44227825Stheraven // the race condition is non-fatal since it will just create 45227825Stheraven // a little resource leak. Better approach would be appreciated. 46227825Stheraven static locale_t result = newlocale(LC_ALL_MASK, "C", 0); 47227825Stheraven return result; 48227825Stheraven} 49227825Stheraven#endif // __cloc_defined 50227825Stheraven 51227825Stheravennamespace { 52227825Stheraven 53227825Stheravenstruct release 54227825Stheraven{ 55227825Stheraven void operator()(locale::facet* p) {p->__release_shared();} 56227825Stheraven}; 57227825Stheraven 58227825Stheraventemplate <class T, class A0> 59227825Stheraveninline 60227825StheravenT& 61227825Stheravenmake(A0 a0) 62227825Stheraven{ 63227825Stheraven static typename aligned_storage<sizeof(T)>::type buf; 64227825Stheraven ::new (&buf) T(a0); 65227825Stheraven return *(T*)&buf; 66227825Stheraven} 67227825Stheraven 68227825Stheraventemplate <class T, class A0, class A1> 69227825Stheraveninline 70227825StheravenT& 71227825Stheravenmake(A0 a0, A1 a1) 72227825Stheraven{ 73227825Stheraven static typename aligned_storage<sizeof(T)>::type buf; 74227825Stheraven ::new (&buf) T(a0, a1); 75227825Stheraven return *(T*)&buf; 76227825Stheraven} 77227825Stheraven 78227825Stheraventemplate <class T, class A0, class A1, class A2> 79227825Stheraveninline 80227825StheravenT& 81227825Stheravenmake(A0 a0, A1 a1, A2 a2) 82227825Stheraven{ 83227825Stheraven static typename aligned_storage<sizeof(T)>::type buf; 84227825Stheraven ::new (&buf) T(a0, a1, a2); 85227825Stheraven return *(T*)&buf; 86227825Stheraven} 87227825Stheraven 88246487Stheraventemplate <typename T, size_t N> 89246487Stheraveninline 90246487Stheraven_LIBCPP_CONSTEXPR 91246487Stheravensize_t 92246487Stheravencountof(const T (&)[N]) 93246487Stheraven{ 94246487Stheraven return N; 95227825Stheraven} 96227825Stheraven 97246487Stheraventemplate <typename T> 98246487Stheraveninline 99246487Stheraven_LIBCPP_CONSTEXPR 100246487Stheravensize_t 101246487Stheravencountof(const T * const begin, const T * const end) 102246487Stheraven{ 103246487Stheraven return static_cast<size_t>(end - begin); 104246487Stheraven} 105246487Stheraven 106246487Stheraven} 107246487Stheraven 108246487Stheravenconst locale::category locale::none; 109246487Stheravenconst locale::category locale::collate; 110246487Stheravenconst locale::category locale::ctype; 111246487Stheravenconst locale::category locale::monetary; 112246487Stheravenconst locale::category locale::numeric; 113246487Stheravenconst locale::category locale::time; 114246487Stheravenconst locale::category locale::messages; 115246487Stheravenconst locale::category locale::all; 116246487Stheraven 117232950Stheraven#pragma clang diagnostic push 118232950Stheraven#pragma clang diagnostic ignored "-Wpadded" 119232950Stheraven 120227825Stheravenclass _LIBCPP_HIDDEN locale::__imp 121227825Stheraven : public facet 122227825Stheraven{ 123227825Stheraven enum {N = 28}; 124232950Stheraven vector<facet*, __sso_allocator<facet*, N> > facets_; 125227825Stheraven string name_; 126227825Stheravenpublic: 127227825Stheraven explicit __imp(size_t refs = 0); 128227825Stheraven explicit __imp(const string& name, size_t refs = 0); 129227825Stheraven __imp(const __imp&); 130227825Stheraven __imp(const __imp&, const string&, locale::category c); 131227825Stheraven __imp(const __imp& other, const __imp& one, locale::category c); 132227825Stheraven __imp(const __imp&, facet* f, long id); 133227825Stheraven ~__imp(); 134227825Stheraven 135227825Stheraven const string& name() const {return name_;} 136232950Stheraven bool has_facet(long id) const 137232950Stheraven {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];} 138227825Stheraven const locale::facet* use_facet(long id) const; 139227825Stheraven 140227825Stheraven static const locale& make_classic(); 141227825Stheraven static locale& make_global(); 142227825Stheravenprivate: 143227825Stheraven void install(facet* f, long id); 144227825Stheraven template <class F> void install(F* f) {install(f, f->id.__get());} 145227825Stheraven template <class F> void install_from(const __imp& other); 146227825Stheraven}; 147227825Stheraven 148232950Stheraven#pragma clang diagnostic pop 149232950Stheraven 150227825Stheravenlocale::__imp::__imp(size_t refs) 151227825Stheraven : facet(refs), 152232950Stheraven facets_(N), 153232950Stheraven name_("C") 154227825Stheraven{ 155227825Stheraven facets_.clear(); 156232950Stheraven install(&make<_VSTD::collate<char> >(1u)); 157232950Stheraven install(&make<_VSTD::collate<wchar_t> >(1u)); 158232950Stheraven install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1u)); 159232950Stheraven install(&make<_VSTD::ctype<wchar_t> >(1u)); 160232950Stheraven install(&make<codecvt<char, char, mbstate_t> >(1u)); 161232950Stheraven install(&make<codecvt<wchar_t, char, mbstate_t> >(1u)); 162232950Stheraven install(&make<codecvt<char16_t, char, mbstate_t> >(1u)); 163232950Stheraven install(&make<codecvt<char32_t, char, mbstate_t> >(1u)); 164232950Stheraven install(&make<numpunct<char> >(1u)); 165232950Stheraven install(&make<numpunct<wchar_t> >(1u)); 166232950Stheraven install(&make<num_get<char> >(1u)); 167232950Stheraven install(&make<num_get<wchar_t> >(1u)); 168232950Stheraven install(&make<num_put<char> >(1u)); 169232950Stheraven install(&make<num_put<wchar_t> >(1u)); 170232950Stheraven install(&make<moneypunct<char, false> >(1u)); 171232950Stheraven install(&make<moneypunct<char, true> >(1u)); 172232950Stheraven install(&make<moneypunct<wchar_t, false> >(1u)); 173232950Stheraven install(&make<moneypunct<wchar_t, true> >(1u)); 174232950Stheraven install(&make<money_get<char> >(1u)); 175232950Stheraven install(&make<money_get<wchar_t> >(1u)); 176232950Stheraven install(&make<money_put<char> >(1u)); 177232950Stheraven install(&make<money_put<wchar_t> >(1u)); 178232950Stheraven install(&make<time_get<char> >(1u)); 179232950Stheraven install(&make<time_get<wchar_t> >(1u)); 180232950Stheraven install(&make<time_put<char> >(1u)); 181232950Stheraven install(&make<time_put<wchar_t> >(1u)); 182232950Stheraven install(&make<_VSTD::messages<char> >(1u)); 183232950Stheraven install(&make<_VSTD::messages<wchar_t> >(1u)); 184227825Stheraven} 185227825Stheraven 186227825Stheravenlocale::__imp::__imp(const string& name, size_t refs) 187227825Stheraven : facet(refs), 188232950Stheraven facets_(N), 189232950Stheraven name_(name) 190227825Stheraven{ 191227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 192227825Stheraven try 193227825Stheraven { 194227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 195227825Stheraven facets_ = locale::classic().__locale_->facets_; 196227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 197227825Stheraven if (facets_[i]) 198227825Stheraven facets_[i]->__add_shared(); 199227825Stheraven install(new collate_byname<char>(name_)); 200227825Stheraven install(new collate_byname<wchar_t>(name_)); 201227825Stheraven install(new ctype_byname<char>(name_)); 202227825Stheraven install(new ctype_byname<wchar_t>(name_)); 203227825Stheraven install(new codecvt_byname<char, char, mbstate_t>(name_)); 204227825Stheraven install(new codecvt_byname<wchar_t, char, mbstate_t>(name_)); 205227825Stheraven install(new codecvt_byname<char16_t, char, mbstate_t>(name_)); 206227825Stheraven install(new codecvt_byname<char32_t, char, mbstate_t>(name_)); 207227825Stheraven install(new numpunct_byname<char>(name_)); 208227825Stheraven install(new numpunct_byname<wchar_t>(name_)); 209227825Stheraven install(new moneypunct_byname<char, false>(name_)); 210227825Stheraven install(new moneypunct_byname<char, true>(name_)); 211227825Stheraven install(new moneypunct_byname<wchar_t, false>(name_)); 212227825Stheraven install(new moneypunct_byname<wchar_t, true>(name_)); 213227825Stheraven install(new time_get_byname<char>(name_)); 214227825Stheraven install(new time_get_byname<wchar_t>(name_)); 215227825Stheraven install(new time_put_byname<char>(name_)); 216227825Stheraven install(new time_put_byname<wchar_t>(name_)); 217227825Stheraven install(new messages_byname<char>(name_)); 218227825Stheraven install(new messages_byname<wchar_t>(name_)); 219227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 220227825Stheraven } 221227825Stheraven catch (...) 222227825Stheraven { 223227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 224227825Stheraven if (facets_[i]) 225227825Stheraven facets_[i]->__release_shared(); 226227825Stheraven throw; 227227825Stheraven } 228227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 229227825Stheraven} 230227825Stheraven 231246487Stheraven// NOTE avoid the `base class should be explicitly initialized in the 232246487Stheraven// copy constructor` warning emitted by GCC 233246487Stheraven#pragma GCC diagnostic push 234246487Stheraven#pragma GCC diagnostic ignored "-Wextra" 235246487Stheraven 236227825Stheravenlocale::__imp::__imp(const __imp& other) 237232950Stheraven : facets_(max<size_t>(N, other.facets_.size())), 238232950Stheraven name_(other.name_) 239227825Stheraven{ 240227825Stheraven facets_ = other.facets_; 241227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 242227825Stheraven if (facets_[i]) 243227825Stheraven facets_[i]->__add_shared(); 244227825Stheraven} 245227825Stheraven 246246487Stheraven#pragma GCC diagnostic pop 247246487Stheraven 248227825Stheravenlocale::__imp::__imp(const __imp& other, const string& name, locale::category c) 249232950Stheraven : facets_(N), 250232950Stheraven name_("*") 251227825Stheraven{ 252227825Stheraven facets_ = other.facets_; 253227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 254227825Stheraven if (facets_[i]) 255227825Stheraven facets_[i]->__add_shared(); 256227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 257227825Stheraven try 258227825Stheraven { 259227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 260227825Stheraven if (c & locale::collate) 261227825Stheraven { 262227825Stheraven install(new collate_byname<char>(name)); 263227825Stheraven install(new collate_byname<wchar_t>(name)); 264227825Stheraven } 265227825Stheraven if (c & locale::ctype) 266227825Stheraven { 267227825Stheraven install(new ctype_byname<char>(name)); 268227825Stheraven install(new ctype_byname<wchar_t>(name)); 269227825Stheraven install(new codecvt_byname<char, char, mbstate_t>(name)); 270227825Stheraven install(new codecvt_byname<wchar_t, char, mbstate_t>(name)); 271227825Stheraven install(new codecvt_byname<char16_t, char, mbstate_t>(name)); 272227825Stheraven install(new codecvt_byname<char32_t, char, mbstate_t>(name)); 273227825Stheraven } 274227825Stheraven if (c & locale::monetary) 275227825Stheraven { 276227825Stheraven install(new moneypunct_byname<char, false>(name)); 277227825Stheraven install(new moneypunct_byname<char, true>(name)); 278227825Stheraven install(new moneypunct_byname<wchar_t, false>(name)); 279227825Stheraven install(new moneypunct_byname<wchar_t, true>(name)); 280227825Stheraven } 281227825Stheraven if (c & locale::numeric) 282227825Stheraven { 283227825Stheraven install(new numpunct_byname<char>(name)); 284227825Stheraven install(new numpunct_byname<wchar_t>(name)); 285227825Stheraven } 286227825Stheraven if (c & locale::time) 287227825Stheraven { 288227825Stheraven install(new time_get_byname<char>(name)); 289227825Stheraven install(new time_get_byname<wchar_t>(name)); 290227825Stheraven install(new time_put_byname<char>(name)); 291227825Stheraven install(new time_put_byname<wchar_t>(name)); 292227825Stheraven } 293227825Stheraven if (c & locale::messages) 294227825Stheraven { 295227825Stheraven install(new messages_byname<char>(name)); 296227825Stheraven install(new messages_byname<wchar_t>(name)); 297227825Stheraven } 298227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 299227825Stheraven } 300227825Stheraven catch (...) 301227825Stheraven { 302227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 303227825Stheraven if (facets_[i]) 304227825Stheraven facets_[i]->__release_shared(); 305227825Stheraven throw; 306227825Stheraven } 307227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 308227825Stheraven} 309227825Stheraven 310227825Stheraventemplate<class F> 311227825Stheraveninline 312227825Stheravenvoid 313227825Stheravenlocale::__imp::install_from(const locale::__imp& one) 314227825Stheraven{ 315227825Stheraven long id = F::id.__get(); 316227825Stheraven install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id); 317227825Stheraven} 318227825Stheraven 319227825Stheravenlocale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) 320232950Stheraven : facets_(N), 321232950Stheraven name_("*") 322227825Stheraven{ 323227825Stheraven facets_ = other.facets_; 324227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 325227825Stheraven if (facets_[i]) 326227825Stheraven facets_[i]->__add_shared(); 327227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 328227825Stheraven try 329227825Stheraven { 330227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 331227825Stheraven if (c & locale::collate) 332227825Stheraven { 333227825Stheraven install_from<_VSTD::collate<char> >(one); 334227825Stheraven install_from<_VSTD::collate<wchar_t> >(one); 335227825Stheraven } 336227825Stheraven if (c & locale::ctype) 337227825Stheraven { 338227825Stheraven install_from<_VSTD::ctype<char> >(one); 339227825Stheraven install_from<_VSTD::ctype<wchar_t> >(one); 340227825Stheraven install_from<_VSTD::codecvt<char, char, mbstate_t> >(one); 341227825Stheraven install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one); 342227825Stheraven install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one); 343227825Stheraven install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one); 344227825Stheraven } 345227825Stheraven if (c & locale::monetary) 346227825Stheraven { 347227825Stheraven install_from<moneypunct<char, false> >(one); 348227825Stheraven install_from<moneypunct<char, true> >(one); 349227825Stheraven install_from<moneypunct<wchar_t, false> >(one); 350227825Stheraven install_from<moneypunct<wchar_t, true> >(one); 351227825Stheraven install_from<money_get<char> >(one); 352227825Stheraven install_from<money_get<wchar_t> >(one); 353227825Stheraven install_from<money_put<char> >(one); 354227825Stheraven install_from<money_put<wchar_t> >(one); 355227825Stheraven } 356227825Stheraven if (c & locale::numeric) 357227825Stheraven { 358227825Stheraven install_from<numpunct<char> >(one); 359227825Stheraven install_from<numpunct<wchar_t> >(one); 360227825Stheraven install_from<num_get<char> >(one); 361227825Stheraven install_from<num_get<wchar_t> >(one); 362227825Stheraven install_from<num_put<char> >(one); 363227825Stheraven install_from<num_put<wchar_t> >(one); 364227825Stheraven } 365227825Stheraven if (c & locale::time) 366227825Stheraven { 367227825Stheraven install_from<time_get<char> >(one); 368227825Stheraven install_from<time_get<wchar_t> >(one); 369227825Stheraven install_from<time_put<char> >(one); 370227825Stheraven install_from<time_put<wchar_t> >(one); 371227825Stheraven } 372227825Stheraven if (c & locale::messages) 373227825Stheraven { 374227825Stheraven install_from<_VSTD::messages<char> >(one); 375227825Stheraven install_from<_VSTD::messages<wchar_t> >(one); 376227825Stheraven } 377227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 378227825Stheraven } 379227825Stheraven catch (...) 380227825Stheraven { 381227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 382227825Stheraven if (facets_[i]) 383227825Stheraven facets_[i]->__release_shared(); 384227825Stheraven throw; 385227825Stheraven } 386227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 387227825Stheraven} 388227825Stheraven 389227825Stheravenlocale::__imp::__imp(const __imp& other, facet* f, long id) 390232950Stheraven : facets_(max<size_t>(N, other.facets_.size()+1)), 391232950Stheraven name_("*") 392227825Stheraven{ 393227825Stheraven f->__add_shared(); 394227825Stheraven unique_ptr<facet, release> hold(f); 395227825Stheraven facets_ = other.facets_; 396227825Stheraven for (unsigned i = 0; i < other.facets_.size(); ++i) 397227825Stheraven if (facets_[i]) 398227825Stheraven facets_[i]->__add_shared(); 399227825Stheraven install(hold.get(), id); 400227825Stheraven} 401227825Stheraven 402227825Stheravenlocale::__imp::~__imp() 403227825Stheraven{ 404227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 405227825Stheraven if (facets_[i]) 406227825Stheraven facets_[i]->__release_shared(); 407227825Stheraven} 408227825Stheraven 409227825Stheravenvoid 410227825Stheravenlocale::__imp::install(facet* f, long id) 411227825Stheraven{ 412227825Stheraven f->__add_shared(); 413227825Stheraven unique_ptr<facet, release> hold(f); 414232950Stheraven if (static_cast<size_t>(id) >= facets_.size()) 415232950Stheraven facets_.resize(static_cast<size_t>(id+1)); 416232950Stheraven if (facets_[static_cast<size_t>(id)]) 417232950Stheraven facets_[static_cast<size_t>(id)]->__release_shared(); 418232950Stheraven facets_[static_cast<size_t>(id)] = hold.release(); 419227825Stheraven} 420227825Stheraven 421227825Stheravenconst locale::facet* 422227825Stheravenlocale::__imp::use_facet(long id) const 423227825Stheraven{ 424227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 425227825Stheraven if (!has_facet(id)) 426227825Stheraven throw bad_cast(); 427227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 428232950Stheraven return facets_[static_cast<size_t>(id)]; 429227825Stheraven} 430227825Stheraven 431227825Stheraven// locale 432227825Stheraven 433227825Stheravenconst locale& 434227825Stheravenlocale::__imp::make_classic() 435227825Stheraven{ 436227825Stheraven // only one thread can get in here and it only gets in once 437227825Stheraven static aligned_storage<sizeof(locale)>::type buf; 438227825Stheraven locale* c = (locale*)&buf; 439232950Stheraven c->__locale_ = &make<__imp>(1u); 440227825Stheraven return *c; 441227825Stheraven} 442227825Stheraven 443227825Stheravenconst locale& 444227825Stheravenlocale::classic() 445227825Stheraven{ 446227825Stheraven static const locale& c = __imp::make_classic(); 447227825Stheraven return c; 448227825Stheraven} 449227825Stheraven 450227825Stheravenlocale& 451227825Stheravenlocale::__imp::make_global() 452227825Stheraven{ 453227825Stheraven // only one thread can get in here and it only gets in once 454227825Stheraven static aligned_storage<sizeof(locale)>::type buf; 455227825Stheraven ::new (&buf) locale(locale::classic()); 456227825Stheraven return *(locale*)&buf; 457227825Stheraven} 458227825Stheraven 459227825Stheravenlocale& 460227825Stheravenlocale::__global() 461227825Stheraven{ 462227825Stheraven static locale& g = __imp::make_global(); 463227825Stheraven return g; 464227825Stheraven} 465227825Stheraven 466227825Stheravenlocale::locale() _NOEXCEPT 467227825Stheraven : __locale_(__global().__locale_) 468227825Stheraven{ 469227825Stheraven __locale_->__add_shared(); 470227825Stheraven} 471227825Stheraven 472227825Stheravenlocale::locale(const locale& l) _NOEXCEPT 473227825Stheraven : __locale_(l.__locale_) 474227825Stheraven{ 475227825Stheraven __locale_->__add_shared(); 476227825Stheraven} 477227825Stheraven 478227825Stheravenlocale::~locale() 479227825Stheraven{ 480227825Stheraven __locale_->__release_shared(); 481227825Stheraven} 482227825Stheraven 483227825Stheravenconst locale& 484227825Stheravenlocale::operator=(const locale& other) _NOEXCEPT 485227825Stheraven{ 486227825Stheraven other.__locale_->__add_shared(); 487227825Stheraven __locale_->__release_shared(); 488227825Stheraven __locale_ = other.__locale_; 489227825Stheraven return *this; 490227825Stheraven} 491227825Stheraven 492227825Stheravenlocale::locale(const char* name) 493227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 494227825Stheraven : __locale_(name ? new __imp(name) 495227825Stheraven : throw runtime_error("locale constructed with null")) 496227825Stheraven#else // _LIBCPP_NO_EXCEPTIONS 497227825Stheraven : __locale_(new __imp(name)) 498227825Stheraven#endif 499227825Stheraven{ 500227825Stheraven __locale_->__add_shared(); 501227825Stheraven} 502227825Stheraven 503227825Stheravenlocale::locale(const string& name) 504227825Stheraven : __locale_(new __imp(name)) 505227825Stheraven{ 506227825Stheraven __locale_->__add_shared(); 507227825Stheraven} 508227825Stheraven 509227825Stheravenlocale::locale(const locale& other, const char* name, category c) 510227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 511227825Stheraven : __locale_(name ? new __imp(*other.__locale_, name, c) 512227825Stheraven : throw runtime_error("locale constructed with null")) 513227825Stheraven#else // _LIBCPP_NO_EXCEPTIONS 514227825Stheraven : __locale_(new __imp(*other.__locale_, name, c)) 515227825Stheraven#endif 516227825Stheraven{ 517227825Stheraven __locale_->__add_shared(); 518227825Stheraven} 519227825Stheraven 520227825Stheravenlocale::locale(const locale& other, const string& name, category c) 521227825Stheraven : __locale_(new __imp(*other.__locale_, name, c)) 522227825Stheraven{ 523227825Stheraven __locale_->__add_shared(); 524227825Stheraven} 525227825Stheraven 526227825Stheravenlocale::locale(const locale& other, const locale& one, category c) 527227825Stheraven : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) 528227825Stheraven{ 529227825Stheraven __locale_->__add_shared(); 530227825Stheraven} 531227825Stheraven 532227825Stheravenstring 533227825Stheravenlocale::name() const 534227825Stheraven{ 535227825Stheraven return __locale_->name(); 536227825Stheraven} 537227825Stheraven 538227825Stheravenvoid 539227825Stheravenlocale::__install_ctor(const locale& other, facet* f, long id) 540227825Stheraven{ 541227825Stheraven if (f) 542227825Stheraven __locale_ = new __imp(*other.__locale_, f, id); 543227825Stheraven else 544227825Stheraven __locale_ = other.__locale_; 545227825Stheraven __locale_->__add_shared(); 546227825Stheraven} 547227825Stheraven 548227825Stheravenlocale 549227825Stheravenlocale::global(const locale& loc) 550227825Stheraven{ 551227825Stheraven locale& g = __global(); 552227825Stheraven locale r = g; 553227825Stheraven g = loc; 554227825Stheraven if (g.name() != "*") 555227825Stheraven setlocale(LC_ALL, g.name().c_str()); 556227825Stheraven return r; 557227825Stheraven} 558227825Stheraven 559227825Stheravenbool 560227825Stheravenlocale::has_facet(id& x) const 561227825Stheraven{ 562227825Stheraven return __locale_->has_facet(x.__get()); 563227825Stheraven} 564227825Stheraven 565227825Stheravenconst locale::facet* 566227825Stheravenlocale::use_facet(id& x) const 567227825Stheraven{ 568227825Stheraven return __locale_->use_facet(x.__get()); 569227825Stheraven} 570227825Stheraven 571227825Stheravenbool 572227825Stheravenlocale::operator==(const locale& y) const 573227825Stheraven{ 574227825Stheraven return (__locale_ == y.__locale_) 575227825Stheraven || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name()); 576227825Stheraven} 577227825Stheraven 578227825Stheraven// locale::facet 579227825Stheraven 580227825Stheravenlocale::facet::~facet() 581227825Stheraven{ 582227825Stheraven} 583227825Stheraven 584227825Stheravenvoid 585227825Stheravenlocale::facet::__on_zero_shared() _NOEXCEPT 586227825Stheraven{ 587227825Stheraven delete this; 588227825Stheraven} 589227825Stheraven 590227825Stheraven// locale::id 591227825Stheraven 592227825Stheravenint32_t locale::id::__next_id = 0; 593227825Stheraven 594227825Stheravennamespace 595227825Stheraven{ 596227825Stheraven 597227825Stheravenclass __fake_bind 598227825Stheraven{ 599227825Stheraven locale::id* id_; 600227825Stheraven void (locale::id::* pmf_)(); 601227825Stheravenpublic: 602227825Stheraven __fake_bind(void (locale::id::* pmf)(), locale::id* id) 603227825Stheraven : id_(id), pmf_(pmf) {} 604227825Stheraven 605227825Stheraven void operator()() const 606227825Stheraven { 607227825Stheraven (id_->*pmf_)(); 608227825Stheraven } 609227825Stheraven}; 610227825Stheraven 611227825Stheraven} 612227825Stheraven 613227825Stheravenlong 614227825Stheravenlocale::id::__get() 615227825Stheraven{ 616227825Stheraven call_once(__flag_, __fake_bind(&locale::id::__init, this)); 617227825Stheraven return __id_ - 1; 618227825Stheraven} 619227825Stheraven 620227825Stheravenvoid 621227825Stheravenlocale::id::__init() 622227825Stheraven{ 623227825Stheraven __id_ = __sync_add_and_fetch(&__next_id, 1); 624227825Stheraven} 625227825Stheraven 626227825Stheraven// template <> class collate_byname<char> 627227825Stheraven 628227825Stheravencollate_byname<char>::collate_byname(const char* n, size_t refs) 629227825Stheraven : collate<char>(refs), 630227825Stheraven __l(newlocale(LC_ALL_MASK, n, 0)) 631227825Stheraven{ 632227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 633227825Stheraven if (__l == 0) 634227825Stheraven throw runtime_error("collate_byname<char>::collate_byname" 635227825Stheraven " failed to construct for " + string(n)); 636227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 637227825Stheraven} 638227825Stheraven 639227825Stheravencollate_byname<char>::collate_byname(const string& name, size_t refs) 640227825Stheraven : collate<char>(refs), 641227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 642227825Stheraven{ 643227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 644227825Stheraven if (__l == 0) 645227825Stheraven throw runtime_error("collate_byname<char>::collate_byname" 646227825Stheraven " failed to construct for " + name); 647227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 648227825Stheraven} 649227825Stheraven 650227825Stheravencollate_byname<char>::~collate_byname() 651227825Stheraven{ 652227825Stheraven freelocale(__l); 653227825Stheraven} 654227825Stheraven 655227825Stheravenint 656227825Stheravencollate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1, 657227825Stheraven const char_type* __lo2, const char_type* __hi2) const 658227825Stheraven{ 659227825Stheraven string_type lhs(__lo1, __hi1); 660227825Stheraven string_type rhs(__lo2, __hi2); 661227825Stheraven int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); 662227825Stheraven if (r < 0) 663227825Stheraven return -1; 664227825Stheraven if (r > 0) 665227825Stheraven return 1; 666227825Stheraven return r; 667227825Stheraven} 668227825Stheraven 669227825Stheravencollate_byname<char>::string_type 670227825Stheravencollate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const 671227825Stheraven{ 672227825Stheraven const string_type in(lo, hi); 673227825Stheraven string_type out(strxfrm_l(0, in.c_str(), 0, __l), char()); 674227825Stheraven strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l); 675227825Stheraven return out; 676227825Stheraven} 677227825Stheraven 678227825Stheraven// template <> class collate_byname<wchar_t> 679227825Stheraven 680227825Stheravencollate_byname<wchar_t>::collate_byname(const char* n, size_t refs) 681227825Stheraven : collate<wchar_t>(refs), 682227825Stheraven __l(newlocale(LC_ALL_MASK, n, 0)) 683227825Stheraven{ 684227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 685227825Stheraven if (__l == 0) 686227825Stheraven throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" 687227825Stheraven " failed to construct for " + string(n)); 688227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 689227825Stheraven} 690227825Stheraven 691227825Stheravencollate_byname<wchar_t>::collate_byname(const string& name, size_t refs) 692227825Stheraven : collate<wchar_t>(refs), 693227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 694227825Stheraven{ 695227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 696227825Stheraven if (__l == 0) 697227825Stheraven throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" 698227825Stheraven " failed to construct for " + name); 699227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 700227825Stheraven} 701227825Stheraven 702227825Stheravencollate_byname<wchar_t>::~collate_byname() 703227825Stheraven{ 704227825Stheraven freelocale(__l); 705227825Stheraven} 706227825Stheraven 707227825Stheravenint 708227825Stheravencollate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1, 709227825Stheraven const char_type* __lo2, const char_type* __hi2) const 710227825Stheraven{ 711227825Stheraven string_type lhs(__lo1, __hi1); 712227825Stheraven string_type rhs(__lo2, __hi2); 713227825Stheraven int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); 714227825Stheraven if (r < 0) 715227825Stheraven return -1; 716227825Stheraven if (r > 0) 717227825Stheraven return 1; 718227825Stheraven return r; 719227825Stheraven} 720227825Stheraven 721227825Stheravencollate_byname<wchar_t>::string_type 722227825Stheravencollate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const 723227825Stheraven{ 724227825Stheraven const string_type in(lo, hi); 725227825Stheraven string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); 726227825Stheraven wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l); 727227825Stheraven return out; 728227825Stheraven} 729227825Stheraven 730227825Stheraven// template <> class ctype<wchar_t>; 731227825Stheraven 732246487Stheravenconst ctype_base::mask ctype_base::space; 733246487Stheravenconst ctype_base::mask ctype_base::print; 734246487Stheravenconst ctype_base::mask ctype_base::cntrl; 735246487Stheravenconst ctype_base::mask ctype_base::upper; 736246487Stheravenconst ctype_base::mask ctype_base::lower; 737246487Stheravenconst ctype_base::mask ctype_base::alpha; 738246487Stheravenconst ctype_base::mask ctype_base::digit; 739246487Stheravenconst ctype_base::mask ctype_base::punct; 740246487Stheravenconst ctype_base::mask ctype_base::xdigit; 741246487Stheravenconst ctype_base::mask ctype_base::blank; 742246487Stheravenconst ctype_base::mask ctype_base::alnum; 743246487Stheravenconst ctype_base::mask ctype_base::graph; 744246487Stheraven 745227825Stheravenlocale::id ctype<wchar_t>::id; 746227825Stheraven 747227825Stheravenctype<wchar_t>::~ctype() 748227825Stheraven{ 749227825Stheraven} 750227825Stheraven 751227825Stheravenbool 752227825Stheravenctype<wchar_t>::do_is(mask m, char_type c) const 753227825Stheraven{ 754227825Stheraven return isascii(c) ? ctype<char>::classic_table()[c] & m : false; 755227825Stheraven} 756227825Stheraven 757227825Stheravenconst wchar_t* 758227825Stheravenctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const 759227825Stheraven{ 760227825Stheraven for (; low != high; ++low, ++vec) 761227825Stheraven *vec = static_cast<mask>(isascii(*low) ? 762227825Stheraven ctype<char>::classic_table()[*low] : 0); 763227825Stheraven return low; 764227825Stheraven} 765227825Stheraven 766227825Stheravenconst wchar_t* 767227825Stheravenctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const 768227825Stheraven{ 769227825Stheraven for (; low != high; ++low) 770227825Stheraven if (isascii(*low) && (ctype<char>::classic_table()[*low] & m)) 771227825Stheraven break; 772227825Stheraven return low; 773227825Stheraven} 774227825Stheraven 775227825Stheravenconst wchar_t* 776227825Stheravenctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const 777227825Stheraven{ 778227825Stheraven for (; low != high; ++low) 779227825Stheraven if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m))) 780227825Stheraven break; 781227825Stheraven return low; 782227825Stheraven} 783227825Stheraven 784227825Stheravenwchar_t 785227825Stheravenctype<wchar_t>::do_toupper(char_type c) const 786227825Stheraven{ 787227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 788227825Stheraven return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; 789249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 790227825Stheraven return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c; 791227825Stheraven#else 792227825Stheraven return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c; 793227825Stheraven#endif 794227825Stheraven} 795227825Stheraven 796227825Stheravenconst wchar_t* 797227825Stheravenctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const 798227825Stheraven{ 799227825Stheraven for (; low != high; ++low) 800227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 801227825Stheraven *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; 802249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 803227825Stheraven *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] 804227825Stheraven : *low; 805227825Stheraven#else 806227825Stheraven *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low; 807227825Stheraven#endif 808227825Stheraven return low; 809227825Stheraven} 810227825Stheraven 811227825Stheravenwchar_t 812227825Stheravenctype<wchar_t>::do_tolower(char_type c) const 813227825Stheraven{ 814227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 815227825Stheraven return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; 816249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 817227825Stheraven return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c; 818227825Stheraven#else 819227825Stheraven return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c; 820227825Stheraven#endif 821227825Stheraven} 822227825Stheraven 823227825Stheravenconst wchar_t* 824227825Stheravenctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const 825227825Stheraven{ 826227825Stheraven for (; low != high; ++low) 827227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 828227825Stheraven *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; 829249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 830227825Stheraven *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] 831227825Stheraven : *low; 832227825Stheraven#else 833227825Stheraven *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low; 834227825Stheraven#endif 835227825Stheraven return low; 836227825Stheraven} 837227825Stheraven 838227825Stheravenwchar_t 839227825Stheravenctype<wchar_t>::do_widen(char c) const 840227825Stheraven{ 841227825Stheraven return c; 842227825Stheraven} 843227825Stheraven 844227825Stheravenconst char* 845227825Stheravenctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const 846227825Stheraven{ 847227825Stheraven for (; low != high; ++low, ++dest) 848227825Stheraven *dest = *low; 849227825Stheraven return low; 850227825Stheraven} 851227825Stheraven 852227825Stheravenchar 853227825Stheravenctype<wchar_t>::do_narrow(char_type c, char dfault) const 854227825Stheraven{ 855227825Stheraven if (isascii(c)) 856227825Stheraven return static_cast<char>(c); 857227825Stheraven return dfault; 858227825Stheraven} 859227825Stheraven 860227825Stheravenconst wchar_t* 861227825Stheravenctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 862227825Stheraven{ 863227825Stheraven for (; low != high; ++low, ++dest) 864227825Stheraven if (isascii(*low)) 865232950Stheraven *dest = static_cast<char>(*low); 866227825Stheraven else 867227825Stheraven *dest = dfault; 868227825Stheraven return low; 869227825Stheraven} 870227825Stheraven 871227825Stheraven// template <> class ctype<char>; 872227825Stheraven 873227825Stheravenlocale::id ctype<char>::id; 874227825Stheraven 875227825Stheravenctype<char>::ctype(const mask* tab, bool del, size_t refs) 876227825Stheraven : locale::facet(refs), 877227825Stheraven __tab_(tab), 878227825Stheraven __del_(del) 879227825Stheraven{ 880227825Stheraven if (__tab_ == 0) 881227825Stheraven __tab_ = classic_table(); 882227825Stheraven} 883227825Stheraven 884227825Stheravenctype<char>::~ctype() 885227825Stheraven{ 886227825Stheraven if (__tab_ && __del_) 887227825Stheraven delete [] __tab_; 888227825Stheraven} 889227825Stheraven 890227825Stheravenchar 891227825Stheravenctype<char>::do_toupper(char_type c) const 892227825Stheraven{ 893227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 894232950Stheraven return isascii(c) ? 895232950Stheraven static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c; 896249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 897249998Sdim return isascii(c) ? 898249998Sdim static_cast<char>(__classic_upper_table()[static_cast<size_t>(c)]) : c; 899227825Stheraven#else 900227825Stheraven return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c; 901227825Stheraven#endif 902227825Stheraven} 903227825Stheraven 904227825Stheravenconst char* 905227825Stheravenctype<char>::do_toupper(char_type* low, const char_type* high) const 906227825Stheraven{ 907227825Stheraven for (; low != high; ++low) 908227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 909232950Stheraven *low = isascii(*low) ? 910232950Stheraven static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low; 911249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 912249998Sdim *low = isascii(*low) ? 913249998Sdim static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low; 914227825Stheraven#else 915227825Stheraven *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low; 916227825Stheraven#endif 917227825Stheraven return low; 918227825Stheraven} 919227825Stheraven 920227825Stheravenchar 921227825Stheravenctype<char>::do_tolower(char_type c) const 922227825Stheraven{ 923227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 924232950Stheraven return isascii(c) ? 925232950Stheraven static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c; 926249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 927249998Sdim return isascii(c) ? 928249998Sdim static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c; 929227825Stheraven#else 930227825Stheraven return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c; 931227825Stheraven#endif 932227825Stheraven} 933227825Stheraven 934227825Stheravenconst char* 935227825Stheravenctype<char>::do_tolower(char_type* low, const char_type* high) const 936227825Stheraven{ 937227825Stheraven for (; low != high; ++low) 938227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 939232950Stheraven *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low; 940249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 941249998Sdim *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low; 942227825Stheraven#else 943227825Stheraven *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; 944227825Stheraven#endif 945227825Stheraven return low; 946227825Stheraven} 947227825Stheraven 948227825Stheravenchar 949227825Stheravenctype<char>::do_widen(char c) const 950227825Stheraven{ 951227825Stheraven return c; 952227825Stheraven} 953227825Stheraven 954227825Stheravenconst char* 955227825Stheravenctype<char>::do_widen(const char* low, const char* high, char_type* dest) const 956227825Stheraven{ 957227825Stheraven for (; low != high; ++low, ++dest) 958227825Stheraven *dest = *low; 959227825Stheraven return low; 960227825Stheraven} 961227825Stheraven 962227825Stheravenchar 963227825Stheravenctype<char>::do_narrow(char_type c, char dfault) const 964227825Stheraven{ 965227825Stheraven if (isascii(c)) 966227825Stheraven return static_cast<char>(c); 967227825Stheraven return dfault; 968227825Stheraven} 969227825Stheraven 970227825Stheravenconst char* 971227825Stheravenctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 972227825Stheraven{ 973227825Stheraven for (; low != high; ++low, ++dest) 974227825Stheraven if (isascii(*low)) 975227825Stheraven *dest = *low; 976227825Stheraven else 977227825Stheraven *dest = dfault; 978227825Stheraven return low; 979227825Stheraven} 980227825Stheraven 981249998Sdim#ifdef EMSCRIPTEN 982249998Sdimextern "C" const unsigned short ** __ctype_b_loc(); 983249998Sdimextern "C" const int ** __ctype_tolower_loc(); 984249998Sdimextern "C" const int ** __ctype_toupper_loc(); 985249998Sdim#endif 986249998Sdim 987227825Stheravenconst ctype<char>::mask* 988227825Stheravenctype<char>::classic_table() _NOEXCEPT 989227825Stheraven{ 990227825Stheraven#if defined(__APPLE__) || defined(__FreeBSD__) 991227825Stheraven return _DefaultRuneLocale.__runetype; 992227825Stheraven#elif defined(__GLIBC__) 993227825Stheraven return __cloc()->__ctype_b; 994232950Stheraven#elif __sun__ 995232950Stheraven return __ctype_mask; 996249998Sdim#elif defined(_WIN32) 997227825Stheraven return _ctype+1; // internal ctype mask table defined in msvcrt.dll 998227825Stheraven// This is assumed to be safe, which is a nonsense assumption because we're 999227825Stheraven// going to end up dereferencing it later... 1000249998Sdim#elif defined(EMSCRIPTEN) 1001249998Sdim return *__ctype_b_loc(); 1002227825Stheraven#else 1003232950Stheraven // Platform not supported: abort so the person doing the port knows what to 1004232950Stheraven // fix 1005232950Stheraven# warning ctype<char>::classic_table() is not implemented 1006232950Stheraven abort(); 1007227825Stheraven return NULL; 1008227825Stheraven#endif 1009227825Stheraven} 1010227825Stheraven 1011227825Stheraven#if defined(__GLIBC__) 1012227825Stheravenconst int* 1013227825Stheravenctype<char>::__classic_lower_table() _NOEXCEPT 1014227825Stheraven{ 1015227825Stheraven return __cloc()->__ctype_tolower; 1016227825Stheraven} 1017227825Stheraven 1018227825Stheravenconst int* 1019227825Stheravenctype<char>::__classic_upper_table() _NOEXCEPT 1020227825Stheraven{ 1021227825Stheraven return __cloc()->__ctype_toupper; 1022227825Stheraven} 1023227825Stheraven#endif // __GLIBC__ 1024227825Stheraven 1025249998Sdim#if defined(EMSCRIPTEN) 1026249998Sdimconst int* 1027249998Sdimctype<char>::__classic_lower_table() _NOEXCEPT 1028249998Sdim{ 1029249998Sdim return *__ctype_tolower_loc(); 1030249998Sdim} 1031249998Sdim 1032249998Sdimconst int* 1033249998Sdimctype<char>::__classic_upper_table() _NOEXCEPT 1034249998Sdim{ 1035249998Sdim return *__ctype_toupper_loc(); 1036249998Sdim} 1037249998Sdim#endif // EMSCRIPTEN 1038249998Sdim 1039227825Stheraven// template <> class ctype_byname<char> 1040227825Stheraven 1041227825Stheravenctype_byname<char>::ctype_byname(const char* name, size_t refs) 1042227825Stheraven : ctype<char>(0, false, refs), 1043227825Stheraven __l(newlocale(LC_ALL_MASK, name, 0)) 1044227825Stheraven{ 1045227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1046227825Stheraven if (__l == 0) 1047227825Stheraven throw runtime_error("ctype_byname<char>::ctype_byname" 1048227825Stheraven " failed to construct for " + string(name)); 1049227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1050227825Stheraven} 1051227825Stheraven 1052227825Stheravenctype_byname<char>::ctype_byname(const string& name, size_t refs) 1053227825Stheraven : ctype<char>(0, false, refs), 1054227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 1055227825Stheraven{ 1056227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1057227825Stheraven if (__l == 0) 1058227825Stheraven throw runtime_error("ctype_byname<char>::ctype_byname" 1059227825Stheraven " failed to construct for " + name); 1060227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1061227825Stheraven} 1062227825Stheraven 1063227825Stheravenctype_byname<char>::~ctype_byname() 1064227825Stheraven{ 1065227825Stheraven freelocale(__l); 1066227825Stheraven} 1067227825Stheraven 1068227825Stheravenchar 1069227825Stheravenctype_byname<char>::do_toupper(char_type c) const 1070227825Stheraven{ 1071232950Stheraven return static_cast<char>(toupper_l(c, __l)); 1072227825Stheraven} 1073227825Stheraven 1074227825Stheravenconst char* 1075227825Stheravenctype_byname<char>::do_toupper(char_type* low, const char_type* high) const 1076227825Stheraven{ 1077227825Stheraven for (; low != high; ++low) 1078232950Stheraven *low = static_cast<char>(toupper_l(*low, __l)); 1079227825Stheraven return low; 1080227825Stheraven} 1081227825Stheraven 1082227825Stheravenchar 1083227825Stheravenctype_byname<char>::do_tolower(char_type c) const 1084227825Stheraven{ 1085232950Stheraven return static_cast<char>(tolower_l(c, __l)); 1086227825Stheraven} 1087227825Stheraven 1088227825Stheravenconst char* 1089227825Stheravenctype_byname<char>::do_tolower(char_type* low, const char_type* high) const 1090227825Stheraven{ 1091227825Stheraven for (; low != high; ++low) 1092232950Stheraven *low = static_cast<char>(tolower_l(*low, __l)); 1093227825Stheraven return low; 1094227825Stheraven} 1095227825Stheraven 1096227825Stheraven// template <> class ctype_byname<wchar_t> 1097227825Stheraven 1098227825Stheravenctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs) 1099227825Stheraven : ctype<wchar_t>(refs), 1100227825Stheraven __l(newlocale(LC_ALL_MASK, name, 0)) 1101227825Stheraven{ 1102227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1103227825Stheraven if (__l == 0) 1104227825Stheraven throw runtime_error("ctype_byname<wchar_t>::ctype_byname" 1105227825Stheraven " failed to construct for " + string(name)); 1106227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1107227825Stheraven} 1108227825Stheraven 1109227825Stheravenctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs) 1110227825Stheraven : ctype<wchar_t>(refs), 1111227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 1112227825Stheraven{ 1113227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1114227825Stheraven if (__l == 0) 1115227825Stheraven throw runtime_error("ctype_byname<wchar_t>::ctype_byname" 1116227825Stheraven " failed to construct for " + name); 1117227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1118227825Stheraven} 1119227825Stheraven 1120227825Stheravenctype_byname<wchar_t>::~ctype_byname() 1121227825Stheraven{ 1122227825Stheraven freelocale(__l); 1123227825Stheraven} 1124227825Stheraven 1125227825Stheravenbool 1126227825Stheravenctype_byname<wchar_t>::do_is(mask m, char_type c) const 1127227825Stheraven{ 1128227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1129227825Stheraven return static_cast<bool>(iswctype_l(c, m, __l)); 1130227825Stheraven#else 1131241903Sdim bool result = false; 1132249998Sdim wint_t ch = static_cast<wint_t>(c); 1133249998Sdim if (m & space) result |= (iswspace_l(ch, __l) != 0); 1134249998Sdim if (m & print) result |= (iswprint_l(ch, __l) != 0); 1135249998Sdim if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0); 1136249998Sdim if (m & upper) result |= (iswupper_l(ch, __l) != 0); 1137249998Sdim if (m & lower) result |= (iswlower_l(ch, __l) != 0); 1138249998Sdim if (m & alpha) result |= (iswalpha_l(ch, __l) != 0); 1139249998Sdim if (m & digit) result |= (iswdigit_l(ch, __l) != 0); 1140249998Sdim if (m & punct) result |= (iswpunct_l(ch, __l) != 0); 1141249998Sdim if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0); 1142249998Sdim if (m & blank) result |= (iswblank_l(ch, __l) != 0); 1143227825Stheraven return result; 1144227825Stheraven#endif 1145227825Stheraven} 1146227825Stheraven 1147227825Stheravenconst wchar_t* 1148227825Stheravenctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const 1149227825Stheraven{ 1150227825Stheraven for (; low != high; ++low, ++vec) 1151227825Stheraven { 1152227825Stheraven if (isascii(*low)) 1153227825Stheraven *vec = static_cast<mask>(ctype<char>::classic_table()[*low]); 1154227825Stheraven else 1155227825Stheraven { 1156227825Stheraven *vec = 0; 1157249998Sdim wint_t ch = static_cast<wint_t>(*low); 1158249998Sdim if (iswspace_l(ch, __l)) 1159227825Stheraven *vec |= space; 1160249998Sdim if (iswprint_l(ch, __l)) 1161227825Stheraven *vec |= print; 1162249998Sdim if (iswcntrl_l(ch, __l)) 1163227825Stheraven *vec |= cntrl; 1164249998Sdim if (iswupper_l(ch, __l)) 1165227825Stheraven *vec |= upper; 1166249998Sdim if (iswlower_l(ch, __l)) 1167227825Stheraven *vec |= lower; 1168249998Sdim if (iswalpha_l(ch, __l)) 1169227825Stheraven *vec |= alpha; 1170249998Sdim if (iswdigit_l(ch, __l)) 1171227825Stheraven *vec |= digit; 1172249998Sdim if (iswpunct_l(ch, __l)) 1173227825Stheraven *vec |= punct; 1174249998Sdim if (iswxdigit_l(ch, __l)) 1175227825Stheraven *vec |= xdigit; 1176227825Stheraven } 1177227825Stheraven } 1178227825Stheraven return low; 1179227825Stheraven} 1180227825Stheraven 1181227825Stheravenconst wchar_t* 1182227825Stheravenctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const 1183227825Stheraven{ 1184227825Stheraven for (; low != high; ++low) 1185227825Stheraven { 1186227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1187227825Stheraven if (iswctype_l(*low, m, __l)) 1188227825Stheraven break; 1189227825Stheraven#else 1190249998Sdim wint_t ch = static_cast<wint_t>(*low); 1191249998Sdim if (m & space && iswspace_l(ch, __l)) break; 1192249998Sdim if (m & print && iswprint_l(ch, __l)) break; 1193249998Sdim if (m & cntrl && iswcntrl_l(ch, __l)) break; 1194249998Sdim if (m & upper && iswupper_l(ch, __l)) break; 1195249998Sdim if (m & lower && iswlower_l(ch, __l)) break; 1196249998Sdim if (m & alpha && iswalpha_l(ch, __l)) break; 1197249998Sdim if (m & digit && iswdigit_l(ch, __l)) break; 1198249998Sdim if (m & punct && iswpunct_l(ch, __l)) break; 1199249998Sdim if (m & xdigit && iswxdigit_l(ch, __l)) break; 1200249998Sdim if (m & blank && iswblank_l(ch, __l)) break; 1201227825Stheraven#endif 1202227825Stheraven } 1203227825Stheraven return low; 1204227825Stheraven} 1205227825Stheraven 1206227825Stheravenconst wchar_t* 1207227825Stheravenctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const 1208227825Stheraven{ 1209227825Stheraven for (; low != high; ++low) 1210227825Stheraven { 1211227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1212227825Stheraven if (!iswctype_l(*low, m, __l)) 1213227825Stheraven break; 1214227825Stheraven#else 1215249998Sdim wint_t ch = static_cast<wint_t>(*low); 1216249998Sdim if (m & space && iswspace_l(ch, __l)) continue; 1217249998Sdim if (m & print && iswprint_l(ch, __l)) continue; 1218249998Sdim if (m & cntrl && iswcntrl_l(ch, __l)) continue; 1219249998Sdim if (m & upper && iswupper_l(ch, __l)) continue; 1220249998Sdim if (m & lower && iswlower_l(ch, __l)) continue; 1221249998Sdim if (m & alpha && iswalpha_l(ch, __l)) continue; 1222249998Sdim if (m & digit && iswdigit_l(ch, __l)) continue; 1223249998Sdim if (m & punct && iswpunct_l(ch, __l)) continue; 1224249998Sdim if (m & xdigit && iswxdigit_l(ch, __l)) continue; 1225249998Sdim if (m & blank && iswblank_l(ch, __l)) continue; 1226227825Stheraven break; 1227227825Stheraven#endif 1228227825Stheraven } 1229227825Stheraven return low; 1230227825Stheraven} 1231227825Stheraven 1232227825Stheravenwchar_t 1233227825Stheravenctype_byname<wchar_t>::do_toupper(char_type c) const 1234227825Stheraven{ 1235227825Stheraven return towupper_l(c, __l); 1236227825Stheraven} 1237227825Stheraven 1238227825Stheravenconst wchar_t* 1239227825Stheravenctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const 1240227825Stheraven{ 1241227825Stheraven for (; low != high; ++low) 1242227825Stheraven *low = towupper_l(*low, __l); 1243227825Stheraven return low; 1244227825Stheraven} 1245227825Stheraven 1246227825Stheravenwchar_t 1247227825Stheravenctype_byname<wchar_t>::do_tolower(char_type c) const 1248227825Stheraven{ 1249227825Stheraven return towlower_l(c, __l); 1250227825Stheraven} 1251227825Stheraven 1252227825Stheravenconst wchar_t* 1253227825Stheravenctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const 1254227825Stheraven{ 1255227825Stheraven for (; low != high; ++low) 1256227825Stheraven *low = towlower_l(*low, __l); 1257227825Stheraven return low; 1258227825Stheraven} 1259227825Stheraven 1260227825Stheravenwchar_t 1261227825Stheravenctype_byname<wchar_t>::do_widen(char c) const 1262227825Stheraven{ 1263227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1264227825Stheraven return btowc_l(c, __l); 1265227825Stheraven#else 1266227825Stheraven return __btowc_l(c, __l); 1267227825Stheraven#endif 1268227825Stheraven} 1269227825Stheraven 1270227825Stheravenconst char* 1271227825Stheravenctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const 1272227825Stheraven{ 1273227825Stheraven for (; low != high; ++low, ++dest) 1274227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1275227825Stheraven *dest = btowc_l(*low, __l); 1276227825Stheraven#else 1277227825Stheraven *dest = __btowc_l(*low, __l); 1278227825Stheraven#endif 1279227825Stheraven return low; 1280227825Stheraven} 1281227825Stheraven 1282227825Stheravenchar 1283227825Stheravenctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const 1284227825Stheraven{ 1285227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1286227825Stheraven int r = wctob_l(c, __l); 1287227825Stheraven#else 1288227825Stheraven int r = __wctob_l(c, __l); 1289227825Stheraven#endif 1290246487Stheraven return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; 1291227825Stheraven} 1292227825Stheraven 1293227825Stheravenconst wchar_t* 1294227825Stheravenctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 1295227825Stheraven{ 1296227825Stheraven for (; low != high; ++low, ++dest) 1297227825Stheraven { 1298227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1299227825Stheraven int r = wctob_l(*low, __l); 1300227825Stheraven#else 1301227825Stheraven int r = __wctob_l(*low, __l); 1302227825Stheraven#endif 1303246487Stheraven *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; 1304227825Stheraven } 1305227825Stheraven return low; 1306227825Stheraven} 1307227825Stheraven 1308227825Stheraven// template <> class codecvt<char, char, mbstate_t> 1309227825Stheraven 1310227825Stheravenlocale::id codecvt<char, char, mbstate_t>::id; 1311227825Stheraven 1312227825Stheravencodecvt<char, char, mbstate_t>::~codecvt() 1313227825Stheraven{ 1314227825Stheraven} 1315227825Stheraven 1316227825Stheravencodecvt<char, char, mbstate_t>::result 1317227825Stheravencodecvt<char, char, mbstate_t>::do_out(state_type&, 1318227825Stheraven const intern_type* frm, const intern_type*, const intern_type*& frm_nxt, 1319227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 1320227825Stheraven{ 1321227825Stheraven frm_nxt = frm; 1322227825Stheraven to_nxt = to; 1323227825Stheraven return noconv; 1324227825Stheraven} 1325227825Stheraven 1326227825Stheravencodecvt<char, char, mbstate_t>::result 1327227825Stheravencodecvt<char, char, mbstate_t>::do_in(state_type&, 1328227825Stheraven const extern_type* frm, const extern_type*, const extern_type*& frm_nxt, 1329227825Stheraven intern_type* to, intern_type*, intern_type*& to_nxt) const 1330227825Stheraven{ 1331227825Stheraven frm_nxt = frm; 1332227825Stheraven to_nxt = to; 1333227825Stheraven return noconv; 1334227825Stheraven} 1335227825Stheraven 1336227825Stheravencodecvt<char, char, mbstate_t>::result 1337227825Stheravencodecvt<char, char, mbstate_t>::do_unshift(state_type&, 1338227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 1339227825Stheraven{ 1340227825Stheraven to_nxt = to; 1341227825Stheraven return noconv; 1342227825Stheraven} 1343227825Stheraven 1344227825Stheravenint 1345227825Stheravencodecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT 1346227825Stheraven{ 1347227825Stheraven return 1; 1348227825Stheraven} 1349227825Stheraven 1350227825Stheravenbool 1351227825Stheravencodecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 1352227825Stheraven{ 1353227825Stheraven return true; 1354227825Stheraven} 1355227825Stheraven 1356227825Stheravenint 1357227825Stheravencodecvt<char, char, mbstate_t>::do_length(state_type&, 1358227825Stheraven const extern_type* frm, const extern_type* end, size_t mx) const 1359227825Stheraven{ 1360232950Stheraven return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm))); 1361227825Stheraven} 1362227825Stheraven 1363227825Stheravenint 1364227825Stheravencodecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT 1365227825Stheraven{ 1366227825Stheraven return 1; 1367227825Stheraven} 1368227825Stheraven 1369227825Stheraven// template <> class codecvt<wchar_t, char, mbstate_t> 1370227825Stheraven 1371227825Stheravenlocale::id codecvt<wchar_t, char, mbstate_t>::id; 1372227825Stheraven 1373227825Stheravencodecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) 1374227825Stheraven : locale::facet(refs), 1375227825Stheraven __l(0) 1376227825Stheraven{ 1377227825Stheraven} 1378227825Stheraven 1379227825Stheravencodecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs) 1380227825Stheraven : locale::facet(refs), 1381227825Stheraven __l(newlocale(LC_ALL_MASK, nm, 0)) 1382227825Stheraven{ 1383227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1384227825Stheraven if (__l == 0) 1385227825Stheraven throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname" 1386227825Stheraven " failed to construct for " + string(nm)); 1387227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1388227825Stheraven} 1389227825Stheraven 1390227825Stheravencodecvt<wchar_t, char, mbstate_t>::~codecvt() 1391227825Stheraven{ 1392227825Stheraven if (__l != 0) 1393227825Stheraven freelocale(__l); 1394227825Stheraven} 1395227825Stheraven 1396227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1397227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, 1398227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 1399227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 1400227825Stheraven{ 1401227825Stheraven // look for first internal null in frm 1402227825Stheraven const intern_type* fend = frm; 1403227825Stheraven for (; fend != frm_end; ++fend) 1404227825Stheraven if (*fend == 0) 1405227825Stheraven break; 1406227825Stheraven // loop over all null-terminated sequences in frm 1407227825Stheraven to_nxt = to; 1408227825Stheraven for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) 1409227825Stheraven { 1410249998Sdim // save state in case it is needed to recover to_nxt on error 1411227825Stheraven mbstate_t save_state = st; 1412227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1413232950Stheraven size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), 1414232950Stheraven static_cast<size_t>(to_end-to), &st, __l); 1415227825Stheraven#else 1416227825Stheraven size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); 1417227825Stheraven#endif 1418227825Stheraven if (n == size_t(-1)) 1419227825Stheraven { 1420227825Stheraven // need to recover to_nxt 1421227825Stheraven for (to_nxt = to; frm != frm_nxt; ++frm) 1422227825Stheraven { 1423227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1424227825Stheraven n = wcrtomb_l(to_nxt, *frm, &save_state, __l); 1425227825Stheraven#else 1426227825Stheraven n = __wcrtomb_l(to_nxt, *frm, &save_state, __l); 1427227825Stheraven#endif 1428227825Stheraven if (n == size_t(-1)) 1429227825Stheraven break; 1430227825Stheraven to_nxt += n; 1431227825Stheraven } 1432227825Stheraven frm_nxt = frm; 1433227825Stheraven return error; 1434227825Stheraven } 1435227825Stheraven if (n == 0) 1436227825Stheraven return partial; 1437227825Stheraven to_nxt += n; 1438227825Stheraven if (to_nxt == to_end) 1439227825Stheraven break; 1440227825Stheraven if (fend != frm_end) // set up next null terminated sequence 1441227825Stheraven { 1442227825Stheraven // Try to write the terminating null 1443227825Stheraven extern_type tmp[MB_LEN_MAX]; 1444227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1445227825Stheraven n = wcrtomb_l(tmp, intern_type(), &st, __l); 1446227825Stheraven#else 1447227825Stheraven n = __wcrtomb_l(tmp, intern_type(), &st, __l); 1448227825Stheraven#endif 1449227825Stheraven if (n == size_t(-1)) // on error 1450227825Stheraven return error; 1451232950Stheraven if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? 1452227825Stheraven return partial; 1453227825Stheraven for (extern_type* p = tmp; n; --n) // write it 1454227825Stheraven *to_nxt++ = *p++; 1455227825Stheraven ++frm_nxt; 1456227825Stheraven // look for next null in frm 1457227825Stheraven for (fend = frm_nxt; fend != frm_end; ++fend) 1458227825Stheraven if (*fend == 0) 1459227825Stheraven break; 1460227825Stheraven } 1461227825Stheraven } 1462227825Stheraven return frm_nxt == frm_end ? ok : partial; 1463227825Stheraven} 1464227825Stheraven 1465227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1466227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, 1467227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 1468227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 1469227825Stheraven{ 1470227825Stheraven // look for first internal null in frm 1471227825Stheraven const extern_type* fend = frm; 1472227825Stheraven for (; fend != frm_end; ++fend) 1473227825Stheraven if (*fend == 0) 1474227825Stheraven break; 1475227825Stheraven // loop over all null-terminated sequences in frm 1476227825Stheraven to_nxt = to; 1477227825Stheraven for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) 1478227825Stheraven { 1479249998Sdim // save state in case it is needed to recover to_nxt on error 1480227825Stheraven mbstate_t save_state = st; 1481227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1482232950Stheraven size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), 1483232950Stheraven static_cast<size_t>(to_end-to), &st, __l); 1484227825Stheraven#else 1485227825Stheraven size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); 1486227825Stheraven#endif 1487227825Stheraven if (n == size_t(-1)) 1488227825Stheraven { 1489227825Stheraven // need to recover to_nxt 1490227825Stheraven for (to_nxt = to; frm != frm_nxt; ++to_nxt) 1491227825Stheraven { 1492227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1493232950Stheraven n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm), 1494232950Stheraven &save_state, __l); 1495227825Stheraven#else 1496227825Stheraven n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l); 1497227825Stheraven#endif 1498227825Stheraven switch (n) 1499227825Stheraven { 1500227825Stheraven case 0: 1501227825Stheraven ++frm; 1502227825Stheraven break; 1503232950Stheraven case size_t(-1): 1504227825Stheraven frm_nxt = frm; 1505227825Stheraven return error; 1506232950Stheraven case size_t(-2): 1507227825Stheraven frm_nxt = frm; 1508227825Stheraven return partial; 1509227825Stheraven default: 1510227825Stheraven frm += n; 1511227825Stheraven break; 1512227825Stheraven } 1513227825Stheraven } 1514227825Stheraven frm_nxt = frm; 1515227825Stheraven return frm_nxt == frm_end ? ok : partial; 1516227825Stheraven } 1517227825Stheraven if (n == 0) 1518227825Stheraven return error; 1519227825Stheraven to_nxt += n; 1520227825Stheraven if (to_nxt == to_end) 1521227825Stheraven break; 1522227825Stheraven if (fend != frm_end) // set up next null terminated sequence 1523227825Stheraven { 1524227825Stheraven // Try to write the terminating null 1525227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1526227825Stheraven n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); 1527227825Stheraven#else 1528227825Stheraven n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); 1529227825Stheraven#endif 1530227825Stheraven if (n != 0) // on error 1531227825Stheraven return error; 1532227825Stheraven ++to_nxt; 1533227825Stheraven ++frm_nxt; 1534227825Stheraven // look for next null in frm 1535227825Stheraven for (fend = frm_nxt; fend != frm_end; ++fend) 1536227825Stheraven if (*fend == 0) 1537227825Stheraven break; 1538227825Stheraven } 1539227825Stheraven } 1540227825Stheraven return frm_nxt == frm_end ? ok : partial; 1541227825Stheraven} 1542227825Stheraven 1543227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1544227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, 1545227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 1546227825Stheraven{ 1547227825Stheraven to_nxt = to; 1548227825Stheraven extern_type tmp[MB_LEN_MAX]; 1549227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1550227825Stheraven size_t n = wcrtomb_l(tmp, intern_type(), &st, __l); 1551227825Stheraven#else 1552227825Stheraven size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l); 1553227825Stheraven#endif 1554227825Stheraven if (n == size_t(-1) || n == 0) // on error 1555227825Stheraven return error; 1556227825Stheraven --n; 1557232950Stheraven if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? 1558227825Stheraven return partial; 1559227825Stheraven for (extern_type* p = tmp; n; --n) // write it 1560227825Stheraven *to_nxt++ = *p++; 1561227825Stheraven return ok; 1562227825Stheraven} 1563227825Stheraven 1564227825Stheravenint 1565227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 1566227825Stheraven{ 1567227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1568227825Stheraven if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0) 1569227825Stheraven#else 1570227825Stheraven if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0) 1571227825Stheraven#endif 1572227825Stheraven { 1573227825Stheraven // stateless encoding 1574227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1575227825Stheraven if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings 1576227825Stheraven#else 1577227825Stheraven if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings 1578227825Stheraven#endif 1579227825Stheraven return 1; // which take more than 1 char to form a wchar_t 1580227825Stheraven return 0; 1581227825Stheraven } 1582227825Stheraven return -1; 1583227825Stheraven} 1584227825Stheraven 1585227825Stheravenbool 1586227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 1587227825Stheraven{ 1588227825Stheraven return false; 1589227825Stheraven} 1590227825Stheraven 1591227825Stheravenint 1592227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, 1593227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 1594227825Stheraven{ 1595227825Stheraven int nbytes = 0; 1596227825Stheraven for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) 1597227825Stheraven { 1598227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1599232950Stheraven size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l); 1600227825Stheraven#else 1601227825Stheraven size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l); 1602227825Stheraven#endif 1603227825Stheraven switch (n) 1604227825Stheraven { 1605227825Stheraven case 0: 1606227825Stheraven ++nbytes; 1607227825Stheraven ++frm; 1608227825Stheraven break; 1609232950Stheraven case size_t(-1): 1610232950Stheraven case size_t(-2): 1611227825Stheraven return nbytes; 1612227825Stheraven default: 1613227825Stheraven nbytes += n; 1614227825Stheraven frm += n; 1615227825Stheraven break; 1616227825Stheraven } 1617227825Stheraven } 1618227825Stheraven return nbytes; 1619227825Stheraven} 1620227825Stheraven 1621227825Stheravenint 1622227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 1623227825Stheraven{ 1624227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1625249998Sdim return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l)); 1626227825Stheraven#else 1627249998Sdim return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l)); 1628227825Stheraven#endif 1629227825Stheraven} 1630227825Stheraven 1631227825Stheraven// Valid UTF ranges 1632227825Stheraven// UTF-32 UTF-16 UTF-8 # of code points 1633227825Stheraven// first second first second third fourth 1634227825Stheraven// 000000 - 00007F 0000 - 007F 00 - 7F 127 1635227825Stheraven// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920 1636227825Stheraven// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048 1637227825Stheraven// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152 1638227825Stheraven// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048 1639227825Stheraven// 00D800 - 00DFFF invalid 1640227825Stheraven// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192 1641227825Stheraven// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608 1642227825Stheraven// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432 1643227825Stheraven// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536 1644227825Stheraven 1645227825Stheravenstatic 1646227825Stheravencodecvt_base::result 1647227825Stheravenutf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 1648227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 1649227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1650227825Stheraven{ 1651227825Stheraven frm_nxt = frm; 1652227825Stheraven to_nxt = to; 1653227825Stheraven if (mode & generate_header) 1654227825Stheraven { 1655227825Stheraven if (to_end-to_nxt < 3) 1656227825Stheraven return codecvt_base::partial; 1657227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 1658227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 1659227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 1660227825Stheraven } 1661227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 1662227825Stheraven { 1663227825Stheraven uint16_t wc1 = *frm_nxt; 1664227825Stheraven if (wc1 > Maxcode) 1665227825Stheraven return codecvt_base::error; 1666227825Stheraven if (wc1 < 0x0080) 1667227825Stheraven { 1668227825Stheraven if (to_end-to_nxt < 1) 1669227825Stheraven return codecvt_base::partial; 1670227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc1); 1671227825Stheraven } 1672227825Stheraven else if (wc1 < 0x0800) 1673227825Stheraven { 1674227825Stheraven if (to_end-to_nxt < 2) 1675227825Stheraven return codecvt_base::partial; 1676227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6)); 1677227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F)); 1678227825Stheraven } 1679227825Stheraven else if (wc1 < 0xD800) 1680227825Stheraven { 1681227825Stheraven if (to_end-to_nxt < 3) 1682227825Stheraven return codecvt_base::partial; 1683227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1684227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1685227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1686227825Stheraven } 1687227825Stheraven else if (wc1 < 0xDC00) 1688227825Stheraven { 1689227825Stheraven if (frm_end-frm_nxt < 2) 1690227825Stheraven return codecvt_base::partial; 1691227825Stheraven uint16_t wc2 = frm_nxt[1]; 1692227825Stheraven if ((wc2 & 0xFC00) != 0xDC00) 1693227825Stheraven return codecvt_base::error; 1694227825Stheraven if (to_end-to_nxt < 4) 1695227825Stheraven return codecvt_base::partial; 1696227825Stheraven if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) + 1697227825Stheraven (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode) 1698227825Stheraven return codecvt_base::error; 1699227825Stheraven ++frm_nxt; 1700227825Stheraven uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; 1701227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2)); 1702227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); 1703227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); 1704227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F)); 1705227825Stheraven } 1706227825Stheraven else if (wc1 < 0xE000) 1707227825Stheraven { 1708227825Stheraven return codecvt_base::error; 1709227825Stheraven } 1710227825Stheraven else 1711227825Stheraven { 1712227825Stheraven if (to_end-to_nxt < 3) 1713227825Stheraven return codecvt_base::partial; 1714227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1715227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1716227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1717227825Stheraven } 1718227825Stheraven } 1719227825Stheraven return codecvt_base::ok; 1720227825Stheraven} 1721227825Stheraven 1722227825Stheravenstatic 1723227825Stheravencodecvt_base::result 1724227825Stheravenutf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 1725227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 1726227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1727227825Stheraven{ 1728227825Stheraven frm_nxt = frm; 1729227825Stheraven to_nxt = to; 1730227825Stheraven if (mode & generate_header) 1731227825Stheraven { 1732227825Stheraven if (to_end-to_nxt < 3) 1733227825Stheraven return codecvt_base::partial; 1734227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 1735227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 1736227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 1737227825Stheraven } 1738227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 1739227825Stheraven { 1740227825Stheraven uint16_t wc1 = static_cast<uint16_t>(*frm_nxt); 1741227825Stheraven if (wc1 > Maxcode) 1742227825Stheraven return codecvt_base::error; 1743227825Stheraven if (wc1 < 0x0080) 1744227825Stheraven { 1745227825Stheraven if (to_end-to_nxt < 1) 1746227825Stheraven return codecvt_base::partial; 1747227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc1); 1748227825Stheraven } 1749227825Stheraven else if (wc1 < 0x0800) 1750227825Stheraven { 1751227825Stheraven if (to_end-to_nxt < 2) 1752227825Stheraven return codecvt_base::partial; 1753227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6)); 1754227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F)); 1755227825Stheraven } 1756227825Stheraven else if (wc1 < 0xD800) 1757227825Stheraven { 1758227825Stheraven if (to_end-to_nxt < 3) 1759227825Stheraven return codecvt_base::partial; 1760227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1761227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1762227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1763227825Stheraven } 1764227825Stheraven else if (wc1 < 0xDC00) 1765227825Stheraven { 1766227825Stheraven if (frm_end-frm_nxt < 2) 1767227825Stheraven return codecvt_base::partial; 1768227825Stheraven uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]); 1769227825Stheraven if ((wc2 & 0xFC00) != 0xDC00) 1770227825Stheraven return codecvt_base::error; 1771227825Stheraven if (to_end-to_nxt < 4) 1772227825Stheraven return codecvt_base::partial; 1773227825Stheraven if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) + 1774227825Stheraven (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode) 1775227825Stheraven return codecvt_base::error; 1776227825Stheraven ++frm_nxt; 1777227825Stheraven uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; 1778227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2)); 1779227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); 1780227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); 1781227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F)); 1782227825Stheraven } 1783227825Stheraven else if (wc1 < 0xE000) 1784227825Stheraven { 1785227825Stheraven return codecvt_base::error; 1786227825Stheraven } 1787227825Stheraven else 1788227825Stheraven { 1789227825Stheraven if (to_end-to_nxt < 3) 1790227825Stheraven return codecvt_base::partial; 1791227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1792227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1793227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1794227825Stheraven } 1795227825Stheraven } 1796227825Stheraven return codecvt_base::ok; 1797227825Stheraven} 1798227825Stheraven 1799227825Stheravenstatic 1800227825Stheravencodecvt_base::result 1801227825Stheravenutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 1802227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 1803227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1804227825Stheraven{ 1805227825Stheraven frm_nxt = frm; 1806227825Stheraven to_nxt = to; 1807227825Stheraven if (mode & consume_header) 1808227825Stheraven { 1809227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 1810227825Stheraven frm_nxt[2] == 0xBF) 1811227825Stheraven frm_nxt += 3; 1812227825Stheraven } 1813227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 1814227825Stheraven { 1815227825Stheraven uint8_t c1 = *frm_nxt; 1816227825Stheraven if (c1 > Maxcode) 1817227825Stheraven return codecvt_base::error; 1818227825Stheraven if (c1 < 0x80) 1819227825Stheraven { 1820227825Stheraven *to_nxt = static_cast<uint16_t>(c1); 1821227825Stheraven ++frm_nxt; 1822227825Stheraven } 1823227825Stheraven else if (c1 < 0xC2) 1824227825Stheraven { 1825227825Stheraven return codecvt_base::error; 1826227825Stheraven } 1827227825Stheraven else if (c1 < 0xE0) 1828227825Stheraven { 1829227825Stheraven if (frm_end-frm_nxt < 2) 1830227825Stheraven return codecvt_base::partial; 1831227825Stheraven uint8_t c2 = frm_nxt[1]; 1832227825Stheraven if ((c2 & 0xC0) != 0x80) 1833227825Stheraven return codecvt_base::error; 1834227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 1835227825Stheraven if (t > Maxcode) 1836227825Stheraven return codecvt_base::error; 1837227825Stheraven *to_nxt = t; 1838227825Stheraven frm_nxt += 2; 1839227825Stheraven } 1840227825Stheraven else if (c1 < 0xF0) 1841227825Stheraven { 1842227825Stheraven if (frm_end-frm_nxt < 3) 1843227825Stheraven return codecvt_base::partial; 1844227825Stheraven uint8_t c2 = frm_nxt[1]; 1845227825Stheraven uint8_t c3 = frm_nxt[2]; 1846227825Stheraven switch (c1) 1847227825Stheraven { 1848227825Stheraven case 0xE0: 1849227825Stheraven if ((c2 & 0xE0) != 0xA0) 1850227825Stheraven return codecvt_base::error; 1851227825Stheraven break; 1852227825Stheraven case 0xED: 1853227825Stheraven if ((c2 & 0xE0) != 0x80) 1854227825Stheraven return codecvt_base::error; 1855227825Stheraven break; 1856227825Stheraven default: 1857227825Stheraven if ((c2 & 0xC0) != 0x80) 1858227825Stheraven return codecvt_base::error; 1859227825Stheraven break; 1860227825Stheraven } 1861227825Stheraven if ((c3 & 0xC0) != 0x80) 1862227825Stheraven return codecvt_base::error; 1863227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 1864227825Stheraven | ((c2 & 0x3F) << 6) 1865227825Stheraven | (c3 & 0x3F)); 1866227825Stheraven if (t > Maxcode) 1867227825Stheraven return codecvt_base::error; 1868227825Stheraven *to_nxt = t; 1869227825Stheraven frm_nxt += 3; 1870227825Stheraven } 1871227825Stheraven else if (c1 < 0xF5) 1872227825Stheraven { 1873227825Stheraven if (frm_end-frm_nxt < 4) 1874227825Stheraven return codecvt_base::partial; 1875227825Stheraven uint8_t c2 = frm_nxt[1]; 1876227825Stheraven uint8_t c3 = frm_nxt[2]; 1877227825Stheraven uint8_t c4 = frm_nxt[3]; 1878227825Stheraven switch (c1) 1879227825Stheraven { 1880227825Stheraven case 0xF0: 1881227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 1882227825Stheraven return codecvt_base::error; 1883227825Stheraven break; 1884227825Stheraven case 0xF4: 1885227825Stheraven if ((c2 & 0xF0) != 0x80) 1886227825Stheraven return codecvt_base::error; 1887227825Stheraven break; 1888227825Stheraven default: 1889227825Stheraven if ((c2 & 0xC0) != 0x80) 1890227825Stheraven return codecvt_base::error; 1891227825Stheraven break; 1892227825Stheraven } 1893227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 1894227825Stheraven return codecvt_base::error; 1895227825Stheraven if (to_end-to_nxt < 2) 1896227825Stheraven return codecvt_base::partial; 1897227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 1898227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 1899227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 1900227825Stheraven return codecvt_base::error; 1901227825Stheraven *to_nxt = static_cast<uint16_t>( 1902227825Stheraven 0xD800 1903227825Stheraven | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) 1904227825Stheraven | ((c2 & 0x0F) << 2) 1905227825Stheraven | ((c3 & 0x30) >> 4)); 1906227825Stheraven *++to_nxt = static_cast<uint16_t>( 1907227825Stheraven 0xDC00 1908227825Stheraven | ((c3 & 0x0F) << 6) 1909227825Stheraven | (c4 & 0x3F)); 1910227825Stheraven frm_nxt += 4; 1911227825Stheraven } 1912227825Stheraven else 1913227825Stheraven { 1914227825Stheraven return codecvt_base::error; 1915227825Stheraven } 1916227825Stheraven } 1917227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 1918227825Stheraven} 1919227825Stheraven 1920227825Stheravenstatic 1921227825Stheravencodecvt_base::result 1922227825Stheravenutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 1923227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 1924227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1925227825Stheraven{ 1926227825Stheraven frm_nxt = frm; 1927227825Stheraven to_nxt = to; 1928227825Stheraven if (mode & consume_header) 1929227825Stheraven { 1930227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 1931227825Stheraven frm_nxt[2] == 0xBF) 1932227825Stheraven frm_nxt += 3; 1933227825Stheraven } 1934227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 1935227825Stheraven { 1936227825Stheraven uint8_t c1 = *frm_nxt; 1937227825Stheraven if (c1 > Maxcode) 1938227825Stheraven return codecvt_base::error; 1939227825Stheraven if (c1 < 0x80) 1940227825Stheraven { 1941227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 1942227825Stheraven ++frm_nxt; 1943227825Stheraven } 1944227825Stheraven else if (c1 < 0xC2) 1945227825Stheraven { 1946227825Stheraven return codecvt_base::error; 1947227825Stheraven } 1948227825Stheraven else if (c1 < 0xE0) 1949227825Stheraven { 1950227825Stheraven if (frm_end-frm_nxt < 2) 1951227825Stheraven return codecvt_base::partial; 1952227825Stheraven uint8_t c2 = frm_nxt[1]; 1953227825Stheraven if ((c2 & 0xC0) != 0x80) 1954227825Stheraven return codecvt_base::error; 1955227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 1956227825Stheraven if (t > Maxcode) 1957227825Stheraven return codecvt_base::error; 1958227825Stheraven *to_nxt = static_cast<uint32_t>(t); 1959227825Stheraven frm_nxt += 2; 1960227825Stheraven } 1961227825Stheraven else if (c1 < 0xF0) 1962227825Stheraven { 1963227825Stheraven if (frm_end-frm_nxt < 3) 1964227825Stheraven return codecvt_base::partial; 1965227825Stheraven uint8_t c2 = frm_nxt[1]; 1966227825Stheraven uint8_t c3 = frm_nxt[2]; 1967227825Stheraven switch (c1) 1968227825Stheraven { 1969227825Stheraven case 0xE0: 1970227825Stheraven if ((c2 & 0xE0) != 0xA0) 1971227825Stheraven return codecvt_base::error; 1972227825Stheraven break; 1973227825Stheraven case 0xED: 1974227825Stheraven if ((c2 & 0xE0) != 0x80) 1975227825Stheraven return codecvt_base::error; 1976227825Stheraven break; 1977227825Stheraven default: 1978227825Stheraven if ((c2 & 0xC0) != 0x80) 1979227825Stheraven return codecvt_base::error; 1980227825Stheraven break; 1981227825Stheraven } 1982227825Stheraven if ((c3 & 0xC0) != 0x80) 1983227825Stheraven return codecvt_base::error; 1984227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 1985227825Stheraven | ((c2 & 0x3F) << 6) 1986227825Stheraven | (c3 & 0x3F)); 1987227825Stheraven if (t > Maxcode) 1988227825Stheraven return codecvt_base::error; 1989227825Stheraven *to_nxt = static_cast<uint32_t>(t); 1990227825Stheraven frm_nxt += 3; 1991227825Stheraven } 1992227825Stheraven else if (c1 < 0xF5) 1993227825Stheraven { 1994227825Stheraven if (frm_end-frm_nxt < 4) 1995227825Stheraven return codecvt_base::partial; 1996227825Stheraven uint8_t c2 = frm_nxt[1]; 1997227825Stheraven uint8_t c3 = frm_nxt[2]; 1998227825Stheraven uint8_t c4 = frm_nxt[3]; 1999227825Stheraven switch (c1) 2000227825Stheraven { 2001227825Stheraven case 0xF0: 2002227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2003227825Stheraven return codecvt_base::error; 2004227825Stheraven break; 2005227825Stheraven case 0xF4: 2006227825Stheraven if ((c2 & 0xF0) != 0x80) 2007227825Stheraven return codecvt_base::error; 2008227825Stheraven break; 2009227825Stheraven default: 2010227825Stheraven if ((c2 & 0xC0) != 0x80) 2011227825Stheraven return codecvt_base::error; 2012227825Stheraven break; 2013227825Stheraven } 2014227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2015227825Stheraven return codecvt_base::error; 2016227825Stheraven if (to_end-to_nxt < 2) 2017227825Stheraven return codecvt_base::partial; 2018227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 2019227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 2020227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 2021227825Stheraven return codecvt_base::error; 2022227825Stheraven *to_nxt = static_cast<uint32_t>( 2023227825Stheraven 0xD800 2024227825Stheraven | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) 2025227825Stheraven | ((c2 & 0x0F) << 2) 2026227825Stheraven | ((c3 & 0x30) >> 4)); 2027227825Stheraven *++to_nxt = static_cast<uint32_t>( 2028227825Stheraven 0xDC00 2029227825Stheraven | ((c3 & 0x0F) << 6) 2030227825Stheraven | (c4 & 0x3F)); 2031227825Stheraven frm_nxt += 4; 2032227825Stheraven } 2033227825Stheraven else 2034227825Stheraven { 2035227825Stheraven return codecvt_base::error; 2036227825Stheraven } 2037227825Stheraven } 2038227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2039227825Stheraven} 2040227825Stheraven 2041227825Stheravenstatic 2042227825Stheravenint 2043227825Stheravenutf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end, 2044227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2045227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2046227825Stheraven{ 2047227825Stheraven const uint8_t* frm_nxt = frm; 2048227825Stheraven if (mode & consume_header) 2049227825Stheraven { 2050227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2051227825Stheraven frm_nxt[2] == 0xBF) 2052227825Stheraven frm_nxt += 3; 2053227825Stheraven } 2054227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) 2055227825Stheraven { 2056227825Stheraven uint8_t c1 = *frm_nxt; 2057227825Stheraven if (c1 > Maxcode) 2058227825Stheraven break; 2059227825Stheraven if (c1 < 0x80) 2060227825Stheraven { 2061227825Stheraven ++frm_nxt; 2062227825Stheraven } 2063227825Stheraven else if (c1 < 0xC2) 2064227825Stheraven { 2065227825Stheraven break; 2066227825Stheraven } 2067227825Stheraven else if (c1 < 0xE0) 2068227825Stheraven { 2069227825Stheraven if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80) 2070227825Stheraven break; 2071227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)); 2072227825Stheraven if (t > Maxcode) 2073227825Stheraven break; 2074227825Stheraven frm_nxt += 2; 2075227825Stheraven } 2076227825Stheraven else if (c1 < 0xF0) 2077227825Stheraven { 2078227825Stheraven if (frm_end-frm_nxt < 3) 2079227825Stheraven break; 2080227825Stheraven uint8_t c2 = frm_nxt[1]; 2081227825Stheraven uint8_t c3 = frm_nxt[2]; 2082227825Stheraven switch (c1) 2083227825Stheraven { 2084227825Stheraven case 0xE0: 2085227825Stheraven if ((c2 & 0xE0) != 0xA0) 2086227825Stheraven return static_cast<int>(frm_nxt - frm); 2087227825Stheraven break; 2088227825Stheraven case 0xED: 2089227825Stheraven if ((c2 & 0xE0) != 0x80) 2090227825Stheraven return static_cast<int>(frm_nxt - frm); 2091227825Stheraven break; 2092227825Stheraven default: 2093227825Stheraven if ((c2 & 0xC0) != 0x80) 2094227825Stheraven return static_cast<int>(frm_nxt - frm); 2095227825Stheraven break; 2096227825Stheraven } 2097227825Stheraven if ((c3 & 0xC0) != 0x80) 2098227825Stheraven break; 2099232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2100227825Stheraven break; 2101227825Stheraven frm_nxt += 3; 2102227825Stheraven } 2103227825Stheraven else if (c1 < 0xF5) 2104227825Stheraven { 2105227825Stheraven if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2) 2106227825Stheraven break; 2107227825Stheraven uint8_t c2 = frm_nxt[1]; 2108227825Stheraven uint8_t c3 = frm_nxt[2]; 2109227825Stheraven uint8_t c4 = frm_nxt[3]; 2110227825Stheraven switch (c1) 2111227825Stheraven { 2112227825Stheraven case 0xF0: 2113227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2114227825Stheraven return static_cast<int>(frm_nxt - frm); 2115227825Stheraven break; 2116227825Stheraven case 0xF4: 2117227825Stheraven if ((c2 & 0xF0) != 0x80) 2118227825Stheraven return static_cast<int>(frm_nxt - frm); 2119227825Stheraven break; 2120227825Stheraven default: 2121227825Stheraven if ((c2 & 0xC0) != 0x80) 2122227825Stheraven return static_cast<int>(frm_nxt - frm); 2123227825Stheraven break; 2124227825Stheraven } 2125227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2126227825Stheraven break; 2127227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 2128227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 2129227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 2130227825Stheraven break; 2131227825Stheraven ++nchar16_t; 2132227825Stheraven frm_nxt += 4; 2133227825Stheraven } 2134227825Stheraven else 2135227825Stheraven { 2136227825Stheraven break; 2137227825Stheraven } 2138227825Stheraven } 2139227825Stheraven return static_cast<int>(frm_nxt - frm); 2140227825Stheraven} 2141227825Stheraven 2142227825Stheravenstatic 2143227825Stheravencodecvt_base::result 2144227825Stheravenucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2145227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2146227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2147227825Stheraven{ 2148227825Stheraven frm_nxt = frm; 2149227825Stheraven to_nxt = to; 2150227825Stheraven if (mode & generate_header) 2151227825Stheraven { 2152227825Stheraven if (to_end-to_nxt < 3) 2153227825Stheraven return codecvt_base::partial; 2154227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 2155227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 2156227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 2157227825Stheraven } 2158227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2159227825Stheraven { 2160227825Stheraven uint32_t wc = *frm_nxt; 2161227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2162227825Stheraven return codecvt_base::error; 2163227825Stheraven if (wc < 0x000080) 2164227825Stheraven { 2165227825Stheraven if (to_end-to_nxt < 1) 2166227825Stheraven return codecvt_base::partial; 2167227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2168227825Stheraven } 2169227825Stheraven else if (wc < 0x000800) 2170227825Stheraven { 2171227825Stheraven if (to_end-to_nxt < 2) 2172227825Stheraven return codecvt_base::partial; 2173227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6)); 2174227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F)); 2175227825Stheraven } 2176227825Stheraven else if (wc < 0x010000) 2177227825Stheraven { 2178227825Stheraven if (to_end-to_nxt < 3) 2179227825Stheraven return codecvt_base::partial; 2180227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12)); 2181227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6)); 2182227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F)); 2183227825Stheraven } 2184227825Stheraven else // if (wc < 0x110000) 2185227825Stheraven { 2186227825Stheraven if (to_end-to_nxt < 4) 2187227825Stheraven return codecvt_base::partial; 2188227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18)); 2189227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12)); 2190227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6)); 2191227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F)); 2192227825Stheraven } 2193227825Stheraven } 2194227825Stheraven return codecvt_base::ok; 2195227825Stheraven} 2196227825Stheraven 2197227825Stheravenstatic 2198227825Stheravencodecvt_base::result 2199227825Stheravenutf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2200227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2201227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2202227825Stheraven{ 2203227825Stheraven frm_nxt = frm; 2204227825Stheraven to_nxt = to; 2205227825Stheraven if (mode & consume_header) 2206227825Stheraven { 2207227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2208227825Stheraven frm_nxt[2] == 0xBF) 2209227825Stheraven frm_nxt += 3; 2210227825Stheraven } 2211227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 2212227825Stheraven { 2213227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2214227825Stheraven if (c1 < 0x80) 2215227825Stheraven { 2216227825Stheraven if (c1 > Maxcode) 2217227825Stheraven return codecvt_base::error; 2218227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2219227825Stheraven ++frm_nxt; 2220227825Stheraven } 2221227825Stheraven else if (c1 < 0xC2) 2222227825Stheraven { 2223227825Stheraven return codecvt_base::error; 2224227825Stheraven } 2225227825Stheraven else if (c1 < 0xE0) 2226227825Stheraven { 2227227825Stheraven if (frm_end-frm_nxt < 2) 2228227825Stheraven return codecvt_base::partial; 2229227825Stheraven uint8_t c2 = frm_nxt[1]; 2230227825Stheraven if ((c2 & 0xC0) != 0x80) 2231227825Stheraven return codecvt_base::error; 2232227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) 2233227825Stheraven | (c2 & 0x3F)); 2234227825Stheraven if (t > Maxcode) 2235227825Stheraven return codecvt_base::error; 2236227825Stheraven *to_nxt = t; 2237227825Stheraven frm_nxt += 2; 2238227825Stheraven } 2239227825Stheraven else if (c1 < 0xF0) 2240227825Stheraven { 2241227825Stheraven if (frm_end-frm_nxt < 3) 2242227825Stheraven return codecvt_base::partial; 2243227825Stheraven uint8_t c2 = frm_nxt[1]; 2244227825Stheraven uint8_t c3 = frm_nxt[2]; 2245227825Stheraven switch (c1) 2246227825Stheraven { 2247227825Stheraven case 0xE0: 2248227825Stheraven if ((c2 & 0xE0) != 0xA0) 2249227825Stheraven return codecvt_base::error; 2250227825Stheraven break; 2251227825Stheraven case 0xED: 2252227825Stheraven if ((c2 & 0xE0) != 0x80) 2253227825Stheraven return codecvt_base::error; 2254227825Stheraven break; 2255227825Stheraven default: 2256227825Stheraven if ((c2 & 0xC0) != 0x80) 2257227825Stheraven return codecvt_base::error; 2258227825Stheraven break; 2259227825Stheraven } 2260227825Stheraven if ((c3 & 0xC0) != 0x80) 2261227825Stheraven return codecvt_base::error; 2262227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) 2263227825Stheraven | ((c2 & 0x3F) << 6) 2264227825Stheraven | (c3 & 0x3F)); 2265227825Stheraven if (t > Maxcode) 2266227825Stheraven return codecvt_base::error; 2267227825Stheraven *to_nxt = t; 2268227825Stheraven frm_nxt += 3; 2269227825Stheraven } 2270227825Stheraven else if (c1 < 0xF5) 2271227825Stheraven { 2272227825Stheraven if (frm_end-frm_nxt < 4) 2273227825Stheraven return codecvt_base::partial; 2274227825Stheraven uint8_t c2 = frm_nxt[1]; 2275227825Stheraven uint8_t c3 = frm_nxt[2]; 2276227825Stheraven uint8_t c4 = frm_nxt[3]; 2277227825Stheraven switch (c1) 2278227825Stheraven { 2279227825Stheraven case 0xF0: 2280227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2281227825Stheraven return codecvt_base::error; 2282227825Stheraven break; 2283227825Stheraven case 0xF4: 2284227825Stheraven if ((c2 & 0xF0) != 0x80) 2285227825Stheraven return codecvt_base::error; 2286227825Stheraven break; 2287227825Stheraven default: 2288227825Stheraven if ((c2 & 0xC0) != 0x80) 2289227825Stheraven return codecvt_base::error; 2290227825Stheraven break; 2291227825Stheraven } 2292227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2293227825Stheraven return codecvt_base::error; 2294227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) 2295227825Stheraven | ((c2 & 0x3F) << 12) 2296227825Stheraven | ((c3 & 0x3F) << 6) 2297227825Stheraven | (c4 & 0x3F)); 2298227825Stheraven if (t > Maxcode) 2299227825Stheraven return codecvt_base::error; 2300227825Stheraven *to_nxt = t; 2301227825Stheraven frm_nxt += 4; 2302227825Stheraven } 2303227825Stheraven else 2304227825Stheraven { 2305227825Stheraven return codecvt_base::error; 2306227825Stheraven } 2307227825Stheraven } 2308227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2309227825Stheraven} 2310227825Stheraven 2311227825Stheravenstatic 2312227825Stheravenint 2313227825Stheravenutf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2314227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2315227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2316227825Stheraven{ 2317227825Stheraven const uint8_t* frm_nxt = frm; 2318227825Stheraven if (mode & consume_header) 2319227825Stheraven { 2320227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2321227825Stheraven frm_nxt[2] == 0xBF) 2322227825Stheraven frm_nxt += 3; 2323227825Stheraven } 2324227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) 2325227825Stheraven { 2326227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2327227825Stheraven if (c1 < 0x80) 2328227825Stheraven { 2329227825Stheraven if (c1 > Maxcode) 2330227825Stheraven break; 2331227825Stheraven ++frm_nxt; 2332227825Stheraven } 2333227825Stheraven else if (c1 < 0xC2) 2334227825Stheraven { 2335227825Stheraven break; 2336227825Stheraven } 2337227825Stheraven else if (c1 < 0xE0) 2338227825Stheraven { 2339227825Stheraven if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) 2340227825Stheraven break; 2341232950Stheraven if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) 2342227825Stheraven break; 2343227825Stheraven frm_nxt += 2; 2344227825Stheraven } 2345227825Stheraven else if (c1 < 0xF0) 2346227825Stheraven { 2347227825Stheraven if (frm_end-frm_nxt < 3) 2348227825Stheraven break; 2349227825Stheraven uint8_t c2 = frm_nxt[1]; 2350227825Stheraven uint8_t c3 = frm_nxt[2]; 2351227825Stheraven switch (c1) 2352227825Stheraven { 2353227825Stheraven case 0xE0: 2354227825Stheraven if ((c2 & 0xE0) != 0xA0) 2355227825Stheraven return static_cast<int>(frm_nxt - frm); 2356227825Stheraven break; 2357227825Stheraven case 0xED: 2358227825Stheraven if ((c2 & 0xE0) != 0x80) 2359227825Stheraven return static_cast<int>(frm_nxt - frm); 2360227825Stheraven break; 2361227825Stheraven default: 2362227825Stheraven if ((c2 & 0xC0) != 0x80) 2363227825Stheraven return static_cast<int>(frm_nxt - frm); 2364227825Stheraven break; 2365227825Stheraven } 2366227825Stheraven if ((c3 & 0xC0) != 0x80) 2367227825Stheraven break; 2368232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2369227825Stheraven break; 2370227825Stheraven frm_nxt += 3; 2371227825Stheraven } 2372227825Stheraven else if (c1 < 0xF5) 2373227825Stheraven { 2374227825Stheraven if (frm_end-frm_nxt < 4) 2375227825Stheraven break; 2376227825Stheraven uint8_t c2 = frm_nxt[1]; 2377227825Stheraven uint8_t c3 = frm_nxt[2]; 2378227825Stheraven uint8_t c4 = frm_nxt[3]; 2379227825Stheraven switch (c1) 2380227825Stheraven { 2381227825Stheraven case 0xF0: 2382227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2383227825Stheraven return static_cast<int>(frm_nxt - frm); 2384227825Stheraven break; 2385227825Stheraven case 0xF4: 2386227825Stheraven if ((c2 & 0xF0) != 0x80) 2387227825Stheraven return static_cast<int>(frm_nxt - frm); 2388227825Stheraven break; 2389227825Stheraven default: 2390227825Stheraven if ((c2 & 0xC0) != 0x80) 2391227825Stheraven return static_cast<int>(frm_nxt - frm); 2392227825Stheraven break; 2393227825Stheraven } 2394227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2395227825Stheraven break; 2396232950Stheraven if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | 2397232950Stheraven ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode) 2398227825Stheraven break; 2399227825Stheraven frm_nxt += 4; 2400227825Stheraven } 2401227825Stheraven else 2402227825Stheraven { 2403227825Stheraven break; 2404227825Stheraven } 2405227825Stheraven } 2406227825Stheraven return static_cast<int>(frm_nxt - frm); 2407227825Stheraven} 2408227825Stheraven 2409227825Stheravenstatic 2410227825Stheravencodecvt_base::result 2411227825Stheravenucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2412227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2413227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2414227825Stheraven{ 2415227825Stheraven frm_nxt = frm; 2416227825Stheraven to_nxt = to; 2417227825Stheraven if (mode & generate_header) 2418227825Stheraven { 2419227825Stheraven if (to_end-to_nxt < 3) 2420227825Stheraven return codecvt_base::partial; 2421227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 2422227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 2423227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 2424227825Stheraven } 2425227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2426227825Stheraven { 2427227825Stheraven uint16_t wc = *frm_nxt; 2428227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2429227825Stheraven return codecvt_base::error; 2430227825Stheraven if (wc < 0x0080) 2431227825Stheraven { 2432227825Stheraven if (to_end-to_nxt < 1) 2433227825Stheraven return codecvt_base::partial; 2434227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2435227825Stheraven } 2436227825Stheraven else if (wc < 0x0800) 2437227825Stheraven { 2438227825Stheraven if (to_end-to_nxt < 2) 2439227825Stheraven return codecvt_base::partial; 2440227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6)); 2441227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F)); 2442227825Stheraven } 2443227825Stheraven else // if (wc <= 0xFFFF) 2444227825Stheraven { 2445227825Stheraven if (to_end-to_nxt < 3) 2446227825Stheraven return codecvt_base::partial; 2447227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12)); 2448227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6)); 2449227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F)); 2450227825Stheraven } 2451227825Stheraven } 2452227825Stheraven return codecvt_base::ok; 2453227825Stheraven} 2454227825Stheraven 2455227825Stheravenstatic 2456227825Stheravencodecvt_base::result 2457227825Stheravenutf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2458227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2459227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2460227825Stheraven{ 2461227825Stheraven frm_nxt = frm; 2462227825Stheraven to_nxt = to; 2463227825Stheraven if (mode & consume_header) 2464227825Stheraven { 2465227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2466227825Stheraven frm_nxt[2] == 0xBF) 2467227825Stheraven frm_nxt += 3; 2468227825Stheraven } 2469227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 2470227825Stheraven { 2471227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2472227825Stheraven if (c1 < 0x80) 2473227825Stheraven { 2474227825Stheraven if (c1 > Maxcode) 2475227825Stheraven return codecvt_base::error; 2476227825Stheraven *to_nxt = static_cast<uint16_t>(c1); 2477227825Stheraven ++frm_nxt; 2478227825Stheraven } 2479227825Stheraven else if (c1 < 0xC2) 2480227825Stheraven { 2481227825Stheraven return codecvt_base::error; 2482227825Stheraven } 2483227825Stheraven else if (c1 < 0xE0) 2484227825Stheraven { 2485227825Stheraven if (frm_end-frm_nxt < 2) 2486227825Stheraven return codecvt_base::partial; 2487227825Stheraven uint8_t c2 = frm_nxt[1]; 2488227825Stheraven if ((c2 & 0xC0) != 0x80) 2489227825Stheraven return codecvt_base::error; 2490227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) 2491227825Stheraven | (c2 & 0x3F)); 2492227825Stheraven if (t > Maxcode) 2493227825Stheraven return codecvt_base::error; 2494227825Stheraven *to_nxt = t; 2495227825Stheraven frm_nxt += 2; 2496227825Stheraven } 2497227825Stheraven else if (c1 < 0xF0) 2498227825Stheraven { 2499227825Stheraven if (frm_end-frm_nxt < 3) 2500227825Stheraven return codecvt_base::partial; 2501227825Stheraven uint8_t c2 = frm_nxt[1]; 2502227825Stheraven uint8_t c3 = frm_nxt[2]; 2503227825Stheraven switch (c1) 2504227825Stheraven { 2505227825Stheraven case 0xE0: 2506227825Stheraven if ((c2 & 0xE0) != 0xA0) 2507227825Stheraven return codecvt_base::error; 2508227825Stheraven break; 2509227825Stheraven case 0xED: 2510227825Stheraven if ((c2 & 0xE0) != 0x80) 2511227825Stheraven return codecvt_base::error; 2512227825Stheraven break; 2513227825Stheraven default: 2514227825Stheraven if ((c2 & 0xC0) != 0x80) 2515227825Stheraven return codecvt_base::error; 2516227825Stheraven break; 2517227825Stheraven } 2518227825Stheraven if ((c3 & 0xC0) != 0x80) 2519227825Stheraven return codecvt_base::error; 2520227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 2521227825Stheraven | ((c2 & 0x3F) << 6) 2522227825Stheraven | (c3 & 0x3F)); 2523227825Stheraven if (t > Maxcode) 2524227825Stheraven return codecvt_base::error; 2525227825Stheraven *to_nxt = t; 2526227825Stheraven frm_nxt += 3; 2527227825Stheraven } 2528227825Stheraven else 2529227825Stheraven { 2530227825Stheraven return codecvt_base::error; 2531227825Stheraven } 2532227825Stheraven } 2533227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2534227825Stheraven} 2535227825Stheraven 2536227825Stheravenstatic 2537227825Stheravenint 2538227825Stheravenutf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2539227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2540227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2541227825Stheraven{ 2542227825Stheraven const uint8_t* frm_nxt = frm; 2543227825Stheraven if (mode & consume_header) 2544227825Stheraven { 2545227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2546227825Stheraven frm_nxt[2] == 0xBF) 2547227825Stheraven frm_nxt += 3; 2548227825Stheraven } 2549227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) 2550227825Stheraven { 2551227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2552227825Stheraven if (c1 < 0x80) 2553227825Stheraven { 2554227825Stheraven if (c1 > Maxcode) 2555227825Stheraven break; 2556227825Stheraven ++frm_nxt; 2557227825Stheraven } 2558227825Stheraven else if (c1 < 0xC2) 2559227825Stheraven { 2560227825Stheraven break; 2561227825Stheraven } 2562227825Stheraven else if (c1 < 0xE0) 2563227825Stheraven { 2564227825Stheraven if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) 2565227825Stheraven break; 2566232950Stheraven if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) 2567227825Stheraven break; 2568227825Stheraven frm_nxt += 2; 2569227825Stheraven } 2570227825Stheraven else if (c1 < 0xF0) 2571227825Stheraven { 2572227825Stheraven if (frm_end-frm_nxt < 3) 2573227825Stheraven break; 2574227825Stheraven uint8_t c2 = frm_nxt[1]; 2575227825Stheraven uint8_t c3 = frm_nxt[2]; 2576227825Stheraven switch (c1) 2577227825Stheraven { 2578227825Stheraven case 0xE0: 2579227825Stheraven if ((c2 & 0xE0) != 0xA0) 2580227825Stheraven return static_cast<int>(frm_nxt - frm); 2581227825Stheraven break; 2582227825Stheraven case 0xED: 2583227825Stheraven if ((c2 & 0xE0) != 0x80) 2584227825Stheraven return static_cast<int>(frm_nxt - frm); 2585227825Stheraven break; 2586227825Stheraven default: 2587227825Stheraven if ((c2 & 0xC0) != 0x80) 2588227825Stheraven return static_cast<int>(frm_nxt - frm); 2589227825Stheraven break; 2590227825Stheraven } 2591227825Stheraven if ((c3 & 0xC0) != 0x80) 2592227825Stheraven break; 2593232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2594227825Stheraven break; 2595227825Stheraven frm_nxt += 3; 2596227825Stheraven } 2597227825Stheraven else 2598227825Stheraven { 2599227825Stheraven break; 2600227825Stheraven } 2601227825Stheraven } 2602227825Stheraven return static_cast<int>(frm_nxt - frm); 2603227825Stheraven} 2604227825Stheraven 2605227825Stheravenstatic 2606227825Stheravencodecvt_base::result 2607227825Stheravenucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2608227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2609227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2610227825Stheraven{ 2611227825Stheraven frm_nxt = frm; 2612227825Stheraven to_nxt = to; 2613227825Stheraven if (mode & generate_header) 2614227825Stheraven { 2615227825Stheraven if (to_end-to_nxt < 2) 2616227825Stheraven return codecvt_base::partial; 2617227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2618227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2619227825Stheraven } 2620227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2621227825Stheraven { 2622227825Stheraven uint32_t wc = *frm_nxt; 2623227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2624227825Stheraven return codecvt_base::error; 2625227825Stheraven if (wc < 0x010000) 2626227825Stheraven { 2627227825Stheraven if (to_end-to_nxt < 2) 2628227825Stheraven return codecvt_base::partial; 2629227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2630227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2631227825Stheraven } 2632227825Stheraven else 2633227825Stheraven { 2634227825Stheraven if (to_end-to_nxt < 4) 2635227825Stheraven return codecvt_base::partial; 2636227825Stheraven uint16_t t = static_cast<uint16_t>( 2637227825Stheraven 0xD800 2638227825Stheraven | ((((wc & 0x1F0000) >> 16) - 1) << 6) 2639227825Stheraven | ((wc & 0x00FC00) >> 10)); 2640227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2641227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2642227825Stheraven t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF)); 2643227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2644227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2645227825Stheraven } 2646227825Stheraven } 2647227825Stheraven return codecvt_base::ok; 2648227825Stheraven} 2649227825Stheraven 2650227825Stheravenstatic 2651227825Stheravencodecvt_base::result 2652227825Stheravenutf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2653227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2654227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2655227825Stheraven{ 2656227825Stheraven frm_nxt = frm; 2657227825Stheraven to_nxt = to; 2658227825Stheraven if (mode & consume_header) 2659227825Stheraven { 2660227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2661227825Stheraven frm_nxt += 2; 2662227825Stheraven } 2663227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2664227825Stheraven { 2665232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2666227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2667227825Stheraven return codecvt_base::error; 2668227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2669227825Stheraven { 2670227825Stheraven if (c1 > Maxcode) 2671227825Stheraven return codecvt_base::error; 2672227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2673227825Stheraven frm_nxt += 2; 2674227825Stheraven } 2675227825Stheraven else 2676227825Stheraven { 2677227825Stheraven if (frm_end-frm_nxt < 4) 2678227825Stheraven return codecvt_base::partial; 2679232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]); 2680227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2681227825Stheraven return codecvt_base::error; 2682227825Stheraven uint32_t t = static_cast<uint32_t>( 2683227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2684227825Stheraven | ((c1 & 0x003F) << 10) 2685227825Stheraven | (c2 & 0x03FF)); 2686227825Stheraven if (t > Maxcode) 2687227825Stheraven return codecvt_base::error; 2688227825Stheraven *to_nxt = t; 2689227825Stheraven frm_nxt += 4; 2690227825Stheraven } 2691227825Stheraven } 2692227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2693227825Stheraven} 2694227825Stheraven 2695227825Stheravenstatic 2696227825Stheravenint 2697227825Stheravenutf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2698227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2699227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2700227825Stheraven{ 2701227825Stheraven const uint8_t* frm_nxt = frm; 2702227825Stheraven if (mode & consume_header) 2703227825Stheraven { 2704227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2705227825Stheraven frm_nxt += 2; 2706227825Stheraven } 2707227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) 2708227825Stheraven { 2709232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2710227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2711227825Stheraven break; 2712227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2713227825Stheraven { 2714227825Stheraven if (c1 > Maxcode) 2715227825Stheraven break; 2716227825Stheraven frm_nxt += 2; 2717227825Stheraven } 2718227825Stheraven else 2719227825Stheraven { 2720227825Stheraven if (frm_end-frm_nxt < 4) 2721227825Stheraven break; 2722232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]); 2723227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2724227825Stheraven break; 2725227825Stheraven uint32_t t = static_cast<uint32_t>( 2726227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2727227825Stheraven | ((c1 & 0x003F) << 10) 2728227825Stheraven | (c2 & 0x03FF)); 2729227825Stheraven if (t > Maxcode) 2730227825Stheraven break; 2731227825Stheraven frm_nxt += 4; 2732227825Stheraven } 2733227825Stheraven } 2734227825Stheraven return static_cast<int>(frm_nxt - frm); 2735227825Stheraven} 2736227825Stheraven 2737227825Stheravenstatic 2738227825Stheravencodecvt_base::result 2739227825Stheravenucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2740227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2741227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2742227825Stheraven{ 2743227825Stheraven frm_nxt = frm; 2744227825Stheraven to_nxt = to; 2745227825Stheraven if (mode & generate_header) 2746227825Stheraven { 2747227825Stheraven if (to_end-to_nxt < 2) 2748227825Stheraven return codecvt_base::partial; 2749227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2750227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2751227825Stheraven } 2752227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2753227825Stheraven { 2754227825Stheraven uint32_t wc = *frm_nxt; 2755227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2756227825Stheraven return codecvt_base::error; 2757227825Stheraven if (wc < 0x010000) 2758227825Stheraven { 2759227825Stheraven if (to_end-to_nxt < 2) 2760227825Stheraven return codecvt_base::partial; 2761227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2762227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2763227825Stheraven } 2764227825Stheraven else 2765227825Stheraven { 2766227825Stheraven if (to_end-to_nxt < 4) 2767227825Stheraven return codecvt_base::partial; 2768227825Stheraven uint16_t t = static_cast<uint16_t>( 2769227825Stheraven 0xD800 2770227825Stheraven | ((((wc & 0x1F0000) >> 16) - 1) << 6) 2771227825Stheraven | ((wc & 0x00FC00) >> 10)); 2772227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2773227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2774227825Stheraven t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF)); 2775227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2776227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2777227825Stheraven } 2778227825Stheraven } 2779227825Stheraven return codecvt_base::ok; 2780227825Stheraven} 2781227825Stheraven 2782227825Stheravenstatic 2783227825Stheravencodecvt_base::result 2784227825Stheravenutf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2785227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2786227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2787227825Stheraven{ 2788227825Stheraven frm_nxt = frm; 2789227825Stheraven to_nxt = to; 2790227825Stheraven if (mode & consume_header) 2791227825Stheraven { 2792227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2793227825Stheraven frm_nxt += 2; 2794227825Stheraven } 2795227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2796227825Stheraven { 2797232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2798227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2799227825Stheraven return codecvt_base::error; 2800227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2801227825Stheraven { 2802227825Stheraven if (c1 > Maxcode) 2803227825Stheraven return codecvt_base::error; 2804227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2805227825Stheraven frm_nxt += 2; 2806227825Stheraven } 2807227825Stheraven else 2808227825Stheraven { 2809227825Stheraven if (frm_end-frm_nxt < 4) 2810227825Stheraven return codecvt_base::partial; 2811232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]); 2812227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2813227825Stheraven return codecvt_base::error; 2814227825Stheraven uint32_t t = static_cast<uint32_t>( 2815227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2816227825Stheraven | ((c1 & 0x003F) << 10) 2817227825Stheraven | (c2 & 0x03FF)); 2818227825Stheraven if (t > Maxcode) 2819227825Stheraven return codecvt_base::error; 2820227825Stheraven *to_nxt = t; 2821227825Stheraven frm_nxt += 4; 2822227825Stheraven } 2823227825Stheraven } 2824227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2825227825Stheraven} 2826227825Stheraven 2827227825Stheravenstatic 2828227825Stheravenint 2829227825Stheravenutf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2830227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2831227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2832227825Stheraven{ 2833227825Stheraven const uint8_t* frm_nxt = frm; 2834227825Stheraven if (mode & consume_header) 2835227825Stheraven { 2836227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2837227825Stheraven frm_nxt += 2; 2838227825Stheraven } 2839227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) 2840227825Stheraven { 2841232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2842227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2843227825Stheraven break; 2844227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2845227825Stheraven { 2846227825Stheraven if (c1 > Maxcode) 2847227825Stheraven break; 2848227825Stheraven frm_nxt += 2; 2849227825Stheraven } 2850227825Stheraven else 2851227825Stheraven { 2852227825Stheraven if (frm_end-frm_nxt < 4) 2853227825Stheraven break; 2854232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]); 2855227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2856227825Stheraven break; 2857227825Stheraven uint32_t t = static_cast<uint32_t>( 2858227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2859227825Stheraven | ((c1 & 0x003F) << 10) 2860227825Stheraven | (c2 & 0x03FF)); 2861227825Stheraven if (t > Maxcode) 2862227825Stheraven break; 2863227825Stheraven frm_nxt += 4; 2864227825Stheraven } 2865227825Stheraven } 2866227825Stheraven return static_cast<int>(frm_nxt - frm); 2867227825Stheraven} 2868227825Stheraven 2869227825Stheravenstatic 2870227825Stheravencodecvt_base::result 2871227825Stheravenucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2872227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2873227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2874227825Stheraven{ 2875227825Stheraven frm_nxt = frm; 2876227825Stheraven to_nxt = to; 2877227825Stheraven if (mode & generate_header) 2878227825Stheraven { 2879227825Stheraven if (to_end-to_nxt < 2) 2880227825Stheraven return codecvt_base::partial; 2881227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2882227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2883227825Stheraven } 2884227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2885227825Stheraven { 2886227825Stheraven uint16_t wc = *frm_nxt; 2887227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2888227825Stheraven return codecvt_base::error; 2889227825Stheraven if (to_end-to_nxt < 2) 2890227825Stheraven return codecvt_base::partial; 2891227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2892227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2893227825Stheraven } 2894227825Stheraven return codecvt_base::ok; 2895227825Stheraven} 2896227825Stheraven 2897227825Stheravenstatic 2898227825Stheravencodecvt_base::result 2899227825Stheravenutf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2900227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2901227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2902227825Stheraven{ 2903227825Stheraven frm_nxt = frm; 2904227825Stheraven to_nxt = to; 2905227825Stheraven if (mode & consume_header) 2906227825Stheraven { 2907227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2908227825Stheraven frm_nxt += 2; 2909227825Stheraven } 2910227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2911227825Stheraven { 2912232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2913227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2914227825Stheraven return codecvt_base::error; 2915227825Stheraven *to_nxt = c1; 2916227825Stheraven frm_nxt += 2; 2917227825Stheraven } 2918227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2919227825Stheraven} 2920227825Stheraven 2921227825Stheravenstatic 2922227825Stheravenint 2923227825Stheravenutf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2924227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2925227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2926227825Stheraven{ 2927227825Stheraven const uint8_t* frm_nxt = frm; 2928227825Stheraven if (mode & consume_header) 2929227825Stheraven { 2930227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2931227825Stheraven frm_nxt += 2; 2932227825Stheraven } 2933227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) 2934227825Stheraven { 2935232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2936227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2937227825Stheraven break; 2938227825Stheraven frm_nxt += 2; 2939227825Stheraven } 2940227825Stheraven return static_cast<int>(frm_nxt - frm); 2941227825Stheraven} 2942227825Stheraven 2943227825Stheravenstatic 2944227825Stheravencodecvt_base::result 2945227825Stheravenucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2946227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2947227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2948227825Stheraven{ 2949227825Stheraven frm_nxt = frm; 2950227825Stheraven to_nxt = to; 2951227825Stheraven if (mode & generate_header) 2952227825Stheraven { 2953227825Stheraven if (to_end-to_nxt < 2) 2954227825Stheraven return codecvt_base::partial; 2955227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2956227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2957227825Stheraven } 2958227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2959227825Stheraven { 2960227825Stheraven uint16_t wc = *frm_nxt; 2961227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2962227825Stheraven return codecvt_base::error; 2963227825Stheraven if (to_end-to_nxt < 2) 2964227825Stheraven return codecvt_base::partial; 2965227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2966227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2967227825Stheraven } 2968227825Stheraven return codecvt_base::ok; 2969227825Stheraven} 2970227825Stheraven 2971227825Stheravenstatic 2972227825Stheravencodecvt_base::result 2973227825Stheravenutf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2974227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2975227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2976227825Stheraven{ 2977227825Stheraven frm_nxt = frm; 2978227825Stheraven to_nxt = to; 2979227825Stheraven if (mode & consume_header) 2980227825Stheraven { 2981227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2982227825Stheraven frm_nxt += 2; 2983227825Stheraven } 2984227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2985227825Stheraven { 2986232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2987227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2988227825Stheraven return codecvt_base::error; 2989227825Stheraven *to_nxt = c1; 2990227825Stheraven frm_nxt += 2; 2991227825Stheraven } 2992227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2993227825Stheraven} 2994227825Stheraven 2995227825Stheravenstatic 2996227825Stheravenint 2997227825Stheravenutf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2998227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2999227825Stheraven codecvt_mode mode = codecvt_mode(0)) 3000227825Stheraven{ 3001227825Stheraven const uint8_t* frm_nxt = frm; 3002227825Stheraven frm_nxt = frm; 3003227825Stheraven if (mode & consume_header) 3004227825Stheraven { 3005227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 3006227825Stheraven frm_nxt += 2; 3007227825Stheraven } 3008227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) 3009227825Stheraven { 3010232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 3011227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 3012227825Stheraven break; 3013227825Stheraven frm_nxt += 2; 3014227825Stheraven } 3015227825Stheraven return static_cast<int>(frm_nxt - frm); 3016227825Stheraven} 3017227825Stheraven 3018227825Stheraven// template <> class codecvt<char16_t, char, mbstate_t> 3019227825Stheraven 3020227825Stheravenlocale::id codecvt<char16_t, char, mbstate_t>::id; 3021227825Stheraven 3022227825Stheravencodecvt<char16_t, char, mbstate_t>::~codecvt() 3023227825Stheraven{ 3024227825Stheraven} 3025227825Stheraven 3026227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3027227825Stheravencodecvt<char16_t, char, mbstate_t>::do_out(state_type&, 3028227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3029227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3030227825Stheraven{ 3031227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3032227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3033227825Stheraven const uint16_t* _frm_nxt = _frm; 3034227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3035227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3036227825Stheraven uint8_t* _to_nxt = _to; 3037227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3038227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3039227825Stheraven to_nxt = to + (_to_nxt - _to); 3040227825Stheraven return r; 3041227825Stheraven} 3042227825Stheraven 3043227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3044227825Stheravencodecvt<char16_t, char, mbstate_t>::do_in(state_type&, 3045227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3046227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3047227825Stheraven{ 3048227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3049227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3050227825Stheraven const uint8_t* _frm_nxt = _frm; 3051227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3052227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3053227825Stheraven uint16_t* _to_nxt = _to; 3054227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3055227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3056227825Stheraven to_nxt = to + (_to_nxt - _to); 3057227825Stheraven return r; 3058227825Stheraven} 3059227825Stheraven 3060227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3061227825Stheravencodecvt<char16_t, char, mbstate_t>::do_unshift(state_type&, 3062227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3063227825Stheraven{ 3064227825Stheraven to_nxt = to; 3065227825Stheraven return noconv; 3066227825Stheraven} 3067227825Stheraven 3068227825Stheravenint 3069227825Stheravencodecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 3070227825Stheraven{ 3071227825Stheraven return 0; 3072227825Stheraven} 3073227825Stheraven 3074227825Stheravenbool 3075227825Stheravencodecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 3076227825Stheraven{ 3077227825Stheraven return false; 3078227825Stheraven} 3079227825Stheraven 3080227825Stheravenint 3081227825Stheravencodecvt<char16_t, char, mbstate_t>::do_length(state_type&, 3082227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3083227825Stheraven{ 3084227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3085227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3086227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx); 3087227825Stheraven} 3088227825Stheraven 3089227825Stheravenint 3090227825Stheravencodecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 3091227825Stheraven{ 3092227825Stheraven return 4; 3093227825Stheraven} 3094227825Stheraven 3095227825Stheraven// template <> class codecvt<char32_t, char, mbstate_t> 3096227825Stheraven 3097227825Stheravenlocale::id codecvt<char32_t, char, mbstate_t>::id; 3098227825Stheraven 3099227825Stheravencodecvt<char32_t, char, mbstate_t>::~codecvt() 3100227825Stheraven{ 3101227825Stheraven} 3102227825Stheraven 3103227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3104227825Stheravencodecvt<char32_t, char, mbstate_t>::do_out(state_type&, 3105227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3106227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3107227825Stheraven{ 3108227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3109227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3110227825Stheraven const uint32_t* _frm_nxt = _frm; 3111227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3112227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3113227825Stheraven uint8_t* _to_nxt = _to; 3114227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3115227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3116227825Stheraven to_nxt = to + (_to_nxt - _to); 3117227825Stheraven return r; 3118227825Stheraven} 3119227825Stheraven 3120227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3121227825Stheravencodecvt<char32_t, char, mbstate_t>::do_in(state_type&, 3122227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3123227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3124227825Stheraven{ 3125227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3126227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3127227825Stheraven const uint8_t* _frm_nxt = _frm; 3128227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3129227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3130227825Stheraven uint32_t* _to_nxt = _to; 3131227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3132227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3133227825Stheraven to_nxt = to + (_to_nxt - _to); 3134227825Stheraven return r; 3135227825Stheraven} 3136227825Stheraven 3137227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3138227825Stheravencodecvt<char32_t, char, mbstate_t>::do_unshift(state_type&, 3139227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3140227825Stheraven{ 3141227825Stheraven to_nxt = to; 3142227825Stheraven return noconv; 3143227825Stheraven} 3144227825Stheraven 3145227825Stheravenint 3146227825Stheravencodecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 3147227825Stheraven{ 3148227825Stheraven return 0; 3149227825Stheraven} 3150227825Stheraven 3151227825Stheravenbool 3152227825Stheravencodecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 3153227825Stheraven{ 3154227825Stheraven return false; 3155227825Stheraven} 3156227825Stheraven 3157227825Stheravenint 3158227825Stheravencodecvt<char32_t, char, mbstate_t>::do_length(state_type&, 3159227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3160227825Stheraven{ 3161227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3162227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3163227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx); 3164227825Stheraven} 3165227825Stheraven 3166227825Stheravenint 3167227825Stheravencodecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 3168227825Stheraven{ 3169227825Stheraven return 4; 3170227825Stheraven} 3171227825Stheraven 3172227825Stheraven// __codecvt_utf8<wchar_t> 3173227825Stheraven 3174227825Stheraven__codecvt_utf8<wchar_t>::result 3175227825Stheraven__codecvt_utf8<wchar_t>::do_out(state_type&, 3176227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3177227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3178227825Stheraven{ 3179227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3180227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3181227825Stheraven const uint32_t* _frm_nxt = _frm; 3182227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3183227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3184227825Stheraven uint8_t* _to_nxt = _to; 3185227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3186227825Stheraven _Maxcode_, _Mode_); 3187227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3188227825Stheraven to_nxt = to + (_to_nxt - _to); 3189227825Stheraven return r; 3190227825Stheraven} 3191227825Stheraven 3192227825Stheraven__codecvt_utf8<wchar_t>::result 3193227825Stheraven__codecvt_utf8<wchar_t>::do_in(state_type&, 3194227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3195227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3196227825Stheraven{ 3197227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3198227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3199227825Stheraven const uint8_t* _frm_nxt = _frm; 3200227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3201227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3202227825Stheraven uint32_t* _to_nxt = _to; 3203227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3204227825Stheraven _Maxcode_, _Mode_); 3205227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3206227825Stheraven to_nxt = to + (_to_nxt - _to); 3207227825Stheraven return r; 3208227825Stheraven} 3209227825Stheraven 3210227825Stheraven__codecvt_utf8<wchar_t>::result 3211227825Stheraven__codecvt_utf8<wchar_t>::do_unshift(state_type&, 3212227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3213227825Stheraven{ 3214227825Stheraven to_nxt = to; 3215227825Stheraven return noconv; 3216227825Stheraven} 3217227825Stheraven 3218227825Stheravenint 3219227825Stheraven__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT 3220227825Stheraven{ 3221227825Stheraven return 0; 3222227825Stheraven} 3223227825Stheraven 3224227825Stheravenbool 3225227825Stheraven__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT 3226227825Stheraven{ 3227227825Stheraven return false; 3228227825Stheraven} 3229227825Stheraven 3230227825Stheravenint 3231227825Stheraven__codecvt_utf8<wchar_t>::do_length(state_type&, 3232227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3233227825Stheraven{ 3234227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3235227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3236227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3237227825Stheraven} 3238227825Stheraven 3239227825Stheravenint 3240227825Stheraven__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT 3241227825Stheraven{ 3242227825Stheraven if (_Mode_ & consume_header) 3243227825Stheraven return 7; 3244227825Stheraven return 4; 3245227825Stheraven} 3246227825Stheraven 3247227825Stheraven// __codecvt_utf8<char16_t> 3248227825Stheraven 3249227825Stheraven__codecvt_utf8<char16_t>::result 3250227825Stheraven__codecvt_utf8<char16_t>::do_out(state_type&, 3251227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3252227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3253227825Stheraven{ 3254227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3255227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3256227825Stheraven const uint16_t* _frm_nxt = _frm; 3257227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3258227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3259227825Stheraven uint8_t* _to_nxt = _to; 3260227825Stheraven result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3261227825Stheraven _Maxcode_, _Mode_); 3262227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3263227825Stheraven to_nxt = to + (_to_nxt - _to); 3264227825Stheraven return r; 3265227825Stheraven} 3266227825Stheraven 3267227825Stheraven__codecvt_utf8<char16_t>::result 3268227825Stheraven__codecvt_utf8<char16_t>::do_in(state_type&, 3269227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3270227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3271227825Stheraven{ 3272227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3273227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3274227825Stheraven const uint8_t* _frm_nxt = _frm; 3275227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3276227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3277227825Stheraven uint16_t* _to_nxt = _to; 3278227825Stheraven result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3279227825Stheraven _Maxcode_, _Mode_); 3280227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3281227825Stheraven to_nxt = to + (_to_nxt - _to); 3282227825Stheraven return r; 3283227825Stheraven} 3284227825Stheraven 3285227825Stheraven__codecvt_utf8<char16_t>::result 3286227825Stheraven__codecvt_utf8<char16_t>::do_unshift(state_type&, 3287227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3288227825Stheraven{ 3289227825Stheraven to_nxt = to; 3290227825Stheraven return noconv; 3291227825Stheraven} 3292227825Stheraven 3293227825Stheravenint 3294227825Stheraven__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT 3295227825Stheraven{ 3296227825Stheraven return 0; 3297227825Stheraven} 3298227825Stheraven 3299227825Stheravenbool 3300227825Stheraven__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT 3301227825Stheraven{ 3302227825Stheraven return false; 3303227825Stheraven} 3304227825Stheraven 3305227825Stheravenint 3306227825Stheraven__codecvt_utf8<char16_t>::do_length(state_type&, 3307227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3308227825Stheraven{ 3309227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3310227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3311227825Stheraven return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3312227825Stheraven} 3313227825Stheraven 3314227825Stheravenint 3315227825Stheraven__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT 3316227825Stheraven{ 3317227825Stheraven if (_Mode_ & consume_header) 3318227825Stheraven return 6; 3319227825Stheraven return 3; 3320227825Stheraven} 3321227825Stheraven 3322227825Stheraven// __codecvt_utf8<char32_t> 3323227825Stheraven 3324227825Stheraven__codecvt_utf8<char32_t>::result 3325227825Stheraven__codecvt_utf8<char32_t>::do_out(state_type&, 3326227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3327227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3328227825Stheraven{ 3329227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3330227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3331227825Stheraven const uint32_t* _frm_nxt = _frm; 3332227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3333227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3334227825Stheraven uint8_t* _to_nxt = _to; 3335227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3336227825Stheraven _Maxcode_, _Mode_); 3337227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3338227825Stheraven to_nxt = to + (_to_nxt - _to); 3339227825Stheraven return r; 3340227825Stheraven} 3341227825Stheraven 3342227825Stheraven__codecvt_utf8<char32_t>::result 3343227825Stheraven__codecvt_utf8<char32_t>::do_in(state_type&, 3344227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3345227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3346227825Stheraven{ 3347227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3348227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3349227825Stheraven const uint8_t* _frm_nxt = _frm; 3350227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3351227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3352227825Stheraven uint32_t* _to_nxt = _to; 3353227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3354227825Stheraven _Maxcode_, _Mode_); 3355227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3356227825Stheraven to_nxt = to + (_to_nxt - _to); 3357227825Stheraven return r; 3358227825Stheraven} 3359227825Stheraven 3360227825Stheraven__codecvt_utf8<char32_t>::result 3361227825Stheraven__codecvt_utf8<char32_t>::do_unshift(state_type&, 3362227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3363227825Stheraven{ 3364227825Stheraven to_nxt = to; 3365227825Stheraven return noconv; 3366227825Stheraven} 3367227825Stheraven 3368227825Stheravenint 3369227825Stheraven__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT 3370227825Stheraven{ 3371227825Stheraven return 0; 3372227825Stheraven} 3373227825Stheraven 3374227825Stheravenbool 3375227825Stheraven__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT 3376227825Stheraven{ 3377227825Stheraven return false; 3378227825Stheraven} 3379227825Stheraven 3380227825Stheravenint 3381227825Stheraven__codecvt_utf8<char32_t>::do_length(state_type&, 3382227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3383227825Stheraven{ 3384227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3385227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3386227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3387227825Stheraven} 3388227825Stheraven 3389227825Stheravenint 3390227825Stheraven__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT 3391227825Stheraven{ 3392227825Stheraven if (_Mode_ & consume_header) 3393227825Stheraven return 7; 3394227825Stheraven return 4; 3395227825Stheraven} 3396227825Stheraven 3397227825Stheraven// __codecvt_utf16<wchar_t, false> 3398227825Stheraven 3399227825Stheraven__codecvt_utf16<wchar_t, false>::result 3400227825Stheraven__codecvt_utf16<wchar_t, false>::do_out(state_type&, 3401227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3402227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3403227825Stheraven{ 3404227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3405227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3406227825Stheraven const uint32_t* _frm_nxt = _frm; 3407227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3408227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3409227825Stheraven uint8_t* _to_nxt = _to; 3410227825Stheraven result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3411227825Stheraven _Maxcode_, _Mode_); 3412227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3413227825Stheraven to_nxt = to + (_to_nxt - _to); 3414227825Stheraven return r; 3415227825Stheraven} 3416227825Stheraven 3417227825Stheraven__codecvt_utf16<wchar_t, false>::result 3418227825Stheraven__codecvt_utf16<wchar_t, false>::do_in(state_type&, 3419227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3420227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3421227825Stheraven{ 3422227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3423227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3424227825Stheraven const uint8_t* _frm_nxt = _frm; 3425227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3426227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3427227825Stheraven uint32_t* _to_nxt = _to; 3428227825Stheraven result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3429227825Stheraven _Maxcode_, _Mode_); 3430227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3431227825Stheraven to_nxt = to + (_to_nxt - _to); 3432227825Stheraven return r; 3433227825Stheraven} 3434227825Stheraven 3435227825Stheraven__codecvt_utf16<wchar_t, false>::result 3436227825Stheraven__codecvt_utf16<wchar_t, false>::do_unshift(state_type&, 3437227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3438227825Stheraven{ 3439227825Stheraven to_nxt = to; 3440227825Stheraven return noconv; 3441227825Stheraven} 3442227825Stheraven 3443227825Stheravenint 3444227825Stheraven__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT 3445227825Stheraven{ 3446227825Stheraven return 0; 3447227825Stheraven} 3448227825Stheraven 3449227825Stheravenbool 3450227825Stheraven__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT 3451227825Stheraven{ 3452227825Stheraven return false; 3453227825Stheraven} 3454227825Stheraven 3455227825Stheravenint 3456227825Stheraven__codecvt_utf16<wchar_t, false>::do_length(state_type&, 3457227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3458227825Stheraven{ 3459227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3460227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3461227825Stheraven return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3462227825Stheraven} 3463227825Stheraven 3464227825Stheravenint 3465227825Stheraven__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT 3466227825Stheraven{ 3467227825Stheraven if (_Mode_ & consume_header) 3468227825Stheraven return 6; 3469227825Stheraven return 4; 3470227825Stheraven} 3471227825Stheraven 3472227825Stheraven// __codecvt_utf16<wchar_t, true> 3473227825Stheraven 3474227825Stheraven__codecvt_utf16<wchar_t, true>::result 3475227825Stheraven__codecvt_utf16<wchar_t, true>::do_out(state_type&, 3476227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3477227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3478227825Stheraven{ 3479227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3480227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3481227825Stheraven const uint32_t* _frm_nxt = _frm; 3482227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3483227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3484227825Stheraven uint8_t* _to_nxt = _to; 3485227825Stheraven result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3486227825Stheraven _Maxcode_, _Mode_); 3487227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3488227825Stheraven to_nxt = to + (_to_nxt - _to); 3489227825Stheraven return r; 3490227825Stheraven} 3491227825Stheraven 3492227825Stheraven__codecvt_utf16<wchar_t, true>::result 3493227825Stheraven__codecvt_utf16<wchar_t, true>::do_in(state_type&, 3494227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3495227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3496227825Stheraven{ 3497227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3498227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3499227825Stheraven const uint8_t* _frm_nxt = _frm; 3500227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3501227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3502227825Stheraven uint32_t* _to_nxt = _to; 3503227825Stheraven result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3504227825Stheraven _Maxcode_, _Mode_); 3505227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3506227825Stheraven to_nxt = to + (_to_nxt - _to); 3507227825Stheraven return r; 3508227825Stheraven} 3509227825Stheraven 3510227825Stheraven__codecvt_utf16<wchar_t, true>::result 3511227825Stheraven__codecvt_utf16<wchar_t, true>::do_unshift(state_type&, 3512227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3513227825Stheraven{ 3514227825Stheraven to_nxt = to; 3515227825Stheraven return noconv; 3516227825Stheraven} 3517227825Stheraven 3518227825Stheravenint 3519227825Stheraven__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT 3520227825Stheraven{ 3521227825Stheraven return 0; 3522227825Stheraven} 3523227825Stheraven 3524227825Stheravenbool 3525227825Stheraven__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT 3526227825Stheraven{ 3527227825Stheraven return false; 3528227825Stheraven} 3529227825Stheraven 3530227825Stheravenint 3531227825Stheraven__codecvt_utf16<wchar_t, true>::do_length(state_type&, 3532227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3533227825Stheraven{ 3534227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3535227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3536227825Stheraven return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3537227825Stheraven} 3538227825Stheraven 3539227825Stheravenint 3540227825Stheraven__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT 3541227825Stheraven{ 3542227825Stheraven if (_Mode_ & consume_header) 3543227825Stheraven return 6; 3544227825Stheraven return 4; 3545227825Stheraven} 3546227825Stheraven 3547227825Stheraven// __codecvt_utf16<char16_t, false> 3548227825Stheraven 3549227825Stheraven__codecvt_utf16<char16_t, false>::result 3550227825Stheraven__codecvt_utf16<char16_t, false>::do_out(state_type&, 3551227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3552227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3553227825Stheraven{ 3554227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3555227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3556227825Stheraven const uint16_t* _frm_nxt = _frm; 3557227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3558227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3559227825Stheraven uint8_t* _to_nxt = _to; 3560227825Stheraven result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3561227825Stheraven _Maxcode_, _Mode_); 3562227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3563227825Stheraven to_nxt = to + (_to_nxt - _to); 3564227825Stheraven return r; 3565227825Stheraven} 3566227825Stheraven 3567227825Stheraven__codecvt_utf16<char16_t, false>::result 3568227825Stheraven__codecvt_utf16<char16_t, false>::do_in(state_type&, 3569227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3570227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3571227825Stheraven{ 3572227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3573227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3574227825Stheraven const uint8_t* _frm_nxt = _frm; 3575227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3576227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3577227825Stheraven uint16_t* _to_nxt = _to; 3578227825Stheraven result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3579227825Stheraven _Maxcode_, _Mode_); 3580227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3581227825Stheraven to_nxt = to + (_to_nxt - _to); 3582227825Stheraven return r; 3583227825Stheraven} 3584227825Stheraven 3585227825Stheraven__codecvt_utf16<char16_t, false>::result 3586227825Stheraven__codecvt_utf16<char16_t, false>::do_unshift(state_type&, 3587227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3588227825Stheraven{ 3589227825Stheraven to_nxt = to; 3590227825Stheraven return noconv; 3591227825Stheraven} 3592227825Stheraven 3593227825Stheravenint 3594227825Stheraven__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT 3595227825Stheraven{ 3596227825Stheraven return 0; 3597227825Stheraven} 3598227825Stheraven 3599227825Stheravenbool 3600227825Stheraven__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT 3601227825Stheraven{ 3602227825Stheraven return false; 3603227825Stheraven} 3604227825Stheraven 3605227825Stheravenint 3606227825Stheraven__codecvt_utf16<char16_t, false>::do_length(state_type&, 3607227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3608227825Stheraven{ 3609227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3610227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3611227825Stheraven return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3612227825Stheraven} 3613227825Stheraven 3614227825Stheravenint 3615227825Stheraven__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT 3616227825Stheraven{ 3617227825Stheraven if (_Mode_ & consume_header) 3618227825Stheraven return 4; 3619227825Stheraven return 2; 3620227825Stheraven} 3621227825Stheraven 3622227825Stheraven// __codecvt_utf16<char16_t, true> 3623227825Stheraven 3624227825Stheraven__codecvt_utf16<char16_t, true>::result 3625227825Stheraven__codecvt_utf16<char16_t, true>::do_out(state_type&, 3626227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3627227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3628227825Stheraven{ 3629227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3630227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3631227825Stheraven const uint16_t* _frm_nxt = _frm; 3632227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3633227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3634227825Stheraven uint8_t* _to_nxt = _to; 3635227825Stheraven result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3636227825Stheraven _Maxcode_, _Mode_); 3637227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3638227825Stheraven to_nxt = to + (_to_nxt - _to); 3639227825Stheraven return r; 3640227825Stheraven} 3641227825Stheraven 3642227825Stheraven__codecvt_utf16<char16_t, true>::result 3643227825Stheraven__codecvt_utf16<char16_t, true>::do_in(state_type&, 3644227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3645227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3646227825Stheraven{ 3647227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3648227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3649227825Stheraven const uint8_t* _frm_nxt = _frm; 3650227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3651227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3652227825Stheraven uint16_t* _to_nxt = _to; 3653227825Stheraven result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3654227825Stheraven _Maxcode_, _Mode_); 3655227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3656227825Stheraven to_nxt = to + (_to_nxt - _to); 3657227825Stheraven return r; 3658227825Stheraven} 3659227825Stheraven 3660227825Stheraven__codecvt_utf16<char16_t, true>::result 3661227825Stheraven__codecvt_utf16<char16_t, true>::do_unshift(state_type&, 3662227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3663227825Stheraven{ 3664227825Stheraven to_nxt = to; 3665227825Stheraven return noconv; 3666227825Stheraven} 3667227825Stheraven 3668227825Stheravenint 3669227825Stheraven__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT 3670227825Stheraven{ 3671227825Stheraven return 0; 3672227825Stheraven} 3673227825Stheraven 3674227825Stheravenbool 3675227825Stheraven__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT 3676227825Stheraven{ 3677227825Stheraven return false; 3678227825Stheraven} 3679227825Stheraven 3680227825Stheravenint 3681227825Stheraven__codecvt_utf16<char16_t, true>::do_length(state_type&, 3682227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3683227825Stheraven{ 3684227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3685227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3686227825Stheraven return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3687227825Stheraven} 3688227825Stheraven 3689227825Stheravenint 3690227825Stheraven__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT 3691227825Stheraven{ 3692227825Stheraven if (_Mode_ & consume_header) 3693227825Stheraven return 4; 3694227825Stheraven return 2; 3695227825Stheraven} 3696227825Stheraven 3697227825Stheraven// __codecvt_utf16<char32_t, false> 3698227825Stheraven 3699227825Stheraven__codecvt_utf16<char32_t, false>::result 3700227825Stheraven__codecvt_utf16<char32_t, false>::do_out(state_type&, 3701227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3702227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3703227825Stheraven{ 3704227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3705227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3706227825Stheraven const uint32_t* _frm_nxt = _frm; 3707227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3708227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3709227825Stheraven uint8_t* _to_nxt = _to; 3710227825Stheraven result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3711227825Stheraven _Maxcode_, _Mode_); 3712227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3713227825Stheraven to_nxt = to + (_to_nxt - _to); 3714227825Stheraven return r; 3715227825Stheraven} 3716227825Stheraven 3717227825Stheraven__codecvt_utf16<char32_t, false>::result 3718227825Stheraven__codecvt_utf16<char32_t, false>::do_in(state_type&, 3719227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3720227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3721227825Stheraven{ 3722227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3723227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3724227825Stheraven const uint8_t* _frm_nxt = _frm; 3725227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3726227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3727227825Stheraven uint32_t* _to_nxt = _to; 3728227825Stheraven result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3729227825Stheraven _Maxcode_, _Mode_); 3730227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3731227825Stheraven to_nxt = to + (_to_nxt - _to); 3732227825Stheraven return r; 3733227825Stheraven} 3734227825Stheraven 3735227825Stheraven__codecvt_utf16<char32_t, false>::result 3736227825Stheraven__codecvt_utf16<char32_t, false>::do_unshift(state_type&, 3737227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3738227825Stheraven{ 3739227825Stheraven to_nxt = to; 3740227825Stheraven return noconv; 3741227825Stheraven} 3742227825Stheraven 3743227825Stheravenint 3744227825Stheraven__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT 3745227825Stheraven{ 3746227825Stheraven return 0; 3747227825Stheraven} 3748227825Stheraven 3749227825Stheravenbool 3750227825Stheraven__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT 3751227825Stheraven{ 3752227825Stheraven return false; 3753227825Stheraven} 3754227825Stheraven 3755227825Stheravenint 3756227825Stheraven__codecvt_utf16<char32_t, false>::do_length(state_type&, 3757227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3758227825Stheraven{ 3759227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3760227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3761227825Stheraven return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3762227825Stheraven} 3763227825Stheraven 3764227825Stheravenint 3765227825Stheraven__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT 3766227825Stheraven{ 3767227825Stheraven if (_Mode_ & consume_header) 3768227825Stheraven return 6; 3769227825Stheraven return 4; 3770227825Stheraven} 3771227825Stheraven 3772227825Stheraven// __codecvt_utf16<char32_t, true> 3773227825Stheraven 3774227825Stheraven__codecvt_utf16<char32_t, true>::result 3775227825Stheraven__codecvt_utf16<char32_t, true>::do_out(state_type&, 3776227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3777227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3778227825Stheraven{ 3779227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3780227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3781227825Stheraven const uint32_t* _frm_nxt = _frm; 3782227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3783227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3784227825Stheraven uint8_t* _to_nxt = _to; 3785227825Stheraven result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3786227825Stheraven _Maxcode_, _Mode_); 3787227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3788227825Stheraven to_nxt = to + (_to_nxt - _to); 3789227825Stheraven return r; 3790227825Stheraven} 3791227825Stheraven 3792227825Stheraven__codecvt_utf16<char32_t, true>::result 3793227825Stheraven__codecvt_utf16<char32_t, true>::do_in(state_type&, 3794227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3795227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3796227825Stheraven{ 3797227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3798227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3799227825Stheraven const uint8_t* _frm_nxt = _frm; 3800227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3801227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3802227825Stheraven uint32_t* _to_nxt = _to; 3803227825Stheraven result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3804227825Stheraven _Maxcode_, _Mode_); 3805227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3806227825Stheraven to_nxt = to + (_to_nxt - _to); 3807227825Stheraven return r; 3808227825Stheraven} 3809227825Stheraven 3810227825Stheraven__codecvt_utf16<char32_t, true>::result 3811227825Stheraven__codecvt_utf16<char32_t, true>::do_unshift(state_type&, 3812227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3813227825Stheraven{ 3814227825Stheraven to_nxt = to; 3815227825Stheraven return noconv; 3816227825Stheraven} 3817227825Stheraven 3818227825Stheravenint 3819227825Stheraven__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT 3820227825Stheraven{ 3821227825Stheraven return 0; 3822227825Stheraven} 3823227825Stheraven 3824227825Stheravenbool 3825227825Stheraven__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT 3826227825Stheraven{ 3827227825Stheraven return false; 3828227825Stheraven} 3829227825Stheraven 3830227825Stheravenint 3831227825Stheraven__codecvt_utf16<char32_t, true>::do_length(state_type&, 3832227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3833227825Stheraven{ 3834227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3835227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3836227825Stheraven return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3837227825Stheraven} 3838227825Stheraven 3839227825Stheravenint 3840227825Stheraven__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT 3841227825Stheraven{ 3842227825Stheraven if (_Mode_ & consume_header) 3843227825Stheraven return 6; 3844227825Stheraven return 4; 3845227825Stheraven} 3846227825Stheraven 3847227825Stheraven// __codecvt_utf8_utf16<wchar_t> 3848227825Stheraven 3849227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3850227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_out(state_type&, 3851227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3852227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3853227825Stheraven{ 3854227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3855227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3856227825Stheraven const uint32_t* _frm_nxt = _frm; 3857227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3858227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3859227825Stheraven uint8_t* _to_nxt = _to; 3860227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3861227825Stheraven _Maxcode_, _Mode_); 3862227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3863227825Stheraven to_nxt = to + (_to_nxt - _to); 3864227825Stheraven return r; 3865227825Stheraven} 3866227825Stheraven 3867227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3868227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_in(state_type&, 3869227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3870227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3871227825Stheraven{ 3872227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3873227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3874227825Stheraven const uint8_t* _frm_nxt = _frm; 3875227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3876227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3877227825Stheraven uint32_t* _to_nxt = _to; 3878227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3879227825Stheraven _Maxcode_, _Mode_); 3880227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3881227825Stheraven to_nxt = to + (_to_nxt - _to); 3882227825Stheraven return r; 3883227825Stheraven} 3884227825Stheraven 3885227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3886227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&, 3887227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3888227825Stheraven{ 3889227825Stheraven to_nxt = to; 3890227825Stheraven return noconv; 3891227825Stheraven} 3892227825Stheraven 3893227825Stheravenint 3894227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT 3895227825Stheraven{ 3896227825Stheraven return 0; 3897227825Stheraven} 3898227825Stheraven 3899227825Stheravenbool 3900227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT 3901227825Stheraven{ 3902227825Stheraven return false; 3903227825Stheraven} 3904227825Stheraven 3905227825Stheravenint 3906227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_length(state_type&, 3907227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3908227825Stheraven{ 3909227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3910227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3911227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3912227825Stheraven} 3913227825Stheraven 3914227825Stheravenint 3915227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT 3916227825Stheraven{ 3917227825Stheraven if (_Mode_ & consume_header) 3918227825Stheraven return 7; 3919227825Stheraven return 4; 3920227825Stheraven} 3921227825Stheraven 3922227825Stheraven// __codecvt_utf8_utf16<char16_t> 3923227825Stheraven 3924227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3925227825Stheraven__codecvt_utf8_utf16<char16_t>::do_out(state_type&, 3926227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3927227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3928227825Stheraven{ 3929227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3930227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3931227825Stheraven const uint16_t* _frm_nxt = _frm; 3932227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3933227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3934227825Stheraven uint8_t* _to_nxt = _to; 3935227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3936227825Stheraven _Maxcode_, _Mode_); 3937227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3938227825Stheraven to_nxt = to + (_to_nxt - _to); 3939227825Stheraven return r; 3940227825Stheraven} 3941227825Stheraven 3942227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3943227825Stheraven__codecvt_utf8_utf16<char16_t>::do_in(state_type&, 3944227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3945227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3946227825Stheraven{ 3947227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3948227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3949227825Stheraven const uint8_t* _frm_nxt = _frm; 3950227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3951227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3952227825Stheraven uint16_t* _to_nxt = _to; 3953227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3954227825Stheraven _Maxcode_, _Mode_); 3955227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3956227825Stheraven to_nxt = to + (_to_nxt - _to); 3957227825Stheraven return r; 3958227825Stheraven} 3959227825Stheraven 3960227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3961227825Stheraven__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&, 3962227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3963227825Stheraven{ 3964227825Stheraven to_nxt = to; 3965227825Stheraven return noconv; 3966227825Stheraven} 3967227825Stheraven 3968227825Stheravenint 3969227825Stheraven__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT 3970227825Stheraven{ 3971227825Stheraven return 0; 3972227825Stheraven} 3973227825Stheraven 3974227825Stheravenbool 3975227825Stheraven__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT 3976227825Stheraven{ 3977227825Stheraven return false; 3978227825Stheraven} 3979227825Stheraven 3980227825Stheravenint 3981227825Stheraven__codecvt_utf8_utf16<char16_t>::do_length(state_type&, 3982227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3983227825Stheraven{ 3984227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3985227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3986227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3987227825Stheraven} 3988227825Stheraven 3989227825Stheravenint 3990227825Stheraven__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT 3991227825Stheraven{ 3992227825Stheraven if (_Mode_ & consume_header) 3993227825Stheraven return 7; 3994227825Stheraven return 4; 3995227825Stheraven} 3996227825Stheraven 3997227825Stheraven// __codecvt_utf8_utf16<char32_t> 3998227825Stheraven 3999227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4000227825Stheraven__codecvt_utf8_utf16<char32_t>::do_out(state_type&, 4001227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 4002227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 4003227825Stheraven{ 4004227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 4005227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 4006227825Stheraven const uint32_t* _frm_nxt = _frm; 4007227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 4008227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 4009227825Stheraven uint8_t* _to_nxt = _to; 4010227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4011227825Stheraven _Maxcode_, _Mode_); 4012227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4013227825Stheraven to_nxt = to + (_to_nxt - _to); 4014227825Stheraven return r; 4015227825Stheraven} 4016227825Stheraven 4017227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4018227825Stheraven__codecvt_utf8_utf16<char32_t>::do_in(state_type&, 4019227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 4020227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 4021227825Stheraven{ 4022227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4023227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4024227825Stheraven const uint8_t* _frm_nxt = _frm; 4025227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 4026227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 4027227825Stheraven uint32_t* _to_nxt = _to; 4028227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4029227825Stheraven _Maxcode_, _Mode_); 4030227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4031227825Stheraven to_nxt = to + (_to_nxt - _to); 4032227825Stheraven return r; 4033227825Stheraven} 4034227825Stheraven 4035227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4036227825Stheraven__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&, 4037227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 4038227825Stheraven{ 4039227825Stheraven to_nxt = to; 4040227825Stheraven return noconv; 4041227825Stheraven} 4042227825Stheraven 4043227825Stheravenint 4044227825Stheraven__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT 4045227825Stheraven{ 4046227825Stheraven return 0; 4047227825Stheraven} 4048227825Stheraven 4049227825Stheravenbool 4050227825Stheraven__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT 4051227825Stheraven{ 4052227825Stheraven return false; 4053227825Stheraven} 4054227825Stheraven 4055227825Stheravenint 4056227825Stheraven__codecvt_utf8_utf16<char32_t>::do_length(state_type&, 4057227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 4058227825Stheraven{ 4059227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4060227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4061227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 4062227825Stheraven} 4063227825Stheraven 4064227825Stheravenint 4065227825Stheraven__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT 4066227825Stheraven{ 4067227825Stheraven if (_Mode_ & consume_header) 4068227825Stheraven return 7; 4069227825Stheraven return 4; 4070227825Stheraven} 4071227825Stheraven 4072227825Stheraven// __narrow_to_utf8<16> 4073227825Stheraven 4074227825Stheraven__narrow_to_utf8<16>::~__narrow_to_utf8() 4075227825Stheraven{ 4076227825Stheraven} 4077227825Stheraven 4078227825Stheraven// __narrow_to_utf8<32> 4079227825Stheraven 4080227825Stheraven__narrow_to_utf8<32>::~__narrow_to_utf8() 4081227825Stheraven{ 4082227825Stheraven} 4083227825Stheraven 4084227825Stheraven// __widen_from_utf8<16> 4085227825Stheraven 4086227825Stheraven__widen_from_utf8<16>::~__widen_from_utf8() 4087227825Stheraven{ 4088227825Stheraven} 4089227825Stheraven 4090227825Stheraven// __widen_from_utf8<32> 4091227825Stheraven 4092227825Stheraven__widen_from_utf8<32>::~__widen_from_utf8() 4093227825Stheraven{ 4094227825Stheraven} 4095227825Stheraven 4096227825Stheraven// numpunct<char> && numpunct<wchar_t> 4097227825Stheraven 4098227825Stheravenlocale::id numpunct< char >::id; 4099227825Stheravenlocale::id numpunct<wchar_t>::id; 4100227825Stheraven 4101227825Stheravennumpunct<char>::numpunct(size_t refs) 4102227825Stheraven : locale::facet(refs), 4103227825Stheraven __decimal_point_('.'), 4104227825Stheraven __thousands_sep_(',') 4105227825Stheraven{ 4106227825Stheraven} 4107227825Stheraven 4108227825Stheravennumpunct<wchar_t>::numpunct(size_t refs) 4109227825Stheraven : locale::facet(refs), 4110227825Stheraven __decimal_point_(L'.'), 4111227825Stheraven __thousands_sep_(L',') 4112227825Stheraven{ 4113227825Stheraven} 4114227825Stheraven 4115227825Stheravennumpunct<char>::~numpunct() 4116227825Stheraven{ 4117227825Stheraven} 4118227825Stheraven 4119227825Stheravennumpunct<wchar_t>::~numpunct() 4120227825Stheraven{ 4121227825Stheraven} 4122227825Stheraven 4123227825Stheraven char numpunct< char >::do_decimal_point() const {return __decimal_point_;} 4124227825Stheravenwchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;} 4125227825Stheraven 4126227825Stheraven char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;} 4127227825Stheravenwchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;} 4128227825Stheraven 4129227825Stheravenstring numpunct< char >::do_grouping() const {return __grouping_;} 4130227825Stheravenstring numpunct<wchar_t>::do_grouping() const {return __grouping_;} 4131227825Stheraven 4132227825Stheraven string numpunct< char >::do_truename() const {return "true";} 4133227825Stheravenwstring numpunct<wchar_t>::do_truename() const {return L"true";} 4134227825Stheraven 4135227825Stheraven string numpunct< char >::do_falsename() const {return "false";} 4136227825Stheravenwstring numpunct<wchar_t>::do_falsename() const {return L"false";} 4137227825Stheraven 4138227825Stheraven// numpunct_byname<char> 4139227825Stheraven 4140227825Stheravennumpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) 4141227825Stheraven : numpunct<char>(refs) 4142227825Stheraven{ 4143227825Stheraven __init(nm); 4144227825Stheraven} 4145227825Stheraven 4146227825Stheravennumpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) 4147227825Stheraven : numpunct<char>(refs) 4148227825Stheraven{ 4149227825Stheraven __init(nm.c_str()); 4150227825Stheraven} 4151227825Stheraven 4152227825Stheravennumpunct_byname<char>::~numpunct_byname() 4153227825Stheraven{ 4154227825Stheraven} 4155227825Stheraven 4156227825Stheravenvoid 4157227825Stheravennumpunct_byname<char>::__init(const char* nm) 4158227825Stheraven{ 4159227825Stheraven if (strcmp(nm, "C") != 0) 4160227825Stheraven { 4161227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 4162227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4163232950Stheraven if (loc == nullptr) 4164227825Stheraven throw runtime_error("numpunct_byname<char>::numpunct_byname" 4165227825Stheraven " failed to construct for " + string(nm)); 4166227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4167227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4168227825Stheraven lconv* lc = localeconv_l(loc.get()); 4169227825Stheraven#else 4170227825Stheraven lconv* lc = __localeconv_l(loc.get()); 4171227825Stheraven#endif 4172227825Stheraven if (*lc->decimal_point) 4173227825Stheraven __decimal_point_ = *lc->decimal_point; 4174227825Stheraven if (*lc->thousands_sep) 4175227825Stheraven __thousands_sep_ = *lc->thousands_sep; 4176227825Stheraven __grouping_ = lc->grouping; 4177227825Stheraven // localization for truename and falsename is not available 4178227825Stheraven } 4179227825Stheraven} 4180227825Stheraven 4181227825Stheraven// numpunct_byname<wchar_t> 4182227825Stheraven 4183227825Stheravennumpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) 4184227825Stheraven : numpunct<wchar_t>(refs) 4185227825Stheraven{ 4186227825Stheraven __init(nm); 4187227825Stheraven} 4188227825Stheraven 4189227825Stheravennumpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) 4190227825Stheraven : numpunct<wchar_t>(refs) 4191227825Stheraven{ 4192227825Stheraven __init(nm.c_str()); 4193227825Stheraven} 4194227825Stheraven 4195227825Stheravennumpunct_byname<wchar_t>::~numpunct_byname() 4196227825Stheraven{ 4197227825Stheraven} 4198227825Stheraven 4199227825Stheravenvoid 4200227825Stheravennumpunct_byname<wchar_t>::__init(const char* nm) 4201227825Stheraven{ 4202227825Stheraven if (strcmp(nm, "C") != 0) 4203227825Stheraven { 4204227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 4205227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4206232950Stheraven if (loc == nullptr) 4207227825Stheraven throw runtime_error("numpunct_byname<char>::numpunct_byname" 4208227825Stheraven " failed to construct for " + string(nm)); 4209227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4210227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4211227825Stheraven lconv* lc = localeconv_l(loc.get()); 4212227825Stheraven#else 4213227825Stheraven lconv* lc = __localeconv_l(loc.get()); 4214227825Stheraven#endif 4215227825Stheraven if (*lc->decimal_point) 4216227825Stheraven __decimal_point_ = *lc->decimal_point; 4217227825Stheraven if (*lc->thousands_sep) 4218227825Stheraven __thousands_sep_ = *lc->thousands_sep; 4219227825Stheraven __grouping_ = lc->grouping; 4220227825Stheraven // locallization for truename and falsename is not available 4221227825Stheraven } 4222227825Stheraven} 4223227825Stheraven 4224227825Stheraven// num_get helpers 4225227825Stheraven 4226227825Stheravenint 4227227825Stheraven__num_get_base::__get_base(ios_base& iob) 4228227825Stheraven{ 4229227825Stheraven ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield; 4230227825Stheraven if (__basefield == ios_base::oct) 4231227825Stheraven return 8; 4232227825Stheraven else if (__basefield == ios_base::hex) 4233227825Stheraven return 16; 4234227825Stheraven else if (__basefield == 0) 4235227825Stheraven return 0; 4236227825Stheraven return 10; 4237227825Stheraven} 4238227825Stheraven 4239227825Stheravenconst char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN"; 4240227825Stheraven 4241227825Stheravenvoid 4242227825Stheraven__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 4243227825Stheraven ios_base::iostate& __err) 4244227825Stheraven{ 4245227825Stheraven if (__grouping.size() != 0) 4246227825Stheraven { 4247227825Stheraven reverse(__g, __g_end); 4248227825Stheraven const char* __ig = __grouping.data(); 4249227825Stheraven const char* __eg = __ig + __grouping.size(); 4250227825Stheraven for (unsigned* __r = __g; __r < __g_end-1; ++__r) 4251227825Stheraven { 4252227825Stheraven if (0 < *__ig && *__ig < numeric_limits<char>::max()) 4253227825Stheraven { 4254232950Stheraven if (static_cast<unsigned>(*__ig) != *__r) 4255227825Stheraven { 4256227825Stheraven __err = ios_base::failbit; 4257227825Stheraven return; 4258227825Stheraven } 4259227825Stheraven } 4260227825Stheraven if (__eg - __ig > 1) 4261227825Stheraven ++__ig; 4262227825Stheraven } 4263227825Stheraven if (0 < *__ig && *__ig < numeric_limits<char>::max()) 4264227825Stheraven { 4265232950Stheraven if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0) 4266227825Stheraven __err = ios_base::failbit; 4267227825Stheraven } 4268227825Stheraven } 4269227825Stheraven} 4270227825Stheraven 4271227825Stheravenvoid 4272227825Stheraven__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, 4273227825Stheraven ios_base::fmtflags __flags) 4274227825Stheraven{ 4275227825Stheraven if (__flags & ios_base::showpos) 4276227825Stheraven *__fmtp++ = '+'; 4277227825Stheraven if (__flags & ios_base::showbase) 4278227825Stheraven *__fmtp++ = '#'; 4279227825Stheraven while(*__len) 4280227825Stheraven *__fmtp++ = *__len++; 4281227825Stheraven if ((__flags & ios_base::basefield) == ios_base::oct) 4282227825Stheraven *__fmtp = 'o'; 4283227825Stheraven else if ((__flags & ios_base::basefield) == ios_base::hex) 4284227825Stheraven { 4285227825Stheraven if (__flags & ios_base::uppercase) 4286227825Stheraven *__fmtp = 'X'; 4287227825Stheraven else 4288227825Stheraven *__fmtp = 'x'; 4289227825Stheraven } 4290227825Stheraven else if (__signd) 4291227825Stheraven *__fmtp = 'd'; 4292227825Stheraven else 4293227825Stheraven *__fmtp = 'u'; 4294227825Stheraven} 4295227825Stheraven 4296227825Stheravenbool 4297227825Stheraven__num_put_base::__format_float(char* __fmtp, const char* __len, 4298227825Stheraven ios_base::fmtflags __flags) 4299227825Stheraven{ 4300227825Stheraven bool specify_precision = true; 4301227825Stheraven if (__flags & ios_base::showpos) 4302227825Stheraven *__fmtp++ = '+'; 4303227825Stheraven if (__flags & ios_base::showpoint) 4304227825Stheraven *__fmtp++ = '#'; 4305227825Stheraven ios_base::fmtflags floatfield = __flags & ios_base::floatfield; 4306227825Stheraven bool uppercase = __flags & ios_base::uppercase; 4307227825Stheraven if (floatfield == (ios_base::fixed | ios_base::scientific)) 4308227825Stheraven specify_precision = false; 4309227825Stheraven else 4310227825Stheraven { 4311227825Stheraven *__fmtp++ = '.'; 4312227825Stheraven *__fmtp++ = '*'; 4313227825Stheraven } 4314227825Stheraven while(*__len) 4315227825Stheraven *__fmtp++ = *__len++; 4316227825Stheraven if (floatfield == ios_base::fixed) 4317227825Stheraven { 4318227825Stheraven if (uppercase) 4319227825Stheraven *__fmtp = 'F'; 4320227825Stheraven else 4321227825Stheraven *__fmtp = 'f'; 4322227825Stheraven } 4323227825Stheraven else if (floatfield == ios_base::scientific) 4324227825Stheraven { 4325227825Stheraven if (uppercase) 4326227825Stheraven *__fmtp = 'E'; 4327227825Stheraven else 4328227825Stheraven *__fmtp = 'e'; 4329227825Stheraven } 4330227825Stheraven else if (floatfield == (ios_base::fixed | ios_base::scientific)) 4331227825Stheraven { 4332227825Stheraven if (uppercase) 4333227825Stheraven *__fmtp = 'A'; 4334227825Stheraven else 4335227825Stheraven *__fmtp = 'a'; 4336227825Stheraven } 4337227825Stheraven else 4338227825Stheraven { 4339227825Stheraven if (uppercase) 4340227825Stheraven *__fmtp = 'G'; 4341227825Stheraven else 4342227825Stheraven *__fmtp = 'g'; 4343227825Stheraven } 4344227825Stheraven return specify_precision; 4345227825Stheraven} 4346227825Stheraven 4347227825Stheravenchar* 4348227825Stheraven__num_put_base::__identify_padding(char* __nb, char* __ne, 4349227825Stheraven const ios_base& __iob) 4350227825Stheraven{ 4351227825Stheraven switch (__iob.flags() & ios_base::adjustfield) 4352227825Stheraven { 4353227825Stheraven case ios_base::internal: 4354227825Stheraven if (__nb[0] == '-' || __nb[0] == '+') 4355227825Stheraven return __nb+1; 4356227825Stheraven if (__ne - __nb >= 2 && __nb[0] == '0' 4357227825Stheraven && (__nb[1] == 'x' || __nb[1] == 'X')) 4358227825Stheraven return __nb+2; 4359227825Stheraven break; 4360227825Stheraven case ios_base::left: 4361227825Stheraven return __ne; 4362227825Stheraven case ios_base::right: 4363227825Stheraven default: 4364227825Stheraven break; 4365227825Stheraven } 4366227825Stheraven return __nb; 4367227825Stheraven} 4368227825Stheraven 4369227825Stheraven// time_get 4370227825Stheraven 4371227825Stheravenstatic 4372227825Stheravenstring* 4373227825Stheraveninit_weeks() 4374227825Stheraven{ 4375227825Stheraven static string weeks[14]; 4376227825Stheraven weeks[0] = "Sunday"; 4377227825Stheraven weeks[1] = "Monday"; 4378227825Stheraven weeks[2] = "Tuesday"; 4379227825Stheraven weeks[3] = "Wednesday"; 4380227825Stheraven weeks[4] = "Thursday"; 4381227825Stheraven weeks[5] = "Friday"; 4382227825Stheraven weeks[6] = "Saturday"; 4383227825Stheraven weeks[7] = "Sun"; 4384227825Stheraven weeks[8] = "Mon"; 4385227825Stheraven weeks[9] = "Tue"; 4386227825Stheraven weeks[10] = "Wed"; 4387227825Stheraven weeks[11] = "Thu"; 4388227825Stheraven weeks[12] = "Fri"; 4389227825Stheraven weeks[13] = "Sat"; 4390227825Stheraven return weeks; 4391227825Stheraven} 4392227825Stheraven 4393227825Stheravenstatic 4394227825Stheravenwstring* 4395227825Stheraveninit_wweeks() 4396227825Stheraven{ 4397227825Stheraven static wstring weeks[14]; 4398227825Stheraven weeks[0] = L"Sunday"; 4399227825Stheraven weeks[1] = L"Monday"; 4400227825Stheraven weeks[2] = L"Tuesday"; 4401227825Stheraven weeks[3] = L"Wednesday"; 4402227825Stheraven weeks[4] = L"Thursday"; 4403227825Stheraven weeks[5] = L"Friday"; 4404227825Stheraven weeks[6] = L"Saturday"; 4405227825Stheraven weeks[7] = L"Sun"; 4406227825Stheraven weeks[8] = L"Mon"; 4407227825Stheraven weeks[9] = L"Tue"; 4408227825Stheraven weeks[10] = L"Wed"; 4409227825Stheraven weeks[11] = L"Thu"; 4410227825Stheraven weeks[12] = L"Fri"; 4411227825Stheraven weeks[13] = L"Sat"; 4412227825Stheraven return weeks; 4413227825Stheraven} 4414227825Stheraven 4415227825Stheraventemplate <> 4416227825Stheravenconst string* 4417227825Stheraven__time_get_c_storage<char>::__weeks() const 4418227825Stheraven{ 4419227825Stheraven static const string* weeks = init_weeks(); 4420227825Stheraven return weeks; 4421227825Stheraven} 4422227825Stheraven 4423227825Stheraventemplate <> 4424227825Stheravenconst wstring* 4425227825Stheraven__time_get_c_storage<wchar_t>::__weeks() const 4426227825Stheraven{ 4427227825Stheraven static const wstring* weeks = init_wweeks(); 4428227825Stheraven return weeks; 4429227825Stheraven} 4430227825Stheraven 4431227825Stheravenstatic 4432227825Stheravenstring* 4433227825Stheraveninit_months() 4434227825Stheraven{ 4435227825Stheraven static string months[24]; 4436227825Stheraven months[0] = "January"; 4437227825Stheraven months[1] = "February"; 4438227825Stheraven months[2] = "March"; 4439227825Stheraven months[3] = "April"; 4440227825Stheraven months[4] = "May"; 4441227825Stheraven months[5] = "June"; 4442227825Stheraven months[6] = "July"; 4443227825Stheraven months[7] = "August"; 4444227825Stheraven months[8] = "September"; 4445227825Stheraven months[9] = "October"; 4446227825Stheraven months[10] = "November"; 4447227825Stheraven months[11] = "December"; 4448227825Stheraven months[12] = "Jan"; 4449227825Stheraven months[13] = "Feb"; 4450227825Stheraven months[14] = "Mar"; 4451227825Stheraven months[15] = "Apr"; 4452227825Stheraven months[16] = "May"; 4453227825Stheraven months[17] = "Jun"; 4454227825Stheraven months[18] = "Jul"; 4455227825Stheraven months[19] = "Aug"; 4456227825Stheraven months[20] = "Sep"; 4457227825Stheraven months[21] = "Oct"; 4458227825Stheraven months[22] = "Nov"; 4459227825Stheraven months[23] = "Dec"; 4460227825Stheraven return months; 4461227825Stheraven} 4462227825Stheraven 4463227825Stheravenstatic 4464227825Stheravenwstring* 4465227825Stheraveninit_wmonths() 4466227825Stheraven{ 4467227825Stheraven static wstring months[24]; 4468227825Stheraven months[0] = L"January"; 4469227825Stheraven months[1] = L"February"; 4470227825Stheraven months[2] = L"March"; 4471227825Stheraven months[3] = L"April"; 4472227825Stheraven months[4] = L"May"; 4473227825Stheraven months[5] = L"June"; 4474227825Stheraven months[6] = L"July"; 4475227825Stheraven months[7] = L"August"; 4476227825Stheraven months[8] = L"September"; 4477227825Stheraven months[9] = L"October"; 4478227825Stheraven months[10] = L"November"; 4479227825Stheraven months[11] = L"December"; 4480227825Stheraven months[12] = L"Jan"; 4481227825Stheraven months[13] = L"Feb"; 4482227825Stheraven months[14] = L"Mar"; 4483227825Stheraven months[15] = L"Apr"; 4484227825Stheraven months[16] = L"May"; 4485227825Stheraven months[17] = L"Jun"; 4486227825Stheraven months[18] = L"Jul"; 4487227825Stheraven months[19] = L"Aug"; 4488227825Stheraven months[20] = L"Sep"; 4489227825Stheraven months[21] = L"Oct"; 4490227825Stheraven months[22] = L"Nov"; 4491227825Stheraven months[23] = L"Dec"; 4492227825Stheraven return months; 4493227825Stheraven} 4494227825Stheraven 4495227825Stheraventemplate <> 4496227825Stheravenconst string* 4497227825Stheraven__time_get_c_storage<char>::__months() const 4498227825Stheraven{ 4499227825Stheraven static const string* months = init_months(); 4500227825Stheraven return months; 4501227825Stheraven} 4502227825Stheraven 4503227825Stheraventemplate <> 4504227825Stheravenconst wstring* 4505227825Stheraven__time_get_c_storage<wchar_t>::__months() const 4506227825Stheraven{ 4507227825Stheraven static const wstring* months = init_wmonths(); 4508227825Stheraven return months; 4509227825Stheraven} 4510227825Stheraven 4511227825Stheravenstatic 4512227825Stheravenstring* 4513227825Stheraveninit_am_pm() 4514227825Stheraven{ 4515227825Stheraven static string am_pm[24]; 4516227825Stheraven am_pm[0] = "AM"; 4517227825Stheraven am_pm[1] = "PM"; 4518227825Stheraven return am_pm; 4519227825Stheraven} 4520227825Stheraven 4521227825Stheravenstatic 4522227825Stheravenwstring* 4523227825Stheraveninit_wam_pm() 4524227825Stheraven{ 4525227825Stheraven static wstring am_pm[24]; 4526227825Stheraven am_pm[0] = L"AM"; 4527227825Stheraven am_pm[1] = L"PM"; 4528227825Stheraven return am_pm; 4529227825Stheraven} 4530227825Stheraven 4531227825Stheraventemplate <> 4532227825Stheravenconst string* 4533227825Stheraven__time_get_c_storage<char>::__am_pm() const 4534227825Stheraven{ 4535227825Stheraven static const string* am_pm = init_am_pm(); 4536227825Stheraven return am_pm; 4537227825Stheraven} 4538227825Stheraven 4539227825Stheraventemplate <> 4540227825Stheravenconst wstring* 4541227825Stheraven__time_get_c_storage<wchar_t>::__am_pm() const 4542227825Stheraven{ 4543227825Stheraven static const wstring* am_pm = init_wam_pm(); 4544227825Stheraven return am_pm; 4545227825Stheraven} 4546227825Stheraven 4547227825Stheraventemplate <> 4548227825Stheravenconst string& 4549227825Stheraven__time_get_c_storage<char>::__x() const 4550227825Stheraven{ 4551227825Stheraven static string s("%m/%d/%y"); 4552227825Stheraven return s; 4553227825Stheraven} 4554227825Stheraven 4555227825Stheraventemplate <> 4556227825Stheravenconst wstring& 4557227825Stheraven__time_get_c_storage<wchar_t>::__x() const 4558227825Stheraven{ 4559227825Stheraven static wstring s(L"%m/%d/%y"); 4560227825Stheraven return s; 4561227825Stheraven} 4562227825Stheraven 4563227825Stheraventemplate <> 4564227825Stheravenconst string& 4565227825Stheraven__time_get_c_storage<char>::__X() const 4566227825Stheraven{ 4567227825Stheraven static string s("%H:%M:%S"); 4568227825Stheraven return s; 4569227825Stheraven} 4570227825Stheraven 4571227825Stheraventemplate <> 4572227825Stheravenconst wstring& 4573227825Stheraven__time_get_c_storage<wchar_t>::__X() const 4574227825Stheraven{ 4575227825Stheraven static wstring s(L"%H:%M:%S"); 4576227825Stheraven return s; 4577227825Stheraven} 4578227825Stheraven 4579227825Stheraventemplate <> 4580227825Stheravenconst string& 4581227825Stheraven__time_get_c_storage<char>::__c() const 4582227825Stheraven{ 4583227825Stheraven static string s("%a %b %d %H:%M:%S %Y"); 4584227825Stheraven return s; 4585227825Stheraven} 4586227825Stheraven 4587227825Stheraventemplate <> 4588227825Stheravenconst wstring& 4589227825Stheraven__time_get_c_storage<wchar_t>::__c() const 4590227825Stheraven{ 4591227825Stheraven static wstring s(L"%a %b %d %H:%M:%S %Y"); 4592227825Stheraven return s; 4593227825Stheraven} 4594227825Stheraven 4595227825Stheraventemplate <> 4596227825Stheravenconst string& 4597227825Stheraven__time_get_c_storage<char>::__r() const 4598227825Stheraven{ 4599227825Stheraven static string s("%I:%M:%S %p"); 4600227825Stheraven return s; 4601227825Stheraven} 4602227825Stheraven 4603227825Stheraventemplate <> 4604227825Stheravenconst wstring& 4605227825Stheraven__time_get_c_storage<wchar_t>::__r() const 4606227825Stheraven{ 4607227825Stheraven static wstring s(L"%I:%M:%S %p"); 4608227825Stheraven return s; 4609227825Stheraven} 4610227825Stheraven 4611227825Stheraven// time_get_byname 4612227825Stheraven 4613227825Stheraven__time_get::__time_get(const char* nm) 4614227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 4615227825Stheraven{ 4616227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4617227825Stheraven if (__loc_ == 0) 4618227825Stheraven throw runtime_error("time_get_byname" 4619227825Stheraven " failed to construct for " + string(nm)); 4620227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4621227825Stheraven} 4622227825Stheraven 4623227825Stheraven__time_get::__time_get(const string& nm) 4624227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 4625227825Stheraven{ 4626227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4627227825Stheraven if (__loc_ == 0) 4628227825Stheraven throw runtime_error("time_get_byname" 4629227825Stheraven " failed to construct for " + nm); 4630227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4631227825Stheraven} 4632227825Stheraven 4633227825Stheraven__time_get::~__time_get() 4634227825Stheraven{ 4635227825Stheraven freelocale(__loc_); 4636227825Stheraven} 4637227825Stheraven 4638232950Stheraven#pragma clang diagnostic ignored "-Wmissing-field-initializers" 4639246487Stheraven#pragma GCC diagnostic ignored "-Wmissing-field-initializers" 4640232950Stheraven 4641227825Stheraventemplate <> 4642227825Stheravenstring 4643227825Stheraven__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) 4644227825Stheraven{ 4645232950Stheraven tm t = {0}; 4646227825Stheraven t.tm_sec = 59; 4647227825Stheraven t.tm_min = 55; 4648227825Stheraven t.tm_hour = 23; 4649227825Stheraven t.tm_mday = 31; 4650227825Stheraven t.tm_mon = 11; 4651227825Stheraven t.tm_year = 161; 4652227825Stheraven t.tm_wday = 6; 4653227825Stheraven t.tm_yday = 364; 4654227825Stheraven t.tm_isdst = -1; 4655227825Stheraven char buf[100]; 4656227825Stheraven char f[3] = {0}; 4657227825Stheraven f[0] = '%'; 4658227825Stheraven f[1] = fmt; 4659246487Stheraven size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); 4660227825Stheraven char* bb = buf; 4661227825Stheraven char* be = buf + n; 4662227825Stheraven string result; 4663227825Stheraven while (bb != be) 4664227825Stheraven { 4665227825Stheraven if (ct.is(ctype_base::space, *bb)) 4666227825Stheraven { 4667227825Stheraven result.push_back(' '); 4668227825Stheraven for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb) 4669227825Stheraven ; 4670227825Stheraven continue; 4671227825Stheraven } 4672227825Stheraven char* w = bb; 4673227825Stheraven ios_base::iostate err = ios_base::goodbit; 4674232950Stheraven ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14, 4675227825Stheraven ct, err, false) 4676227825Stheraven - this->__weeks_; 4677227825Stheraven if (i < 14) 4678227825Stheraven { 4679227825Stheraven result.push_back('%'); 4680227825Stheraven if (i < 7) 4681227825Stheraven result.push_back('A'); 4682227825Stheraven else 4683227825Stheraven result.push_back('a'); 4684227825Stheraven bb = w; 4685227825Stheraven continue; 4686227825Stheraven } 4687227825Stheraven w = bb; 4688227825Stheraven i = __scan_keyword(w, be, this->__months_, this->__months_+24, 4689227825Stheraven ct, err, false) 4690227825Stheraven - this->__months_; 4691227825Stheraven if (i < 24) 4692227825Stheraven { 4693227825Stheraven result.push_back('%'); 4694227825Stheraven if (i < 12) 4695227825Stheraven result.push_back('B'); 4696227825Stheraven else 4697227825Stheraven result.push_back('b'); 4698227825Stheraven if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4699227825Stheraven result.back() = 'm'; 4700227825Stheraven bb = w; 4701227825Stheraven continue; 4702227825Stheraven } 4703227825Stheraven if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4704227825Stheraven { 4705227825Stheraven w = bb; 4706227825Stheraven i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2, 4707227825Stheraven ct, err, false) - this->__am_pm_; 4708227825Stheraven if (i < 2) 4709227825Stheraven { 4710227825Stheraven result.push_back('%'); 4711227825Stheraven result.push_back('p'); 4712227825Stheraven bb = w; 4713227825Stheraven continue; 4714227825Stheraven } 4715227825Stheraven } 4716227825Stheraven w = bb; 4717227825Stheraven if (ct.is(ctype_base::digit, *bb)) 4718227825Stheraven { 4719227825Stheraven switch(__get_up_to_n_digits(bb, be, err, ct, 4)) 4720227825Stheraven { 4721227825Stheraven case 6: 4722227825Stheraven result.push_back('%'); 4723227825Stheraven result.push_back('w'); 4724227825Stheraven break; 4725227825Stheraven case 7: 4726227825Stheraven result.push_back('%'); 4727227825Stheraven result.push_back('u'); 4728227825Stheraven break; 4729227825Stheraven case 11: 4730227825Stheraven result.push_back('%'); 4731227825Stheraven result.push_back('I'); 4732227825Stheraven break; 4733227825Stheraven case 12: 4734227825Stheraven result.push_back('%'); 4735227825Stheraven result.push_back('m'); 4736227825Stheraven break; 4737227825Stheraven case 23: 4738227825Stheraven result.push_back('%'); 4739227825Stheraven result.push_back('H'); 4740227825Stheraven break; 4741227825Stheraven case 31: 4742227825Stheraven result.push_back('%'); 4743227825Stheraven result.push_back('d'); 4744227825Stheraven break; 4745227825Stheraven case 55: 4746227825Stheraven result.push_back('%'); 4747227825Stheraven result.push_back('M'); 4748227825Stheraven break; 4749227825Stheraven case 59: 4750227825Stheraven result.push_back('%'); 4751227825Stheraven result.push_back('S'); 4752227825Stheraven break; 4753227825Stheraven case 61: 4754227825Stheraven result.push_back('%'); 4755227825Stheraven result.push_back('y'); 4756227825Stheraven break; 4757227825Stheraven case 364: 4758227825Stheraven result.push_back('%'); 4759227825Stheraven result.push_back('j'); 4760227825Stheraven break; 4761227825Stheraven case 2061: 4762227825Stheraven result.push_back('%'); 4763227825Stheraven result.push_back('Y'); 4764227825Stheraven break; 4765227825Stheraven default: 4766227825Stheraven for (; w != bb; ++w) 4767227825Stheraven result.push_back(*w); 4768227825Stheraven break; 4769227825Stheraven } 4770227825Stheraven continue; 4771227825Stheraven } 4772227825Stheraven if (*bb == '%') 4773227825Stheraven { 4774227825Stheraven result.push_back('%'); 4775227825Stheraven result.push_back('%'); 4776227825Stheraven ++bb; 4777227825Stheraven continue; 4778227825Stheraven } 4779227825Stheraven result.push_back(*bb); 4780227825Stheraven ++bb; 4781227825Stheraven } 4782227825Stheraven return result; 4783227825Stheraven} 4784227825Stheraven 4785232950Stheraven#pragma clang diagnostic ignored "-Wmissing-braces" 4786232950Stheraven 4787227825Stheraventemplate <> 4788227825Stheravenwstring 4789227825Stheraven__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) 4790227825Stheraven{ 4791232950Stheraven tm t = {0}; 4792227825Stheraven t.tm_sec = 59; 4793227825Stheraven t.tm_min = 55; 4794227825Stheraven t.tm_hour = 23; 4795227825Stheraven t.tm_mday = 31; 4796227825Stheraven t.tm_mon = 11; 4797227825Stheraven t.tm_year = 161; 4798227825Stheraven t.tm_wday = 6; 4799227825Stheraven t.tm_yday = 364; 4800227825Stheraven t.tm_isdst = -1; 4801227825Stheraven char buf[100]; 4802227825Stheraven char f[3] = {0}; 4803227825Stheraven f[0] = '%'; 4804227825Stheraven f[1] = fmt; 4805246487Stheraven strftime_l(buf, countof(buf), f, &t, __loc_); 4806227825Stheraven wchar_t wbuf[100]; 4807227825Stheraven wchar_t* wbb = wbuf; 4808227825Stheraven mbstate_t mb = {0}; 4809227825Stheraven const char* bb = buf; 4810227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4811246487Stheraven size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); 4812227825Stheraven#else 4813246487Stheraven size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); 4814227825Stheraven#endif 4815232950Stheraven if (j == size_t(-1)) 4816227825Stheraven __throw_runtime_error("locale not supported"); 4817232950Stheraven wchar_t* wbe = wbb + j; 4818227825Stheraven wstring result; 4819227825Stheraven while (wbb != wbe) 4820227825Stheraven { 4821227825Stheraven if (ct.is(ctype_base::space, *wbb)) 4822227825Stheraven { 4823227825Stheraven result.push_back(L' '); 4824227825Stheraven for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb) 4825227825Stheraven ; 4826227825Stheraven continue; 4827227825Stheraven } 4828227825Stheraven wchar_t* w = wbb; 4829227825Stheraven ios_base::iostate err = ios_base::goodbit; 4830232950Stheraven ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14, 4831227825Stheraven ct, err, false) 4832227825Stheraven - this->__weeks_; 4833227825Stheraven if (i < 14) 4834227825Stheraven { 4835227825Stheraven result.push_back(L'%'); 4836227825Stheraven if (i < 7) 4837227825Stheraven result.push_back(L'A'); 4838227825Stheraven else 4839227825Stheraven result.push_back(L'a'); 4840227825Stheraven wbb = w; 4841227825Stheraven continue; 4842227825Stheraven } 4843227825Stheraven w = wbb; 4844227825Stheraven i = __scan_keyword(w, wbe, this->__months_, this->__months_+24, 4845227825Stheraven ct, err, false) 4846227825Stheraven - this->__months_; 4847227825Stheraven if (i < 24) 4848227825Stheraven { 4849227825Stheraven result.push_back(L'%'); 4850227825Stheraven if (i < 12) 4851227825Stheraven result.push_back(L'B'); 4852227825Stheraven else 4853227825Stheraven result.push_back(L'b'); 4854227825Stheraven if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4855227825Stheraven result.back() = L'm'; 4856227825Stheraven wbb = w; 4857227825Stheraven continue; 4858227825Stheraven } 4859227825Stheraven if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4860227825Stheraven { 4861227825Stheraven w = wbb; 4862227825Stheraven i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2, 4863227825Stheraven ct, err, false) - this->__am_pm_; 4864227825Stheraven if (i < 2) 4865227825Stheraven { 4866227825Stheraven result.push_back(L'%'); 4867227825Stheraven result.push_back(L'p'); 4868227825Stheraven wbb = w; 4869227825Stheraven continue; 4870227825Stheraven } 4871227825Stheraven } 4872227825Stheraven w = wbb; 4873227825Stheraven if (ct.is(ctype_base::digit, *wbb)) 4874227825Stheraven { 4875227825Stheraven switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4)) 4876227825Stheraven { 4877227825Stheraven case 6: 4878227825Stheraven result.push_back(L'%'); 4879227825Stheraven result.push_back(L'w'); 4880227825Stheraven break; 4881227825Stheraven case 7: 4882227825Stheraven result.push_back(L'%'); 4883227825Stheraven result.push_back(L'u'); 4884227825Stheraven break; 4885227825Stheraven case 11: 4886227825Stheraven result.push_back(L'%'); 4887227825Stheraven result.push_back(L'I'); 4888227825Stheraven break; 4889227825Stheraven case 12: 4890227825Stheraven result.push_back(L'%'); 4891227825Stheraven result.push_back(L'm'); 4892227825Stheraven break; 4893227825Stheraven case 23: 4894227825Stheraven result.push_back(L'%'); 4895227825Stheraven result.push_back(L'H'); 4896227825Stheraven break; 4897227825Stheraven case 31: 4898227825Stheraven result.push_back(L'%'); 4899227825Stheraven result.push_back(L'd'); 4900227825Stheraven break; 4901227825Stheraven case 55: 4902227825Stheraven result.push_back(L'%'); 4903227825Stheraven result.push_back(L'M'); 4904227825Stheraven break; 4905227825Stheraven case 59: 4906227825Stheraven result.push_back(L'%'); 4907227825Stheraven result.push_back(L'S'); 4908227825Stheraven break; 4909227825Stheraven case 61: 4910227825Stheraven result.push_back(L'%'); 4911227825Stheraven result.push_back(L'y'); 4912227825Stheraven break; 4913227825Stheraven case 364: 4914227825Stheraven result.push_back(L'%'); 4915227825Stheraven result.push_back(L'j'); 4916227825Stheraven break; 4917227825Stheraven case 2061: 4918227825Stheraven result.push_back(L'%'); 4919227825Stheraven result.push_back(L'Y'); 4920227825Stheraven break; 4921227825Stheraven default: 4922227825Stheraven for (; w != wbb; ++w) 4923227825Stheraven result.push_back(*w); 4924227825Stheraven break; 4925227825Stheraven } 4926227825Stheraven continue; 4927227825Stheraven } 4928227825Stheraven if (ct.narrow(*wbb, 0) == '%') 4929227825Stheraven { 4930227825Stheraven result.push_back(L'%'); 4931227825Stheraven result.push_back(L'%'); 4932227825Stheraven ++wbb; 4933227825Stheraven continue; 4934227825Stheraven } 4935227825Stheraven result.push_back(*wbb); 4936227825Stheraven ++wbb; 4937227825Stheraven } 4938227825Stheraven return result; 4939227825Stheraven} 4940227825Stheraven 4941227825Stheraventemplate <> 4942227825Stheravenvoid 4943227825Stheraven__time_get_storage<char>::init(const ctype<char>& ct) 4944227825Stheraven{ 4945241903Sdim tm t = {0}; 4946227825Stheraven char buf[100]; 4947227825Stheraven // __weeks_ 4948227825Stheraven for (int i = 0; i < 7; ++i) 4949227825Stheraven { 4950227825Stheraven t.tm_wday = i; 4951246487Stheraven strftime_l(buf, countof(buf), "%A", &t, __loc_); 4952227825Stheraven __weeks_[i] = buf; 4953246487Stheraven strftime_l(buf, countof(buf), "%a", &t, __loc_); 4954227825Stheraven __weeks_[i+7] = buf; 4955227825Stheraven } 4956227825Stheraven // __months_ 4957227825Stheraven for (int i = 0; i < 12; ++i) 4958227825Stheraven { 4959227825Stheraven t.tm_mon = i; 4960246487Stheraven strftime_l(buf, countof(buf), "%B", &t, __loc_); 4961227825Stheraven __months_[i] = buf; 4962246487Stheraven strftime_l(buf, countof(buf), "%b", &t, __loc_); 4963227825Stheraven __months_[i+12] = buf; 4964227825Stheraven } 4965227825Stheraven // __am_pm_ 4966227825Stheraven t.tm_hour = 1; 4967246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 4968227825Stheraven __am_pm_[0] = buf; 4969227825Stheraven t.tm_hour = 13; 4970246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 4971227825Stheraven __am_pm_[1] = buf; 4972227825Stheraven __c_ = __analyze('c', ct); 4973227825Stheraven __r_ = __analyze('r', ct); 4974227825Stheraven __x_ = __analyze('x', ct); 4975227825Stheraven __X_ = __analyze('X', ct); 4976227825Stheraven} 4977227825Stheraven 4978227825Stheraventemplate <> 4979227825Stheravenvoid 4980227825Stheraven__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) 4981227825Stheraven{ 4982227825Stheraven tm t = {0}; 4983227825Stheraven char buf[100]; 4984227825Stheraven wchar_t wbuf[100]; 4985227825Stheraven wchar_t* wbe; 4986227825Stheraven mbstate_t mb = {0}; 4987227825Stheraven // __weeks_ 4988227825Stheraven for (int i = 0; i < 7; ++i) 4989227825Stheraven { 4990227825Stheraven t.tm_wday = i; 4991246487Stheraven strftime_l(buf, countof(buf), "%A", &t, __loc_); 4992227825Stheraven mb = mbstate_t(); 4993227825Stheraven const char* bb = buf; 4994227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4995246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 4996227825Stheraven#else 4997246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 4998227825Stheraven#endif 4999232950Stheraven if (j == size_t(-1)) 5000227825Stheraven __throw_runtime_error("locale not supported"); 5001227825Stheraven wbe = wbuf + j; 5002227825Stheraven __weeks_[i].assign(wbuf, wbe); 5003246487Stheraven strftime_l(buf, countof(buf), "%a", &t, __loc_); 5004227825Stheraven mb = mbstate_t(); 5005227825Stheraven bb = buf; 5006227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5007246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5008227825Stheraven#else 5009246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5010227825Stheraven#endif 5011232950Stheraven if (j == size_t(-1)) 5012227825Stheraven __throw_runtime_error("locale not supported"); 5013227825Stheraven wbe = wbuf + j; 5014227825Stheraven __weeks_[i+7].assign(wbuf, wbe); 5015227825Stheraven } 5016227825Stheraven // __months_ 5017227825Stheraven for (int i = 0; i < 12; ++i) 5018227825Stheraven { 5019227825Stheraven t.tm_mon = i; 5020246487Stheraven strftime_l(buf, countof(buf), "%B", &t, __loc_); 5021227825Stheraven mb = mbstate_t(); 5022227825Stheraven const char* bb = buf; 5023227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5024246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5025227825Stheraven#else 5026246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5027227825Stheraven#endif 5028232950Stheraven if (j == size_t(-1)) 5029227825Stheraven __throw_runtime_error("locale not supported"); 5030227825Stheraven wbe = wbuf + j; 5031227825Stheraven __months_[i].assign(wbuf, wbe); 5032246487Stheraven strftime_l(buf, countof(buf), "%b", &t, __loc_); 5033227825Stheraven mb = mbstate_t(); 5034227825Stheraven bb = buf; 5035227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5036246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5037227825Stheraven#else 5038246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5039227825Stheraven#endif 5040232950Stheraven if (j == size_t(-1)) 5041227825Stheraven __throw_runtime_error("locale not supported"); 5042227825Stheraven wbe = wbuf + j; 5043227825Stheraven __months_[i+12].assign(wbuf, wbe); 5044227825Stheraven } 5045227825Stheraven // __am_pm_ 5046227825Stheraven t.tm_hour = 1; 5047246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5048227825Stheraven mb = mbstate_t(); 5049227825Stheraven const char* bb = buf; 5050227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5051246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5052227825Stheraven#else 5053246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5054227825Stheraven#endif 5055232950Stheraven if (j == size_t(-1)) 5056227825Stheraven __throw_runtime_error("locale not supported"); 5057227825Stheraven wbe = wbuf + j; 5058227825Stheraven __am_pm_[0].assign(wbuf, wbe); 5059227825Stheraven t.tm_hour = 13; 5060246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5061227825Stheraven mb = mbstate_t(); 5062227825Stheraven bb = buf; 5063227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5064246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5065227825Stheraven#else 5066246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5067227825Stheraven#endif 5068232950Stheraven if (j == size_t(-1)) 5069227825Stheraven __throw_runtime_error("locale not supported"); 5070227825Stheraven wbe = wbuf + j; 5071227825Stheraven __am_pm_[1].assign(wbuf, wbe); 5072227825Stheraven __c_ = __analyze('c', ct); 5073227825Stheraven __r_ = __analyze('r', ct); 5074227825Stheraven __x_ = __analyze('x', ct); 5075227825Stheraven __X_ = __analyze('X', ct); 5076227825Stheraven} 5077227825Stheraven 5078227825Stheraventemplate <class CharT> 5079227825Stheravenstruct _LIBCPP_HIDDEN __time_get_temp 5080227825Stheraven : public ctype_byname<CharT> 5081227825Stheraven{ 5082227825Stheraven explicit __time_get_temp(const char* nm) 5083227825Stheraven : ctype_byname<CharT>(nm, 1) {} 5084227825Stheraven explicit __time_get_temp(const string& nm) 5085227825Stheraven : ctype_byname<CharT>(nm, 1) {} 5086227825Stheraven}; 5087227825Stheraven 5088227825Stheraventemplate <> 5089227825Stheraven__time_get_storage<char>::__time_get_storage(const char* __nm) 5090227825Stheraven : __time_get(__nm) 5091227825Stheraven{ 5092227825Stheraven const __time_get_temp<char> ct(__nm); 5093227825Stheraven init(ct); 5094227825Stheraven} 5095227825Stheraven 5096227825Stheraventemplate <> 5097227825Stheraven__time_get_storage<char>::__time_get_storage(const string& __nm) 5098227825Stheraven : __time_get(__nm) 5099227825Stheraven{ 5100227825Stheraven const __time_get_temp<char> ct(__nm); 5101227825Stheraven init(ct); 5102227825Stheraven} 5103227825Stheraven 5104227825Stheraventemplate <> 5105227825Stheraven__time_get_storage<wchar_t>::__time_get_storage(const char* __nm) 5106227825Stheraven : __time_get(__nm) 5107227825Stheraven{ 5108227825Stheraven const __time_get_temp<wchar_t> ct(__nm); 5109227825Stheraven init(ct); 5110227825Stheraven} 5111227825Stheraven 5112227825Stheraventemplate <> 5113227825Stheraven__time_get_storage<wchar_t>::__time_get_storage(const string& __nm) 5114227825Stheraven : __time_get(__nm) 5115227825Stheraven{ 5116227825Stheraven const __time_get_temp<wchar_t> ct(__nm); 5117227825Stheraven init(ct); 5118227825Stheraven} 5119227825Stheraven 5120227825Stheraventemplate <> 5121227825Stheraventime_base::dateorder 5122227825Stheraven__time_get_storage<char>::__do_date_order() const 5123227825Stheraven{ 5124227825Stheraven unsigned i; 5125227825Stheraven for (i = 0; i < __x_.size(); ++i) 5126227825Stheraven if (__x_[i] == '%') 5127227825Stheraven break; 5128227825Stheraven ++i; 5129227825Stheraven switch (__x_[i]) 5130227825Stheraven { 5131227825Stheraven case 'y': 5132227825Stheraven case 'Y': 5133227825Stheraven for (++i; i < __x_.size(); ++i) 5134227825Stheraven if (__x_[i] == '%') 5135227825Stheraven break; 5136227825Stheraven if (i == __x_.size()) 5137227825Stheraven break; 5138227825Stheraven ++i; 5139227825Stheraven switch (__x_[i]) 5140227825Stheraven { 5141227825Stheraven case 'm': 5142227825Stheraven for (++i; i < __x_.size(); ++i) 5143227825Stheraven if (__x_[i] == '%') 5144227825Stheraven break; 5145227825Stheraven if (i == __x_.size()) 5146227825Stheraven break; 5147227825Stheraven ++i; 5148227825Stheraven if (__x_[i] == 'd') 5149227825Stheraven return time_base::ymd; 5150227825Stheraven break; 5151227825Stheraven case 'd': 5152227825Stheraven for (++i; i < __x_.size(); ++i) 5153227825Stheraven if (__x_[i] == '%') 5154227825Stheraven break; 5155227825Stheraven if (i == __x_.size()) 5156227825Stheraven break; 5157227825Stheraven ++i; 5158227825Stheraven if (__x_[i] == 'm') 5159227825Stheraven return time_base::ydm; 5160227825Stheraven break; 5161227825Stheraven } 5162227825Stheraven break; 5163227825Stheraven case 'm': 5164227825Stheraven for (++i; i < __x_.size(); ++i) 5165227825Stheraven if (__x_[i] == '%') 5166227825Stheraven break; 5167227825Stheraven if (i == __x_.size()) 5168227825Stheraven break; 5169227825Stheraven ++i; 5170227825Stheraven if (__x_[i] == 'd') 5171227825Stheraven { 5172227825Stheraven for (++i; i < __x_.size(); ++i) 5173227825Stheraven if (__x_[i] == '%') 5174227825Stheraven break; 5175227825Stheraven if (i == __x_.size()) 5176227825Stheraven break; 5177227825Stheraven ++i; 5178227825Stheraven if (__x_[i] == 'y' || __x_[i] == 'Y') 5179227825Stheraven return time_base::mdy; 5180227825Stheraven break; 5181227825Stheraven } 5182227825Stheraven break; 5183227825Stheraven case 'd': 5184227825Stheraven for (++i; i < __x_.size(); ++i) 5185227825Stheraven if (__x_[i] == '%') 5186227825Stheraven break; 5187227825Stheraven if (i == __x_.size()) 5188227825Stheraven break; 5189227825Stheraven ++i; 5190227825Stheraven if (__x_[i] == 'm') 5191227825Stheraven { 5192227825Stheraven for (++i; i < __x_.size(); ++i) 5193227825Stheraven if (__x_[i] == '%') 5194227825Stheraven break; 5195227825Stheraven if (i == __x_.size()) 5196227825Stheraven break; 5197227825Stheraven ++i; 5198227825Stheraven if (__x_[i] == 'y' || __x_[i] == 'Y') 5199227825Stheraven return time_base::dmy; 5200227825Stheraven break; 5201227825Stheraven } 5202227825Stheraven break; 5203227825Stheraven } 5204227825Stheraven return time_base::no_order; 5205227825Stheraven} 5206227825Stheraven 5207227825Stheraventemplate <> 5208227825Stheraventime_base::dateorder 5209227825Stheraven__time_get_storage<wchar_t>::__do_date_order() const 5210227825Stheraven{ 5211227825Stheraven unsigned i; 5212227825Stheraven for (i = 0; i < __x_.size(); ++i) 5213227825Stheraven if (__x_[i] == L'%') 5214227825Stheraven break; 5215227825Stheraven ++i; 5216227825Stheraven switch (__x_[i]) 5217227825Stheraven { 5218227825Stheraven case L'y': 5219227825Stheraven case L'Y': 5220227825Stheraven for (++i; i < __x_.size(); ++i) 5221227825Stheraven if (__x_[i] == L'%') 5222227825Stheraven break; 5223227825Stheraven if (i == __x_.size()) 5224227825Stheraven break; 5225227825Stheraven ++i; 5226227825Stheraven switch (__x_[i]) 5227227825Stheraven { 5228227825Stheraven case L'm': 5229227825Stheraven for (++i; i < __x_.size(); ++i) 5230227825Stheraven if (__x_[i] == L'%') 5231227825Stheraven break; 5232227825Stheraven if (i == __x_.size()) 5233227825Stheraven break; 5234227825Stheraven ++i; 5235227825Stheraven if (__x_[i] == L'd') 5236227825Stheraven return time_base::ymd; 5237227825Stheraven break; 5238227825Stheraven case L'd': 5239227825Stheraven for (++i; i < __x_.size(); ++i) 5240227825Stheraven if (__x_[i] == L'%') 5241227825Stheraven break; 5242227825Stheraven if (i == __x_.size()) 5243227825Stheraven break; 5244227825Stheraven ++i; 5245227825Stheraven if (__x_[i] == L'm') 5246227825Stheraven return time_base::ydm; 5247227825Stheraven break; 5248227825Stheraven } 5249227825Stheraven break; 5250227825Stheraven case L'm': 5251227825Stheraven for (++i; i < __x_.size(); ++i) 5252227825Stheraven if (__x_[i] == L'%') 5253227825Stheraven break; 5254227825Stheraven if (i == __x_.size()) 5255227825Stheraven break; 5256227825Stheraven ++i; 5257227825Stheraven if (__x_[i] == L'd') 5258227825Stheraven { 5259227825Stheraven for (++i; i < __x_.size(); ++i) 5260227825Stheraven if (__x_[i] == L'%') 5261227825Stheraven break; 5262227825Stheraven if (i == __x_.size()) 5263227825Stheraven break; 5264227825Stheraven ++i; 5265227825Stheraven if (__x_[i] == L'y' || __x_[i] == L'Y') 5266227825Stheraven return time_base::mdy; 5267227825Stheraven break; 5268227825Stheraven } 5269227825Stheraven break; 5270227825Stheraven case L'd': 5271227825Stheraven for (++i; i < __x_.size(); ++i) 5272227825Stheraven if (__x_[i] == L'%') 5273227825Stheraven break; 5274227825Stheraven if (i == __x_.size()) 5275227825Stheraven break; 5276227825Stheraven ++i; 5277227825Stheraven if (__x_[i] == L'm') 5278227825Stheraven { 5279227825Stheraven for (++i; i < __x_.size(); ++i) 5280227825Stheraven if (__x_[i] == L'%') 5281227825Stheraven break; 5282227825Stheraven if (i == __x_.size()) 5283227825Stheraven break; 5284227825Stheraven ++i; 5285227825Stheraven if (__x_[i] == L'y' || __x_[i] == L'Y') 5286227825Stheraven return time_base::dmy; 5287227825Stheraven break; 5288227825Stheraven } 5289227825Stheraven break; 5290227825Stheraven } 5291227825Stheraven return time_base::no_order; 5292227825Stheraven} 5293227825Stheraven 5294227825Stheraven// time_put 5295227825Stheraven 5296227825Stheraven__time_put::__time_put(const char* nm) 5297227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 5298227825Stheraven{ 5299227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5300227825Stheraven if (__loc_ == 0) 5301227825Stheraven throw runtime_error("time_put_byname" 5302227825Stheraven " failed to construct for " + string(nm)); 5303227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5304227825Stheraven} 5305227825Stheraven 5306227825Stheraven__time_put::__time_put(const string& nm) 5307227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 5308227825Stheraven{ 5309227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5310227825Stheraven if (__loc_ == 0) 5311227825Stheraven throw runtime_error("time_put_byname" 5312227825Stheraven " failed to construct for " + nm); 5313227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5314227825Stheraven} 5315227825Stheraven 5316227825Stheraven__time_put::~__time_put() 5317227825Stheraven{ 5318227825Stheraven if (__loc_) 5319227825Stheraven freelocale(__loc_); 5320227825Stheraven} 5321227825Stheraven 5322227825Stheravenvoid 5323227825Stheraven__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, 5324227825Stheraven char __fmt, char __mod) const 5325227825Stheraven{ 5326227825Stheraven char fmt[] = {'%', __fmt, __mod, 0}; 5327227825Stheraven if (__mod != 0) 5328227825Stheraven swap(fmt[1], fmt[2]); 5329246487Stheraven size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); 5330227825Stheraven __ne = __nb + n; 5331227825Stheraven} 5332227825Stheraven 5333227825Stheravenvoid 5334227825Stheraven__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 5335227825Stheraven char __fmt, char __mod) const 5336227825Stheraven{ 5337227825Stheraven char __nar[100]; 5338227825Stheraven char* __ne = __nar + 100; 5339227825Stheraven __do_put(__nar, __ne, __tm, __fmt, __mod); 5340227825Stheraven mbstate_t mb = {0}; 5341227825Stheraven const char* __nb = __nar; 5342227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5343246487Stheraven size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); 5344227825Stheraven#else 5345246487Stheraven size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); 5346227825Stheraven#endif 5347232950Stheraven if (j == size_t(-1)) 5348227825Stheraven __throw_runtime_error("locale not supported"); 5349227825Stheraven __we = __wb + j; 5350227825Stheraven} 5351227825Stheraven 5352227825Stheraven// moneypunct_byname 5353227825Stheraven 5354232950Stheraventemplate <class charT> 5355227825Stheravenstatic 5356227825Stheravenvoid 5357232950Stheraven__init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_, 5358232950Stheraven bool intl, char cs_precedes, char sep_by_space, char sign_posn, 5359232950Stheraven charT space_char) 5360227825Stheraven{ 5361227825Stheraven const char sign = static_cast<char>(money_base::sign); 5362227825Stheraven const char space = static_cast<char>(money_base::space); 5363227825Stheraven const char none = static_cast<char>(money_base::none); 5364227825Stheraven const char symbol = static_cast<char>(money_base::symbol); 5365227825Stheraven const char value = static_cast<char>(money_base::value); 5366232950Stheraven const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4; 5367232950Stheraven 5368232950Stheraven // Comments on case branches reflect 'C11 7.11.2.1 The localeconv 5369232950Stheraven // function'. "Space between sign and symbol or value" means that 5370232950Stheraven // if the sign is adjacent to the symbol, there's a space between 5371232950Stheraven // them, and otherwise there's a space between the sign and value. 5372232950Stheraven // 5373232950Stheraven // C11's localeconv specifies that the fourth character of an 5374232950Stheraven // international curr_symbol is used to separate the sign and 5375232950Stheraven // value when sep_by_space says to do so. C++ can't represent 5376232950Stheraven // that, so we just use a space. When sep_by_space says to 5377232950Stheraven // separate the symbol and value-or-sign with a space, we rearrange the 5378232950Stheraven // curr_symbol to put its spacing character on the correct side of 5379232950Stheraven // the symbol. 5380232950Stheraven // 5381232950Stheraven // We also need to avoid adding an extra space between the sign 5382232950Stheraven // and value when the currency symbol is suppressed (by not 5383232950Stheraven // setting showbase). We match glibc's strfmon by interpreting 5384232950Stheraven // sep_by_space==1 as "omit the space when the currency symbol is 5385232950Stheraven // absent". 5386232950Stheraven // 5387232950Stheraven // Users who want to get this right should use ICU instead. 5388232950Stheraven 5389227825Stheraven switch (cs_precedes) 5390227825Stheraven { 5391232950Stheraven case 0: // value before curr_symbol 5392232950Stheraven if (symbol_contains_sep) { 5393232950Stheraven // Move the separator to before the symbol, to place it 5394232950Stheraven // between the value and symbol. 5395232950Stheraven rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, 5396232950Stheraven __curr_symbol_.end()); 5397232950Stheraven } 5398227825Stheraven switch (sign_posn) 5399227825Stheraven { 5400232950Stheraven case 0: // Parentheses surround the quantity and currency symbol. 5401227825Stheraven pat.field[0] = sign; 5402227825Stheraven pat.field[1] = value; 5403232950Stheraven pat.field[2] = none; // Any space appears in the symbol. 5404227825Stheraven pat.field[3] = symbol; 5405227825Stheraven switch (sep_by_space) 5406227825Stheraven { 5407232950Stheraven case 0: // No space separates the currency symbol and value. 5408232950Stheraven // This case may have changed between C99 and C11; 5409232950Stheraven // assume the currency symbol matches the intention. 5410232950Stheraven case 2: // Space between sign and currency or value. 5411232950Stheraven // The "sign" is two parentheses, so no space here either. 5412227825Stheraven return; 5413232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5414232950Stheraven if (!symbol_contains_sep) { 5415232950Stheraven // We insert the space into the symbol instead of 5416232950Stheraven // setting pat.field[2]=space so that when 5417232950Stheraven // showbase is not set, the space goes away too. 5418232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5419232950Stheraven } 5420227825Stheraven return; 5421227825Stheraven default: 5422227825Stheraven break; 5423227825Stheraven } 5424227825Stheraven break; 5425232950Stheraven case 1: // The sign string precedes the quantity and currency symbol. 5426227825Stheraven pat.field[0] = sign; 5427227825Stheraven pat.field[3] = symbol; 5428227825Stheraven switch (sep_by_space) 5429227825Stheraven { 5430232950Stheraven case 0: // No space separates the currency symbol and value. 5431227825Stheraven pat.field[1] = value; 5432227825Stheraven pat.field[2] = none; 5433227825Stheraven return; 5434232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5435227825Stheraven pat.field[1] = value; 5436232950Stheraven pat.field[2] = none; 5437232950Stheraven if (!symbol_contains_sep) { 5438232950Stheraven // We insert the space into the symbol instead of 5439232950Stheraven // setting pat.field[2]=space so that when 5440232950Stheraven // showbase is not set, the space goes away too. 5441232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5442232950Stheraven } 5443227825Stheraven return; 5444232950Stheraven case 2: // Space between sign and currency or value. 5445227825Stheraven pat.field[1] = space; 5446227825Stheraven pat.field[2] = value; 5447232950Stheraven if (symbol_contains_sep) { 5448232950Stheraven // Remove the separator from the symbol, since it 5449232950Stheraven // has already appeared after the sign. 5450232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5451232950Stheraven } 5452227825Stheraven return; 5453227825Stheraven default: 5454227825Stheraven break; 5455227825Stheraven } 5456227825Stheraven break; 5457232950Stheraven case 2: // The sign string succeeds the quantity and currency symbol. 5458227825Stheraven pat.field[0] = value; 5459227825Stheraven pat.field[3] = sign; 5460227825Stheraven switch (sep_by_space) 5461227825Stheraven { 5462232950Stheraven case 0: // No space separates the currency symbol and value. 5463227825Stheraven pat.field[1] = none; 5464227825Stheraven pat.field[2] = symbol; 5465227825Stheraven return; 5466232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5467232950Stheraven if (!symbol_contains_sep) { 5468232950Stheraven // We insert the space into the symbol instead of 5469232950Stheraven // setting pat.field[1]=space so that when 5470232950Stheraven // showbase is not set, the space goes away too. 5471232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5472232950Stheraven } 5473232950Stheraven pat.field[1] = none; 5474227825Stheraven pat.field[2] = symbol; 5475227825Stheraven return; 5476232950Stheraven case 2: // Space between sign and currency or value. 5477227825Stheraven pat.field[1] = symbol; 5478227825Stheraven pat.field[2] = space; 5479232950Stheraven if (symbol_contains_sep) { 5480232950Stheraven // Remove the separator from the symbol, since it 5481232950Stheraven // should not be removed if showbase is absent. 5482232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5483232950Stheraven } 5484227825Stheraven return; 5485227825Stheraven default: 5486227825Stheraven break; 5487227825Stheraven } 5488227825Stheraven break; 5489232950Stheraven case 3: // The sign string immediately precedes the currency symbol. 5490227825Stheraven pat.field[0] = value; 5491227825Stheraven pat.field[3] = symbol; 5492227825Stheraven switch (sep_by_space) 5493227825Stheraven { 5494232950Stheraven case 0: // No space separates the currency symbol and value. 5495227825Stheraven pat.field[1] = none; 5496227825Stheraven pat.field[2] = sign; 5497227825Stheraven return; 5498232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5499227825Stheraven pat.field[1] = space; 5500227825Stheraven pat.field[2] = sign; 5501232950Stheraven if (symbol_contains_sep) { 5502232950Stheraven // Remove the separator from the symbol, since it 5503232950Stheraven // has already appeared before the sign. 5504232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5505232950Stheraven } 5506227825Stheraven return; 5507232950Stheraven case 2: // Space between sign and currency or value. 5508227825Stheraven pat.field[1] = sign; 5509232950Stheraven pat.field[2] = none; 5510232950Stheraven if (!symbol_contains_sep) { 5511232950Stheraven // We insert the space into the symbol instead of 5512232950Stheraven // setting pat.field[2]=space so that when 5513232950Stheraven // showbase is not set, the space goes away too. 5514232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5515232950Stheraven } 5516227825Stheraven return; 5517227825Stheraven default: 5518227825Stheraven break; 5519227825Stheraven } 5520227825Stheraven break; 5521232950Stheraven case 4: // The sign string immediately succeeds the currency symbol. 5522227825Stheraven pat.field[0] = value; 5523227825Stheraven pat.field[3] = sign; 5524227825Stheraven switch (sep_by_space) 5525227825Stheraven { 5526232950Stheraven case 0: // No space separates the currency symbol and value. 5527227825Stheraven pat.field[1] = none; 5528227825Stheraven pat.field[2] = symbol; 5529227825Stheraven return; 5530232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5531232950Stheraven pat.field[1] = none; 5532227825Stheraven pat.field[2] = symbol; 5533232950Stheraven if (!symbol_contains_sep) { 5534232950Stheraven // We insert the space into the symbol instead of 5535232950Stheraven // setting pat.field[1]=space so that when 5536232950Stheraven // showbase is not set, the space goes away too. 5537232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5538232950Stheraven } 5539227825Stheraven return; 5540232950Stheraven case 2: // Space between sign and currency or value. 5541227825Stheraven pat.field[1] = symbol; 5542227825Stheraven pat.field[2] = space; 5543232950Stheraven if (symbol_contains_sep) { 5544232950Stheraven // Remove the separator from the symbol, since it 5545232950Stheraven // should not disappear when showbase is absent. 5546232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5547232950Stheraven } 5548227825Stheraven return; 5549227825Stheraven default: 5550227825Stheraven break; 5551227825Stheraven } 5552227825Stheraven break; 5553227825Stheraven default: 5554227825Stheraven break; 5555227825Stheraven } 5556227825Stheraven break; 5557232950Stheraven case 1: // curr_symbol before value 5558227825Stheraven switch (sign_posn) 5559227825Stheraven { 5560232950Stheraven case 0: // Parentheses surround the quantity and currency symbol. 5561227825Stheraven pat.field[0] = sign; 5562227825Stheraven pat.field[1] = symbol; 5563232950Stheraven pat.field[2] = none; // Any space appears in the symbol. 5564227825Stheraven pat.field[3] = value; 5565227825Stheraven switch (sep_by_space) 5566227825Stheraven { 5567232950Stheraven case 0: // No space separates the currency symbol and value. 5568232950Stheraven // This case may have changed between C99 and C11; 5569232950Stheraven // assume the currency symbol matches the intention. 5570232950Stheraven case 2: // Space between sign and currency or value. 5571232950Stheraven // The "sign" is two parentheses, so no space here either. 5572227825Stheraven return; 5573232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5574232950Stheraven if (!symbol_contains_sep) { 5575232950Stheraven // We insert the space into the symbol instead of 5576232950Stheraven // setting pat.field[2]=space so that when 5577232950Stheraven // showbase is not set, the space goes away too. 5578232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5579232950Stheraven } 5580227825Stheraven return; 5581227825Stheraven default: 5582227825Stheraven break; 5583227825Stheraven } 5584227825Stheraven break; 5585232950Stheraven case 1: // The sign string precedes the quantity and currency symbol. 5586227825Stheraven pat.field[0] = sign; 5587227825Stheraven pat.field[3] = value; 5588227825Stheraven switch (sep_by_space) 5589227825Stheraven { 5590232950Stheraven case 0: // No space separates the currency symbol and value. 5591227825Stheraven pat.field[1] = symbol; 5592227825Stheraven pat.field[2] = none; 5593227825Stheraven return; 5594232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5595227825Stheraven pat.field[1] = symbol; 5596232950Stheraven pat.field[2] = none; 5597232950Stheraven if (!symbol_contains_sep) { 5598232950Stheraven // We insert the space into the symbol instead of 5599232950Stheraven // setting pat.field[2]=space so that when 5600232950Stheraven // showbase is not set, the space goes away too. 5601232950Stheraven __curr_symbol_.push_back(space_char); 5602232950Stheraven } 5603227825Stheraven return; 5604232950Stheraven case 2: // Space between sign and currency or value. 5605227825Stheraven pat.field[1] = space; 5606227825Stheraven pat.field[2] = symbol; 5607232950Stheraven if (symbol_contains_sep) { 5608232950Stheraven // Remove the separator from the symbol, since it 5609232950Stheraven // has already appeared after the sign. 5610232950Stheraven __curr_symbol_.pop_back(); 5611232950Stheraven } 5612227825Stheraven return; 5613227825Stheraven default: 5614227825Stheraven break; 5615227825Stheraven } 5616227825Stheraven break; 5617232950Stheraven case 2: // The sign string succeeds the quantity and currency symbol. 5618227825Stheraven pat.field[0] = symbol; 5619227825Stheraven pat.field[3] = sign; 5620227825Stheraven switch (sep_by_space) 5621227825Stheraven { 5622232950Stheraven case 0: // No space separates the currency symbol and value. 5623227825Stheraven pat.field[1] = none; 5624227825Stheraven pat.field[2] = value; 5625227825Stheraven return; 5626232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5627232950Stheraven pat.field[1] = none; 5628227825Stheraven pat.field[2] = value; 5629232950Stheraven if (!symbol_contains_sep) { 5630232950Stheraven // We insert the space into the symbol instead of 5631232950Stheraven // setting pat.field[1]=space so that when 5632232950Stheraven // showbase is not set, the space goes away too. 5633232950Stheraven __curr_symbol_.push_back(space_char); 5634232950Stheraven } 5635227825Stheraven return; 5636232950Stheraven case 2: // Space between sign and currency or value. 5637227825Stheraven pat.field[1] = value; 5638227825Stheraven pat.field[2] = space; 5639232950Stheraven if (symbol_contains_sep) { 5640232950Stheraven // Remove the separator from the symbol, since it 5641232950Stheraven // will appear before the sign. 5642232950Stheraven __curr_symbol_.pop_back(); 5643232950Stheraven } 5644227825Stheraven return; 5645227825Stheraven default: 5646227825Stheraven break; 5647227825Stheraven } 5648227825Stheraven break; 5649232950Stheraven case 3: // The sign string immediately precedes the currency symbol. 5650227825Stheraven pat.field[0] = sign; 5651227825Stheraven pat.field[3] = value; 5652227825Stheraven switch (sep_by_space) 5653227825Stheraven { 5654232950Stheraven case 0: // No space separates the currency symbol and value. 5655227825Stheraven pat.field[1] = symbol; 5656227825Stheraven pat.field[2] = none; 5657227825Stheraven return; 5658232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5659227825Stheraven pat.field[1] = symbol; 5660232950Stheraven pat.field[2] = none; 5661232950Stheraven if (!symbol_contains_sep) { 5662232950Stheraven // We insert the space into the symbol instead of 5663232950Stheraven // setting pat.field[2]=space so that when 5664232950Stheraven // showbase is not set, the space goes away too. 5665232950Stheraven __curr_symbol_.push_back(space_char); 5666232950Stheraven } 5667227825Stheraven return; 5668232950Stheraven case 2: // Space between sign and currency or value. 5669227825Stheraven pat.field[1] = space; 5670227825Stheraven pat.field[2] = symbol; 5671232950Stheraven if (symbol_contains_sep) { 5672232950Stheraven // Remove the separator from the symbol, since it 5673232950Stheraven // has already appeared after the sign. 5674232950Stheraven __curr_symbol_.pop_back(); 5675232950Stheraven } 5676227825Stheraven return; 5677227825Stheraven default: 5678227825Stheraven break; 5679227825Stheraven } 5680227825Stheraven break; 5681232950Stheraven case 4: // The sign string immediately succeeds the currency symbol. 5682227825Stheraven pat.field[0] = symbol; 5683227825Stheraven pat.field[3] = value; 5684227825Stheraven switch (sep_by_space) 5685227825Stheraven { 5686232950Stheraven case 0: // No space separates the currency symbol and value. 5687227825Stheraven pat.field[1] = sign; 5688227825Stheraven pat.field[2] = none; 5689227825Stheraven return; 5690232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5691227825Stheraven pat.field[1] = sign; 5692227825Stheraven pat.field[2] = space; 5693232950Stheraven if (symbol_contains_sep) { 5694232950Stheraven // Remove the separator from the symbol, since it 5695232950Stheraven // should not disappear when showbase is absent. 5696232950Stheraven __curr_symbol_.pop_back(); 5697232950Stheraven } 5698227825Stheraven return; 5699232950Stheraven case 2: // Space between sign and currency or value. 5700232950Stheraven pat.field[1] = none; 5701227825Stheraven pat.field[2] = sign; 5702232950Stheraven if (!symbol_contains_sep) { 5703232950Stheraven // We insert the space into the symbol instead of 5704232950Stheraven // setting pat.field[1]=space so that when 5705232950Stheraven // showbase is not set, the space goes away too. 5706232950Stheraven __curr_symbol_.push_back(space_char); 5707232950Stheraven } 5708227825Stheraven return; 5709227825Stheraven default: 5710227825Stheraven break; 5711227825Stheraven } 5712227825Stheraven break; 5713227825Stheraven default: 5714227825Stheraven break; 5715227825Stheraven } 5716227825Stheraven break; 5717227825Stheraven default: 5718227825Stheraven break; 5719227825Stheraven } 5720227825Stheraven pat.field[0] = symbol; 5721227825Stheraven pat.field[1] = sign; 5722227825Stheraven pat.field[2] = none; 5723227825Stheraven pat.field[3] = value; 5724227825Stheraven} 5725227825Stheraven 5726227825Stheraventemplate<> 5727227825Stheravenvoid 5728227825Stheravenmoneypunct_byname<char, false>::init(const char* nm) 5729227825Stheraven{ 5730227825Stheraven typedef moneypunct<char, false> base; 5731227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5732227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5733232950Stheraven if (loc == nullptr) 5734227825Stheraven throw runtime_error("moneypunct_byname" 5735227825Stheraven " failed to construct for " + string(nm)); 5736227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5737227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5738227825Stheraven lconv* lc = localeconv_l(loc.get()); 5739227825Stheraven#else 5740227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5741227825Stheraven#endif 5742227825Stheraven if (*lc->mon_decimal_point) 5743227825Stheraven __decimal_point_ = *lc->mon_decimal_point; 5744227825Stheraven else 5745227825Stheraven __decimal_point_ = base::do_decimal_point(); 5746227825Stheraven if (*lc->mon_thousands_sep) 5747227825Stheraven __thousands_sep_ = *lc->mon_thousands_sep; 5748227825Stheraven else 5749227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5750227825Stheraven __grouping_ = lc->mon_grouping; 5751227825Stheraven __curr_symbol_ = lc->currency_symbol; 5752227825Stheraven if (lc->frac_digits != CHAR_MAX) 5753227825Stheraven __frac_digits_ = lc->frac_digits; 5754227825Stheraven else 5755227825Stheraven __frac_digits_ = base::do_frac_digits(); 5756227825Stheraven if (lc->p_sign_posn == 0) 5757227825Stheraven __positive_sign_ = "()"; 5758227825Stheraven else 5759227825Stheraven __positive_sign_ = lc->positive_sign; 5760227825Stheraven if (lc->n_sign_posn == 0) 5761227825Stheraven __negative_sign_ = "()"; 5762227825Stheraven else 5763227825Stheraven __negative_sign_ = lc->negative_sign; 5764232950Stheraven // Assume the positive and negative formats will want spaces in 5765232950Stheraven // the same places in curr_symbol since there's no way to 5766232950Stheraven // represent anything else. 5767232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5768232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, false, 5769232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); 5770232950Stheraven __init_pat(__neg_format_, __curr_symbol_, false, 5771232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); 5772227825Stheraven} 5773227825Stheraven 5774227825Stheraventemplate<> 5775227825Stheravenvoid 5776227825Stheravenmoneypunct_byname<char, true>::init(const char* nm) 5777227825Stheraven{ 5778227825Stheraven typedef moneypunct<char, true> base; 5779227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5780227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5781232950Stheraven if (loc == nullptr) 5782227825Stheraven throw runtime_error("moneypunct_byname" 5783227825Stheraven " failed to construct for " + string(nm)); 5784227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5785227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5786227825Stheraven lconv* lc = localeconv_l(loc.get()); 5787227825Stheraven#else 5788227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5789227825Stheraven#endif 5790227825Stheraven if (*lc->mon_decimal_point) 5791227825Stheraven __decimal_point_ = *lc->mon_decimal_point; 5792227825Stheraven else 5793227825Stheraven __decimal_point_ = base::do_decimal_point(); 5794227825Stheraven if (*lc->mon_thousands_sep) 5795227825Stheraven __thousands_sep_ = *lc->mon_thousands_sep; 5796227825Stheraven else 5797227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5798227825Stheraven __grouping_ = lc->mon_grouping; 5799227825Stheraven __curr_symbol_ = lc->int_curr_symbol; 5800227825Stheraven if (lc->int_frac_digits != CHAR_MAX) 5801227825Stheraven __frac_digits_ = lc->int_frac_digits; 5802227825Stheraven else 5803227825Stheraven __frac_digits_ = base::do_frac_digits(); 5804249998Sdim#ifdef _WIN32 5805227825Stheraven if (lc->p_sign_posn == 0) 5806227825Stheraven#else // _WIN32 5807227825Stheraven if (lc->int_p_sign_posn == 0) 5808227825Stheraven#endif //_WIN32 5809227825Stheraven __positive_sign_ = "()"; 5810227825Stheraven else 5811227825Stheraven __positive_sign_ = lc->positive_sign; 5812249998Sdim#ifdef _WIN32 5813227825Stheraven if(lc->n_sign_posn == 0) 5814227825Stheraven#else // _WIN32 5815227825Stheraven if (lc->int_n_sign_posn == 0) 5816227825Stheraven#endif // _WIN32 5817227825Stheraven __negative_sign_ = "()"; 5818227825Stheraven else 5819227825Stheraven __negative_sign_ = lc->negative_sign; 5820232950Stheraven // Assume the positive and negative formats will want spaces in 5821232950Stheraven // the same places in curr_symbol since there's no way to 5822232950Stheraven // represent anything else. 5823232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5824249998Sdim#ifdef _WIN32 5825232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 5826232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); 5827232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 5828232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); 5829227825Stheraven#else 5830232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 5831232950Stheraven lc->int_p_cs_precedes, lc->int_p_sep_by_space, 5832232950Stheraven lc->int_p_sign_posn, ' '); 5833232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 5834232950Stheraven lc->int_n_cs_precedes, lc->int_n_sep_by_space, 5835232950Stheraven lc->int_n_sign_posn, ' '); 5836227825Stheraven#endif // _WIN32 5837227825Stheraven} 5838227825Stheraven 5839227825Stheraventemplate<> 5840227825Stheravenvoid 5841227825Stheravenmoneypunct_byname<wchar_t, false>::init(const char* nm) 5842227825Stheraven{ 5843227825Stheraven typedef moneypunct<wchar_t, false> base; 5844227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5845227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5846232950Stheraven if (loc == nullptr) 5847227825Stheraven throw runtime_error("moneypunct_byname" 5848227825Stheraven " failed to construct for " + string(nm)); 5849227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5850227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5851227825Stheraven lconv* lc = localeconv_l(loc.get()); 5852227825Stheraven#else 5853227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5854227825Stheraven#endif 5855227825Stheraven if (*lc->mon_decimal_point) 5856227825Stheraven __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5857227825Stheraven else 5858227825Stheraven __decimal_point_ = base::do_decimal_point(); 5859227825Stheraven if (*lc->mon_thousands_sep) 5860227825Stheraven __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5861227825Stheraven else 5862227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5863227825Stheraven __grouping_ = lc->mon_grouping; 5864227825Stheraven wchar_t wbuf[100]; 5865227825Stheraven mbstate_t mb = {0}; 5866227825Stheraven const char* bb = lc->currency_symbol; 5867227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5868246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5869227825Stheraven#else 5870246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5871227825Stheraven#endif 5872232950Stheraven if (j == size_t(-1)) 5873227825Stheraven __throw_runtime_error("locale not supported"); 5874227825Stheraven wchar_t* wbe = wbuf + j; 5875227825Stheraven __curr_symbol_.assign(wbuf, wbe); 5876227825Stheraven if (lc->frac_digits != CHAR_MAX) 5877227825Stheraven __frac_digits_ = lc->frac_digits; 5878227825Stheraven else 5879227825Stheraven __frac_digits_ = base::do_frac_digits(); 5880227825Stheraven if (lc->p_sign_posn == 0) 5881227825Stheraven __positive_sign_ = L"()"; 5882227825Stheraven else 5883227825Stheraven { 5884227825Stheraven mb = mbstate_t(); 5885227825Stheraven bb = lc->positive_sign; 5886227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5887246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5888227825Stheraven#else 5889246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5890227825Stheraven#endif 5891232950Stheraven if (j == size_t(-1)) 5892227825Stheraven __throw_runtime_error("locale not supported"); 5893227825Stheraven wbe = wbuf + j; 5894227825Stheraven __positive_sign_.assign(wbuf, wbe); 5895227825Stheraven } 5896227825Stheraven if (lc->n_sign_posn == 0) 5897227825Stheraven __negative_sign_ = L"()"; 5898227825Stheraven else 5899227825Stheraven { 5900227825Stheraven mb = mbstate_t(); 5901227825Stheraven bb = lc->negative_sign; 5902227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5903246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5904227825Stheraven#else 5905246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5906227825Stheraven#endif 5907232950Stheraven if (j == size_t(-1)) 5908227825Stheraven __throw_runtime_error("locale not supported"); 5909227825Stheraven wbe = wbuf + j; 5910227825Stheraven __negative_sign_.assign(wbuf, wbe); 5911227825Stheraven } 5912232950Stheraven // Assume the positive and negative formats will want spaces in 5913232950Stheraven // the same places in curr_symbol since there's no way to 5914232950Stheraven // represent anything else. 5915232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5916232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, false, 5917232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); 5918232950Stheraven __init_pat(__neg_format_, __curr_symbol_, false, 5919232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); 5920227825Stheraven} 5921227825Stheraven 5922227825Stheraventemplate<> 5923227825Stheravenvoid 5924227825Stheravenmoneypunct_byname<wchar_t, true>::init(const char* nm) 5925227825Stheraven{ 5926227825Stheraven typedef moneypunct<wchar_t, true> base; 5927227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5928227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5929232950Stheraven if (loc == nullptr) 5930227825Stheraven throw runtime_error("moneypunct_byname" 5931227825Stheraven " failed to construct for " + string(nm)); 5932227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5933227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5934227825Stheraven lconv* lc = localeconv_l(loc.get()); 5935227825Stheraven#else 5936227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5937227825Stheraven#endif 5938227825Stheraven if (*lc->mon_decimal_point) 5939227825Stheraven __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5940227825Stheraven else 5941227825Stheraven __decimal_point_ = base::do_decimal_point(); 5942227825Stheraven if (*lc->mon_thousands_sep) 5943227825Stheraven __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5944227825Stheraven else 5945227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5946227825Stheraven __grouping_ = lc->mon_grouping; 5947227825Stheraven wchar_t wbuf[100]; 5948227825Stheraven mbstate_t mb = {0}; 5949227825Stheraven const char* bb = lc->int_curr_symbol; 5950227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5951246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5952227825Stheraven#else 5953246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5954227825Stheraven#endif 5955232950Stheraven if (j == size_t(-1)) 5956227825Stheraven __throw_runtime_error("locale not supported"); 5957227825Stheraven wchar_t* wbe = wbuf + j; 5958227825Stheraven __curr_symbol_.assign(wbuf, wbe); 5959227825Stheraven if (lc->int_frac_digits != CHAR_MAX) 5960227825Stheraven __frac_digits_ = lc->int_frac_digits; 5961227825Stheraven else 5962227825Stheraven __frac_digits_ = base::do_frac_digits(); 5963249998Sdim#ifdef _WIN32 5964227825Stheraven if (lc->p_sign_posn == 0) 5965227825Stheraven#else // _WIN32 5966227825Stheraven if (lc->int_p_sign_posn == 0) 5967227825Stheraven#endif // _WIN32 5968227825Stheraven __positive_sign_ = L"()"; 5969227825Stheraven else 5970227825Stheraven { 5971227825Stheraven mb = mbstate_t(); 5972227825Stheraven bb = lc->positive_sign; 5973227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5974246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5975227825Stheraven#else 5976246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5977227825Stheraven#endif 5978232950Stheraven if (j == size_t(-1)) 5979227825Stheraven __throw_runtime_error("locale not supported"); 5980227825Stheraven wbe = wbuf + j; 5981227825Stheraven __positive_sign_.assign(wbuf, wbe); 5982227825Stheraven } 5983249998Sdim#ifdef _WIN32 5984227825Stheraven if (lc->n_sign_posn == 0) 5985227825Stheraven#else // _WIN32 5986227825Stheraven if (lc->int_n_sign_posn == 0) 5987227825Stheraven#endif // _WIN32 5988227825Stheraven __negative_sign_ = L"()"; 5989227825Stheraven else 5990227825Stheraven { 5991227825Stheraven mb = mbstate_t(); 5992227825Stheraven bb = lc->negative_sign; 5993227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5994246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5995227825Stheraven#else 5996246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5997227825Stheraven#endif 5998232950Stheraven if (j == size_t(-1)) 5999227825Stheraven __throw_runtime_error("locale not supported"); 6000227825Stheraven wbe = wbuf + j; 6001227825Stheraven __negative_sign_.assign(wbuf, wbe); 6002227825Stheraven } 6003232950Stheraven // Assume the positive and negative formats will want spaces in 6004232950Stheraven // the same places in curr_symbol since there's no way to 6005232950Stheraven // represent anything else. 6006232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 6007249998Sdim#ifdef _WIN32 6008232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 6009232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); 6010232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 6011232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); 6012227825Stheraven#else // _WIN32 6013232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 6014232950Stheraven lc->int_p_cs_precedes, lc->int_p_sep_by_space, 6015232950Stheraven lc->int_p_sign_posn, L' '); 6016232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 6017232950Stheraven lc->int_n_cs_precedes, lc->int_n_sep_by_space, 6018232950Stheraven lc->int_n_sign_posn, L' '); 6019227825Stheraven#endif // _WIN32 6020227825Stheraven} 6021227825Stheraven 6022227825Stheravenvoid __do_nothing(void*) {} 6023227825Stheraven 6024227825Stheravenvoid __throw_runtime_error(const char* msg) 6025227825Stheraven{ 6026227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 6027227825Stheraven throw runtime_error(msg); 6028249998Sdim#else 6029249998Sdim (void)msg; 6030227825Stheraven#endif 6031227825Stheraven} 6032227825Stheraven 6033227825Stheraventemplate class collate<char>; 6034227825Stheraventemplate class collate<wchar_t>; 6035227825Stheraven 6036227825Stheraventemplate class num_get<char>; 6037227825Stheraventemplate class num_get<wchar_t>; 6038227825Stheraven 6039232950Stheraventemplate struct __num_get<char>; 6040232950Stheraventemplate struct __num_get<wchar_t>; 6041227825Stheraven 6042227825Stheraventemplate class num_put<char>; 6043227825Stheraventemplate class num_put<wchar_t>; 6044227825Stheraven 6045232950Stheraventemplate struct __num_put<char>; 6046232950Stheraventemplate struct __num_put<wchar_t>; 6047227825Stheraven 6048227825Stheraventemplate class time_get<char>; 6049227825Stheraventemplate class time_get<wchar_t>; 6050227825Stheraven 6051227825Stheraventemplate class time_get_byname<char>; 6052227825Stheraventemplate class time_get_byname<wchar_t>; 6053227825Stheraven 6054227825Stheraventemplate class time_put<char>; 6055227825Stheraventemplate class time_put<wchar_t>; 6056227825Stheraven 6057227825Stheraventemplate class time_put_byname<char>; 6058227825Stheraventemplate class time_put_byname<wchar_t>; 6059227825Stheraven 6060227825Stheraventemplate class moneypunct<char, false>; 6061227825Stheraventemplate class moneypunct<char, true>; 6062227825Stheraventemplate class moneypunct<wchar_t, false>; 6063227825Stheraventemplate class moneypunct<wchar_t, true>; 6064227825Stheraven 6065227825Stheraventemplate class moneypunct_byname<char, false>; 6066227825Stheraventemplate class moneypunct_byname<char, true>; 6067227825Stheraventemplate class moneypunct_byname<wchar_t, false>; 6068227825Stheraventemplate class moneypunct_byname<wchar_t, true>; 6069227825Stheraven 6070227825Stheraventemplate class money_get<char>; 6071227825Stheraventemplate class money_get<wchar_t>; 6072227825Stheraven 6073227825Stheraventemplate class __money_get<char>; 6074227825Stheraventemplate class __money_get<wchar_t>; 6075227825Stheraven 6076227825Stheraventemplate class money_put<char>; 6077227825Stheraventemplate class money_put<wchar_t>; 6078227825Stheraven 6079227825Stheraventemplate class __money_put<char>; 6080227825Stheraventemplate class __money_put<wchar_t>; 6081227825Stheraven 6082227825Stheraventemplate class messages<char>; 6083227825Stheraventemplate class messages<wchar_t>; 6084227825Stheraven 6085227825Stheraventemplate class messages_byname<char>; 6086227825Stheraventemplate class messages_byname<wchar_t>; 6087227825Stheraven 6088227825Stheraventemplate class codecvt_byname<char, char, mbstate_t>; 6089227825Stheraventemplate class codecvt_byname<wchar_t, char, mbstate_t>; 6090227825Stheraventemplate class codecvt_byname<char16_t, char, mbstate_t>; 6091227825Stheraventemplate class codecvt_byname<char32_t, char, mbstate_t>; 6092227825Stheraven 6093227825Stheraventemplate class __vector_base_common<true>; 6094227825Stheraven 6095227825Stheraven_LIBCPP_END_NAMESPACE_STD 6096