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 233253159Stheraven#if defined(__clang__) || _GNUC_VER >= 406 234246487Stheraven#pragma GCC diagnostic push 235246487Stheraven#pragma GCC diagnostic ignored "-Wextra" 236253159Stheraven#endif 237246487Stheraven 238227825Stheravenlocale::__imp::__imp(const __imp& other) 239232950Stheraven : facets_(max<size_t>(N, other.facets_.size())), 240232950Stheraven name_(other.name_) 241227825Stheraven{ 242227825Stheraven facets_ = other.facets_; 243227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 244227825Stheraven if (facets_[i]) 245227825Stheraven facets_[i]->__add_shared(); 246227825Stheraven} 247227825Stheraven 248253159Stheraven#if defined(__clang__) || _GNUC_VER >= 406 249246487Stheraven#pragma GCC diagnostic pop 250253159Stheraven#endif 251246487Stheraven 252227825Stheravenlocale::__imp::__imp(const __imp& other, const string& name, locale::category c) 253232950Stheraven : facets_(N), 254232950Stheraven name_("*") 255227825Stheraven{ 256227825Stheraven facets_ = other.facets_; 257227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 258227825Stheraven if (facets_[i]) 259227825Stheraven facets_[i]->__add_shared(); 260227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 261227825Stheraven try 262227825Stheraven { 263227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 264227825Stheraven if (c & locale::collate) 265227825Stheraven { 266227825Stheraven install(new collate_byname<char>(name)); 267227825Stheraven install(new collate_byname<wchar_t>(name)); 268227825Stheraven } 269227825Stheraven if (c & locale::ctype) 270227825Stheraven { 271227825Stheraven install(new ctype_byname<char>(name)); 272227825Stheraven install(new ctype_byname<wchar_t>(name)); 273227825Stheraven install(new codecvt_byname<char, char, mbstate_t>(name)); 274227825Stheraven install(new codecvt_byname<wchar_t, char, mbstate_t>(name)); 275227825Stheraven install(new codecvt_byname<char16_t, char, mbstate_t>(name)); 276227825Stheraven install(new codecvt_byname<char32_t, char, mbstate_t>(name)); 277227825Stheraven } 278227825Stheraven if (c & locale::monetary) 279227825Stheraven { 280227825Stheraven install(new moneypunct_byname<char, false>(name)); 281227825Stheraven install(new moneypunct_byname<char, true>(name)); 282227825Stheraven install(new moneypunct_byname<wchar_t, false>(name)); 283227825Stheraven install(new moneypunct_byname<wchar_t, true>(name)); 284227825Stheraven } 285227825Stheraven if (c & locale::numeric) 286227825Stheraven { 287227825Stheraven install(new numpunct_byname<char>(name)); 288227825Stheraven install(new numpunct_byname<wchar_t>(name)); 289227825Stheraven } 290227825Stheraven if (c & locale::time) 291227825Stheraven { 292227825Stheraven install(new time_get_byname<char>(name)); 293227825Stheraven install(new time_get_byname<wchar_t>(name)); 294227825Stheraven install(new time_put_byname<char>(name)); 295227825Stheraven install(new time_put_byname<wchar_t>(name)); 296227825Stheraven } 297227825Stheraven if (c & locale::messages) 298227825Stheraven { 299227825Stheraven install(new messages_byname<char>(name)); 300227825Stheraven install(new messages_byname<wchar_t>(name)); 301227825Stheraven } 302227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 303227825Stheraven } 304227825Stheraven catch (...) 305227825Stheraven { 306227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 307227825Stheraven if (facets_[i]) 308227825Stheraven facets_[i]->__release_shared(); 309227825Stheraven throw; 310227825Stheraven } 311227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 312227825Stheraven} 313227825Stheraven 314227825Stheraventemplate<class F> 315227825Stheraveninline 316227825Stheravenvoid 317227825Stheravenlocale::__imp::install_from(const locale::__imp& one) 318227825Stheraven{ 319227825Stheraven long id = F::id.__get(); 320227825Stheraven install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id); 321227825Stheraven} 322227825Stheraven 323227825Stheravenlocale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) 324232950Stheraven : facets_(N), 325232950Stheraven name_("*") 326227825Stheraven{ 327227825Stheraven facets_ = other.facets_; 328227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 329227825Stheraven if (facets_[i]) 330227825Stheraven facets_[i]->__add_shared(); 331227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 332227825Stheraven try 333227825Stheraven { 334227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 335227825Stheraven if (c & locale::collate) 336227825Stheraven { 337227825Stheraven install_from<_VSTD::collate<char> >(one); 338227825Stheraven install_from<_VSTD::collate<wchar_t> >(one); 339227825Stheraven } 340227825Stheraven if (c & locale::ctype) 341227825Stheraven { 342227825Stheraven install_from<_VSTD::ctype<char> >(one); 343227825Stheraven install_from<_VSTD::ctype<wchar_t> >(one); 344227825Stheraven install_from<_VSTD::codecvt<char, char, mbstate_t> >(one); 345227825Stheraven install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one); 346227825Stheraven install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one); 347227825Stheraven install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one); 348227825Stheraven } 349227825Stheraven if (c & locale::monetary) 350227825Stheraven { 351227825Stheraven install_from<moneypunct<char, false> >(one); 352227825Stheraven install_from<moneypunct<char, true> >(one); 353227825Stheraven install_from<moneypunct<wchar_t, false> >(one); 354227825Stheraven install_from<moneypunct<wchar_t, true> >(one); 355227825Stheraven install_from<money_get<char> >(one); 356227825Stheraven install_from<money_get<wchar_t> >(one); 357227825Stheraven install_from<money_put<char> >(one); 358227825Stheraven install_from<money_put<wchar_t> >(one); 359227825Stheraven } 360227825Stheraven if (c & locale::numeric) 361227825Stheraven { 362227825Stheraven install_from<numpunct<char> >(one); 363227825Stheraven install_from<numpunct<wchar_t> >(one); 364227825Stheraven install_from<num_get<char> >(one); 365227825Stheraven install_from<num_get<wchar_t> >(one); 366227825Stheraven install_from<num_put<char> >(one); 367227825Stheraven install_from<num_put<wchar_t> >(one); 368227825Stheraven } 369227825Stheraven if (c & locale::time) 370227825Stheraven { 371227825Stheraven install_from<time_get<char> >(one); 372227825Stheraven install_from<time_get<wchar_t> >(one); 373227825Stheraven install_from<time_put<char> >(one); 374227825Stheraven install_from<time_put<wchar_t> >(one); 375227825Stheraven } 376227825Stheraven if (c & locale::messages) 377227825Stheraven { 378227825Stheraven install_from<_VSTD::messages<char> >(one); 379227825Stheraven install_from<_VSTD::messages<wchar_t> >(one); 380227825Stheraven } 381227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 382227825Stheraven } 383227825Stheraven catch (...) 384227825Stheraven { 385227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 386227825Stheraven if (facets_[i]) 387227825Stheraven facets_[i]->__release_shared(); 388227825Stheraven throw; 389227825Stheraven } 390227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 391227825Stheraven} 392227825Stheraven 393227825Stheravenlocale::__imp::__imp(const __imp& other, facet* f, long id) 394232950Stheraven : facets_(max<size_t>(N, other.facets_.size()+1)), 395232950Stheraven name_("*") 396227825Stheraven{ 397227825Stheraven f->__add_shared(); 398227825Stheraven unique_ptr<facet, release> hold(f); 399227825Stheraven facets_ = other.facets_; 400227825Stheraven for (unsigned i = 0; i < other.facets_.size(); ++i) 401227825Stheraven if (facets_[i]) 402227825Stheraven facets_[i]->__add_shared(); 403227825Stheraven install(hold.get(), id); 404227825Stheraven} 405227825Stheraven 406227825Stheravenlocale::__imp::~__imp() 407227825Stheraven{ 408227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 409227825Stheraven if (facets_[i]) 410227825Stheraven facets_[i]->__release_shared(); 411227825Stheraven} 412227825Stheraven 413227825Stheravenvoid 414227825Stheravenlocale::__imp::install(facet* f, long id) 415227825Stheraven{ 416227825Stheraven f->__add_shared(); 417227825Stheraven unique_ptr<facet, release> hold(f); 418232950Stheraven if (static_cast<size_t>(id) >= facets_.size()) 419232950Stheraven facets_.resize(static_cast<size_t>(id+1)); 420232950Stheraven if (facets_[static_cast<size_t>(id)]) 421232950Stheraven facets_[static_cast<size_t>(id)]->__release_shared(); 422232950Stheraven facets_[static_cast<size_t>(id)] = hold.release(); 423227825Stheraven} 424227825Stheraven 425227825Stheravenconst locale::facet* 426227825Stheravenlocale::__imp::use_facet(long id) const 427227825Stheraven{ 428227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 429227825Stheraven if (!has_facet(id)) 430227825Stheraven throw bad_cast(); 431227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 432232950Stheraven return facets_[static_cast<size_t>(id)]; 433227825Stheraven} 434227825Stheraven 435227825Stheraven// locale 436227825Stheraven 437227825Stheravenconst locale& 438227825Stheravenlocale::__imp::make_classic() 439227825Stheraven{ 440227825Stheraven // only one thread can get in here and it only gets in once 441227825Stheraven static aligned_storage<sizeof(locale)>::type buf; 442227825Stheraven locale* c = (locale*)&buf; 443232950Stheraven c->__locale_ = &make<__imp>(1u); 444227825Stheraven return *c; 445227825Stheraven} 446227825Stheraven 447227825Stheravenconst locale& 448227825Stheravenlocale::classic() 449227825Stheraven{ 450227825Stheraven static const locale& c = __imp::make_classic(); 451227825Stheraven return c; 452227825Stheraven} 453227825Stheraven 454227825Stheravenlocale& 455227825Stheravenlocale::__imp::make_global() 456227825Stheraven{ 457227825Stheraven // only one thread can get in here and it only gets in once 458227825Stheraven static aligned_storage<sizeof(locale)>::type buf; 459227825Stheraven ::new (&buf) locale(locale::classic()); 460227825Stheraven return *(locale*)&buf; 461227825Stheraven} 462227825Stheraven 463227825Stheravenlocale& 464227825Stheravenlocale::__global() 465227825Stheraven{ 466227825Stheraven static locale& g = __imp::make_global(); 467227825Stheraven return g; 468227825Stheraven} 469227825Stheraven 470227825Stheravenlocale::locale() _NOEXCEPT 471227825Stheraven : __locale_(__global().__locale_) 472227825Stheraven{ 473227825Stheraven __locale_->__add_shared(); 474227825Stheraven} 475227825Stheraven 476227825Stheravenlocale::locale(const locale& l) _NOEXCEPT 477227825Stheraven : __locale_(l.__locale_) 478227825Stheraven{ 479227825Stheraven __locale_->__add_shared(); 480227825Stheraven} 481227825Stheraven 482227825Stheravenlocale::~locale() 483227825Stheraven{ 484227825Stheraven __locale_->__release_shared(); 485227825Stheraven} 486227825Stheraven 487227825Stheravenconst locale& 488227825Stheravenlocale::operator=(const locale& other) _NOEXCEPT 489227825Stheraven{ 490227825Stheraven other.__locale_->__add_shared(); 491227825Stheraven __locale_->__release_shared(); 492227825Stheraven __locale_ = other.__locale_; 493227825Stheraven return *this; 494227825Stheraven} 495227825Stheraven 496227825Stheravenlocale::locale(const char* name) 497227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 498227825Stheraven : __locale_(name ? new __imp(name) 499227825Stheraven : throw runtime_error("locale constructed with null")) 500227825Stheraven#else // _LIBCPP_NO_EXCEPTIONS 501227825Stheraven : __locale_(new __imp(name)) 502227825Stheraven#endif 503227825Stheraven{ 504227825Stheraven __locale_->__add_shared(); 505227825Stheraven} 506227825Stheraven 507227825Stheravenlocale::locale(const string& name) 508227825Stheraven : __locale_(new __imp(name)) 509227825Stheraven{ 510227825Stheraven __locale_->__add_shared(); 511227825Stheraven} 512227825Stheraven 513227825Stheravenlocale::locale(const locale& other, const char* name, category c) 514227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 515227825Stheraven : __locale_(name ? new __imp(*other.__locale_, name, c) 516227825Stheraven : throw runtime_error("locale constructed with null")) 517227825Stheraven#else // _LIBCPP_NO_EXCEPTIONS 518227825Stheraven : __locale_(new __imp(*other.__locale_, name, c)) 519227825Stheraven#endif 520227825Stheraven{ 521227825Stheraven __locale_->__add_shared(); 522227825Stheraven} 523227825Stheraven 524227825Stheravenlocale::locale(const locale& other, const string& name, category c) 525227825Stheraven : __locale_(new __imp(*other.__locale_, name, c)) 526227825Stheraven{ 527227825Stheraven __locale_->__add_shared(); 528227825Stheraven} 529227825Stheraven 530227825Stheravenlocale::locale(const locale& other, const locale& one, category c) 531227825Stheraven : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) 532227825Stheraven{ 533227825Stheraven __locale_->__add_shared(); 534227825Stheraven} 535227825Stheraven 536227825Stheravenstring 537227825Stheravenlocale::name() const 538227825Stheraven{ 539227825Stheraven return __locale_->name(); 540227825Stheraven} 541227825Stheraven 542227825Stheravenvoid 543227825Stheravenlocale::__install_ctor(const locale& other, facet* f, long id) 544227825Stheraven{ 545227825Stheraven if (f) 546227825Stheraven __locale_ = new __imp(*other.__locale_, f, id); 547227825Stheraven else 548227825Stheraven __locale_ = other.__locale_; 549227825Stheraven __locale_->__add_shared(); 550227825Stheraven} 551227825Stheraven 552227825Stheravenlocale 553227825Stheravenlocale::global(const locale& loc) 554227825Stheraven{ 555227825Stheraven locale& g = __global(); 556227825Stheraven locale r = g; 557227825Stheraven g = loc; 558227825Stheraven if (g.name() != "*") 559227825Stheraven setlocale(LC_ALL, g.name().c_str()); 560227825Stheraven return r; 561227825Stheraven} 562227825Stheraven 563227825Stheravenbool 564227825Stheravenlocale::has_facet(id& x) const 565227825Stheraven{ 566227825Stheraven return __locale_->has_facet(x.__get()); 567227825Stheraven} 568227825Stheraven 569227825Stheravenconst locale::facet* 570227825Stheravenlocale::use_facet(id& x) const 571227825Stheraven{ 572227825Stheraven return __locale_->use_facet(x.__get()); 573227825Stheraven} 574227825Stheraven 575227825Stheravenbool 576227825Stheravenlocale::operator==(const locale& y) const 577227825Stheraven{ 578227825Stheraven return (__locale_ == y.__locale_) 579227825Stheraven || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name()); 580227825Stheraven} 581227825Stheraven 582227825Stheraven// locale::facet 583227825Stheraven 584227825Stheravenlocale::facet::~facet() 585227825Stheraven{ 586227825Stheraven} 587227825Stheraven 588227825Stheravenvoid 589227825Stheravenlocale::facet::__on_zero_shared() _NOEXCEPT 590227825Stheraven{ 591227825Stheraven delete this; 592227825Stheraven} 593227825Stheraven 594227825Stheraven// locale::id 595227825Stheraven 596227825Stheravenint32_t locale::id::__next_id = 0; 597227825Stheraven 598227825Stheravennamespace 599227825Stheraven{ 600227825Stheraven 601227825Stheravenclass __fake_bind 602227825Stheraven{ 603227825Stheraven locale::id* id_; 604227825Stheraven void (locale::id::* pmf_)(); 605227825Stheravenpublic: 606227825Stheraven __fake_bind(void (locale::id::* pmf)(), locale::id* id) 607227825Stheraven : id_(id), pmf_(pmf) {} 608227825Stheraven 609227825Stheraven void operator()() const 610227825Stheraven { 611227825Stheraven (id_->*pmf_)(); 612227825Stheraven } 613227825Stheraven}; 614227825Stheraven 615227825Stheraven} 616227825Stheraven 617227825Stheravenlong 618227825Stheravenlocale::id::__get() 619227825Stheraven{ 620227825Stheraven call_once(__flag_, __fake_bind(&locale::id::__init, this)); 621227825Stheraven return __id_ - 1; 622227825Stheraven} 623227825Stheraven 624227825Stheravenvoid 625227825Stheravenlocale::id::__init() 626227825Stheraven{ 627227825Stheraven __id_ = __sync_add_and_fetch(&__next_id, 1); 628227825Stheraven} 629227825Stheraven 630227825Stheraven// template <> class collate_byname<char> 631227825Stheraven 632227825Stheravencollate_byname<char>::collate_byname(const char* n, size_t refs) 633227825Stheraven : collate<char>(refs), 634227825Stheraven __l(newlocale(LC_ALL_MASK, n, 0)) 635227825Stheraven{ 636227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 637227825Stheraven if (__l == 0) 638227825Stheraven throw runtime_error("collate_byname<char>::collate_byname" 639227825Stheraven " failed to construct for " + string(n)); 640227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 641227825Stheraven} 642227825Stheraven 643227825Stheravencollate_byname<char>::collate_byname(const string& name, size_t refs) 644227825Stheraven : collate<char>(refs), 645227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 646227825Stheraven{ 647227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 648227825Stheraven if (__l == 0) 649227825Stheraven throw runtime_error("collate_byname<char>::collate_byname" 650227825Stheraven " failed to construct for " + name); 651227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 652227825Stheraven} 653227825Stheraven 654227825Stheravencollate_byname<char>::~collate_byname() 655227825Stheraven{ 656227825Stheraven freelocale(__l); 657227825Stheraven} 658227825Stheraven 659227825Stheravenint 660227825Stheravencollate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1, 661227825Stheraven const char_type* __lo2, const char_type* __hi2) const 662227825Stheraven{ 663227825Stheraven string_type lhs(__lo1, __hi1); 664227825Stheraven string_type rhs(__lo2, __hi2); 665227825Stheraven int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); 666227825Stheraven if (r < 0) 667227825Stheraven return -1; 668227825Stheraven if (r > 0) 669227825Stheraven return 1; 670227825Stheraven return r; 671227825Stheraven} 672227825Stheraven 673227825Stheravencollate_byname<char>::string_type 674227825Stheravencollate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const 675227825Stheraven{ 676227825Stheraven const string_type in(lo, hi); 677227825Stheraven string_type out(strxfrm_l(0, in.c_str(), 0, __l), char()); 678227825Stheraven strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l); 679227825Stheraven return out; 680227825Stheraven} 681227825Stheraven 682227825Stheraven// template <> class collate_byname<wchar_t> 683227825Stheraven 684227825Stheravencollate_byname<wchar_t>::collate_byname(const char* n, size_t refs) 685227825Stheraven : collate<wchar_t>(refs), 686227825Stheraven __l(newlocale(LC_ALL_MASK, n, 0)) 687227825Stheraven{ 688227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 689227825Stheraven if (__l == 0) 690227825Stheraven throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" 691227825Stheraven " failed to construct for " + string(n)); 692227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 693227825Stheraven} 694227825Stheraven 695227825Stheravencollate_byname<wchar_t>::collate_byname(const string& name, size_t refs) 696227825Stheraven : collate<wchar_t>(refs), 697227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 698227825Stheraven{ 699227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 700227825Stheraven if (__l == 0) 701227825Stheraven throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" 702227825Stheraven " failed to construct for " + name); 703227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 704227825Stheraven} 705227825Stheraven 706227825Stheravencollate_byname<wchar_t>::~collate_byname() 707227825Stheraven{ 708227825Stheraven freelocale(__l); 709227825Stheraven} 710227825Stheraven 711227825Stheravenint 712227825Stheravencollate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1, 713227825Stheraven const char_type* __lo2, const char_type* __hi2) const 714227825Stheraven{ 715227825Stheraven string_type lhs(__lo1, __hi1); 716227825Stheraven string_type rhs(__lo2, __hi2); 717227825Stheraven int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); 718227825Stheraven if (r < 0) 719227825Stheraven return -1; 720227825Stheraven if (r > 0) 721227825Stheraven return 1; 722227825Stheraven return r; 723227825Stheraven} 724227825Stheraven 725227825Stheravencollate_byname<wchar_t>::string_type 726227825Stheravencollate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const 727227825Stheraven{ 728227825Stheraven const string_type in(lo, hi); 729227825Stheraven string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); 730227825Stheraven wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l); 731227825Stheraven return out; 732227825Stheraven} 733227825Stheraven 734227825Stheraven// template <> class ctype<wchar_t>; 735227825Stheraven 736246487Stheravenconst ctype_base::mask ctype_base::space; 737246487Stheravenconst ctype_base::mask ctype_base::print; 738246487Stheravenconst ctype_base::mask ctype_base::cntrl; 739246487Stheravenconst ctype_base::mask ctype_base::upper; 740246487Stheravenconst ctype_base::mask ctype_base::lower; 741246487Stheravenconst ctype_base::mask ctype_base::alpha; 742246487Stheravenconst ctype_base::mask ctype_base::digit; 743246487Stheravenconst ctype_base::mask ctype_base::punct; 744246487Stheravenconst ctype_base::mask ctype_base::xdigit; 745246487Stheravenconst ctype_base::mask ctype_base::blank; 746246487Stheravenconst ctype_base::mask ctype_base::alnum; 747246487Stheravenconst ctype_base::mask ctype_base::graph; 748246487Stheraven 749227825Stheravenlocale::id ctype<wchar_t>::id; 750227825Stheraven 751227825Stheravenctype<wchar_t>::~ctype() 752227825Stheraven{ 753227825Stheraven} 754227825Stheraven 755227825Stheravenbool 756227825Stheravenctype<wchar_t>::do_is(mask m, char_type c) const 757227825Stheraven{ 758227825Stheraven return isascii(c) ? ctype<char>::classic_table()[c] & m : false; 759227825Stheraven} 760227825Stheraven 761227825Stheravenconst wchar_t* 762227825Stheravenctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const 763227825Stheraven{ 764227825Stheraven for (; low != high; ++low, ++vec) 765227825Stheraven *vec = static_cast<mask>(isascii(*low) ? 766227825Stheraven ctype<char>::classic_table()[*low] : 0); 767227825Stheraven return low; 768227825Stheraven} 769227825Stheraven 770227825Stheravenconst wchar_t* 771227825Stheravenctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const 772227825Stheraven{ 773227825Stheraven for (; low != high; ++low) 774227825Stheraven if (isascii(*low) && (ctype<char>::classic_table()[*low] & m)) 775227825Stheraven break; 776227825Stheraven return low; 777227825Stheraven} 778227825Stheraven 779227825Stheravenconst wchar_t* 780227825Stheravenctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const 781227825Stheraven{ 782227825Stheraven for (; low != high; ++low) 783227825Stheraven if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m))) 784227825Stheraven break; 785227825Stheraven return low; 786227825Stheraven} 787227825Stheraven 788227825Stheravenwchar_t 789227825Stheravenctype<wchar_t>::do_toupper(char_type c) const 790227825Stheraven{ 791227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 792227825Stheraven return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; 793253159Stheraven#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__) 794227825Stheraven return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c; 795227825Stheraven#else 796227825Stheraven return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c; 797227825Stheraven#endif 798227825Stheraven} 799227825Stheraven 800227825Stheravenconst wchar_t* 801227825Stheravenctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const 802227825Stheraven{ 803227825Stheraven for (; low != high; ++low) 804227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 805227825Stheraven *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; 806253159Stheraven#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__) 807227825Stheraven *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] 808227825Stheraven : *low; 809227825Stheraven#else 810227825Stheraven *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low; 811227825Stheraven#endif 812227825Stheraven return low; 813227825Stheraven} 814227825Stheraven 815227825Stheravenwchar_t 816227825Stheravenctype<wchar_t>::do_tolower(char_type c) const 817227825Stheraven{ 818227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 819227825Stheraven return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; 820253159Stheraven#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__) 821227825Stheraven return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c; 822227825Stheraven#else 823227825Stheraven return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c; 824227825Stheraven#endif 825227825Stheraven} 826227825Stheraven 827227825Stheravenconst wchar_t* 828227825Stheravenctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const 829227825Stheraven{ 830227825Stheraven for (; low != high; ++low) 831227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 832227825Stheraven *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; 833253159Stheraven#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__) 834227825Stheraven *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] 835227825Stheraven : *low; 836227825Stheraven#else 837227825Stheraven *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low; 838227825Stheraven#endif 839227825Stheraven return low; 840227825Stheraven} 841227825Stheraven 842227825Stheravenwchar_t 843227825Stheravenctype<wchar_t>::do_widen(char c) const 844227825Stheraven{ 845227825Stheraven return c; 846227825Stheraven} 847227825Stheraven 848227825Stheravenconst char* 849227825Stheravenctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const 850227825Stheraven{ 851227825Stheraven for (; low != high; ++low, ++dest) 852227825Stheraven *dest = *low; 853227825Stheraven return low; 854227825Stheraven} 855227825Stheraven 856227825Stheravenchar 857227825Stheravenctype<wchar_t>::do_narrow(char_type c, char dfault) const 858227825Stheraven{ 859227825Stheraven if (isascii(c)) 860227825Stheraven return static_cast<char>(c); 861227825Stheraven return dfault; 862227825Stheraven} 863227825Stheraven 864227825Stheravenconst wchar_t* 865227825Stheravenctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 866227825Stheraven{ 867227825Stheraven for (; low != high; ++low, ++dest) 868227825Stheraven if (isascii(*low)) 869232950Stheraven *dest = static_cast<char>(*low); 870227825Stheraven else 871227825Stheraven *dest = dfault; 872227825Stheraven return low; 873227825Stheraven} 874227825Stheraven 875227825Stheraven// template <> class ctype<char>; 876227825Stheraven 877227825Stheravenlocale::id ctype<char>::id; 878227825Stheraven 879227825Stheravenctype<char>::ctype(const mask* tab, bool del, size_t refs) 880227825Stheraven : locale::facet(refs), 881227825Stheraven __tab_(tab), 882227825Stheraven __del_(del) 883227825Stheraven{ 884227825Stheraven if (__tab_ == 0) 885227825Stheraven __tab_ = classic_table(); 886227825Stheraven} 887227825Stheraven 888227825Stheravenctype<char>::~ctype() 889227825Stheraven{ 890227825Stheraven if (__tab_ && __del_) 891227825Stheraven delete [] __tab_; 892227825Stheraven} 893227825Stheraven 894227825Stheravenchar 895227825Stheravenctype<char>::do_toupper(char_type c) const 896227825Stheraven{ 897227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 898232950Stheraven return isascii(c) ? 899232950Stheraven static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c; 900253159Stheraven#elif defined(__NetBSD__) 901253159Stheraven return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]); 902249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 903249998Sdim return isascii(c) ? 904253159Stheraven static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c; 905227825Stheraven#else 906227825Stheraven return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c; 907227825Stheraven#endif 908227825Stheraven} 909227825Stheraven 910227825Stheravenconst char* 911227825Stheravenctype<char>::do_toupper(char_type* low, const char_type* high) const 912227825Stheraven{ 913227825Stheraven for (; low != high; ++low) 914227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 915232950Stheraven *low = isascii(*low) ? 916232950Stheraven static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low; 917253159Stheraven#elif defined(__NetBSD__) 918253159Stheraven *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]); 919249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 920249998Sdim *low = isascii(*low) ? 921249998Sdim static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low; 922227825Stheraven#else 923227825Stheraven *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low; 924227825Stheraven#endif 925227825Stheraven return low; 926227825Stheraven} 927227825Stheraven 928227825Stheravenchar 929227825Stheravenctype<char>::do_tolower(char_type c) const 930227825Stheraven{ 931227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 932232950Stheraven return isascii(c) ? 933232950Stheraven static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c; 934253159Stheraven#elif defined(__NetBSD__) 935253159Stheraven return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]); 936253159Stheraven#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__) 937249998Sdim return isascii(c) ? 938249998Sdim static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c; 939227825Stheraven#else 940227825Stheraven return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c; 941227825Stheraven#endif 942227825Stheraven} 943227825Stheraven 944227825Stheravenconst char* 945227825Stheravenctype<char>::do_tolower(char_type* low, const char_type* high) const 946227825Stheraven{ 947227825Stheraven for (; low != high; ++low) 948227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 949232950Stheraven *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low; 950253159Stheraven#elif defined(__NetBSD__) 951253159Stheraven *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]); 952249998Sdim#elif defined(__GLIBC__) || defined(EMSCRIPTEN) 953249998Sdim *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low; 954227825Stheraven#else 955227825Stheraven *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; 956227825Stheraven#endif 957227825Stheraven return low; 958227825Stheraven} 959227825Stheraven 960227825Stheravenchar 961227825Stheravenctype<char>::do_widen(char c) const 962227825Stheraven{ 963227825Stheraven return c; 964227825Stheraven} 965227825Stheraven 966227825Stheravenconst char* 967227825Stheravenctype<char>::do_widen(const char* low, const char* high, char_type* dest) const 968227825Stheraven{ 969227825Stheraven for (; low != high; ++low, ++dest) 970227825Stheraven *dest = *low; 971227825Stheraven return low; 972227825Stheraven} 973227825Stheraven 974227825Stheravenchar 975227825Stheravenctype<char>::do_narrow(char_type c, char dfault) const 976227825Stheraven{ 977227825Stheraven if (isascii(c)) 978227825Stheraven return static_cast<char>(c); 979227825Stheraven return dfault; 980227825Stheraven} 981227825Stheraven 982227825Stheravenconst char* 983227825Stheravenctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 984227825Stheraven{ 985227825Stheraven for (; low != high; ++low, ++dest) 986227825Stheraven if (isascii(*low)) 987227825Stheraven *dest = *low; 988227825Stheraven else 989227825Stheraven *dest = dfault; 990227825Stheraven return low; 991227825Stheraven} 992227825Stheraven 993249998Sdim#ifdef EMSCRIPTEN 994249998Sdimextern "C" const unsigned short ** __ctype_b_loc(); 995249998Sdimextern "C" const int ** __ctype_tolower_loc(); 996249998Sdimextern "C" const int ** __ctype_toupper_loc(); 997249998Sdim#endif 998249998Sdim 999227825Stheravenconst ctype<char>::mask* 1000227825Stheravenctype<char>::classic_table() _NOEXCEPT 1001227825Stheraven{ 1002227825Stheraven#if defined(__APPLE__) || defined(__FreeBSD__) 1003227825Stheraven return _DefaultRuneLocale.__runetype; 1004253159Stheraven#elif defined(__NetBSD__) 1005253159Stheraven return _C_ctype_tab_ + 1; 1006227825Stheraven#elif defined(__GLIBC__) 1007227825Stheraven return __cloc()->__ctype_b; 1008232950Stheraven#elif __sun__ 1009232950Stheraven return __ctype_mask; 1010249998Sdim#elif defined(_WIN32) 1011227825Stheraven return _ctype+1; // internal ctype mask table defined in msvcrt.dll 1012227825Stheraven// This is assumed to be safe, which is a nonsense assumption because we're 1013227825Stheraven// going to end up dereferencing it later... 1014249998Sdim#elif defined(EMSCRIPTEN) 1015249998Sdim return *__ctype_b_loc(); 1016227825Stheraven#else 1017232950Stheraven // Platform not supported: abort so the person doing the port knows what to 1018232950Stheraven // fix 1019232950Stheraven# warning ctype<char>::classic_table() is not implemented 1020232950Stheraven abort(); 1021227825Stheraven return NULL; 1022227825Stheraven#endif 1023227825Stheraven} 1024227825Stheraven 1025227825Stheraven#if defined(__GLIBC__) 1026227825Stheravenconst int* 1027227825Stheravenctype<char>::__classic_lower_table() _NOEXCEPT 1028227825Stheraven{ 1029227825Stheraven return __cloc()->__ctype_tolower; 1030227825Stheraven} 1031227825Stheraven 1032227825Stheravenconst int* 1033227825Stheravenctype<char>::__classic_upper_table() _NOEXCEPT 1034227825Stheraven{ 1035227825Stheraven return __cloc()->__ctype_toupper; 1036227825Stheraven} 1037253159Stheraven#elif __NetBSD__ 1038253159Stheravenconst short* 1039253159Stheravenctype<char>::__classic_lower_table() _NOEXCEPT 1040253159Stheraven{ 1041253159Stheraven return _C_tolower_tab_ + 1; 1042253159Stheraven} 1043227825Stheraven 1044253159Stheravenconst short* 1045253159Stheravenctype<char>::__classic_upper_table() _NOEXCEPT 1046253159Stheraven{ 1047253159Stheraven return _C_toupper_tab_ + 1; 1048253159Stheraven} 1049253159Stheraven 1050253159Stheraven#elif defined(EMSCRIPTEN) 1051249998Sdimconst int* 1052249998Sdimctype<char>::__classic_lower_table() _NOEXCEPT 1053249998Sdim{ 1054249998Sdim return *__ctype_tolower_loc(); 1055249998Sdim} 1056249998Sdim 1057249998Sdimconst int* 1058249998Sdimctype<char>::__classic_upper_table() _NOEXCEPT 1059249998Sdim{ 1060249998Sdim return *__ctype_toupper_loc(); 1061249998Sdim} 1062253159Stheraven#endif // __GLIBC__ || EMSCRIPTEN || __NETBSD__ 1063249998Sdim 1064227825Stheraven// template <> class ctype_byname<char> 1065227825Stheraven 1066227825Stheravenctype_byname<char>::ctype_byname(const char* name, size_t refs) 1067227825Stheraven : ctype<char>(0, false, refs), 1068227825Stheraven __l(newlocale(LC_ALL_MASK, name, 0)) 1069227825Stheraven{ 1070227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1071227825Stheraven if (__l == 0) 1072227825Stheraven throw runtime_error("ctype_byname<char>::ctype_byname" 1073227825Stheraven " failed to construct for " + string(name)); 1074227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1075227825Stheraven} 1076227825Stheraven 1077227825Stheravenctype_byname<char>::ctype_byname(const string& name, size_t refs) 1078227825Stheraven : ctype<char>(0, false, refs), 1079227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 1080227825Stheraven{ 1081227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1082227825Stheraven if (__l == 0) 1083227825Stheraven throw runtime_error("ctype_byname<char>::ctype_byname" 1084227825Stheraven " failed to construct for " + name); 1085227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1086227825Stheraven} 1087227825Stheraven 1088227825Stheravenctype_byname<char>::~ctype_byname() 1089227825Stheraven{ 1090227825Stheraven freelocale(__l); 1091227825Stheraven} 1092227825Stheraven 1093227825Stheravenchar 1094227825Stheravenctype_byname<char>::do_toupper(char_type c) const 1095227825Stheraven{ 1096253159Stheraven return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l)); 1097227825Stheraven} 1098227825Stheraven 1099227825Stheravenconst char* 1100227825Stheravenctype_byname<char>::do_toupper(char_type* low, const char_type* high) const 1101227825Stheraven{ 1102227825Stheraven for (; low != high; ++low) 1103253159Stheraven *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l)); 1104227825Stheraven return low; 1105227825Stheraven} 1106227825Stheraven 1107227825Stheravenchar 1108227825Stheravenctype_byname<char>::do_tolower(char_type c) const 1109227825Stheraven{ 1110253159Stheraven return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l)); 1111227825Stheraven} 1112227825Stheraven 1113227825Stheravenconst char* 1114227825Stheravenctype_byname<char>::do_tolower(char_type* low, const char_type* high) const 1115227825Stheraven{ 1116227825Stheraven for (; low != high; ++low) 1117253159Stheraven *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l)); 1118227825Stheraven return low; 1119227825Stheraven} 1120227825Stheraven 1121227825Stheraven// template <> class ctype_byname<wchar_t> 1122227825Stheraven 1123227825Stheravenctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs) 1124227825Stheraven : ctype<wchar_t>(refs), 1125227825Stheraven __l(newlocale(LC_ALL_MASK, name, 0)) 1126227825Stheraven{ 1127227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1128227825Stheraven if (__l == 0) 1129227825Stheraven throw runtime_error("ctype_byname<wchar_t>::ctype_byname" 1130227825Stheraven " failed to construct for " + string(name)); 1131227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1132227825Stheraven} 1133227825Stheraven 1134227825Stheravenctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs) 1135227825Stheraven : ctype<wchar_t>(refs), 1136227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 1137227825Stheraven{ 1138227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1139227825Stheraven if (__l == 0) 1140227825Stheraven throw runtime_error("ctype_byname<wchar_t>::ctype_byname" 1141227825Stheraven " failed to construct for " + name); 1142227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1143227825Stheraven} 1144227825Stheraven 1145227825Stheravenctype_byname<wchar_t>::~ctype_byname() 1146227825Stheraven{ 1147227825Stheraven freelocale(__l); 1148227825Stheraven} 1149227825Stheraven 1150227825Stheravenbool 1151227825Stheravenctype_byname<wchar_t>::do_is(mask m, char_type c) const 1152227825Stheraven{ 1153227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1154227825Stheraven return static_cast<bool>(iswctype_l(c, m, __l)); 1155227825Stheraven#else 1156241903Sdim bool result = false; 1157249998Sdim wint_t ch = static_cast<wint_t>(c); 1158249998Sdim if (m & space) result |= (iswspace_l(ch, __l) != 0); 1159249998Sdim if (m & print) result |= (iswprint_l(ch, __l) != 0); 1160249998Sdim if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0); 1161249998Sdim if (m & upper) result |= (iswupper_l(ch, __l) != 0); 1162249998Sdim if (m & lower) result |= (iswlower_l(ch, __l) != 0); 1163249998Sdim if (m & alpha) result |= (iswalpha_l(ch, __l) != 0); 1164249998Sdim if (m & digit) result |= (iswdigit_l(ch, __l) != 0); 1165249998Sdim if (m & punct) result |= (iswpunct_l(ch, __l) != 0); 1166249998Sdim if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0); 1167249998Sdim if (m & blank) result |= (iswblank_l(ch, __l) != 0); 1168227825Stheraven return result; 1169227825Stheraven#endif 1170227825Stheraven} 1171227825Stheraven 1172227825Stheravenconst wchar_t* 1173227825Stheravenctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const 1174227825Stheraven{ 1175227825Stheraven for (; low != high; ++low, ++vec) 1176227825Stheraven { 1177227825Stheraven if (isascii(*low)) 1178227825Stheraven *vec = static_cast<mask>(ctype<char>::classic_table()[*low]); 1179227825Stheraven else 1180227825Stheraven { 1181227825Stheraven *vec = 0; 1182249998Sdim wint_t ch = static_cast<wint_t>(*low); 1183249998Sdim if (iswspace_l(ch, __l)) 1184227825Stheraven *vec |= space; 1185249998Sdim if (iswprint_l(ch, __l)) 1186227825Stheraven *vec |= print; 1187249998Sdim if (iswcntrl_l(ch, __l)) 1188227825Stheraven *vec |= cntrl; 1189249998Sdim if (iswupper_l(ch, __l)) 1190227825Stheraven *vec |= upper; 1191249998Sdim if (iswlower_l(ch, __l)) 1192227825Stheraven *vec |= lower; 1193249998Sdim if (iswalpha_l(ch, __l)) 1194227825Stheraven *vec |= alpha; 1195249998Sdim if (iswdigit_l(ch, __l)) 1196227825Stheraven *vec |= digit; 1197249998Sdim if (iswpunct_l(ch, __l)) 1198227825Stheraven *vec |= punct; 1199249998Sdim if (iswxdigit_l(ch, __l)) 1200227825Stheraven *vec |= xdigit; 1201227825Stheraven } 1202227825Stheraven } 1203227825Stheraven return low; 1204227825Stheraven} 1205227825Stheraven 1206227825Stheravenconst wchar_t* 1207227825Stheravenctype_byname<wchar_t>::do_scan_is(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)) break; 1217249998Sdim if (m & print && iswprint_l(ch, __l)) break; 1218249998Sdim if (m & cntrl && iswcntrl_l(ch, __l)) break; 1219249998Sdim if (m & upper && iswupper_l(ch, __l)) break; 1220249998Sdim if (m & lower && iswlower_l(ch, __l)) break; 1221249998Sdim if (m & alpha && iswalpha_l(ch, __l)) break; 1222249998Sdim if (m & digit && iswdigit_l(ch, __l)) break; 1223249998Sdim if (m & punct && iswpunct_l(ch, __l)) break; 1224249998Sdim if (m & xdigit && iswxdigit_l(ch, __l)) break; 1225249998Sdim if (m & blank && iswblank_l(ch, __l)) break; 1226227825Stheraven#endif 1227227825Stheraven } 1228227825Stheraven return low; 1229227825Stheraven} 1230227825Stheraven 1231227825Stheravenconst wchar_t* 1232227825Stheravenctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const 1233227825Stheraven{ 1234227825Stheraven for (; low != high; ++low) 1235227825Stheraven { 1236227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1237227825Stheraven if (!iswctype_l(*low, m, __l)) 1238227825Stheraven break; 1239227825Stheraven#else 1240249998Sdim wint_t ch = static_cast<wint_t>(*low); 1241249998Sdim if (m & space && iswspace_l(ch, __l)) continue; 1242249998Sdim if (m & print && iswprint_l(ch, __l)) continue; 1243249998Sdim if (m & cntrl && iswcntrl_l(ch, __l)) continue; 1244249998Sdim if (m & upper && iswupper_l(ch, __l)) continue; 1245249998Sdim if (m & lower && iswlower_l(ch, __l)) continue; 1246249998Sdim if (m & alpha && iswalpha_l(ch, __l)) continue; 1247249998Sdim if (m & digit && iswdigit_l(ch, __l)) continue; 1248249998Sdim if (m & punct && iswpunct_l(ch, __l)) continue; 1249249998Sdim if (m & xdigit && iswxdigit_l(ch, __l)) continue; 1250249998Sdim if (m & blank && iswblank_l(ch, __l)) continue; 1251227825Stheraven break; 1252227825Stheraven#endif 1253227825Stheraven } 1254227825Stheraven return low; 1255227825Stheraven} 1256227825Stheraven 1257227825Stheravenwchar_t 1258227825Stheravenctype_byname<wchar_t>::do_toupper(char_type c) const 1259227825Stheraven{ 1260227825Stheraven return towupper_l(c, __l); 1261227825Stheraven} 1262227825Stheraven 1263227825Stheravenconst wchar_t* 1264227825Stheravenctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const 1265227825Stheraven{ 1266227825Stheraven for (; low != high; ++low) 1267227825Stheraven *low = towupper_l(*low, __l); 1268227825Stheraven return low; 1269227825Stheraven} 1270227825Stheraven 1271227825Stheravenwchar_t 1272227825Stheravenctype_byname<wchar_t>::do_tolower(char_type c) const 1273227825Stheraven{ 1274227825Stheraven return towlower_l(c, __l); 1275227825Stheraven} 1276227825Stheraven 1277227825Stheravenconst wchar_t* 1278227825Stheravenctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const 1279227825Stheraven{ 1280227825Stheraven for (; low != high; ++low) 1281227825Stheraven *low = towlower_l(*low, __l); 1282227825Stheraven return low; 1283227825Stheraven} 1284227825Stheraven 1285227825Stheravenwchar_t 1286227825Stheravenctype_byname<wchar_t>::do_widen(char c) const 1287227825Stheraven{ 1288227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1289227825Stheraven return btowc_l(c, __l); 1290227825Stheraven#else 1291227825Stheraven return __btowc_l(c, __l); 1292227825Stheraven#endif 1293227825Stheraven} 1294227825Stheraven 1295227825Stheravenconst char* 1296227825Stheravenctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const 1297227825Stheraven{ 1298227825Stheraven for (; low != high; ++low, ++dest) 1299227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1300227825Stheraven *dest = btowc_l(*low, __l); 1301227825Stheraven#else 1302227825Stheraven *dest = __btowc_l(*low, __l); 1303227825Stheraven#endif 1304227825Stheraven return low; 1305227825Stheraven} 1306227825Stheraven 1307227825Stheravenchar 1308227825Stheravenctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const 1309227825Stheraven{ 1310227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1311227825Stheraven int r = wctob_l(c, __l); 1312227825Stheraven#else 1313227825Stheraven int r = __wctob_l(c, __l); 1314227825Stheraven#endif 1315246487Stheraven return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; 1316227825Stheraven} 1317227825Stheraven 1318227825Stheravenconst wchar_t* 1319227825Stheravenctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 1320227825Stheraven{ 1321227825Stheraven for (; low != high; ++low, ++dest) 1322227825Stheraven { 1323227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1324227825Stheraven int r = wctob_l(*low, __l); 1325227825Stheraven#else 1326227825Stheraven int r = __wctob_l(*low, __l); 1327227825Stheraven#endif 1328246487Stheraven *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; 1329227825Stheraven } 1330227825Stheraven return low; 1331227825Stheraven} 1332227825Stheraven 1333227825Stheraven// template <> class codecvt<char, char, mbstate_t> 1334227825Stheraven 1335227825Stheravenlocale::id codecvt<char, char, mbstate_t>::id; 1336227825Stheraven 1337227825Stheravencodecvt<char, char, mbstate_t>::~codecvt() 1338227825Stheraven{ 1339227825Stheraven} 1340227825Stheraven 1341227825Stheravencodecvt<char, char, mbstate_t>::result 1342227825Stheravencodecvt<char, char, mbstate_t>::do_out(state_type&, 1343227825Stheraven const intern_type* frm, const intern_type*, const intern_type*& frm_nxt, 1344227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 1345227825Stheraven{ 1346227825Stheraven frm_nxt = frm; 1347227825Stheraven to_nxt = to; 1348227825Stheraven return noconv; 1349227825Stheraven} 1350227825Stheraven 1351227825Stheravencodecvt<char, char, mbstate_t>::result 1352227825Stheravencodecvt<char, char, mbstate_t>::do_in(state_type&, 1353227825Stheraven const extern_type* frm, const extern_type*, const extern_type*& frm_nxt, 1354227825Stheraven intern_type* to, intern_type*, intern_type*& to_nxt) const 1355227825Stheraven{ 1356227825Stheraven frm_nxt = frm; 1357227825Stheraven to_nxt = to; 1358227825Stheraven return noconv; 1359227825Stheraven} 1360227825Stheraven 1361227825Stheravencodecvt<char, char, mbstate_t>::result 1362227825Stheravencodecvt<char, char, mbstate_t>::do_unshift(state_type&, 1363227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 1364227825Stheraven{ 1365227825Stheraven to_nxt = to; 1366227825Stheraven return noconv; 1367227825Stheraven} 1368227825Stheraven 1369227825Stheravenint 1370227825Stheravencodecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT 1371227825Stheraven{ 1372227825Stheraven return 1; 1373227825Stheraven} 1374227825Stheraven 1375227825Stheravenbool 1376227825Stheravencodecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 1377227825Stheraven{ 1378227825Stheraven return true; 1379227825Stheraven} 1380227825Stheraven 1381227825Stheravenint 1382227825Stheravencodecvt<char, char, mbstate_t>::do_length(state_type&, 1383227825Stheraven const extern_type* frm, const extern_type* end, size_t mx) const 1384227825Stheraven{ 1385232950Stheraven return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm))); 1386227825Stheraven} 1387227825Stheraven 1388227825Stheravenint 1389227825Stheravencodecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT 1390227825Stheraven{ 1391227825Stheraven return 1; 1392227825Stheraven} 1393227825Stheraven 1394227825Stheraven// template <> class codecvt<wchar_t, char, mbstate_t> 1395227825Stheraven 1396227825Stheravenlocale::id codecvt<wchar_t, char, mbstate_t>::id; 1397227825Stheraven 1398227825Stheravencodecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) 1399227825Stheraven : locale::facet(refs), 1400253159Stheraven __l(_LIBCPP_GET_C_LOCALE) 1401227825Stheraven{ 1402227825Stheraven} 1403227825Stheraven 1404227825Stheravencodecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs) 1405227825Stheraven : locale::facet(refs), 1406227825Stheraven __l(newlocale(LC_ALL_MASK, nm, 0)) 1407227825Stheraven{ 1408227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1409227825Stheraven if (__l == 0) 1410227825Stheraven throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname" 1411227825Stheraven " failed to construct for " + string(nm)); 1412227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1413227825Stheraven} 1414227825Stheraven 1415227825Stheravencodecvt<wchar_t, char, mbstate_t>::~codecvt() 1416227825Stheraven{ 1417253159Stheraven if (__l != _LIBCPP_GET_C_LOCALE) 1418227825Stheraven freelocale(__l); 1419227825Stheraven} 1420227825Stheraven 1421227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1422227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, 1423227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 1424227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 1425227825Stheraven{ 1426227825Stheraven // look for first internal null in frm 1427227825Stheraven const intern_type* fend = frm; 1428227825Stheraven for (; fend != frm_end; ++fend) 1429227825Stheraven if (*fend == 0) 1430227825Stheraven break; 1431227825Stheraven // loop over all null-terminated sequences in frm 1432227825Stheraven to_nxt = to; 1433227825Stheraven for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) 1434227825Stheraven { 1435249998Sdim // save state in case it is needed to recover to_nxt on error 1436227825Stheraven mbstate_t save_state = st; 1437227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1438232950Stheraven size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), 1439232950Stheraven static_cast<size_t>(to_end-to), &st, __l); 1440227825Stheraven#else 1441227825Stheraven size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); 1442227825Stheraven#endif 1443227825Stheraven if (n == size_t(-1)) 1444227825Stheraven { 1445227825Stheraven // need to recover to_nxt 1446227825Stheraven for (to_nxt = to; frm != frm_nxt; ++frm) 1447227825Stheraven { 1448227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1449227825Stheraven n = wcrtomb_l(to_nxt, *frm, &save_state, __l); 1450227825Stheraven#else 1451227825Stheraven n = __wcrtomb_l(to_nxt, *frm, &save_state, __l); 1452227825Stheraven#endif 1453227825Stheraven if (n == size_t(-1)) 1454227825Stheraven break; 1455227825Stheraven to_nxt += n; 1456227825Stheraven } 1457227825Stheraven frm_nxt = frm; 1458227825Stheraven return error; 1459227825Stheraven } 1460227825Stheraven if (n == 0) 1461227825Stheraven return partial; 1462227825Stheraven to_nxt += n; 1463227825Stheraven if (to_nxt == to_end) 1464227825Stheraven break; 1465227825Stheraven if (fend != frm_end) // set up next null terminated sequence 1466227825Stheraven { 1467227825Stheraven // Try to write the terminating null 1468227825Stheraven extern_type tmp[MB_LEN_MAX]; 1469227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1470227825Stheraven n = wcrtomb_l(tmp, intern_type(), &st, __l); 1471227825Stheraven#else 1472227825Stheraven n = __wcrtomb_l(tmp, intern_type(), &st, __l); 1473227825Stheraven#endif 1474227825Stheraven if (n == size_t(-1)) // on error 1475227825Stheraven return error; 1476232950Stheraven if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? 1477227825Stheraven return partial; 1478227825Stheraven for (extern_type* p = tmp; n; --n) // write it 1479227825Stheraven *to_nxt++ = *p++; 1480227825Stheraven ++frm_nxt; 1481227825Stheraven // look for next null in frm 1482227825Stheraven for (fend = frm_nxt; fend != frm_end; ++fend) 1483227825Stheraven if (*fend == 0) 1484227825Stheraven break; 1485227825Stheraven } 1486227825Stheraven } 1487227825Stheraven return frm_nxt == frm_end ? ok : partial; 1488227825Stheraven} 1489227825Stheraven 1490227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1491227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, 1492227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 1493227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 1494227825Stheraven{ 1495227825Stheraven // look for first internal null in frm 1496227825Stheraven const extern_type* fend = frm; 1497227825Stheraven for (; fend != frm_end; ++fend) 1498227825Stheraven if (*fend == 0) 1499227825Stheraven break; 1500227825Stheraven // loop over all null-terminated sequences in frm 1501227825Stheraven to_nxt = to; 1502227825Stheraven for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) 1503227825Stheraven { 1504249998Sdim // save state in case it is needed to recover to_nxt on error 1505227825Stheraven mbstate_t save_state = st; 1506227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1507232950Stheraven size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), 1508232950Stheraven static_cast<size_t>(to_end-to), &st, __l); 1509227825Stheraven#else 1510227825Stheraven size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); 1511227825Stheraven#endif 1512227825Stheraven if (n == size_t(-1)) 1513227825Stheraven { 1514227825Stheraven // need to recover to_nxt 1515227825Stheraven for (to_nxt = to; frm != frm_nxt; ++to_nxt) 1516227825Stheraven { 1517227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1518232950Stheraven n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm), 1519232950Stheraven &save_state, __l); 1520227825Stheraven#else 1521227825Stheraven n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l); 1522227825Stheraven#endif 1523227825Stheraven switch (n) 1524227825Stheraven { 1525227825Stheraven case 0: 1526227825Stheraven ++frm; 1527227825Stheraven break; 1528232950Stheraven case size_t(-1): 1529227825Stheraven frm_nxt = frm; 1530227825Stheraven return error; 1531232950Stheraven case size_t(-2): 1532227825Stheraven frm_nxt = frm; 1533227825Stheraven return partial; 1534227825Stheraven default: 1535227825Stheraven frm += n; 1536227825Stheraven break; 1537227825Stheraven } 1538227825Stheraven } 1539227825Stheraven frm_nxt = frm; 1540227825Stheraven return frm_nxt == frm_end ? ok : partial; 1541227825Stheraven } 1542227825Stheraven if (n == 0) 1543227825Stheraven return error; 1544227825Stheraven to_nxt += n; 1545227825Stheraven if (to_nxt == to_end) 1546227825Stheraven break; 1547227825Stheraven if (fend != frm_end) // set up next null terminated sequence 1548227825Stheraven { 1549227825Stheraven // Try to write the terminating null 1550227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1551227825Stheraven n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); 1552227825Stheraven#else 1553227825Stheraven n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); 1554227825Stheraven#endif 1555227825Stheraven if (n != 0) // on error 1556227825Stheraven return error; 1557227825Stheraven ++to_nxt; 1558227825Stheraven ++frm_nxt; 1559227825Stheraven // look for next null in frm 1560227825Stheraven for (fend = frm_nxt; fend != frm_end; ++fend) 1561227825Stheraven if (*fend == 0) 1562227825Stheraven break; 1563227825Stheraven } 1564227825Stheraven } 1565227825Stheraven return frm_nxt == frm_end ? ok : partial; 1566227825Stheraven} 1567227825Stheraven 1568227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1569227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, 1570227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 1571227825Stheraven{ 1572227825Stheraven to_nxt = to; 1573227825Stheraven extern_type tmp[MB_LEN_MAX]; 1574227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1575227825Stheraven size_t n = wcrtomb_l(tmp, intern_type(), &st, __l); 1576227825Stheraven#else 1577227825Stheraven size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l); 1578227825Stheraven#endif 1579227825Stheraven if (n == size_t(-1) || n == 0) // on error 1580227825Stheraven return error; 1581227825Stheraven --n; 1582232950Stheraven if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? 1583227825Stheraven return partial; 1584227825Stheraven for (extern_type* p = tmp; n; --n) // write it 1585227825Stheraven *to_nxt++ = *p++; 1586227825Stheraven return ok; 1587227825Stheraven} 1588227825Stheraven 1589227825Stheravenint 1590227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 1591227825Stheraven{ 1592227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1593227825Stheraven if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0) 1594227825Stheraven#else 1595227825Stheraven if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0) 1596227825Stheraven#endif 1597227825Stheraven { 1598227825Stheraven // stateless encoding 1599227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1600227825Stheraven if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings 1601227825Stheraven#else 1602227825Stheraven if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings 1603227825Stheraven#endif 1604227825Stheraven return 1; // which take more than 1 char to form a wchar_t 1605227825Stheraven return 0; 1606227825Stheraven } 1607227825Stheraven return -1; 1608227825Stheraven} 1609227825Stheraven 1610227825Stheravenbool 1611227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 1612227825Stheraven{ 1613227825Stheraven return false; 1614227825Stheraven} 1615227825Stheraven 1616227825Stheravenint 1617227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, 1618227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 1619227825Stheraven{ 1620227825Stheraven int nbytes = 0; 1621227825Stheraven for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) 1622227825Stheraven { 1623227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1624232950Stheraven size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l); 1625227825Stheraven#else 1626227825Stheraven size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l); 1627227825Stheraven#endif 1628227825Stheraven switch (n) 1629227825Stheraven { 1630227825Stheraven case 0: 1631227825Stheraven ++nbytes; 1632227825Stheraven ++frm; 1633227825Stheraven break; 1634232950Stheraven case size_t(-1): 1635232950Stheraven case size_t(-2): 1636227825Stheraven return nbytes; 1637227825Stheraven default: 1638227825Stheraven nbytes += n; 1639227825Stheraven frm += n; 1640227825Stheraven break; 1641227825Stheraven } 1642227825Stheraven } 1643227825Stheraven return nbytes; 1644227825Stheraven} 1645227825Stheraven 1646227825Stheravenint 1647227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 1648227825Stheraven{ 1649227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1650249998Sdim return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l)); 1651227825Stheraven#else 1652249998Sdim return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l)); 1653227825Stheraven#endif 1654227825Stheraven} 1655227825Stheraven 1656227825Stheraven// Valid UTF ranges 1657227825Stheraven// UTF-32 UTF-16 UTF-8 # of code points 1658227825Stheraven// first second first second third fourth 1659227825Stheraven// 000000 - 00007F 0000 - 007F 00 - 7F 127 1660227825Stheraven// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920 1661227825Stheraven// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048 1662227825Stheraven// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152 1663227825Stheraven// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048 1664227825Stheraven// 00D800 - 00DFFF invalid 1665227825Stheraven// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192 1666227825Stheraven// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608 1667227825Stheraven// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432 1668227825Stheraven// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536 1669227825Stheraven 1670227825Stheravenstatic 1671227825Stheravencodecvt_base::result 1672227825Stheravenutf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 1673227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 1674227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1675227825Stheraven{ 1676227825Stheraven frm_nxt = frm; 1677227825Stheraven to_nxt = to; 1678227825Stheraven if (mode & generate_header) 1679227825Stheraven { 1680227825Stheraven if (to_end-to_nxt < 3) 1681227825Stheraven return codecvt_base::partial; 1682227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 1683227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 1684227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 1685227825Stheraven } 1686227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 1687227825Stheraven { 1688227825Stheraven uint16_t wc1 = *frm_nxt; 1689227825Stheraven if (wc1 > Maxcode) 1690227825Stheraven return codecvt_base::error; 1691227825Stheraven if (wc1 < 0x0080) 1692227825Stheraven { 1693227825Stheraven if (to_end-to_nxt < 1) 1694227825Stheraven return codecvt_base::partial; 1695227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc1); 1696227825Stheraven } 1697227825Stheraven else if (wc1 < 0x0800) 1698227825Stheraven { 1699227825Stheraven if (to_end-to_nxt < 2) 1700227825Stheraven return codecvt_base::partial; 1701227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6)); 1702227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F)); 1703227825Stheraven } 1704227825Stheraven else if (wc1 < 0xD800) 1705227825Stheraven { 1706227825Stheraven if (to_end-to_nxt < 3) 1707227825Stheraven return codecvt_base::partial; 1708227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1709227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1710227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1711227825Stheraven } 1712227825Stheraven else if (wc1 < 0xDC00) 1713227825Stheraven { 1714227825Stheraven if (frm_end-frm_nxt < 2) 1715227825Stheraven return codecvt_base::partial; 1716227825Stheraven uint16_t wc2 = frm_nxt[1]; 1717227825Stheraven if ((wc2 & 0xFC00) != 0xDC00) 1718227825Stheraven return codecvt_base::error; 1719227825Stheraven if (to_end-to_nxt < 4) 1720227825Stheraven return codecvt_base::partial; 1721227825Stheraven if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) + 1722227825Stheraven (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode) 1723227825Stheraven return codecvt_base::error; 1724227825Stheraven ++frm_nxt; 1725227825Stheraven uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; 1726227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2)); 1727227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); 1728227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); 1729227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F)); 1730227825Stheraven } 1731227825Stheraven else if (wc1 < 0xE000) 1732227825Stheraven { 1733227825Stheraven return codecvt_base::error; 1734227825Stheraven } 1735227825Stheraven else 1736227825Stheraven { 1737227825Stheraven if (to_end-to_nxt < 3) 1738227825Stheraven return codecvt_base::partial; 1739227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1740227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1741227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1742227825Stheraven } 1743227825Stheraven } 1744227825Stheraven return codecvt_base::ok; 1745227825Stheraven} 1746227825Stheraven 1747227825Stheravenstatic 1748227825Stheravencodecvt_base::result 1749227825Stheravenutf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 1750227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 1751227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1752227825Stheraven{ 1753227825Stheraven frm_nxt = frm; 1754227825Stheraven to_nxt = to; 1755227825Stheraven if (mode & generate_header) 1756227825Stheraven { 1757227825Stheraven if (to_end-to_nxt < 3) 1758227825Stheraven return codecvt_base::partial; 1759227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 1760227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 1761227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 1762227825Stheraven } 1763227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 1764227825Stheraven { 1765227825Stheraven uint16_t wc1 = static_cast<uint16_t>(*frm_nxt); 1766227825Stheraven if (wc1 > Maxcode) 1767227825Stheraven return codecvt_base::error; 1768227825Stheraven if (wc1 < 0x0080) 1769227825Stheraven { 1770227825Stheraven if (to_end-to_nxt < 1) 1771227825Stheraven return codecvt_base::partial; 1772227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc1); 1773227825Stheraven } 1774227825Stheraven else if (wc1 < 0x0800) 1775227825Stheraven { 1776227825Stheraven if (to_end-to_nxt < 2) 1777227825Stheraven return codecvt_base::partial; 1778227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6)); 1779227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F)); 1780227825Stheraven } 1781227825Stheraven else if (wc1 < 0xD800) 1782227825Stheraven { 1783227825Stheraven if (to_end-to_nxt < 3) 1784227825Stheraven return codecvt_base::partial; 1785227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1786227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1787227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1788227825Stheraven } 1789227825Stheraven else if (wc1 < 0xDC00) 1790227825Stheraven { 1791227825Stheraven if (frm_end-frm_nxt < 2) 1792227825Stheraven return codecvt_base::partial; 1793227825Stheraven uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]); 1794227825Stheraven if ((wc2 & 0xFC00) != 0xDC00) 1795227825Stheraven return codecvt_base::error; 1796227825Stheraven if (to_end-to_nxt < 4) 1797227825Stheraven return codecvt_base::partial; 1798227825Stheraven if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) + 1799227825Stheraven (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode) 1800227825Stheraven return codecvt_base::error; 1801227825Stheraven ++frm_nxt; 1802227825Stheraven uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; 1803227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2)); 1804227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); 1805227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); 1806227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F)); 1807227825Stheraven } 1808227825Stheraven else if (wc1 < 0xE000) 1809227825Stheraven { 1810227825Stheraven return codecvt_base::error; 1811227825Stheraven } 1812227825Stheraven else 1813227825Stheraven { 1814227825Stheraven if (to_end-to_nxt < 3) 1815227825Stheraven return codecvt_base::partial; 1816227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1817227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1818227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1819227825Stheraven } 1820227825Stheraven } 1821227825Stheraven return codecvt_base::ok; 1822227825Stheraven} 1823227825Stheraven 1824227825Stheravenstatic 1825227825Stheravencodecvt_base::result 1826227825Stheravenutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 1827227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 1828227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1829227825Stheraven{ 1830227825Stheraven frm_nxt = frm; 1831227825Stheraven to_nxt = to; 1832227825Stheraven if (mode & consume_header) 1833227825Stheraven { 1834227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 1835227825Stheraven frm_nxt[2] == 0xBF) 1836227825Stheraven frm_nxt += 3; 1837227825Stheraven } 1838227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 1839227825Stheraven { 1840227825Stheraven uint8_t c1 = *frm_nxt; 1841227825Stheraven if (c1 > Maxcode) 1842227825Stheraven return codecvt_base::error; 1843227825Stheraven if (c1 < 0x80) 1844227825Stheraven { 1845227825Stheraven *to_nxt = static_cast<uint16_t>(c1); 1846227825Stheraven ++frm_nxt; 1847227825Stheraven } 1848227825Stheraven else if (c1 < 0xC2) 1849227825Stheraven { 1850227825Stheraven return codecvt_base::error; 1851227825Stheraven } 1852227825Stheraven else if (c1 < 0xE0) 1853227825Stheraven { 1854227825Stheraven if (frm_end-frm_nxt < 2) 1855227825Stheraven return codecvt_base::partial; 1856227825Stheraven uint8_t c2 = frm_nxt[1]; 1857227825Stheraven if ((c2 & 0xC0) != 0x80) 1858227825Stheraven return codecvt_base::error; 1859227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 1860227825Stheraven if (t > Maxcode) 1861227825Stheraven return codecvt_base::error; 1862227825Stheraven *to_nxt = t; 1863227825Stheraven frm_nxt += 2; 1864227825Stheraven } 1865227825Stheraven else if (c1 < 0xF0) 1866227825Stheraven { 1867227825Stheraven if (frm_end-frm_nxt < 3) 1868227825Stheraven return codecvt_base::partial; 1869227825Stheraven uint8_t c2 = frm_nxt[1]; 1870227825Stheraven uint8_t c3 = frm_nxt[2]; 1871227825Stheraven switch (c1) 1872227825Stheraven { 1873227825Stheraven case 0xE0: 1874227825Stheraven if ((c2 & 0xE0) != 0xA0) 1875227825Stheraven return codecvt_base::error; 1876227825Stheraven break; 1877227825Stheraven case 0xED: 1878227825Stheraven if ((c2 & 0xE0) != 0x80) 1879227825Stheraven return codecvt_base::error; 1880227825Stheraven break; 1881227825Stheraven default: 1882227825Stheraven if ((c2 & 0xC0) != 0x80) 1883227825Stheraven return codecvt_base::error; 1884227825Stheraven break; 1885227825Stheraven } 1886227825Stheraven if ((c3 & 0xC0) != 0x80) 1887227825Stheraven return codecvt_base::error; 1888227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 1889227825Stheraven | ((c2 & 0x3F) << 6) 1890227825Stheraven | (c3 & 0x3F)); 1891227825Stheraven if (t > Maxcode) 1892227825Stheraven return codecvt_base::error; 1893227825Stheraven *to_nxt = t; 1894227825Stheraven frm_nxt += 3; 1895227825Stheraven } 1896227825Stheraven else if (c1 < 0xF5) 1897227825Stheraven { 1898227825Stheraven if (frm_end-frm_nxt < 4) 1899227825Stheraven return codecvt_base::partial; 1900227825Stheraven uint8_t c2 = frm_nxt[1]; 1901227825Stheraven uint8_t c3 = frm_nxt[2]; 1902227825Stheraven uint8_t c4 = frm_nxt[3]; 1903227825Stheraven switch (c1) 1904227825Stheraven { 1905227825Stheraven case 0xF0: 1906227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 1907227825Stheraven return codecvt_base::error; 1908227825Stheraven break; 1909227825Stheraven case 0xF4: 1910227825Stheraven if ((c2 & 0xF0) != 0x80) 1911227825Stheraven return codecvt_base::error; 1912227825Stheraven break; 1913227825Stheraven default: 1914227825Stheraven if ((c2 & 0xC0) != 0x80) 1915227825Stheraven return codecvt_base::error; 1916227825Stheraven break; 1917227825Stheraven } 1918227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 1919227825Stheraven return codecvt_base::error; 1920227825Stheraven if (to_end-to_nxt < 2) 1921227825Stheraven return codecvt_base::partial; 1922227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 1923227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 1924227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 1925227825Stheraven return codecvt_base::error; 1926227825Stheraven *to_nxt = static_cast<uint16_t>( 1927227825Stheraven 0xD800 1928227825Stheraven | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) 1929227825Stheraven | ((c2 & 0x0F) << 2) 1930227825Stheraven | ((c3 & 0x30) >> 4)); 1931227825Stheraven *++to_nxt = static_cast<uint16_t>( 1932227825Stheraven 0xDC00 1933227825Stheraven | ((c3 & 0x0F) << 6) 1934227825Stheraven | (c4 & 0x3F)); 1935227825Stheraven frm_nxt += 4; 1936227825Stheraven } 1937227825Stheraven else 1938227825Stheraven { 1939227825Stheraven return codecvt_base::error; 1940227825Stheraven } 1941227825Stheraven } 1942227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 1943227825Stheraven} 1944227825Stheraven 1945227825Stheravenstatic 1946227825Stheravencodecvt_base::result 1947227825Stheravenutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 1948227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 1949227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1950227825Stheraven{ 1951227825Stheraven frm_nxt = frm; 1952227825Stheraven to_nxt = to; 1953227825Stheraven if (mode & consume_header) 1954227825Stheraven { 1955227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 1956227825Stheraven frm_nxt[2] == 0xBF) 1957227825Stheraven frm_nxt += 3; 1958227825Stheraven } 1959227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 1960227825Stheraven { 1961227825Stheraven uint8_t c1 = *frm_nxt; 1962227825Stheraven if (c1 > Maxcode) 1963227825Stheraven return codecvt_base::error; 1964227825Stheraven if (c1 < 0x80) 1965227825Stheraven { 1966227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 1967227825Stheraven ++frm_nxt; 1968227825Stheraven } 1969227825Stheraven else if (c1 < 0xC2) 1970227825Stheraven { 1971227825Stheraven return codecvt_base::error; 1972227825Stheraven } 1973227825Stheraven else if (c1 < 0xE0) 1974227825Stheraven { 1975227825Stheraven if (frm_end-frm_nxt < 2) 1976227825Stheraven return codecvt_base::partial; 1977227825Stheraven uint8_t c2 = frm_nxt[1]; 1978227825Stheraven if ((c2 & 0xC0) != 0x80) 1979227825Stheraven return codecvt_base::error; 1980227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 1981227825Stheraven if (t > Maxcode) 1982227825Stheraven return codecvt_base::error; 1983227825Stheraven *to_nxt = static_cast<uint32_t>(t); 1984227825Stheraven frm_nxt += 2; 1985227825Stheraven } 1986227825Stheraven else if (c1 < 0xF0) 1987227825Stheraven { 1988227825Stheraven if (frm_end-frm_nxt < 3) 1989227825Stheraven return codecvt_base::partial; 1990227825Stheraven uint8_t c2 = frm_nxt[1]; 1991227825Stheraven uint8_t c3 = frm_nxt[2]; 1992227825Stheraven switch (c1) 1993227825Stheraven { 1994227825Stheraven case 0xE0: 1995227825Stheraven if ((c2 & 0xE0) != 0xA0) 1996227825Stheraven return codecvt_base::error; 1997227825Stheraven break; 1998227825Stheraven case 0xED: 1999227825Stheraven if ((c2 & 0xE0) != 0x80) 2000227825Stheraven return codecvt_base::error; 2001227825Stheraven break; 2002227825Stheraven default: 2003227825Stheraven if ((c2 & 0xC0) != 0x80) 2004227825Stheraven return codecvt_base::error; 2005227825Stheraven break; 2006227825Stheraven } 2007227825Stheraven if ((c3 & 0xC0) != 0x80) 2008227825Stheraven return codecvt_base::error; 2009227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 2010227825Stheraven | ((c2 & 0x3F) << 6) 2011227825Stheraven | (c3 & 0x3F)); 2012227825Stheraven if (t > Maxcode) 2013227825Stheraven return codecvt_base::error; 2014227825Stheraven *to_nxt = static_cast<uint32_t>(t); 2015227825Stheraven frm_nxt += 3; 2016227825Stheraven } 2017227825Stheraven else if (c1 < 0xF5) 2018227825Stheraven { 2019227825Stheraven if (frm_end-frm_nxt < 4) 2020227825Stheraven return codecvt_base::partial; 2021227825Stheraven uint8_t c2 = frm_nxt[1]; 2022227825Stheraven uint8_t c3 = frm_nxt[2]; 2023227825Stheraven uint8_t c4 = frm_nxt[3]; 2024227825Stheraven switch (c1) 2025227825Stheraven { 2026227825Stheraven case 0xF0: 2027227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2028227825Stheraven return codecvt_base::error; 2029227825Stheraven break; 2030227825Stheraven case 0xF4: 2031227825Stheraven if ((c2 & 0xF0) != 0x80) 2032227825Stheraven return codecvt_base::error; 2033227825Stheraven break; 2034227825Stheraven default: 2035227825Stheraven if ((c2 & 0xC0) != 0x80) 2036227825Stheraven return codecvt_base::error; 2037227825Stheraven break; 2038227825Stheraven } 2039227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2040227825Stheraven return codecvt_base::error; 2041227825Stheraven if (to_end-to_nxt < 2) 2042227825Stheraven return codecvt_base::partial; 2043227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 2044227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 2045227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 2046227825Stheraven return codecvt_base::error; 2047227825Stheraven *to_nxt = static_cast<uint32_t>( 2048227825Stheraven 0xD800 2049227825Stheraven | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) 2050227825Stheraven | ((c2 & 0x0F) << 2) 2051227825Stheraven | ((c3 & 0x30) >> 4)); 2052227825Stheraven *++to_nxt = static_cast<uint32_t>( 2053227825Stheraven 0xDC00 2054227825Stheraven | ((c3 & 0x0F) << 6) 2055227825Stheraven | (c4 & 0x3F)); 2056227825Stheraven frm_nxt += 4; 2057227825Stheraven } 2058227825Stheraven else 2059227825Stheraven { 2060227825Stheraven return codecvt_base::error; 2061227825Stheraven } 2062227825Stheraven } 2063227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2064227825Stheraven} 2065227825Stheraven 2066227825Stheravenstatic 2067227825Stheravenint 2068227825Stheravenutf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end, 2069227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2070227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2071227825Stheraven{ 2072227825Stheraven const uint8_t* frm_nxt = frm; 2073227825Stheraven if (mode & consume_header) 2074227825Stheraven { 2075227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2076227825Stheraven frm_nxt[2] == 0xBF) 2077227825Stheraven frm_nxt += 3; 2078227825Stheraven } 2079227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) 2080227825Stheraven { 2081227825Stheraven uint8_t c1 = *frm_nxt; 2082227825Stheraven if (c1 > Maxcode) 2083227825Stheraven break; 2084227825Stheraven if (c1 < 0x80) 2085227825Stheraven { 2086227825Stheraven ++frm_nxt; 2087227825Stheraven } 2088227825Stheraven else if (c1 < 0xC2) 2089227825Stheraven { 2090227825Stheraven break; 2091227825Stheraven } 2092227825Stheraven else if (c1 < 0xE0) 2093227825Stheraven { 2094227825Stheraven if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80) 2095227825Stheraven break; 2096227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)); 2097227825Stheraven if (t > Maxcode) 2098227825Stheraven break; 2099227825Stheraven frm_nxt += 2; 2100227825Stheraven } 2101227825Stheraven else if (c1 < 0xF0) 2102227825Stheraven { 2103227825Stheraven if (frm_end-frm_nxt < 3) 2104227825Stheraven break; 2105227825Stheraven uint8_t c2 = frm_nxt[1]; 2106227825Stheraven uint8_t c3 = frm_nxt[2]; 2107227825Stheraven switch (c1) 2108227825Stheraven { 2109227825Stheraven case 0xE0: 2110227825Stheraven if ((c2 & 0xE0) != 0xA0) 2111227825Stheraven return static_cast<int>(frm_nxt - frm); 2112227825Stheraven break; 2113227825Stheraven case 0xED: 2114227825Stheraven if ((c2 & 0xE0) != 0x80) 2115227825Stheraven return static_cast<int>(frm_nxt - frm); 2116227825Stheraven break; 2117227825Stheraven default: 2118227825Stheraven if ((c2 & 0xC0) != 0x80) 2119227825Stheraven return static_cast<int>(frm_nxt - frm); 2120227825Stheraven break; 2121227825Stheraven } 2122227825Stheraven if ((c3 & 0xC0) != 0x80) 2123227825Stheraven break; 2124232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2125227825Stheraven break; 2126227825Stheraven frm_nxt += 3; 2127227825Stheraven } 2128227825Stheraven else if (c1 < 0xF5) 2129227825Stheraven { 2130227825Stheraven if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2) 2131227825Stheraven break; 2132227825Stheraven uint8_t c2 = frm_nxt[1]; 2133227825Stheraven uint8_t c3 = frm_nxt[2]; 2134227825Stheraven uint8_t c4 = frm_nxt[3]; 2135227825Stheraven switch (c1) 2136227825Stheraven { 2137227825Stheraven case 0xF0: 2138227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2139227825Stheraven return static_cast<int>(frm_nxt - frm); 2140227825Stheraven break; 2141227825Stheraven case 0xF4: 2142227825Stheraven if ((c2 & 0xF0) != 0x80) 2143227825Stheraven return static_cast<int>(frm_nxt - frm); 2144227825Stheraven break; 2145227825Stheraven default: 2146227825Stheraven if ((c2 & 0xC0) != 0x80) 2147227825Stheraven return static_cast<int>(frm_nxt - frm); 2148227825Stheraven break; 2149227825Stheraven } 2150227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2151227825Stheraven break; 2152227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 2153227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 2154227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 2155227825Stheraven break; 2156227825Stheraven ++nchar16_t; 2157227825Stheraven frm_nxt += 4; 2158227825Stheraven } 2159227825Stheraven else 2160227825Stheraven { 2161227825Stheraven break; 2162227825Stheraven } 2163227825Stheraven } 2164227825Stheraven return static_cast<int>(frm_nxt - frm); 2165227825Stheraven} 2166227825Stheraven 2167227825Stheravenstatic 2168227825Stheravencodecvt_base::result 2169227825Stheravenucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2170227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2171227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2172227825Stheraven{ 2173227825Stheraven frm_nxt = frm; 2174227825Stheraven to_nxt = to; 2175227825Stheraven if (mode & generate_header) 2176227825Stheraven { 2177227825Stheraven if (to_end-to_nxt < 3) 2178227825Stheraven return codecvt_base::partial; 2179227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 2180227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 2181227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 2182227825Stheraven } 2183227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2184227825Stheraven { 2185227825Stheraven uint32_t wc = *frm_nxt; 2186227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2187227825Stheraven return codecvt_base::error; 2188227825Stheraven if (wc < 0x000080) 2189227825Stheraven { 2190227825Stheraven if (to_end-to_nxt < 1) 2191227825Stheraven return codecvt_base::partial; 2192227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2193227825Stheraven } 2194227825Stheraven else if (wc < 0x000800) 2195227825Stheraven { 2196227825Stheraven if (to_end-to_nxt < 2) 2197227825Stheraven return codecvt_base::partial; 2198227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6)); 2199227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F)); 2200227825Stheraven } 2201227825Stheraven else if (wc < 0x010000) 2202227825Stheraven { 2203227825Stheraven if (to_end-to_nxt < 3) 2204227825Stheraven return codecvt_base::partial; 2205227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12)); 2206227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6)); 2207227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F)); 2208227825Stheraven } 2209227825Stheraven else // if (wc < 0x110000) 2210227825Stheraven { 2211227825Stheraven if (to_end-to_nxt < 4) 2212227825Stheraven return codecvt_base::partial; 2213227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18)); 2214227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12)); 2215227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6)); 2216227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F)); 2217227825Stheraven } 2218227825Stheraven } 2219227825Stheraven return codecvt_base::ok; 2220227825Stheraven} 2221227825Stheraven 2222227825Stheravenstatic 2223227825Stheravencodecvt_base::result 2224227825Stheravenutf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2225227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2226227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2227227825Stheraven{ 2228227825Stheraven frm_nxt = frm; 2229227825Stheraven to_nxt = to; 2230227825Stheraven if (mode & consume_header) 2231227825Stheraven { 2232227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2233227825Stheraven frm_nxt[2] == 0xBF) 2234227825Stheraven frm_nxt += 3; 2235227825Stheraven } 2236227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 2237227825Stheraven { 2238227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2239227825Stheraven if (c1 < 0x80) 2240227825Stheraven { 2241227825Stheraven if (c1 > Maxcode) 2242227825Stheraven return codecvt_base::error; 2243227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2244227825Stheraven ++frm_nxt; 2245227825Stheraven } 2246227825Stheraven else if (c1 < 0xC2) 2247227825Stheraven { 2248227825Stheraven return codecvt_base::error; 2249227825Stheraven } 2250227825Stheraven else if (c1 < 0xE0) 2251227825Stheraven { 2252227825Stheraven if (frm_end-frm_nxt < 2) 2253227825Stheraven return codecvt_base::partial; 2254227825Stheraven uint8_t c2 = frm_nxt[1]; 2255227825Stheraven if ((c2 & 0xC0) != 0x80) 2256227825Stheraven return codecvt_base::error; 2257227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) 2258227825Stheraven | (c2 & 0x3F)); 2259227825Stheraven if (t > Maxcode) 2260227825Stheraven return codecvt_base::error; 2261227825Stheraven *to_nxt = t; 2262227825Stheraven frm_nxt += 2; 2263227825Stheraven } 2264227825Stheraven else if (c1 < 0xF0) 2265227825Stheraven { 2266227825Stheraven if (frm_end-frm_nxt < 3) 2267227825Stheraven return codecvt_base::partial; 2268227825Stheraven uint8_t c2 = frm_nxt[1]; 2269227825Stheraven uint8_t c3 = frm_nxt[2]; 2270227825Stheraven switch (c1) 2271227825Stheraven { 2272227825Stheraven case 0xE0: 2273227825Stheraven if ((c2 & 0xE0) != 0xA0) 2274227825Stheraven return codecvt_base::error; 2275227825Stheraven break; 2276227825Stheraven case 0xED: 2277227825Stheraven if ((c2 & 0xE0) != 0x80) 2278227825Stheraven return codecvt_base::error; 2279227825Stheraven break; 2280227825Stheraven default: 2281227825Stheraven if ((c2 & 0xC0) != 0x80) 2282227825Stheraven return codecvt_base::error; 2283227825Stheraven break; 2284227825Stheraven } 2285227825Stheraven if ((c3 & 0xC0) != 0x80) 2286227825Stheraven return codecvt_base::error; 2287227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) 2288227825Stheraven | ((c2 & 0x3F) << 6) 2289227825Stheraven | (c3 & 0x3F)); 2290227825Stheraven if (t > Maxcode) 2291227825Stheraven return codecvt_base::error; 2292227825Stheraven *to_nxt = t; 2293227825Stheraven frm_nxt += 3; 2294227825Stheraven } 2295227825Stheraven else if (c1 < 0xF5) 2296227825Stheraven { 2297227825Stheraven if (frm_end-frm_nxt < 4) 2298227825Stheraven return codecvt_base::partial; 2299227825Stheraven uint8_t c2 = frm_nxt[1]; 2300227825Stheraven uint8_t c3 = frm_nxt[2]; 2301227825Stheraven uint8_t c4 = frm_nxt[3]; 2302227825Stheraven switch (c1) 2303227825Stheraven { 2304227825Stheraven case 0xF0: 2305227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2306227825Stheraven return codecvt_base::error; 2307227825Stheraven break; 2308227825Stheraven case 0xF4: 2309227825Stheraven if ((c2 & 0xF0) != 0x80) 2310227825Stheraven return codecvt_base::error; 2311227825Stheraven break; 2312227825Stheraven default: 2313227825Stheraven if ((c2 & 0xC0) != 0x80) 2314227825Stheraven return codecvt_base::error; 2315227825Stheraven break; 2316227825Stheraven } 2317227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2318227825Stheraven return codecvt_base::error; 2319227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) 2320227825Stheraven | ((c2 & 0x3F) << 12) 2321227825Stheraven | ((c3 & 0x3F) << 6) 2322227825Stheraven | (c4 & 0x3F)); 2323227825Stheraven if (t > Maxcode) 2324227825Stheraven return codecvt_base::error; 2325227825Stheraven *to_nxt = t; 2326227825Stheraven frm_nxt += 4; 2327227825Stheraven } 2328227825Stheraven else 2329227825Stheraven { 2330227825Stheraven return codecvt_base::error; 2331227825Stheraven } 2332227825Stheraven } 2333227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2334227825Stheraven} 2335227825Stheraven 2336227825Stheravenstatic 2337227825Stheravenint 2338227825Stheravenutf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2339227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2340227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2341227825Stheraven{ 2342227825Stheraven const uint8_t* frm_nxt = frm; 2343227825Stheraven if (mode & consume_header) 2344227825Stheraven { 2345227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2346227825Stheraven frm_nxt[2] == 0xBF) 2347227825Stheraven frm_nxt += 3; 2348227825Stheraven } 2349227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) 2350227825Stheraven { 2351227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2352227825Stheraven if (c1 < 0x80) 2353227825Stheraven { 2354227825Stheraven if (c1 > Maxcode) 2355227825Stheraven break; 2356227825Stheraven ++frm_nxt; 2357227825Stheraven } 2358227825Stheraven else if (c1 < 0xC2) 2359227825Stheraven { 2360227825Stheraven break; 2361227825Stheraven } 2362227825Stheraven else if (c1 < 0xE0) 2363227825Stheraven { 2364227825Stheraven if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) 2365227825Stheraven break; 2366232950Stheraven if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) 2367227825Stheraven break; 2368227825Stheraven frm_nxt += 2; 2369227825Stheraven } 2370227825Stheraven else if (c1 < 0xF0) 2371227825Stheraven { 2372227825Stheraven if (frm_end-frm_nxt < 3) 2373227825Stheraven break; 2374227825Stheraven uint8_t c2 = frm_nxt[1]; 2375227825Stheraven uint8_t c3 = frm_nxt[2]; 2376227825Stheraven switch (c1) 2377227825Stheraven { 2378227825Stheraven case 0xE0: 2379227825Stheraven if ((c2 & 0xE0) != 0xA0) 2380227825Stheraven return static_cast<int>(frm_nxt - frm); 2381227825Stheraven break; 2382227825Stheraven case 0xED: 2383227825Stheraven if ((c2 & 0xE0) != 0x80) 2384227825Stheraven return static_cast<int>(frm_nxt - frm); 2385227825Stheraven break; 2386227825Stheraven default: 2387227825Stheraven if ((c2 & 0xC0) != 0x80) 2388227825Stheraven return static_cast<int>(frm_nxt - frm); 2389227825Stheraven break; 2390227825Stheraven } 2391227825Stheraven if ((c3 & 0xC0) != 0x80) 2392227825Stheraven break; 2393232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2394227825Stheraven break; 2395227825Stheraven frm_nxt += 3; 2396227825Stheraven } 2397227825Stheraven else if (c1 < 0xF5) 2398227825Stheraven { 2399227825Stheraven if (frm_end-frm_nxt < 4) 2400227825Stheraven break; 2401227825Stheraven uint8_t c2 = frm_nxt[1]; 2402227825Stheraven uint8_t c3 = frm_nxt[2]; 2403227825Stheraven uint8_t c4 = frm_nxt[3]; 2404227825Stheraven switch (c1) 2405227825Stheraven { 2406227825Stheraven case 0xF0: 2407227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2408227825Stheraven return static_cast<int>(frm_nxt - frm); 2409227825Stheraven break; 2410227825Stheraven case 0xF4: 2411227825Stheraven if ((c2 & 0xF0) != 0x80) 2412227825Stheraven return static_cast<int>(frm_nxt - frm); 2413227825Stheraven break; 2414227825Stheraven default: 2415227825Stheraven if ((c2 & 0xC0) != 0x80) 2416227825Stheraven return static_cast<int>(frm_nxt - frm); 2417227825Stheraven break; 2418227825Stheraven } 2419227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2420227825Stheraven break; 2421232950Stheraven if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | 2422232950Stheraven ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode) 2423227825Stheraven break; 2424227825Stheraven frm_nxt += 4; 2425227825Stheraven } 2426227825Stheraven else 2427227825Stheraven { 2428227825Stheraven break; 2429227825Stheraven } 2430227825Stheraven } 2431227825Stheraven return static_cast<int>(frm_nxt - frm); 2432227825Stheraven} 2433227825Stheraven 2434227825Stheravenstatic 2435227825Stheravencodecvt_base::result 2436227825Stheravenucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2437227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2438227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2439227825Stheraven{ 2440227825Stheraven frm_nxt = frm; 2441227825Stheraven to_nxt = to; 2442227825Stheraven if (mode & generate_header) 2443227825Stheraven { 2444227825Stheraven if (to_end-to_nxt < 3) 2445227825Stheraven return codecvt_base::partial; 2446227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 2447227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 2448227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 2449227825Stheraven } 2450227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2451227825Stheraven { 2452227825Stheraven uint16_t wc = *frm_nxt; 2453227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2454227825Stheraven return codecvt_base::error; 2455227825Stheraven if (wc < 0x0080) 2456227825Stheraven { 2457227825Stheraven if (to_end-to_nxt < 1) 2458227825Stheraven return codecvt_base::partial; 2459227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2460227825Stheraven } 2461227825Stheraven else if (wc < 0x0800) 2462227825Stheraven { 2463227825Stheraven if (to_end-to_nxt < 2) 2464227825Stheraven return codecvt_base::partial; 2465227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6)); 2466227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F)); 2467227825Stheraven } 2468227825Stheraven else // if (wc <= 0xFFFF) 2469227825Stheraven { 2470227825Stheraven if (to_end-to_nxt < 3) 2471227825Stheraven return codecvt_base::partial; 2472227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12)); 2473227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6)); 2474227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F)); 2475227825Stheraven } 2476227825Stheraven } 2477227825Stheraven return codecvt_base::ok; 2478227825Stheraven} 2479227825Stheraven 2480227825Stheravenstatic 2481227825Stheravencodecvt_base::result 2482227825Stheravenutf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2483227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2484227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2485227825Stheraven{ 2486227825Stheraven frm_nxt = frm; 2487227825Stheraven to_nxt = to; 2488227825Stheraven if (mode & consume_header) 2489227825Stheraven { 2490227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2491227825Stheraven frm_nxt[2] == 0xBF) 2492227825Stheraven frm_nxt += 3; 2493227825Stheraven } 2494227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 2495227825Stheraven { 2496227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2497227825Stheraven if (c1 < 0x80) 2498227825Stheraven { 2499227825Stheraven if (c1 > Maxcode) 2500227825Stheraven return codecvt_base::error; 2501227825Stheraven *to_nxt = static_cast<uint16_t>(c1); 2502227825Stheraven ++frm_nxt; 2503227825Stheraven } 2504227825Stheraven else if (c1 < 0xC2) 2505227825Stheraven { 2506227825Stheraven return codecvt_base::error; 2507227825Stheraven } 2508227825Stheraven else if (c1 < 0xE0) 2509227825Stheraven { 2510227825Stheraven if (frm_end-frm_nxt < 2) 2511227825Stheraven return codecvt_base::partial; 2512227825Stheraven uint8_t c2 = frm_nxt[1]; 2513227825Stheraven if ((c2 & 0xC0) != 0x80) 2514227825Stheraven return codecvt_base::error; 2515227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) 2516227825Stheraven | (c2 & 0x3F)); 2517227825Stheraven if (t > Maxcode) 2518227825Stheraven return codecvt_base::error; 2519227825Stheraven *to_nxt = t; 2520227825Stheraven frm_nxt += 2; 2521227825Stheraven } 2522227825Stheraven else if (c1 < 0xF0) 2523227825Stheraven { 2524227825Stheraven if (frm_end-frm_nxt < 3) 2525227825Stheraven return codecvt_base::partial; 2526227825Stheraven uint8_t c2 = frm_nxt[1]; 2527227825Stheraven uint8_t c3 = frm_nxt[2]; 2528227825Stheraven switch (c1) 2529227825Stheraven { 2530227825Stheraven case 0xE0: 2531227825Stheraven if ((c2 & 0xE0) != 0xA0) 2532227825Stheraven return codecvt_base::error; 2533227825Stheraven break; 2534227825Stheraven case 0xED: 2535227825Stheraven if ((c2 & 0xE0) != 0x80) 2536227825Stheraven return codecvt_base::error; 2537227825Stheraven break; 2538227825Stheraven default: 2539227825Stheraven if ((c2 & 0xC0) != 0x80) 2540227825Stheraven return codecvt_base::error; 2541227825Stheraven break; 2542227825Stheraven } 2543227825Stheraven if ((c3 & 0xC0) != 0x80) 2544227825Stheraven return codecvt_base::error; 2545227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 2546227825Stheraven | ((c2 & 0x3F) << 6) 2547227825Stheraven | (c3 & 0x3F)); 2548227825Stheraven if (t > Maxcode) 2549227825Stheraven return codecvt_base::error; 2550227825Stheraven *to_nxt = t; 2551227825Stheraven frm_nxt += 3; 2552227825Stheraven } 2553227825Stheraven else 2554227825Stheraven { 2555227825Stheraven return codecvt_base::error; 2556227825Stheraven } 2557227825Stheraven } 2558227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2559227825Stheraven} 2560227825Stheraven 2561227825Stheravenstatic 2562227825Stheravenint 2563227825Stheravenutf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2564227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2565227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2566227825Stheraven{ 2567227825Stheraven const uint8_t* frm_nxt = frm; 2568227825Stheraven if (mode & consume_header) 2569227825Stheraven { 2570227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2571227825Stheraven frm_nxt[2] == 0xBF) 2572227825Stheraven frm_nxt += 3; 2573227825Stheraven } 2574227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) 2575227825Stheraven { 2576227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2577227825Stheraven if (c1 < 0x80) 2578227825Stheraven { 2579227825Stheraven if (c1 > Maxcode) 2580227825Stheraven break; 2581227825Stheraven ++frm_nxt; 2582227825Stheraven } 2583227825Stheraven else if (c1 < 0xC2) 2584227825Stheraven { 2585227825Stheraven break; 2586227825Stheraven } 2587227825Stheraven else if (c1 < 0xE0) 2588227825Stheraven { 2589227825Stheraven if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) 2590227825Stheraven break; 2591232950Stheraven if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) 2592227825Stheraven break; 2593227825Stheraven frm_nxt += 2; 2594227825Stheraven } 2595227825Stheraven else if (c1 < 0xF0) 2596227825Stheraven { 2597227825Stheraven if (frm_end-frm_nxt < 3) 2598227825Stheraven break; 2599227825Stheraven uint8_t c2 = frm_nxt[1]; 2600227825Stheraven uint8_t c3 = frm_nxt[2]; 2601227825Stheraven switch (c1) 2602227825Stheraven { 2603227825Stheraven case 0xE0: 2604227825Stheraven if ((c2 & 0xE0) != 0xA0) 2605227825Stheraven return static_cast<int>(frm_nxt - frm); 2606227825Stheraven break; 2607227825Stheraven case 0xED: 2608227825Stheraven if ((c2 & 0xE0) != 0x80) 2609227825Stheraven return static_cast<int>(frm_nxt - frm); 2610227825Stheraven break; 2611227825Stheraven default: 2612227825Stheraven if ((c2 & 0xC0) != 0x80) 2613227825Stheraven return static_cast<int>(frm_nxt - frm); 2614227825Stheraven break; 2615227825Stheraven } 2616227825Stheraven if ((c3 & 0xC0) != 0x80) 2617227825Stheraven break; 2618232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2619227825Stheraven break; 2620227825Stheraven frm_nxt += 3; 2621227825Stheraven } 2622227825Stheraven else 2623227825Stheraven { 2624227825Stheraven break; 2625227825Stheraven } 2626227825Stheraven } 2627227825Stheraven return static_cast<int>(frm_nxt - frm); 2628227825Stheraven} 2629227825Stheraven 2630227825Stheravenstatic 2631227825Stheravencodecvt_base::result 2632227825Stheravenucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2633227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2634227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2635227825Stheraven{ 2636227825Stheraven frm_nxt = frm; 2637227825Stheraven to_nxt = to; 2638227825Stheraven if (mode & generate_header) 2639227825Stheraven { 2640227825Stheraven if (to_end-to_nxt < 2) 2641227825Stheraven return codecvt_base::partial; 2642227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2643227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2644227825Stheraven } 2645227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2646227825Stheraven { 2647227825Stheraven uint32_t wc = *frm_nxt; 2648227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2649227825Stheraven return codecvt_base::error; 2650227825Stheraven if (wc < 0x010000) 2651227825Stheraven { 2652227825Stheraven if (to_end-to_nxt < 2) 2653227825Stheraven return codecvt_base::partial; 2654227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2655227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2656227825Stheraven } 2657227825Stheraven else 2658227825Stheraven { 2659227825Stheraven if (to_end-to_nxt < 4) 2660227825Stheraven return codecvt_base::partial; 2661227825Stheraven uint16_t t = static_cast<uint16_t>( 2662227825Stheraven 0xD800 2663227825Stheraven | ((((wc & 0x1F0000) >> 16) - 1) << 6) 2664227825Stheraven | ((wc & 0x00FC00) >> 10)); 2665227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2666227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2667227825Stheraven t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF)); 2668227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2669227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2670227825Stheraven } 2671227825Stheraven } 2672227825Stheraven return codecvt_base::ok; 2673227825Stheraven} 2674227825Stheraven 2675227825Stheravenstatic 2676227825Stheravencodecvt_base::result 2677227825Stheravenutf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2678227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2679227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2680227825Stheraven{ 2681227825Stheraven frm_nxt = frm; 2682227825Stheraven to_nxt = to; 2683227825Stheraven if (mode & consume_header) 2684227825Stheraven { 2685227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2686227825Stheraven frm_nxt += 2; 2687227825Stheraven } 2688227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2689227825Stheraven { 2690232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2691227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2692227825Stheraven return codecvt_base::error; 2693227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2694227825Stheraven { 2695227825Stheraven if (c1 > Maxcode) 2696227825Stheraven return codecvt_base::error; 2697227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2698227825Stheraven frm_nxt += 2; 2699227825Stheraven } 2700227825Stheraven else 2701227825Stheraven { 2702227825Stheraven if (frm_end-frm_nxt < 4) 2703227825Stheraven return codecvt_base::partial; 2704232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]); 2705227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2706227825Stheraven return codecvt_base::error; 2707227825Stheraven uint32_t t = static_cast<uint32_t>( 2708227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2709227825Stheraven | ((c1 & 0x003F) << 10) 2710227825Stheraven | (c2 & 0x03FF)); 2711227825Stheraven if (t > Maxcode) 2712227825Stheraven return codecvt_base::error; 2713227825Stheraven *to_nxt = t; 2714227825Stheraven frm_nxt += 4; 2715227825Stheraven } 2716227825Stheraven } 2717227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2718227825Stheraven} 2719227825Stheraven 2720227825Stheravenstatic 2721227825Stheravenint 2722227825Stheravenutf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2723227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2724227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2725227825Stheraven{ 2726227825Stheraven const uint8_t* frm_nxt = frm; 2727227825Stheraven if (mode & consume_header) 2728227825Stheraven { 2729227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2730227825Stheraven frm_nxt += 2; 2731227825Stheraven } 2732227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) 2733227825Stheraven { 2734232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2735227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2736227825Stheraven break; 2737227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2738227825Stheraven { 2739227825Stheraven if (c1 > Maxcode) 2740227825Stheraven break; 2741227825Stheraven frm_nxt += 2; 2742227825Stheraven } 2743227825Stheraven else 2744227825Stheraven { 2745227825Stheraven if (frm_end-frm_nxt < 4) 2746227825Stheraven break; 2747232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]); 2748227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2749227825Stheraven break; 2750227825Stheraven uint32_t t = static_cast<uint32_t>( 2751227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2752227825Stheraven | ((c1 & 0x003F) << 10) 2753227825Stheraven | (c2 & 0x03FF)); 2754227825Stheraven if (t > Maxcode) 2755227825Stheraven break; 2756227825Stheraven frm_nxt += 4; 2757227825Stheraven } 2758227825Stheraven } 2759227825Stheraven return static_cast<int>(frm_nxt - frm); 2760227825Stheraven} 2761227825Stheraven 2762227825Stheravenstatic 2763227825Stheravencodecvt_base::result 2764227825Stheravenucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2765227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2766227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2767227825Stheraven{ 2768227825Stheraven frm_nxt = frm; 2769227825Stheraven to_nxt = to; 2770227825Stheraven if (mode & generate_header) 2771227825Stheraven { 2772227825Stheraven if (to_end-to_nxt < 2) 2773227825Stheraven return codecvt_base::partial; 2774227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2775227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2776227825Stheraven } 2777227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2778227825Stheraven { 2779227825Stheraven uint32_t wc = *frm_nxt; 2780227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2781227825Stheraven return codecvt_base::error; 2782227825Stheraven if (wc < 0x010000) 2783227825Stheraven { 2784227825Stheraven if (to_end-to_nxt < 2) 2785227825Stheraven return codecvt_base::partial; 2786227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2787227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2788227825Stheraven } 2789227825Stheraven else 2790227825Stheraven { 2791227825Stheraven if (to_end-to_nxt < 4) 2792227825Stheraven return codecvt_base::partial; 2793227825Stheraven uint16_t t = static_cast<uint16_t>( 2794227825Stheraven 0xD800 2795227825Stheraven | ((((wc & 0x1F0000) >> 16) - 1) << 6) 2796227825Stheraven | ((wc & 0x00FC00) >> 10)); 2797227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2798227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2799227825Stheraven t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF)); 2800227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2801227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2802227825Stheraven } 2803227825Stheraven } 2804227825Stheraven return codecvt_base::ok; 2805227825Stheraven} 2806227825Stheraven 2807227825Stheravenstatic 2808227825Stheravencodecvt_base::result 2809227825Stheravenutf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2810227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2811227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2812227825Stheraven{ 2813227825Stheraven frm_nxt = frm; 2814227825Stheraven to_nxt = to; 2815227825Stheraven if (mode & consume_header) 2816227825Stheraven { 2817227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2818227825Stheraven frm_nxt += 2; 2819227825Stheraven } 2820227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2821227825Stheraven { 2822232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2823227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2824227825Stheraven return codecvt_base::error; 2825227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2826227825Stheraven { 2827227825Stheraven if (c1 > Maxcode) 2828227825Stheraven return codecvt_base::error; 2829227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2830227825Stheraven frm_nxt += 2; 2831227825Stheraven } 2832227825Stheraven else 2833227825Stheraven { 2834227825Stheraven if (frm_end-frm_nxt < 4) 2835227825Stheraven return codecvt_base::partial; 2836232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]); 2837227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2838227825Stheraven return codecvt_base::error; 2839227825Stheraven uint32_t t = static_cast<uint32_t>( 2840227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2841227825Stheraven | ((c1 & 0x003F) << 10) 2842227825Stheraven | (c2 & 0x03FF)); 2843227825Stheraven if (t > Maxcode) 2844227825Stheraven return codecvt_base::error; 2845227825Stheraven *to_nxt = t; 2846227825Stheraven frm_nxt += 4; 2847227825Stheraven } 2848227825Stheraven } 2849227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2850227825Stheraven} 2851227825Stheraven 2852227825Stheravenstatic 2853227825Stheravenint 2854227825Stheravenutf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2855227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2856227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2857227825Stheraven{ 2858227825Stheraven const uint8_t* frm_nxt = frm; 2859227825Stheraven if (mode & consume_header) 2860227825Stheraven { 2861227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2862227825Stheraven frm_nxt += 2; 2863227825Stheraven } 2864227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) 2865227825Stheraven { 2866232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2867227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2868227825Stheraven break; 2869227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2870227825Stheraven { 2871227825Stheraven if (c1 > Maxcode) 2872227825Stheraven break; 2873227825Stheraven frm_nxt += 2; 2874227825Stheraven } 2875227825Stheraven else 2876227825Stheraven { 2877227825Stheraven if (frm_end-frm_nxt < 4) 2878227825Stheraven break; 2879232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]); 2880227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2881227825Stheraven break; 2882227825Stheraven uint32_t t = static_cast<uint32_t>( 2883227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2884227825Stheraven | ((c1 & 0x003F) << 10) 2885227825Stheraven | (c2 & 0x03FF)); 2886227825Stheraven if (t > Maxcode) 2887227825Stheraven break; 2888227825Stheraven frm_nxt += 4; 2889227825Stheraven } 2890227825Stheraven } 2891227825Stheraven return static_cast<int>(frm_nxt - frm); 2892227825Stheraven} 2893227825Stheraven 2894227825Stheravenstatic 2895227825Stheravencodecvt_base::result 2896227825Stheravenucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2897227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2898227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2899227825Stheraven{ 2900227825Stheraven frm_nxt = frm; 2901227825Stheraven to_nxt = to; 2902227825Stheraven if (mode & generate_header) 2903227825Stheraven { 2904227825Stheraven if (to_end-to_nxt < 2) 2905227825Stheraven return codecvt_base::partial; 2906227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2907227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2908227825Stheraven } 2909227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2910227825Stheraven { 2911227825Stheraven uint16_t wc = *frm_nxt; 2912227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2913227825Stheraven return codecvt_base::error; 2914227825Stheraven if (to_end-to_nxt < 2) 2915227825Stheraven return codecvt_base::partial; 2916227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2917227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2918227825Stheraven } 2919227825Stheraven return codecvt_base::ok; 2920227825Stheraven} 2921227825Stheraven 2922227825Stheravenstatic 2923227825Stheravencodecvt_base::result 2924227825Stheravenutf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2925227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2926227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2927227825Stheraven{ 2928227825Stheraven frm_nxt = frm; 2929227825Stheraven to_nxt = to; 2930227825Stheraven if (mode & consume_header) 2931227825Stheraven { 2932227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2933227825Stheraven frm_nxt += 2; 2934227825Stheraven } 2935227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2936227825Stheraven { 2937232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2938227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2939227825Stheraven return codecvt_base::error; 2940227825Stheraven *to_nxt = c1; 2941227825Stheraven frm_nxt += 2; 2942227825Stheraven } 2943227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2944227825Stheraven} 2945227825Stheraven 2946227825Stheravenstatic 2947227825Stheravenint 2948227825Stheravenutf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2949227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2950227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2951227825Stheraven{ 2952227825Stheraven const uint8_t* frm_nxt = frm; 2953227825Stheraven if (mode & consume_header) 2954227825Stheraven { 2955227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2956227825Stheraven frm_nxt += 2; 2957227825Stheraven } 2958227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) 2959227825Stheraven { 2960232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2961227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2962227825Stheraven break; 2963227825Stheraven frm_nxt += 2; 2964227825Stheraven } 2965227825Stheraven return static_cast<int>(frm_nxt - frm); 2966227825Stheraven} 2967227825Stheraven 2968227825Stheravenstatic 2969227825Stheravencodecvt_base::result 2970227825Stheravenucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2971227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2972227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2973227825Stheraven{ 2974227825Stheraven frm_nxt = frm; 2975227825Stheraven to_nxt = to; 2976227825Stheraven if (mode & generate_header) 2977227825Stheraven { 2978227825Stheraven if (to_end-to_nxt < 2) 2979227825Stheraven return codecvt_base::partial; 2980227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2981227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2982227825Stheraven } 2983227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2984227825Stheraven { 2985227825Stheraven uint16_t wc = *frm_nxt; 2986227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2987227825Stheraven return codecvt_base::error; 2988227825Stheraven if (to_end-to_nxt < 2) 2989227825Stheraven return codecvt_base::partial; 2990227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2991227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2992227825Stheraven } 2993227825Stheraven return codecvt_base::ok; 2994227825Stheraven} 2995227825Stheraven 2996227825Stheravenstatic 2997227825Stheravencodecvt_base::result 2998227825Stheravenutf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2999227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 3000227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 3001227825Stheraven{ 3002227825Stheraven frm_nxt = frm; 3003227825Stheraven to_nxt = to; 3004227825Stheraven if (mode & consume_header) 3005227825Stheraven { 3006227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 3007227825Stheraven frm_nxt += 2; 3008227825Stheraven } 3009227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 3010227825Stheraven { 3011232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 3012227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 3013227825Stheraven return codecvt_base::error; 3014227825Stheraven *to_nxt = c1; 3015227825Stheraven frm_nxt += 2; 3016227825Stheraven } 3017227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 3018227825Stheraven} 3019227825Stheraven 3020227825Stheravenstatic 3021227825Stheravenint 3022227825Stheravenutf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 3023227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 3024227825Stheraven codecvt_mode mode = codecvt_mode(0)) 3025227825Stheraven{ 3026227825Stheraven const uint8_t* frm_nxt = frm; 3027227825Stheraven frm_nxt = frm; 3028227825Stheraven if (mode & consume_header) 3029227825Stheraven { 3030227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 3031227825Stheraven frm_nxt += 2; 3032227825Stheraven } 3033227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) 3034227825Stheraven { 3035232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 3036227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 3037227825Stheraven break; 3038227825Stheraven frm_nxt += 2; 3039227825Stheraven } 3040227825Stheraven return static_cast<int>(frm_nxt - frm); 3041227825Stheraven} 3042227825Stheraven 3043227825Stheraven// template <> class codecvt<char16_t, char, mbstate_t> 3044227825Stheraven 3045227825Stheravenlocale::id codecvt<char16_t, char, mbstate_t>::id; 3046227825Stheraven 3047227825Stheravencodecvt<char16_t, char, mbstate_t>::~codecvt() 3048227825Stheraven{ 3049227825Stheraven} 3050227825Stheraven 3051227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3052227825Stheravencodecvt<char16_t, char, mbstate_t>::do_out(state_type&, 3053227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3054227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3055227825Stheraven{ 3056227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3057227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3058227825Stheraven const uint16_t* _frm_nxt = _frm; 3059227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3060227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3061227825Stheraven uint8_t* _to_nxt = _to; 3062227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3063227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3064227825Stheraven to_nxt = to + (_to_nxt - _to); 3065227825Stheraven return r; 3066227825Stheraven} 3067227825Stheraven 3068227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3069227825Stheravencodecvt<char16_t, char, mbstate_t>::do_in(state_type&, 3070227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3071227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3072227825Stheraven{ 3073227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3074227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3075227825Stheraven const uint8_t* _frm_nxt = _frm; 3076227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3077227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3078227825Stheraven uint16_t* _to_nxt = _to; 3079227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3080227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3081227825Stheraven to_nxt = to + (_to_nxt - _to); 3082227825Stheraven return r; 3083227825Stheraven} 3084227825Stheraven 3085227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3086227825Stheravencodecvt<char16_t, char, mbstate_t>::do_unshift(state_type&, 3087227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3088227825Stheraven{ 3089227825Stheraven to_nxt = to; 3090227825Stheraven return noconv; 3091227825Stheraven} 3092227825Stheraven 3093227825Stheravenint 3094227825Stheravencodecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 3095227825Stheraven{ 3096227825Stheraven return 0; 3097227825Stheraven} 3098227825Stheraven 3099227825Stheravenbool 3100227825Stheravencodecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 3101227825Stheraven{ 3102227825Stheraven return false; 3103227825Stheraven} 3104227825Stheraven 3105227825Stheravenint 3106227825Stheravencodecvt<char16_t, char, mbstate_t>::do_length(state_type&, 3107227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3108227825Stheraven{ 3109227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3110227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3111227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx); 3112227825Stheraven} 3113227825Stheraven 3114227825Stheravenint 3115227825Stheravencodecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 3116227825Stheraven{ 3117227825Stheraven return 4; 3118227825Stheraven} 3119227825Stheraven 3120227825Stheraven// template <> class codecvt<char32_t, char, mbstate_t> 3121227825Stheraven 3122227825Stheravenlocale::id codecvt<char32_t, char, mbstate_t>::id; 3123227825Stheraven 3124227825Stheravencodecvt<char32_t, char, mbstate_t>::~codecvt() 3125227825Stheraven{ 3126227825Stheraven} 3127227825Stheraven 3128227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3129227825Stheravencodecvt<char32_t, char, mbstate_t>::do_out(state_type&, 3130227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3131227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3132227825Stheraven{ 3133227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3134227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3135227825Stheraven const uint32_t* _frm_nxt = _frm; 3136227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3137227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3138227825Stheraven uint8_t* _to_nxt = _to; 3139227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3140227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3141227825Stheraven to_nxt = to + (_to_nxt - _to); 3142227825Stheraven return r; 3143227825Stheraven} 3144227825Stheraven 3145227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3146227825Stheravencodecvt<char32_t, char, mbstate_t>::do_in(state_type&, 3147227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3148227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3149227825Stheraven{ 3150227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3151227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3152227825Stheraven const uint8_t* _frm_nxt = _frm; 3153227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3154227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3155227825Stheraven uint32_t* _to_nxt = _to; 3156227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3157227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3158227825Stheraven to_nxt = to + (_to_nxt - _to); 3159227825Stheraven return r; 3160227825Stheraven} 3161227825Stheraven 3162227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3163227825Stheravencodecvt<char32_t, char, mbstate_t>::do_unshift(state_type&, 3164227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3165227825Stheraven{ 3166227825Stheraven to_nxt = to; 3167227825Stheraven return noconv; 3168227825Stheraven} 3169227825Stheraven 3170227825Stheravenint 3171227825Stheravencodecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 3172227825Stheraven{ 3173227825Stheraven return 0; 3174227825Stheraven} 3175227825Stheraven 3176227825Stheravenbool 3177227825Stheravencodecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 3178227825Stheraven{ 3179227825Stheraven return false; 3180227825Stheraven} 3181227825Stheraven 3182227825Stheravenint 3183227825Stheravencodecvt<char32_t, char, mbstate_t>::do_length(state_type&, 3184227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3185227825Stheraven{ 3186227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3187227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3188227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx); 3189227825Stheraven} 3190227825Stheraven 3191227825Stheravenint 3192227825Stheravencodecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 3193227825Stheraven{ 3194227825Stheraven return 4; 3195227825Stheraven} 3196227825Stheraven 3197227825Stheraven// __codecvt_utf8<wchar_t> 3198227825Stheraven 3199227825Stheraven__codecvt_utf8<wchar_t>::result 3200227825Stheraven__codecvt_utf8<wchar_t>::do_out(state_type&, 3201227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3202227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3203227825Stheraven{ 3204227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3205227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3206227825Stheraven const uint32_t* _frm_nxt = _frm; 3207227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3208227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3209227825Stheraven uint8_t* _to_nxt = _to; 3210227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3211227825Stheraven _Maxcode_, _Mode_); 3212227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3213227825Stheraven to_nxt = to + (_to_nxt - _to); 3214227825Stheraven return r; 3215227825Stheraven} 3216227825Stheraven 3217227825Stheraven__codecvt_utf8<wchar_t>::result 3218227825Stheraven__codecvt_utf8<wchar_t>::do_in(state_type&, 3219227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3220227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3221227825Stheraven{ 3222227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3223227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3224227825Stheraven const uint8_t* _frm_nxt = _frm; 3225227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3226227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3227227825Stheraven uint32_t* _to_nxt = _to; 3228227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3229227825Stheraven _Maxcode_, _Mode_); 3230227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3231227825Stheraven to_nxt = to + (_to_nxt - _to); 3232227825Stheraven return r; 3233227825Stheraven} 3234227825Stheraven 3235227825Stheraven__codecvt_utf8<wchar_t>::result 3236227825Stheraven__codecvt_utf8<wchar_t>::do_unshift(state_type&, 3237227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3238227825Stheraven{ 3239227825Stheraven to_nxt = to; 3240227825Stheraven return noconv; 3241227825Stheraven} 3242227825Stheraven 3243227825Stheravenint 3244227825Stheraven__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT 3245227825Stheraven{ 3246227825Stheraven return 0; 3247227825Stheraven} 3248227825Stheraven 3249227825Stheravenbool 3250227825Stheraven__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT 3251227825Stheraven{ 3252227825Stheraven return false; 3253227825Stheraven} 3254227825Stheraven 3255227825Stheravenint 3256227825Stheraven__codecvt_utf8<wchar_t>::do_length(state_type&, 3257227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3258227825Stheraven{ 3259227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3260227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3261227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3262227825Stheraven} 3263227825Stheraven 3264227825Stheravenint 3265227825Stheraven__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT 3266227825Stheraven{ 3267227825Stheraven if (_Mode_ & consume_header) 3268227825Stheraven return 7; 3269227825Stheraven return 4; 3270227825Stheraven} 3271227825Stheraven 3272227825Stheraven// __codecvt_utf8<char16_t> 3273227825Stheraven 3274227825Stheraven__codecvt_utf8<char16_t>::result 3275227825Stheraven__codecvt_utf8<char16_t>::do_out(state_type&, 3276227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3277227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3278227825Stheraven{ 3279227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3280227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3281227825Stheraven const uint16_t* _frm_nxt = _frm; 3282227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3283227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3284227825Stheraven uint8_t* _to_nxt = _to; 3285227825Stheraven result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3286227825Stheraven _Maxcode_, _Mode_); 3287227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3288227825Stheraven to_nxt = to + (_to_nxt - _to); 3289227825Stheraven return r; 3290227825Stheraven} 3291227825Stheraven 3292227825Stheraven__codecvt_utf8<char16_t>::result 3293227825Stheraven__codecvt_utf8<char16_t>::do_in(state_type&, 3294227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3295227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3296227825Stheraven{ 3297227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3298227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3299227825Stheraven const uint8_t* _frm_nxt = _frm; 3300227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3301227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3302227825Stheraven uint16_t* _to_nxt = _to; 3303227825Stheraven result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3304227825Stheraven _Maxcode_, _Mode_); 3305227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3306227825Stheraven to_nxt = to + (_to_nxt - _to); 3307227825Stheraven return r; 3308227825Stheraven} 3309227825Stheraven 3310227825Stheraven__codecvt_utf8<char16_t>::result 3311227825Stheraven__codecvt_utf8<char16_t>::do_unshift(state_type&, 3312227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3313227825Stheraven{ 3314227825Stheraven to_nxt = to; 3315227825Stheraven return noconv; 3316227825Stheraven} 3317227825Stheraven 3318227825Stheravenint 3319227825Stheraven__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT 3320227825Stheraven{ 3321227825Stheraven return 0; 3322227825Stheraven} 3323227825Stheraven 3324227825Stheravenbool 3325227825Stheraven__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT 3326227825Stheraven{ 3327227825Stheraven return false; 3328227825Stheraven} 3329227825Stheraven 3330227825Stheravenint 3331227825Stheraven__codecvt_utf8<char16_t>::do_length(state_type&, 3332227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3333227825Stheraven{ 3334227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3335227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3336227825Stheraven return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3337227825Stheraven} 3338227825Stheraven 3339227825Stheravenint 3340227825Stheraven__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT 3341227825Stheraven{ 3342227825Stheraven if (_Mode_ & consume_header) 3343227825Stheraven return 6; 3344227825Stheraven return 3; 3345227825Stheraven} 3346227825Stheraven 3347227825Stheraven// __codecvt_utf8<char32_t> 3348227825Stheraven 3349227825Stheraven__codecvt_utf8<char32_t>::result 3350227825Stheraven__codecvt_utf8<char32_t>::do_out(state_type&, 3351227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3352227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3353227825Stheraven{ 3354227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3355227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3356227825Stheraven const uint32_t* _frm_nxt = _frm; 3357227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3358227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3359227825Stheraven uint8_t* _to_nxt = _to; 3360227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3361227825Stheraven _Maxcode_, _Mode_); 3362227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3363227825Stheraven to_nxt = to + (_to_nxt - _to); 3364227825Stheraven return r; 3365227825Stheraven} 3366227825Stheraven 3367227825Stheraven__codecvt_utf8<char32_t>::result 3368227825Stheraven__codecvt_utf8<char32_t>::do_in(state_type&, 3369227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3370227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3371227825Stheraven{ 3372227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3373227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3374227825Stheraven const uint8_t* _frm_nxt = _frm; 3375227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3376227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3377227825Stheraven uint32_t* _to_nxt = _to; 3378227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3379227825Stheraven _Maxcode_, _Mode_); 3380227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3381227825Stheraven to_nxt = to + (_to_nxt - _to); 3382227825Stheraven return r; 3383227825Stheraven} 3384227825Stheraven 3385227825Stheraven__codecvt_utf8<char32_t>::result 3386227825Stheraven__codecvt_utf8<char32_t>::do_unshift(state_type&, 3387227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3388227825Stheraven{ 3389227825Stheraven to_nxt = to; 3390227825Stheraven return noconv; 3391227825Stheraven} 3392227825Stheraven 3393227825Stheravenint 3394227825Stheraven__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT 3395227825Stheraven{ 3396227825Stheraven return 0; 3397227825Stheraven} 3398227825Stheraven 3399227825Stheravenbool 3400227825Stheraven__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT 3401227825Stheraven{ 3402227825Stheraven return false; 3403227825Stheraven} 3404227825Stheraven 3405227825Stheravenint 3406227825Stheraven__codecvt_utf8<char32_t>::do_length(state_type&, 3407227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3408227825Stheraven{ 3409227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3410227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3411227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3412227825Stheraven} 3413227825Stheraven 3414227825Stheravenint 3415227825Stheraven__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT 3416227825Stheraven{ 3417227825Stheraven if (_Mode_ & consume_header) 3418227825Stheraven return 7; 3419227825Stheraven return 4; 3420227825Stheraven} 3421227825Stheraven 3422227825Stheraven// __codecvt_utf16<wchar_t, false> 3423227825Stheraven 3424227825Stheraven__codecvt_utf16<wchar_t, false>::result 3425227825Stheraven__codecvt_utf16<wchar_t, false>::do_out(state_type&, 3426227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3427227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3428227825Stheraven{ 3429227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3430227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3431227825Stheraven const uint32_t* _frm_nxt = _frm; 3432227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3433227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3434227825Stheraven uint8_t* _to_nxt = _to; 3435227825Stheraven result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3436227825Stheraven _Maxcode_, _Mode_); 3437227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3438227825Stheraven to_nxt = to + (_to_nxt - _to); 3439227825Stheraven return r; 3440227825Stheraven} 3441227825Stheraven 3442227825Stheraven__codecvt_utf16<wchar_t, false>::result 3443227825Stheraven__codecvt_utf16<wchar_t, false>::do_in(state_type&, 3444227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3445227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3446227825Stheraven{ 3447227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3448227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3449227825Stheraven const uint8_t* _frm_nxt = _frm; 3450227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3451227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3452227825Stheraven uint32_t* _to_nxt = _to; 3453227825Stheraven result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3454227825Stheraven _Maxcode_, _Mode_); 3455227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3456227825Stheraven to_nxt = to + (_to_nxt - _to); 3457227825Stheraven return r; 3458227825Stheraven} 3459227825Stheraven 3460227825Stheraven__codecvt_utf16<wchar_t, false>::result 3461227825Stheraven__codecvt_utf16<wchar_t, false>::do_unshift(state_type&, 3462227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3463227825Stheraven{ 3464227825Stheraven to_nxt = to; 3465227825Stheraven return noconv; 3466227825Stheraven} 3467227825Stheraven 3468227825Stheravenint 3469227825Stheraven__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT 3470227825Stheraven{ 3471227825Stheraven return 0; 3472227825Stheraven} 3473227825Stheraven 3474227825Stheravenbool 3475227825Stheraven__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT 3476227825Stheraven{ 3477227825Stheraven return false; 3478227825Stheraven} 3479227825Stheraven 3480227825Stheravenint 3481227825Stheraven__codecvt_utf16<wchar_t, false>::do_length(state_type&, 3482227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3483227825Stheraven{ 3484227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3485227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3486227825Stheraven return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3487227825Stheraven} 3488227825Stheraven 3489227825Stheravenint 3490227825Stheraven__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT 3491227825Stheraven{ 3492227825Stheraven if (_Mode_ & consume_header) 3493227825Stheraven return 6; 3494227825Stheraven return 4; 3495227825Stheraven} 3496227825Stheraven 3497227825Stheraven// __codecvt_utf16<wchar_t, true> 3498227825Stheraven 3499227825Stheraven__codecvt_utf16<wchar_t, true>::result 3500227825Stheraven__codecvt_utf16<wchar_t, true>::do_out(state_type&, 3501227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3502227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3503227825Stheraven{ 3504227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3505227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3506227825Stheraven const uint32_t* _frm_nxt = _frm; 3507227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3508227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3509227825Stheraven uint8_t* _to_nxt = _to; 3510227825Stheraven result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3511227825Stheraven _Maxcode_, _Mode_); 3512227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3513227825Stheraven to_nxt = to + (_to_nxt - _to); 3514227825Stheraven return r; 3515227825Stheraven} 3516227825Stheraven 3517227825Stheraven__codecvt_utf16<wchar_t, true>::result 3518227825Stheraven__codecvt_utf16<wchar_t, true>::do_in(state_type&, 3519227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3520227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3521227825Stheraven{ 3522227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3523227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3524227825Stheraven const uint8_t* _frm_nxt = _frm; 3525227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3526227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3527227825Stheraven uint32_t* _to_nxt = _to; 3528227825Stheraven result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3529227825Stheraven _Maxcode_, _Mode_); 3530227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3531227825Stheraven to_nxt = to + (_to_nxt - _to); 3532227825Stheraven return r; 3533227825Stheraven} 3534227825Stheraven 3535227825Stheraven__codecvt_utf16<wchar_t, true>::result 3536227825Stheraven__codecvt_utf16<wchar_t, true>::do_unshift(state_type&, 3537227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3538227825Stheraven{ 3539227825Stheraven to_nxt = to; 3540227825Stheraven return noconv; 3541227825Stheraven} 3542227825Stheraven 3543227825Stheravenint 3544227825Stheraven__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT 3545227825Stheraven{ 3546227825Stheraven return 0; 3547227825Stheraven} 3548227825Stheraven 3549227825Stheravenbool 3550227825Stheraven__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT 3551227825Stheraven{ 3552227825Stheraven return false; 3553227825Stheraven} 3554227825Stheraven 3555227825Stheravenint 3556227825Stheraven__codecvt_utf16<wchar_t, true>::do_length(state_type&, 3557227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3558227825Stheraven{ 3559227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3560227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3561227825Stheraven return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3562227825Stheraven} 3563227825Stheraven 3564227825Stheravenint 3565227825Stheraven__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT 3566227825Stheraven{ 3567227825Stheraven if (_Mode_ & consume_header) 3568227825Stheraven return 6; 3569227825Stheraven return 4; 3570227825Stheraven} 3571227825Stheraven 3572227825Stheraven// __codecvt_utf16<char16_t, false> 3573227825Stheraven 3574227825Stheraven__codecvt_utf16<char16_t, false>::result 3575227825Stheraven__codecvt_utf16<char16_t, false>::do_out(state_type&, 3576227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3577227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3578227825Stheraven{ 3579227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3580227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3581227825Stheraven const uint16_t* _frm_nxt = _frm; 3582227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3583227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3584227825Stheraven uint8_t* _to_nxt = _to; 3585227825Stheraven result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3586227825Stheraven _Maxcode_, _Mode_); 3587227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3588227825Stheraven to_nxt = to + (_to_nxt - _to); 3589227825Stheraven return r; 3590227825Stheraven} 3591227825Stheraven 3592227825Stheraven__codecvt_utf16<char16_t, false>::result 3593227825Stheraven__codecvt_utf16<char16_t, false>::do_in(state_type&, 3594227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3595227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3596227825Stheraven{ 3597227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3598227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3599227825Stheraven const uint8_t* _frm_nxt = _frm; 3600227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3601227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3602227825Stheraven uint16_t* _to_nxt = _to; 3603227825Stheraven result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3604227825Stheraven _Maxcode_, _Mode_); 3605227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3606227825Stheraven to_nxt = to + (_to_nxt - _to); 3607227825Stheraven return r; 3608227825Stheraven} 3609227825Stheraven 3610227825Stheraven__codecvt_utf16<char16_t, false>::result 3611227825Stheraven__codecvt_utf16<char16_t, false>::do_unshift(state_type&, 3612227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3613227825Stheraven{ 3614227825Stheraven to_nxt = to; 3615227825Stheraven return noconv; 3616227825Stheraven} 3617227825Stheraven 3618227825Stheravenint 3619227825Stheraven__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT 3620227825Stheraven{ 3621227825Stheraven return 0; 3622227825Stheraven} 3623227825Stheraven 3624227825Stheravenbool 3625227825Stheraven__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT 3626227825Stheraven{ 3627227825Stheraven return false; 3628227825Stheraven} 3629227825Stheraven 3630227825Stheravenint 3631227825Stheraven__codecvt_utf16<char16_t, false>::do_length(state_type&, 3632227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3633227825Stheraven{ 3634227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3635227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3636227825Stheraven return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3637227825Stheraven} 3638227825Stheraven 3639227825Stheravenint 3640227825Stheraven__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT 3641227825Stheraven{ 3642227825Stheraven if (_Mode_ & consume_header) 3643227825Stheraven return 4; 3644227825Stheraven return 2; 3645227825Stheraven} 3646227825Stheraven 3647227825Stheraven// __codecvt_utf16<char16_t, true> 3648227825Stheraven 3649227825Stheraven__codecvt_utf16<char16_t, true>::result 3650227825Stheraven__codecvt_utf16<char16_t, true>::do_out(state_type&, 3651227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3652227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3653227825Stheraven{ 3654227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3655227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3656227825Stheraven const uint16_t* _frm_nxt = _frm; 3657227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3658227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3659227825Stheraven uint8_t* _to_nxt = _to; 3660227825Stheraven result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3661227825Stheraven _Maxcode_, _Mode_); 3662227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3663227825Stheraven to_nxt = to + (_to_nxt - _to); 3664227825Stheraven return r; 3665227825Stheraven} 3666227825Stheraven 3667227825Stheraven__codecvt_utf16<char16_t, true>::result 3668227825Stheraven__codecvt_utf16<char16_t, true>::do_in(state_type&, 3669227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3670227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3671227825Stheraven{ 3672227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3673227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3674227825Stheraven const uint8_t* _frm_nxt = _frm; 3675227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3676227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3677227825Stheraven uint16_t* _to_nxt = _to; 3678227825Stheraven result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3679227825Stheraven _Maxcode_, _Mode_); 3680227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3681227825Stheraven to_nxt = to + (_to_nxt - _to); 3682227825Stheraven return r; 3683227825Stheraven} 3684227825Stheraven 3685227825Stheraven__codecvt_utf16<char16_t, true>::result 3686227825Stheraven__codecvt_utf16<char16_t, true>::do_unshift(state_type&, 3687227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3688227825Stheraven{ 3689227825Stheraven to_nxt = to; 3690227825Stheraven return noconv; 3691227825Stheraven} 3692227825Stheraven 3693227825Stheravenint 3694227825Stheraven__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT 3695227825Stheraven{ 3696227825Stheraven return 0; 3697227825Stheraven} 3698227825Stheraven 3699227825Stheravenbool 3700227825Stheraven__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT 3701227825Stheraven{ 3702227825Stheraven return false; 3703227825Stheraven} 3704227825Stheraven 3705227825Stheravenint 3706227825Stheraven__codecvt_utf16<char16_t, true>::do_length(state_type&, 3707227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3708227825Stheraven{ 3709227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3710227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3711227825Stheraven return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3712227825Stheraven} 3713227825Stheraven 3714227825Stheravenint 3715227825Stheraven__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT 3716227825Stheraven{ 3717227825Stheraven if (_Mode_ & consume_header) 3718227825Stheraven return 4; 3719227825Stheraven return 2; 3720227825Stheraven} 3721227825Stheraven 3722227825Stheraven// __codecvt_utf16<char32_t, false> 3723227825Stheraven 3724227825Stheraven__codecvt_utf16<char32_t, false>::result 3725227825Stheraven__codecvt_utf16<char32_t, false>::do_out(state_type&, 3726227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3727227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3728227825Stheraven{ 3729227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3730227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3731227825Stheraven const uint32_t* _frm_nxt = _frm; 3732227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3733227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3734227825Stheraven uint8_t* _to_nxt = _to; 3735227825Stheraven result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3736227825Stheraven _Maxcode_, _Mode_); 3737227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3738227825Stheraven to_nxt = to + (_to_nxt - _to); 3739227825Stheraven return r; 3740227825Stheraven} 3741227825Stheraven 3742227825Stheraven__codecvt_utf16<char32_t, false>::result 3743227825Stheraven__codecvt_utf16<char32_t, false>::do_in(state_type&, 3744227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3745227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3746227825Stheraven{ 3747227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3748227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3749227825Stheraven const uint8_t* _frm_nxt = _frm; 3750227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3751227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3752227825Stheraven uint32_t* _to_nxt = _to; 3753227825Stheraven result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3754227825Stheraven _Maxcode_, _Mode_); 3755227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3756227825Stheraven to_nxt = to + (_to_nxt - _to); 3757227825Stheraven return r; 3758227825Stheraven} 3759227825Stheraven 3760227825Stheraven__codecvt_utf16<char32_t, false>::result 3761227825Stheraven__codecvt_utf16<char32_t, false>::do_unshift(state_type&, 3762227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3763227825Stheraven{ 3764227825Stheraven to_nxt = to; 3765227825Stheraven return noconv; 3766227825Stheraven} 3767227825Stheraven 3768227825Stheravenint 3769227825Stheraven__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT 3770227825Stheraven{ 3771227825Stheraven return 0; 3772227825Stheraven} 3773227825Stheraven 3774227825Stheravenbool 3775227825Stheraven__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT 3776227825Stheraven{ 3777227825Stheraven return false; 3778227825Stheraven} 3779227825Stheraven 3780227825Stheravenint 3781227825Stheraven__codecvt_utf16<char32_t, false>::do_length(state_type&, 3782227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3783227825Stheraven{ 3784227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3785227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3786227825Stheraven return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3787227825Stheraven} 3788227825Stheraven 3789227825Stheravenint 3790227825Stheraven__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT 3791227825Stheraven{ 3792227825Stheraven if (_Mode_ & consume_header) 3793227825Stheraven return 6; 3794227825Stheraven return 4; 3795227825Stheraven} 3796227825Stheraven 3797227825Stheraven// __codecvt_utf16<char32_t, true> 3798227825Stheraven 3799227825Stheraven__codecvt_utf16<char32_t, true>::result 3800227825Stheraven__codecvt_utf16<char32_t, true>::do_out(state_type&, 3801227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3802227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3803227825Stheraven{ 3804227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3805227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3806227825Stheraven const uint32_t* _frm_nxt = _frm; 3807227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3808227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3809227825Stheraven uint8_t* _to_nxt = _to; 3810227825Stheraven result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3811227825Stheraven _Maxcode_, _Mode_); 3812227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3813227825Stheraven to_nxt = to + (_to_nxt - _to); 3814227825Stheraven return r; 3815227825Stheraven} 3816227825Stheraven 3817227825Stheraven__codecvt_utf16<char32_t, true>::result 3818227825Stheraven__codecvt_utf16<char32_t, true>::do_in(state_type&, 3819227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3820227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3821227825Stheraven{ 3822227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3823227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3824227825Stheraven const uint8_t* _frm_nxt = _frm; 3825227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3826227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3827227825Stheraven uint32_t* _to_nxt = _to; 3828227825Stheraven result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3829227825Stheraven _Maxcode_, _Mode_); 3830227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3831227825Stheraven to_nxt = to + (_to_nxt - _to); 3832227825Stheraven return r; 3833227825Stheraven} 3834227825Stheraven 3835227825Stheraven__codecvt_utf16<char32_t, true>::result 3836227825Stheraven__codecvt_utf16<char32_t, true>::do_unshift(state_type&, 3837227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3838227825Stheraven{ 3839227825Stheraven to_nxt = to; 3840227825Stheraven return noconv; 3841227825Stheraven} 3842227825Stheraven 3843227825Stheravenint 3844227825Stheraven__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT 3845227825Stheraven{ 3846227825Stheraven return 0; 3847227825Stheraven} 3848227825Stheraven 3849227825Stheravenbool 3850227825Stheraven__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT 3851227825Stheraven{ 3852227825Stheraven return false; 3853227825Stheraven} 3854227825Stheraven 3855227825Stheravenint 3856227825Stheraven__codecvt_utf16<char32_t, true>::do_length(state_type&, 3857227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3858227825Stheraven{ 3859227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3860227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3861227825Stheraven return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3862227825Stheraven} 3863227825Stheraven 3864227825Stheravenint 3865227825Stheraven__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT 3866227825Stheraven{ 3867227825Stheraven if (_Mode_ & consume_header) 3868227825Stheraven return 6; 3869227825Stheraven return 4; 3870227825Stheraven} 3871227825Stheraven 3872227825Stheraven// __codecvt_utf8_utf16<wchar_t> 3873227825Stheraven 3874227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3875227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_out(state_type&, 3876227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3877227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3878227825Stheraven{ 3879227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3880227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3881227825Stheraven const uint32_t* _frm_nxt = _frm; 3882227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3883227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3884227825Stheraven uint8_t* _to_nxt = _to; 3885227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3886227825Stheraven _Maxcode_, _Mode_); 3887227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3888227825Stheraven to_nxt = to + (_to_nxt - _to); 3889227825Stheraven return r; 3890227825Stheraven} 3891227825Stheraven 3892227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3893227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_in(state_type&, 3894227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3895227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3896227825Stheraven{ 3897227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3898227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3899227825Stheraven const uint8_t* _frm_nxt = _frm; 3900227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3901227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3902227825Stheraven uint32_t* _to_nxt = _to; 3903227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3904227825Stheraven _Maxcode_, _Mode_); 3905227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3906227825Stheraven to_nxt = to + (_to_nxt - _to); 3907227825Stheraven return r; 3908227825Stheraven} 3909227825Stheraven 3910227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3911227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&, 3912227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3913227825Stheraven{ 3914227825Stheraven to_nxt = to; 3915227825Stheraven return noconv; 3916227825Stheraven} 3917227825Stheraven 3918227825Stheravenint 3919227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT 3920227825Stheraven{ 3921227825Stheraven return 0; 3922227825Stheraven} 3923227825Stheraven 3924227825Stheravenbool 3925227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT 3926227825Stheraven{ 3927227825Stheraven return false; 3928227825Stheraven} 3929227825Stheraven 3930227825Stheravenint 3931227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_length(state_type&, 3932227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3933227825Stheraven{ 3934227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3935227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3936227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3937227825Stheraven} 3938227825Stheraven 3939227825Stheravenint 3940227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT 3941227825Stheraven{ 3942227825Stheraven if (_Mode_ & consume_header) 3943227825Stheraven return 7; 3944227825Stheraven return 4; 3945227825Stheraven} 3946227825Stheraven 3947227825Stheraven// __codecvt_utf8_utf16<char16_t> 3948227825Stheraven 3949227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3950227825Stheraven__codecvt_utf8_utf16<char16_t>::do_out(state_type&, 3951227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3952227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3953227825Stheraven{ 3954227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3955227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3956227825Stheraven const uint16_t* _frm_nxt = _frm; 3957227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3958227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3959227825Stheraven uint8_t* _to_nxt = _to; 3960227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3961227825Stheraven _Maxcode_, _Mode_); 3962227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3963227825Stheraven to_nxt = to + (_to_nxt - _to); 3964227825Stheraven return r; 3965227825Stheraven} 3966227825Stheraven 3967227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3968227825Stheraven__codecvt_utf8_utf16<char16_t>::do_in(state_type&, 3969227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3970227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3971227825Stheraven{ 3972227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3973227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3974227825Stheraven const uint8_t* _frm_nxt = _frm; 3975227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3976227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3977227825Stheraven uint16_t* _to_nxt = _to; 3978227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3979227825Stheraven _Maxcode_, _Mode_); 3980227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3981227825Stheraven to_nxt = to + (_to_nxt - _to); 3982227825Stheraven return r; 3983227825Stheraven} 3984227825Stheraven 3985227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3986227825Stheraven__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&, 3987227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3988227825Stheraven{ 3989227825Stheraven to_nxt = to; 3990227825Stheraven return noconv; 3991227825Stheraven} 3992227825Stheraven 3993227825Stheravenint 3994227825Stheraven__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT 3995227825Stheraven{ 3996227825Stheraven return 0; 3997227825Stheraven} 3998227825Stheraven 3999227825Stheravenbool 4000227825Stheraven__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT 4001227825Stheraven{ 4002227825Stheraven return false; 4003227825Stheraven} 4004227825Stheraven 4005227825Stheravenint 4006227825Stheraven__codecvt_utf8_utf16<char16_t>::do_length(state_type&, 4007227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 4008227825Stheraven{ 4009227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4010227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4011227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 4012227825Stheraven} 4013227825Stheraven 4014227825Stheravenint 4015227825Stheraven__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT 4016227825Stheraven{ 4017227825Stheraven if (_Mode_ & consume_header) 4018227825Stheraven return 7; 4019227825Stheraven return 4; 4020227825Stheraven} 4021227825Stheraven 4022227825Stheraven// __codecvt_utf8_utf16<char32_t> 4023227825Stheraven 4024227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4025227825Stheraven__codecvt_utf8_utf16<char32_t>::do_out(state_type&, 4026227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 4027227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 4028227825Stheraven{ 4029227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 4030227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 4031227825Stheraven const uint32_t* _frm_nxt = _frm; 4032227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 4033227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 4034227825Stheraven uint8_t* _to_nxt = _to; 4035227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4036227825Stheraven _Maxcode_, _Mode_); 4037227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4038227825Stheraven to_nxt = to + (_to_nxt - _to); 4039227825Stheraven return r; 4040227825Stheraven} 4041227825Stheraven 4042227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4043227825Stheraven__codecvt_utf8_utf16<char32_t>::do_in(state_type&, 4044227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 4045227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 4046227825Stheraven{ 4047227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4048227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4049227825Stheraven const uint8_t* _frm_nxt = _frm; 4050227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 4051227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 4052227825Stheraven uint32_t* _to_nxt = _to; 4053227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4054227825Stheraven _Maxcode_, _Mode_); 4055227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4056227825Stheraven to_nxt = to + (_to_nxt - _to); 4057227825Stheraven return r; 4058227825Stheraven} 4059227825Stheraven 4060227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4061227825Stheraven__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&, 4062227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 4063227825Stheraven{ 4064227825Stheraven to_nxt = to; 4065227825Stheraven return noconv; 4066227825Stheraven} 4067227825Stheraven 4068227825Stheravenint 4069227825Stheraven__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT 4070227825Stheraven{ 4071227825Stheraven return 0; 4072227825Stheraven} 4073227825Stheraven 4074227825Stheravenbool 4075227825Stheraven__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT 4076227825Stheraven{ 4077227825Stheraven return false; 4078227825Stheraven} 4079227825Stheraven 4080227825Stheravenint 4081227825Stheraven__codecvt_utf8_utf16<char32_t>::do_length(state_type&, 4082227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 4083227825Stheraven{ 4084227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4085227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4086227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 4087227825Stheraven} 4088227825Stheraven 4089227825Stheravenint 4090227825Stheraven__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT 4091227825Stheraven{ 4092227825Stheraven if (_Mode_ & consume_header) 4093227825Stheraven return 7; 4094227825Stheraven return 4; 4095227825Stheraven} 4096227825Stheraven 4097227825Stheraven// __narrow_to_utf8<16> 4098227825Stheraven 4099227825Stheraven__narrow_to_utf8<16>::~__narrow_to_utf8() 4100227825Stheraven{ 4101227825Stheraven} 4102227825Stheraven 4103227825Stheraven// __narrow_to_utf8<32> 4104227825Stheraven 4105227825Stheraven__narrow_to_utf8<32>::~__narrow_to_utf8() 4106227825Stheraven{ 4107227825Stheraven} 4108227825Stheraven 4109227825Stheraven// __widen_from_utf8<16> 4110227825Stheraven 4111227825Stheraven__widen_from_utf8<16>::~__widen_from_utf8() 4112227825Stheraven{ 4113227825Stheraven} 4114227825Stheraven 4115227825Stheraven// __widen_from_utf8<32> 4116227825Stheraven 4117227825Stheraven__widen_from_utf8<32>::~__widen_from_utf8() 4118227825Stheraven{ 4119227825Stheraven} 4120227825Stheraven 4121227825Stheraven// numpunct<char> && numpunct<wchar_t> 4122227825Stheraven 4123227825Stheravenlocale::id numpunct< char >::id; 4124227825Stheravenlocale::id numpunct<wchar_t>::id; 4125227825Stheraven 4126227825Stheravennumpunct<char>::numpunct(size_t refs) 4127227825Stheraven : locale::facet(refs), 4128227825Stheraven __decimal_point_('.'), 4129227825Stheraven __thousands_sep_(',') 4130227825Stheraven{ 4131227825Stheraven} 4132227825Stheraven 4133227825Stheravennumpunct<wchar_t>::numpunct(size_t refs) 4134227825Stheraven : locale::facet(refs), 4135227825Stheraven __decimal_point_(L'.'), 4136227825Stheraven __thousands_sep_(L',') 4137227825Stheraven{ 4138227825Stheraven} 4139227825Stheraven 4140227825Stheravennumpunct<char>::~numpunct() 4141227825Stheraven{ 4142227825Stheraven} 4143227825Stheraven 4144227825Stheravennumpunct<wchar_t>::~numpunct() 4145227825Stheraven{ 4146227825Stheraven} 4147227825Stheraven 4148227825Stheraven char numpunct< char >::do_decimal_point() const {return __decimal_point_;} 4149227825Stheravenwchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;} 4150227825Stheraven 4151227825Stheraven char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;} 4152227825Stheravenwchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;} 4153227825Stheraven 4154227825Stheravenstring numpunct< char >::do_grouping() const {return __grouping_;} 4155227825Stheravenstring numpunct<wchar_t>::do_grouping() const {return __grouping_;} 4156227825Stheraven 4157227825Stheraven string numpunct< char >::do_truename() const {return "true";} 4158227825Stheravenwstring numpunct<wchar_t>::do_truename() const {return L"true";} 4159227825Stheraven 4160227825Stheraven string numpunct< char >::do_falsename() const {return "false";} 4161227825Stheravenwstring numpunct<wchar_t>::do_falsename() const {return L"false";} 4162227825Stheraven 4163227825Stheraven// numpunct_byname<char> 4164227825Stheraven 4165227825Stheravennumpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) 4166227825Stheraven : numpunct<char>(refs) 4167227825Stheraven{ 4168227825Stheraven __init(nm); 4169227825Stheraven} 4170227825Stheraven 4171227825Stheravennumpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) 4172227825Stheraven : numpunct<char>(refs) 4173227825Stheraven{ 4174227825Stheraven __init(nm.c_str()); 4175227825Stheraven} 4176227825Stheraven 4177227825Stheravennumpunct_byname<char>::~numpunct_byname() 4178227825Stheraven{ 4179227825Stheraven} 4180227825Stheraven 4181227825Stheravenvoid 4182227825Stheravennumpunct_byname<char>::__init(const char* nm) 4183227825Stheraven{ 4184227825Stheraven if (strcmp(nm, "C") != 0) 4185227825Stheraven { 4186227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 4187227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4188232950Stheraven if (loc == nullptr) 4189227825Stheraven throw runtime_error("numpunct_byname<char>::numpunct_byname" 4190227825Stheraven " failed to construct for " + string(nm)); 4191227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4192227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4193227825Stheraven lconv* lc = localeconv_l(loc.get()); 4194227825Stheraven#else 4195227825Stheraven lconv* lc = __localeconv_l(loc.get()); 4196227825Stheraven#endif 4197227825Stheraven if (*lc->decimal_point) 4198227825Stheraven __decimal_point_ = *lc->decimal_point; 4199227825Stheraven if (*lc->thousands_sep) 4200227825Stheraven __thousands_sep_ = *lc->thousands_sep; 4201227825Stheraven __grouping_ = lc->grouping; 4202227825Stheraven // localization for truename and falsename is not available 4203227825Stheraven } 4204227825Stheraven} 4205227825Stheraven 4206227825Stheraven// numpunct_byname<wchar_t> 4207227825Stheraven 4208227825Stheravennumpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) 4209227825Stheraven : numpunct<wchar_t>(refs) 4210227825Stheraven{ 4211227825Stheraven __init(nm); 4212227825Stheraven} 4213227825Stheraven 4214227825Stheravennumpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) 4215227825Stheraven : numpunct<wchar_t>(refs) 4216227825Stheraven{ 4217227825Stheraven __init(nm.c_str()); 4218227825Stheraven} 4219227825Stheraven 4220227825Stheravennumpunct_byname<wchar_t>::~numpunct_byname() 4221227825Stheraven{ 4222227825Stheraven} 4223227825Stheraven 4224227825Stheravenvoid 4225227825Stheravennumpunct_byname<wchar_t>::__init(const char* nm) 4226227825Stheraven{ 4227227825Stheraven if (strcmp(nm, "C") != 0) 4228227825Stheraven { 4229227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 4230227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4231232950Stheraven if (loc == nullptr) 4232227825Stheraven throw runtime_error("numpunct_byname<char>::numpunct_byname" 4233227825Stheraven " failed to construct for " + string(nm)); 4234227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4235227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4236227825Stheraven lconv* lc = localeconv_l(loc.get()); 4237227825Stheraven#else 4238227825Stheraven lconv* lc = __localeconv_l(loc.get()); 4239227825Stheraven#endif 4240227825Stheraven if (*lc->decimal_point) 4241227825Stheraven __decimal_point_ = *lc->decimal_point; 4242227825Stheraven if (*lc->thousands_sep) 4243227825Stheraven __thousands_sep_ = *lc->thousands_sep; 4244227825Stheraven __grouping_ = lc->grouping; 4245227825Stheraven // locallization for truename and falsename is not available 4246227825Stheraven } 4247227825Stheraven} 4248227825Stheraven 4249227825Stheraven// num_get helpers 4250227825Stheraven 4251227825Stheravenint 4252227825Stheraven__num_get_base::__get_base(ios_base& iob) 4253227825Stheraven{ 4254227825Stheraven ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield; 4255227825Stheraven if (__basefield == ios_base::oct) 4256227825Stheraven return 8; 4257227825Stheraven else if (__basefield == ios_base::hex) 4258227825Stheraven return 16; 4259227825Stheraven else if (__basefield == 0) 4260227825Stheraven return 0; 4261227825Stheraven return 10; 4262227825Stheraven} 4263227825Stheraven 4264227825Stheravenconst char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN"; 4265227825Stheraven 4266227825Stheravenvoid 4267227825Stheraven__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 4268227825Stheraven ios_base::iostate& __err) 4269227825Stheraven{ 4270227825Stheraven if (__grouping.size() != 0) 4271227825Stheraven { 4272227825Stheraven reverse(__g, __g_end); 4273227825Stheraven const char* __ig = __grouping.data(); 4274227825Stheraven const char* __eg = __ig + __grouping.size(); 4275227825Stheraven for (unsigned* __r = __g; __r < __g_end-1; ++__r) 4276227825Stheraven { 4277227825Stheraven if (0 < *__ig && *__ig < numeric_limits<char>::max()) 4278227825Stheraven { 4279232950Stheraven if (static_cast<unsigned>(*__ig) != *__r) 4280227825Stheraven { 4281227825Stheraven __err = ios_base::failbit; 4282227825Stheraven return; 4283227825Stheraven } 4284227825Stheraven } 4285227825Stheraven if (__eg - __ig > 1) 4286227825Stheraven ++__ig; 4287227825Stheraven } 4288227825Stheraven if (0 < *__ig && *__ig < numeric_limits<char>::max()) 4289227825Stheraven { 4290232950Stheraven if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0) 4291227825Stheraven __err = ios_base::failbit; 4292227825Stheraven } 4293227825Stheraven } 4294227825Stheraven} 4295227825Stheraven 4296227825Stheravenvoid 4297227825Stheraven__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, 4298227825Stheraven ios_base::fmtflags __flags) 4299227825Stheraven{ 4300227825Stheraven if (__flags & ios_base::showpos) 4301227825Stheraven *__fmtp++ = '+'; 4302227825Stheraven if (__flags & ios_base::showbase) 4303227825Stheraven *__fmtp++ = '#'; 4304227825Stheraven while(*__len) 4305227825Stheraven *__fmtp++ = *__len++; 4306227825Stheraven if ((__flags & ios_base::basefield) == ios_base::oct) 4307227825Stheraven *__fmtp = 'o'; 4308227825Stheraven else if ((__flags & ios_base::basefield) == ios_base::hex) 4309227825Stheraven { 4310227825Stheraven if (__flags & ios_base::uppercase) 4311227825Stheraven *__fmtp = 'X'; 4312227825Stheraven else 4313227825Stheraven *__fmtp = 'x'; 4314227825Stheraven } 4315227825Stheraven else if (__signd) 4316227825Stheraven *__fmtp = 'd'; 4317227825Stheraven else 4318227825Stheraven *__fmtp = 'u'; 4319227825Stheraven} 4320227825Stheraven 4321227825Stheravenbool 4322227825Stheraven__num_put_base::__format_float(char* __fmtp, const char* __len, 4323227825Stheraven ios_base::fmtflags __flags) 4324227825Stheraven{ 4325227825Stheraven bool specify_precision = true; 4326227825Stheraven if (__flags & ios_base::showpos) 4327227825Stheraven *__fmtp++ = '+'; 4328227825Stheraven if (__flags & ios_base::showpoint) 4329227825Stheraven *__fmtp++ = '#'; 4330227825Stheraven ios_base::fmtflags floatfield = __flags & ios_base::floatfield; 4331227825Stheraven bool uppercase = __flags & ios_base::uppercase; 4332227825Stheraven if (floatfield == (ios_base::fixed | ios_base::scientific)) 4333227825Stheraven specify_precision = false; 4334227825Stheraven else 4335227825Stheraven { 4336227825Stheraven *__fmtp++ = '.'; 4337227825Stheraven *__fmtp++ = '*'; 4338227825Stheraven } 4339227825Stheraven while(*__len) 4340227825Stheraven *__fmtp++ = *__len++; 4341227825Stheraven if (floatfield == ios_base::fixed) 4342227825Stheraven { 4343227825Stheraven if (uppercase) 4344227825Stheraven *__fmtp = 'F'; 4345227825Stheraven else 4346227825Stheraven *__fmtp = 'f'; 4347227825Stheraven } 4348227825Stheraven else if (floatfield == ios_base::scientific) 4349227825Stheraven { 4350227825Stheraven if (uppercase) 4351227825Stheraven *__fmtp = 'E'; 4352227825Stheraven else 4353227825Stheraven *__fmtp = 'e'; 4354227825Stheraven } 4355227825Stheraven else if (floatfield == (ios_base::fixed | ios_base::scientific)) 4356227825Stheraven { 4357227825Stheraven if (uppercase) 4358227825Stheraven *__fmtp = 'A'; 4359227825Stheraven else 4360227825Stheraven *__fmtp = 'a'; 4361227825Stheraven } 4362227825Stheraven else 4363227825Stheraven { 4364227825Stheraven if (uppercase) 4365227825Stheraven *__fmtp = 'G'; 4366227825Stheraven else 4367227825Stheraven *__fmtp = 'g'; 4368227825Stheraven } 4369227825Stheraven return specify_precision; 4370227825Stheraven} 4371227825Stheraven 4372227825Stheravenchar* 4373227825Stheraven__num_put_base::__identify_padding(char* __nb, char* __ne, 4374227825Stheraven const ios_base& __iob) 4375227825Stheraven{ 4376227825Stheraven switch (__iob.flags() & ios_base::adjustfield) 4377227825Stheraven { 4378227825Stheraven case ios_base::internal: 4379227825Stheraven if (__nb[0] == '-' || __nb[0] == '+') 4380227825Stheraven return __nb+1; 4381227825Stheraven if (__ne - __nb >= 2 && __nb[0] == '0' 4382227825Stheraven && (__nb[1] == 'x' || __nb[1] == 'X')) 4383227825Stheraven return __nb+2; 4384227825Stheraven break; 4385227825Stheraven case ios_base::left: 4386227825Stheraven return __ne; 4387227825Stheraven case ios_base::right: 4388227825Stheraven default: 4389227825Stheraven break; 4390227825Stheraven } 4391227825Stheraven return __nb; 4392227825Stheraven} 4393227825Stheraven 4394227825Stheraven// time_get 4395227825Stheraven 4396227825Stheravenstatic 4397227825Stheravenstring* 4398227825Stheraveninit_weeks() 4399227825Stheraven{ 4400227825Stheraven static string weeks[14]; 4401227825Stheraven weeks[0] = "Sunday"; 4402227825Stheraven weeks[1] = "Monday"; 4403227825Stheraven weeks[2] = "Tuesday"; 4404227825Stheraven weeks[3] = "Wednesday"; 4405227825Stheraven weeks[4] = "Thursday"; 4406227825Stheraven weeks[5] = "Friday"; 4407227825Stheraven weeks[6] = "Saturday"; 4408227825Stheraven weeks[7] = "Sun"; 4409227825Stheraven weeks[8] = "Mon"; 4410227825Stheraven weeks[9] = "Tue"; 4411227825Stheraven weeks[10] = "Wed"; 4412227825Stheraven weeks[11] = "Thu"; 4413227825Stheraven weeks[12] = "Fri"; 4414227825Stheraven weeks[13] = "Sat"; 4415227825Stheraven return weeks; 4416227825Stheraven} 4417227825Stheraven 4418227825Stheravenstatic 4419227825Stheravenwstring* 4420227825Stheraveninit_wweeks() 4421227825Stheraven{ 4422227825Stheraven static wstring weeks[14]; 4423227825Stheraven weeks[0] = L"Sunday"; 4424227825Stheraven weeks[1] = L"Monday"; 4425227825Stheraven weeks[2] = L"Tuesday"; 4426227825Stheraven weeks[3] = L"Wednesday"; 4427227825Stheraven weeks[4] = L"Thursday"; 4428227825Stheraven weeks[5] = L"Friday"; 4429227825Stheraven weeks[6] = L"Saturday"; 4430227825Stheraven weeks[7] = L"Sun"; 4431227825Stheraven weeks[8] = L"Mon"; 4432227825Stheraven weeks[9] = L"Tue"; 4433227825Stheraven weeks[10] = L"Wed"; 4434227825Stheraven weeks[11] = L"Thu"; 4435227825Stheraven weeks[12] = L"Fri"; 4436227825Stheraven weeks[13] = L"Sat"; 4437227825Stheraven return weeks; 4438227825Stheraven} 4439227825Stheraven 4440227825Stheraventemplate <> 4441227825Stheravenconst string* 4442227825Stheraven__time_get_c_storage<char>::__weeks() const 4443227825Stheraven{ 4444227825Stheraven static const string* weeks = init_weeks(); 4445227825Stheraven return weeks; 4446227825Stheraven} 4447227825Stheraven 4448227825Stheraventemplate <> 4449227825Stheravenconst wstring* 4450227825Stheraven__time_get_c_storage<wchar_t>::__weeks() const 4451227825Stheraven{ 4452227825Stheraven static const wstring* weeks = init_wweeks(); 4453227825Stheraven return weeks; 4454227825Stheraven} 4455227825Stheraven 4456227825Stheravenstatic 4457227825Stheravenstring* 4458227825Stheraveninit_months() 4459227825Stheraven{ 4460227825Stheraven static string months[24]; 4461227825Stheraven months[0] = "January"; 4462227825Stheraven months[1] = "February"; 4463227825Stheraven months[2] = "March"; 4464227825Stheraven months[3] = "April"; 4465227825Stheraven months[4] = "May"; 4466227825Stheraven months[5] = "June"; 4467227825Stheraven months[6] = "July"; 4468227825Stheraven months[7] = "August"; 4469227825Stheraven months[8] = "September"; 4470227825Stheraven months[9] = "October"; 4471227825Stheraven months[10] = "November"; 4472227825Stheraven months[11] = "December"; 4473227825Stheraven months[12] = "Jan"; 4474227825Stheraven months[13] = "Feb"; 4475227825Stheraven months[14] = "Mar"; 4476227825Stheraven months[15] = "Apr"; 4477227825Stheraven months[16] = "May"; 4478227825Stheraven months[17] = "Jun"; 4479227825Stheraven months[18] = "Jul"; 4480227825Stheraven months[19] = "Aug"; 4481227825Stheraven months[20] = "Sep"; 4482227825Stheraven months[21] = "Oct"; 4483227825Stheraven months[22] = "Nov"; 4484227825Stheraven months[23] = "Dec"; 4485227825Stheraven return months; 4486227825Stheraven} 4487227825Stheraven 4488227825Stheravenstatic 4489227825Stheravenwstring* 4490227825Stheraveninit_wmonths() 4491227825Stheraven{ 4492227825Stheraven static wstring months[24]; 4493227825Stheraven months[0] = L"January"; 4494227825Stheraven months[1] = L"February"; 4495227825Stheraven months[2] = L"March"; 4496227825Stheraven months[3] = L"April"; 4497227825Stheraven months[4] = L"May"; 4498227825Stheraven months[5] = L"June"; 4499227825Stheraven months[6] = L"July"; 4500227825Stheraven months[7] = L"August"; 4501227825Stheraven months[8] = L"September"; 4502227825Stheraven months[9] = L"October"; 4503227825Stheraven months[10] = L"November"; 4504227825Stheraven months[11] = L"December"; 4505227825Stheraven months[12] = L"Jan"; 4506227825Stheraven months[13] = L"Feb"; 4507227825Stheraven months[14] = L"Mar"; 4508227825Stheraven months[15] = L"Apr"; 4509227825Stheraven months[16] = L"May"; 4510227825Stheraven months[17] = L"Jun"; 4511227825Stheraven months[18] = L"Jul"; 4512227825Stheraven months[19] = L"Aug"; 4513227825Stheraven months[20] = L"Sep"; 4514227825Stheraven months[21] = L"Oct"; 4515227825Stheraven months[22] = L"Nov"; 4516227825Stheraven months[23] = L"Dec"; 4517227825Stheraven return months; 4518227825Stheraven} 4519227825Stheraven 4520227825Stheraventemplate <> 4521227825Stheravenconst string* 4522227825Stheraven__time_get_c_storage<char>::__months() const 4523227825Stheraven{ 4524227825Stheraven static const string* months = init_months(); 4525227825Stheraven return months; 4526227825Stheraven} 4527227825Stheraven 4528227825Stheraventemplate <> 4529227825Stheravenconst wstring* 4530227825Stheraven__time_get_c_storage<wchar_t>::__months() const 4531227825Stheraven{ 4532227825Stheraven static const wstring* months = init_wmonths(); 4533227825Stheraven return months; 4534227825Stheraven} 4535227825Stheraven 4536227825Stheravenstatic 4537227825Stheravenstring* 4538227825Stheraveninit_am_pm() 4539227825Stheraven{ 4540227825Stheraven static string am_pm[24]; 4541227825Stheraven am_pm[0] = "AM"; 4542227825Stheraven am_pm[1] = "PM"; 4543227825Stheraven return am_pm; 4544227825Stheraven} 4545227825Stheraven 4546227825Stheravenstatic 4547227825Stheravenwstring* 4548227825Stheraveninit_wam_pm() 4549227825Stheraven{ 4550227825Stheraven static wstring am_pm[24]; 4551227825Stheraven am_pm[0] = L"AM"; 4552227825Stheraven am_pm[1] = L"PM"; 4553227825Stheraven return am_pm; 4554227825Stheraven} 4555227825Stheraven 4556227825Stheraventemplate <> 4557227825Stheravenconst string* 4558227825Stheraven__time_get_c_storage<char>::__am_pm() const 4559227825Stheraven{ 4560227825Stheraven static const string* am_pm = init_am_pm(); 4561227825Stheraven return am_pm; 4562227825Stheraven} 4563227825Stheraven 4564227825Stheraventemplate <> 4565227825Stheravenconst wstring* 4566227825Stheraven__time_get_c_storage<wchar_t>::__am_pm() const 4567227825Stheraven{ 4568227825Stheraven static const wstring* am_pm = init_wam_pm(); 4569227825Stheraven return am_pm; 4570227825Stheraven} 4571227825Stheraven 4572227825Stheraventemplate <> 4573227825Stheravenconst string& 4574227825Stheraven__time_get_c_storage<char>::__x() const 4575227825Stheraven{ 4576227825Stheraven static string s("%m/%d/%y"); 4577227825Stheraven return s; 4578227825Stheraven} 4579227825Stheraven 4580227825Stheraventemplate <> 4581227825Stheravenconst wstring& 4582227825Stheraven__time_get_c_storage<wchar_t>::__x() const 4583227825Stheraven{ 4584227825Stheraven static wstring s(L"%m/%d/%y"); 4585227825Stheraven return s; 4586227825Stheraven} 4587227825Stheraven 4588227825Stheraventemplate <> 4589227825Stheravenconst string& 4590227825Stheraven__time_get_c_storage<char>::__X() const 4591227825Stheraven{ 4592227825Stheraven static string s("%H:%M:%S"); 4593227825Stheraven return s; 4594227825Stheraven} 4595227825Stheraven 4596227825Stheraventemplate <> 4597227825Stheravenconst wstring& 4598227825Stheraven__time_get_c_storage<wchar_t>::__X() const 4599227825Stheraven{ 4600227825Stheraven static wstring s(L"%H:%M:%S"); 4601227825Stheraven return s; 4602227825Stheraven} 4603227825Stheraven 4604227825Stheraventemplate <> 4605227825Stheravenconst string& 4606227825Stheraven__time_get_c_storage<char>::__c() const 4607227825Stheraven{ 4608227825Stheraven static string s("%a %b %d %H:%M:%S %Y"); 4609227825Stheraven return s; 4610227825Stheraven} 4611227825Stheraven 4612227825Stheraventemplate <> 4613227825Stheravenconst wstring& 4614227825Stheraven__time_get_c_storage<wchar_t>::__c() const 4615227825Stheraven{ 4616227825Stheraven static wstring s(L"%a %b %d %H:%M:%S %Y"); 4617227825Stheraven return s; 4618227825Stheraven} 4619227825Stheraven 4620227825Stheraventemplate <> 4621227825Stheravenconst string& 4622227825Stheraven__time_get_c_storage<char>::__r() const 4623227825Stheraven{ 4624227825Stheraven static string s("%I:%M:%S %p"); 4625227825Stheraven return s; 4626227825Stheraven} 4627227825Stheraven 4628227825Stheraventemplate <> 4629227825Stheravenconst wstring& 4630227825Stheraven__time_get_c_storage<wchar_t>::__r() const 4631227825Stheraven{ 4632227825Stheraven static wstring s(L"%I:%M:%S %p"); 4633227825Stheraven return s; 4634227825Stheraven} 4635227825Stheraven 4636227825Stheraven// time_get_byname 4637227825Stheraven 4638227825Stheraven__time_get::__time_get(const char* nm) 4639227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 4640227825Stheraven{ 4641227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4642227825Stheraven if (__loc_ == 0) 4643227825Stheraven throw runtime_error("time_get_byname" 4644227825Stheraven " failed to construct for " + string(nm)); 4645227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4646227825Stheraven} 4647227825Stheraven 4648227825Stheraven__time_get::__time_get(const string& nm) 4649227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 4650227825Stheraven{ 4651227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4652227825Stheraven if (__loc_ == 0) 4653227825Stheraven throw runtime_error("time_get_byname" 4654227825Stheraven " failed to construct for " + nm); 4655227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4656227825Stheraven} 4657227825Stheraven 4658227825Stheraven__time_get::~__time_get() 4659227825Stheraven{ 4660227825Stheraven freelocale(__loc_); 4661227825Stheraven} 4662227825Stheraven 4663232950Stheraven#pragma clang diagnostic ignored "-Wmissing-field-initializers" 4664246487Stheraven#pragma GCC diagnostic ignored "-Wmissing-field-initializers" 4665232950Stheraven 4666227825Stheraventemplate <> 4667227825Stheravenstring 4668227825Stheraven__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) 4669227825Stheraven{ 4670232950Stheraven tm t = {0}; 4671227825Stheraven t.tm_sec = 59; 4672227825Stheraven t.tm_min = 55; 4673227825Stheraven t.tm_hour = 23; 4674227825Stheraven t.tm_mday = 31; 4675227825Stheraven t.tm_mon = 11; 4676227825Stheraven t.tm_year = 161; 4677227825Stheraven t.tm_wday = 6; 4678227825Stheraven t.tm_yday = 364; 4679227825Stheraven t.tm_isdst = -1; 4680227825Stheraven char buf[100]; 4681227825Stheraven char f[3] = {0}; 4682227825Stheraven f[0] = '%'; 4683227825Stheraven f[1] = fmt; 4684246487Stheraven size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); 4685227825Stheraven char* bb = buf; 4686227825Stheraven char* be = buf + n; 4687227825Stheraven string result; 4688227825Stheraven while (bb != be) 4689227825Stheraven { 4690227825Stheraven if (ct.is(ctype_base::space, *bb)) 4691227825Stheraven { 4692227825Stheraven result.push_back(' '); 4693227825Stheraven for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb) 4694227825Stheraven ; 4695227825Stheraven continue; 4696227825Stheraven } 4697227825Stheraven char* w = bb; 4698227825Stheraven ios_base::iostate err = ios_base::goodbit; 4699232950Stheraven ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14, 4700227825Stheraven ct, err, false) 4701227825Stheraven - this->__weeks_; 4702227825Stheraven if (i < 14) 4703227825Stheraven { 4704227825Stheraven result.push_back('%'); 4705227825Stheraven if (i < 7) 4706227825Stheraven result.push_back('A'); 4707227825Stheraven else 4708227825Stheraven result.push_back('a'); 4709227825Stheraven bb = w; 4710227825Stheraven continue; 4711227825Stheraven } 4712227825Stheraven w = bb; 4713227825Stheraven i = __scan_keyword(w, be, this->__months_, this->__months_+24, 4714227825Stheraven ct, err, false) 4715227825Stheraven - this->__months_; 4716227825Stheraven if (i < 24) 4717227825Stheraven { 4718227825Stheraven result.push_back('%'); 4719227825Stheraven if (i < 12) 4720227825Stheraven result.push_back('B'); 4721227825Stheraven else 4722227825Stheraven result.push_back('b'); 4723227825Stheraven if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4724227825Stheraven result.back() = 'm'; 4725227825Stheraven bb = w; 4726227825Stheraven continue; 4727227825Stheraven } 4728227825Stheraven if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4729227825Stheraven { 4730227825Stheraven w = bb; 4731227825Stheraven i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2, 4732227825Stheraven ct, err, false) - this->__am_pm_; 4733227825Stheraven if (i < 2) 4734227825Stheraven { 4735227825Stheraven result.push_back('%'); 4736227825Stheraven result.push_back('p'); 4737227825Stheraven bb = w; 4738227825Stheraven continue; 4739227825Stheraven } 4740227825Stheraven } 4741227825Stheraven w = bb; 4742227825Stheraven if (ct.is(ctype_base::digit, *bb)) 4743227825Stheraven { 4744227825Stheraven switch(__get_up_to_n_digits(bb, be, err, ct, 4)) 4745227825Stheraven { 4746227825Stheraven case 6: 4747227825Stheraven result.push_back('%'); 4748227825Stheraven result.push_back('w'); 4749227825Stheraven break; 4750227825Stheraven case 7: 4751227825Stheraven result.push_back('%'); 4752227825Stheraven result.push_back('u'); 4753227825Stheraven break; 4754227825Stheraven case 11: 4755227825Stheraven result.push_back('%'); 4756227825Stheraven result.push_back('I'); 4757227825Stheraven break; 4758227825Stheraven case 12: 4759227825Stheraven result.push_back('%'); 4760227825Stheraven result.push_back('m'); 4761227825Stheraven break; 4762227825Stheraven case 23: 4763227825Stheraven result.push_back('%'); 4764227825Stheraven result.push_back('H'); 4765227825Stheraven break; 4766227825Stheraven case 31: 4767227825Stheraven result.push_back('%'); 4768227825Stheraven result.push_back('d'); 4769227825Stheraven break; 4770227825Stheraven case 55: 4771227825Stheraven result.push_back('%'); 4772227825Stheraven result.push_back('M'); 4773227825Stheraven break; 4774227825Stheraven case 59: 4775227825Stheraven result.push_back('%'); 4776227825Stheraven result.push_back('S'); 4777227825Stheraven break; 4778227825Stheraven case 61: 4779227825Stheraven result.push_back('%'); 4780227825Stheraven result.push_back('y'); 4781227825Stheraven break; 4782227825Stheraven case 364: 4783227825Stheraven result.push_back('%'); 4784227825Stheraven result.push_back('j'); 4785227825Stheraven break; 4786227825Stheraven case 2061: 4787227825Stheraven result.push_back('%'); 4788227825Stheraven result.push_back('Y'); 4789227825Stheraven break; 4790227825Stheraven default: 4791227825Stheraven for (; w != bb; ++w) 4792227825Stheraven result.push_back(*w); 4793227825Stheraven break; 4794227825Stheraven } 4795227825Stheraven continue; 4796227825Stheraven } 4797227825Stheraven if (*bb == '%') 4798227825Stheraven { 4799227825Stheraven result.push_back('%'); 4800227825Stheraven result.push_back('%'); 4801227825Stheraven ++bb; 4802227825Stheraven continue; 4803227825Stheraven } 4804227825Stheraven result.push_back(*bb); 4805227825Stheraven ++bb; 4806227825Stheraven } 4807227825Stheraven return result; 4808227825Stheraven} 4809227825Stheraven 4810232950Stheraven#pragma clang diagnostic ignored "-Wmissing-braces" 4811232950Stheraven 4812227825Stheraventemplate <> 4813227825Stheravenwstring 4814227825Stheraven__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) 4815227825Stheraven{ 4816232950Stheraven tm t = {0}; 4817227825Stheraven t.tm_sec = 59; 4818227825Stheraven t.tm_min = 55; 4819227825Stheraven t.tm_hour = 23; 4820227825Stheraven t.tm_mday = 31; 4821227825Stheraven t.tm_mon = 11; 4822227825Stheraven t.tm_year = 161; 4823227825Stheraven t.tm_wday = 6; 4824227825Stheraven t.tm_yday = 364; 4825227825Stheraven t.tm_isdst = -1; 4826227825Stheraven char buf[100]; 4827227825Stheraven char f[3] = {0}; 4828227825Stheraven f[0] = '%'; 4829227825Stheraven f[1] = fmt; 4830246487Stheraven strftime_l(buf, countof(buf), f, &t, __loc_); 4831227825Stheraven wchar_t wbuf[100]; 4832227825Stheraven wchar_t* wbb = wbuf; 4833227825Stheraven mbstate_t mb = {0}; 4834227825Stheraven const char* bb = buf; 4835227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4836246487Stheraven size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); 4837227825Stheraven#else 4838246487Stheraven size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); 4839227825Stheraven#endif 4840232950Stheraven if (j == size_t(-1)) 4841227825Stheraven __throw_runtime_error("locale not supported"); 4842232950Stheraven wchar_t* wbe = wbb + j; 4843227825Stheraven wstring result; 4844227825Stheraven while (wbb != wbe) 4845227825Stheraven { 4846227825Stheraven if (ct.is(ctype_base::space, *wbb)) 4847227825Stheraven { 4848227825Stheraven result.push_back(L' '); 4849227825Stheraven for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb) 4850227825Stheraven ; 4851227825Stheraven continue; 4852227825Stheraven } 4853227825Stheraven wchar_t* w = wbb; 4854227825Stheraven ios_base::iostate err = ios_base::goodbit; 4855232950Stheraven ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14, 4856227825Stheraven ct, err, false) 4857227825Stheraven - this->__weeks_; 4858227825Stheraven if (i < 14) 4859227825Stheraven { 4860227825Stheraven result.push_back(L'%'); 4861227825Stheraven if (i < 7) 4862227825Stheraven result.push_back(L'A'); 4863227825Stheraven else 4864227825Stheraven result.push_back(L'a'); 4865227825Stheraven wbb = w; 4866227825Stheraven continue; 4867227825Stheraven } 4868227825Stheraven w = wbb; 4869227825Stheraven i = __scan_keyword(w, wbe, this->__months_, this->__months_+24, 4870227825Stheraven ct, err, false) 4871227825Stheraven - this->__months_; 4872227825Stheraven if (i < 24) 4873227825Stheraven { 4874227825Stheraven result.push_back(L'%'); 4875227825Stheraven if (i < 12) 4876227825Stheraven result.push_back(L'B'); 4877227825Stheraven else 4878227825Stheraven result.push_back(L'b'); 4879227825Stheraven if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4880227825Stheraven result.back() = L'm'; 4881227825Stheraven wbb = w; 4882227825Stheraven continue; 4883227825Stheraven } 4884227825Stheraven if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4885227825Stheraven { 4886227825Stheraven w = wbb; 4887227825Stheraven i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2, 4888227825Stheraven ct, err, false) - this->__am_pm_; 4889227825Stheraven if (i < 2) 4890227825Stheraven { 4891227825Stheraven result.push_back(L'%'); 4892227825Stheraven result.push_back(L'p'); 4893227825Stheraven wbb = w; 4894227825Stheraven continue; 4895227825Stheraven } 4896227825Stheraven } 4897227825Stheraven w = wbb; 4898227825Stheraven if (ct.is(ctype_base::digit, *wbb)) 4899227825Stheraven { 4900227825Stheraven switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4)) 4901227825Stheraven { 4902227825Stheraven case 6: 4903227825Stheraven result.push_back(L'%'); 4904227825Stheraven result.push_back(L'w'); 4905227825Stheraven break; 4906227825Stheraven case 7: 4907227825Stheraven result.push_back(L'%'); 4908227825Stheraven result.push_back(L'u'); 4909227825Stheraven break; 4910227825Stheraven case 11: 4911227825Stheraven result.push_back(L'%'); 4912227825Stheraven result.push_back(L'I'); 4913227825Stheraven break; 4914227825Stheraven case 12: 4915227825Stheraven result.push_back(L'%'); 4916227825Stheraven result.push_back(L'm'); 4917227825Stheraven break; 4918227825Stheraven case 23: 4919227825Stheraven result.push_back(L'%'); 4920227825Stheraven result.push_back(L'H'); 4921227825Stheraven break; 4922227825Stheraven case 31: 4923227825Stheraven result.push_back(L'%'); 4924227825Stheraven result.push_back(L'd'); 4925227825Stheraven break; 4926227825Stheraven case 55: 4927227825Stheraven result.push_back(L'%'); 4928227825Stheraven result.push_back(L'M'); 4929227825Stheraven break; 4930227825Stheraven case 59: 4931227825Stheraven result.push_back(L'%'); 4932227825Stheraven result.push_back(L'S'); 4933227825Stheraven break; 4934227825Stheraven case 61: 4935227825Stheraven result.push_back(L'%'); 4936227825Stheraven result.push_back(L'y'); 4937227825Stheraven break; 4938227825Stheraven case 364: 4939227825Stheraven result.push_back(L'%'); 4940227825Stheraven result.push_back(L'j'); 4941227825Stheraven break; 4942227825Stheraven case 2061: 4943227825Stheraven result.push_back(L'%'); 4944227825Stheraven result.push_back(L'Y'); 4945227825Stheraven break; 4946227825Stheraven default: 4947227825Stheraven for (; w != wbb; ++w) 4948227825Stheraven result.push_back(*w); 4949227825Stheraven break; 4950227825Stheraven } 4951227825Stheraven continue; 4952227825Stheraven } 4953227825Stheraven if (ct.narrow(*wbb, 0) == '%') 4954227825Stheraven { 4955227825Stheraven result.push_back(L'%'); 4956227825Stheraven result.push_back(L'%'); 4957227825Stheraven ++wbb; 4958227825Stheraven continue; 4959227825Stheraven } 4960227825Stheraven result.push_back(*wbb); 4961227825Stheraven ++wbb; 4962227825Stheraven } 4963227825Stheraven return result; 4964227825Stheraven} 4965227825Stheraven 4966227825Stheraventemplate <> 4967227825Stheravenvoid 4968227825Stheraven__time_get_storage<char>::init(const ctype<char>& ct) 4969227825Stheraven{ 4970241903Sdim tm t = {0}; 4971227825Stheraven char buf[100]; 4972227825Stheraven // __weeks_ 4973227825Stheraven for (int i = 0; i < 7; ++i) 4974227825Stheraven { 4975227825Stheraven t.tm_wday = i; 4976246487Stheraven strftime_l(buf, countof(buf), "%A", &t, __loc_); 4977227825Stheraven __weeks_[i] = buf; 4978246487Stheraven strftime_l(buf, countof(buf), "%a", &t, __loc_); 4979227825Stheraven __weeks_[i+7] = buf; 4980227825Stheraven } 4981227825Stheraven // __months_ 4982227825Stheraven for (int i = 0; i < 12; ++i) 4983227825Stheraven { 4984227825Stheraven t.tm_mon = i; 4985246487Stheraven strftime_l(buf, countof(buf), "%B", &t, __loc_); 4986227825Stheraven __months_[i] = buf; 4987246487Stheraven strftime_l(buf, countof(buf), "%b", &t, __loc_); 4988227825Stheraven __months_[i+12] = buf; 4989227825Stheraven } 4990227825Stheraven // __am_pm_ 4991227825Stheraven t.tm_hour = 1; 4992246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 4993227825Stheraven __am_pm_[0] = buf; 4994227825Stheraven t.tm_hour = 13; 4995246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 4996227825Stheraven __am_pm_[1] = buf; 4997227825Stheraven __c_ = __analyze('c', ct); 4998227825Stheraven __r_ = __analyze('r', ct); 4999227825Stheraven __x_ = __analyze('x', ct); 5000227825Stheraven __X_ = __analyze('X', ct); 5001227825Stheraven} 5002227825Stheraven 5003227825Stheraventemplate <> 5004227825Stheravenvoid 5005227825Stheraven__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) 5006227825Stheraven{ 5007227825Stheraven tm t = {0}; 5008227825Stheraven char buf[100]; 5009227825Stheraven wchar_t wbuf[100]; 5010227825Stheraven wchar_t* wbe; 5011227825Stheraven mbstate_t mb = {0}; 5012227825Stheraven // __weeks_ 5013227825Stheraven for (int i = 0; i < 7; ++i) 5014227825Stheraven { 5015227825Stheraven t.tm_wday = i; 5016246487Stheraven strftime_l(buf, countof(buf), "%A", &t, __loc_); 5017227825Stheraven mb = mbstate_t(); 5018227825Stheraven const char* bb = buf; 5019227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5020246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5021227825Stheraven#else 5022246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5023227825Stheraven#endif 5024232950Stheraven if (j == size_t(-1)) 5025227825Stheraven __throw_runtime_error("locale not supported"); 5026227825Stheraven wbe = wbuf + j; 5027227825Stheraven __weeks_[i].assign(wbuf, wbe); 5028246487Stheraven strftime_l(buf, countof(buf), "%a", &t, __loc_); 5029227825Stheraven mb = mbstate_t(); 5030227825Stheraven bb = buf; 5031227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5032246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5033227825Stheraven#else 5034246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5035227825Stheraven#endif 5036232950Stheraven if (j == size_t(-1)) 5037227825Stheraven __throw_runtime_error("locale not supported"); 5038227825Stheraven wbe = wbuf + j; 5039227825Stheraven __weeks_[i+7].assign(wbuf, wbe); 5040227825Stheraven } 5041227825Stheraven // __months_ 5042227825Stheraven for (int i = 0; i < 12; ++i) 5043227825Stheraven { 5044227825Stheraven t.tm_mon = i; 5045246487Stheraven strftime_l(buf, countof(buf), "%B", &t, __loc_); 5046227825Stheraven mb = mbstate_t(); 5047227825Stheraven const char* bb = buf; 5048227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5049246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5050227825Stheraven#else 5051246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5052227825Stheraven#endif 5053232950Stheraven if (j == size_t(-1)) 5054227825Stheraven __throw_runtime_error("locale not supported"); 5055227825Stheraven wbe = wbuf + j; 5056227825Stheraven __months_[i].assign(wbuf, wbe); 5057246487Stheraven strftime_l(buf, countof(buf), "%b", &t, __loc_); 5058227825Stheraven mb = mbstate_t(); 5059227825Stheraven bb = buf; 5060227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5061246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5062227825Stheraven#else 5063246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5064227825Stheraven#endif 5065232950Stheraven if (j == size_t(-1)) 5066227825Stheraven __throw_runtime_error("locale not supported"); 5067227825Stheraven wbe = wbuf + j; 5068227825Stheraven __months_[i+12].assign(wbuf, wbe); 5069227825Stheraven } 5070227825Stheraven // __am_pm_ 5071227825Stheraven t.tm_hour = 1; 5072246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5073227825Stheraven mb = mbstate_t(); 5074227825Stheraven const char* bb = buf; 5075227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5076246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5077227825Stheraven#else 5078246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5079227825Stheraven#endif 5080232950Stheraven if (j == size_t(-1)) 5081227825Stheraven __throw_runtime_error("locale not supported"); 5082227825Stheraven wbe = wbuf + j; 5083227825Stheraven __am_pm_[0].assign(wbuf, wbe); 5084227825Stheraven t.tm_hour = 13; 5085246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5086227825Stheraven mb = mbstate_t(); 5087227825Stheraven bb = buf; 5088227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5089246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5090227825Stheraven#else 5091246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5092227825Stheraven#endif 5093232950Stheraven if (j == size_t(-1)) 5094227825Stheraven __throw_runtime_error("locale not supported"); 5095227825Stheraven wbe = wbuf + j; 5096227825Stheraven __am_pm_[1].assign(wbuf, wbe); 5097227825Stheraven __c_ = __analyze('c', ct); 5098227825Stheraven __r_ = __analyze('r', ct); 5099227825Stheraven __x_ = __analyze('x', ct); 5100227825Stheraven __X_ = __analyze('X', ct); 5101227825Stheraven} 5102227825Stheraven 5103227825Stheraventemplate <class CharT> 5104227825Stheravenstruct _LIBCPP_HIDDEN __time_get_temp 5105227825Stheraven : public ctype_byname<CharT> 5106227825Stheraven{ 5107227825Stheraven explicit __time_get_temp(const char* nm) 5108227825Stheraven : ctype_byname<CharT>(nm, 1) {} 5109227825Stheraven explicit __time_get_temp(const string& nm) 5110227825Stheraven : ctype_byname<CharT>(nm, 1) {} 5111227825Stheraven}; 5112227825Stheraven 5113227825Stheraventemplate <> 5114227825Stheraven__time_get_storage<char>::__time_get_storage(const char* __nm) 5115227825Stheraven : __time_get(__nm) 5116227825Stheraven{ 5117227825Stheraven const __time_get_temp<char> ct(__nm); 5118227825Stheraven init(ct); 5119227825Stheraven} 5120227825Stheraven 5121227825Stheraventemplate <> 5122227825Stheraven__time_get_storage<char>::__time_get_storage(const string& __nm) 5123227825Stheraven : __time_get(__nm) 5124227825Stheraven{ 5125227825Stheraven const __time_get_temp<char> ct(__nm); 5126227825Stheraven init(ct); 5127227825Stheraven} 5128227825Stheraven 5129227825Stheraventemplate <> 5130227825Stheraven__time_get_storage<wchar_t>::__time_get_storage(const char* __nm) 5131227825Stheraven : __time_get(__nm) 5132227825Stheraven{ 5133227825Stheraven const __time_get_temp<wchar_t> ct(__nm); 5134227825Stheraven init(ct); 5135227825Stheraven} 5136227825Stheraven 5137227825Stheraventemplate <> 5138227825Stheraven__time_get_storage<wchar_t>::__time_get_storage(const string& __nm) 5139227825Stheraven : __time_get(__nm) 5140227825Stheraven{ 5141227825Stheraven const __time_get_temp<wchar_t> ct(__nm); 5142227825Stheraven init(ct); 5143227825Stheraven} 5144227825Stheraven 5145227825Stheraventemplate <> 5146227825Stheraventime_base::dateorder 5147227825Stheraven__time_get_storage<char>::__do_date_order() const 5148227825Stheraven{ 5149227825Stheraven unsigned i; 5150227825Stheraven for (i = 0; i < __x_.size(); ++i) 5151227825Stheraven if (__x_[i] == '%') 5152227825Stheraven break; 5153227825Stheraven ++i; 5154227825Stheraven switch (__x_[i]) 5155227825Stheraven { 5156227825Stheraven case 'y': 5157227825Stheraven case 'Y': 5158227825Stheraven for (++i; i < __x_.size(); ++i) 5159227825Stheraven if (__x_[i] == '%') 5160227825Stheraven break; 5161227825Stheraven if (i == __x_.size()) 5162227825Stheraven break; 5163227825Stheraven ++i; 5164227825Stheraven switch (__x_[i]) 5165227825Stheraven { 5166227825Stheraven case 'm': 5167227825Stheraven for (++i; i < __x_.size(); ++i) 5168227825Stheraven if (__x_[i] == '%') 5169227825Stheraven break; 5170227825Stheraven if (i == __x_.size()) 5171227825Stheraven break; 5172227825Stheraven ++i; 5173227825Stheraven if (__x_[i] == 'd') 5174227825Stheraven return time_base::ymd; 5175227825Stheraven break; 5176227825Stheraven case 'd': 5177227825Stheraven for (++i; i < __x_.size(); ++i) 5178227825Stheraven if (__x_[i] == '%') 5179227825Stheraven break; 5180227825Stheraven if (i == __x_.size()) 5181227825Stheraven break; 5182227825Stheraven ++i; 5183227825Stheraven if (__x_[i] == 'm') 5184227825Stheraven return time_base::ydm; 5185227825Stheraven break; 5186227825Stheraven } 5187227825Stheraven break; 5188227825Stheraven case 'm': 5189227825Stheraven for (++i; i < __x_.size(); ++i) 5190227825Stheraven if (__x_[i] == '%') 5191227825Stheraven break; 5192227825Stheraven if (i == __x_.size()) 5193227825Stheraven break; 5194227825Stheraven ++i; 5195227825Stheraven if (__x_[i] == 'd') 5196227825Stheraven { 5197227825Stheraven for (++i; i < __x_.size(); ++i) 5198227825Stheraven if (__x_[i] == '%') 5199227825Stheraven break; 5200227825Stheraven if (i == __x_.size()) 5201227825Stheraven break; 5202227825Stheraven ++i; 5203227825Stheraven if (__x_[i] == 'y' || __x_[i] == 'Y') 5204227825Stheraven return time_base::mdy; 5205227825Stheraven break; 5206227825Stheraven } 5207227825Stheraven break; 5208227825Stheraven case 'd': 5209227825Stheraven for (++i; i < __x_.size(); ++i) 5210227825Stheraven if (__x_[i] == '%') 5211227825Stheraven break; 5212227825Stheraven if (i == __x_.size()) 5213227825Stheraven break; 5214227825Stheraven ++i; 5215227825Stheraven if (__x_[i] == 'm') 5216227825Stheraven { 5217227825Stheraven for (++i; i < __x_.size(); ++i) 5218227825Stheraven if (__x_[i] == '%') 5219227825Stheraven break; 5220227825Stheraven if (i == __x_.size()) 5221227825Stheraven break; 5222227825Stheraven ++i; 5223227825Stheraven if (__x_[i] == 'y' || __x_[i] == 'Y') 5224227825Stheraven return time_base::dmy; 5225227825Stheraven break; 5226227825Stheraven } 5227227825Stheraven break; 5228227825Stheraven } 5229227825Stheraven return time_base::no_order; 5230227825Stheraven} 5231227825Stheraven 5232227825Stheraventemplate <> 5233227825Stheraventime_base::dateorder 5234227825Stheraven__time_get_storage<wchar_t>::__do_date_order() const 5235227825Stheraven{ 5236227825Stheraven unsigned i; 5237227825Stheraven for (i = 0; i < __x_.size(); ++i) 5238227825Stheraven if (__x_[i] == L'%') 5239227825Stheraven break; 5240227825Stheraven ++i; 5241227825Stheraven switch (__x_[i]) 5242227825Stheraven { 5243227825Stheraven case L'y': 5244227825Stheraven case L'Y': 5245227825Stheraven for (++i; i < __x_.size(); ++i) 5246227825Stheraven if (__x_[i] == L'%') 5247227825Stheraven break; 5248227825Stheraven if (i == __x_.size()) 5249227825Stheraven break; 5250227825Stheraven ++i; 5251227825Stheraven switch (__x_[i]) 5252227825Stheraven { 5253227825Stheraven case L'm': 5254227825Stheraven for (++i; i < __x_.size(); ++i) 5255227825Stheraven if (__x_[i] == L'%') 5256227825Stheraven break; 5257227825Stheraven if (i == __x_.size()) 5258227825Stheraven break; 5259227825Stheraven ++i; 5260227825Stheraven if (__x_[i] == L'd') 5261227825Stheraven return time_base::ymd; 5262227825Stheraven break; 5263227825Stheraven case L'd': 5264227825Stheraven for (++i; i < __x_.size(); ++i) 5265227825Stheraven if (__x_[i] == L'%') 5266227825Stheraven break; 5267227825Stheraven if (i == __x_.size()) 5268227825Stheraven break; 5269227825Stheraven ++i; 5270227825Stheraven if (__x_[i] == L'm') 5271227825Stheraven return time_base::ydm; 5272227825Stheraven break; 5273227825Stheraven } 5274227825Stheraven break; 5275227825Stheraven case L'm': 5276227825Stheraven for (++i; i < __x_.size(); ++i) 5277227825Stheraven if (__x_[i] == L'%') 5278227825Stheraven break; 5279227825Stheraven if (i == __x_.size()) 5280227825Stheraven break; 5281227825Stheraven ++i; 5282227825Stheraven if (__x_[i] == L'd') 5283227825Stheraven { 5284227825Stheraven for (++i; i < __x_.size(); ++i) 5285227825Stheraven if (__x_[i] == L'%') 5286227825Stheraven break; 5287227825Stheraven if (i == __x_.size()) 5288227825Stheraven break; 5289227825Stheraven ++i; 5290227825Stheraven if (__x_[i] == L'y' || __x_[i] == L'Y') 5291227825Stheraven return time_base::mdy; 5292227825Stheraven break; 5293227825Stheraven } 5294227825Stheraven break; 5295227825Stheraven case L'd': 5296227825Stheraven for (++i; i < __x_.size(); ++i) 5297227825Stheraven if (__x_[i] == L'%') 5298227825Stheraven break; 5299227825Stheraven if (i == __x_.size()) 5300227825Stheraven break; 5301227825Stheraven ++i; 5302227825Stheraven if (__x_[i] == L'm') 5303227825Stheraven { 5304227825Stheraven for (++i; i < __x_.size(); ++i) 5305227825Stheraven if (__x_[i] == L'%') 5306227825Stheraven break; 5307227825Stheraven if (i == __x_.size()) 5308227825Stheraven break; 5309227825Stheraven ++i; 5310227825Stheraven if (__x_[i] == L'y' || __x_[i] == L'Y') 5311227825Stheraven return time_base::dmy; 5312227825Stheraven break; 5313227825Stheraven } 5314227825Stheraven break; 5315227825Stheraven } 5316227825Stheraven return time_base::no_order; 5317227825Stheraven} 5318227825Stheraven 5319227825Stheraven// time_put 5320227825Stheraven 5321227825Stheraven__time_put::__time_put(const char* nm) 5322227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 5323227825Stheraven{ 5324227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5325227825Stheraven if (__loc_ == 0) 5326227825Stheraven throw runtime_error("time_put_byname" 5327227825Stheraven " failed to construct for " + string(nm)); 5328227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5329227825Stheraven} 5330227825Stheraven 5331227825Stheraven__time_put::__time_put(const string& nm) 5332227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 5333227825Stheraven{ 5334227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5335227825Stheraven if (__loc_ == 0) 5336227825Stheraven throw runtime_error("time_put_byname" 5337227825Stheraven " failed to construct for " + nm); 5338227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5339227825Stheraven} 5340227825Stheraven 5341227825Stheraven__time_put::~__time_put() 5342227825Stheraven{ 5343253159Stheraven if (__loc_ != _LIBCPP_GET_C_LOCALE) 5344227825Stheraven freelocale(__loc_); 5345227825Stheraven} 5346227825Stheraven 5347227825Stheravenvoid 5348227825Stheraven__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, 5349227825Stheraven char __fmt, char __mod) const 5350227825Stheraven{ 5351227825Stheraven char fmt[] = {'%', __fmt, __mod, 0}; 5352227825Stheraven if (__mod != 0) 5353227825Stheraven swap(fmt[1], fmt[2]); 5354246487Stheraven size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); 5355227825Stheraven __ne = __nb + n; 5356227825Stheraven} 5357227825Stheraven 5358227825Stheravenvoid 5359227825Stheraven__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 5360227825Stheraven char __fmt, char __mod) const 5361227825Stheraven{ 5362227825Stheraven char __nar[100]; 5363227825Stheraven char* __ne = __nar + 100; 5364227825Stheraven __do_put(__nar, __ne, __tm, __fmt, __mod); 5365227825Stheraven mbstate_t mb = {0}; 5366227825Stheraven const char* __nb = __nar; 5367227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5368246487Stheraven size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); 5369227825Stheraven#else 5370246487Stheraven size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); 5371227825Stheraven#endif 5372232950Stheraven if (j == size_t(-1)) 5373227825Stheraven __throw_runtime_error("locale not supported"); 5374227825Stheraven __we = __wb + j; 5375227825Stheraven} 5376227825Stheraven 5377227825Stheraven// moneypunct_byname 5378227825Stheraven 5379232950Stheraventemplate <class charT> 5380227825Stheravenstatic 5381227825Stheravenvoid 5382232950Stheraven__init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_, 5383232950Stheraven bool intl, char cs_precedes, char sep_by_space, char sign_posn, 5384232950Stheraven charT space_char) 5385227825Stheraven{ 5386227825Stheraven const char sign = static_cast<char>(money_base::sign); 5387227825Stheraven const char space = static_cast<char>(money_base::space); 5388227825Stheraven const char none = static_cast<char>(money_base::none); 5389227825Stheraven const char symbol = static_cast<char>(money_base::symbol); 5390227825Stheraven const char value = static_cast<char>(money_base::value); 5391232950Stheraven const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4; 5392232950Stheraven 5393232950Stheraven // Comments on case branches reflect 'C11 7.11.2.1 The localeconv 5394232950Stheraven // function'. "Space between sign and symbol or value" means that 5395232950Stheraven // if the sign is adjacent to the symbol, there's a space between 5396232950Stheraven // them, and otherwise there's a space between the sign and value. 5397232950Stheraven // 5398232950Stheraven // C11's localeconv specifies that the fourth character of an 5399232950Stheraven // international curr_symbol is used to separate the sign and 5400232950Stheraven // value when sep_by_space says to do so. C++ can't represent 5401232950Stheraven // that, so we just use a space. When sep_by_space says to 5402232950Stheraven // separate the symbol and value-or-sign with a space, we rearrange the 5403232950Stheraven // curr_symbol to put its spacing character on the correct side of 5404232950Stheraven // the symbol. 5405232950Stheraven // 5406232950Stheraven // We also need to avoid adding an extra space between the sign 5407232950Stheraven // and value when the currency symbol is suppressed (by not 5408232950Stheraven // setting showbase). We match glibc's strfmon by interpreting 5409232950Stheraven // sep_by_space==1 as "omit the space when the currency symbol is 5410232950Stheraven // absent". 5411232950Stheraven // 5412232950Stheraven // Users who want to get this right should use ICU instead. 5413232950Stheraven 5414227825Stheraven switch (cs_precedes) 5415227825Stheraven { 5416232950Stheraven case 0: // value before curr_symbol 5417232950Stheraven if (symbol_contains_sep) { 5418232950Stheraven // Move the separator to before the symbol, to place it 5419232950Stheraven // between the value and symbol. 5420232950Stheraven rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, 5421232950Stheraven __curr_symbol_.end()); 5422232950Stheraven } 5423227825Stheraven switch (sign_posn) 5424227825Stheraven { 5425232950Stheraven case 0: // Parentheses surround the quantity and currency symbol. 5426227825Stheraven pat.field[0] = sign; 5427227825Stheraven pat.field[1] = value; 5428232950Stheraven pat.field[2] = none; // Any space appears in the symbol. 5429227825Stheraven pat.field[3] = symbol; 5430227825Stheraven switch (sep_by_space) 5431227825Stheraven { 5432232950Stheraven case 0: // No space separates the currency symbol and value. 5433232950Stheraven // This case may have changed between C99 and C11; 5434232950Stheraven // assume the currency symbol matches the intention. 5435232950Stheraven case 2: // Space between sign and currency or value. 5436232950Stheraven // The "sign" is two parentheses, so no space here either. 5437227825Stheraven return; 5438232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5439232950Stheraven if (!symbol_contains_sep) { 5440232950Stheraven // We insert the space into the symbol instead of 5441232950Stheraven // setting pat.field[2]=space so that when 5442232950Stheraven // showbase is not set, the space goes away too. 5443232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5444232950Stheraven } 5445227825Stheraven return; 5446227825Stheraven default: 5447227825Stheraven break; 5448227825Stheraven } 5449227825Stheraven break; 5450232950Stheraven case 1: // The sign string precedes the quantity and currency symbol. 5451227825Stheraven pat.field[0] = sign; 5452227825Stheraven pat.field[3] = symbol; 5453227825Stheraven switch (sep_by_space) 5454227825Stheraven { 5455232950Stheraven case 0: // No space separates the currency symbol and value. 5456227825Stheraven pat.field[1] = value; 5457227825Stheraven pat.field[2] = none; 5458227825Stheraven return; 5459232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5460227825Stheraven pat.field[1] = value; 5461232950Stheraven pat.field[2] = none; 5462232950Stheraven if (!symbol_contains_sep) { 5463232950Stheraven // We insert the space into the symbol instead of 5464232950Stheraven // setting pat.field[2]=space so that when 5465232950Stheraven // showbase is not set, the space goes away too. 5466232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5467232950Stheraven } 5468227825Stheraven return; 5469232950Stheraven case 2: // Space between sign and currency or value. 5470227825Stheraven pat.field[1] = space; 5471227825Stheraven pat.field[2] = value; 5472232950Stheraven if (symbol_contains_sep) { 5473232950Stheraven // Remove the separator from the symbol, since it 5474232950Stheraven // has already appeared after the sign. 5475232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5476232950Stheraven } 5477227825Stheraven return; 5478227825Stheraven default: 5479227825Stheraven break; 5480227825Stheraven } 5481227825Stheraven break; 5482232950Stheraven case 2: // The sign string succeeds the quantity and currency symbol. 5483227825Stheraven pat.field[0] = value; 5484227825Stheraven pat.field[3] = sign; 5485227825Stheraven switch (sep_by_space) 5486227825Stheraven { 5487232950Stheraven case 0: // No space separates the currency symbol and value. 5488227825Stheraven pat.field[1] = none; 5489227825Stheraven pat.field[2] = symbol; 5490227825Stheraven return; 5491232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5492232950Stheraven if (!symbol_contains_sep) { 5493232950Stheraven // We insert the space into the symbol instead of 5494232950Stheraven // setting pat.field[1]=space so that when 5495232950Stheraven // showbase is not set, the space goes away too. 5496232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5497232950Stheraven } 5498232950Stheraven pat.field[1] = none; 5499227825Stheraven pat.field[2] = symbol; 5500227825Stheraven return; 5501232950Stheraven case 2: // Space between sign and currency or value. 5502227825Stheraven pat.field[1] = symbol; 5503227825Stheraven pat.field[2] = space; 5504232950Stheraven if (symbol_contains_sep) { 5505232950Stheraven // Remove the separator from the symbol, since it 5506232950Stheraven // should not be removed if showbase is absent. 5507232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5508232950Stheraven } 5509227825Stheraven return; 5510227825Stheraven default: 5511227825Stheraven break; 5512227825Stheraven } 5513227825Stheraven break; 5514232950Stheraven case 3: // The sign string immediately precedes the currency symbol. 5515227825Stheraven pat.field[0] = value; 5516227825Stheraven pat.field[3] = symbol; 5517227825Stheraven switch (sep_by_space) 5518227825Stheraven { 5519232950Stheraven case 0: // No space separates the currency symbol and value. 5520227825Stheraven pat.field[1] = none; 5521227825Stheraven pat.field[2] = sign; 5522227825Stheraven return; 5523232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5524227825Stheraven pat.field[1] = space; 5525227825Stheraven pat.field[2] = sign; 5526232950Stheraven if (symbol_contains_sep) { 5527232950Stheraven // Remove the separator from the symbol, since it 5528232950Stheraven // has already appeared before the sign. 5529232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5530232950Stheraven } 5531227825Stheraven return; 5532232950Stheraven case 2: // Space between sign and currency or value. 5533227825Stheraven pat.field[1] = sign; 5534232950Stheraven pat.field[2] = none; 5535232950Stheraven if (!symbol_contains_sep) { 5536232950Stheraven // We insert the space into the symbol instead of 5537232950Stheraven // setting pat.field[2]=space so that when 5538232950Stheraven // showbase is not set, the space goes away too. 5539232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5540232950Stheraven } 5541227825Stheraven return; 5542227825Stheraven default: 5543227825Stheraven break; 5544227825Stheraven } 5545227825Stheraven break; 5546232950Stheraven case 4: // The sign string immediately succeeds the currency symbol. 5547227825Stheraven pat.field[0] = value; 5548227825Stheraven pat.field[3] = sign; 5549227825Stheraven switch (sep_by_space) 5550227825Stheraven { 5551232950Stheraven case 0: // No space separates the currency symbol and value. 5552227825Stheraven pat.field[1] = none; 5553227825Stheraven pat.field[2] = symbol; 5554227825Stheraven return; 5555232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5556232950Stheraven pat.field[1] = none; 5557227825Stheraven pat.field[2] = symbol; 5558232950Stheraven if (!symbol_contains_sep) { 5559232950Stheraven // We insert the space into the symbol instead of 5560232950Stheraven // setting pat.field[1]=space so that when 5561232950Stheraven // showbase is not set, the space goes away too. 5562232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5563232950Stheraven } 5564227825Stheraven return; 5565232950Stheraven case 2: // Space between sign and currency or value. 5566227825Stheraven pat.field[1] = symbol; 5567227825Stheraven pat.field[2] = space; 5568232950Stheraven if (symbol_contains_sep) { 5569232950Stheraven // Remove the separator from the symbol, since it 5570232950Stheraven // should not disappear when showbase is absent. 5571232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5572232950Stheraven } 5573227825Stheraven return; 5574227825Stheraven default: 5575227825Stheraven break; 5576227825Stheraven } 5577227825Stheraven break; 5578227825Stheraven default: 5579227825Stheraven break; 5580227825Stheraven } 5581227825Stheraven break; 5582232950Stheraven case 1: // curr_symbol before value 5583227825Stheraven switch (sign_posn) 5584227825Stheraven { 5585232950Stheraven case 0: // Parentheses surround the quantity and currency symbol. 5586227825Stheraven pat.field[0] = sign; 5587227825Stheraven pat.field[1] = symbol; 5588232950Stheraven pat.field[2] = none; // Any space appears in the symbol. 5589227825Stheraven pat.field[3] = value; 5590227825Stheraven switch (sep_by_space) 5591227825Stheraven { 5592232950Stheraven case 0: // No space separates the currency symbol and value. 5593232950Stheraven // This case may have changed between C99 and C11; 5594232950Stheraven // assume the currency symbol matches the intention. 5595232950Stheraven case 2: // Space between sign and currency or value. 5596232950Stheraven // The "sign" is two parentheses, so no space here either. 5597227825Stheraven return; 5598232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5599232950Stheraven if (!symbol_contains_sep) { 5600232950Stheraven // We insert the space into the symbol instead of 5601232950Stheraven // setting pat.field[2]=space so that when 5602232950Stheraven // showbase is not set, the space goes away too. 5603232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5604232950Stheraven } 5605227825Stheraven return; 5606227825Stheraven default: 5607227825Stheraven break; 5608227825Stheraven } 5609227825Stheraven break; 5610232950Stheraven case 1: // The sign string precedes the quantity and currency symbol. 5611227825Stheraven pat.field[0] = sign; 5612227825Stheraven pat.field[3] = value; 5613227825Stheraven switch (sep_by_space) 5614227825Stheraven { 5615232950Stheraven case 0: // No space separates the currency symbol and value. 5616227825Stheraven pat.field[1] = symbol; 5617227825Stheraven pat.field[2] = none; 5618227825Stheraven return; 5619232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5620227825Stheraven pat.field[1] = symbol; 5621232950Stheraven pat.field[2] = none; 5622232950Stheraven if (!symbol_contains_sep) { 5623232950Stheraven // We insert the space into the symbol instead of 5624232950Stheraven // setting pat.field[2]=space so that when 5625232950Stheraven // showbase is not set, the space goes away too. 5626232950Stheraven __curr_symbol_.push_back(space_char); 5627232950Stheraven } 5628227825Stheraven return; 5629232950Stheraven case 2: // Space between sign and currency or value. 5630227825Stheraven pat.field[1] = space; 5631227825Stheraven pat.field[2] = symbol; 5632232950Stheraven if (symbol_contains_sep) { 5633232950Stheraven // Remove the separator from the symbol, since it 5634232950Stheraven // has already appeared after the sign. 5635232950Stheraven __curr_symbol_.pop_back(); 5636232950Stheraven } 5637227825Stheraven return; 5638227825Stheraven default: 5639227825Stheraven break; 5640227825Stheraven } 5641227825Stheraven break; 5642232950Stheraven case 2: // The sign string succeeds the quantity and currency symbol. 5643227825Stheraven pat.field[0] = symbol; 5644227825Stheraven pat.field[3] = sign; 5645227825Stheraven switch (sep_by_space) 5646227825Stheraven { 5647232950Stheraven case 0: // No space separates the currency symbol and value. 5648227825Stheraven pat.field[1] = none; 5649227825Stheraven pat.field[2] = value; 5650227825Stheraven return; 5651232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5652232950Stheraven pat.field[1] = none; 5653227825Stheraven pat.field[2] = value; 5654232950Stheraven if (!symbol_contains_sep) { 5655232950Stheraven // We insert the space into the symbol instead of 5656232950Stheraven // setting pat.field[1]=space so that when 5657232950Stheraven // showbase is not set, the space goes away too. 5658232950Stheraven __curr_symbol_.push_back(space_char); 5659232950Stheraven } 5660227825Stheraven return; 5661232950Stheraven case 2: // Space between sign and currency or value. 5662227825Stheraven pat.field[1] = value; 5663227825Stheraven pat.field[2] = space; 5664232950Stheraven if (symbol_contains_sep) { 5665232950Stheraven // Remove the separator from the symbol, since it 5666232950Stheraven // will appear before the sign. 5667232950Stheraven __curr_symbol_.pop_back(); 5668232950Stheraven } 5669227825Stheraven return; 5670227825Stheraven default: 5671227825Stheraven break; 5672227825Stheraven } 5673227825Stheraven break; 5674232950Stheraven case 3: // The sign string immediately precedes the currency symbol. 5675227825Stheraven pat.field[0] = sign; 5676227825Stheraven pat.field[3] = value; 5677227825Stheraven switch (sep_by_space) 5678227825Stheraven { 5679232950Stheraven case 0: // No space separates the currency symbol and value. 5680227825Stheraven pat.field[1] = symbol; 5681227825Stheraven pat.field[2] = none; 5682227825Stheraven return; 5683232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5684227825Stheraven pat.field[1] = symbol; 5685232950Stheraven pat.field[2] = none; 5686232950Stheraven if (!symbol_contains_sep) { 5687232950Stheraven // We insert the space into the symbol instead of 5688232950Stheraven // setting pat.field[2]=space so that when 5689232950Stheraven // showbase is not set, the space goes away too. 5690232950Stheraven __curr_symbol_.push_back(space_char); 5691232950Stheraven } 5692227825Stheraven return; 5693232950Stheraven case 2: // Space between sign and currency or value. 5694227825Stheraven pat.field[1] = space; 5695227825Stheraven pat.field[2] = symbol; 5696232950Stheraven if (symbol_contains_sep) { 5697232950Stheraven // Remove the separator from the symbol, since it 5698232950Stheraven // has already appeared after the sign. 5699232950Stheraven __curr_symbol_.pop_back(); 5700232950Stheraven } 5701227825Stheraven return; 5702227825Stheraven default: 5703227825Stheraven break; 5704227825Stheraven } 5705227825Stheraven break; 5706232950Stheraven case 4: // The sign string immediately succeeds the currency symbol. 5707227825Stheraven pat.field[0] = symbol; 5708227825Stheraven pat.field[3] = value; 5709227825Stheraven switch (sep_by_space) 5710227825Stheraven { 5711232950Stheraven case 0: // No space separates the currency symbol and value. 5712227825Stheraven pat.field[1] = sign; 5713227825Stheraven pat.field[2] = none; 5714227825Stheraven return; 5715232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5716227825Stheraven pat.field[1] = sign; 5717227825Stheraven pat.field[2] = space; 5718232950Stheraven if (symbol_contains_sep) { 5719232950Stheraven // Remove the separator from the symbol, since it 5720232950Stheraven // should not disappear when showbase is absent. 5721232950Stheraven __curr_symbol_.pop_back(); 5722232950Stheraven } 5723227825Stheraven return; 5724232950Stheraven case 2: // Space between sign and currency or value. 5725232950Stheraven pat.field[1] = none; 5726227825Stheraven pat.field[2] = sign; 5727232950Stheraven if (!symbol_contains_sep) { 5728232950Stheraven // We insert the space into the symbol instead of 5729232950Stheraven // setting pat.field[1]=space so that when 5730232950Stheraven // showbase is not set, the space goes away too. 5731232950Stheraven __curr_symbol_.push_back(space_char); 5732232950Stheraven } 5733227825Stheraven return; 5734227825Stheraven default: 5735227825Stheraven break; 5736227825Stheraven } 5737227825Stheraven break; 5738227825Stheraven default: 5739227825Stheraven break; 5740227825Stheraven } 5741227825Stheraven break; 5742227825Stheraven default: 5743227825Stheraven break; 5744227825Stheraven } 5745227825Stheraven pat.field[0] = symbol; 5746227825Stheraven pat.field[1] = sign; 5747227825Stheraven pat.field[2] = none; 5748227825Stheraven pat.field[3] = value; 5749227825Stheraven} 5750227825Stheraven 5751227825Stheraventemplate<> 5752227825Stheravenvoid 5753227825Stheravenmoneypunct_byname<char, false>::init(const char* nm) 5754227825Stheraven{ 5755227825Stheraven typedef moneypunct<char, false> base; 5756227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5757227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5758232950Stheraven if (loc == nullptr) 5759227825Stheraven throw runtime_error("moneypunct_byname" 5760227825Stheraven " failed to construct for " + string(nm)); 5761227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5762227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5763227825Stheraven lconv* lc = localeconv_l(loc.get()); 5764227825Stheraven#else 5765227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5766227825Stheraven#endif 5767227825Stheraven if (*lc->mon_decimal_point) 5768227825Stheraven __decimal_point_ = *lc->mon_decimal_point; 5769227825Stheraven else 5770227825Stheraven __decimal_point_ = base::do_decimal_point(); 5771227825Stheraven if (*lc->mon_thousands_sep) 5772227825Stheraven __thousands_sep_ = *lc->mon_thousands_sep; 5773227825Stheraven else 5774227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5775227825Stheraven __grouping_ = lc->mon_grouping; 5776227825Stheraven __curr_symbol_ = lc->currency_symbol; 5777227825Stheraven if (lc->frac_digits != CHAR_MAX) 5778227825Stheraven __frac_digits_ = lc->frac_digits; 5779227825Stheraven else 5780227825Stheraven __frac_digits_ = base::do_frac_digits(); 5781227825Stheraven if (lc->p_sign_posn == 0) 5782227825Stheraven __positive_sign_ = "()"; 5783227825Stheraven else 5784227825Stheraven __positive_sign_ = lc->positive_sign; 5785227825Stheraven if (lc->n_sign_posn == 0) 5786227825Stheraven __negative_sign_ = "()"; 5787227825Stheraven else 5788227825Stheraven __negative_sign_ = lc->negative_sign; 5789232950Stheraven // Assume the positive and negative formats will want spaces in 5790232950Stheraven // the same places in curr_symbol since there's no way to 5791232950Stheraven // represent anything else. 5792232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5793232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, false, 5794232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); 5795232950Stheraven __init_pat(__neg_format_, __curr_symbol_, false, 5796232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); 5797227825Stheraven} 5798227825Stheraven 5799227825Stheraventemplate<> 5800227825Stheravenvoid 5801227825Stheravenmoneypunct_byname<char, true>::init(const char* nm) 5802227825Stheraven{ 5803227825Stheraven typedef moneypunct<char, true> base; 5804227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5805227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5806232950Stheraven if (loc == nullptr) 5807227825Stheraven throw runtime_error("moneypunct_byname" 5808227825Stheraven " failed to construct for " + string(nm)); 5809227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5810227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5811227825Stheraven lconv* lc = localeconv_l(loc.get()); 5812227825Stheraven#else 5813227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5814227825Stheraven#endif 5815227825Stheraven if (*lc->mon_decimal_point) 5816227825Stheraven __decimal_point_ = *lc->mon_decimal_point; 5817227825Stheraven else 5818227825Stheraven __decimal_point_ = base::do_decimal_point(); 5819227825Stheraven if (*lc->mon_thousands_sep) 5820227825Stheraven __thousands_sep_ = *lc->mon_thousands_sep; 5821227825Stheraven else 5822227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5823227825Stheraven __grouping_ = lc->mon_grouping; 5824227825Stheraven __curr_symbol_ = lc->int_curr_symbol; 5825227825Stheraven if (lc->int_frac_digits != CHAR_MAX) 5826227825Stheraven __frac_digits_ = lc->int_frac_digits; 5827227825Stheraven else 5828227825Stheraven __frac_digits_ = base::do_frac_digits(); 5829249998Sdim#ifdef _WIN32 5830227825Stheraven if (lc->p_sign_posn == 0) 5831227825Stheraven#else // _WIN32 5832227825Stheraven if (lc->int_p_sign_posn == 0) 5833227825Stheraven#endif //_WIN32 5834227825Stheraven __positive_sign_ = "()"; 5835227825Stheraven else 5836227825Stheraven __positive_sign_ = lc->positive_sign; 5837249998Sdim#ifdef _WIN32 5838227825Stheraven if(lc->n_sign_posn == 0) 5839227825Stheraven#else // _WIN32 5840227825Stheraven if (lc->int_n_sign_posn == 0) 5841227825Stheraven#endif // _WIN32 5842227825Stheraven __negative_sign_ = "()"; 5843227825Stheraven else 5844227825Stheraven __negative_sign_ = lc->negative_sign; 5845232950Stheraven // Assume the positive and negative formats will want spaces in 5846232950Stheraven // the same places in curr_symbol since there's no way to 5847232950Stheraven // represent anything else. 5848232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5849249998Sdim#ifdef _WIN32 5850232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 5851232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); 5852232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 5853232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); 5854227825Stheraven#else 5855232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 5856232950Stheraven lc->int_p_cs_precedes, lc->int_p_sep_by_space, 5857232950Stheraven lc->int_p_sign_posn, ' '); 5858232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 5859232950Stheraven lc->int_n_cs_precedes, lc->int_n_sep_by_space, 5860232950Stheraven lc->int_n_sign_posn, ' '); 5861227825Stheraven#endif // _WIN32 5862227825Stheraven} 5863227825Stheraven 5864227825Stheraventemplate<> 5865227825Stheravenvoid 5866227825Stheravenmoneypunct_byname<wchar_t, false>::init(const char* nm) 5867227825Stheraven{ 5868227825Stheraven typedef moneypunct<wchar_t, false> base; 5869227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5870227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5871232950Stheraven if (loc == nullptr) 5872227825Stheraven throw runtime_error("moneypunct_byname" 5873227825Stheraven " failed to construct for " + string(nm)); 5874227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5875227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5876227825Stheraven lconv* lc = localeconv_l(loc.get()); 5877227825Stheraven#else 5878227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5879227825Stheraven#endif 5880227825Stheraven if (*lc->mon_decimal_point) 5881227825Stheraven __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5882227825Stheraven else 5883227825Stheraven __decimal_point_ = base::do_decimal_point(); 5884227825Stheraven if (*lc->mon_thousands_sep) 5885227825Stheraven __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5886227825Stheraven else 5887227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5888227825Stheraven __grouping_ = lc->mon_grouping; 5889227825Stheraven wchar_t wbuf[100]; 5890227825Stheraven mbstate_t mb = {0}; 5891227825Stheraven const char* bb = lc->currency_symbol; 5892227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5893246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5894227825Stheraven#else 5895246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5896227825Stheraven#endif 5897232950Stheraven if (j == size_t(-1)) 5898227825Stheraven __throw_runtime_error("locale not supported"); 5899227825Stheraven wchar_t* wbe = wbuf + j; 5900227825Stheraven __curr_symbol_.assign(wbuf, wbe); 5901227825Stheraven if (lc->frac_digits != CHAR_MAX) 5902227825Stheraven __frac_digits_ = lc->frac_digits; 5903227825Stheraven else 5904227825Stheraven __frac_digits_ = base::do_frac_digits(); 5905227825Stheraven if (lc->p_sign_posn == 0) 5906227825Stheraven __positive_sign_ = L"()"; 5907227825Stheraven else 5908227825Stheraven { 5909227825Stheraven mb = mbstate_t(); 5910227825Stheraven bb = lc->positive_sign; 5911227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5912246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5913227825Stheraven#else 5914246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5915227825Stheraven#endif 5916232950Stheraven if (j == size_t(-1)) 5917227825Stheraven __throw_runtime_error("locale not supported"); 5918227825Stheraven wbe = wbuf + j; 5919227825Stheraven __positive_sign_.assign(wbuf, wbe); 5920227825Stheraven } 5921227825Stheraven if (lc->n_sign_posn == 0) 5922227825Stheraven __negative_sign_ = L"()"; 5923227825Stheraven else 5924227825Stheraven { 5925227825Stheraven mb = mbstate_t(); 5926227825Stheraven bb = lc->negative_sign; 5927227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5928246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5929227825Stheraven#else 5930246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5931227825Stheraven#endif 5932232950Stheraven if (j == size_t(-1)) 5933227825Stheraven __throw_runtime_error("locale not supported"); 5934227825Stheraven wbe = wbuf + j; 5935227825Stheraven __negative_sign_.assign(wbuf, wbe); 5936227825Stheraven } 5937232950Stheraven // Assume the positive and negative formats will want spaces in 5938232950Stheraven // the same places in curr_symbol since there's no way to 5939232950Stheraven // represent anything else. 5940232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5941232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, false, 5942232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); 5943232950Stheraven __init_pat(__neg_format_, __curr_symbol_, false, 5944232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); 5945227825Stheraven} 5946227825Stheraven 5947227825Stheraventemplate<> 5948227825Stheravenvoid 5949227825Stheravenmoneypunct_byname<wchar_t, true>::init(const char* nm) 5950227825Stheraven{ 5951227825Stheraven typedef moneypunct<wchar_t, true> base; 5952227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5953227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5954232950Stheraven if (loc == nullptr) 5955227825Stheraven throw runtime_error("moneypunct_byname" 5956227825Stheraven " failed to construct for " + string(nm)); 5957227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5958227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5959227825Stheraven lconv* lc = localeconv_l(loc.get()); 5960227825Stheraven#else 5961227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5962227825Stheraven#endif 5963227825Stheraven if (*lc->mon_decimal_point) 5964227825Stheraven __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5965227825Stheraven else 5966227825Stheraven __decimal_point_ = base::do_decimal_point(); 5967227825Stheraven if (*lc->mon_thousands_sep) 5968227825Stheraven __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5969227825Stheraven else 5970227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5971227825Stheraven __grouping_ = lc->mon_grouping; 5972227825Stheraven wchar_t wbuf[100]; 5973227825Stheraven mbstate_t mb = {0}; 5974227825Stheraven const char* bb = lc->int_curr_symbol; 5975227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5976246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5977227825Stheraven#else 5978246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5979227825Stheraven#endif 5980232950Stheraven if (j == size_t(-1)) 5981227825Stheraven __throw_runtime_error("locale not supported"); 5982227825Stheraven wchar_t* wbe = wbuf + j; 5983227825Stheraven __curr_symbol_.assign(wbuf, wbe); 5984227825Stheraven if (lc->int_frac_digits != CHAR_MAX) 5985227825Stheraven __frac_digits_ = lc->int_frac_digits; 5986227825Stheraven else 5987227825Stheraven __frac_digits_ = base::do_frac_digits(); 5988249998Sdim#ifdef _WIN32 5989227825Stheraven if (lc->p_sign_posn == 0) 5990227825Stheraven#else // _WIN32 5991227825Stheraven if (lc->int_p_sign_posn == 0) 5992227825Stheraven#endif // _WIN32 5993227825Stheraven __positive_sign_ = L"()"; 5994227825Stheraven else 5995227825Stheraven { 5996227825Stheraven mb = mbstate_t(); 5997227825Stheraven bb = lc->positive_sign; 5998227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5999246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6000227825Stheraven#else 6001246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6002227825Stheraven#endif 6003232950Stheraven if (j == size_t(-1)) 6004227825Stheraven __throw_runtime_error("locale not supported"); 6005227825Stheraven wbe = wbuf + j; 6006227825Stheraven __positive_sign_.assign(wbuf, wbe); 6007227825Stheraven } 6008249998Sdim#ifdef _WIN32 6009227825Stheraven if (lc->n_sign_posn == 0) 6010227825Stheraven#else // _WIN32 6011227825Stheraven if (lc->int_n_sign_posn == 0) 6012227825Stheraven#endif // _WIN32 6013227825Stheraven __negative_sign_ = L"()"; 6014227825Stheraven else 6015227825Stheraven { 6016227825Stheraven mb = mbstate_t(); 6017227825Stheraven bb = lc->negative_sign; 6018227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 6019246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6020227825Stheraven#else 6021246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6022227825Stheraven#endif 6023232950Stheraven if (j == size_t(-1)) 6024227825Stheraven __throw_runtime_error("locale not supported"); 6025227825Stheraven wbe = wbuf + j; 6026227825Stheraven __negative_sign_.assign(wbuf, wbe); 6027227825Stheraven } 6028232950Stheraven // Assume the positive and negative formats will want spaces in 6029232950Stheraven // the same places in curr_symbol since there's no way to 6030232950Stheraven // represent anything else. 6031232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 6032249998Sdim#ifdef _WIN32 6033232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 6034232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); 6035232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 6036232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); 6037227825Stheraven#else // _WIN32 6038232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 6039232950Stheraven lc->int_p_cs_precedes, lc->int_p_sep_by_space, 6040232950Stheraven lc->int_p_sign_posn, L' '); 6041232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 6042232950Stheraven lc->int_n_cs_precedes, lc->int_n_sep_by_space, 6043232950Stheraven lc->int_n_sign_posn, L' '); 6044227825Stheraven#endif // _WIN32 6045227825Stheraven} 6046227825Stheraven 6047227825Stheravenvoid __do_nothing(void*) {} 6048227825Stheraven 6049227825Stheravenvoid __throw_runtime_error(const char* msg) 6050227825Stheraven{ 6051227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 6052227825Stheraven throw runtime_error(msg); 6053249998Sdim#else 6054249998Sdim (void)msg; 6055227825Stheraven#endif 6056227825Stheraven} 6057227825Stheraven 6058227825Stheraventemplate class collate<char>; 6059227825Stheraventemplate class collate<wchar_t>; 6060227825Stheraven 6061227825Stheraventemplate class num_get<char>; 6062227825Stheraventemplate class num_get<wchar_t>; 6063227825Stheraven 6064232950Stheraventemplate struct __num_get<char>; 6065232950Stheraventemplate struct __num_get<wchar_t>; 6066227825Stheraven 6067227825Stheraventemplate class num_put<char>; 6068227825Stheraventemplate class num_put<wchar_t>; 6069227825Stheraven 6070232950Stheraventemplate struct __num_put<char>; 6071232950Stheraventemplate struct __num_put<wchar_t>; 6072227825Stheraven 6073227825Stheraventemplate class time_get<char>; 6074227825Stheraventemplate class time_get<wchar_t>; 6075227825Stheraven 6076227825Stheraventemplate class time_get_byname<char>; 6077227825Stheraventemplate class time_get_byname<wchar_t>; 6078227825Stheraven 6079227825Stheraventemplate class time_put<char>; 6080227825Stheraventemplate class time_put<wchar_t>; 6081227825Stheraven 6082227825Stheraventemplate class time_put_byname<char>; 6083227825Stheraventemplate class time_put_byname<wchar_t>; 6084227825Stheraven 6085227825Stheraventemplate class moneypunct<char, false>; 6086227825Stheraventemplate class moneypunct<char, true>; 6087227825Stheraventemplate class moneypunct<wchar_t, false>; 6088227825Stheraventemplate class moneypunct<wchar_t, true>; 6089227825Stheraven 6090227825Stheraventemplate class moneypunct_byname<char, false>; 6091227825Stheraventemplate class moneypunct_byname<char, true>; 6092227825Stheraventemplate class moneypunct_byname<wchar_t, false>; 6093227825Stheraventemplate class moneypunct_byname<wchar_t, true>; 6094227825Stheraven 6095227825Stheraventemplate class money_get<char>; 6096227825Stheraventemplate class money_get<wchar_t>; 6097227825Stheraven 6098227825Stheraventemplate class __money_get<char>; 6099227825Stheraventemplate class __money_get<wchar_t>; 6100227825Stheraven 6101227825Stheraventemplate class money_put<char>; 6102227825Stheraventemplate class money_put<wchar_t>; 6103227825Stheraven 6104227825Stheraventemplate class __money_put<char>; 6105227825Stheraventemplate class __money_put<wchar_t>; 6106227825Stheraven 6107227825Stheraventemplate class messages<char>; 6108227825Stheraventemplate class messages<wchar_t>; 6109227825Stheraven 6110227825Stheraventemplate class messages_byname<char>; 6111227825Stheraventemplate class messages_byname<wchar_t>; 6112227825Stheraven 6113227825Stheraventemplate class codecvt_byname<char, char, mbstate_t>; 6114227825Stheraventemplate class codecvt_byname<wchar_t, char, mbstate_t>; 6115227825Stheraventemplate class codecvt_byname<char16_t, char, mbstate_t>; 6116227825Stheraventemplate class codecvt_byname<char32_t, char, mbstate_t>; 6117227825Stheraven 6118227825Stheraventemplate class __vector_base_common<true>; 6119227825Stheraven 6120227825Stheraven_LIBCPP_END_NAMESPACE_STD 6121