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 10262801Sdim#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; 11262801Sdim 12232950Stheraven// On Solaris, we need to define something to make the C99 parts of localeconv 13232950Stheraven// visible. 14232950Stheraven#ifdef __sun__ 15232950Stheraven#define _LCONV_C99 16232950Stheraven#endif 17232950Stheraven 18227825Stheraven#include "string" 19227825Stheraven#include "locale" 20227825Stheraven#include "codecvt" 21227825Stheraven#include "vector" 22227825Stheraven#include "algorithm" 23227825Stheraven#include "typeinfo" 24262801Sdim#ifndef _LIBCPP_NO_EXCEPTIONS 25262801Sdim# include "type_traits" 26262801Sdim#endif 27227825Stheraven#include "clocale" 28227825Stheraven#include "cstring" 29227825Stheraven#include "cwctype" 30227825Stheraven#include "__sso_allocator" 31262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 32227825Stheraven#include <support/win32/locale_win32.h> 33262801Sdim#else // _LIBCPP_MSVCRT 34227825Stheraven#include <langinfo.h> 35262801Sdim#endif // !_LIBCPP_MSVCRT 36227825Stheraven#include <stdlib.h> 37262801Sdim#include <stdio.h> 38227825Stheraven 39249998Sdim// On Linux, wint_t and wchar_t have different signed-ness, and this causes 40249998Sdim// lots of noise in the build log, but no bugs that I know of. 41262801Sdim#if defined(__clang__) 42249998Sdim#pragma clang diagnostic ignored "-Wsign-conversion" 43262801Sdim#endif 44249998Sdim 45227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 46227825Stheraven 47227825Stheraven#ifdef __cloc_defined 48227825Stheravenlocale_t __cloc() { 49227825Stheraven // In theory this could create a race condition. In practice 50227825Stheraven // the race condition is non-fatal since it will just create 51227825Stheraven // a little resource leak. Better approach would be appreciated. 52227825Stheraven static locale_t result = newlocale(LC_ALL_MASK, "C", 0); 53227825Stheraven return result; 54227825Stheraven} 55227825Stheraven#endif // __cloc_defined 56227825Stheraven 57227825Stheravennamespace { 58227825Stheraven 59227825Stheravenstruct release 60227825Stheraven{ 61227825Stheraven void operator()(locale::facet* p) {p->__release_shared();} 62227825Stheraven}; 63227825Stheraven 64227825Stheraventemplate <class T, class A0> 65227825Stheraveninline 66227825StheravenT& 67227825Stheravenmake(A0 a0) 68227825Stheraven{ 69227825Stheraven static typename aligned_storage<sizeof(T)>::type buf; 70227825Stheraven ::new (&buf) T(a0); 71227825Stheraven return *(T*)&buf; 72227825Stheraven} 73227825Stheraven 74227825Stheraventemplate <class T, class A0, class A1> 75227825Stheraveninline 76227825StheravenT& 77227825Stheravenmake(A0 a0, A1 a1) 78227825Stheraven{ 79227825Stheraven static typename aligned_storage<sizeof(T)>::type buf; 80227825Stheraven ::new (&buf) T(a0, a1); 81227825Stheraven return *(T*)&buf; 82227825Stheraven} 83227825Stheraven 84227825Stheraventemplate <class T, class A0, class A1, class A2> 85227825Stheraveninline 86227825StheravenT& 87227825Stheravenmake(A0 a0, A1 a1, A2 a2) 88227825Stheraven{ 89227825Stheraven static typename aligned_storage<sizeof(T)>::type buf; 90227825Stheraven ::new (&buf) T(a0, a1, a2); 91227825Stheraven return *(T*)&buf; 92227825Stheraven} 93227825Stheraven 94246487Stheraventemplate <typename T, size_t N> 95246487Stheraveninline 96246487Stheraven_LIBCPP_CONSTEXPR 97246487Stheravensize_t 98246487Stheravencountof(const T (&)[N]) 99246487Stheraven{ 100246487Stheraven return N; 101227825Stheraven} 102227825Stheraven 103246487Stheraventemplate <typename T> 104246487Stheraveninline 105246487Stheraven_LIBCPP_CONSTEXPR 106246487Stheravensize_t 107246487Stheravencountof(const T * const begin, const T * const end) 108246487Stheraven{ 109246487Stheraven return static_cast<size_t>(end - begin); 110246487Stheraven} 111246487Stheraven 112246487Stheraven} 113246487Stheraven 114262801Sdim#if defined(_AIX) 115262801Sdim// Set priority to INT_MIN + 256 + 150 116262801Sdim# pragma priority ( -2147483242 ) 117262801Sdim#endif 118262801Sdim 119246487Stheravenconst locale::category locale::none; 120246487Stheravenconst locale::category locale::collate; 121246487Stheravenconst locale::category locale::ctype; 122246487Stheravenconst locale::category locale::monetary; 123246487Stheravenconst locale::category locale::numeric; 124246487Stheravenconst locale::category locale::time; 125246487Stheravenconst locale::category locale::messages; 126246487Stheravenconst locale::category locale::all; 127246487Stheraven 128262801Sdim#if defined(__clang__) 129232950Stheraven#pragma clang diagnostic push 130232950Stheraven#pragma clang diagnostic ignored "-Wpadded" 131262801Sdim#endif 132232950Stheraven 133227825Stheravenclass _LIBCPP_HIDDEN locale::__imp 134227825Stheraven : public facet 135227825Stheraven{ 136227825Stheraven enum {N = 28}; 137262801Sdim#if defined(_LIBCPP_MSVC) 138262801Sdim// FIXME: MSVC doesn't support aligned parameters by value. 139262801Sdim// I can't get the __sso_allocator to work here 140262801Sdim// for MSVC I think for this reason. 141262801Sdim vector<facet*> facets_; 142262801Sdim#else 143232950Stheraven vector<facet*, __sso_allocator<facet*, N> > facets_; 144262801Sdim#endif 145227825Stheraven string name_; 146227825Stheravenpublic: 147227825Stheraven explicit __imp(size_t refs = 0); 148227825Stheraven explicit __imp(const string& name, size_t refs = 0); 149227825Stheraven __imp(const __imp&); 150227825Stheraven __imp(const __imp&, const string&, locale::category c); 151227825Stheraven __imp(const __imp& other, const __imp& one, locale::category c); 152227825Stheraven __imp(const __imp&, facet* f, long id); 153227825Stheraven ~__imp(); 154227825Stheraven 155227825Stheraven const string& name() const {return name_;} 156232950Stheraven bool has_facet(long id) const 157232950Stheraven {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];} 158227825Stheraven const locale::facet* use_facet(long id) const; 159227825Stheraven 160227825Stheraven static const locale& make_classic(); 161227825Stheraven static locale& make_global(); 162227825Stheravenprivate: 163227825Stheraven void install(facet* f, long id); 164227825Stheraven template <class F> void install(F* f) {install(f, f->id.__get());} 165227825Stheraven template <class F> void install_from(const __imp& other); 166227825Stheraven}; 167227825Stheraven 168262801Sdim#if defined(__clang__) 169232950Stheraven#pragma clang diagnostic pop 170262801Sdim#endif 171232950Stheraven 172227825Stheravenlocale::__imp::__imp(size_t refs) 173227825Stheraven : facet(refs), 174232950Stheraven facets_(N), 175232950Stheraven name_("C") 176227825Stheraven{ 177227825Stheraven facets_.clear(); 178232950Stheraven install(&make<_VSTD::collate<char> >(1u)); 179232950Stheraven install(&make<_VSTD::collate<wchar_t> >(1u)); 180232950Stheraven install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1u)); 181232950Stheraven install(&make<_VSTD::ctype<wchar_t> >(1u)); 182232950Stheraven install(&make<codecvt<char, char, mbstate_t> >(1u)); 183232950Stheraven install(&make<codecvt<wchar_t, char, mbstate_t> >(1u)); 184232950Stheraven install(&make<codecvt<char16_t, char, mbstate_t> >(1u)); 185232950Stheraven install(&make<codecvt<char32_t, char, mbstate_t> >(1u)); 186232950Stheraven install(&make<numpunct<char> >(1u)); 187232950Stheraven install(&make<numpunct<wchar_t> >(1u)); 188232950Stheraven install(&make<num_get<char> >(1u)); 189232950Stheraven install(&make<num_get<wchar_t> >(1u)); 190232950Stheraven install(&make<num_put<char> >(1u)); 191232950Stheraven install(&make<num_put<wchar_t> >(1u)); 192232950Stheraven install(&make<moneypunct<char, false> >(1u)); 193232950Stheraven install(&make<moneypunct<char, true> >(1u)); 194232950Stheraven install(&make<moneypunct<wchar_t, false> >(1u)); 195232950Stheraven install(&make<moneypunct<wchar_t, true> >(1u)); 196232950Stheraven install(&make<money_get<char> >(1u)); 197232950Stheraven install(&make<money_get<wchar_t> >(1u)); 198232950Stheraven install(&make<money_put<char> >(1u)); 199232950Stheraven install(&make<money_put<wchar_t> >(1u)); 200232950Stheraven install(&make<time_get<char> >(1u)); 201232950Stheraven install(&make<time_get<wchar_t> >(1u)); 202232950Stheraven install(&make<time_put<char> >(1u)); 203232950Stheraven install(&make<time_put<wchar_t> >(1u)); 204232950Stheraven install(&make<_VSTD::messages<char> >(1u)); 205232950Stheraven install(&make<_VSTD::messages<wchar_t> >(1u)); 206227825Stheraven} 207227825Stheraven 208227825Stheravenlocale::__imp::__imp(const string& name, size_t refs) 209227825Stheraven : facet(refs), 210232950Stheraven facets_(N), 211232950Stheraven name_(name) 212227825Stheraven{ 213227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 214227825Stheraven try 215227825Stheraven { 216227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 217227825Stheraven facets_ = locale::classic().__locale_->facets_; 218227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 219227825Stheraven if (facets_[i]) 220227825Stheraven facets_[i]->__add_shared(); 221227825Stheraven install(new collate_byname<char>(name_)); 222227825Stheraven install(new collate_byname<wchar_t>(name_)); 223227825Stheraven install(new ctype_byname<char>(name_)); 224227825Stheraven install(new ctype_byname<wchar_t>(name_)); 225227825Stheraven install(new codecvt_byname<char, char, mbstate_t>(name_)); 226227825Stheraven install(new codecvt_byname<wchar_t, char, mbstate_t>(name_)); 227227825Stheraven install(new codecvt_byname<char16_t, char, mbstate_t>(name_)); 228227825Stheraven install(new codecvt_byname<char32_t, char, mbstate_t>(name_)); 229227825Stheraven install(new numpunct_byname<char>(name_)); 230227825Stheraven install(new numpunct_byname<wchar_t>(name_)); 231227825Stheraven install(new moneypunct_byname<char, false>(name_)); 232227825Stheraven install(new moneypunct_byname<char, true>(name_)); 233227825Stheraven install(new moneypunct_byname<wchar_t, false>(name_)); 234227825Stheraven install(new moneypunct_byname<wchar_t, true>(name_)); 235227825Stheraven install(new time_get_byname<char>(name_)); 236227825Stheraven install(new time_get_byname<wchar_t>(name_)); 237227825Stheraven install(new time_put_byname<char>(name_)); 238227825Stheraven install(new time_put_byname<wchar_t>(name_)); 239227825Stheraven install(new messages_byname<char>(name_)); 240227825Stheraven install(new messages_byname<wchar_t>(name_)); 241227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 242227825Stheraven } 243227825Stheraven catch (...) 244227825Stheraven { 245227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 246227825Stheraven if (facets_[i]) 247227825Stheraven facets_[i]->__release_shared(); 248227825Stheraven throw; 249227825Stheraven } 250227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 251227825Stheraven} 252227825Stheraven 253246487Stheraven// NOTE avoid the `base class should be explicitly initialized in the 254246487Stheraven// copy constructor` warning emitted by GCC 255253159Stheraven#if defined(__clang__) || _GNUC_VER >= 406 256246487Stheraven#pragma GCC diagnostic push 257246487Stheraven#pragma GCC diagnostic ignored "-Wextra" 258253159Stheraven#endif 259246487Stheraven 260227825Stheravenlocale::__imp::__imp(const __imp& other) 261232950Stheraven : facets_(max<size_t>(N, other.facets_.size())), 262232950Stheraven name_(other.name_) 263227825Stheraven{ 264227825Stheraven facets_ = other.facets_; 265227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 266227825Stheraven if (facets_[i]) 267227825Stheraven facets_[i]->__add_shared(); 268227825Stheraven} 269227825Stheraven 270253159Stheraven#if defined(__clang__) || _GNUC_VER >= 406 271246487Stheraven#pragma GCC diagnostic pop 272253159Stheraven#endif 273246487Stheraven 274227825Stheravenlocale::__imp::__imp(const __imp& other, const string& name, locale::category c) 275232950Stheraven : facets_(N), 276232950Stheraven name_("*") 277227825Stheraven{ 278227825Stheraven facets_ = other.facets_; 279227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 280227825Stheraven if (facets_[i]) 281227825Stheraven facets_[i]->__add_shared(); 282227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 283227825Stheraven try 284227825Stheraven { 285227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 286227825Stheraven if (c & locale::collate) 287227825Stheraven { 288227825Stheraven install(new collate_byname<char>(name)); 289227825Stheraven install(new collate_byname<wchar_t>(name)); 290227825Stheraven } 291227825Stheraven if (c & locale::ctype) 292227825Stheraven { 293227825Stheraven install(new ctype_byname<char>(name)); 294227825Stheraven install(new ctype_byname<wchar_t>(name)); 295227825Stheraven install(new codecvt_byname<char, char, mbstate_t>(name)); 296227825Stheraven install(new codecvt_byname<wchar_t, char, mbstate_t>(name)); 297227825Stheraven install(new codecvt_byname<char16_t, char, mbstate_t>(name)); 298227825Stheraven install(new codecvt_byname<char32_t, char, mbstate_t>(name)); 299227825Stheraven } 300227825Stheraven if (c & locale::monetary) 301227825Stheraven { 302227825Stheraven install(new moneypunct_byname<char, false>(name)); 303227825Stheraven install(new moneypunct_byname<char, true>(name)); 304227825Stheraven install(new moneypunct_byname<wchar_t, false>(name)); 305227825Stheraven install(new moneypunct_byname<wchar_t, true>(name)); 306227825Stheraven } 307227825Stheraven if (c & locale::numeric) 308227825Stheraven { 309227825Stheraven install(new numpunct_byname<char>(name)); 310227825Stheraven install(new numpunct_byname<wchar_t>(name)); 311227825Stheraven } 312227825Stheraven if (c & locale::time) 313227825Stheraven { 314227825Stheraven install(new time_get_byname<char>(name)); 315227825Stheraven install(new time_get_byname<wchar_t>(name)); 316227825Stheraven install(new time_put_byname<char>(name)); 317227825Stheraven install(new time_put_byname<wchar_t>(name)); 318227825Stheraven } 319227825Stheraven if (c & locale::messages) 320227825Stheraven { 321227825Stheraven install(new messages_byname<char>(name)); 322227825Stheraven install(new messages_byname<wchar_t>(name)); 323227825Stheraven } 324227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 325227825Stheraven } 326227825Stheraven catch (...) 327227825Stheraven { 328227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 329227825Stheraven if (facets_[i]) 330227825Stheraven facets_[i]->__release_shared(); 331227825Stheraven throw; 332227825Stheraven } 333227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 334227825Stheraven} 335227825Stheraven 336227825Stheraventemplate<class F> 337227825Stheraveninline 338227825Stheravenvoid 339227825Stheravenlocale::__imp::install_from(const locale::__imp& one) 340227825Stheraven{ 341227825Stheraven long id = F::id.__get(); 342227825Stheraven install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id); 343227825Stheraven} 344227825Stheraven 345227825Stheravenlocale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) 346232950Stheraven : facets_(N), 347232950Stheraven name_("*") 348227825Stheraven{ 349227825Stheraven facets_ = other.facets_; 350227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 351227825Stheraven if (facets_[i]) 352227825Stheraven facets_[i]->__add_shared(); 353227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 354227825Stheraven try 355227825Stheraven { 356227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 357227825Stheraven if (c & locale::collate) 358227825Stheraven { 359227825Stheraven install_from<_VSTD::collate<char> >(one); 360227825Stheraven install_from<_VSTD::collate<wchar_t> >(one); 361227825Stheraven } 362227825Stheraven if (c & locale::ctype) 363227825Stheraven { 364227825Stheraven install_from<_VSTD::ctype<char> >(one); 365227825Stheraven install_from<_VSTD::ctype<wchar_t> >(one); 366227825Stheraven install_from<_VSTD::codecvt<char, char, mbstate_t> >(one); 367227825Stheraven install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one); 368227825Stheraven install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one); 369227825Stheraven install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one); 370227825Stheraven } 371227825Stheraven if (c & locale::monetary) 372227825Stheraven { 373227825Stheraven install_from<moneypunct<char, false> >(one); 374227825Stheraven install_from<moneypunct<char, true> >(one); 375227825Stheraven install_from<moneypunct<wchar_t, false> >(one); 376227825Stheraven install_from<moneypunct<wchar_t, true> >(one); 377227825Stheraven install_from<money_get<char> >(one); 378227825Stheraven install_from<money_get<wchar_t> >(one); 379227825Stheraven install_from<money_put<char> >(one); 380227825Stheraven install_from<money_put<wchar_t> >(one); 381227825Stheraven } 382227825Stheraven if (c & locale::numeric) 383227825Stheraven { 384227825Stheraven install_from<numpunct<char> >(one); 385227825Stheraven install_from<numpunct<wchar_t> >(one); 386227825Stheraven install_from<num_get<char> >(one); 387227825Stheraven install_from<num_get<wchar_t> >(one); 388227825Stheraven install_from<num_put<char> >(one); 389227825Stheraven install_from<num_put<wchar_t> >(one); 390227825Stheraven } 391227825Stheraven if (c & locale::time) 392227825Stheraven { 393227825Stheraven install_from<time_get<char> >(one); 394227825Stheraven install_from<time_get<wchar_t> >(one); 395227825Stheraven install_from<time_put<char> >(one); 396227825Stheraven install_from<time_put<wchar_t> >(one); 397227825Stheraven } 398227825Stheraven if (c & locale::messages) 399227825Stheraven { 400227825Stheraven install_from<_VSTD::messages<char> >(one); 401227825Stheraven install_from<_VSTD::messages<wchar_t> >(one); 402227825Stheraven } 403227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 404227825Stheraven } 405227825Stheraven catch (...) 406227825Stheraven { 407227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 408227825Stheraven if (facets_[i]) 409227825Stheraven facets_[i]->__release_shared(); 410227825Stheraven throw; 411227825Stheraven } 412227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 413227825Stheraven} 414227825Stheraven 415227825Stheravenlocale::__imp::__imp(const __imp& other, facet* f, long id) 416232950Stheraven : facets_(max<size_t>(N, other.facets_.size()+1)), 417232950Stheraven name_("*") 418227825Stheraven{ 419227825Stheraven f->__add_shared(); 420227825Stheraven unique_ptr<facet, release> hold(f); 421227825Stheraven facets_ = other.facets_; 422227825Stheraven for (unsigned i = 0; i < other.facets_.size(); ++i) 423227825Stheraven if (facets_[i]) 424227825Stheraven facets_[i]->__add_shared(); 425227825Stheraven install(hold.get(), id); 426227825Stheraven} 427227825Stheraven 428227825Stheravenlocale::__imp::~__imp() 429227825Stheraven{ 430227825Stheraven for (unsigned i = 0; i < facets_.size(); ++i) 431227825Stheraven if (facets_[i]) 432227825Stheraven facets_[i]->__release_shared(); 433227825Stheraven} 434227825Stheraven 435227825Stheravenvoid 436227825Stheravenlocale::__imp::install(facet* f, long id) 437227825Stheraven{ 438227825Stheraven f->__add_shared(); 439227825Stheraven unique_ptr<facet, release> hold(f); 440232950Stheraven if (static_cast<size_t>(id) >= facets_.size()) 441232950Stheraven facets_.resize(static_cast<size_t>(id+1)); 442232950Stheraven if (facets_[static_cast<size_t>(id)]) 443232950Stheraven facets_[static_cast<size_t>(id)]->__release_shared(); 444232950Stheraven facets_[static_cast<size_t>(id)] = hold.release(); 445227825Stheraven} 446227825Stheraven 447227825Stheravenconst locale::facet* 448227825Stheravenlocale::__imp::use_facet(long id) const 449227825Stheraven{ 450227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 451227825Stheraven if (!has_facet(id)) 452227825Stheraven throw bad_cast(); 453227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 454232950Stheraven return facets_[static_cast<size_t>(id)]; 455227825Stheraven} 456227825Stheraven 457227825Stheraven// locale 458227825Stheraven 459227825Stheravenconst locale& 460227825Stheravenlocale::__imp::make_classic() 461227825Stheraven{ 462227825Stheraven // only one thread can get in here and it only gets in once 463227825Stheraven static aligned_storage<sizeof(locale)>::type buf; 464227825Stheraven locale* c = (locale*)&buf; 465232950Stheraven c->__locale_ = &make<__imp>(1u); 466227825Stheraven return *c; 467227825Stheraven} 468227825Stheraven 469227825Stheravenconst locale& 470227825Stheravenlocale::classic() 471227825Stheraven{ 472227825Stheraven static const locale& c = __imp::make_classic(); 473227825Stheraven return c; 474227825Stheraven} 475227825Stheraven 476227825Stheravenlocale& 477227825Stheravenlocale::__imp::make_global() 478227825Stheraven{ 479227825Stheraven // only one thread can get in here and it only gets in once 480227825Stheraven static aligned_storage<sizeof(locale)>::type buf; 481227825Stheraven ::new (&buf) locale(locale::classic()); 482227825Stheraven return *(locale*)&buf; 483227825Stheraven} 484227825Stheraven 485227825Stheravenlocale& 486227825Stheravenlocale::__global() 487227825Stheraven{ 488227825Stheraven static locale& g = __imp::make_global(); 489227825Stheraven return g; 490227825Stheraven} 491227825Stheraven 492227825Stheravenlocale::locale() _NOEXCEPT 493227825Stheraven : __locale_(__global().__locale_) 494227825Stheraven{ 495227825Stheraven __locale_->__add_shared(); 496227825Stheraven} 497227825Stheraven 498227825Stheravenlocale::locale(const locale& l) _NOEXCEPT 499227825Stheraven : __locale_(l.__locale_) 500227825Stheraven{ 501227825Stheraven __locale_->__add_shared(); 502227825Stheraven} 503227825Stheraven 504227825Stheravenlocale::~locale() 505227825Stheraven{ 506227825Stheraven __locale_->__release_shared(); 507227825Stheraven} 508227825Stheraven 509227825Stheravenconst locale& 510227825Stheravenlocale::operator=(const locale& other) _NOEXCEPT 511227825Stheraven{ 512227825Stheraven other.__locale_->__add_shared(); 513227825Stheraven __locale_->__release_shared(); 514227825Stheraven __locale_ = other.__locale_; 515227825Stheraven return *this; 516227825Stheraven} 517227825Stheraven 518227825Stheravenlocale::locale(const char* name) 519227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 520227825Stheraven : __locale_(name ? new __imp(name) 521227825Stheraven : throw runtime_error("locale constructed with null")) 522227825Stheraven#else // _LIBCPP_NO_EXCEPTIONS 523227825Stheraven : __locale_(new __imp(name)) 524227825Stheraven#endif 525227825Stheraven{ 526227825Stheraven __locale_->__add_shared(); 527227825Stheraven} 528227825Stheraven 529227825Stheravenlocale::locale(const string& name) 530227825Stheraven : __locale_(new __imp(name)) 531227825Stheraven{ 532227825Stheraven __locale_->__add_shared(); 533227825Stheraven} 534227825Stheraven 535227825Stheravenlocale::locale(const locale& other, const char* name, category c) 536227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 537227825Stheraven : __locale_(name ? new __imp(*other.__locale_, name, c) 538227825Stheraven : throw runtime_error("locale constructed with null")) 539227825Stheraven#else // _LIBCPP_NO_EXCEPTIONS 540227825Stheraven : __locale_(new __imp(*other.__locale_, name, c)) 541227825Stheraven#endif 542227825Stheraven{ 543227825Stheraven __locale_->__add_shared(); 544227825Stheraven} 545227825Stheraven 546227825Stheravenlocale::locale(const locale& other, const string& name, category c) 547227825Stheraven : __locale_(new __imp(*other.__locale_, name, c)) 548227825Stheraven{ 549227825Stheraven __locale_->__add_shared(); 550227825Stheraven} 551227825Stheraven 552227825Stheravenlocale::locale(const locale& other, const locale& one, category c) 553227825Stheraven : __locale_(new __imp(*other.__locale_, *one.__locale_, c)) 554227825Stheraven{ 555227825Stheraven __locale_->__add_shared(); 556227825Stheraven} 557227825Stheraven 558227825Stheravenstring 559227825Stheravenlocale::name() const 560227825Stheraven{ 561227825Stheraven return __locale_->name(); 562227825Stheraven} 563227825Stheraven 564227825Stheravenvoid 565227825Stheravenlocale::__install_ctor(const locale& other, facet* f, long id) 566227825Stheraven{ 567227825Stheraven if (f) 568227825Stheraven __locale_ = new __imp(*other.__locale_, f, id); 569227825Stheraven else 570227825Stheraven __locale_ = other.__locale_; 571227825Stheraven __locale_->__add_shared(); 572227825Stheraven} 573227825Stheraven 574227825Stheravenlocale 575227825Stheravenlocale::global(const locale& loc) 576227825Stheraven{ 577227825Stheraven locale& g = __global(); 578227825Stheraven locale r = g; 579227825Stheraven g = loc; 580227825Stheraven if (g.name() != "*") 581227825Stheraven setlocale(LC_ALL, g.name().c_str()); 582227825Stheraven return r; 583227825Stheraven} 584227825Stheraven 585227825Stheravenbool 586227825Stheravenlocale::has_facet(id& x) const 587227825Stheraven{ 588227825Stheraven return __locale_->has_facet(x.__get()); 589227825Stheraven} 590227825Stheraven 591227825Stheravenconst locale::facet* 592227825Stheravenlocale::use_facet(id& x) const 593227825Stheraven{ 594227825Stheraven return __locale_->use_facet(x.__get()); 595227825Stheraven} 596227825Stheraven 597227825Stheravenbool 598227825Stheravenlocale::operator==(const locale& y) const 599227825Stheraven{ 600227825Stheraven return (__locale_ == y.__locale_) 601227825Stheraven || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name()); 602227825Stheraven} 603227825Stheraven 604227825Stheraven// locale::facet 605227825Stheraven 606227825Stheravenlocale::facet::~facet() 607227825Stheraven{ 608227825Stheraven} 609227825Stheraven 610227825Stheravenvoid 611227825Stheravenlocale::facet::__on_zero_shared() _NOEXCEPT 612227825Stheraven{ 613227825Stheraven delete this; 614227825Stheraven} 615227825Stheraven 616227825Stheraven// locale::id 617227825Stheraven 618227825Stheravenint32_t locale::id::__next_id = 0; 619227825Stheraven 620227825Stheravennamespace 621227825Stheraven{ 622227825Stheraven 623227825Stheravenclass __fake_bind 624227825Stheraven{ 625227825Stheraven locale::id* id_; 626227825Stheraven void (locale::id::* pmf_)(); 627227825Stheravenpublic: 628227825Stheraven __fake_bind(void (locale::id::* pmf)(), locale::id* id) 629227825Stheraven : id_(id), pmf_(pmf) {} 630227825Stheraven 631227825Stheraven void operator()() const 632227825Stheraven { 633227825Stheraven (id_->*pmf_)(); 634227825Stheraven } 635227825Stheraven}; 636227825Stheraven 637227825Stheraven} 638227825Stheraven 639227825Stheravenlong 640227825Stheravenlocale::id::__get() 641227825Stheraven{ 642227825Stheraven call_once(__flag_, __fake_bind(&locale::id::__init, this)); 643227825Stheraven return __id_ - 1; 644227825Stheraven} 645227825Stheraven 646227825Stheravenvoid 647227825Stheravenlocale::id::__init() 648227825Stheraven{ 649227825Stheraven __id_ = __sync_add_and_fetch(&__next_id, 1); 650227825Stheraven} 651227825Stheraven 652227825Stheraven// template <> class collate_byname<char> 653227825Stheraven 654227825Stheravencollate_byname<char>::collate_byname(const char* n, size_t refs) 655227825Stheraven : collate<char>(refs), 656227825Stheraven __l(newlocale(LC_ALL_MASK, n, 0)) 657227825Stheraven{ 658227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 659227825Stheraven if (__l == 0) 660227825Stheraven throw runtime_error("collate_byname<char>::collate_byname" 661227825Stheraven " failed to construct for " + string(n)); 662227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 663227825Stheraven} 664227825Stheraven 665227825Stheravencollate_byname<char>::collate_byname(const string& name, size_t refs) 666227825Stheraven : collate<char>(refs), 667227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 668227825Stheraven{ 669227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 670227825Stheraven if (__l == 0) 671227825Stheraven throw runtime_error("collate_byname<char>::collate_byname" 672227825Stheraven " failed to construct for " + name); 673227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 674227825Stheraven} 675227825Stheraven 676227825Stheravencollate_byname<char>::~collate_byname() 677227825Stheraven{ 678227825Stheraven freelocale(__l); 679227825Stheraven} 680227825Stheraven 681227825Stheravenint 682227825Stheravencollate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1, 683227825Stheraven const char_type* __lo2, const char_type* __hi2) const 684227825Stheraven{ 685227825Stheraven string_type lhs(__lo1, __hi1); 686227825Stheraven string_type rhs(__lo2, __hi2); 687227825Stheraven int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); 688227825Stheraven if (r < 0) 689227825Stheraven return -1; 690227825Stheraven if (r > 0) 691227825Stheraven return 1; 692227825Stheraven return r; 693227825Stheraven} 694227825Stheraven 695227825Stheravencollate_byname<char>::string_type 696227825Stheravencollate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const 697227825Stheraven{ 698227825Stheraven const string_type in(lo, hi); 699227825Stheraven string_type out(strxfrm_l(0, in.c_str(), 0, __l), char()); 700227825Stheraven strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l); 701227825Stheraven return out; 702227825Stheraven} 703227825Stheraven 704227825Stheraven// template <> class collate_byname<wchar_t> 705227825Stheraven 706227825Stheravencollate_byname<wchar_t>::collate_byname(const char* n, size_t refs) 707227825Stheraven : collate<wchar_t>(refs), 708227825Stheraven __l(newlocale(LC_ALL_MASK, n, 0)) 709227825Stheraven{ 710227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 711227825Stheraven if (__l == 0) 712227825Stheraven throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" 713227825Stheraven " failed to construct for " + string(n)); 714227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 715227825Stheraven} 716227825Stheraven 717227825Stheravencollate_byname<wchar_t>::collate_byname(const string& name, size_t refs) 718227825Stheraven : collate<wchar_t>(refs), 719227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 720227825Stheraven{ 721227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 722227825Stheraven if (__l == 0) 723227825Stheraven throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" 724227825Stheraven " failed to construct for " + name); 725227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 726227825Stheraven} 727227825Stheraven 728227825Stheravencollate_byname<wchar_t>::~collate_byname() 729227825Stheraven{ 730227825Stheraven freelocale(__l); 731227825Stheraven} 732227825Stheraven 733227825Stheravenint 734227825Stheravencollate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1, 735227825Stheraven const char_type* __lo2, const char_type* __hi2) const 736227825Stheraven{ 737227825Stheraven string_type lhs(__lo1, __hi1); 738227825Stheraven string_type rhs(__lo2, __hi2); 739227825Stheraven int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); 740227825Stheraven if (r < 0) 741227825Stheraven return -1; 742227825Stheraven if (r > 0) 743227825Stheraven return 1; 744227825Stheraven return r; 745227825Stheraven} 746227825Stheraven 747227825Stheravencollate_byname<wchar_t>::string_type 748227825Stheravencollate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const 749227825Stheraven{ 750227825Stheraven const string_type in(lo, hi); 751227825Stheraven string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); 752227825Stheraven wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l); 753227825Stheraven return out; 754227825Stheraven} 755227825Stheraven 756227825Stheraven// template <> class ctype<wchar_t>; 757227825Stheraven 758246487Stheravenconst ctype_base::mask ctype_base::space; 759246487Stheravenconst ctype_base::mask ctype_base::print; 760246487Stheravenconst ctype_base::mask ctype_base::cntrl; 761246487Stheravenconst ctype_base::mask ctype_base::upper; 762246487Stheravenconst ctype_base::mask ctype_base::lower; 763246487Stheravenconst ctype_base::mask ctype_base::alpha; 764246487Stheravenconst ctype_base::mask ctype_base::digit; 765246487Stheravenconst ctype_base::mask ctype_base::punct; 766246487Stheravenconst ctype_base::mask ctype_base::xdigit; 767246487Stheravenconst ctype_base::mask ctype_base::blank; 768246487Stheravenconst ctype_base::mask ctype_base::alnum; 769246487Stheravenconst ctype_base::mask ctype_base::graph; 770246487Stheraven 771227825Stheravenlocale::id ctype<wchar_t>::id; 772227825Stheraven 773227825Stheravenctype<wchar_t>::~ctype() 774227825Stheraven{ 775227825Stheraven} 776227825Stheraven 777227825Stheravenbool 778227825Stheravenctype<wchar_t>::do_is(mask m, char_type c) const 779227825Stheraven{ 780262801Sdim return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false; 781227825Stheraven} 782227825Stheraven 783227825Stheravenconst wchar_t* 784227825Stheravenctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const 785227825Stheraven{ 786227825Stheraven for (; low != high; ++low, ++vec) 787227825Stheraven *vec = static_cast<mask>(isascii(*low) ? 788227825Stheraven ctype<char>::classic_table()[*low] : 0); 789227825Stheraven return low; 790227825Stheraven} 791227825Stheraven 792227825Stheravenconst wchar_t* 793227825Stheravenctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const 794227825Stheraven{ 795227825Stheraven for (; low != high; ++low) 796227825Stheraven if (isascii(*low) && (ctype<char>::classic_table()[*low] & m)) 797227825Stheraven break; 798227825Stheraven return low; 799227825Stheraven} 800227825Stheraven 801227825Stheravenconst wchar_t* 802227825Stheravenctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const 803227825Stheraven{ 804227825Stheraven for (; low != high; ++low) 805227825Stheraven if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m))) 806227825Stheraven break; 807227825Stheraven return low; 808227825Stheraven} 809227825Stheraven 810227825Stheravenwchar_t 811227825Stheravenctype<wchar_t>::do_toupper(char_type c) const 812227825Stheraven{ 813227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 814227825Stheraven return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; 815262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 816227825Stheraven return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c; 817227825Stheraven#else 818227825Stheraven return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c; 819227825Stheraven#endif 820227825Stheraven} 821227825Stheraven 822227825Stheravenconst wchar_t* 823227825Stheravenctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const 824227825Stheraven{ 825227825Stheraven for (; low != high; ++low) 826227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 827227825Stheraven *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; 828262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 829227825Stheraven *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] 830227825Stheraven : *low; 831227825Stheraven#else 832227825Stheraven *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low; 833227825Stheraven#endif 834227825Stheraven return low; 835227825Stheraven} 836227825Stheraven 837227825Stheravenwchar_t 838227825Stheravenctype<wchar_t>::do_tolower(char_type c) const 839227825Stheraven{ 840227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 841227825Stheraven return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; 842262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 843227825Stheraven return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c; 844227825Stheraven#else 845227825Stheraven return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c; 846227825Stheraven#endif 847227825Stheraven} 848227825Stheraven 849227825Stheravenconst wchar_t* 850227825Stheravenctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const 851227825Stheraven{ 852227825Stheraven for (; low != high; ++low) 853227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 854227825Stheraven *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; 855262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 856227825Stheraven *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] 857227825Stheraven : *low; 858227825Stheraven#else 859227825Stheraven *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low; 860227825Stheraven#endif 861227825Stheraven return low; 862227825Stheraven} 863227825Stheraven 864227825Stheravenwchar_t 865227825Stheravenctype<wchar_t>::do_widen(char c) const 866227825Stheraven{ 867227825Stheraven return c; 868227825Stheraven} 869227825Stheraven 870227825Stheravenconst char* 871227825Stheravenctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const 872227825Stheraven{ 873227825Stheraven for (; low != high; ++low, ++dest) 874227825Stheraven *dest = *low; 875227825Stheraven return low; 876227825Stheraven} 877227825Stheraven 878227825Stheravenchar 879227825Stheravenctype<wchar_t>::do_narrow(char_type c, char dfault) const 880227825Stheraven{ 881227825Stheraven if (isascii(c)) 882227825Stheraven return static_cast<char>(c); 883227825Stheraven return dfault; 884227825Stheraven} 885227825Stheraven 886227825Stheravenconst wchar_t* 887227825Stheravenctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 888227825Stheraven{ 889227825Stheraven for (; low != high; ++low, ++dest) 890227825Stheraven if (isascii(*low)) 891232950Stheraven *dest = static_cast<char>(*low); 892227825Stheraven else 893227825Stheraven *dest = dfault; 894227825Stheraven return low; 895227825Stheraven} 896227825Stheraven 897227825Stheraven// template <> class ctype<char>; 898227825Stheraven 899227825Stheravenlocale::id ctype<char>::id; 900227825Stheraven 901227825Stheravenctype<char>::ctype(const mask* tab, bool del, size_t refs) 902227825Stheraven : locale::facet(refs), 903227825Stheraven __tab_(tab), 904227825Stheraven __del_(del) 905227825Stheraven{ 906227825Stheraven if (__tab_ == 0) 907227825Stheraven __tab_ = classic_table(); 908227825Stheraven} 909227825Stheraven 910227825Stheravenctype<char>::~ctype() 911227825Stheraven{ 912227825Stheraven if (__tab_ && __del_) 913227825Stheraven delete [] __tab_; 914227825Stheraven} 915227825Stheraven 916227825Stheravenchar 917227825Stheravenctype<char>::do_toupper(char_type c) const 918227825Stheraven{ 919227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 920232950Stheraven return isascii(c) ? 921232950Stheraven static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c; 922253159Stheraven#elif defined(__NetBSD__) 923253159Stheraven return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]); 924262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) 925249998Sdim return isascii(c) ? 926253159Stheraven static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c; 927227825Stheraven#else 928227825Stheraven return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c; 929227825Stheraven#endif 930227825Stheraven} 931227825Stheraven 932227825Stheravenconst char* 933227825Stheravenctype<char>::do_toupper(char_type* low, const char_type* high) const 934227825Stheraven{ 935227825Stheraven for (; low != high; ++low) 936227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 937232950Stheraven *low = isascii(*low) ? 938232950Stheraven static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low; 939253159Stheraven#elif defined(__NetBSD__) 940253159Stheraven *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]); 941262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) 942249998Sdim *low = isascii(*low) ? 943249998Sdim static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low; 944227825Stheraven#else 945227825Stheraven *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low; 946227825Stheraven#endif 947227825Stheraven return low; 948227825Stheraven} 949227825Stheraven 950227825Stheravenchar 951227825Stheravenctype<char>::do_tolower(char_type c) const 952227825Stheraven{ 953227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 954232950Stheraven return isascii(c) ? 955232950Stheraven static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c; 956253159Stheraven#elif defined(__NetBSD__) 957253159Stheraven return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]); 958262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 959249998Sdim return isascii(c) ? 960249998Sdim static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c; 961227825Stheraven#else 962227825Stheraven return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c; 963227825Stheraven#endif 964227825Stheraven} 965227825Stheraven 966227825Stheravenconst char* 967227825Stheravenctype<char>::do_tolower(char_type* low, const char_type* high) const 968227825Stheraven{ 969227825Stheraven for (; low != high; ++low) 970227825Stheraven#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE 971232950Stheraven *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low; 972253159Stheraven#elif defined(__NetBSD__) 973253159Stheraven *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]); 974262801Sdim#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) 975249998Sdim *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low; 976227825Stheraven#else 977227825Stheraven *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; 978227825Stheraven#endif 979227825Stheraven return low; 980227825Stheraven} 981227825Stheraven 982227825Stheravenchar 983227825Stheravenctype<char>::do_widen(char c) const 984227825Stheraven{ 985227825Stheraven return c; 986227825Stheraven} 987227825Stheraven 988227825Stheravenconst char* 989227825Stheravenctype<char>::do_widen(const char* low, const char* high, char_type* dest) const 990227825Stheraven{ 991227825Stheraven for (; low != high; ++low, ++dest) 992227825Stheraven *dest = *low; 993227825Stheraven return low; 994227825Stheraven} 995227825Stheraven 996227825Stheravenchar 997227825Stheravenctype<char>::do_narrow(char_type c, char dfault) const 998227825Stheraven{ 999227825Stheraven if (isascii(c)) 1000227825Stheraven return static_cast<char>(c); 1001227825Stheraven return dfault; 1002227825Stheraven} 1003227825Stheraven 1004227825Stheravenconst char* 1005227825Stheravenctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 1006227825Stheraven{ 1007227825Stheraven for (; low != high; ++low, ++dest) 1008227825Stheraven if (isascii(*low)) 1009227825Stheraven *dest = *low; 1010227825Stheraven else 1011227825Stheraven *dest = dfault; 1012227825Stheraven return low; 1013227825Stheraven} 1014227825Stheraven 1015262801Sdim#ifdef __EMSCRIPTEN__ 1016249998Sdimextern "C" const unsigned short ** __ctype_b_loc(); 1017249998Sdimextern "C" const int ** __ctype_tolower_loc(); 1018249998Sdimextern "C" const int ** __ctype_toupper_loc(); 1019249998Sdim#endif 1020249998Sdim 1021227825Stheravenconst ctype<char>::mask* 1022227825Stheravenctype<char>::classic_table() _NOEXCEPT 1023227825Stheraven{ 1024227825Stheraven#if defined(__APPLE__) || defined(__FreeBSD__) 1025227825Stheraven return _DefaultRuneLocale.__runetype; 1026253159Stheraven#elif defined(__NetBSD__) 1027253159Stheraven return _C_ctype_tab_ + 1; 1028227825Stheraven#elif defined(__GLIBC__) 1029227825Stheraven return __cloc()->__ctype_b; 1030232950Stheraven#elif __sun__ 1031232950Stheraven return __ctype_mask; 1032262801Sdim#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 1033227825Stheraven return _ctype+1; // internal ctype mask table defined in msvcrt.dll 1034227825Stheraven// This is assumed to be safe, which is a nonsense assumption because we're 1035227825Stheraven// going to end up dereferencing it later... 1036262801Sdim#elif defined(__EMSCRIPTEN__) 1037249998Sdim return *__ctype_b_loc(); 1038262801Sdim#elif defined(_AIX) 1039262801Sdim return (const unsigned long *)__lc_ctype_ptr->obj->mask; 1040227825Stheraven#else 1041232950Stheraven // Platform not supported: abort so the person doing the port knows what to 1042232950Stheraven // fix 1043232950Stheraven# warning ctype<char>::classic_table() is not implemented 1044262801Sdim printf("ctype<char>::classic_table() is not implemented\n"); 1045232950Stheraven abort(); 1046227825Stheraven return NULL; 1047227825Stheraven#endif 1048227825Stheraven} 1049227825Stheraven 1050227825Stheraven#if defined(__GLIBC__) 1051227825Stheravenconst int* 1052227825Stheravenctype<char>::__classic_lower_table() _NOEXCEPT 1053227825Stheraven{ 1054227825Stheraven return __cloc()->__ctype_tolower; 1055227825Stheraven} 1056227825Stheraven 1057227825Stheravenconst int* 1058227825Stheravenctype<char>::__classic_upper_table() _NOEXCEPT 1059227825Stheraven{ 1060227825Stheraven return __cloc()->__ctype_toupper; 1061227825Stheraven} 1062253159Stheraven#elif __NetBSD__ 1063253159Stheravenconst short* 1064253159Stheravenctype<char>::__classic_lower_table() _NOEXCEPT 1065253159Stheraven{ 1066253159Stheraven return _C_tolower_tab_ + 1; 1067253159Stheraven} 1068227825Stheraven 1069253159Stheravenconst short* 1070253159Stheravenctype<char>::__classic_upper_table() _NOEXCEPT 1071253159Stheraven{ 1072253159Stheraven return _C_toupper_tab_ + 1; 1073253159Stheraven} 1074253159Stheraven 1075262801Sdim#elif defined(__EMSCRIPTEN__) 1076249998Sdimconst int* 1077249998Sdimctype<char>::__classic_lower_table() _NOEXCEPT 1078249998Sdim{ 1079249998Sdim return *__ctype_tolower_loc(); 1080249998Sdim} 1081249998Sdim 1082249998Sdimconst int* 1083249998Sdimctype<char>::__classic_upper_table() _NOEXCEPT 1084249998Sdim{ 1085249998Sdim return *__ctype_toupper_loc(); 1086249998Sdim} 1087262801Sdim#endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__ 1088249998Sdim 1089227825Stheraven// template <> class ctype_byname<char> 1090227825Stheraven 1091227825Stheravenctype_byname<char>::ctype_byname(const char* name, size_t refs) 1092227825Stheraven : ctype<char>(0, false, refs), 1093227825Stheraven __l(newlocale(LC_ALL_MASK, name, 0)) 1094227825Stheraven{ 1095227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1096227825Stheraven if (__l == 0) 1097227825Stheraven throw runtime_error("ctype_byname<char>::ctype_byname" 1098227825Stheraven " failed to construct for " + string(name)); 1099227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1100227825Stheraven} 1101227825Stheraven 1102227825Stheravenctype_byname<char>::ctype_byname(const string& name, size_t refs) 1103227825Stheraven : ctype<char>(0, false, refs), 1104227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 1105227825Stheraven{ 1106227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1107227825Stheraven if (__l == 0) 1108227825Stheraven throw runtime_error("ctype_byname<char>::ctype_byname" 1109227825Stheraven " failed to construct for " + name); 1110227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1111227825Stheraven} 1112227825Stheraven 1113227825Stheravenctype_byname<char>::~ctype_byname() 1114227825Stheraven{ 1115227825Stheraven freelocale(__l); 1116227825Stheraven} 1117227825Stheraven 1118227825Stheravenchar 1119227825Stheravenctype_byname<char>::do_toupper(char_type c) const 1120227825Stheraven{ 1121253159Stheraven return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l)); 1122227825Stheraven} 1123227825Stheraven 1124227825Stheravenconst char* 1125227825Stheravenctype_byname<char>::do_toupper(char_type* low, const char_type* high) const 1126227825Stheraven{ 1127227825Stheraven for (; low != high; ++low) 1128253159Stheraven *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l)); 1129227825Stheraven return low; 1130227825Stheraven} 1131227825Stheraven 1132227825Stheravenchar 1133227825Stheravenctype_byname<char>::do_tolower(char_type c) const 1134227825Stheraven{ 1135253159Stheraven return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l)); 1136227825Stheraven} 1137227825Stheraven 1138227825Stheravenconst char* 1139227825Stheravenctype_byname<char>::do_tolower(char_type* low, const char_type* high) const 1140227825Stheraven{ 1141227825Stheraven for (; low != high; ++low) 1142253159Stheraven *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l)); 1143227825Stheraven return low; 1144227825Stheraven} 1145227825Stheraven 1146227825Stheraven// template <> class ctype_byname<wchar_t> 1147227825Stheraven 1148227825Stheravenctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs) 1149227825Stheraven : ctype<wchar_t>(refs), 1150227825Stheraven __l(newlocale(LC_ALL_MASK, name, 0)) 1151227825Stheraven{ 1152227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1153227825Stheraven if (__l == 0) 1154227825Stheraven throw runtime_error("ctype_byname<wchar_t>::ctype_byname" 1155227825Stheraven " failed to construct for " + string(name)); 1156227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1157227825Stheraven} 1158227825Stheraven 1159227825Stheravenctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs) 1160227825Stheraven : ctype<wchar_t>(refs), 1161227825Stheraven __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) 1162227825Stheraven{ 1163227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1164227825Stheraven if (__l == 0) 1165227825Stheraven throw runtime_error("ctype_byname<wchar_t>::ctype_byname" 1166227825Stheraven " failed to construct for " + name); 1167227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1168227825Stheraven} 1169227825Stheraven 1170227825Stheravenctype_byname<wchar_t>::~ctype_byname() 1171227825Stheraven{ 1172227825Stheraven freelocale(__l); 1173227825Stheraven} 1174227825Stheraven 1175227825Stheravenbool 1176227825Stheravenctype_byname<wchar_t>::do_is(mask m, char_type c) const 1177227825Stheraven{ 1178227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1179227825Stheraven return static_cast<bool>(iswctype_l(c, m, __l)); 1180227825Stheraven#else 1181241903Sdim bool result = false; 1182249998Sdim wint_t ch = static_cast<wint_t>(c); 1183249998Sdim if (m & space) result |= (iswspace_l(ch, __l) != 0); 1184249998Sdim if (m & print) result |= (iswprint_l(ch, __l) != 0); 1185249998Sdim if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0); 1186249998Sdim if (m & upper) result |= (iswupper_l(ch, __l) != 0); 1187249998Sdim if (m & lower) result |= (iswlower_l(ch, __l) != 0); 1188249998Sdim if (m & alpha) result |= (iswalpha_l(ch, __l) != 0); 1189249998Sdim if (m & digit) result |= (iswdigit_l(ch, __l) != 0); 1190249998Sdim if (m & punct) result |= (iswpunct_l(ch, __l) != 0); 1191249998Sdim if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0); 1192249998Sdim if (m & blank) result |= (iswblank_l(ch, __l) != 0); 1193227825Stheraven return result; 1194227825Stheraven#endif 1195227825Stheraven} 1196227825Stheraven 1197227825Stheravenconst wchar_t* 1198227825Stheravenctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const 1199227825Stheraven{ 1200227825Stheraven for (; low != high; ++low, ++vec) 1201227825Stheraven { 1202227825Stheraven if (isascii(*low)) 1203227825Stheraven *vec = static_cast<mask>(ctype<char>::classic_table()[*low]); 1204227825Stheraven else 1205227825Stheraven { 1206227825Stheraven *vec = 0; 1207249998Sdim wint_t ch = static_cast<wint_t>(*low); 1208249998Sdim if (iswspace_l(ch, __l)) 1209227825Stheraven *vec |= space; 1210249998Sdim if (iswprint_l(ch, __l)) 1211227825Stheraven *vec |= print; 1212249998Sdim if (iswcntrl_l(ch, __l)) 1213227825Stheraven *vec |= cntrl; 1214249998Sdim if (iswupper_l(ch, __l)) 1215227825Stheraven *vec |= upper; 1216249998Sdim if (iswlower_l(ch, __l)) 1217227825Stheraven *vec |= lower; 1218249998Sdim if (iswalpha_l(ch, __l)) 1219227825Stheraven *vec |= alpha; 1220249998Sdim if (iswdigit_l(ch, __l)) 1221227825Stheraven *vec |= digit; 1222249998Sdim if (iswpunct_l(ch, __l)) 1223227825Stheraven *vec |= punct; 1224249998Sdim if (iswxdigit_l(ch, __l)) 1225227825Stheraven *vec |= xdigit; 1226227825Stheraven } 1227227825Stheraven } 1228227825Stheraven return low; 1229227825Stheraven} 1230227825Stheraven 1231227825Stheravenconst wchar_t* 1232227825Stheravenctype_byname<wchar_t>::do_scan_is(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)) break; 1242249998Sdim if (m & print && iswprint_l(ch, __l)) break; 1243249998Sdim if (m & cntrl && iswcntrl_l(ch, __l)) break; 1244249998Sdim if (m & upper && iswupper_l(ch, __l)) break; 1245249998Sdim if (m & lower && iswlower_l(ch, __l)) break; 1246249998Sdim if (m & alpha && iswalpha_l(ch, __l)) break; 1247249998Sdim if (m & digit && iswdigit_l(ch, __l)) break; 1248249998Sdim if (m & punct && iswpunct_l(ch, __l)) break; 1249249998Sdim if (m & xdigit && iswxdigit_l(ch, __l)) break; 1250249998Sdim if (m & blank && iswblank_l(ch, __l)) break; 1251227825Stheraven#endif 1252227825Stheraven } 1253227825Stheraven return low; 1254227825Stheraven} 1255227825Stheraven 1256227825Stheravenconst wchar_t* 1257227825Stheravenctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const 1258227825Stheraven{ 1259227825Stheraven for (; low != high; ++low) 1260227825Stheraven { 1261227825Stheraven#ifdef _LIBCPP_WCTYPE_IS_MASK 1262227825Stheraven if (!iswctype_l(*low, m, __l)) 1263227825Stheraven break; 1264227825Stheraven#else 1265249998Sdim wint_t ch = static_cast<wint_t>(*low); 1266249998Sdim if (m & space && iswspace_l(ch, __l)) continue; 1267249998Sdim if (m & print && iswprint_l(ch, __l)) continue; 1268249998Sdim if (m & cntrl && iswcntrl_l(ch, __l)) continue; 1269249998Sdim if (m & upper && iswupper_l(ch, __l)) continue; 1270249998Sdim if (m & lower && iswlower_l(ch, __l)) continue; 1271249998Sdim if (m & alpha && iswalpha_l(ch, __l)) continue; 1272249998Sdim if (m & digit && iswdigit_l(ch, __l)) continue; 1273249998Sdim if (m & punct && iswpunct_l(ch, __l)) continue; 1274249998Sdim if (m & xdigit && iswxdigit_l(ch, __l)) continue; 1275249998Sdim if (m & blank && iswblank_l(ch, __l)) continue; 1276227825Stheraven break; 1277227825Stheraven#endif 1278227825Stheraven } 1279227825Stheraven return low; 1280227825Stheraven} 1281227825Stheraven 1282227825Stheravenwchar_t 1283227825Stheravenctype_byname<wchar_t>::do_toupper(char_type c) const 1284227825Stheraven{ 1285227825Stheraven return towupper_l(c, __l); 1286227825Stheraven} 1287227825Stheraven 1288227825Stheravenconst wchar_t* 1289227825Stheravenctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const 1290227825Stheraven{ 1291227825Stheraven for (; low != high; ++low) 1292227825Stheraven *low = towupper_l(*low, __l); 1293227825Stheraven return low; 1294227825Stheraven} 1295227825Stheraven 1296227825Stheravenwchar_t 1297227825Stheravenctype_byname<wchar_t>::do_tolower(char_type c) const 1298227825Stheraven{ 1299227825Stheraven return towlower_l(c, __l); 1300227825Stheraven} 1301227825Stheraven 1302227825Stheravenconst wchar_t* 1303227825Stheravenctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const 1304227825Stheraven{ 1305227825Stheraven for (; low != high; ++low) 1306227825Stheraven *low = towlower_l(*low, __l); 1307227825Stheraven return low; 1308227825Stheraven} 1309227825Stheraven 1310227825Stheravenwchar_t 1311227825Stheravenctype_byname<wchar_t>::do_widen(char c) const 1312227825Stheraven{ 1313227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1314227825Stheraven return btowc_l(c, __l); 1315227825Stheraven#else 1316227825Stheraven return __btowc_l(c, __l); 1317227825Stheraven#endif 1318227825Stheraven} 1319227825Stheraven 1320227825Stheravenconst char* 1321227825Stheravenctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const 1322227825Stheraven{ 1323227825Stheraven for (; low != high; ++low, ++dest) 1324227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1325227825Stheraven *dest = btowc_l(*low, __l); 1326227825Stheraven#else 1327227825Stheraven *dest = __btowc_l(*low, __l); 1328227825Stheraven#endif 1329227825Stheraven return low; 1330227825Stheraven} 1331227825Stheraven 1332227825Stheravenchar 1333227825Stheravenctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const 1334227825Stheraven{ 1335227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1336227825Stheraven int r = wctob_l(c, __l); 1337227825Stheraven#else 1338227825Stheraven int r = __wctob_l(c, __l); 1339227825Stheraven#endif 1340246487Stheraven return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; 1341227825Stheraven} 1342227825Stheraven 1343227825Stheravenconst wchar_t* 1344227825Stheravenctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const 1345227825Stheraven{ 1346227825Stheraven for (; low != high; ++low, ++dest) 1347227825Stheraven { 1348227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1349227825Stheraven int r = wctob_l(*low, __l); 1350227825Stheraven#else 1351227825Stheraven int r = __wctob_l(*low, __l); 1352227825Stheraven#endif 1353246487Stheraven *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; 1354227825Stheraven } 1355227825Stheraven return low; 1356227825Stheraven} 1357227825Stheraven 1358227825Stheraven// template <> class codecvt<char, char, mbstate_t> 1359227825Stheraven 1360227825Stheravenlocale::id codecvt<char, char, mbstate_t>::id; 1361227825Stheraven 1362227825Stheravencodecvt<char, char, mbstate_t>::~codecvt() 1363227825Stheraven{ 1364227825Stheraven} 1365227825Stheraven 1366227825Stheravencodecvt<char, char, mbstate_t>::result 1367227825Stheravencodecvt<char, char, mbstate_t>::do_out(state_type&, 1368227825Stheraven const intern_type* frm, const intern_type*, const intern_type*& frm_nxt, 1369227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 1370227825Stheraven{ 1371227825Stheraven frm_nxt = frm; 1372227825Stheraven to_nxt = to; 1373227825Stheraven return noconv; 1374227825Stheraven} 1375227825Stheraven 1376227825Stheravencodecvt<char, char, mbstate_t>::result 1377227825Stheravencodecvt<char, char, mbstate_t>::do_in(state_type&, 1378227825Stheraven const extern_type* frm, const extern_type*, const extern_type*& frm_nxt, 1379227825Stheraven intern_type* to, intern_type*, intern_type*& to_nxt) const 1380227825Stheraven{ 1381227825Stheraven frm_nxt = frm; 1382227825Stheraven to_nxt = to; 1383227825Stheraven return noconv; 1384227825Stheraven} 1385227825Stheraven 1386227825Stheravencodecvt<char, char, mbstate_t>::result 1387227825Stheravencodecvt<char, char, mbstate_t>::do_unshift(state_type&, 1388227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 1389227825Stheraven{ 1390227825Stheraven to_nxt = to; 1391227825Stheraven return noconv; 1392227825Stheraven} 1393227825Stheraven 1394227825Stheravenint 1395227825Stheravencodecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT 1396227825Stheraven{ 1397227825Stheraven return 1; 1398227825Stheraven} 1399227825Stheraven 1400227825Stheravenbool 1401227825Stheravencodecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 1402227825Stheraven{ 1403227825Stheraven return true; 1404227825Stheraven} 1405227825Stheraven 1406227825Stheravenint 1407227825Stheravencodecvt<char, char, mbstate_t>::do_length(state_type&, 1408227825Stheraven const extern_type* frm, const extern_type* end, size_t mx) const 1409227825Stheraven{ 1410232950Stheraven return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm))); 1411227825Stheraven} 1412227825Stheraven 1413227825Stheravenint 1414227825Stheravencodecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT 1415227825Stheraven{ 1416227825Stheraven return 1; 1417227825Stheraven} 1418227825Stheraven 1419227825Stheraven// template <> class codecvt<wchar_t, char, mbstate_t> 1420227825Stheraven 1421227825Stheravenlocale::id codecvt<wchar_t, char, mbstate_t>::id; 1422227825Stheraven 1423227825Stheravencodecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) 1424227825Stheraven : locale::facet(refs), 1425253159Stheraven __l(_LIBCPP_GET_C_LOCALE) 1426227825Stheraven{ 1427227825Stheraven} 1428227825Stheraven 1429227825Stheravencodecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs) 1430227825Stheraven : locale::facet(refs), 1431227825Stheraven __l(newlocale(LC_ALL_MASK, nm, 0)) 1432227825Stheraven{ 1433227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 1434227825Stheraven if (__l == 0) 1435227825Stheraven throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname" 1436227825Stheraven " failed to construct for " + string(nm)); 1437227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 1438227825Stheraven} 1439227825Stheraven 1440227825Stheravencodecvt<wchar_t, char, mbstate_t>::~codecvt() 1441227825Stheraven{ 1442253159Stheraven if (__l != _LIBCPP_GET_C_LOCALE) 1443227825Stheraven freelocale(__l); 1444227825Stheraven} 1445227825Stheraven 1446227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1447227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, 1448227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 1449227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 1450227825Stheraven{ 1451227825Stheraven // look for first internal null in frm 1452227825Stheraven const intern_type* fend = frm; 1453227825Stheraven for (; fend != frm_end; ++fend) 1454227825Stheraven if (*fend == 0) 1455227825Stheraven break; 1456227825Stheraven // loop over all null-terminated sequences in frm 1457227825Stheraven to_nxt = to; 1458227825Stheraven for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) 1459227825Stheraven { 1460249998Sdim // save state in case it is needed to recover to_nxt on error 1461227825Stheraven mbstate_t save_state = st; 1462227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1463232950Stheraven size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), 1464232950Stheraven static_cast<size_t>(to_end-to), &st, __l); 1465227825Stheraven#else 1466227825Stheraven size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); 1467227825Stheraven#endif 1468227825Stheraven if (n == size_t(-1)) 1469227825Stheraven { 1470227825Stheraven // need to recover to_nxt 1471227825Stheraven for (to_nxt = to; frm != frm_nxt; ++frm) 1472227825Stheraven { 1473227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1474227825Stheraven n = wcrtomb_l(to_nxt, *frm, &save_state, __l); 1475227825Stheraven#else 1476227825Stheraven n = __wcrtomb_l(to_nxt, *frm, &save_state, __l); 1477227825Stheraven#endif 1478227825Stheraven if (n == size_t(-1)) 1479227825Stheraven break; 1480227825Stheraven to_nxt += n; 1481227825Stheraven } 1482227825Stheraven frm_nxt = frm; 1483227825Stheraven return error; 1484227825Stheraven } 1485227825Stheraven if (n == 0) 1486227825Stheraven return partial; 1487227825Stheraven to_nxt += n; 1488227825Stheraven if (to_nxt == to_end) 1489227825Stheraven break; 1490227825Stheraven if (fend != frm_end) // set up next null terminated sequence 1491227825Stheraven { 1492227825Stheraven // Try to write the terminating null 1493227825Stheraven extern_type tmp[MB_LEN_MAX]; 1494227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1495227825Stheraven n = wcrtomb_l(tmp, intern_type(), &st, __l); 1496227825Stheraven#else 1497227825Stheraven n = __wcrtomb_l(tmp, intern_type(), &st, __l); 1498227825Stheraven#endif 1499227825Stheraven if (n == size_t(-1)) // on error 1500227825Stheraven return error; 1501232950Stheraven if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? 1502227825Stheraven return partial; 1503227825Stheraven for (extern_type* p = tmp; n; --n) // write it 1504227825Stheraven *to_nxt++ = *p++; 1505227825Stheraven ++frm_nxt; 1506227825Stheraven // look for next null in frm 1507227825Stheraven for (fend = frm_nxt; fend != frm_end; ++fend) 1508227825Stheraven if (*fend == 0) 1509227825Stheraven break; 1510227825Stheraven } 1511227825Stheraven } 1512227825Stheraven return frm_nxt == frm_end ? ok : partial; 1513227825Stheraven} 1514227825Stheraven 1515227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1516227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, 1517227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 1518227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 1519227825Stheraven{ 1520227825Stheraven // look for first internal null in frm 1521227825Stheraven const extern_type* fend = frm; 1522227825Stheraven for (; fend != frm_end; ++fend) 1523227825Stheraven if (*fend == 0) 1524227825Stheraven break; 1525227825Stheraven // loop over all null-terminated sequences in frm 1526227825Stheraven to_nxt = to; 1527227825Stheraven for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt) 1528227825Stheraven { 1529249998Sdim // save state in case it is needed to recover to_nxt on error 1530227825Stheraven mbstate_t save_state = st; 1531227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1532232950Stheraven size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), 1533232950Stheraven static_cast<size_t>(to_end-to), &st, __l); 1534227825Stheraven#else 1535227825Stheraven size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); 1536227825Stheraven#endif 1537227825Stheraven if (n == size_t(-1)) 1538227825Stheraven { 1539227825Stheraven // need to recover to_nxt 1540227825Stheraven for (to_nxt = to; frm != frm_nxt; ++to_nxt) 1541227825Stheraven { 1542227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1543232950Stheraven n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm), 1544232950Stheraven &save_state, __l); 1545227825Stheraven#else 1546227825Stheraven n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l); 1547227825Stheraven#endif 1548227825Stheraven switch (n) 1549227825Stheraven { 1550227825Stheraven case 0: 1551227825Stheraven ++frm; 1552227825Stheraven break; 1553232950Stheraven case size_t(-1): 1554227825Stheraven frm_nxt = frm; 1555227825Stheraven return error; 1556232950Stheraven case size_t(-2): 1557227825Stheraven frm_nxt = frm; 1558227825Stheraven return partial; 1559227825Stheraven default: 1560227825Stheraven frm += n; 1561227825Stheraven break; 1562227825Stheraven } 1563227825Stheraven } 1564227825Stheraven frm_nxt = frm; 1565227825Stheraven return frm_nxt == frm_end ? ok : partial; 1566227825Stheraven } 1567227825Stheraven if (n == 0) 1568227825Stheraven return error; 1569227825Stheraven to_nxt += n; 1570227825Stheraven if (to_nxt == to_end) 1571227825Stheraven break; 1572227825Stheraven if (fend != frm_end) // set up next null terminated sequence 1573227825Stheraven { 1574227825Stheraven // Try to write the terminating null 1575227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1576227825Stheraven n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); 1577227825Stheraven#else 1578227825Stheraven n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); 1579227825Stheraven#endif 1580227825Stheraven if (n != 0) // on error 1581227825Stheraven return error; 1582227825Stheraven ++to_nxt; 1583227825Stheraven ++frm_nxt; 1584227825Stheraven // look for next null in frm 1585227825Stheraven for (fend = frm_nxt; fend != frm_end; ++fend) 1586227825Stheraven if (*fend == 0) 1587227825Stheraven break; 1588227825Stheraven } 1589227825Stheraven } 1590227825Stheraven return frm_nxt == frm_end ? ok : partial; 1591227825Stheraven} 1592227825Stheraven 1593227825Stheravencodecvt<wchar_t, char, mbstate_t>::result 1594227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, 1595227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 1596227825Stheraven{ 1597227825Stheraven to_nxt = to; 1598227825Stheraven extern_type tmp[MB_LEN_MAX]; 1599227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1600227825Stheraven size_t n = wcrtomb_l(tmp, intern_type(), &st, __l); 1601227825Stheraven#else 1602227825Stheraven size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l); 1603227825Stheraven#endif 1604227825Stheraven if (n == size_t(-1) || n == 0) // on error 1605227825Stheraven return error; 1606227825Stheraven --n; 1607232950Stheraven if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? 1608227825Stheraven return partial; 1609227825Stheraven for (extern_type* p = tmp; n; --n) // write it 1610227825Stheraven *to_nxt++ = *p++; 1611227825Stheraven return ok; 1612227825Stheraven} 1613227825Stheraven 1614227825Stheravenint 1615227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 1616227825Stheraven{ 1617227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1618227825Stheraven if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0) 1619227825Stheraven#else 1620227825Stheraven if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0) 1621227825Stheraven#endif 1622227825Stheraven { 1623227825Stheraven // stateless encoding 1624227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1625227825Stheraven if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings 1626227825Stheraven#else 1627227825Stheraven if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings 1628227825Stheraven#endif 1629227825Stheraven return 1; // which take more than 1 char to form a wchar_t 1630227825Stheraven return 0; 1631227825Stheraven } 1632227825Stheraven return -1; 1633227825Stheraven} 1634227825Stheraven 1635227825Stheravenbool 1636227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 1637227825Stheraven{ 1638227825Stheraven return false; 1639227825Stheraven} 1640227825Stheraven 1641227825Stheravenint 1642227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, 1643227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 1644227825Stheraven{ 1645227825Stheraven int nbytes = 0; 1646227825Stheraven for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) 1647227825Stheraven { 1648227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1649232950Stheraven size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l); 1650227825Stheraven#else 1651227825Stheraven size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l); 1652227825Stheraven#endif 1653227825Stheraven switch (n) 1654227825Stheraven { 1655227825Stheraven case 0: 1656227825Stheraven ++nbytes; 1657227825Stheraven ++frm; 1658227825Stheraven break; 1659232950Stheraven case size_t(-1): 1660232950Stheraven case size_t(-2): 1661227825Stheraven return nbytes; 1662227825Stheraven default: 1663227825Stheraven nbytes += n; 1664227825Stheraven frm += n; 1665227825Stheraven break; 1666227825Stheraven } 1667227825Stheraven } 1668227825Stheraven return nbytes; 1669227825Stheraven} 1670227825Stheraven 1671227825Stheravenint 1672227825Stheravencodecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 1673227825Stheraven{ 1674227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1675249998Sdim return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l)); 1676227825Stheraven#else 1677249998Sdim return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l)); 1678227825Stheraven#endif 1679227825Stheraven} 1680227825Stheraven 1681227825Stheraven// Valid UTF ranges 1682227825Stheraven// UTF-32 UTF-16 UTF-8 # of code points 1683227825Stheraven// first second first second third fourth 1684227825Stheraven// 000000 - 00007F 0000 - 007F 00 - 7F 127 1685227825Stheraven// 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920 1686227825Stheraven// 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048 1687227825Stheraven// 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152 1688227825Stheraven// 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048 1689227825Stheraven// 00D800 - 00DFFF invalid 1690227825Stheraven// 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192 1691227825Stheraven// 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608 1692227825Stheraven// 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432 1693227825Stheraven// 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536 1694227825Stheraven 1695227825Stheravenstatic 1696227825Stheravencodecvt_base::result 1697227825Stheravenutf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 1698227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 1699227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1700227825Stheraven{ 1701227825Stheraven frm_nxt = frm; 1702227825Stheraven to_nxt = to; 1703227825Stheraven if (mode & generate_header) 1704227825Stheraven { 1705227825Stheraven if (to_end-to_nxt < 3) 1706227825Stheraven return codecvt_base::partial; 1707227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 1708227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 1709227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 1710227825Stheraven } 1711227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 1712227825Stheraven { 1713227825Stheraven uint16_t wc1 = *frm_nxt; 1714227825Stheraven if (wc1 > Maxcode) 1715227825Stheraven return codecvt_base::error; 1716227825Stheraven if (wc1 < 0x0080) 1717227825Stheraven { 1718227825Stheraven if (to_end-to_nxt < 1) 1719227825Stheraven return codecvt_base::partial; 1720227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc1); 1721227825Stheraven } 1722227825Stheraven else if (wc1 < 0x0800) 1723227825Stheraven { 1724227825Stheraven if (to_end-to_nxt < 2) 1725227825Stheraven return codecvt_base::partial; 1726227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6)); 1727227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F)); 1728227825Stheraven } 1729227825Stheraven else if (wc1 < 0xD800) 1730227825Stheraven { 1731227825Stheraven if (to_end-to_nxt < 3) 1732227825Stheraven return codecvt_base::partial; 1733227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1734227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1735227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1736227825Stheraven } 1737227825Stheraven else if (wc1 < 0xDC00) 1738227825Stheraven { 1739227825Stheraven if (frm_end-frm_nxt < 2) 1740227825Stheraven return codecvt_base::partial; 1741227825Stheraven uint16_t wc2 = frm_nxt[1]; 1742227825Stheraven if ((wc2 & 0xFC00) != 0xDC00) 1743227825Stheraven return codecvt_base::error; 1744227825Stheraven if (to_end-to_nxt < 4) 1745227825Stheraven return codecvt_base::partial; 1746227825Stheraven if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) + 1747227825Stheraven (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode) 1748227825Stheraven return codecvt_base::error; 1749227825Stheraven ++frm_nxt; 1750227825Stheraven uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; 1751227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2)); 1752227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); 1753227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); 1754227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F)); 1755227825Stheraven } 1756227825Stheraven else if (wc1 < 0xE000) 1757227825Stheraven { 1758227825Stheraven return codecvt_base::error; 1759227825Stheraven } 1760227825Stheraven else 1761227825Stheraven { 1762227825Stheraven if (to_end-to_nxt < 3) 1763227825Stheraven return codecvt_base::partial; 1764227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1765227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1766227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1767227825Stheraven } 1768227825Stheraven } 1769227825Stheraven return codecvt_base::ok; 1770227825Stheraven} 1771227825Stheraven 1772227825Stheravenstatic 1773227825Stheravencodecvt_base::result 1774227825Stheravenutf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 1775227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 1776227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1777227825Stheraven{ 1778227825Stheraven frm_nxt = frm; 1779227825Stheraven to_nxt = to; 1780227825Stheraven if (mode & generate_header) 1781227825Stheraven { 1782227825Stheraven if (to_end-to_nxt < 3) 1783227825Stheraven return codecvt_base::partial; 1784227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 1785227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 1786227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 1787227825Stheraven } 1788227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 1789227825Stheraven { 1790227825Stheraven uint16_t wc1 = static_cast<uint16_t>(*frm_nxt); 1791227825Stheraven if (wc1 > Maxcode) 1792227825Stheraven return codecvt_base::error; 1793227825Stheraven if (wc1 < 0x0080) 1794227825Stheraven { 1795227825Stheraven if (to_end-to_nxt < 1) 1796227825Stheraven return codecvt_base::partial; 1797227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc1); 1798227825Stheraven } 1799227825Stheraven else if (wc1 < 0x0800) 1800227825Stheraven { 1801227825Stheraven if (to_end-to_nxt < 2) 1802227825Stheraven return codecvt_base::partial; 1803227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6)); 1804227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F)); 1805227825Stheraven } 1806227825Stheraven else if (wc1 < 0xD800) 1807227825Stheraven { 1808227825Stheraven if (to_end-to_nxt < 3) 1809227825Stheraven return codecvt_base::partial; 1810227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1811227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1812227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1813227825Stheraven } 1814227825Stheraven else if (wc1 < 0xDC00) 1815227825Stheraven { 1816227825Stheraven if (frm_end-frm_nxt < 2) 1817227825Stheraven return codecvt_base::partial; 1818227825Stheraven uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]); 1819227825Stheraven if ((wc2 & 0xFC00) != 0xDC00) 1820227825Stheraven return codecvt_base::error; 1821227825Stheraven if (to_end-to_nxt < 4) 1822227825Stheraven return codecvt_base::partial; 1823227825Stheraven if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) + 1824227825Stheraven (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode) 1825227825Stheraven return codecvt_base::error; 1826227825Stheraven ++frm_nxt; 1827227825Stheraven uint8_t z = ((wc1 & 0x03C0) >> 6) + 1; 1828227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2)); 1829227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2)); 1830227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6)); 1831227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F)); 1832227825Stheraven } 1833227825Stheraven else if (wc1 < 0xE000) 1834227825Stheraven { 1835227825Stheraven return codecvt_base::error; 1836227825Stheraven } 1837227825Stheraven else 1838227825Stheraven { 1839227825Stheraven if (to_end-to_nxt < 3) 1840227825Stheraven return codecvt_base::partial; 1841227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12)); 1842227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6)); 1843227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F)); 1844227825Stheraven } 1845227825Stheraven } 1846227825Stheraven return codecvt_base::ok; 1847227825Stheraven} 1848227825Stheraven 1849227825Stheravenstatic 1850227825Stheravencodecvt_base::result 1851227825Stheravenutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 1852227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 1853227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1854227825Stheraven{ 1855227825Stheraven frm_nxt = frm; 1856227825Stheraven to_nxt = to; 1857227825Stheraven if (mode & consume_header) 1858227825Stheraven { 1859227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 1860227825Stheraven frm_nxt[2] == 0xBF) 1861227825Stheraven frm_nxt += 3; 1862227825Stheraven } 1863227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 1864227825Stheraven { 1865227825Stheraven uint8_t c1 = *frm_nxt; 1866227825Stheraven if (c1 > Maxcode) 1867227825Stheraven return codecvt_base::error; 1868227825Stheraven if (c1 < 0x80) 1869227825Stheraven { 1870227825Stheraven *to_nxt = static_cast<uint16_t>(c1); 1871227825Stheraven ++frm_nxt; 1872227825Stheraven } 1873227825Stheraven else if (c1 < 0xC2) 1874227825Stheraven { 1875227825Stheraven return codecvt_base::error; 1876227825Stheraven } 1877227825Stheraven else if (c1 < 0xE0) 1878227825Stheraven { 1879227825Stheraven if (frm_end-frm_nxt < 2) 1880227825Stheraven return codecvt_base::partial; 1881227825Stheraven uint8_t c2 = frm_nxt[1]; 1882227825Stheraven if ((c2 & 0xC0) != 0x80) 1883227825Stheraven return codecvt_base::error; 1884227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 1885227825Stheraven if (t > Maxcode) 1886227825Stheraven return codecvt_base::error; 1887227825Stheraven *to_nxt = t; 1888227825Stheraven frm_nxt += 2; 1889227825Stheraven } 1890227825Stheraven else if (c1 < 0xF0) 1891227825Stheraven { 1892227825Stheraven if (frm_end-frm_nxt < 3) 1893227825Stheraven return codecvt_base::partial; 1894227825Stheraven uint8_t c2 = frm_nxt[1]; 1895227825Stheraven uint8_t c3 = frm_nxt[2]; 1896227825Stheraven switch (c1) 1897227825Stheraven { 1898227825Stheraven case 0xE0: 1899227825Stheraven if ((c2 & 0xE0) != 0xA0) 1900227825Stheraven return codecvt_base::error; 1901227825Stheraven break; 1902227825Stheraven case 0xED: 1903227825Stheraven if ((c2 & 0xE0) != 0x80) 1904227825Stheraven return codecvt_base::error; 1905227825Stheraven break; 1906227825Stheraven default: 1907227825Stheraven if ((c2 & 0xC0) != 0x80) 1908227825Stheraven return codecvt_base::error; 1909227825Stheraven break; 1910227825Stheraven } 1911227825Stheraven if ((c3 & 0xC0) != 0x80) 1912227825Stheraven return codecvt_base::error; 1913227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 1914227825Stheraven | ((c2 & 0x3F) << 6) 1915227825Stheraven | (c3 & 0x3F)); 1916227825Stheraven if (t > Maxcode) 1917227825Stheraven return codecvt_base::error; 1918227825Stheraven *to_nxt = t; 1919227825Stheraven frm_nxt += 3; 1920227825Stheraven } 1921227825Stheraven else if (c1 < 0xF5) 1922227825Stheraven { 1923227825Stheraven if (frm_end-frm_nxt < 4) 1924227825Stheraven return codecvt_base::partial; 1925227825Stheraven uint8_t c2 = frm_nxt[1]; 1926227825Stheraven uint8_t c3 = frm_nxt[2]; 1927227825Stheraven uint8_t c4 = frm_nxt[3]; 1928227825Stheraven switch (c1) 1929227825Stheraven { 1930227825Stheraven case 0xF0: 1931227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 1932227825Stheraven return codecvt_base::error; 1933227825Stheraven break; 1934227825Stheraven case 0xF4: 1935227825Stheraven if ((c2 & 0xF0) != 0x80) 1936227825Stheraven return codecvt_base::error; 1937227825Stheraven break; 1938227825Stheraven default: 1939227825Stheraven if ((c2 & 0xC0) != 0x80) 1940227825Stheraven return codecvt_base::error; 1941227825Stheraven break; 1942227825Stheraven } 1943227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 1944227825Stheraven return codecvt_base::error; 1945227825Stheraven if (to_end-to_nxt < 2) 1946227825Stheraven return codecvt_base::partial; 1947227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 1948227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 1949227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 1950227825Stheraven return codecvt_base::error; 1951227825Stheraven *to_nxt = static_cast<uint16_t>( 1952227825Stheraven 0xD800 1953227825Stheraven | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) 1954227825Stheraven | ((c2 & 0x0F) << 2) 1955227825Stheraven | ((c3 & 0x30) >> 4)); 1956227825Stheraven *++to_nxt = static_cast<uint16_t>( 1957227825Stheraven 0xDC00 1958227825Stheraven | ((c3 & 0x0F) << 6) 1959227825Stheraven | (c4 & 0x3F)); 1960227825Stheraven frm_nxt += 4; 1961227825Stheraven } 1962227825Stheraven else 1963227825Stheraven { 1964227825Stheraven return codecvt_base::error; 1965227825Stheraven } 1966227825Stheraven } 1967227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 1968227825Stheraven} 1969227825Stheraven 1970227825Stheravenstatic 1971227825Stheravencodecvt_base::result 1972227825Stheravenutf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 1973227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 1974227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 1975227825Stheraven{ 1976227825Stheraven frm_nxt = frm; 1977227825Stheraven to_nxt = to; 1978227825Stheraven if (mode & consume_header) 1979227825Stheraven { 1980227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 1981227825Stheraven frm_nxt[2] == 0xBF) 1982227825Stheraven frm_nxt += 3; 1983227825Stheraven } 1984227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 1985227825Stheraven { 1986227825Stheraven uint8_t c1 = *frm_nxt; 1987227825Stheraven if (c1 > Maxcode) 1988227825Stheraven return codecvt_base::error; 1989227825Stheraven if (c1 < 0x80) 1990227825Stheraven { 1991227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 1992227825Stheraven ++frm_nxt; 1993227825Stheraven } 1994227825Stheraven else if (c1 < 0xC2) 1995227825Stheraven { 1996227825Stheraven return codecvt_base::error; 1997227825Stheraven } 1998227825Stheraven else if (c1 < 0xE0) 1999227825Stheraven { 2000227825Stheraven if (frm_end-frm_nxt < 2) 2001227825Stheraven return codecvt_base::partial; 2002227825Stheraven uint8_t c2 = frm_nxt[1]; 2003227825Stheraven if ((c2 & 0xC0) != 0x80) 2004227825Stheraven return codecvt_base::error; 2005227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F)); 2006227825Stheraven if (t > Maxcode) 2007227825Stheraven return codecvt_base::error; 2008227825Stheraven *to_nxt = static_cast<uint32_t>(t); 2009227825Stheraven frm_nxt += 2; 2010227825Stheraven } 2011227825Stheraven else if (c1 < 0xF0) 2012227825Stheraven { 2013227825Stheraven if (frm_end-frm_nxt < 3) 2014227825Stheraven return codecvt_base::partial; 2015227825Stheraven uint8_t c2 = frm_nxt[1]; 2016227825Stheraven uint8_t c3 = frm_nxt[2]; 2017227825Stheraven switch (c1) 2018227825Stheraven { 2019227825Stheraven case 0xE0: 2020227825Stheraven if ((c2 & 0xE0) != 0xA0) 2021227825Stheraven return codecvt_base::error; 2022227825Stheraven break; 2023227825Stheraven case 0xED: 2024227825Stheraven if ((c2 & 0xE0) != 0x80) 2025227825Stheraven return codecvt_base::error; 2026227825Stheraven break; 2027227825Stheraven default: 2028227825Stheraven if ((c2 & 0xC0) != 0x80) 2029227825Stheraven return codecvt_base::error; 2030227825Stheraven break; 2031227825Stheraven } 2032227825Stheraven if ((c3 & 0xC0) != 0x80) 2033227825Stheraven return codecvt_base::error; 2034227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 2035227825Stheraven | ((c2 & 0x3F) << 6) 2036227825Stheraven | (c3 & 0x3F)); 2037227825Stheraven if (t > Maxcode) 2038227825Stheraven return codecvt_base::error; 2039227825Stheraven *to_nxt = static_cast<uint32_t>(t); 2040227825Stheraven frm_nxt += 3; 2041227825Stheraven } 2042227825Stheraven else if (c1 < 0xF5) 2043227825Stheraven { 2044227825Stheraven if (frm_end-frm_nxt < 4) 2045227825Stheraven return codecvt_base::partial; 2046227825Stheraven uint8_t c2 = frm_nxt[1]; 2047227825Stheraven uint8_t c3 = frm_nxt[2]; 2048227825Stheraven uint8_t c4 = frm_nxt[3]; 2049227825Stheraven switch (c1) 2050227825Stheraven { 2051227825Stheraven case 0xF0: 2052227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2053227825Stheraven return codecvt_base::error; 2054227825Stheraven break; 2055227825Stheraven case 0xF4: 2056227825Stheraven if ((c2 & 0xF0) != 0x80) 2057227825Stheraven return codecvt_base::error; 2058227825Stheraven break; 2059227825Stheraven default: 2060227825Stheraven if ((c2 & 0xC0) != 0x80) 2061227825Stheraven return codecvt_base::error; 2062227825Stheraven break; 2063227825Stheraven } 2064227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2065227825Stheraven return codecvt_base::error; 2066227825Stheraven if (to_end-to_nxt < 2) 2067227825Stheraven return codecvt_base::partial; 2068227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 2069227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 2070227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 2071227825Stheraven return codecvt_base::error; 2072227825Stheraven *to_nxt = static_cast<uint32_t>( 2073227825Stheraven 0xD800 2074227825Stheraven | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) 2075227825Stheraven | ((c2 & 0x0F) << 2) 2076227825Stheraven | ((c3 & 0x30) >> 4)); 2077227825Stheraven *++to_nxt = static_cast<uint32_t>( 2078227825Stheraven 0xDC00 2079227825Stheraven | ((c3 & 0x0F) << 6) 2080227825Stheraven | (c4 & 0x3F)); 2081227825Stheraven frm_nxt += 4; 2082227825Stheraven } 2083227825Stheraven else 2084227825Stheraven { 2085227825Stheraven return codecvt_base::error; 2086227825Stheraven } 2087227825Stheraven } 2088227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2089227825Stheraven} 2090227825Stheraven 2091227825Stheravenstatic 2092227825Stheravenint 2093227825Stheravenutf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end, 2094227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2095227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2096227825Stheraven{ 2097227825Stheraven const uint8_t* frm_nxt = frm; 2098227825Stheraven if (mode & consume_header) 2099227825Stheraven { 2100227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2101227825Stheraven frm_nxt[2] == 0xBF) 2102227825Stheraven frm_nxt += 3; 2103227825Stheraven } 2104227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t) 2105227825Stheraven { 2106227825Stheraven uint8_t c1 = *frm_nxt; 2107227825Stheraven if (c1 > Maxcode) 2108227825Stheraven break; 2109227825Stheraven if (c1 < 0x80) 2110227825Stheraven { 2111227825Stheraven ++frm_nxt; 2112227825Stheraven } 2113227825Stheraven else if (c1 < 0xC2) 2114227825Stheraven { 2115227825Stheraven break; 2116227825Stheraven } 2117227825Stheraven else if (c1 < 0xE0) 2118227825Stheraven { 2119227825Stheraven if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80) 2120227825Stheraven break; 2121227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)); 2122227825Stheraven if (t > Maxcode) 2123227825Stheraven break; 2124227825Stheraven frm_nxt += 2; 2125227825Stheraven } 2126227825Stheraven else if (c1 < 0xF0) 2127227825Stheraven { 2128227825Stheraven if (frm_end-frm_nxt < 3) 2129227825Stheraven break; 2130227825Stheraven uint8_t c2 = frm_nxt[1]; 2131227825Stheraven uint8_t c3 = frm_nxt[2]; 2132227825Stheraven switch (c1) 2133227825Stheraven { 2134227825Stheraven case 0xE0: 2135227825Stheraven if ((c2 & 0xE0) != 0xA0) 2136227825Stheraven return static_cast<int>(frm_nxt - frm); 2137227825Stheraven break; 2138227825Stheraven case 0xED: 2139227825Stheraven if ((c2 & 0xE0) != 0x80) 2140227825Stheraven return static_cast<int>(frm_nxt - frm); 2141227825Stheraven break; 2142227825Stheraven default: 2143227825Stheraven if ((c2 & 0xC0) != 0x80) 2144227825Stheraven return static_cast<int>(frm_nxt - frm); 2145227825Stheraven break; 2146227825Stheraven } 2147227825Stheraven if ((c3 & 0xC0) != 0x80) 2148227825Stheraven break; 2149232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2150227825Stheraven break; 2151227825Stheraven frm_nxt += 3; 2152227825Stheraven } 2153227825Stheraven else if (c1 < 0xF5) 2154227825Stheraven { 2155227825Stheraven if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2) 2156227825Stheraven break; 2157227825Stheraven uint8_t c2 = frm_nxt[1]; 2158227825Stheraven uint8_t c3 = frm_nxt[2]; 2159227825Stheraven uint8_t c4 = frm_nxt[3]; 2160227825Stheraven switch (c1) 2161227825Stheraven { 2162227825Stheraven case 0xF0: 2163227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2164227825Stheraven return static_cast<int>(frm_nxt - frm); 2165227825Stheraven break; 2166227825Stheraven case 0xF4: 2167227825Stheraven if ((c2 & 0xF0) != 0x80) 2168227825Stheraven return static_cast<int>(frm_nxt - frm); 2169227825Stheraven break; 2170227825Stheraven default: 2171227825Stheraven if ((c2 & 0xC0) != 0x80) 2172227825Stheraven return static_cast<int>(frm_nxt - frm); 2173227825Stheraven break; 2174227825Stheraven } 2175227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2176227825Stheraven break; 2177227825Stheraven if (((((unsigned long)c1 & 7) << 18) + 2178227825Stheraven (((unsigned long)c2 & 0x3F) << 12) + 2179227825Stheraven (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode) 2180227825Stheraven break; 2181227825Stheraven ++nchar16_t; 2182227825Stheraven frm_nxt += 4; 2183227825Stheraven } 2184227825Stheraven else 2185227825Stheraven { 2186227825Stheraven break; 2187227825Stheraven } 2188227825Stheraven } 2189227825Stheraven return static_cast<int>(frm_nxt - frm); 2190227825Stheraven} 2191227825Stheraven 2192227825Stheravenstatic 2193227825Stheravencodecvt_base::result 2194227825Stheravenucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2195227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2196227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2197227825Stheraven{ 2198227825Stheraven frm_nxt = frm; 2199227825Stheraven to_nxt = to; 2200227825Stheraven if (mode & generate_header) 2201227825Stheraven { 2202227825Stheraven if (to_end-to_nxt < 3) 2203227825Stheraven return codecvt_base::partial; 2204227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 2205227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 2206227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 2207227825Stheraven } 2208227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2209227825Stheraven { 2210227825Stheraven uint32_t wc = *frm_nxt; 2211227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2212227825Stheraven return codecvt_base::error; 2213227825Stheraven if (wc < 0x000080) 2214227825Stheraven { 2215227825Stheraven if (to_end-to_nxt < 1) 2216227825Stheraven return codecvt_base::partial; 2217227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2218227825Stheraven } 2219227825Stheraven else if (wc < 0x000800) 2220227825Stheraven { 2221227825Stheraven if (to_end-to_nxt < 2) 2222227825Stheraven return codecvt_base::partial; 2223227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6)); 2224227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F)); 2225227825Stheraven } 2226227825Stheraven else if (wc < 0x010000) 2227227825Stheraven { 2228227825Stheraven if (to_end-to_nxt < 3) 2229227825Stheraven return codecvt_base::partial; 2230227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12)); 2231227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6)); 2232227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F)); 2233227825Stheraven } 2234227825Stheraven else // if (wc < 0x110000) 2235227825Stheraven { 2236227825Stheraven if (to_end-to_nxt < 4) 2237227825Stheraven return codecvt_base::partial; 2238227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18)); 2239227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12)); 2240227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6)); 2241227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F)); 2242227825Stheraven } 2243227825Stheraven } 2244227825Stheraven return codecvt_base::ok; 2245227825Stheraven} 2246227825Stheraven 2247227825Stheravenstatic 2248227825Stheravencodecvt_base::result 2249227825Stheravenutf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2250227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2251227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2252227825Stheraven{ 2253227825Stheraven frm_nxt = frm; 2254227825Stheraven to_nxt = to; 2255227825Stheraven if (mode & consume_header) 2256227825Stheraven { 2257227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2258227825Stheraven frm_nxt[2] == 0xBF) 2259227825Stheraven frm_nxt += 3; 2260227825Stheraven } 2261227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 2262227825Stheraven { 2263227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2264227825Stheraven if (c1 < 0x80) 2265227825Stheraven { 2266227825Stheraven if (c1 > Maxcode) 2267227825Stheraven return codecvt_base::error; 2268227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2269227825Stheraven ++frm_nxt; 2270227825Stheraven } 2271227825Stheraven else if (c1 < 0xC2) 2272227825Stheraven { 2273227825Stheraven return codecvt_base::error; 2274227825Stheraven } 2275227825Stheraven else if (c1 < 0xE0) 2276227825Stheraven { 2277227825Stheraven if (frm_end-frm_nxt < 2) 2278227825Stheraven return codecvt_base::partial; 2279227825Stheraven uint8_t c2 = frm_nxt[1]; 2280227825Stheraven if ((c2 & 0xC0) != 0x80) 2281227825Stheraven return codecvt_base::error; 2282227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) 2283227825Stheraven | (c2 & 0x3F)); 2284227825Stheraven if (t > Maxcode) 2285227825Stheraven return codecvt_base::error; 2286227825Stheraven *to_nxt = t; 2287227825Stheraven frm_nxt += 2; 2288227825Stheraven } 2289227825Stheraven else if (c1 < 0xF0) 2290227825Stheraven { 2291227825Stheraven if (frm_end-frm_nxt < 3) 2292227825Stheraven return codecvt_base::partial; 2293227825Stheraven uint8_t c2 = frm_nxt[1]; 2294227825Stheraven uint8_t c3 = frm_nxt[2]; 2295227825Stheraven switch (c1) 2296227825Stheraven { 2297227825Stheraven case 0xE0: 2298227825Stheraven if ((c2 & 0xE0) != 0xA0) 2299227825Stheraven return codecvt_base::error; 2300227825Stheraven break; 2301227825Stheraven case 0xED: 2302227825Stheraven if ((c2 & 0xE0) != 0x80) 2303227825Stheraven return codecvt_base::error; 2304227825Stheraven break; 2305227825Stheraven default: 2306227825Stheraven if ((c2 & 0xC0) != 0x80) 2307227825Stheraven return codecvt_base::error; 2308227825Stheraven break; 2309227825Stheraven } 2310227825Stheraven if ((c3 & 0xC0) != 0x80) 2311227825Stheraven return codecvt_base::error; 2312227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) 2313227825Stheraven | ((c2 & 0x3F) << 6) 2314227825Stheraven | (c3 & 0x3F)); 2315227825Stheraven if (t > Maxcode) 2316227825Stheraven return codecvt_base::error; 2317227825Stheraven *to_nxt = t; 2318227825Stheraven frm_nxt += 3; 2319227825Stheraven } 2320227825Stheraven else if (c1 < 0xF5) 2321227825Stheraven { 2322227825Stheraven if (frm_end-frm_nxt < 4) 2323227825Stheraven return codecvt_base::partial; 2324227825Stheraven uint8_t c2 = frm_nxt[1]; 2325227825Stheraven uint8_t c3 = frm_nxt[2]; 2326227825Stheraven uint8_t c4 = frm_nxt[3]; 2327227825Stheraven switch (c1) 2328227825Stheraven { 2329227825Stheraven case 0xF0: 2330227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2331227825Stheraven return codecvt_base::error; 2332227825Stheraven break; 2333227825Stheraven case 0xF4: 2334227825Stheraven if ((c2 & 0xF0) != 0x80) 2335227825Stheraven return codecvt_base::error; 2336227825Stheraven break; 2337227825Stheraven default: 2338227825Stheraven if ((c2 & 0xC0) != 0x80) 2339227825Stheraven return codecvt_base::error; 2340227825Stheraven break; 2341227825Stheraven } 2342227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2343227825Stheraven return codecvt_base::error; 2344227825Stheraven uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) 2345227825Stheraven | ((c2 & 0x3F) << 12) 2346227825Stheraven | ((c3 & 0x3F) << 6) 2347227825Stheraven | (c4 & 0x3F)); 2348227825Stheraven if (t > Maxcode) 2349227825Stheraven return codecvt_base::error; 2350227825Stheraven *to_nxt = t; 2351227825Stheraven frm_nxt += 4; 2352227825Stheraven } 2353227825Stheraven else 2354227825Stheraven { 2355227825Stheraven return codecvt_base::error; 2356227825Stheraven } 2357227825Stheraven } 2358227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2359227825Stheraven} 2360227825Stheraven 2361227825Stheravenstatic 2362227825Stheravenint 2363227825Stheravenutf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2364227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2365227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2366227825Stheraven{ 2367227825Stheraven const uint8_t* frm_nxt = frm; 2368227825Stheraven if (mode & consume_header) 2369227825Stheraven { 2370227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2371227825Stheraven frm_nxt[2] == 0xBF) 2372227825Stheraven frm_nxt += 3; 2373227825Stheraven } 2374227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) 2375227825Stheraven { 2376227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2377227825Stheraven if (c1 < 0x80) 2378227825Stheraven { 2379227825Stheraven if (c1 > Maxcode) 2380227825Stheraven break; 2381227825Stheraven ++frm_nxt; 2382227825Stheraven } 2383227825Stheraven else if (c1 < 0xC2) 2384227825Stheraven { 2385227825Stheraven break; 2386227825Stheraven } 2387227825Stheraven else if (c1 < 0xE0) 2388227825Stheraven { 2389227825Stheraven if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) 2390227825Stheraven break; 2391232950Stheraven if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) 2392227825Stheraven break; 2393227825Stheraven frm_nxt += 2; 2394227825Stheraven } 2395227825Stheraven else if (c1 < 0xF0) 2396227825Stheraven { 2397227825Stheraven if (frm_end-frm_nxt < 3) 2398227825Stheraven break; 2399227825Stheraven uint8_t c2 = frm_nxt[1]; 2400227825Stheraven uint8_t c3 = frm_nxt[2]; 2401227825Stheraven switch (c1) 2402227825Stheraven { 2403227825Stheraven case 0xE0: 2404227825Stheraven if ((c2 & 0xE0) != 0xA0) 2405227825Stheraven return static_cast<int>(frm_nxt - frm); 2406227825Stheraven break; 2407227825Stheraven case 0xED: 2408227825Stheraven if ((c2 & 0xE0) != 0x80) 2409227825Stheraven return static_cast<int>(frm_nxt - frm); 2410227825Stheraven break; 2411227825Stheraven default: 2412227825Stheraven if ((c2 & 0xC0) != 0x80) 2413227825Stheraven return static_cast<int>(frm_nxt - frm); 2414227825Stheraven break; 2415227825Stheraven } 2416227825Stheraven if ((c3 & 0xC0) != 0x80) 2417227825Stheraven break; 2418232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2419227825Stheraven break; 2420227825Stheraven frm_nxt += 3; 2421227825Stheraven } 2422227825Stheraven else if (c1 < 0xF5) 2423227825Stheraven { 2424227825Stheraven if (frm_end-frm_nxt < 4) 2425227825Stheraven break; 2426227825Stheraven uint8_t c2 = frm_nxt[1]; 2427227825Stheraven uint8_t c3 = frm_nxt[2]; 2428227825Stheraven uint8_t c4 = frm_nxt[3]; 2429227825Stheraven switch (c1) 2430227825Stheraven { 2431227825Stheraven case 0xF0: 2432227825Stheraven if (!(0x90 <= c2 && c2 <= 0xBF)) 2433227825Stheraven return static_cast<int>(frm_nxt - frm); 2434227825Stheraven break; 2435227825Stheraven case 0xF4: 2436227825Stheraven if ((c2 & 0xF0) != 0x80) 2437227825Stheraven return static_cast<int>(frm_nxt - frm); 2438227825Stheraven break; 2439227825Stheraven default: 2440227825Stheraven if ((c2 & 0xC0) != 0x80) 2441227825Stheraven return static_cast<int>(frm_nxt - frm); 2442227825Stheraven break; 2443227825Stheraven } 2444227825Stheraven if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80) 2445227825Stheraven break; 2446232950Stheraven if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | 2447232950Stheraven ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode) 2448227825Stheraven break; 2449227825Stheraven frm_nxt += 4; 2450227825Stheraven } 2451227825Stheraven else 2452227825Stheraven { 2453227825Stheraven break; 2454227825Stheraven } 2455227825Stheraven } 2456227825Stheraven return static_cast<int>(frm_nxt - frm); 2457227825Stheraven} 2458227825Stheraven 2459227825Stheravenstatic 2460227825Stheravencodecvt_base::result 2461227825Stheravenucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2462227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2463227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2464227825Stheraven{ 2465227825Stheraven frm_nxt = frm; 2466227825Stheraven to_nxt = to; 2467227825Stheraven if (mode & generate_header) 2468227825Stheraven { 2469227825Stheraven if (to_end-to_nxt < 3) 2470227825Stheraven return codecvt_base::partial; 2471227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xEF); 2472227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBB); 2473227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xBF); 2474227825Stheraven } 2475227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2476227825Stheraven { 2477227825Stheraven uint16_t wc = *frm_nxt; 2478227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2479227825Stheraven return codecvt_base::error; 2480227825Stheraven if (wc < 0x0080) 2481227825Stheraven { 2482227825Stheraven if (to_end-to_nxt < 1) 2483227825Stheraven return codecvt_base::partial; 2484227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2485227825Stheraven } 2486227825Stheraven else if (wc < 0x0800) 2487227825Stheraven { 2488227825Stheraven if (to_end-to_nxt < 2) 2489227825Stheraven return codecvt_base::partial; 2490227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6)); 2491227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F)); 2492227825Stheraven } 2493227825Stheraven else // if (wc <= 0xFFFF) 2494227825Stheraven { 2495227825Stheraven if (to_end-to_nxt < 3) 2496227825Stheraven return codecvt_base::partial; 2497227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12)); 2498227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6)); 2499227825Stheraven *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F)); 2500227825Stheraven } 2501227825Stheraven } 2502227825Stheraven return codecvt_base::ok; 2503227825Stheraven} 2504227825Stheraven 2505227825Stheravenstatic 2506227825Stheravencodecvt_base::result 2507227825Stheravenutf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2508227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2509227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2510227825Stheraven{ 2511227825Stheraven frm_nxt = frm; 2512227825Stheraven to_nxt = to; 2513227825Stheraven if (mode & consume_header) 2514227825Stheraven { 2515227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2516227825Stheraven frm_nxt[2] == 0xBF) 2517227825Stheraven frm_nxt += 3; 2518227825Stheraven } 2519227825Stheraven for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt) 2520227825Stheraven { 2521227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2522227825Stheraven if (c1 < 0x80) 2523227825Stheraven { 2524227825Stheraven if (c1 > Maxcode) 2525227825Stheraven return codecvt_base::error; 2526227825Stheraven *to_nxt = static_cast<uint16_t>(c1); 2527227825Stheraven ++frm_nxt; 2528227825Stheraven } 2529227825Stheraven else if (c1 < 0xC2) 2530227825Stheraven { 2531227825Stheraven return codecvt_base::error; 2532227825Stheraven } 2533227825Stheraven else if (c1 < 0xE0) 2534227825Stheraven { 2535227825Stheraven if (frm_end-frm_nxt < 2) 2536227825Stheraven return codecvt_base::partial; 2537227825Stheraven uint8_t c2 = frm_nxt[1]; 2538227825Stheraven if ((c2 & 0xC0) != 0x80) 2539227825Stheraven return codecvt_base::error; 2540227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) 2541227825Stheraven | (c2 & 0x3F)); 2542227825Stheraven if (t > Maxcode) 2543227825Stheraven return codecvt_base::error; 2544227825Stheraven *to_nxt = t; 2545227825Stheraven frm_nxt += 2; 2546227825Stheraven } 2547227825Stheraven else if (c1 < 0xF0) 2548227825Stheraven { 2549227825Stheraven if (frm_end-frm_nxt < 3) 2550227825Stheraven return codecvt_base::partial; 2551227825Stheraven uint8_t c2 = frm_nxt[1]; 2552227825Stheraven uint8_t c3 = frm_nxt[2]; 2553227825Stheraven switch (c1) 2554227825Stheraven { 2555227825Stheraven case 0xE0: 2556227825Stheraven if ((c2 & 0xE0) != 0xA0) 2557227825Stheraven return codecvt_base::error; 2558227825Stheraven break; 2559227825Stheraven case 0xED: 2560227825Stheraven if ((c2 & 0xE0) != 0x80) 2561227825Stheraven return codecvt_base::error; 2562227825Stheraven break; 2563227825Stheraven default: 2564227825Stheraven if ((c2 & 0xC0) != 0x80) 2565227825Stheraven return codecvt_base::error; 2566227825Stheraven break; 2567227825Stheraven } 2568227825Stheraven if ((c3 & 0xC0) != 0x80) 2569227825Stheraven return codecvt_base::error; 2570227825Stheraven uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) 2571227825Stheraven | ((c2 & 0x3F) << 6) 2572227825Stheraven | (c3 & 0x3F)); 2573227825Stheraven if (t > Maxcode) 2574227825Stheraven return codecvt_base::error; 2575227825Stheraven *to_nxt = t; 2576227825Stheraven frm_nxt += 3; 2577227825Stheraven } 2578227825Stheraven else 2579227825Stheraven { 2580227825Stheraven return codecvt_base::error; 2581227825Stheraven } 2582227825Stheraven } 2583227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2584227825Stheraven} 2585227825Stheraven 2586227825Stheravenstatic 2587227825Stheravenint 2588227825Stheravenutf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2589227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2590227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2591227825Stheraven{ 2592227825Stheraven const uint8_t* frm_nxt = frm; 2593227825Stheraven if (mode & consume_header) 2594227825Stheraven { 2595227825Stheraven if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && 2596227825Stheraven frm_nxt[2] == 0xBF) 2597227825Stheraven frm_nxt += 3; 2598227825Stheraven } 2599227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t) 2600227825Stheraven { 2601227825Stheraven uint8_t c1 = static_cast<uint8_t>(*frm_nxt); 2602227825Stheraven if (c1 < 0x80) 2603227825Stheraven { 2604227825Stheraven if (c1 > Maxcode) 2605227825Stheraven break; 2606227825Stheraven ++frm_nxt; 2607227825Stheraven } 2608227825Stheraven else if (c1 < 0xC2) 2609227825Stheraven { 2610227825Stheraven break; 2611227825Stheraven } 2612227825Stheraven else if (c1 < 0xE0) 2613227825Stheraven { 2614227825Stheraven if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80)) 2615227825Stheraven break; 2616232950Stheraven if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode) 2617227825Stheraven break; 2618227825Stheraven frm_nxt += 2; 2619227825Stheraven } 2620227825Stheraven else if (c1 < 0xF0) 2621227825Stheraven { 2622227825Stheraven if (frm_end-frm_nxt < 3) 2623227825Stheraven break; 2624227825Stheraven uint8_t c2 = frm_nxt[1]; 2625227825Stheraven uint8_t c3 = frm_nxt[2]; 2626227825Stheraven switch (c1) 2627227825Stheraven { 2628227825Stheraven case 0xE0: 2629227825Stheraven if ((c2 & 0xE0) != 0xA0) 2630227825Stheraven return static_cast<int>(frm_nxt - frm); 2631227825Stheraven break; 2632227825Stheraven case 0xED: 2633227825Stheraven if ((c2 & 0xE0) != 0x80) 2634227825Stheraven return static_cast<int>(frm_nxt - frm); 2635227825Stheraven break; 2636227825Stheraven default: 2637227825Stheraven if ((c2 & 0xC0) != 0x80) 2638227825Stheraven return static_cast<int>(frm_nxt - frm); 2639227825Stheraven break; 2640227825Stheraven } 2641227825Stheraven if ((c3 & 0xC0) != 0x80) 2642227825Stheraven break; 2643232950Stheraven if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode) 2644227825Stheraven break; 2645227825Stheraven frm_nxt += 3; 2646227825Stheraven } 2647227825Stheraven else 2648227825Stheraven { 2649227825Stheraven break; 2650227825Stheraven } 2651227825Stheraven } 2652227825Stheraven return static_cast<int>(frm_nxt - frm); 2653227825Stheraven} 2654227825Stheraven 2655227825Stheravenstatic 2656227825Stheravencodecvt_base::result 2657227825Stheravenucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2658227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2659227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2660227825Stheraven{ 2661227825Stheraven frm_nxt = frm; 2662227825Stheraven to_nxt = to; 2663227825Stheraven if (mode & generate_header) 2664227825Stheraven { 2665227825Stheraven if (to_end-to_nxt < 2) 2666227825Stheraven return codecvt_base::partial; 2667227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2668227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2669227825Stheraven } 2670227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2671227825Stheraven { 2672227825Stheraven uint32_t wc = *frm_nxt; 2673227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2674227825Stheraven return codecvt_base::error; 2675227825Stheraven if (wc < 0x010000) 2676227825Stheraven { 2677227825Stheraven if (to_end-to_nxt < 2) 2678227825Stheraven return codecvt_base::partial; 2679227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2680227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2681227825Stheraven } 2682227825Stheraven else 2683227825Stheraven { 2684227825Stheraven if (to_end-to_nxt < 4) 2685227825Stheraven return codecvt_base::partial; 2686227825Stheraven uint16_t t = static_cast<uint16_t>( 2687227825Stheraven 0xD800 2688227825Stheraven | ((((wc & 0x1F0000) >> 16) - 1) << 6) 2689227825Stheraven | ((wc & 0x00FC00) >> 10)); 2690227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2691227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2692227825Stheraven t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF)); 2693227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2694227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2695227825Stheraven } 2696227825Stheraven } 2697227825Stheraven return codecvt_base::ok; 2698227825Stheraven} 2699227825Stheraven 2700227825Stheravenstatic 2701227825Stheravencodecvt_base::result 2702227825Stheravenutf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2703227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2704227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2705227825Stheraven{ 2706227825Stheraven frm_nxt = frm; 2707227825Stheraven to_nxt = to; 2708227825Stheraven if (mode & consume_header) 2709227825Stheraven { 2710227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2711227825Stheraven frm_nxt += 2; 2712227825Stheraven } 2713227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2714227825Stheraven { 2715232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2716227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2717227825Stheraven return codecvt_base::error; 2718227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2719227825Stheraven { 2720227825Stheraven if (c1 > Maxcode) 2721227825Stheraven return codecvt_base::error; 2722227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2723227825Stheraven frm_nxt += 2; 2724227825Stheraven } 2725227825Stheraven else 2726227825Stheraven { 2727227825Stheraven if (frm_end-frm_nxt < 4) 2728227825Stheraven return codecvt_base::partial; 2729232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]); 2730227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2731227825Stheraven return codecvt_base::error; 2732227825Stheraven uint32_t t = static_cast<uint32_t>( 2733227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2734227825Stheraven | ((c1 & 0x003F) << 10) 2735227825Stheraven | (c2 & 0x03FF)); 2736227825Stheraven if (t > Maxcode) 2737227825Stheraven return codecvt_base::error; 2738227825Stheraven *to_nxt = t; 2739227825Stheraven frm_nxt += 4; 2740227825Stheraven } 2741227825Stheraven } 2742227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2743227825Stheraven} 2744227825Stheraven 2745227825Stheravenstatic 2746227825Stheravenint 2747227825Stheravenutf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2748227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2749227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2750227825Stheraven{ 2751227825Stheraven const uint8_t* frm_nxt = frm; 2752227825Stheraven if (mode & consume_header) 2753227825Stheraven { 2754227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2755227825Stheraven frm_nxt += 2; 2756227825Stheraven } 2757227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) 2758227825Stheraven { 2759232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2760227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2761227825Stheraven break; 2762227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2763227825Stheraven { 2764227825Stheraven if (c1 > Maxcode) 2765227825Stheraven break; 2766227825Stheraven frm_nxt += 2; 2767227825Stheraven } 2768227825Stheraven else 2769227825Stheraven { 2770227825Stheraven if (frm_end-frm_nxt < 4) 2771227825Stheraven break; 2772232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]); 2773227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2774227825Stheraven break; 2775227825Stheraven uint32_t t = static_cast<uint32_t>( 2776227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2777227825Stheraven | ((c1 & 0x003F) << 10) 2778227825Stheraven | (c2 & 0x03FF)); 2779227825Stheraven if (t > Maxcode) 2780227825Stheraven break; 2781227825Stheraven frm_nxt += 4; 2782227825Stheraven } 2783227825Stheraven } 2784227825Stheraven return static_cast<int>(frm_nxt - frm); 2785227825Stheraven} 2786227825Stheraven 2787227825Stheravenstatic 2788227825Stheravencodecvt_base::result 2789227825Stheravenucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt, 2790227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2791227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2792227825Stheraven{ 2793227825Stheraven frm_nxt = frm; 2794227825Stheraven to_nxt = to; 2795227825Stheraven if (mode & generate_header) 2796227825Stheraven { 2797227825Stheraven if (to_end-to_nxt < 2) 2798227825Stheraven return codecvt_base::partial; 2799227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2800227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2801227825Stheraven } 2802227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2803227825Stheraven { 2804227825Stheraven uint32_t wc = *frm_nxt; 2805227825Stheraven if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode) 2806227825Stheraven return codecvt_base::error; 2807227825Stheraven if (wc < 0x010000) 2808227825Stheraven { 2809227825Stheraven if (to_end-to_nxt < 2) 2810227825Stheraven return codecvt_base::partial; 2811227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2812227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2813227825Stheraven } 2814227825Stheraven else 2815227825Stheraven { 2816227825Stheraven if (to_end-to_nxt < 4) 2817227825Stheraven return codecvt_base::partial; 2818227825Stheraven uint16_t t = static_cast<uint16_t>( 2819227825Stheraven 0xD800 2820227825Stheraven | ((((wc & 0x1F0000) >> 16) - 1) << 6) 2821227825Stheraven | ((wc & 0x00FC00) >> 10)); 2822227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2823227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2824227825Stheraven t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF)); 2825227825Stheraven *to_nxt++ = static_cast<uint8_t>(t); 2826227825Stheraven *to_nxt++ = static_cast<uint8_t>(t >> 8); 2827227825Stheraven } 2828227825Stheraven } 2829227825Stheraven return codecvt_base::ok; 2830227825Stheraven} 2831227825Stheraven 2832227825Stheravenstatic 2833227825Stheravencodecvt_base::result 2834227825Stheravenutf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2835227825Stheraven uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt, 2836227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2837227825Stheraven{ 2838227825Stheraven frm_nxt = frm; 2839227825Stheraven to_nxt = to; 2840227825Stheraven if (mode & consume_header) 2841227825Stheraven { 2842227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2843227825Stheraven frm_nxt += 2; 2844227825Stheraven } 2845227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2846227825Stheraven { 2847232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2848227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2849227825Stheraven return codecvt_base::error; 2850227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2851227825Stheraven { 2852227825Stheraven if (c1 > Maxcode) 2853227825Stheraven return codecvt_base::error; 2854227825Stheraven *to_nxt = static_cast<uint32_t>(c1); 2855227825Stheraven frm_nxt += 2; 2856227825Stheraven } 2857227825Stheraven else 2858227825Stheraven { 2859227825Stheraven if (frm_end-frm_nxt < 4) 2860227825Stheraven return codecvt_base::partial; 2861232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]); 2862227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2863227825Stheraven return codecvt_base::error; 2864227825Stheraven uint32_t t = static_cast<uint32_t>( 2865227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2866227825Stheraven | ((c1 & 0x003F) << 10) 2867227825Stheraven | (c2 & 0x03FF)); 2868227825Stheraven if (t > Maxcode) 2869227825Stheraven return codecvt_base::error; 2870227825Stheraven *to_nxt = t; 2871227825Stheraven frm_nxt += 4; 2872227825Stheraven } 2873227825Stheraven } 2874227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2875227825Stheraven} 2876227825Stheraven 2877227825Stheravenstatic 2878227825Stheravenint 2879227825Stheravenutf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, 2880227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2881227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2882227825Stheraven{ 2883227825Stheraven const uint8_t* frm_nxt = frm; 2884227825Stheraven if (mode & consume_header) 2885227825Stheraven { 2886227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 2887227825Stheraven frm_nxt += 2; 2888227825Stheraven } 2889227825Stheraven for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t) 2890227825Stheraven { 2891232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 2892227825Stheraven if ((c1 & 0xFC00) == 0xDC00) 2893227825Stheraven break; 2894227825Stheraven if ((c1 & 0xFC00) != 0xD800) 2895227825Stheraven { 2896227825Stheraven if (c1 > Maxcode) 2897227825Stheraven break; 2898227825Stheraven frm_nxt += 2; 2899227825Stheraven } 2900227825Stheraven else 2901227825Stheraven { 2902227825Stheraven if (frm_end-frm_nxt < 4) 2903227825Stheraven break; 2904232950Stheraven uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]); 2905227825Stheraven if ((c2 & 0xFC00) != 0xDC00) 2906227825Stheraven break; 2907227825Stheraven uint32_t t = static_cast<uint32_t>( 2908227825Stheraven ((((c1 & 0x03C0) >> 6) + 1) << 16) 2909227825Stheraven | ((c1 & 0x003F) << 10) 2910227825Stheraven | (c2 & 0x03FF)); 2911227825Stheraven if (t > Maxcode) 2912227825Stheraven break; 2913227825Stheraven frm_nxt += 4; 2914227825Stheraven } 2915227825Stheraven } 2916227825Stheraven return static_cast<int>(frm_nxt - frm); 2917227825Stheraven} 2918227825Stheraven 2919227825Stheravenstatic 2920227825Stheravencodecvt_base::result 2921227825Stheravenucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2922227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2923227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2924227825Stheraven{ 2925227825Stheraven frm_nxt = frm; 2926227825Stheraven to_nxt = to; 2927227825Stheraven if (mode & generate_header) 2928227825Stheraven { 2929227825Stheraven if (to_end-to_nxt < 2) 2930227825Stheraven return codecvt_base::partial; 2931227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 2932227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 2933227825Stheraven } 2934227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 2935227825Stheraven { 2936227825Stheraven uint16_t wc = *frm_nxt; 2937227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 2938227825Stheraven return codecvt_base::error; 2939227825Stheraven if (to_end-to_nxt < 2) 2940227825Stheraven return codecvt_base::partial; 2941227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 2942227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 2943227825Stheraven } 2944227825Stheraven return codecvt_base::ok; 2945227825Stheraven} 2946227825Stheraven 2947227825Stheravenstatic 2948227825Stheravencodecvt_base::result 2949227825Stheravenutf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 2950227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 2951227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2952227825Stheraven{ 2953227825Stheraven frm_nxt = frm; 2954227825Stheraven to_nxt = to; 2955227825Stheraven if (mode & consume_header) 2956227825Stheraven { 2957227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2958227825Stheraven frm_nxt += 2; 2959227825Stheraven } 2960227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 2961227825Stheraven { 2962232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2963227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2964227825Stheraven return codecvt_base::error; 2965227825Stheraven *to_nxt = c1; 2966227825Stheraven frm_nxt += 2; 2967227825Stheraven } 2968227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 2969227825Stheraven} 2970227825Stheraven 2971227825Stheravenstatic 2972227825Stheravenint 2973227825Stheravenutf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 2974227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 2975227825Stheraven codecvt_mode mode = codecvt_mode(0)) 2976227825Stheraven{ 2977227825Stheraven const uint8_t* frm_nxt = frm; 2978227825Stheraven if (mode & consume_header) 2979227825Stheraven { 2980227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) 2981227825Stheraven frm_nxt += 2; 2982227825Stheraven } 2983227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) 2984227825Stheraven { 2985232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]); 2986227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 2987227825Stheraven break; 2988227825Stheraven frm_nxt += 2; 2989227825Stheraven } 2990227825Stheraven return static_cast<int>(frm_nxt - frm); 2991227825Stheraven} 2992227825Stheraven 2993227825Stheravenstatic 2994227825Stheravencodecvt_base::result 2995227825Stheravenucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, 2996227825Stheraven uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt, 2997227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 2998227825Stheraven{ 2999227825Stheraven frm_nxt = frm; 3000227825Stheraven to_nxt = to; 3001227825Stheraven if (mode & generate_header) 3002227825Stheraven { 3003227825Stheraven if (to_end-to_nxt < 2) 3004227825Stheraven return codecvt_base::partial; 3005227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFF); 3006227825Stheraven *to_nxt++ = static_cast<uint8_t>(0xFE); 3007227825Stheraven } 3008227825Stheraven for (; frm_nxt < frm_end; ++frm_nxt) 3009227825Stheraven { 3010227825Stheraven uint16_t wc = *frm_nxt; 3011227825Stheraven if ((wc & 0xF800) == 0xD800 || wc > Maxcode) 3012227825Stheraven return codecvt_base::error; 3013227825Stheraven if (to_end-to_nxt < 2) 3014227825Stheraven return codecvt_base::partial; 3015227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc); 3016227825Stheraven *to_nxt++ = static_cast<uint8_t>(wc >> 8); 3017227825Stheraven } 3018227825Stheraven return codecvt_base::ok; 3019227825Stheraven} 3020227825Stheraven 3021227825Stheravenstatic 3022227825Stheravencodecvt_base::result 3023227825Stheravenutf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt, 3024227825Stheraven uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt, 3025227825Stheraven unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0)) 3026227825Stheraven{ 3027227825Stheraven frm_nxt = frm; 3028227825Stheraven to_nxt = to; 3029227825Stheraven if (mode & consume_header) 3030227825Stheraven { 3031227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 3032227825Stheraven frm_nxt += 2; 3033227825Stheraven } 3034227825Stheraven for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt) 3035227825Stheraven { 3036232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 3037227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 3038227825Stheraven return codecvt_base::error; 3039227825Stheraven *to_nxt = c1; 3040227825Stheraven frm_nxt += 2; 3041227825Stheraven } 3042227825Stheraven return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok; 3043227825Stheraven} 3044227825Stheraven 3045227825Stheravenstatic 3046227825Stheravenint 3047227825Stheravenutf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, 3048227825Stheraven size_t mx, unsigned long Maxcode = 0x10FFFF, 3049227825Stheraven codecvt_mode mode = codecvt_mode(0)) 3050227825Stheraven{ 3051227825Stheraven const uint8_t* frm_nxt = frm; 3052227825Stheraven frm_nxt = frm; 3053227825Stheraven if (mode & consume_header) 3054227825Stheraven { 3055227825Stheraven if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) 3056227825Stheraven frm_nxt += 2; 3057227825Stheraven } 3058227825Stheraven for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t) 3059227825Stheraven { 3060232950Stheraven uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]); 3061227825Stheraven if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode) 3062227825Stheraven break; 3063227825Stheraven frm_nxt += 2; 3064227825Stheraven } 3065227825Stheraven return static_cast<int>(frm_nxt - frm); 3066227825Stheraven} 3067227825Stheraven 3068227825Stheraven// template <> class codecvt<char16_t, char, mbstate_t> 3069227825Stheraven 3070227825Stheravenlocale::id codecvt<char16_t, char, mbstate_t>::id; 3071227825Stheraven 3072227825Stheravencodecvt<char16_t, char, mbstate_t>::~codecvt() 3073227825Stheraven{ 3074227825Stheraven} 3075227825Stheraven 3076227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3077227825Stheravencodecvt<char16_t, char, mbstate_t>::do_out(state_type&, 3078227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3079227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3080227825Stheraven{ 3081227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3082227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3083227825Stheraven const uint16_t* _frm_nxt = _frm; 3084227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3085227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3086227825Stheraven uint8_t* _to_nxt = _to; 3087227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3088227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3089227825Stheraven to_nxt = to + (_to_nxt - _to); 3090227825Stheraven return r; 3091227825Stheraven} 3092227825Stheraven 3093227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3094227825Stheravencodecvt<char16_t, char, mbstate_t>::do_in(state_type&, 3095227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3096227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3097227825Stheraven{ 3098227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3099227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3100227825Stheraven const uint8_t* _frm_nxt = _frm; 3101227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3102227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3103227825Stheraven uint16_t* _to_nxt = _to; 3104227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3105227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3106227825Stheraven to_nxt = to + (_to_nxt - _to); 3107227825Stheraven return r; 3108227825Stheraven} 3109227825Stheraven 3110227825Stheravencodecvt<char16_t, char, mbstate_t>::result 3111227825Stheravencodecvt<char16_t, char, mbstate_t>::do_unshift(state_type&, 3112227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3113227825Stheraven{ 3114227825Stheraven to_nxt = to; 3115227825Stheraven return noconv; 3116227825Stheraven} 3117227825Stheraven 3118227825Stheravenint 3119227825Stheravencodecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 3120227825Stheraven{ 3121227825Stheraven return 0; 3122227825Stheraven} 3123227825Stheraven 3124227825Stheravenbool 3125227825Stheravencodecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 3126227825Stheraven{ 3127227825Stheraven return false; 3128227825Stheraven} 3129227825Stheraven 3130227825Stheravenint 3131227825Stheravencodecvt<char16_t, char, mbstate_t>::do_length(state_type&, 3132227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3133227825Stheraven{ 3134227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3135227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3136227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx); 3137227825Stheraven} 3138227825Stheraven 3139227825Stheravenint 3140227825Stheravencodecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 3141227825Stheraven{ 3142227825Stheraven return 4; 3143227825Stheraven} 3144227825Stheraven 3145227825Stheraven// template <> class codecvt<char32_t, char, mbstate_t> 3146227825Stheraven 3147227825Stheravenlocale::id codecvt<char32_t, char, mbstate_t>::id; 3148227825Stheraven 3149227825Stheravencodecvt<char32_t, char, mbstate_t>::~codecvt() 3150227825Stheraven{ 3151227825Stheraven} 3152227825Stheraven 3153227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3154227825Stheravencodecvt<char32_t, char, mbstate_t>::do_out(state_type&, 3155227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3156227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3157227825Stheraven{ 3158227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3159227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3160227825Stheraven const uint32_t* _frm_nxt = _frm; 3161227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3162227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3163227825Stheraven uint8_t* _to_nxt = _to; 3164227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3165227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3166227825Stheraven to_nxt = to + (_to_nxt - _to); 3167227825Stheraven return r; 3168227825Stheraven} 3169227825Stheraven 3170227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3171227825Stheravencodecvt<char32_t, char, mbstate_t>::do_in(state_type&, 3172227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3173227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3174227825Stheraven{ 3175227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3176227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3177227825Stheraven const uint8_t* _frm_nxt = _frm; 3178227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3179227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3180227825Stheraven uint32_t* _to_nxt = _to; 3181227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt); 3182227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3183227825Stheraven to_nxt = to + (_to_nxt - _to); 3184227825Stheraven return r; 3185227825Stheraven} 3186227825Stheraven 3187227825Stheravencodecvt<char32_t, char, mbstate_t>::result 3188227825Stheravencodecvt<char32_t, char, mbstate_t>::do_unshift(state_type&, 3189227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3190227825Stheraven{ 3191227825Stheraven to_nxt = to; 3192227825Stheraven return noconv; 3193227825Stheraven} 3194227825Stheraven 3195227825Stheravenint 3196227825Stheravencodecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT 3197227825Stheraven{ 3198227825Stheraven return 0; 3199227825Stheraven} 3200227825Stheraven 3201227825Stheravenbool 3202227825Stheravencodecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT 3203227825Stheraven{ 3204227825Stheraven return false; 3205227825Stheraven} 3206227825Stheraven 3207227825Stheravenint 3208227825Stheravencodecvt<char32_t, char, mbstate_t>::do_length(state_type&, 3209227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3210227825Stheraven{ 3211227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3212227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3213227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx); 3214227825Stheraven} 3215227825Stheraven 3216227825Stheravenint 3217227825Stheravencodecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT 3218227825Stheraven{ 3219227825Stheraven return 4; 3220227825Stheraven} 3221227825Stheraven 3222227825Stheraven// __codecvt_utf8<wchar_t> 3223227825Stheraven 3224227825Stheraven__codecvt_utf8<wchar_t>::result 3225227825Stheraven__codecvt_utf8<wchar_t>::do_out(state_type&, 3226227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3227227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3228227825Stheraven{ 3229262801Sdim#if _WIN32 3230262801Sdim const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3231262801Sdim const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3232262801Sdim const uint16_t* _frm_nxt = _frm; 3233262801Sdim#else 3234227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3235227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3236227825Stheraven const uint32_t* _frm_nxt = _frm; 3237262801Sdim#endif 3238227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3239227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3240227825Stheraven uint8_t* _to_nxt = _to; 3241262801Sdim#if _WIN32 3242262801Sdim result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3243262801Sdim _Maxcode_, _Mode_); 3244262801Sdim#else 3245227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3246227825Stheraven _Maxcode_, _Mode_); 3247262801Sdim#endif 3248227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3249227825Stheraven to_nxt = to + (_to_nxt - _to); 3250227825Stheraven return r; 3251227825Stheraven} 3252227825Stheraven 3253227825Stheraven__codecvt_utf8<wchar_t>::result 3254227825Stheraven__codecvt_utf8<wchar_t>::do_in(state_type&, 3255227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3256227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3257227825Stheraven{ 3258227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3259227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3260227825Stheraven const uint8_t* _frm_nxt = _frm; 3261262801Sdim#if _WIN32 3262262801Sdim uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3263262801Sdim uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3264262801Sdim uint16_t* _to_nxt = _to; 3265262801Sdim result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3266262801Sdim _Maxcode_, _Mode_); 3267262801Sdim#else 3268227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3269227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3270227825Stheraven uint32_t* _to_nxt = _to; 3271227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3272227825Stheraven _Maxcode_, _Mode_); 3273262801Sdim#endif 3274227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3275227825Stheraven to_nxt = to + (_to_nxt - _to); 3276227825Stheraven return r; 3277227825Stheraven} 3278227825Stheraven 3279227825Stheraven__codecvt_utf8<wchar_t>::result 3280227825Stheraven__codecvt_utf8<wchar_t>::do_unshift(state_type&, 3281227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3282227825Stheraven{ 3283227825Stheraven to_nxt = to; 3284227825Stheraven return noconv; 3285227825Stheraven} 3286227825Stheraven 3287227825Stheravenint 3288227825Stheraven__codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT 3289227825Stheraven{ 3290227825Stheraven return 0; 3291227825Stheraven} 3292227825Stheraven 3293227825Stheravenbool 3294227825Stheraven__codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT 3295227825Stheraven{ 3296227825Stheraven return false; 3297227825Stheraven} 3298227825Stheraven 3299227825Stheravenint 3300227825Stheraven__codecvt_utf8<wchar_t>::do_length(state_type&, 3301227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3302227825Stheraven{ 3303227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3304227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3305227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3306227825Stheraven} 3307227825Stheraven 3308227825Stheravenint 3309227825Stheraven__codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT 3310227825Stheraven{ 3311227825Stheraven if (_Mode_ & consume_header) 3312227825Stheraven return 7; 3313227825Stheraven return 4; 3314227825Stheraven} 3315227825Stheraven 3316227825Stheraven// __codecvt_utf8<char16_t> 3317227825Stheraven 3318227825Stheraven__codecvt_utf8<char16_t>::result 3319227825Stheraven__codecvt_utf8<char16_t>::do_out(state_type&, 3320227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3321227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3322227825Stheraven{ 3323227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3324227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3325227825Stheraven const uint16_t* _frm_nxt = _frm; 3326227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3327227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3328227825Stheraven uint8_t* _to_nxt = _to; 3329227825Stheraven result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3330227825Stheraven _Maxcode_, _Mode_); 3331227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3332227825Stheraven to_nxt = to + (_to_nxt - _to); 3333227825Stheraven return r; 3334227825Stheraven} 3335227825Stheraven 3336227825Stheraven__codecvt_utf8<char16_t>::result 3337227825Stheraven__codecvt_utf8<char16_t>::do_in(state_type&, 3338227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3339227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3340227825Stheraven{ 3341227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3342227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3343227825Stheraven const uint8_t* _frm_nxt = _frm; 3344227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3345227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3346227825Stheraven uint16_t* _to_nxt = _to; 3347227825Stheraven result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3348227825Stheraven _Maxcode_, _Mode_); 3349227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3350227825Stheraven to_nxt = to + (_to_nxt - _to); 3351227825Stheraven return r; 3352227825Stheraven} 3353227825Stheraven 3354227825Stheraven__codecvt_utf8<char16_t>::result 3355227825Stheraven__codecvt_utf8<char16_t>::do_unshift(state_type&, 3356227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3357227825Stheraven{ 3358227825Stheraven to_nxt = to; 3359227825Stheraven return noconv; 3360227825Stheraven} 3361227825Stheraven 3362227825Stheravenint 3363227825Stheraven__codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT 3364227825Stheraven{ 3365227825Stheraven return 0; 3366227825Stheraven} 3367227825Stheraven 3368227825Stheravenbool 3369227825Stheraven__codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT 3370227825Stheraven{ 3371227825Stheraven return false; 3372227825Stheraven} 3373227825Stheraven 3374227825Stheravenint 3375227825Stheraven__codecvt_utf8<char16_t>::do_length(state_type&, 3376227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3377227825Stheraven{ 3378227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3379227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3380227825Stheraven return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3381227825Stheraven} 3382227825Stheraven 3383227825Stheravenint 3384227825Stheraven__codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT 3385227825Stheraven{ 3386227825Stheraven if (_Mode_ & consume_header) 3387227825Stheraven return 6; 3388227825Stheraven return 3; 3389227825Stheraven} 3390227825Stheraven 3391227825Stheraven// __codecvt_utf8<char32_t> 3392227825Stheraven 3393227825Stheraven__codecvt_utf8<char32_t>::result 3394227825Stheraven__codecvt_utf8<char32_t>::do_out(state_type&, 3395227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3396227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3397227825Stheraven{ 3398227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3399227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3400227825Stheraven const uint32_t* _frm_nxt = _frm; 3401227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3402227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3403227825Stheraven uint8_t* _to_nxt = _to; 3404227825Stheraven result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3405227825Stheraven _Maxcode_, _Mode_); 3406227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3407227825Stheraven to_nxt = to + (_to_nxt - _to); 3408227825Stheraven return r; 3409227825Stheraven} 3410227825Stheraven 3411227825Stheraven__codecvt_utf8<char32_t>::result 3412227825Stheraven__codecvt_utf8<char32_t>::do_in(state_type&, 3413227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3414227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3415227825Stheraven{ 3416227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3417227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3418227825Stheraven const uint8_t* _frm_nxt = _frm; 3419227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3420227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3421227825Stheraven uint32_t* _to_nxt = _to; 3422227825Stheraven result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3423227825Stheraven _Maxcode_, _Mode_); 3424227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3425227825Stheraven to_nxt = to + (_to_nxt - _to); 3426227825Stheraven return r; 3427227825Stheraven} 3428227825Stheraven 3429227825Stheraven__codecvt_utf8<char32_t>::result 3430227825Stheraven__codecvt_utf8<char32_t>::do_unshift(state_type&, 3431227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3432227825Stheraven{ 3433227825Stheraven to_nxt = to; 3434227825Stheraven return noconv; 3435227825Stheraven} 3436227825Stheraven 3437227825Stheravenint 3438227825Stheraven__codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT 3439227825Stheraven{ 3440227825Stheraven return 0; 3441227825Stheraven} 3442227825Stheraven 3443227825Stheravenbool 3444227825Stheraven__codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT 3445227825Stheraven{ 3446227825Stheraven return false; 3447227825Stheraven} 3448227825Stheraven 3449227825Stheravenint 3450227825Stheraven__codecvt_utf8<char32_t>::do_length(state_type&, 3451227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3452227825Stheraven{ 3453227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3454227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3455227825Stheraven return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3456227825Stheraven} 3457227825Stheraven 3458227825Stheravenint 3459227825Stheraven__codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT 3460227825Stheraven{ 3461227825Stheraven if (_Mode_ & consume_header) 3462227825Stheraven return 7; 3463227825Stheraven return 4; 3464227825Stheraven} 3465227825Stheraven 3466227825Stheraven// __codecvt_utf16<wchar_t, false> 3467227825Stheraven 3468227825Stheraven__codecvt_utf16<wchar_t, false>::result 3469227825Stheraven__codecvt_utf16<wchar_t, false>::do_out(state_type&, 3470227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3471227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3472227825Stheraven{ 3473227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3474227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3475227825Stheraven const uint32_t* _frm_nxt = _frm; 3476227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3477227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3478227825Stheraven uint8_t* _to_nxt = _to; 3479227825Stheraven result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3480227825Stheraven _Maxcode_, _Mode_); 3481227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3482227825Stheraven to_nxt = to + (_to_nxt - _to); 3483227825Stheraven return r; 3484227825Stheraven} 3485227825Stheraven 3486227825Stheraven__codecvt_utf16<wchar_t, false>::result 3487227825Stheraven__codecvt_utf16<wchar_t, false>::do_in(state_type&, 3488227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3489227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3490227825Stheraven{ 3491227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3492227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3493227825Stheraven const uint8_t* _frm_nxt = _frm; 3494227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3495227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3496227825Stheraven uint32_t* _to_nxt = _to; 3497227825Stheraven result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3498227825Stheraven _Maxcode_, _Mode_); 3499227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3500227825Stheraven to_nxt = to + (_to_nxt - _to); 3501227825Stheraven return r; 3502227825Stheraven} 3503227825Stheraven 3504227825Stheraven__codecvt_utf16<wchar_t, false>::result 3505227825Stheraven__codecvt_utf16<wchar_t, false>::do_unshift(state_type&, 3506227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3507227825Stheraven{ 3508227825Stheraven to_nxt = to; 3509227825Stheraven return noconv; 3510227825Stheraven} 3511227825Stheraven 3512227825Stheravenint 3513227825Stheraven__codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT 3514227825Stheraven{ 3515227825Stheraven return 0; 3516227825Stheraven} 3517227825Stheraven 3518227825Stheravenbool 3519227825Stheraven__codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT 3520227825Stheraven{ 3521227825Stheraven return false; 3522227825Stheraven} 3523227825Stheraven 3524227825Stheravenint 3525227825Stheraven__codecvt_utf16<wchar_t, false>::do_length(state_type&, 3526227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3527227825Stheraven{ 3528227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3529227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3530227825Stheraven return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3531227825Stheraven} 3532227825Stheraven 3533227825Stheravenint 3534227825Stheraven__codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT 3535227825Stheraven{ 3536227825Stheraven if (_Mode_ & consume_header) 3537227825Stheraven return 6; 3538227825Stheraven return 4; 3539227825Stheraven} 3540227825Stheraven 3541227825Stheraven// __codecvt_utf16<wchar_t, true> 3542227825Stheraven 3543227825Stheraven__codecvt_utf16<wchar_t, true>::result 3544227825Stheraven__codecvt_utf16<wchar_t, true>::do_out(state_type&, 3545227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3546227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3547227825Stheraven{ 3548227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3549227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3550227825Stheraven const uint32_t* _frm_nxt = _frm; 3551227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3552227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3553227825Stheraven uint8_t* _to_nxt = _to; 3554227825Stheraven result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3555227825Stheraven _Maxcode_, _Mode_); 3556227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3557227825Stheraven to_nxt = to + (_to_nxt - _to); 3558227825Stheraven return r; 3559227825Stheraven} 3560227825Stheraven 3561227825Stheraven__codecvt_utf16<wchar_t, true>::result 3562227825Stheraven__codecvt_utf16<wchar_t, true>::do_in(state_type&, 3563227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3564227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3565227825Stheraven{ 3566227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3567227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3568227825Stheraven const uint8_t* _frm_nxt = _frm; 3569227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3570227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3571227825Stheraven uint32_t* _to_nxt = _to; 3572227825Stheraven result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3573227825Stheraven _Maxcode_, _Mode_); 3574227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3575227825Stheraven to_nxt = to + (_to_nxt - _to); 3576227825Stheraven return r; 3577227825Stheraven} 3578227825Stheraven 3579227825Stheraven__codecvt_utf16<wchar_t, true>::result 3580227825Stheraven__codecvt_utf16<wchar_t, true>::do_unshift(state_type&, 3581227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3582227825Stheraven{ 3583227825Stheraven to_nxt = to; 3584227825Stheraven return noconv; 3585227825Stheraven} 3586227825Stheraven 3587227825Stheravenint 3588227825Stheraven__codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT 3589227825Stheraven{ 3590227825Stheraven return 0; 3591227825Stheraven} 3592227825Stheraven 3593227825Stheravenbool 3594227825Stheraven__codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT 3595227825Stheraven{ 3596227825Stheraven return false; 3597227825Stheraven} 3598227825Stheraven 3599227825Stheravenint 3600227825Stheraven__codecvt_utf16<wchar_t, true>::do_length(state_type&, 3601227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3602227825Stheraven{ 3603227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3604227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3605227825Stheraven return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3606227825Stheraven} 3607227825Stheraven 3608227825Stheravenint 3609227825Stheraven__codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT 3610227825Stheraven{ 3611227825Stheraven if (_Mode_ & consume_header) 3612227825Stheraven return 6; 3613227825Stheraven return 4; 3614227825Stheraven} 3615227825Stheraven 3616227825Stheraven// __codecvt_utf16<char16_t, false> 3617227825Stheraven 3618227825Stheraven__codecvt_utf16<char16_t, false>::result 3619227825Stheraven__codecvt_utf16<char16_t, false>::do_out(state_type&, 3620227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3621227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3622227825Stheraven{ 3623227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3624227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3625227825Stheraven const uint16_t* _frm_nxt = _frm; 3626227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3627227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3628227825Stheraven uint8_t* _to_nxt = _to; 3629227825Stheraven result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3630227825Stheraven _Maxcode_, _Mode_); 3631227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3632227825Stheraven to_nxt = to + (_to_nxt - _to); 3633227825Stheraven return r; 3634227825Stheraven} 3635227825Stheraven 3636227825Stheraven__codecvt_utf16<char16_t, false>::result 3637227825Stheraven__codecvt_utf16<char16_t, false>::do_in(state_type&, 3638227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3639227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3640227825Stheraven{ 3641227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3642227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3643227825Stheraven const uint8_t* _frm_nxt = _frm; 3644227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3645227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3646227825Stheraven uint16_t* _to_nxt = _to; 3647227825Stheraven result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3648227825Stheraven _Maxcode_, _Mode_); 3649227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3650227825Stheraven to_nxt = to + (_to_nxt - _to); 3651227825Stheraven return r; 3652227825Stheraven} 3653227825Stheraven 3654227825Stheraven__codecvt_utf16<char16_t, false>::result 3655227825Stheraven__codecvt_utf16<char16_t, false>::do_unshift(state_type&, 3656227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3657227825Stheraven{ 3658227825Stheraven to_nxt = to; 3659227825Stheraven return noconv; 3660227825Stheraven} 3661227825Stheraven 3662227825Stheravenint 3663227825Stheraven__codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT 3664227825Stheraven{ 3665227825Stheraven return 0; 3666227825Stheraven} 3667227825Stheraven 3668227825Stheravenbool 3669227825Stheraven__codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT 3670227825Stheraven{ 3671227825Stheraven return false; 3672227825Stheraven} 3673227825Stheraven 3674227825Stheravenint 3675227825Stheraven__codecvt_utf16<char16_t, false>::do_length(state_type&, 3676227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3677227825Stheraven{ 3678227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3679227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3680227825Stheraven return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3681227825Stheraven} 3682227825Stheraven 3683227825Stheravenint 3684227825Stheraven__codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT 3685227825Stheraven{ 3686227825Stheraven if (_Mode_ & consume_header) 3687227825Stheraven return 4; 3688227825Stheraven return 2; 3689227825Stheraven} 3690227825Stheraven 3691227825Stheraven// __codecvt_utf16<char16_t, true> 3692227825Stheraven 3693227825Stheraven__codecvt_utf16<char16_t, true>::result 3694227825Stheraven__codecvt_utf16<char16_t, true>::do_out(state_type&, 3695227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3696227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3697227825Stheraven{ 3698227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3699227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 3700227825Stheraven const uint16_t* _frm_nxt = _frm; 3701227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3702227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3703227825Stheraven uint8_t* _to_nxt = _to; 3704227825Stheraven result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3705227825Stheraven _Maxcode_, _Mode_); 3706227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3707227825Stheraven to_nxt = to + (_to_nxt - _to); 3708227825Stheraven return r; 3709227825Stheraven} 3710227825Stheraven 3711227825Stheraven__codecvt_utf16<char16_t, true>::result 3712227825Stheraven__codecvt_utf16<char16_t, true>::do_in(state_type&, 3713227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3714227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3715227825Stheraven{ 3716227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3717227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3718227825Stheraven const uint8_t* _frm_nxt = _frm; 3719227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 3720227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 3721227825Stheraven uint16_t* _to_nxt = _to; 3722227825Stheraven result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3723227825Stheraven _Maxcode_, _Mode_); 3724227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3725227825Stheraven to_nxt = to + (_to_nxt - _to); 3726227825Stheraven return r; 3727227825Stheraven} 3728227825Stheraven 3729227825Stheraven__codecvt_utf16<char16_t, true>::result 3730227825Stheraven__codecvt_utf16<char16_t, true>::do_unshift(state_type&, 3731227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3732227825Stheraven{ 3733227825Stheraven to_nxt = to; 3734227825Stheraven return noconv; 3735227825Stheraven} 3736227825Stheraven 3737227825Stheravenint 3738227825Stheraven__codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT 3739227825Stheraven{ 3740227825Stheraven return 0; 3741227825Stheraven} 3742227825Stheraven 3743227825Stheravenbool 3744227825Stheraven__codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT 3745227825Stheraven{ 3746227825Stheraven return false; 3747227825Stheraven} 3748227825Stheraven 3749227825Stheravenint 3750227825Stheraven__codecvt_utf16<char16_t, true>::do_length(state_type&, 3751227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3752227825Stheraven{ 3753227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3754227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3755227825Stheraven return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3756227825Stheraven} 3757227825Stheraven 3758227825Stheravenint 3759227825Stheraven__codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT 3760227825Stheraven{ 3761227825Stheraven if (_Mode_ & consume_header) 3762227825Stheraven return 4; 3763227825Stheraven return 2; 3764227825Stheraven} 3765227825Stheraven 3766227825Stheraven// __codecvt_utf16<char32_t, false> 3767227825Stheraven 3768227825Stheraven__codecvt_utf16<char32_t, false>::result 3769227825Stheraven__codecvt_utf16<char32_t, false>::do_out(state_type&, 3770227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3771227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3772227825Stheraven{ 3773227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3774227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3775227825Stheraven const uint32_t* _frm_nxt = _frm; 3776227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3777227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3778227825Stheraven uint8_t* _to_nxt = _to; 3779227825Stheraven result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3780227825Stheraven _Maxcode_, _Mode_); 3781227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3782227825Stheraven to_nxt = to + (_to_nxt - _to); 3783227825Stheraven return r; 3784227825Stheraven} 3785227825Stheraven 3786227825Stheraven__codecvt_utf16<char32_t, false>::result 3787227825Stheraven__codecvt_utf16<char32_t, false>::do_in(state_type&, 3788227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3789227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3790227825Stheraven{ 3791227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3792227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3793227825Stheraven const uint8_t* _frm_nxt = _frm; 3794227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3795227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3796227825Stheraven uint32_t* _to_nxt = _to; 3797227825Stheraven result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3798227825Stheraven _Maxcode_, _Mode_); 3799227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3800227825Stheraven to_nxt = to + (_to_nxt - _to); 3801227825Stheraven return r; 3802227825Stheraven} 3803227825Stheraven 3804227825Stheraven__codecvt_utf16<char32_t, false>::result 3805227825Stheraven__codecvt_utf16<char32_t, false>::do_unshift(state_type&, 3806227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3807227825Stheraven{ 3808227825Stheraven to_nxt = to; 3809227825Stheraven return noconv; 3810227825Stheraven} 3811227825Stheraven 3812227825Stheravenint 3813227825Stheraven__codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT 3814227825Stheraven{ 3815227825Stheraven return 0; 3816227825Stheraven} 3817227825Stheraven 3818227825Stheravenbool 3819227825Stheraven__codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT 3820227825Stheraven{ 3821227825Stheraven return false; 3822227825Stheraven} 3823227825Stheraven 3824227825Stheravenint 3825227825Stheraven__codecvt_utf16<char32_t, false>::do_length(state_type&, 3826227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3827227825Stheraven{ 3828227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3829227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3830227825Stheraven return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3831227825Stheraven} 3832227825Stheraven 3833227825Stheravenint 3834227825Stheraven__codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT 3835227825Stheraven{ 3836227825Stheraven if (_Mode_ & consume_header) 3837227825Stheraven return 6; 3838227825Stheraven return 4; 3839227825Stheraven} 3840227825Stheraven 3841227825Stheraven// __codecvt_utf16<char32_t, true> 3842227825Stheraven 3843227825Stheraven__codecvt_utf16<char32_t, true>::result 3844227825Stheraven__codecvt_utf16<char32_t, true>::do_out(state_type&, 3845227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3846227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3847227825Stheraven{ 3848227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3849227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3850227825Stheraven const uint32_t* _frm_nxt = _frm; 3851227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3852227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3853227825Stheraven uint8_t* _to_nxt = _to; 3854227825Stheraven result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3855227825Stheraven _Maxcode_, _Mode_); 3856227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3857227825Stheraven to_nxt = to + (_to_nxt - _to); 3858227825Stheraven return r; 3859227825Stheraven} 3860227825Stheraven 3861227825Stheraven__codecvt_utf16<char32_t, true>::result 3862227825Stheraven__codecvt_utf16<char32_t, true>::do_in(state_type&, 3863227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3864227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3865227825Stheraven{ 3866227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3867227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3868227825Stheraven const uint8_t* _frm_nxt = _frm; 3869227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3870227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3871227825Stheraven uint32_t* _to_nxt = _to; 3872227825Stheraven result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3873227825Stheraven _Maxcode_, _Mode_); 3874227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3875227825Stheraven to_nxt = to + (_to_nxt - _to); 3876227825Stheraven return r; 3877227825Stheraven} 3878227825Stheraven 3879227825Stheraven__codecvt_utf16<char32_t, true>::result 3880227825Stheraven__codecvt_utf16<char32_t, true>::do_unshift(state_type&, 3881227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3882227825Stheraven{ 3883227825Stheraven to_nxt = to; 3884227825Stheraven return noconv; 3885227825Stheraven} 3886227825Stheraven 3887227825Stheravenint 3888227825Stheraven__codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT 3889227825Stheraven{ 3890227825Stheraven return 0; 3891227825Stheraven} 3892227825Stheraven 3893227825Stheravenbool 3894227825Stheraven__codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT 3895227825Stheraven{ 3896227825Stheraven return false; 3897227825Stheraven} 3898227825Stheraven 3899227825Stheravenint 3900227825Stheraven__codecvt_utf16<char32_t, true>::do_length(state_type&, 3901227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3902227825Stheraven{ 3903227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3904227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3905227825Stheraven return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3906227825Stheraven} 3907227825Stheraven 3908227825Stheravenint 3909227825Stheraven__codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT 3910227825Stheraven{ 3911227825Stheraven if (_Mode_ & consume_header) 3912227825Stheraven return 6; 3913227825Stheraven return 4; 3914227825Stheraven} 3915227825Stheraven 3916227825Stheraven// __codecvt_utf8_utf16<wchar_t> 3917227825Stheraven 3918227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3919227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_out(state_type&, 3920227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3921227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3922227825Stheraven{ 3923227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 3924227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 3925227825Stheraven const uint32_t* _frm_nxt = _frm; 3926227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 3927227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 3928227825Stheraven uint8_t* _to_nxt = _to; 3929227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3930227825Stheraven _Maxcode_, _Mode_); 3931227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3932227825Stheraven to_nxt = to + (_to_nxt - _to); 3933227825Stheraven return r; 3934227825Stheraven} 3935227825Stheraven 3936227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3937227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_in(state_type&, 3938227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 3939227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 3940227825Stheraven{ 3941227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3942227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3943227825Stheraven const uint8_t* _frm_nxt = _frm; 3944227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 3945227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 3946227825Stheraven uint32_t* _to_nxt = _to; 3947227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 3948227825Stheraven _Maxcode_, _Mode_); 3949227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 3950227825Stheraven to_nxt = to + (_to_nxt - _to); 3951227825Stheraven return r; 3952227825Stheraven} 3953227825Stheraven 3954227825Stheraven__codecvt_utf8_utf16<wchar_t>::result 3955227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&, 3956227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 3957227825Stheraven{ 3958227825Stheraven to_nxt = to; 3959227825Stheraven return noconv; 3960227825Stheraven} 3961227825Stheraven 3962227825Stheravenint 3963227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT 3964227825Stheraven{ 3965227825Stheraven return 0; 3966227825Stheraven} 3967227825Stheraven 3968227825Stheravenbool 3969227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT 3970227825Stheraven{ 3971227825Stheraven return false; 3972227825Stheraven} 3973227825Stheraven 3974227825Stheravenint 3975227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_length(state_type&, 3976227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 3977227825Stheraven{ 3978227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 3979227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 3980227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 3981227825Stheraven} 3982227825Stheraven 3983227825Stheravenint 3984227825Stheraven__codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT 3985227825Stheraven{ 3986227825Stheraven if (_Mode_ & consume_header) 3987227825Stheraven return 7; 3988227825Stheraven return 4; 3989227825Stheraven} 3990227825Stheraven 3991227825Stheraven// __codecvt_utf8_utf16<char16_t> 3992227825Stheraven 3993227825Stheraven__codecvt_utf8_utf16<char16_t>::result 3994227825Stheraven__codecvt_utf8_utf16<char16_t>::do_out(state_type&, 3995227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 3996227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 3997227825Stheraven{ 3998227825Stheraven const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm); 3999227825Stheraven const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end); 4000227825Stheraven const uint16_t* _frm_nxt = _frm; 4001227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 4002227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 4003227825Stheraven uint8_t* _to_nxt = _to; 4004227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4005227825Stheraven _Maxcode_, _Mode_); 4006227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4007227825Stheraven to_nxt = to + (_to_nxt - _to); 4008227825Stheraven return r; 4009227825Stheraven} 4010227825Stheraven 4011227825Stheraven__codecvt_utf8_utf16<char16_t>::result 4012227825Stheraven__codecvt_utf8_utf16<char16_t>::do_in(state_type&, 4013227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 4014227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 4015227825Stheraven{ 4016227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4017227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4018227825Stheraven const uint8_t* _frm_nxt = _frm; 4019227825Stheraven uint16_t* _to = reinterpret_cast<uint16_t*>(to); 4020227825Stheraven uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end); 4021227825Stheraven uint16_t* _to_nxt = _to; 4022227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4023227825Stheraven _Maxcode_, _Mode_); 4024227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4025227825Stheraven to_nxt = to + (_to_nxt - _to); 4026227825Stheraven return r; 4027227825Stheraven} 4028227825Stheraven 4029227825Stheraven__codecvt_utf8_utf16<char16_t>::result 4030227825Stheraven__codecvt_utf8_utf16<char16_t>::do_unshift(state_type&, 4031227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 4032227825Stheraven{ 4033227825Stheraven to_nxt = to; 4034227825Stheraven return noconv; 4035227825Stheraven} 4036227825Stheraven 4037227825Stheravenint 4038227825Stheraven__codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT 4039227825Stheraven{ 4040227825Stheraven return 0; 4041227825Stheraven} 4042227825Stheraven 4043227825Stheravenbool 4044227825Stheraven__codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT 4045227825Stheraven{ 4046227825Stheraven return false; 4047227825Stheraven} 4048227825Stheraven 4049227825Stheravenint 4050227825Stheraven__codecvt_utf8_utf16<char16_t>::do_length(state_type&, 4051227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 4052227825Stheraven{ 4053227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4054227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4055227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 4056227825Stheraven} 4057227825Stheraven 4058227825Stheravenint 4059227825Stheraven__codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT 4060227825Stheraven{ 4061227825Stheraven if (_Mode_ & consume_header) 4062227825Stheraven return 7; 4063227825Stheraven return 4; 4064227825Stheraven} 4065227825Stheraven 4066227825Stheraven// __codecvt_utf8_utf16<char32_t> 4067227825Stheraven 4068227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4069227825Stheraven__codecvt_utf8_utf16<char32_t>::do_out(state_type&, 4070227825Stheraven const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt, 4071227825Stheraven extern_type* to, extern_type* to_end, extern_type*& to_nxt) const 4072227825Stheraven{ 4073227825Stheraven const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm); 4074227825Stheraven const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end); 4075227825Stheraven const uint32_t* _frm_nxt = _frm; 4076227825Stheraven uint8_t* _to = reinterpret_cast<uint8_t*>(to); 4077227825Stheraven uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end); 4078227825Stheraven uint8_t* _to_nxt = _to; 4079227825Stheraven result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4080227825Stheraven _Maxcode_, _Mode_); 4081227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4082227825Stheraven to_nxt = to + (_to_nxt - _to); 4083227825Stheraven return r; 4084227825Stheraven} 4085227825Stheraven 4086227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4087227825Stheraven__codecvt_utf8_utf16<char32_t>::do_in(state_type&, 4088227825Stheraven const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt, 4089227825Stheraven intern_type* to, intern_type* to_end, intern_type*& to_nxt) const 4090227825Stheraven{ 4091227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4092227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4093227825Stheraven const uint8_t* _frm_nxt = _frm; 4094227825Stheraven uint32_t* _to = reinterpret_cast<uint32_t*>(to); 4095227825Stheraven uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end); 4096227825Stheraven uint32_t* _to_nxt = _to; 4097227825Stheraven result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, 4098227825Stheraven _Maxcode_, _Mode_); 4099227825Stheraven frm_nxt = frm + (_frm_nxt - _frm); 4100227825Stheraven to_nxt = to + (_to_nxt - _to); 4101227825Stheraven return r; 4102227825Stheraven} 4103227825Stheraven 4104227825Stheraven__codecvt_utf8_utf16<char32_t>::result 4105227825Stheraven__codecvt_utf8_utf16<char32_t>::do_unshift(state_type&, 4106227825Stheraven extern_type* to, extern_type*, extern_type*& to_nxt) const 4107227825Stheraven{ 4108227825Stheraven to_nxt = to; 4109227825Stheraven return noconv; 4110227825Stheraven} 4111227825Stheraven 4112227825Stheravenint 4113227825Stheraven__codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT 4114227825Stheraven{ 4115227825Stheraven return 0; 4116227825Stheraven} 4117227825Stheraven 4118227825Stheravenbool 4119227825Stheraven__codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT 4120227825Stheraven{ 4121227825Stheraven return false; 4122227825Stheraven} 4123227825Stheraven 4124227825Stheravenint 4125227825Stheraven__codecvt_utf8_utf16<char32_t>::do_length(state_type&, 4126227825Stheraven const extern_type* frm, const extern_type* frm_end, size_t mx) const 4127227825Stheraven{ 4128227825Stheraven const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm); 4129227825Stheraven const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end); 4130227825Stheraven return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_); 4131227825Stheraven} 4132227825Stheraven 4133227825Stheravenint 4134227825Stheraven__codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT 4135227825Stheraven{ 4136227825Stheraven if (_Mode_ & consume_header) 4137227825Stheraven return 7; 4138227825Stheraven return 4; 4139227825Stheraven} 4140227825Stheraven 4141227825Stheraven// __narrow_to_utf8<16> 4142227825Stheraven 4143227825Stheraven__narrow_to_utf8<16>::~__narrow_to_utf8() 4144227825Stheraven{ 4145227825Stheraven} 4146227825Stheraven 4147227825Stheraven// __narrow_to_utf8<32> 4148227825Stheraven 4149227825Stheraven__narrow_to_utf8<32>::~__narrow_to_utf8() 4150227825Stheraven{ 4151227825Stheraven} 4152227825Stheraven 4153227825Stheraven// __widen_from_utf8<16> 4154227825Stheraven 4155227825Stheraven__widen_from_utf8<16>::~__widen_from_utf8() 4156227825Stheraven{ 4157227825Stheraven} 4158227825Stheraven 4159227825Stheraven// __widen_from_utf8<32> 4160227825Stheraven 4161227825Stheraven__widen_from_utf8<32>::~__widen_from_utf8() 4162227825Stheraven{ 4163227825Stheraven} 4164227825Stheraven 4165227825Stheraven// numpunct<char> && numpunct<wchar_t> 4166227825Stheraven 4167227825Stheravenlocale::id numpunct< char >::id; 4168227825Stheravenlocale::id numpunct<wchar_t>::id; 4169227825Stheraven 4170227825Stheravennumpunct<char>::numpunct(size_t refs) 4171227825Stheraven : locale::facet(refs), 4172227825Stheraven __decimal_point_('.'), 4173227825Stheraven __thousands_sep_(',') 4174227825Stheraven{ 4175227825Stheraven} 4176227825Stheraven 4177227825Stheravennumpunct<wchar_t>::numpunct(size_t refs) 4178227825Stheraven : locale::facet(refs), 4179227825Stheraven __decimal_point_(L'.'), 4180227825Stheraven __thousands_sep_(L',') 4181227825Stheraven{ 4182227825Stheraven} 4183227825Stheraven 4184227825Stheravennumpunct<char>::~numpunct() 4185227825Stheraven{ 4186227825Stheraven} 4187227825Stheraven 4188227825Stheravennumpunct<wchar_t>::~numpunct() 4189227825Stheraven{ 4190227825Stheraven} 4191227825Stheraven 4192227825Stheraven char numpunct< char >::do_decimal_point() const {return __decimal_point_;} 4193227825Stheravenwchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;} 4194227825Stheraven 4195227825Stheraven char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;} 4196227825Stheravenwchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;} 4197227825Stheraven 4198227825Stheravenstring numpunct< char >::do_grouping() const {return __grouping_;} 4199227825Stheravenstring numpunct<wchar_t>::do_grouping() const {return __grouping_;} 4200227825Stheraven 4201227825Stheraven string numpunct< char >::do_truename() const {return "true";} 4202227825Stheravenwstring numpunct<wchar_t>::do_truename() const {return L"true";} 4203227825Stheraven 4204227825Stheraven string numpunct< char >::do_falsename() const {return "false";} 4205227825Stheravenwstring numpunct<wchar_t>::do_falsename() const {return L"false";} 4206227825Stheraven 4207227825Stheraven// numpunct_byname<char> 4208227825Stheraven 4209227825Stheravennumpunct_byname<char>::numpunct_byname(const char* nm, size_t refs) 4210227825Stheraven : numpunct<char>(refs) 4211227825Stheraven{ 4212227825Stheraven __init(nm); 4213227825Stheraven} 4214227825Stheraven 4215227825Stheravennumpunct_byname<char>::numpunct_byname(const string& nm, size_t refs) 4216227825Stheraven : numpunct<char>(refs) 4217227825Stheraven{ 4218227825Stheraven __init(nm.c_str()); 4219227825Stheraven} 4220227825Stheraven 4221227825Stheravennumpunct_byname<char>::~numpunct_byname() 4222227825Stheraven{ 4223227825Stheraven} 4224227825Stheraven 4225227825Stheravenvoid 4226227825Stheravennumpunct_byname<char>::__init(const char* nm) 4227227825Stheraven{ 4228227825Stheraven if (strcmp(nm, "C") != 0) 4229227825Stheraven { 4230227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 4231227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4232232950Stheraven if (loc == nullptr) 4233227825Stheraven throw runtime_error("numpunct_byname<char>::numpunct_byname" 4234227825Stheraven " failed to construct for " + string(nm)); 4235227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4236227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4237227825Stheraven lconv* lc = localeconv_l(loc.get()); 4238227825Stheraven#else 4239227825Stheraven lconv* lc = __localeconv_l(loc.get()); 4240227825Stheraven#endif 4241227825Stheraven if (*lc->decimal_point) 4242227825Stheraven __decimal_point_ = *lc->decimal_point; 4243227825Stheraven if (*lc->thousands_sep) 4244227825Stheraven __thousands_sep_ = *lc->thousands_sep; 4245227825Stheraven __grouping_ = lc->grouping; 4246227825Stheraven // localization for truename and falsename is not available 4247227825Stheraven } 4248227825Stheraven} 4249227825Stheraven 4250227825Stheraven// numpunct_byname<wchar_t> 4251227825Stheraven 4252227825Stheravennumpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs) 4253227825Stheraven : numpunct<wchar_t>(refs) 4254227825Stheraven{ 4255227825Stheraven __init(nm); 4256227825Stheraven} 4257227825Stheraven 4258227825Stheravennumpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs) 4259227825Stheraven : numpunct<wchar_t>(refs) 4260227825Stheraven{ 4261227825Stheraven __init(nm.c_str()); 4262227825Stheraven} 4263227825Stheraven 4264227825Stheravennumpunct_byname<wchar_t>::~numpunct_byname() 4265227825Stheraven{ 4266227825Stheraven} 4267227825Stheraven 4268227825Stheravenvoid 4269227825Stheravennumpunct_byname<wchar_t>::__init(const char* nm) 4270227825Stheraven{ 4271227825Stheraven if (strcmp(nm, "C") != 0) 4272227825Stheraven { 4273227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 4274227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4275232950Stheraven if (loc == nullptr) 4276227825Stheraven throw runtime_error("numpunct_byname<char>::numpunct_byname" 4277227825Stheraven " failed to construct for " + string(nm)); 4278227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4279227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4280227825Stheraven lconv* lc = localeconv_l(loc.get()); 4281227825Stheraven#else 4282227825Stheraven lconv* lc = __localeconv_l(loc.get()); 4283227825Stheraven#endif 4284227825Stheraven if (*lc->decimal_point) 4285227825Stheraven __decimal_point_ = *lc->decimal_point; 4286227825Stheraven if (*lc->thousands_sep) 4287227825Stheraven __thousands_sep_ = *lc->thousands_sep; 4288227825Stheraven __grouping_ = lc->grouping; 4289227825Stheraven // locallization for truename and falsename is not available 4290227825Stheraven } 4291227825Stheraven} 4292227825Stheraven 4293227825Stheraven// num_get helpers 4294227825Stheraven 4295227825Stheravenint 4296227825Stheraven__num_get_base::__get_base(ios_base& iob) 4297227825Stheraven{ 4298227825Stheraven ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield; 4299227825Stheraven if (__basefield == ios_base::oct) 4300227825Stheraven return 8; 4301227825Stheraven else if (__basefield == ios_base::hex) 4302227825Stheraven return 16; 4303227825Stheraven else if (__basefield == 0) 4304227825Stheraven return 0; 4305227825Stheraven return 10; 4306227825Stheraven} 4307227825Stheraven 4308227825Stheravenconst char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN"; 4309227825Stheraven 4310227825Stheravenvoid 4311227825Stheraven__check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 4312227825Stheraven ios_base::iostate& __err) 4313227825Stheraven{ 4314227825Stheraven if (__grouping.size() != 0) 4315227825Stheraven { 4316227825Stheraven reverse(__g, __g_end); 4317227825Stheraven const char* __ig = __grouping.data(); 4318227825Stheraven const char* __eg = __ig + __grouping.size(); 4319227825Stheraven for (unsigned* __r = __g; __r < __g_end-1; ++__r) 4320227825Stheraven { 4321227825Stheraven if (0 < *__ig && *__ig < numeric_limits<char>::max()) 4322227825Stheraven { 4323232950Stheraven if (static_cast<unsigned>(*__ig) != *__r) 4324227825Stheraven { 4325227825Stheraven __err = ios_base::failbit; 4326227825Stheraven return; 4327227825Stheraven } 4328227825Stheraven } 4329227825Stheraven if (__eg - __ig > 1) 4330227825Stheraven ++__ig; 4331227825Stheraven } 4332227825Stheraven if (0 < *__ig && *__ig < numeric_limits<char>::max()) 4333227825Stheraven { 4334232950Stheraven if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0) 4335227825Stheraven __err = ios_base::failbit; 4336227825Stheraven } 4337227825Stheraven } 4338227825Stheraven} 4339227825Stheraven 4340227825Stheravenvoid 4341227825Stheraven__num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd, 4342227825Stheraven ios_base::fmtflags __flags) 4343227825Stheraven{ 4344227825Stheraven if (__flags & ios_base::showpos) 4345227825Stheraven *__fmtp++ = '+'; 4346227825Stheraven if (__flags & ios_base::showbase) 4347227825Stheraven *__fmtp++ = '#'; 4348227825Stheraven while(*__len) 4349227825Stheraven *__fmtp++ = *__len++; 4350227825Stheraven if ((__flags & ios_base::basefield) == ios_base::oct) 4351227825Stheraven *__fmtp = 'o'; 4352227825Stheraven else if ((__flags & ios_base::basefield) == ios_base::hex) 4353227825Stheraven { 4354227825Stheraven if (__flags & ios_base::uppercase) 4355227825Stheraven *__fmtp = 'X'; 4356227825Stheraven else 4357227825Stheraven *__fmtp = 'x'; 4358227825Stheraven } 4359227825Stheraven else if (__signd) 4360227825Stheraven *__fmtp = 'd'; 4361227825Stheraven else 4362227825Stheraven *__fmtp = 'u'; 4363227825Stheraven} 4364227825Stheraven 4365227825Stheravenbool 4366227825Stheraven__num_put_base::__format_float(char* __fmtp, const char* __len, 4367227825Stheraven ios_base::fmtflags __flags) 4368227825Stheraven{ 4369227825Stheraven bool specify_precision = true; 4370227825Stheraven if (__flags & ios_base::showpos) 4371227825Stheraven *__fmtp++ = '+'; 4372227825Stheraven if (__flags & ios_base::showpoint) 4373227825Stheraven *__fmtp++ = '#'; 4374227825Stheraven ios_base::fmtflags floatfield = __flags & ios_base::floatfield; 4375262801Sdim bool uppercase = (__flags & ios_base::uppercase) != 0; 4376227825Stheraven if (floatfield == (ios_base::fixed | ios_base::scientific)) 4377227825Stheraven specify_precision = false; 4378227825Stheraven else 4379227825Stheraven { 4380227825Stheraven *__fmtp++ = '.'; 4381227825Stheraven *__fmtp++ = '*'; 4382227825Stheraven } 4383227825Stheraven while(*__len) 4384227825Stheraven *__fmtp++ = *__len++; 4385227825Stheraven if (floatfield == ios_base::fixed) 4386227825Stheraven { 4387227825Stheraven if (uppercase) 4388227825Stheraven *__fmtp = 'F'; 4389227825Stheraven else 4390227825Stheraven *__fmtp = 'f'; 4391227825Stheraven } 4392227825Stheraven else if (floatfield == ios_base::scientific) 4393227825Stheraven { 4394227825Stheraven if (uppercase) 4395227825Stheraven *__fmtp = 'E'; 4396227825Stheraven else 4397227825Stheraven *__fmtp = 'e'; 4398227825Stheraven } 4399227825Stheraven else if (floatfield == (ios_base::fixed | ios_base::scientific)) 4400227825Stheraven { 4401227825Stheraven if (uppercase) 4402227825Stheraven *__fmtp = 'A'; 4403227825Stheraven else 4404227825Stheraven *__fmtp = 'a'; 4405227825Stheraven } 4406227825Stheraven else 4407227825Stheraven { 4408227825Stheraven if (uppercase) 4409227825Stheraven *__fmtp = 'G'; 4410227825Stheraven else 4411227825Stheraven *__fmtp = 'g'; 4412227825Stheraven } 4413227825Stheraven return specify_precision; 4414227825Stheraven} 4415227825Stheraven 4416227825Stheravenchar* 4417227825Stheraven__num_put_base::__identify_padding(char* __nb, char* __ne, 4418227825Stheraven const ios_base& __iob) 4419227825Stheraven{ 4420227825Stheraven switch (__iob.flags() & ios_base::adjustfield) 4421227825Stheraven { 4422227825Stheraven case ios_base::internal: 4423227825Stheraven if (__nb[0] == '-' || __nb[0] == '+') 4424227825Stheraven return __nb+1; 4425227825Stheraven if (__ne - __nb >= 2 && __nb[0] == '0' 4426227825Stheraven && (__nb[1] == 'x' || __nb[1] == 'X')) 4427227825Stheraven return __nb+2; 4428227825Stheraven break; 4429227825Stheraven case ios_base::left: 4430227825Stheraven return __ne; 4431227825Stheraven case ios_base::right: 4432227825Stheraven default: 4433227825Stheraven break; 4434227825Stheraven } 4435227825Stheraven return __nb; 4436227825Stheraven} 4437227825Stheraven 4438227825Stheraven// time_get 4439227825Stheraven 4440227825Stheravenstatic 4441227825Stheravenstring* 4442227825Stheraveninit_weeks() 4443227825Stheraven{ 4444227825Stheraven static string weeks[14]; 4445227825Stheraven weeks[0] = "Sunday"; 4446227825Stheraven weeks[1] = "Monday"; 4447227825Stheraven weeks[2] = "Tuesday"; 4448227825Stheraven weeks[3] = "Wednesday"; 4449227825Stheraven weeks[4] = "Thursday"; 4450227825Stheraven weeks[5] = "Friday"; 4451227825Stheraven weeks[6] = "Saturday"; 4452227825Stheraven weeks[7] = "Sun"; 4453227825Stheraven weeks[8] = "Mon"; 4454227825Stheraven weeks[9] = "Tue"; 4455227825Stheraven weeks[10] = "Wed"; 4456227825Stheraven weeks[11] = "Thu"; 4457227825Stheraven weeks[12] = "Fri"; 4458227825Stheraven weeks[13] = "Sat"; 4459227825Stheraven return weeks; 4460227825Stheraven} 4461227825Stheraven 4462227825Stheravenstatic 4463227825Stheravenwstring* 4464227825Stheraveninit_wweeks() 4465227825Stheraven{ 4466227825Stheraven static wstring weeks[14]; 4467227825Stheraven weeks[0] = L"Sunday"; 4468227825Stheraven weeks[1] = L"Monday"; 4469227825Stheraven weeks[2] = L"Tuesday"; 4470227825Stheraven weeks[3] = L"Wednesday"; 4471227825Stheraven weeks[4] = L"Thursday"; 4472227825Stheraven weeks[5] = L"Friday"; 4473227825Stheraven weeks[6] = L"Saturday"; 4474227825Stheraven weeks[7] = L"Sun"; 4475227825Stheraven weeks[8] = L"Mon"; 4476227825Stheraven weeks[9] = L"Tue"; 4477227825Stheraven weeks[10] = L"Wed"; 4478227825Stheraven weeks[11] = L"Thu"; 4479227825Stheraven weeks[12] = L"Fri"; 4480227825Stheraven weeks[13] = L"Sat"; 4481227825Stheraven return weeks; 4482227825Stheraven} 4483227825Stheraven 4484227825Stheraventemplate <> 4485227825Stheravenconst string* 4486227825Stheraven__time_get_c_storage<char>::__weeks() const 4487227825Stheraven{ 4488227825Stheraven static const string* weeks = init_weeks(); 4489227825Stheraven return weeks; 4490227825Stheraven} 4491227825Stheraven 4492227825Stheraventemplate <> 4493227825Stheravenconst wstring* 4494227825Stheraven__time_get_c_storage<wchar_t>::__weeks() const 4495227825Stheraven{ 4496227825Stheraven static const wstring* weeks = init_wweeks(); 4497227825Stheraven return weeks; 4498227825Stheraven} 4499227825Stheraven 4500227825Stheravenstatic 4501227825Stheravenstring* 4502227825Stheraveninit_months() 4503227825Stheraven{ 4504227825Stheraven static string months[24]; 4505227825Stheraven months[0] = "January"; 4506227825Stheraven months[1] = "February"; 4507227825Stheraven months[2] = "March"; 4508227825Stheraven months[3] = "April"; 4509227825Stheraven months[4] = "May"; 4510227825Stheraven months[5] = "June"; 4511227825Stheraven months[6] = "July"; 4512227825Stheraven months[7] = "August"; 4513227825Stheraven months[8] = "September"; 4514227825Stheraven months[9] = "October"; 4515227825Stheraven months[10] = "November"; 4516227825Stheraven months[11] = "December"; 4517227825Stheraven months[12] = "Jan"; 4518227825Stheraven months[13] = "Feb"; 4519227825Stheraven months[14] = "Mar"; 4520227825Stheraven months[15] = "Apr"; 4521227825Stheraven months[16] = "May"; 4522227825Stheraven months[17] = "Jun"; 4523227825Stheraven months[18] = "Jul"; 4524227825Stheraven months[19] = "Aug"; 4525227825Stheraven months[20] = "Sep"; 4526227825Stheraven months[21] = "Oct"; 4527227825Stheraven months[22] = "Nov"; 4528227825Stheraven months[23] = "Dec"; 4529227825Stheraven return months; 4530227825Stheraven} 4531227825Stheraven 4532227825Stheravenstatic 4533227825Stheravenwstring* 4534227825Stheraveninit_wmonths() 4535227825Stheraven{ 4536227825Stheraven static wstring months[24]; 4537227825Stheraven months[0] = L"January"; 4538227825Stheraven months[1] = L"February"; 4539227825Stheraven months[2] = L"March"; 4540227825Stheraven months[3] = L"April"; 4541227825Stheraven months[4] = L"May"; 4542227825Stheraven months[5] = L"June"; 4543227825Stheraven months[6] = L"July"; 4544227825Stheraven months[7] = L"August"; 4545227825Stheraven months[8] = L"September"; 4546227825Stheraven months[9] = L"October"; 4547227825Stheraven months[10] = L"November"; 4548227825Stheraven months[11] = L"December"; 4549227825Stheraven months[12] = L"Jan"; 4550227825Stheraven months[13] = L"Feb"; 4551227825Stheraven months[14] = L"Mar"; 4552227825Stheraven months[15] = L"Apr"; 4553227825Stheraven months[16] = L"May"; 4554227825Stheraven months[17] = L"Jun"; 4555227825Stheraven months[18] = L"Jul"; 4556227825Stheraven months[19] = L"Aug"; 4557227825Stheraven months[20] = L"Sep"; 4558227825Stheraven months[21] = L"Oct"; 4559227825Stheraven months[22] = L"Nov"; 4560227825Stheraven months[23] = L"Dec"; 4561227825Stheraven return months; 4562227825Stheraven} 4563227825Stheraven 4564227825Stheraventemplate <> 4565227825Stheravenconst string* 4566227825Stheraven__time_get_c_storage<char>::__months() const 4567227825Stheraven{ 4568227825Stheraven static const string* months = init_months(); 4569227825Stheraven return months; 4570227825Stheraven} 4571227825Stheraven 4572227825Stheraventemplate <> 4573227825Stheravenconst wstring* 4574227825Stheraven__time_get_c_storage<wchar_t>::__months() const 4575227825Stheraven{ 4576227825Stheraven static const wstring* months = init_wmonths(); 4577227825Stheraven return months; 4578227825Stheraven} 4579227825Stheraven 4580227825Stheravenstatic 4581227825Stheravenstring* 4582227825Stheraveninit_am_pm() 4583227825Stheraven{ 4584227825Stheraven static string am_pm[24]; 4585227825Stheraven am_pm[0] = "AM"; 4586227825Stheraven am_pm[1] = "PM"; 4587227825Stheraven return am_pm; 4588227825Stheraven} 4589227825Stheraven 4590227825Stheravenstatic 4591227825Stheravenwstring* 4592227825Stheraveninit_wam_pm() 4593227825Stheraven{ 4594227825Stheraven static wstring am_pm[24]; 4595227825Stheraven am_pm[0] = L"AM"; 4596227825Stheraven am_pm[1] = L"PM"; 4597227825Stheraven return am_pm; 4598227825Stheraven} 4599227825Stheraven 4600227825Stheraventemplate <> 4601227825Stheravenconst string* 4602227825Stheraven__time_get_c_storage<char>::__am_pm() const 4603227825Stheraven{ 4604227825Stheraven static const string* am_pm = init_am_pm(); 4605227825Stheraven return am_pm; 4606227825Stheraven} 4607227825Stheraven 4608227825Stheraventemplate <> 4609227825Stheravenconst wstring* 4610227825Stheraven__time_get_c_storage<wchar_t>::__am_pm() const 4611227825Stheraven{ 4612227825Stheraven static const wstring* am_pm = init_wam_pm(); 4613227825Stheraven return am_pm; 4614227825Stheraven} 4615227825Stheraven 4616227825Stheraventemplate <> 4617227825Stheravenconst string& 4618227825Stheraven__time_get_c_storage<char>::__x() const 4619227825Stheraven{ 4620227825Stheraven static string s("%m/%d/%y"); 4621227825Stheraven return s; 4622227825Stheraven} 4623227825Stheraven 4624227825Stheraventemplate <> 4625227825Stheravenconst wstring& 4626227825Stheraven__time_get_c_storage<wchar_t>::__x() const 4627227825Stheraven{ 4628227825Stheraven static wstring s(L"%m/%d/%y"); 4629227825Stheraven return s; 4630227825Stheraven} 4631227825Stheraven 4632227825Stheraventemplate <> 4633227825Stheravenconst string& 4634227825Stheraven__time_get_c_storage<char>::__X() const 4635227825Stheraven{ 4636227825Stheraven static string s("%H:%M:%S"); 4637227825Stheraven return s; 4638227825Stheraven} 4639227825Stheraven 4640227825Stheraventemplate <> 4641227825Stheravenconst wstring& 4642227825Stheraven__time_get_c_storage<wchar_t>::__X() const 4643227825Stheraven{ 4644227825Stheraven static wstring s(L"%H:%M:%S"); 4645227825Stheraven return s; 4646227825Stheraven} 4647227825Stheraven 4648227825Stheraventemplate <> 4649227825Stheravenconst string& 4650227825Stheraven__time_get_c_storage<char>::__c() const 4651227825Stheraven{ 4652227825Stheraven static string s("%a %b %d %H:%M:%S %Y"); 4653227825Stheraven return s; 4654227825Stheraven} 4655227825Stheraven 4656227825Stheraventemplate <> 4657227825Stheravenconst wstring& 4658227825Stheraven__time_get_c_storage<wchar_t>::__c() const 4659227825Stheraven{ 4660227825Stheraven static wstring s(L"%a %b %d %H:%M:%S %Y"); 4661227825Stheraven return s; 4662227825Stheraven} 4663227825Stheraven 4664227825Stheraventemplate <> 4665227825Stheravenconst string& 4666227825Stheraven__time_get_c_storage<char>::__r() const 4667227825Stheraven{ 4668227825Stheraven static string s("%I:%M:%S %p"); 4669227825Stheraven return s; 4670227825Stheraven} 4671227825Stheraven 4672227825Stheraventemplate <> 4673227825Stheravenconst wstring& 4674227825Stheraven__time_get_c_storage<wchar_t>::__r() const 4675227825Stheraven{ 4676227825Stheraven static wstring s(L"%I:%M:%S %p"); 4677227825Stheraven return s; 4678227825Stheraven} 4679227825Stheraven 4680227825Stheraven// time_get_byname 4681227825Stheraven 4682227825Stheraven__time_get::__time_get(const char* nm) 4683227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 4684227825Stheraven{ 4685227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4686227825Stheraven if (__loc_ == 0) 4687227825Stheraven throw runtime_error("time_get_byname" 4688227825Stheraven " failed to construct for " + string(nm)); 4689227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4690227825Stheraven} 4691227825Stheraven 4692227825Stheraven__time_get::__time_get(const string& nm) 4693227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 4694227825Stheraven{ 4695227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 4696227825Stheraven if (__loc_ == 0) 4697227825Stheraven throw runtime_error("time_get_byname" 4698227825Stheraven " failed to construct for " + nm); 4699227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 4700227825Stheraven} 4701227825Stheraven 4702227825Stheraven__time_get::~__time_get() 4703227825Stheraven{ 4704227825Stheraven freelocale(__loc_); 4705227825Stheraven} 4706262801Sdim#if defined(__clang__) 4707232950Stheraven#pragma clang diagnostic ignored "-Wmissing-field-initializers" 4708262801Sdim#endif 4709262801Sdim#if defined(__GNUG__) 4710246487Stheraven#pragma GCC diagnostic ignored "-Wmissing-field-initializers" 4711262801Sdim#endif 4712232950Stheraven 4713227825Stheraventemplate <> 4714227825Stheravenstring 4715227825Stheraven__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct) 4716227825Stheraven{ 4717232950Stheraven tm t = {0}; 4718227825Stheraven t.tm_sec = 59; 4719227825Stheraven t.tm_min = 55; 4720227825Stheraven t.tm_hour = 23; 4721227825Stheraven t.tm_mday = 31; 4722227825Stheraven t.tm_mon = 11; 4723227825Stheraven t.tm_year = 161; 4724227825Stheraven t.tm_wday = 6; 4725227825Stheraven t.tm_yday = 364; 4726227825Stheraven t.tm_isdst = -1; 4727227825Stheraven char buf[100]; 4728227825Stheraven char f[3] = {0}; 4729227825Stheraven f[0] = '%'; 4730227825Stheraven f[1] = fmt; 4731246487Stheraven size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); 4732227825Stheraven char* bb = buf; 4733227825Stheraven char* be = buf + n; 4734227825Stheraven string result; 4735227825Stheraven while (bb != be) 4736227825Stheraven { 4737227825Stheraven if (ct.is(ctype_base::space, *bb)) 4738227825Stheraven { 4739227825Stheraven result.push_back(' '); 4740227825Stheraven for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb) 4741227825Stheraven ; 4742227825Stheraven continue; 4743227825Stheraven } 4744227825Stheraven char* w = bb; 4745227825Stheraven ios_base::iostate err = ios_base::goodbit; 4746232950Stheraven ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14, 4747227825Stheraven ct, err, false) 4748227825Stheraven - this->__weeks_; 4749227825Stheraven if (i < 14) 4750227825Stheraven { 4751227825Stheraven result.push_back('%'); 4752227825Stheraven if (i < 7) 4753227825Stheraven result.push_back('A'); 4754227825Stheraven else 4755227825Stheraven result.push_back('a'); 4756227825Stheraven bb = w; 4757227825Stheraven continue; 4758227825Stheraven } 4759227825Stheraven w = bb; 4760227825Stheraven i = __scan_keyword(w, be, this->__months_, this->__months_+24, 4761227825Stheraven ct, err, false) 4762227825Stheraven - this->__months_; 4763227825Stheraven if (i < 24) 4764227825Stheraven { 4765227825Stheraven result.push_back('%'); 4766227825Stheraven if (i < 12) 4767227825Stheraven result.push_back('B'); 4768227825Stheraven else 4769227825Stheraven result.push_back('b'); 4770227825Stheraven if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4771227825Stheraven result.back() = 'm'; 4772227825Stheraven bb = w; 4773227825Stheraven continue; 4774227825Stheraven } 4775227825Stheraven if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4776227825Stheraven { 4777227825Stheraven w = bb; 4778227825Stheraven i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2, 4779227825Stheraven ct, err, false) - this->__am_pm_; 4780227825Stheraven if (i < 2) 4781227825Stheraven { 4782227825Stheraven result.push_back('%'); 4783227825Stheraven result.push_back('p'); 4784227825Stheraven bb = w; 4785227825Stheraven continue; 4786227825Stheraven } 4787227825Stheraven } 4788227825Stheraven w = bb; 4789227825Stheraven if (ct.is(ctype_base::digit, *bb)) 4790227825Stheraven { 4791227825Stheraven switch(__get_up_to_n_digits(bb, be, err, ct, 4)) 4792227825Stheraven { 4793227825Stheraven case 6: 4794227825Stheraven result.push_back('%'); 4795227825Stheraven result.push_back('w'); 4796227825Stheraven break; 4797227825Stheraven case 7: 4798227825Stheraven result.push_back('%'); 4799227825Stheraven result.push_back('u'); 4800227825Stheraven break; 4801227825Stheraven case 11: 4802227825Stheraven result.push_back('%'); 4803227825Stheraven result.push_back('I'); 4804227825Stheraven break; 4805227825Stheraven case 12: 4806227825Stheraven result.push_back('%'); 4807227825Stheraven result.push_back('m'); 4808227825Stheraven break; 4809227825Stheraven case 23: 4810227825Stheraven result.push_back('%'); 4811227825Stheraven result.push_back('H'); 4812227825Stheraven break; 4813227825Stheraven case 31: 4814227825Stheraven result.push_back('%'); 4815227825Stheraven result.push_back('d'); 4816227825Stheraven break; 4817227825Stheraven case 55: 4818227825Stheraven result.push_back('%'); 4819227825Stheraven result.push_back('M'); 4820227825Stheraven break; 4821227825Stheraven case 59: 4822227825Stheraven result.push_back('%'); 4823227825Stheraven result.push_back('S'); 4824227825Stheraven break; 4825227825Stheraven case 61: 4826227825Stheraven result.push_back('%'); 4827227825Stheraven result.push_back('y'); 4828227825Stheraven break; 4829227825Stheraven case 364: 4830227825Stheraven result.push_back('%'); 4831227825Stheraven result.push_back('j'); 4832227825Stheraven break; 4833227825Stheraven case 2061: 4834227825Stheraven result.push_back('%'); 4835227825Stheraven result.push_back('Y'); 4836227825Stheraven break; 4837227825Stheraven default: 4838227825Stheraven for (; w != bb; ++w) 4839227825Stheraven result.push_back(*w); 4840227825Stheraven break; 4841227825Stheraven } 4842227825Stheraven continue; 4843227825Stheraven } 4844227825Stheraven if (*bb == '%') 4845227825Stheraven { 4846227825Stheraven result.push_back('%'); 4847227825Stheraven result.push_back('%'); 4848227825Stheraven ++bb; 4849227825Stheraven continue; 4850227825Stheraven } 4851227825Stheraven result.push_back(*bb); 4852227825Stheraven ++bb; 4853227825Stheraven } 4854227825Stheraven return result; 4855227825Stheraven} 4856227825Stheraven 4857262801Sdim#if defined(__clang__) 4858232950Stheraven#pragma clang diagnostic ignored "-Wmissing-braces" 4859262801Sdim#endif 4860232950Stheraven 4861227825Stheraventemplate <> 4862227825Stheravenwstring 4863227825Stheraven__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) 4864227825Stheraven{ 4865232950Stheraven tm t = {0}; 4866227825Stheraven t.tm_sec = 59; 4867227825Stheraven t.tm_min = 55; 4868227825Stheraven t.tm_hour = 23; 4869227825Stheraven t.tm_mday = 31; 4870227825Stheraven t.tm_mon = 11; 4871227825Stheraven t.tm_year = 161; 4872227825Stheraven t.tm_wday = 6; 4873227825Stheraven t.tm_yday = 364; 4874227825Stheraven t.tm_isdst = -1; 4875227825Stheraven char buf[100]; 4876227825Stheraven char f[3] = {0}; 4877227825Stheraven f[0] = '%'; 4878227825Stheraven f[1] = fmt; 4879246487Stheraven strftime_l(buf, countof(buf), f, &t, __loc_); 4880227825Stheraven wchar_t wbuf[100]; 4881227825Stheraven wchar_t* wbb = wbuf; 4882227825Stheraven mbstate_t mb = {0}; 4883227825Stheraven const char* bb = buf; 4884227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 4885246487Stheraven size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); 4886227825Stheraven#else 4887246487Stheraven size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); 4888227825Stheraven#endif 4889232950Stheraven if (j == size_t(-1)) 4890227825Stheraven __throw_runtime_error("locale not supported"); 4891232950Stheraven wchar_t* wbe = wbb + j; 4892227825Stheraven wstring result; 4893227825Stheraven while (wbb != wbe) 4894227825Stheraven { 4895227825Stheraven if (ct.is(ctype_base::space, *wbb)) 4896227825Stheraven { 4897227825Stheraven result.push_back(L' '); 4898227825Stheraven for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb) 4899227825Stheraven ; 4900227825Stheraven continue; 4901227825Stheraven } 4902227825Stheraven wchar_t* w = wbb; 4903227825Stheraven ios_base::iostate err = ios_base::goodbit; 4904232950Stheraven ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14, 4905227825Stheraven ct, err, false) 4906227825Stheraven - this->__weeks_; 4907227825Stheraven if (i < 14) 4908227825Stheraven { 4909227825Stheraven result.push_back(L'%'); 4910227825Stheraven if (i < 7) 4911227825Stheraven result.push_back(L'A'); 4912227825Stheraven else 4913227825Stheraven result.push_back(L'a'); 4914227825Stheraven wbb = w; 4915227825Stheraven continue; 4916227825Stheraven } 4917227825Stheraven w = wbb; 4918227825Stheraven i = __scan_keyword(w, wbe, this->__months_, this->__months_+24, 4919227825Stheraven ct, err, false) 4920227825Stheraven - this->__months_; 4921227825Stheraven if (i < 24) 4922227825Stheraven { 4923227825Stheraven result.push_back(L'%'); 4924227825Stheraven if (i < 12) 4925227825Stheraven result.push_back(L'B'); 4926227825Stheraven else 4927227825Stheraven result.push_back(L'b'); 4928227825Stheraven if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0])) 4929227825Stheraven result.back() = L'm'; 4930227825Stheraven wbb = w; 4931227825Stheraven continue; 4932227825Stheraven } 4933227825Stheraven if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0) 4934227825Stheraven { 4935227825Stheraven w = wbb; 4936227825Stheraven i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2, 4937227825Stheraven ct, err, false) - this->__am_pm_; 4938227825Stheraven if (i < 2) 4939227825Stheraven { 4940227825Stheraven result.push_back(L'%'); 4941227825Stheraven result.push_back(L'p'); 4942227825Stheraven wbb = w; 4943227825Stheraven continue; 4944227825Stheraven } 4945227825Stheraven } 4946227825Stheraven w = wbb; 4947227825Stheraven if (ct.is(ctype_base::digit, *wbb)) 4948227825Stheraven { 4949227825Stheraven switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4)) 4950227825Stheraven { 4951227825Stheraven case 6: 4952227825Stheraven result.push_back(L'%'); 4953227825Stheraven result.push_back(L'w'); 4954227825Stheraven break; 4955227825Stheraven case 7: 4956227825Stheraven result.push_back(L'%'); 4957227825Stheraven result.push_back(L'u'); 4958227825Stheraven break; 4959227825Stheraven case 11: 4960227825Stheraven result.push_back(L'%'); 4961227825Stheraven result.push_back(L'I'); 4962227825Stheraven break; 4963227825Stheraven case 12: 4964227825Stheraven result.push_back(L'%'); 4965227825Stheraven result.push_back(L'm'); 4966227825Stheraven break; 4967227825Stheraven case 23: 4968227825Stheraven result.push_back(L'%'); 4969227825Stheraven result.push_back(L'H'); 4970227825Stheraven break; 4971227825Stheraven case 31: 4972227825Stheraven result.push_back(L'%'); 4973227825Stheraven result.push_back(L'd'); 4974227825Stheraven break; 4975227825Stheraven case 55: 4976227825Stheraven result.push_back(L'%'); 4977227825Stheraven result.push_back(L'M'); 4978227825Stheraven break; 4979227825Stheraven case 59: 4980227825Stheraven result.push_back(L'%'); 4981227825Stheraven result.push_back(L'S'); 4982227825Stheraven break; 4983227825Stheraven case 61: 4984227825Stheraven result.push_back(L'%'); 4985227825Stheraven result.push_back(L'y'); 4986227825Stheraven break; 4987227825Stheraven case 364: 4988227825Stheraven result.push_back(L'%'); 4989227825Stheraven result.push_back(L'j'); 4990227825Stheraven break; 4991227825Stheraven case 2061: 4992227825Stheraven result.push_back(L'%'); 4993227825Stheraven result.push_back(L'Y'); 4994227825Stheraven break; 4995227825Stheraven default: 4996227825Stheraven for (; w != wbb; ++w) 4997227825Stheraven result.push_back(*w); 4998227825Stheraven break; 4999227825Stheraven } 5000227825Stheraven continue; 5001227825Stheraven } 5002227825Stheraven if (ct.narrow(*wbb, 0) == '%') 5003227825Stheraven { 5004227825Stheraven result.push_back(L'%'); 5005227825Stheraven result.push_back(L'%'); 5006227825Stheraven ++wbb; 5007227825Stheraven continue; 5008227825Stheraven } 5009227825Stheraven result.push_back(*wbb); 5010227825Stheraven ++wbb; 5011227825Stheraven } 5012227825Stheraven return result; 5013227825Stheraven} 5014227825Stheraven 5015227825Stheraventemplate <> 5016227825Stheravenvoid 5017227825Stheraven__time_get_storage<char>::init(const ctype<char>& ct) 5018227825Stheraven{ 5019241903Sdim tm t = {0}; 5020227825Stheraven char buf[100]; 5021227825Stheraven // __weeks_ 5022227825Stheraven for (int i = 0; i < 7; ++i) 5023227825Stheraven { 5024227825Stheraven t.tm_wday = i; 5025246487Stheraven strftime_l(buf, countof(buf), "%A", &t, __loc_); 5026227825Stheraven __weeks_[i] = buf; 5027246487Stheraven strftime_l(buf, countof(buf), "%a", &t, __loc_); 5028227825Stheraven __weeks_[i+7] = buf; 5029227825Stheraven } 5030227825Stheraven // __months_ 5031227825Stheraven for (int i = 0; i < 12; ++i) 5032227825Stheraven { 5033227825Stheraven t.tm_mon = i; 5034246487Stheraven strftime_l(buf, countof(buf), "%B", &t, __loc_); 5035227825Stheraven __months_[i] = buf; 5036246487Stheraven strftime_l(buf, countof(buf), "%b", &t, __loc_); 5037227825Stheraven __months_[i+12] = buf; 5038227825Stheraven } 5039227825Stheraven // __am_pm_ 5040227825Stheraven t.tm_hour = 1; 5041246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5042227825Stheraven __am_pm_[0] = buf; 5043227825Stheraven t.tm_hour = 13; 5044246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5045227825Stheraven __am_pm_[1] = buf; 5046227825Stheraven __c_ = __analyze('c', ct); 5047227825Stheraven __r_ = __analyze('r', ct); 5048227825Stheraven __x_ = __analyze('x', ct); 5049227825Stheraven __X_ = __analyze('X', ct); 5050227825Stheraven} 5051227825Stheraven 5052227825Stheraventemplate <> 5053227825Stheravenvoid 5054227825Stheraven__time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) 5055227825Stheraven{ 5056227825Stheraven tm t = {0}; 5057227825Stheraven char buf[100]; 5058227825Stheraven wchar_t wbuf[100]; 5059227825Stheraven wchar_t* wbe; 5060227825Stheraven mbstate_t mb = {0}; 5061227825Stheraven // __weeks_ 5062227825Stheraven for (int i = 0; i < 7; ++i) 5063227825Stheraven { 5064227825Stheraven t.tm_wday = i; 5065246487Stheraven strftime_l(buf, countof(buf), "%A", &t, __loc_); 5066227825Stheraven mb = mbstate_t(); 5067227825Stheraven const char* bb = buf; 5068227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5069246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5070227825Stheraven#else 5071246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5072227825Stheraven#endif 5073232950Stheraven if (j == size_t(-1)) 5074227825Stheraven __throw_runtime_error("locale not supported"); 5075227825Stheraven wbe = wbuf + j; 5076227825Stheraven __weeks_[i].assign(wbuf, wbe); 5077246487Stheraven strftime_l(buf, countof(buf), "%a", &t, __loc_); 5078227825Stheraven mb = mbstate_t(); 5079227825Stheraven bb = buf; 5080227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5081246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5082227825Stheraven#else 5083246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5084227825Stheraven#endif 5085232950Stheraven if (j == size_t(-1)) 5086227825Stheraven __throw_runtime_error("locale not supported"); 5087227825Stheraven wbe = wbuf + j; 5088227825Stheraven __weeks_[i+7].assign(wbuf, wbe); 5089227825Stheraven } 5090227825Stheraven // __months_ 5091227825Stheraven for (int i = 0; i < 12; ++i) 5092227825Stheraven { 5093227825Stheraven t.tm_mon = i; 5094246487Stheraven strftime_l(buf, countof(buf), "%B", &t, __loc_); 5095227825Stheraven mb = mbstate_t(); 5096227825Stheraven const char* bb = buf; 5097227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5098246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5099227825Stheraven#else 5100246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5101227825Stheraven#endif 5102232950Stheraven if (j == size_t(-1)) 5103227825Stheraven __throw_runtime_error("locale not supported"); 5104227825Stheraven wbe = wbuf + j; 5105227825Stheraven __months_[i].assign(wbuf, wbe); 5106246487Stheraven strftime_l(buf, countof(buf), "%b", &t, __loc_); 5107227825Stheraven mb = mbstate_t(); 5108227825Stheraven bb = buf; 5109227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5110246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5111227825Stheraven#else 5112246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5113227825Stheraven#endif 5114232950Stheraven if (j == size_t(-1)) 5115227825Stheraven __throw_runtime_error("locale not supported"); 5116227825Stheraven wbe = wbuf + j; 5117227825Stheraven __months_[i+12].assign(wbuf, wbe); 5118227825Stheraven } 5119227825Stheraven // __am_pm_ 5120227825Stheraven t.tm_hour = 1; 5121246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5122227825Stheraven mb = mbstate_t(); 5123227825Stheraven const char* bb = buf; 5124227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5125246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5126227825Stheraven#else 5127246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5128227825Stheraven#endif 5129232950Stheraven if (j == size_t(-1)) 5130227825Stheraven __throw_runtime_error("locale not supported"); 5131227825Stheraven wbe = wbuf + j; 5132227825Stheraven __am_pm_[0].assign(wbuf, wbe); 5133227825Stheraven t.tm_hour = 13; 5134246487Stheraven strftime_l(buf, countof(buf), "%p", &t, __loc_); 5135227825Stheraven mb = mbstate_t(); 5136227825Stheraven bb = buf; 5137227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5138246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5139227825Stheraven#else 5140246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); 5141227825Stheraven#endif 5142232950Stheraven if (j == size_t(-1)) 5143227825Stheraven __throw_runtime_error("locale not supported"); 5144227825Stheraven wbe = wbuf + j; 5145227825Stheraven __am_pm_[1].assign(wbuf, wbe); 5146227825Stheraven __c_ = __analyze('c', ct); 5147227825Stheraven __r_ = __analyze('r', ct); 5148227825Stheraven __x_ = __analyze('x', ct); 5149227825Stheraven __X_ = __analyze('X', ct); 5150227825Stheraven} 5151227825Stheraven 5152227825Stheraventemplate <class CharT> 5153227825Stheravenstruct _LIBCPP_HIDDEN __time_get_temp 5154227825Stheraven : public ctype_byname<CharT> 5155227825Stheraven{ 5156227825Stheraven explicit __time_get_temp(const char* nm) 5157227825Stheraven : ctype_byname<CharT>(nm, 1) {} 5158227825Stheraven explicit __time_get_temp(const string& nm) 5159227825Stheraven : ctype_byname<CharT>(nm, 1) {} 5160227825Stheraven}; 5161227825Stheraven 5162227825Stheraventemplate <> 5163227825Stheraven__time_get_storage<char>::__time_get_storage(const char* __nm) 5164227825Stheraven : __time_get(__nm) 5165227825Stheraven{ 5166227825Stheraven const __time_get_temp<char> ct(__nm); 5167227825Stheraven init(ct); 5168227825Stheraven} 5169227825Stheraven 5170227825Stheraventemplate <> 5171227825Stheraven__time_get_storage<char>::__time_get_storage(const string& __nm) 5172227825Stheraven : __time_get(__nm) 5173227825Stheraven{ 5174227825Stheraven const __time_get_temp<char> ct(__nm); 5175227825Stheraven init(ct); 5176227825Stheraven} 5177227825Stheraven 5178227825Stheraventemplate <> 5179227825Stheraven__time_get_storage<wchar_t>::__time_get_storage(const char* __nm) 5180227825Stheraven : __time_get(__nm) 5181227825Stheraven{ 5182227825Stheraven const __time_get_temp<wchar_t> ct(__nm); 5183227825Stheraven init(ct); 5184227825Stheraven} 5185227825Stheraven 5186227825Stheraventemplate <> 5187227825Stheraven__time_get_storage<wchar_t>::__time_get_storage(const string& __nm) 5188227825Stheraven : __time_get(__nm) 5189227825Stheraven{ 5190227825Stheraven const __time_get_temp<wchar_t> ct(__nm); 5191227825Stheraven init(ct); 5192227825Stheraven} 5193227825Stheraven 5194227825Stheraventemplate <> 5195227825Stheraventime_base::dateorder 5196227825Stheraven__time_get_storage<char>::__do_date_order() const 5197227825Stheraven{ 5198227825Stheraven unsigned i; 5199227825Stheraven for (i = 0; i < __x_.size(); ++i) 5200227825Stheraven if (__x_[i] == '%') 5201227825Stheraven break; 5202227825Stheraven ++i; 5203227825Stheraven switch (__x_[i]) 5204227825Stheraven { 5205227825Stheraven case 'y': 5206227825Stheraven case 'Y': 5207227825Stheraven for (++i; i < __x_.size(); ++i) 5208227825Stheraven if (__x_[i] == '%') 5209227825Stheraven break; 5210227825Stheraven if (i == __x_.size()) 5211227825Stheraven break; 5212227825Stheraven ++i; 5213227825Stheraven switch (__x_[i]) 5214227825Stheraven { 5215227825Stheraven case 'm': 5216227825Stheraven for (++i; i < __x_.size(); ++i) 5217227825Stheraven if (__x_[i] == '%') 5218227825Stheraven break; 5219227825Stheraven if (i == __x_.size()) 5220227825Stheraven break; 5221227825Stheraven ++i; 5222227825Stheraven if (__x_[i] == 'd') 5223227825Stheraven return time_base::ymd; 5224227825Stheraven break; 5225227825Stheraven case 'd': 5226227825Stheraven for (++i; i < __x_.size(); ++i) 5227227825Stheraven if (__x_[i] == '%') 5228227825Stheraven break; 5229227825Stheraven if (i == __x_.size()) 5230227825Stheraven break; 5231227825Stheraven ++i; 5232227825Stheraven if (__x_[i] == 'm') 5233227825Stheraven return time_base::ydm; 5234227825Stheraven break; 5235227825Stheraven } 5236227825Stheraven break; 5237227825Stheraven case 'm': 5238227825Stheraven for (++i; i < __x_.size(); ++i) 5239227825Stheraven if (__x_[i] == '%') 5240227825Stheraven break; 5241227825Stheraven if (i == __x_.size()) 5242227825Stheraven break; 5243227825Stheraven ++i; 5244227825Stheraven if (__x_[i] == 'd') 5245227825Stheraven { 5246227825Stheraven for (++i; i < __x_.size(); ++i) 5247227825Stheraven if (__x_[i] == '%') 5248227825Stheraven break; 5249227825Stheraven if (i == __x_.size()) 5250227825Stheraven break; 5251227825Stheraven ++i; 5252227825Stheraven if (__x_[i] == 'y' || __x_[i] == 'Y') 5253227825Stheraven return time_base::mdy; 5254227825Stheraven break; 5255227825Stheraven } 5256227825Stheraven break; 5257227825Stheraven case 'd': 5258227825Stheraven for (++i; i < __x_.size(); ++i) 5259227825Stheraven if (__x_[i] == '%') 5260227825Stheraven break; 5261227825Stheraven if (i == __x_.size()) 5262227825Stheraven break; 5263227825Stheraven ++i; 5264227825Stheraven if (__x_[i] == 'm') 5265227825Stheraven { 5266227825Stheraven for (++i; i < __x_.size(); ++i) 5267227825Stheraven if (__x_[i] == '%') 5268227825Stheraven break; 5269227825Stheraven if (i == __x_.size()) 5270227825Stheraven break; 5271227825Stheraven ++i; 5272227825Stheraven if (__x_[i] == 'y' || __x_[i] == 'Y') 5273227825Stheraven return time_base::dmy; 5274227825Stheraven break; 5275227825Stheraven } 5276227825Stheraven break; 5277227825Stheraven } 5278227825Stheraven return time_base::no_order; 5279227825Stheraven} 5280227825Stheraven 5281227825Stheraventemplate <> 5282227825Stheraventime_base::dateorder 5283227825Stheraven__time_get_storage<wchar_t>::__do_date_order() const 5284227825Stheraven{ 5285227825Stheraven unsigned i; 5286227825Stheraven for (i = 0; i < __x_.size(); ++i) 5287227825Stheraven if (__x_[i] == L'%') 5288227825Stheraven break; 5289227825Stheraven ++i; 5290227825Stheraven switch (__x_[i]) 5291227825Stheraven { 5292227825Stheraven case L'y': 5293227825Stheraven case L'Y': 5294227825Stheraven for (++i; i < __x_.size(); ++i) 5295227825Stheraven if (__x_[i] == L'%') 5296227825Stheraven break; 5297227825Stheraven if (i == __x_.size()) 5298227825Stheraven break; 5299227825Stheraven ++i; 5300227825Stheraven switch (__x_[i]) 5301227825Stheraven { 5302227825Stheraven case L'm': 5303227825Stheraven for (++i; i < __x_.size(); ++i) 5304227825Stheraven if (__x_[i] == L'%') 5305227825Stheraven break; 5306227825Stheraven if (i == __x_.size()) 5307227825Stheraven break; 5308227825Stheraven ++i; 5309227825Stheraven if (__x_[i] == L'd') 5310227825Stheraven return time_base::ymd; 5311227825Stheraven break; 5312227825Stheraven case L'd': 5313227825Stheraven for (++i; i < __x_.size(); ++i) 5314227825Stheraven if (__x_[i] == L'%') 5315227825Stheraven break; 5316227825Stheraven if (i == __x_.size()) 5317227825Stheraven break; 5318227825Stheraven ++i; 5319227825Stheraven if (__x_[i] == L'm') 5320227825Stheraven return time_base::ydm; 5321227825Stheraven break; 5322227825Stheraven } 5323227825Stheraven break; 5324227825Stheraven case L'm': 5325227825Stheraven for (++i; i < __x_.size(); ++i) 5326227825Stheraven if (__x_[i] == L'%') 5327227825Stheraven break; 5328227825Stheraven if (i == __x_.size()) 5329227825Stheraven break; 5330227825Stheraven ++i; 5331227825Stheraven if (__x_[i] == L'd') 5332227825Stheraven { 5333227825Stheraven for (++i; i < __x_.size(); ++i) 5334227825Stheraven if (__x_[i] == L'%') 5335227825Stheraven break; 5336227825Stheraven if (i == __x_.size()) 5337227825Stheraven break; 5338227825Stheraven ++i; 5339227825Stheraven if (__x_[i] == L'y' || __x_[i] == L'Y') 5340227825Stheraven return time_base::mdy; 5341227825Stheraven break; 5342227825Stheraven } 5343227825Stheraven break; 5344227825Stheraven case L'd': 5345227825Stheraven for (++i; i < __x_.size(); ++i) 5346227825Stheraven if (__x_[i] == L'%') 5347227825Stheraven break; 5348227825Stheraven if (i == __x_.size()) 5349227825Stheraven break; 5350227825Stheraven ++i; 5351227825Stheraven if (__x_[i] == L'm') 5352227825Stheraven { 5353227825Stheraven for (++i; i < __x_.size(); ++i) 5354227825Stheraven if (__x_[i] == L'%') 5355227825Stheraven break; 5356227825Stheraven if (i == __x_.size()) 5357227825Stheraven break; 5358227825Stheraven ++i; 5359227825Stheraven if (__x_[i] == L'y' || __x_[i] == L'Y') 5360227825Stheraven return time_base::dmy; 5361227825Stheraven break; 5362227825Stheraven } 5363227825Stheraven break; 5364227825Stheraven } 5365227825Stheraven return time_base::no_order; 5366227825Stheraven} 5367227825Stheraven 5368227825Stheraven// time_put 5369227825Stheraven 5370227825Stheraven__time_put::__time_put(const char* nm) 5371227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm, 0)) 5372227825Stheraven{ 5373227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5374227825Stheraven if (__loc_ == 0) 5375227825Stheraven throw runtime_error("time_put_byname" 5376227825Stheraven " failed to construct for " + string(nm)); 5377227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5378227825Stheraven} 5379227825Stheraven 5380227825Stheraven__time_put::__time_put(const string& nm) 5381227825Stheraven : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) 5382227825Stheraven{ 5383227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5384227825Stheraven if (__loc_ == 0) 5385227825Stheraven throw runtime_error("time_put_byname" 5386227825Stheraven " failed to construct for " + nm); 5387227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5388227825Stheraven} 5389227825Stheraven 5390227825Stheraven__time_put::~__time_put() 5391227825Stheraven{ 5392253159Stheraven if (__loc_ != _LIBCPP_GET_C_LOCALE) 5393227825Stheraven freelocale(__loc_); 5394227825Stheraven} 5395227825Stheraven 5396227825Stheravenvoid 5397227825Stheraven__time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, 5398227825Stheraven char __fmt, char __mod) const 5399227825Stheraven{ 5400227825Stheraven char fmt[] = {'%', __fmt, __mod, 0}; 5401227825Stheraven if (__mod != 0) 5402227825Stheraven swap(fmt[1], fmt[2]); 5403246487Stheraven size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); 5404227825Stheraven __ne = __nb + n; 5405227825Stheraven} 5406227825Stheraven 5407227825Stheravenvoid 5408227825Stheraven__time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 5409227825Stheraven char __fmt, char __mod) const 5410227825Stheraven{ 5411227825Stheraven char __nar[100]; 5412227825Stheraven char* __ne = __nar + 100; 5413227825Stheraven __do_put(__nar, __ne, __tm, __fmt, __mod); 5414227825Stheraven mbstate_t mb = {0}; 5415227825Stheraven const char* __nb = __nar; 5416227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5417246487Stheraven size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); 5418227825Stheraven#else 5419246487Stheraven size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); 5420227825Stheraven#endif 5421232950Stheraven if (j == size_t(-1)) 5422227825Stheraven __throw_runtime_error("locale not supported"); 5423227825Stheraven __we = __wb + j; 5424227825Stheraven} 5425227825Stheraven 5426227825Stheraven// moneypunct_byname 5427227825Stheraven 5428232950Stheraventemplate <class charT> 5429227825Stheravenstatic 5430227825Stheravenvoid 5431232950Stheraven__init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_, 5432232950Stheraven bool intl, char cs_precedes, char sep_by_space, char sign_posn, 5433232950Stheraven charT space_char) 5434227825Stheraven{ 5435227825Stheraven const char sign = static_cast<char>(money_base::sign); 5436227825Stheraven const char space = static_cast<char>(money_base::space); 5437227825Stheraven const char none = static_cast<char>(money_base::none); 5438227825Stheraven const char symbol = static_cast<char>(money_base::symbol); 5439227825Stheraven const char value = static_cast<char>(money_base::value); 5440232950Stheraven const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4; 5441232950Stheraven 5442232950Stheraven // Comments on case branches reflect 'C11 7.11.2.1 The localeconv 5443232950Stheraven // function'. "Space between sign and symbol or value" means that 5444232950Stheraven // if the sign is adjacent to the symbol, there's a space between 5445232950Stheraven // them, and otherwise there's a space between the sign and value. 5446232950Stheraven // 5447232950Stheraven // C11's localeconv specifies that the fourth character of an 5448232950Stheraven // international curr_symbol is used to separate the sign and 5449232950Stheraven // value when sep_by_space says to do so. C++ can't represent 5450232950Stheraven // that, so we just use a space. When sep_by_space says to 5451232950Stheraven // separate the symbol and value-or-sign with a space, we rearrange the 5452232950Stheraven // curr_symbol to put its spacing character on the correct side of 5453232950Stheraven // the symbol. 5454232950Stheraven // 5455232950Stheraven // We also need to avoid adding an extra space between the sign 5456232950Stheraven // and value when the currency symbol is suppressed (by not 5457232950Stheraven // setting showbase). We match glibc's strfmon by interpreting 5458232950Stheraven // sep_by_space==1 as "omit the space when the currency symbol is 5459232950Stheraven // absent". 5460232950Stheraven // 5461232950Stheraven // Users who want to get this right should use ICU instead. 5462232950Stheraven 5463227825Stheraven switch (cs_precedes) 5464227825Stheraven { 5465232950Stheraven case 0: // value before curr_symbol 5466232950Stheraven if (symbol_contains_sep) { 5467232950Stheraven // Move the separator to before the symbol, to place it 5468232950Stheraven // between the value and symbol. 5469232950Stheraven rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3, 5470232950Stheraven __curr_symbol_.end()); 5471232950Stheraven } 5472227825Stheraven switch (sign_posn) 5473227825Stheraven { 5474232950Stheraven case 0: // Parentheses surround the quantity and currency symbol. 5475227825Stheraven pat.field[0] = sign; 5476227825Stheraven pat.field[1] = value; 5477232950Stheraven pat.field[2] = none; // Any space appears in the symbol. 5478227825Stheraven pat.field[3] = symbol; 5479227825Stheraven switch (sep_by_space) 5480227825Stheraven { 5481232950Stheraven case 0: // No space separates the currency symbol and value. 5482232950Stheraven // This case may have changed between C99 and C11; 5483232950Stheraven // assume the currency symbol matches the intention. 5484232950Stheraven case 2: // Space between sign and currency or value. 5485232950Stheraven // The "sign" is two parentheses, so no space here either. 5486227825Stheraven return; 5487232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5488232950Stheraven if (!symbol_contains_sep) { 5489232950Stheraven // We insert the space into the symbol instead of 5490232950Stheraven // setting pat.field[2]=space so that when 5491232950Stheraven // showbase is not set, the space goes away too. 5492232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5493232950Stheraven } 5494227825Stheraven return; 5495227825Stheraven default: 5496227825Stheraven break; 5497227825Stheraven } 5498227825Stheraven break; 5499232950Stheraven case 1: // The sign string precedes the quantity and currency symbol. 5500227825Stheraven pat.field[0] = sign; 5501227825Stheraven pat.field[3] = symbol; 5502227825Stheraven switch (sep_by_space) 5503227825Stheraven { 5504232950Stheraven case 0: // No space separates the currency symbol and value. 5505227825Stheraven pat.field[1] = value; 5506227825Stheraven pat.field[2] = none; 5507227825Stheraven return; 5508232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5509227825Stheraven pat.field[1] = value; 5510232950Stheraven pat.field[2] = none; 5511232950Stheraven if (!symbol_contains_sep) { 5512232950Stheraven // We insert the space into the symbol instead of 5513232950Stheraven // setting pat.field[2]=space so that when 5514232950Stheraven // showbase is not set, the space goes away too. 5515232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5516232950Stheraven } 5517227825Stheraven return; 5518232950Stheraven case 2: // Space between sign and currency or value. 5519227825Stheraven pat.field[1] = space; 5520227825Stheraven pat.field[2] = value; 5521232950Stheraven if (symbol_contains_sep) { 5522232950Stheraven // Remove the separator from the symbol, since it 5523232950Stheraven // has already appeared after the sign. 5524232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5525232950Stheraven } 5526227825Stheraven return; 5527227825Stheraven default: 5528227825Stheraven break; 5529227825Stheraven } 5530227825Stheraven break; 5531232950Stheraven case 2: // The sign string succeeds the quantity and currency symbol. 5532227825Stheraven pat.field[0] = value; 5533227825Stheraven pat.field[3] = sign; 5534227825Stheraven switch (sep_by_space) 5535227825Stheraven { 5536232950Stheraven case 0: // No space separates the currency symbol and value. 5537227825Stheraven pat.field[1] = none; 5538227825Stheraven pat.field[2] = symbol; 5539227825Stheraven return; 5540232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5541232950Stheraven if (!symbol_contains_sep) { 5542232950Stheraven // We insert the space into the symbol instead of 5543232950Stheraven // setting pat.field[1]=space so that when 5544232950Stheraven // showbase is not set, the space goes away too. 5545232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5546232950Stheraven } 5547232950Stheraven pat.field[1] = none; 5548227825Stheraven pat.field[2] = symbol; 5549227825Stheraven return; 5550232950Stheraven case 2: // Space between sign and currency or value. 5551227825Stheraven pat.field[1] = symbol; 5552227825Stheraven pat.field[2] = space; 5553232950Stheraven if (symbol_contains_sep) { 5554232950Stheraven // Remove the separator from the symbol, since it 5555232950Stheraven // should not be removed if showbase is absent. 5556232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5557232950Stheraven } 5558227825Stheraven return; 5559227825Stheraven default: 5560227825Stheraven break; 5561227825Stheraven } 5562227825Stheraven break; 5563232950Stheraven case 3: // The sign string immediately precedes the currency symbol. 5564227825Stheraven pat.field[0] = value; 5565227825Stheraven pat.field[3] = symbol; 5566227825Stheraven switch (sep_by_space) 5567227825Stheraven { 5568232950Stheraven case 0: // No space separates the currency symbol and value. 5569227825Stheraven pat.field[1] = none; 5570227825Stheraven pat.field[2] = sign; 5571227825Stheraven return; 5572232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5573227825Stheraven pat.field[1] = space; 5574227825Stheraven pat.field[2] = sign; 5575232950Stheraven if (symbol_contains_sep) { 5576232950Stheraven // Remove the separator from the symbol, since it 5577232950Stheraven // has already appeared before the sign. 5578232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5579232950Stheraven } 5580227825Stheraven return; 5581232950Stheraven case 2: // Space between sign and currency or value. 5582227825Stheraven pat.field[1] = sign; 5583232950Stheraven pat.field[2] = none; 5584232950Stheraven if (!symbol_contains_sep) { 5585232950Stheraven // We insert the space into the symbol instead of 5586232950Stheraven // setting pat.field[2]=space so that when 5587232950Stheraven // showbase is not set, the space goes away too. 5588232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5589232950Stheraven } 5590227825Stheraven return; 5591227825Stheraven default: 5592227825Stheraven break; 5593227825Stheraven } 5594227825Stheraven break; 5595232950Stheraven case 4: // The sign string immediately succeeds the currency symbol. 5596227825Stheraven pat.field[0] = value; 5597227825Stheraven pat.field[3] = sign; 5598227825Stheraven switch (sep_by_space) 5599227825Stheraven { 5600232950Stheraven case 0: // No space separates the currency symbol and value. 5601227825Stheraven pat.field[1] = none; 5602227825Stheraven pat.field[2] = symbol; 5603227825Stheraven return; 5604232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5605232950Stheraven pat.field[1] = none; 5606227825Stheraven pat.field[2] = symbol; 5607232950Stheraven if (!symbol_contains_sep) { 5608232950Stheraven // We insert the space into the symbol instead of 5609232950Stheraven // setting pat.field[1]=space so that when 5610232950Stheraven // showbase is not set, the space goes away too. 5611232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5612232950Stheraven } 5613227825Stheraven return; 5614232950Stheraven case 2: // Space between sign and currency or value. 5615227825Stheraven pat.field[1] = symbol; 5616227825Stheraven pat.field[2] = space; 5617232950Stheraven if (symbol_contains_sep) { 5618232950Stheraven // Remove the separator from the symbol, since it 5619232950Stheraven // should not disappear when showbase is absent. 5620232950Stheraven __curr_symbol_.erase(__curr_symbol_.begin()); 5621232950Stheraven } 5622227825Stheraven return; 5623227825Stheraven default: 5624227825Stheraven break; 5625227825Stheraven } 5626227825Stheraven break; 5627227825Stheraven default: 5628227825Stheraven break; 5629227825Stheraven } 5630227825Stheraven break; 5631232950Stheraven case 1: // curr_symbol before value 5632227825Stheraven switch (sign_posn) 5633227825Stheraven { 5634232950Stheraven case 0: // Parentheses surround the quantity and currency symbol. 5635227825Stheraven pat.field[0] = sign; 5636227825Stheraven pat.field[1] = symbol; 5637232950Stheraven pat.field[2] = none; // Any space appears in the symbol. 5638227825Stheraven pat.field[3] = value; 5639227825Stheraven switch (sep_by_space) 5640227825Stheraven { 5641232950Stheraven case 0: // No space separates the currency symbol and value. 5642232950Stheraven // This case may have changed between C99 and C11; 5643232950Stheraven // assume the currency symbol matches the intention. 5644232950Stheraven case 2: // Space between sign and currency or value. 5645232950Stheraven // The "sign" is two parentheses, so no space here either. 5646227825Stheraven return; 5647232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5648232950Stheraven if (!symbol_contains_sep) { 5649232950Stheraven // We insert the space into the symbol instead of 5650232950Stheraven // setting pat.field[2]=space so that when 5651232950Stheraven // showbase is not set, the space goes away too. 5652232950Stheraven __curr_symbol_.insert(0, 1, space_char); 5653232950Stheraven } 5654227825Stheraven return; 5655227825Stheraven default: 5656227825Stheraven break; 5657227825Stheraven } 5658227825Stheraven break; 5659232950Stheraven case 1: // The sign string precedes the quantity and currency symbol. 5660227825Stheraven pat.field[0] = sign; 5661227825Stheraven pat.field[3] = value; 5662227825Stheraven switch (sep_by_space) 5663227825Stheraven { 5664232950Stheraven case 0: // No space separates the currency symbol and value. 5665227825Stheraven pat.field[1] = symbol; 5666227825Stheraven pat.field[2] = none; 5667227825Stheraven return; 5668232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5669227825Stheraven pat.field[1] = symbol; 5670232950Stheraven pat.field[2] = none; 5671232950Stheraven if (!symbol_contains_sep) { 5672232950Stheraven // We insert the space into the symbol instead of 5673232950Stheraven // setting pat.field[2]=space so that when 5674232950Stheraven // showbase is not set, the space goes away too. 5675232950Stheraven __curr_symbol_.push_back(space_char); 5676232950Stheraven } 5677227825Stheraven return; 5678232950Stheraven case 2: // Space between sign and currency or value. 5679227825Stheraven pat.field[1] = space; 5680227825Stheraven pat.field[2] = symbol; 5681232950Stheraven if (symbol_contains_sep) { 5682232950Stheraven // Remove the separator from the symbol, since it 5683232950Stheraven // has already appeared after the sign. 5684232950Stheraven __curr_symbol_.pop_back(); 5685232950Stheraven } 5686227825Stheraven return; 5687227825Stheraven default: 5688227825Stheraven break; 5689227825Stheraven } 5690227825Stheraven break; 5691232950Stheraven case 2: // The sign string succeeds the quantity and currency symbol. 5692227825Stheraven pat.field[0] = symbol; 5693227825Stheraven pat.field[3] = sign; 5694227825Stheraven switch (sep_by_space) 5695227825Stheraven { 5696232950Stheraven case 0: // No space separates the currency symbol and value. 5697227825Stheraven pat.field[1] = none; 5698227825Stheraven pat.field[2] = value; 5699227825Stheraven return; 5700232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5701232950Stheraven pat.field[1] = none; 5702227825Stheraven pat.field[2] = value; 5703232950Stheraven if (!symbol_contains_sep) { 5704232950Stheraven // We insert the space into the symbol instead of 5705232950Stheraven // setting pat.field[1]=space so that when 5706232950Stheraven // showbase is not set, the space goes away too. 5707232950Stheraven __curr_symbol_.push_back(space_char); 5708232950Stheraven } 5709227825Stheraven return; 5710232950Stheraven case 2: // Space between sign and currency or value. 5711227825Stheraven pat.field[1] = value; 5712227825Stheraven pat.field[2] = space; 5713232950Stheraven if (symbol_contains_sep) { 5714232950Stheraven // Remove the separator from the symbol, since it 5715232950Stheraven // will appear before the sign. 5716232950Stheraven __curr_symbol_.pop_back(); 5717232950Stheraven } 5718227825Stheraven return; 5719227825Stheraven default: 5720227825Stheraven break; 5721227825Stheraven } 5722227825Stheraven break; 5723232950Stheraven case 3: // The sign string immediately precedes the currency symbol. 5724227825Stheraven pat.field[0] = sign; 5725227825Stheraven pat.field[3] = value; 5726227825Stheraven switch (sep_by_space) 5727227825Stheraven { 5728232950Stheraven case 0: // No space separates the currency symbol and value. 5729227825Stheraven pat.field[1] = symbol; 5730227825Stheraven pat.field[2] = none; 5731227825Stheraven return; 5732232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5733227825Stheraven pat.field[1] = symbol; 5734232950Stheraven pat.field[2] = none; 5735232950Stheraven if (!symbol_contains_sep) { 5736232950Stheraven // We insert the space into the symbol instead of 5737232950Stheraven // setting pat.field[2]=space so that when 5738232950Stheraven // showbase is not set, the space goes away too. 5739232950Stheraven __curr_symbol_.push_back(space_char); 5740232950Stheraven } 5741227825Stheraven return; 5742232950Stheraven case 2: // Space between sign and currency or value. 5743227825Stheraven pat.field[1] = space; 5744227825Stheraven pat.field[2] = symbol; 5745232950Stheraven if (symbol_contains_sep) { 5746232950Stheraven // Remove the separator from the symbol, since it 5747232950Stheraven // has already appeared after the sign. 5748232950Stheraven __curr_symbol_.pop_back(); 5749232950Stheraven } 5750227825Stheraven return; 5751227825Stheraven default: 5752227825Stheraven break; 5753227825Stheraven } 5754227825Stheraven break; 5755232950Stheraven case 4: // The sign string immediately succeeds the currency symbol. 5756227825Stheraven pat.field[0] = symbol; 5757227825Stheraven pat.field[3] = value; 5758227825Stheraven switch (sep_by_space) 5759227825Stheraven { 5760232950Stheraven case 0: // No space separates the currency symbol and value. 5761227825Stheraven pat.field[1] = sign; 5762227825Stheraven pat.field[2] = none; 5763227825Stheraven return; 5764232950Stheraven case 1: // Space between currency-and-sign or currency and value. 5765227825Stheraven pat.field[1] = sign; 5766227825Stheraven pat.field[2] = space; 5767232950Stheraven if (symbol_contains_sep) { 5768232950Stheraven // Remove the separator from the symbol, since it 5769232950Stheraven // should not disappear when showbase is absent. 5770232950Stheraven __curr_symbol_.pop_back(); 5771232950Stheraven } 5772227825Stheraven return; 5773232950Stheraven case 2: // Space between sign and currency or value. 5774232950Stheraven pat.field[1] = none; 5775227825Stheraven pat.field[2] = sign; 5776232950Stheraven if (!symbol_contains_sep) { 5777232950Stheraven // We insert the space into the symbol instead of 5778232950Stheraven // setting pat.field[1]=space so that when 5779232950Stheraven // showbase is not set, the space goes away too. 5780232950Stheraven __curr_symbol_.push_back(space_char); 5781232950Stheraven } 5782227825Stheraven return; 5783227825Stheraven default: 5784227825Stheraven break; 5785227825Stheraven } 5786227825Stheraven break; 5787227825Stheraven default: 5788227825Stheraven break; 5789227825Stheraven } 5790227825Stheraven break; 5791227825Stheraven default: 5792227825Stheraven break; 5793227825Stheraven } 5794227825Stheraven pat.field[0] = symbol; 5795227825Stheraven pat.field[1] = sign; 5796227825Stheraven pat.field[2] = none; 5797227825Stheraven pat.field[3] = value; 5798227825Stheraven} 5799227825Stheraven 5800227825Stheraventemplate<> 5801227825Stheravenvoid 5802227825Stheravenmoneypunct_byname<char, false>::init(const char* nm) 5803227825Stheraven{ 5804227825Stheraven typedef moneypunct<char, false> base; 5805227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5806227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5807232950Stheraven if (loc == nullptr) 5808227825Stheraven throw runtime_error("moneypunct_byname" 5809227825Stheraven " failed to construct for " + string(nm)); 5810227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5811227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5812227825Stheraven lconv* lc = localeconv_l(loc.get()); 5813227825Stheraven#else 5814227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5815227825Stheraven#endif 5816227825Stheraven if (*lc->mon_decimal_point) 5817227825Stheraven __decimal_point_ = *lc->mon_decimal_point; 5818227825Stheraven else 5819227825Stheraven __decimal_point_ = base::do_decimal_point(); 5820227825Stheraven if (*lc->mon_thousands_sep) 5821227825Stheraven __thousands_sep_ = *lc->mon_thousands_sep; 5822227825Stheraven else 5823227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5824227825Stheraven __grouping_ = lc->mon_grouping; 5825227825Stheraven __curr_symbol_ = lc->currency_symbol; 5826227825Stheraven if (lc->frac_digits != CHAR_MAX) 5827227825Stheraven __frac_digits_ = lc->frac_digits; 5828227825Stheraven else 5829227825Stheraven __frac_digits_ = base::do_frac_digits(); 5830227825Stheraven if (lc->p_sign_posn == 0) 5831227825Stheraven __positive_sign_ = "()"; 5832227825Stheraven else 5833227825Stheraven __positive_sign_ = lc->positive_sign; 5834227825Stheraven if (lc->n_sign_posn == 0) 5835227825Stheraven __negative_sign_ = "()"; 5836227825Stheraven else 5837227825Stheraven __negative_sign_ = lc->negative_sign; 5838232950Stheraven // Assume the positive and negative formats will want spaces in 5839232950Stheraven // the same places in curr_symbol since there's no way to 5840232950Stheraven // represent anything else. 5841232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5842232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, false, 5843232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); 5844232950Stheraven __init_pat(__neg_format_, __curr_symbol_, false, 5845232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); 5846227825Stheraven} 5847227825Stheraven 5848227825Stheraventemplate<> 5849227825Stheravenvoid 5850227825Stheravenmoneypunct_byname<char, true>::init(const char* nm) 5851227825Stheraven{ 5852227825Stheraven typedef moneypunct<char, true> base; 5853227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5854227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5855232950Stheraven if (loc == nullptr) 5856227825Stheraven throw runtime_error("moneypunct_byname" 5857227825Stheraven " failed to construct for " + string(nm)); 5858227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5859227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5860227825Stheraven lconv* lc = localeconv_l(loc.get()); 5861227825Stheraven#else 5862227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5863227825Stheraven#endif 5864227825Stheraven if (*lc->mon_decimal_point) 5865227825Stheraven __decimal_point_ = *lc->mon_decimal_point; 5866227825Stheraven else 5867227825Stheraven __decimal_point_ = base::do_decimal_point(); 5868227825Stheraven if (*lc->mon_thousands_sep) 5869227825Stheraven __thousands_sep_ = *lc->mon_thousands_sep; 5870227825Stheraven else 5871227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5872227825Stheraven __grouping_ = lc->mon_grouping; 5873227825Stheraven __curr_symbol_ = lc->int_curr_symbol; 5874227825Stheraven if (lc->int_frac_digits != CHAR_MAX) 5875227825Stheraven __frac_digits_ = lc->int_frac_digits; 5876227825Stheraven else 5877227825Stheraven __frac_digits_ = base::do_frac_digits(); 5878262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 5879227825Stheraven if (lc->p_sign_posn == 0) 5880262801Sdim#else // _LIBCPP_MSVCRT 5881227825Stheraven if (lc->int_p_sign_posn == 0) 5882262801Sdim#endif // !_LIBCPP_MSVCRT 5883227825Stheraven __positive_sign_ = "()"; 5884227825Stheraven else 5885227825Stheraven __positive_sign_ = lc->positive_sign; 5886262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 5887227825Stheraven if(lc->n_sign_posn == 0) 5888262801Sdim#else // _LIBCPP_MSVCRT 5889227825Stheraven if (lc->int_n_sign_posn == 0) 5890262801Sdim#endif // !_LIBCPP_MSVCRT 5891227825Stheraven __negative_sign_ = "()"; 5892227825Stheraven else 5893227825Stheraven __negative_sign_ = lc->negative_sign; 5894232950Stheraven // Assume the positive and negative formats will want spaces in 5895232950Stheraven // the same places in curr_symbol since there's no way to 5896232950Stheraven // represent anything else. 5897232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5898262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 5899232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 5900232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' '); 5901232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 5902232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' '); 5903262801Sdim#else // _LIBCPP_MSVCRT 5904232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 5905232950Stheraven lc->int_p_cs_precedes, lc->int_p_sep_by_space, 5906232950Stheraven lc->int_p_sign_posn, ' '); 5907232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 5908232950Stheraven lc->int_n_cs_precedes, lc->int_n_sep_by_space, 5909232950Stheraven lc->int_n_sign_posn, ' '); 5910262801Sdim#endif // !_LIBCPP_MSVCRT 5911227825Stheraven} 5912227825Stheraven 5913227825Stheraventemplate<> 5914227825Stheravenvoid 5915227825Stheravenmoneypunct_byname<wchar_t, false>::init(const char* nm) 5916227825Stheraven{ 5917227825Stheraven typedef moneypunct<wchar_t, false> base; 5918227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 5919227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 5920232950Stheraven if (loc == nullptr) 5921227825Stheraven throw runtime_error("moneypunct_byname" 5922227825Stheraven " failed to construct for " + string(nm)); 5923227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 5924227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5925227825Stheraven lconv* lc = localeconv_l(loc.get()); 5926227825Stheraven#else 5927227825Stheraven lconv* lc = __localeconv_l(loc.get()); 5928227825Stheraven#endif 5929227825Stheraven if (*lc->mon_decimal_point) 5930227825Stheraven __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 5931227825Stheraven else 5932227825Stheraven __decimal_point_ = base::do_decimal_point(); 5933227825Stheraven if (*lc->mon_thousands_sep) 5934227825Stheraven __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 5935227825Stheraven else 5936227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 5937227825Stheraven __grouping_ = lc->mon_grouping; 5938227825Stheraven wchar_t wbuf[100]; 5939227825Stheraven mbstate_t mb = {0}; 5940227825Stheraven const char* bb = lc->currency_symbol; 5941227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5942246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5943227825Stheraven#else 5944246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5945227825Stheraven#endif 5946232950Stheraven if (j == size_t(-1)) 5947227825Stheraven __throw_runtime_error("locale not supported"); 5948227825Stheraven wchar_t* wbe = wbuf + j; 5949227825Stheraven __curr_symbol_.assign(wbuf, wbe); 5950227825Stheraven if (lc->frac_digits != CHAR_MAX) 5951227825Stheraven __frac_digits_ = lc->frac_digits; 5952227825Stheraven else 5953227825Stheraven __frac_digits_ = base::do_frac_digits(); 5954227825Stheraven if (lc->p_sign_posn == 0) 5955227825Stheraven __positive_sign_ = L"()"; 5956227825Stheraven else 5957227825Stheraven { 5958227825Stheraven mb = mbstate_t(); 5959227825Stheraven bb = lc->positive_sign; 5960227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5961246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5962227825Stheraven#else 5963246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5964227825Stheraven#endif 5965232950Stheraven if (j == size_t(-1)) 5966227825Stheraven __throw_runtime_error("locale not supported"); 5967227825Stheraven wbe = wbuf + j; 5968227825Stheraven __positive_sign_.assign(wbuf, wbe); 5969227825Stheraven } 5970227825Stheraven if (lc->n_sign_posn == 0) 5971227825Stheraven __negative_sign_ = L"()"; 5972227825Stheraven else 5973227825Stheraven { 5974227825Stheraven mb = mbstate_t(); 5975227825Stheraven bb = lc->negative_sign; 5976227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 5977246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5978227825Stheraven#else 5979246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 5980227825Stheraven#endif 5981232950Stheraven if (j == size_t(-1)) 5982227825Stheraven __throw_runtime_error("locale not supported"); 5983227825Stheraven wbe = wbuf + j; 5984227825Stheraven __negative_sign_.assign(wbuf, wbe); 5985227825Stheraven } 5986232950Stheraven // Assume the positive and negative formats will want spaces in 5987232950Stheraven // the same places in curr_symbol since there's no way to 5988232950Stheraven // represent anything else. 5989232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 5990232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, false, 5991232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); 5992232950Stheraven __init_pat(__neg_format_, __curr_symbol_, false, 5993232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); 5994227825Stheraven} 5995227825Stheraven 5996227825Stheraventemplate<> 5997227825Stheravenvoid 5998227825Stheravenmoneypunct_byname<wchar_t, true>::init(const char* nm) 5999227825Stheraven{ 6000227825Stheraven typedef moneypunct<wchar_t, true> base; 6001227825Stheraven __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); 6002227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 6003232950Stheraven if (loc == nullptr) 6004227825Stheraven throw runtime_error("moneypunct_byname" 6005227825Stheraven " failed to construct for " + string(nm)); 6006227825Stheraven#endif // _LIBCPP_NO_EXCEPTIONS 6007227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 6008227825Stheraven lconv* lc = localeconv_l(loc.get()); 6009227825Stheraven#else 6010227825Stheraven lconv* lc = __localeconv_l(loc.get()); 6011227825Stheraven#endif 6012227825Stheraven if (*lc->mon_decimal_point) 6013227825Stheraven __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point); 6014227825Stheraven else 6015227825Stheraven __decimal_point_ = base::do_decimal_point(); 6016227825Stheraven if (*lc->mon_thousands_sep) 6017227825Stheraven __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep); 6018227825Stheraven else 6019227825Stheraven __thousands_sep_ = base::do_thousands_sep(); 6020227825Stheraven __grouping_ = lc->mon_grouping; 6021227825Stheraven wchar_t wbuf[100]; 6022227825Stheraven mbstate_t mb = {0}; 6023227825Stheraven const char* bb = lc->int_curr_symbol; 6024227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 6025246487Stheraven size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6026227825Stheraven#else 6027246487Stheraven size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6028227825Stheraven#endif 6029232950Stheraven if (j == size_t(-1)) 6030227825Stheraven __throw_runtime_error("locale not supported"); 6031227825Stheraven wchar_t* wbe = wbuf + j; 6032227825Stheraven __curr_symbol_.assign(wbuf, wbe); 6033227825Stheraven if (lc->int_frac_digits != CHAR_MAX) 6034227825Stheraven __frac_digits_ = lc->int_frac_digits; 6035227825Stheraven else 6036227825Stheraven __frac_digits_ = base::do_frac_digits(); 6037262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 6038227825Stheraven if (lc->p_sign_posn == 0) 6039262801Sdim#else // _LIBCPP_MSVCRT 6040227825Stheraven if (lc->int_p_sign_posn == 0) 6041262801Sdim#endif // !_LIBCPP_MSVCRT 6042227825Stheraven __positive_sign_ = L"()"; 6043227825Stheraven else 6044227825Stheraven { 6045227825Stheraven mb = mbstate_t(); 6046227825Stheraven bb = lc->positive_sign; 6047227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 6048246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6049227825Stheraven#else 6050246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6051227825Stheraven#endif 6052232950Stheraven if (j == size_t(-1)) 6053227825Stheraven __throw_runtime_error("locale not supported"); 6054227825Stheraven wbe = wbuf + j; 6055227825Stheraven __positive_sign_.assign(wbuf, wbe); 6056227825Stheraven } 6057262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 6058227825Stheraven if (lc->n_sign_posn == 0) 6059262801Sdim#else // _LIBCPP_MSVCRT 6060227825Stheraven if (lc->int_n_sign_posn == 0) 6061262801Sdim#endif // !_LIBCPP_MSVCRT 6062227825Stheraven __negative_sign_ = L"()"; 6063227825Stheraven else 6064227825Stheraven { 6065227825Stheraven mb = mbstate_t(); 6066227825Stheraven bb = lc->negative_sign; 6067227825Stheraven#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 6068246487Stheraven j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6069227825Stheraven#else 6070246487Stheraven j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); 6071227825Stheraven#endif 6072232950Stheraven if (j == size_t(-1)) 6073227825Stheraven __throw_runtime_error("locale not supported"); 6074227825Stheraven wbe = wbuf + j; 6075227825Stheraven __negative_sign_.assign(wbuf, wbe); 6076227825Stheraven } 6077232950Stheraven // Assume the positive and negative formats will want spaces in 6078232950Stheraven // the same places in curr_symbol since there's no way to 6079232950Stheraven // represent anything else. 6080232950Stheraven string_type __dummy_curr_symbol = __curr_symbol_; 6081262801Sdim#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) 6082232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 6083232950Stheraven lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' '); 6084232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 6085232950Stheraven lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' '); 6086262801Sdim#else // _LIBCPP_MSVCRT 6087232950Stheraven __init_pat(__pos_format_, __dummy_curr_symbol, true, 6088232950Stheraven lc->int_p_cs_precedes, lc->int_p_sep_by_space, 6089232950Stheraven lc->int_p_sign_posn, L' '); 6090232950Stheraven __init_pat(__neg_format_, __curr_symbol_, true, 6091232950Stheraven lc->int_n_cs_precedes, lc->int_n_sep_by_space, 6092232950Stheraven lc->int_n_sign_posn, L' '); 6093262801Sdim#endif // !_LIBCPP_MSVCRT 6094227825Stheraven} 6095227825Stheraven 6096227825Stheravenvoid __do_nothing(void*) {} 6097227825Stheraven 6098227825Stheravenvoid __throw_runtime_error(const char* msg) 6099227825Stheraven{ 6100227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 6101227825Stheraven throw runtime_error(msg); 6102249998Sdim#else 6103249998Sdim (void)msg; 6104227825Stheraven#endif 6105227825Stheraven} 6106227825Stheraven 6107227825Stheraventemplate class collate<char>; 6108227825Stheraventemplate class collate<wchar_t>; 6109227825Stheraven 6110227825Stheraventemplate class num_get<char>; 6111227825Stheraventemplate class num_get<wchar_t>; 6112227825Stheraven 6113232950Stheraventemplate struct __num_get<char>; 6114232950Stheraventemplate struct __num_get<wchar_t>; 6115227825Stheraven 6116227825Stheraventemplate class num_put<char>; 6117227825Stheraventemplate class num_put<wchar_t>; 6118227825Stheraven 6119232950Stheraventemplate struct __num_put<char>; 6120232950Stheraventemplate struct __num_put<wchar_t>; 6121227825Stheraven 6122227825Stheraventemplate class time_get<char>; 6123227825Stheraventemplate class time_get<wchar_t>; 6124227825Stheraven 6125227825Stheraventemplate class time_get_byname<char>; 6126227825Stheraventemplate class time_get_byname<wchar_t>; 6127227825Stheraven 6128227825Stheraventemplate class time_put<char>; 6129227825Stheraventemplate class time_put<wchar_t>; 6130227825Stheraven 6131227825Stheraventemplate class time_put_byname<char>; 6132227825Stheraventemplate class time_put_byname<wchar_t>; 6133227825Stheraven 6134227825Stheraventemplate class moneypunct<char, false>; 6135227825Stheraventemplate class moneypunct<char, true>; 6136227825Stheraventemplate class moneypunct<wchar_t, false>; 6137227825Stheraventemplate class moneypunct<wchar_t, true>; 6138227825Stheraven 6139227825Stheraventemplate class moneypunct_byname<char, false>; 6140227825Stheraventemplate class moneypunct_byname<char, true>; 6141227825Stheraventemplate class moneypunct_byname<wchar_t, false>; 6142227825Stheraventemplate class moneypunct_byname<wchar_t, true>; 6143227825Stheraven 6144227825Stheraventemplate class money_get<char>; 6145227825Stheraventemplate class money_get<wchar_t>; 6146227825Stheraven 6147227825Stheraventemplate class __money_get<char>; 6148227825Stheraventemplate class __money_get<wchar_t>; 6149227825Stheraven 6150227825Stheraventemplate class money_put<char>; 6151227825Stheraventemplate class money_put<wchar_t>; 6152227825Stheraven 6153227825Stheraventemplate class __money_put<char>; 6154227825Stheraventemplate class __money_put<wchar_t>; 6155227825Stheraven 6156227825Stheraventemplate class messages<char>; 6157227825Stheraventemplate class messages<wchar_t>; 6158227825Stheraven 6159227825Stheraventemplate class messages_byname<char>; 6160227825Stheraventemplate class messages_byname<wchar_t>; 6161227825Stheraven 6162227825Stheraventemplate class codecvt_byname<char, char, mbstate_t>; 6163227825Stheraventemplate class codecvt_byname<wchar_t, char, mbstate_t>; 6164227825Stheraventemplate class codecvt_byname<char16_t, char, mbstate_t>; 6165227825Stheraventemplate class codecvt_byname<char32_t, char, mbstate_t>; 6166227825Stheraven 6167227825Stheraventemplate class __vector_base_common<true>; 6168227825Stheraven 6169227825Stheraven_LIBCPP_END_NAMESPACE_STD 6170