1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP___LOCALE 11#define _LIBCPP___LOCALE 12 13#include <__config> 14#include <string> 15#include <memory> 16#include <utility> 17#include <mutex> 18#include <cstdint> 19#include <cctype> 20#include <locale.h> 21#if defined(_LIBCPP_MSVCRT_LIKE) 22# include <cstring> 23# include <support/win32/locale_win32.h> 24#elif defined(_AIX) 25# include <support/ibm/xlocale.h> 26#elif defined(__ANDROID__) 27# include <support/android/locale_bionic.h> 28#elif defined(__sun__) 29# include <xlocale.h> 30# include <support/solaris/xlocale.h> 31#elif defined(_NEWLIB_VERSION) 32# include <support/newlib/xlocale.h> 33#elif (defined(__APPLE__) || defined(__FreeBSD__) \ 34 || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)) 35# include <xlocale.h> 36#elif defined(__Fuchsia__) 37# include <support/fuchsia/xlocale.h> 38#elif defined(__wasi__) 39// WASI libc uses musl's locales support. 40# include <support/musl/xlocale.h> 41#elif defined(_LIBCPP_HAS_MUSL_LIBC) 42# include <support/musl/xlocale.h> 43#endif 44 45#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 46#pragma GCC system_header 47#endif 48 49_LIBCPP_BEGIN_NAMESPACE_STD 50 51#if !defined(_LIBCPP_LOCALE__L_EXTENSIONS) 52struct __libcpp_locale_guard { 53 _LIBCPP_INLINE_VISIBILITY 54 __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {} 55 56 _LIBCPP_INLINE_VISIBILITY 57 ~__libcpp_locale_guard() { 58 if (__old_loc_) 59 uselocale(__old_loc_); 60 } 61 62 locale_t __old_loc_; 63private: 64 __libcpp_locale_guard(__libcpp_locale_guard const&); 65 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&); 66}; 67#elif defined(_LIBCPP_MSVCRT_LIKE) 68struct __libcpp_locale_guard { 69 __libcpp_locale_guard(locale_t __l) : 70 __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { 71 // Setting the locale can be expensive even when the locale given is 72 // already the current locale, so do an explicit check to see if the 73 // current locale is already the one we want. 74 const char* __lc = __setlocale(nullptr); 75 // If every category is the same, the locale string will simply be the 76 // locale name, otherwise it will be a semicolon-separated string listing 77 // each category. In the second case, we know at least one category won't 78 // be what we want, so we only have to check the first case. 79 if (strcmp(__l.__get_locale(), __lc) != 0) { 80 __locale_all = _strdup(__lc); 81 if (__locale_all == nullptr) 82 __throw_bad_alloc(); 83 __setlocale(__l.__get_locale()); 84 } 85 } 86 ~__libcpp_locale_guard() { 87 // The CRT documentation doesn't explicitly say, but setlocale() does the 88 // right thing when given a semicolon-separated list of locale settings 89 // for the different categories in the same format as returned by 90 // setlocale(LC_ALL, nullptr). 91 if (__locale_all != nullptr) { 92 __setlocale(__locale_all); 93 free(__locale_all); 94 } 95 _configthreadlocale(__status); 96 } 97 static const char* __setlocale(const char* __locale) { 98 const char* __new_locale = setlocale(LC_ALL, __locale); 99 if (__new_locale == nullptr) 100 __throw_bad_alloc(); 101 return __new_locale; 102 } 103 int __status; 104 char* __locale_all = nullptr; 105}; 106#endif 107 108 109class _LIBCPP_TYPE_VIS locale; 110 111template <class _Facet> 112_LIBCPP_INLINE_VISIBILITY 113bool 114has_facet(const locale&) _NOEXCEPT; 115 116template <class _Facet> 117_LIBCPP_INLINE_VISIBILITY 118const _Facet& 119use_facet(const locale&); 120 121class _LIBCPP_TYPE_VIS locale 122{ 123public: 124 // types: 125 class _LIBCPP_TYPE_VIS facet; 126 class _LIBCPP_TYPE_VIS id; 127 128 typedef int category; 129 _LIBCPP_AVAILABILITY_LOCALE_CATEGORY 130 static const category // values assigned here are for exposition only 131 none = 0, 132 collate = LC_COLLATE_MASK, 133 ctype = LC_CTYPE_MASK, 134 monetary = LC_MONETARY_MASK, 135 numeric = LC_NUMERIC_MASK, 136 time = LC_TIME_MASK, 137 messages = LC_MESSAGES_MASK, 138 all = collate | ctype | monetary | numeric | time | messages; 139 140 // construct/copy/destroy: 141 locale() _NOEXCEPT; 142 locale(const locale&) _NOEXCEPT; 143 explicit locale(const char*); 144 explicit locale(const string&); 145 locale(const locale&, const char*, category); 146 locale(const locale&, const string&, category); 147 template <class _Facet> 148 _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*); 149 locale(const locale&, const locale&, category); 150 151 ~locale(); 152 153 const locale& operator=(const locale&) _NOEXCEPT; 154 155 template <class _Facet> 156 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 157 locale combine(const locale&) const; 158 159 // locale operations: 160 string name() const; 161 bool operator==(const locale&) const; 162 bool operator!=(const locale& __y) const {return !(*this == __y);} 163 template <class _CharT, class _Traits, class _Allocator> 164 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 165 bool operator()(const basic_string<_CharT, _Traits, _Allocator>&, 166 const basic_string<_CharT, _Traits, _Allocator>&) const; 167 168 // global locale objects: 169 static locale global(const locale&); 170 static const locale& classic(); 171 172private: 173 class __imp; 174 __imp* __locale_; 175 176 void __install_ctor(const locale&, facet*, long); 177 static locale& __global(); 178 bool has_facet(id&) const; 179 const facet* use_facet(id&) const; 180 181 template <class _Facet> friend bool has_facet(const locale&) _NOEXCEPT; 182 template <class _Facet> friend const _Facet& use_facet(const locale&); 183}; 184 185class _LIBCPP_TYPE_VIS locale::facet 186 : public __shared_count 187{ 188protected: 189 _LIBCPP_INLINE_VISIBILITY 190 explicit facet(size_t __refs = 0) 191 : __shared_count(static_cast<long>(__refs)-1) {} 192 193 virtual ~facet(); 194 195// facet(const facet&) = delete; // effectively done in __shared_count 196// void operator=(const facet&) = delete; 197private: 198 virtual void __on_zero_shared() _NOEXCEPT; 199}; 200 201class _LIBCPP_TYPE_VIS locale::id 202{ 203 once_flag __flag_; 204 int32_t __id_; 205 206 static int32_t __next_id; 207public: 208 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {} 209private: 210 void __init(); 211 void operator=(const id&); // = delete; 212 id(const id&); // = delete; 213public: // only needed for tests 214 long __get(); 215 216 friend class locale; 217 friend class locale::__imp; 218}; 219 220template <class _Facet> 221inline _LIBCPP_INLINE_VISIBILITY 222locale::locale(const locale& __other, _Facet* __f) 223{ 224 __install_ctor(__other, __f, __f ? __f->id.__get() : 0); 225} 226 227template <class _Facet> 228locale 229locale::combine(const locale& __other) const 230{ 231 if (!_VSTD::has_facet<_Facet>(__other)) 232 __throw_runtime_error("locale::combine: locale missing facet"); 233 234 return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other))); 235} 236 237template <class _Facet> 238inline _LIBCPP_INLINE_VISIBILITY 239bool 240has_facet(const locale& __l) _NOEXCEPT 241{ 242 return __l.has_facet(_Facet::id); 243} 244 245template <class _Facet> 246inline _LIBCPP_INLINE_VISIBILITY 247const _Facet& 248use_facet(const locale& __l) 249{ 250 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id)); 251} 252 253// template <class _CharT> class collate; 254 255template <class _CharT> 256class _LIBCPP_TEMPLATE_VIS collate 257 : public locale::facet 258{ 259public: 260 typedef _CharT char_type; 261 typedef basic_string<char_type> string_type; 262 263 _LIBCPP_INLINE_VISIBILITY 264 explicit collate(size_t __refs = 0) 265 : locale::facet(__refs) {} 266 267 _LIBCPP_INLINE_VISIBILITY 268 int compare(const char_type* __lo1, const char_type* __hi1, 269 const char_type* __lo2, const char_type* __hi2) const 270 { 271 return do_compare(__lo1, __hi1, __lo2, __hi2); 272 } 273 274 // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work 275 // around a dllimport bug that expects an external instantiation. 276 _LIBCPP_INLINE_VISIBILITY 277 _LIBCPP_ALWAYS_INLINE 278 string_type transform(const char_type* __lo, const char_type* __hi) const 279 { 280 return do_transform(__lo, __hi); 281 } 282 283 _LIBCPP_INLINE_VISIBILITY 284 long hash(const char_type* __lo, const char_type* __hi) const 285 { 286 return do_hash(__lo, __hi); 287 } 288 289 static locale::id id; 290 291protected: 292 ~collate(); 293 virtual int do_compare(const char_type* __lo1, const char_type* __hi1, 294 const char_type* __lo2, const char_type* __hi2) const; 295 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const 296 {return string_type(__lo, __hi);} 297 virtual long do_hash(const char_type* __lo, const char_type* __hi) const; 298}; 299 300template <class _CharT> locale::id collate<_CharT>::id; 301 302template <class _CharT> 303collate<_CharT>::~collate() 304{ 305} 306 307template <class _CharT> 308int 309collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1, 310 const char_type* __lo2, const char_type* __hi2) const 311{ 312 for (; __lo2 != __hi2; ++__lo1, ++__lo2) 313 { 314 if (__lo1 == __hi1 || *__lo1 < *__lo2) 315 return -1; 316 if (*__lo2 < *__lo1) 317 return 1; 318 } 319 return __lo1 != __hi1; 320} 321 322template <class _CharT> 323long 324collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const 325{ 326 size_t __h = 0; 327 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8; 328 const size_t __mask = size_t(0xF) << (__sr + 4); 329 for(const char_type* __p = __lo; __p != __hi; ++__p) 330 { 331 __h = (__h << 4) + static_cast<size_t>(*__p); 332 size_t __g = __h & __mask; 333 __h ^= __g | (__g >> __sr); 334 } 335 return static_cast<long>(__h); 336} 337 338_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>) 339_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>) 340 341// template <class CharT> class collate_byname; 342 343template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname; 344 345template <> 346class _LIBCPP_TYPE_VIS collate_byname<char> 347 : public collate<char> 348{ 349 locale_t __l; 350public: 351 typedef char char_type; 352 typedef basic_string<char_type> string_type; 353 354 explicit collate_byname(const char* __n, size_t __refs = 0); 355 explicit collate_byname(const string& __n, size_t __refs = 0); 356 357protected: 358 ~collate_byname(); 359 virtual int do_compare(const char_type* __lo1, const char_type* __hi1, 360 const char_type* __lo2, const char_type* __hi2) const; 361 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; 362}; 363 364template <> 365class _LIBCPP_TYPE_VIS collate_byname<wchar_t> 366 : public collate<wchar_t> 367{ 368 locale_t __l; 369public: 370 typedef wchar_t char_type; 371 typedef basic_string<char_type> string_type; 372 373 explicit collate_byname(const char* __n, size_t __refs = 0); 374 explicit collate_byname(const string& __n, size_t __refs = 0); 375 376protected: 377 ~collate_byname(); 378 379 virtual int do_compare(const char_type* __lo1, const char_type* __hi1, 380 const char_type* __lo2, const char_type* __hi2) const; 381 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const; 382}; 383 384template <class _CharT, class _Traits, class _Allocator> 385bool 386locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, 387 const basic_string<_CharT, _Traits, _Allocator>& __y) const 388{ 389 return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare( 390 __x.data(), __x.data() + __x.size(), 391 __y.data(), __y.data() + __y.size()) < 0; 392} 393 394// template <class charT> class ctype 395 396class _LIBCPP_TYPE_VIS ctype_base 397{ 398public: 399#if defined(__GLIBC__) 400 typedef unsigned short mask; 401 static const mask space = _ISspace; 402 static const mask print = _ISprint; 403 static const mask cntrl = _IScntrl; 404 static const mask upper = _ISupper; 405 static const mask lower = _ISlower; 406 static const mask alpha = _ISalpha; 407 static const mask digit = _ISdigit; 408 static const mask punct = _ISpunct; 409 static const mask xdigit = _ISxdigit; 410 static const mask blank = _ISblank; 411#if defined(__mips__) 412 static const mask __regex_word = static_cast<mask>(_ISbit(15)); 413#else 414 static const mask __regex_word = 0x80; 415#endif 416#elif defined(_LIBCPP_MSVCRT_LIKE) 417 typedef unsigned short mask; 418 static const mask space = _SPACE; 419 static const mask print = _BLANK|_PUNCT|_ALPHA|_DIGIT; 420 static const mask cntrl = _CONTROL; 421 static const mask upper = _UPPER; 422 static const mask lower = _LOWER; 423 static const mask alpha = _ALPHA; 424 static const mask digit = _DIGIT; 425 static const mask punct = _PUNCT; 426 static const mask xdigit = _HEX; 427 static const mask blank = _BLANK; 428 static const mask __regex_word = 0x80; 429# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT 430#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 431# ifdef __APPLE__ 432 typedef __uint32_t mask; 433# elif defined(__FreeBSD__) 434 typedef unsigned long mask; 435# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) 436 typedef unsigned short mask; 437# endif 438 static const mask space = _CTYPE_S; 439 static const mask print = _CTYPE_R; 440 static const mask cntrl = _CTYPE_C; 441 static const mask upper = _CTYPE_U; 442 static const mask lower = _CTYPE_L; 443 static const mask alpha = _CTYPE_A; 444 static const mask digit = _CTYPE_D; 445 static const mask punct = _CTYPE_P; 446 static const mask xdigit = _CTYPE_X; 447 448# if defined(__NetBSD__) 449 static const mask blank = _CTYPE_BL; 450 // NetBSD defines classes up to 0x2000 451 // see sys/ctype_bits.h, _CTYPE_Q 452 static const mask __regex_word = 0x8000; 453# else 454 static const mask blank = _CTYPE_B; 455 static const mask __regex_word = 0x80; 456# endif 457#elif defined(__sun__) || defined(_AIX) 458 typedef unsigned int mask; 459 static const mask space = _ISSPACE; 460 static const mask print = _ISPRINT; 461 static const mask cntrl = _ISCNTRL; 462 static const mask upper = _ISUPPER; 463 static const mask lower = _ISLOWER; 464 static const mask alpha = _ISALPHA; 465 static const mask digit = _ISDIGIT; 466 static const mask punct = _ISPUNCT; 467 static const mask xdigit = _ISXDIGIT; 468 static const mask blank = _ISBLANK; 469 static const mask __regex_word = 0x80; 470#elif defined(_NEWLIB_VERSION) 471 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. 472 typedef char mask; 473 static const mask space = _S; 474 static const mask print = _P | _U | _L | _N | _B; 475 static const mask cntrl = _C; 476 static const mask upper = _U; 477 static const mask lower = _L; 478 static const mask alpha = _U | _L; 479 static const mask digit = _N; 480 static const mask punct = _P; 481 static const mask xdigit = _X | _N; 482 static const mask blank = _B; 483 static const mask __regex_word = 0x80; 484# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT 485# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA 486# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT 487#else 488 typedef unsigned long mask; 489 static const mask space = 1<<0; 490 static const mask print = 1<<1; 491 static const mask cntrl = 1<<2; 492 static const mask upper = 1<<3; 493 static const mask lower = 1<<4; 494 static const mask alpha = 1<<5; 495 static const mask digit = 1<<6; 496 static const mask punct = 1<<7; 497 static const mask xdigit = 1<<8; 498 static const mask blank = 1<<9; 499#if defined(__BIONIC__) 500 // Historically this was a part of regex_traits rather than ctype_base. The 501 // historical value of the constant is preserved for ABI compatibility. 502 static const mask __regex_word = 0x8000; 503#else 504 static const mask __regex_word = 1<<10; 505#endif // defined(__BIONIC__) 506#endif 507 static const mask alnum = alpha | digit; 508 static const mask graph = alnum | punct; 509 510 _LIBCPP_INLINE_VISIBILITY ctype_base() {} 511}; 512 513template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype; 514 515template <> 516class _LIBCPP_TYPE_VIS ctype<wchar_t> 517 : public locale::facet, 518 public ctype_base 519{ 520public: 521 typedef wchar_t char_type; 522 523 _LIBCPP_INLINE_VISIBILITY 524 explicit ctype(size_t __refs = 0) 525 : locale::facet(__refs) {} 526 527 _LIBCPP_INLINE_VISIBILITY 528 bool is(mask __m, char_type __c) const 529 { 530 return do_is(__m, __c); 531 } 532 533 _LIBCPP_INLINE_VISIBILITY 534 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const 535 { 536 return do_is(__low, __high, __vec); 537 } 538 539 _LIBCPP_INLINE_VISIBILITY 540 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const 541 { 542 return do_scan_is(__m, __low, __high); 543 } 544 545 _LIBCPP_INLINE_VISIBILITY 546 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const 547 { 548 return do_scan_not(__m, __low, __high); 549 } 550 551 _LIBCPP_INLINE_VISIBILITY 552 char_type toupper(char_type __c) const 553 { 554 return do_toupper(__c); 555 } 556 557 _LIBCPP_INLINE_VISIBILITY 558 const char_type* toupper(char_type* __low, const char_type* __high) const 559 { 560 return do_toupper(__low, __high); 561 } 562 563 _LIBCPP_INLINE_VISIBILITY 564 char_type tolower(char_type __c) const 565 { 566 return do_tolower(__c); 567 } 568 569 _LIBCPP_INLINE_VISIBILITY 570 const char_type* tolower(char_type* __low, const char_type* __high) const 571 { 572 return do_tolower(__low, __high); 573 } 574 575 _LIBCPP_INLINE_VISIBILITY 576 char_type widen(char __c) const 577 { 578 return do_widen(__c); 579 } 580 581 _LIBCPP_INLINE_VISIBILITY 582 const char* widen(const char* __low, const char* __high, char_type* __to) const 583 { 584 return do_widen(__low, __high, __to); 585 } 586 587 _LIBCPP_INLINE_VISIBILITY 588 char narrow(char_type __c, char __dfault) const 589 { 590 return do_narrow(__c, __dfault); 591 } 592 593 _LIBCPP_INLINE_VISIBILITY 594 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const 595 { 596 return do_narrow(__low, __high, __dfault, __to); 597 } 598 599 static locale::id id; 600 601protected: 602 ~ctype(); 603 virtual bool do_is(mask __m, char_type __c) const; 604 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; 605 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; 606 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; 607 virtual char_type do_toupper(char_type) const; 608 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 609 virtual char_type do_tolower(char_type) const; 610 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 611 virtual char_type do_widen(char) const; 612 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; 613 virtual char do_narrow(char_type, char __dfault) const; 614 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; 615}; 616 617template <> 618class _LIBCPP_TYPE_VIS ctype<char> 619 : public locale::facet, public ctype_base 620{ 621 const mask* __tab_; 622 bool __del_; 623public: 624 typedef char char_type; 625 626 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0); 627 628 _LIBCPP_INLINE_VISIBILITY 629 bool is(mask __m, char_type __c) const 630 { 631 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false; 632 } 633 634 _LIBCPP_INLINE_VISIBILITY 635 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const 636 { 637 for (; __low != __high; ++__low, ++__vec) 638 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0; 639 return __low; 640 } 641 642 _LIBCPP_INLINE_VISIBILITY 643 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const 644 { 645 for (; __low != __high; ++__low) 646 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)) 647 break; 648 return __low; 649 } 650 651 _LIBCPP_INLINE_VISIBILITY 652 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const 653 { 654 for (; __low != __high; ++__low) 655 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))) 656 break; 657 return __low; 658 } 659 660 _LIBCPP_INLINE_VISIBILITY 661 char_type toupper(char_type __c) const 662 { 663 return do_toupper(__c); 664 } 665 666 _LIBCPP_INLINE_VISIBILITY 667 const char_type* toupper(char_type* __low, const char_type* __high) const 668 { 669 return do_toupper(__low, __high); 670 } 671 672 _LIBCPP_INLINE_VISIBILITY 673 char_type tolower(char_type __c) const 674 { 675 return do_tolower(__c); 676 } 677 678 _LIBCPP_INLINE_VISIBILITY 679 const char_type* tolower(char_type* __low, const char_type* __high) const 680 { 681 return do_tolower(__low, __high); 682 } 683 684 _LIBCPP_INLINE_VISIBILITY 685 char_type widen(char __c) const 686 { 687 return do_widen(__c); 688 } 689 690 _LIBCPP_INLINE_VISIBILITY 691 const char* widen(const char* __low, const char* __high, char_type* __to) const 692 { 693 return do_widen(__low, __high, __to); 694 } 695 696 _LIBCPP_INLINE_VISIBILITY 697 char narrow(char_type __c, char __dfault) const 698 { 699 return do_narrow(__c, __dfault); 700 } 701 702 _LIBCPP_INLINE_VISIBILITY 703 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const 704 { 705 return do_narrow(__low, __high, __dfault, __to); 706 } 707 708 static locale::id id; 709 710#ifdef _CACHED_RUNES 711 static const size_t table_size = _CACHED_RUNES; 712#else 713 static const size_t table_size = 256; // FIXME: Don't hardcode this. 714#endif 715 _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;} 716 static const mask* classic_table() _NOEXCEPT; 717#if defined(__GLIBC__) || defined(__EMSCRIPTEN__) 718 static const int* __classic_upper_table() _NOEXCEPT; 719 static const int* __classic_lower_table() _NOEXCEPT; 720#endif 721#if defined(__NetBSD__) 722 static const short* __classic_upper_table() _NOEXCEPT; 723 static const short* __classic_lower_table() _NOEXCEPT; 724#endif 725 726protected: 727 ~ctype(); 728 virtual char_type do_toupper(char_type __c) const; 729 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 730 virtual char_type do_tolower(char_type __c) const; 731 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 732 virtual char_type do_widen(char __c) const; 733 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const; 734 virtual char do_narrow(char_type __c, char __dfault) const; 735 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const; 736}; 737 738// template <class CharT> class ctype_byname; 739 740template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname; 741 742template <> 743class _LIBCPP_TYPE_VIS ctype_byname<char> 744 : public ctype<char> 745{ 746 locale_t __l; 747 748public: 749 explicit ctype_byname(const char*, size_t = 0); 750 explicit ctype_byname(const string&, size_t = 0); 751 752protected: 753 ~ctype_byname(); 754 virtual char_type do_toupper(char_type) const; 755 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 756 virtual char_type do_tolower(char_type) const; 757 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 758}; 759 760template <> 761class _LIBCPP_TYPE_VIS ctype_byname<wchar_t> 762 : public ctype<wchar_t> 763{ 764 locale_t __l; 765 766public: 767 explicit ctype_byname(const char*, size_t = 0); 768 explicit ctype_byname(const string&, size_t = 0); 769 770protected: 771 ~ctype_byname(); 772 virtual bool do_is(mask __m, char_type __c) const; 773 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; 774 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; 775 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; 776 virtual char_type do_toupper(char_type) const; 777 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 778 virtual char_type do_tolower(char_type) const; 779 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 780 virtual char_type do_widen(char) const; 781 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; 782 virtual char do_narrow(char_type, char __dfault) const; 783 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; 784}; 785 786template <class _CharT> 787inline _LIBCPP_INLINE_VISIBILITY 788bool 789isspace(_CharT __c, const locale& __loc) 790{ 791 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); 792} 793 794template <class _CharT> 795inline _LIBCPP_INLINE_VISIBILITY 796bool 797isprint(_CharT __c, const locale& __loc) 798{ 799 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); 800} 801 802template <class _CharT> 803inline _LIBCPP_INLINE_VISIBILITY 804bool 805iscntrl(_CharT __c, const locale& __loc) 806{ 807 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); 808} 809 810template <class _CharT> 811inline _LIBCPP_INLINE_VISIBILITY 812bool 813isupper(_CharT __c, const locale& __loc) 814{ 815 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); 816} 817 818template <class _CharT> 819inline _LIBCPP_INLINE_VISIBILITY 820bool 821islower(_CharT __c, const locale& __loc) 822{ 823 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); 824} 825 826template <class _CharT> 827inline _LIBCPP_INLINE_VISIBILITY 828bool 829isalpha(_CharT __c, const locale& __loc) 830{ 831 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); 832} 833 834template <class _CharT> 835inline _LIBCPP_INLINE_VISIBILITY 836bool 837isdigit(_CharT __c, const locale& __loc) 838{ 839 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); 840} 841 842template <class _CharT> 843inline _LIBCPP_INLINE_VISIBILITY 844bool 845ispunct(_CharT __c, const locale& __loc) 846{ 847 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); 848} 849 850template <class _CharT> 851inline _LIBCPP_INLINE_VISIBILITY 852bool 853isxdigit(_CharT __c, const locale& __loc) 854{ 855 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); 856} 857 858template <class _CharT> 859inline _LIBCPP_INLINE_VISIBILITY 860bool 861isalnum(_CharT __c, const locale& __loc) 862{ 863 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); 864} 865 866template <class _CharT> 867inline _LIBCPP_INLINE_VISIBILITY 868bool 869isgraph(_CharT __c, const locale& __loc) 870{ 871 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); 872} 873 874template <class _CharT> 875inline _LIBCPP_INLINE_VISIBILITY 876_CharT 877toupper(_CharT __c, const locale& __loc) 878{ 879 return use_facet<ctype<_CharT> >(__loc).toupper(__c); 880} 881 882template <class _CharT> 883inline _LIBCPP_INLINE_VISIBILITY 884_CharT 885tolower(_CharT __c, const locale& __loc) 886{ 887 return use_facet<ctype<_CharT> >(__loc).tolower(__c); 888} 889 890// codecvt_base 891 892class _LIBCPP_TYPE_VIS codecvt_base 893{ 894public: 895 _LIBCPP_INLINE_VISIBILITY codecvt_base() {} 896 enum result {ok, partial, error, noconv}; 897}; 898 899// template <class internT, class externT, class stateT> class codecvt; 900 901template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt; 902 903// template <> class codecvt<char, char, mbstate_t> 904 905template <> 906class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t> 907 : public locale::facet, 908 public codecvt_base 909{ 910public: 911 typedef char intern_type; 912 typedef char extern_type; 913 typedef mbstate_t state_type; 914 915 _LIBCPP_INLINE_VISIBILITY 916 explicit codecvt(size_t __refs = 0) 917 : locale::facet(__refs) {} 918 919 _LIBCPP_INLINE_VISIBILITY 920 result out(state_type& __st, 921 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 922 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 923 { 924 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 925 } 926 927 _LIBCPP_INLINE_VISIBILITY 928 result unshift(state_type& __st, 929 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 930 { 931 return do_unshift(__st, __to, __to_end, __to_nxt); 932 } 933 934 _LIBCPP_INLINE_VISIBILITY 935 result in(state_type& __st, 936 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 937 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 938 { 939 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 940 } 941 942 _LIBCPP_INLINE_VISIBILITY 943 int encoding() const _NOEXCEPT 944 { 945 return do_encoding(); 946 } 947 948 _LIBCPP_INLINE_VISIBILITY 949 bool always_noconv() const _NOEXCEPT 950 { 951 return do_always_noconv(); 952 } 953 954 _LIBCPP_INLINE_VISIBILITY 955 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 956 { 957 return do_length(__st, __frm, __end, __mx); 958 } 959 960 _LIBCPP_INLINE_VISIBILITY 961 int max_length() const _NOEXCEPT 962 { 963 return do_max_length(); 964 } 965 966 static locale::id id; 967 968protected: 969 _LIBCPP_INLINE_VISIBILITY 970 explicit codecvt(const char*, size_t __refs = 0) 971 : locale::facet(__refs) {} 972 973 ~codecvt(); 974 975 virtual result do_out(state_type& __st, 976 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 977 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 978 virtual result do_in(state_type& __st, 979 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 980 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 981 virtual result do_unshift(state_type& __st, 982 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 983 virtual int do_encoding() const _NOEXCEPT; 984 virtual bool do_always_noconv() const _NOEXCEPT; 985 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 986 virtual int do_max_length() const _NOEXCEPT; 987}; 988 989// template <> class codecvt<wchar_t, char, mbstate_t> 990 991template <> 992class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t> 993 : public locale::facet, 994 public codecvt_base 995{ 996 locale_t __l; 997public: 998 typedef wchar_t intern_type; 999 typedef char extern_type; 1000 typedef mbstate_t state_type; 1001 1002 explicit codecvt(size_t __refs = 0); 1003 1004 _LIBCPP_INLINE_VISIBILITY 1005 result out(state_type& __st, 1006 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1007 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1008 { 1009 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1010 } 1011 1012 _LIBCPP_INLINE_VISIBILITY 1013 result unshift(state_type& __st, 1014 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1015 { 1016 return do_unshift(__st, __to, __to_end, __to_nxt); 1017 } 1018 1019 _LIBCPP_INLINE_VISIBILITY 1020 result in(state_type& __st, 1021 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1022 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1023 { 1024 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1025 } 1026 1027 _LIBCPP_INLINE_VISIBILITY 1028 int encoding() const _NOEXCEPT 1029 { 1030 return do_encoding(); 1031 } 1032 1033 _LIBCPP_INLINE_VISIBILITY 1034 bool always_noconv() const _NOEXCEPT 1035 { 1036 return do_always_noconv(); 1037 } 1038 1039 _LIBCPP_INLINE_VISIBILITY 1040 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1041 { 1042 return do_length(__st, __frm, __end, __mx); 1043 } 1044 1045 _LIBCPP_INLINE_VISIBILITY 1046 int max_length() const _NOEXCEPT 1047 { 1048 return do_max_length(); 1049 } 1050 1051 static locale::id id; 1052 1053protected: 1054 explicit codecvt(const char*, size_t __refs = 0); 1055 1056 ~codecvt(); 1057 1058 virtual result do_out(state_type& __st, 1059 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1060 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1061 virtual result do_in(state_type& __st, 1062 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1063 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1064 virtual result do_unshift(state_type& __st, 1065 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1066 virtual int do_encoding() const _NOEXCEPT; 1067 virtual bool do_always_noconv() const _NOEXCEPT; 1068 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1069 virtual int do_max_length() const _NOEXCEPT; 1070}; 1071 1072// template <> class codecvt<char16_t, char, mbstate_t> 1073 1074template <> 1075class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t> 1076 : public locale::facet, 1077 public codecvt_base 1078{ 1079public: 1080 typedef char16_t intern_type; 1081 typedef char extern_type; 1082 typedef mbstate_t state_type; 1083 1084 _LIBCPP_INLINE_VISIBILITY 1085 explicit codecvt(size_t __refs = 0) 1086 : locale::facet(__refs) {} 1087 1088 _LIBCPP_INLINE_VISIBILITY 1089 result out(state_type& __st, 1090 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1091 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1092 { 1093 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1094 } 1095 1096 _LIBCPP_INLINE_VISIBILITY 1097 result unshift(state_type& __st, 1098 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1099 { 1100 return do_unshift(__st, __to, __to_end, __to_nxt); 1101 } 1102 1103 _LIBCPP_INLINE_VISIBILITY 1104 result in(state_type& __st, 1105 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1106 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1107 { 1108 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1109 } 1110 1111 _LIBCPP_INLINE_VISIBILITY 1112 int encoding() const _NOEXCEPT 1113 { 1114 return do_encoding(); 1115 } 1116 1117 _LIBCPP_INLINE_VISIBILITY 1118 bool always_noconv() const _NOEXCEPT 1119 { 1120 return do_always_noconv(); 1121 } 1122 1123 _LIBCPP_INLINE_VISIBILITY 1124 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1125 { 1126 return do_length(__st, __frm, __end, __mx); 1127 } 1128 1129 _LIBCPP_INLINE_VISIBILITY 1130 int max_length() const _NOEXCEPT 1131 { 1132 return do_max_length(); 1133 } 1134 1135 static locale::id id; 1136 1137protected: 1138 _LIBCPP_INLINE_VISIBILITY 1139 explicit codecvt(const char*, size_t __refs = 0) 1140 : locale::facet(__refs) {} 1141 1142 ~codecvt(); 1143 1144 virtual result do_out(state_type& __st, 1145 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1146 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1147 virtual result do_in(state_type& __st, 1148 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1149 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1150 virtual result do_unshift(state_type& __st, 1151 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1152 virtual int do_encoding() const _NOEXCEPT; 1153 virtual bool do_always_noconv() const _NOEXCEPT; 1154 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1155 virtual int do_max_length() const _NOEXCEPT; 1156}; 1157 1158// template <> class codecvt<char32_t, char, mbstate_t> 1159 1160template <> 1161class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t> 1162 : public locale::facet, 1163 public codecvt_base 1164{ 1165public: 1166 typedef char32_t intern_type; 1167 typedef char extern_type; 1168 typedef mbstate_t state_type; 1169 1170 _LIBCPP_INLINE_VISIBILITY 1171 explicit codecvt(size_t __refs = 0) 1172 : locale::facet(__refs) {} 1173 1174 _LIBCPP_INLINE_VISIBILITY 1175 result out(state_type& __st, 1176 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1177 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1178 { 1179 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1180 } 1181 1182 _LIBCPP_INLINE_VISIBILITY 1183 result unshift(state_type& __st, 1184 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1185 { 1186 return do_unshift(__st, __to, __to_end, __to_nxt); 1187 } 1188 1189 _LIBCPP_INLINE_VISIBILITY 1190 result in(state_type& __st, 1191 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1192 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1193 { 1194 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1195 } 1196 1197 _LIBCPP_INLINE_VISIBILITY 1198 int encoding() const _NOEXCEPT 1199 { 1200 return do_encoding(); 1201 } 1202 1203 _LIBCPP_INLINE_VISIBILITY 1204 bool always_noconv() const _NOEXCEPT 1205 { 1206 return do_always_noconv(); 1207 } 1208 1209 _LIBCPP_INLINE_VISIBILITY 1210 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1211 { 1212 return do_length(__st, __frm, __end, __mx); 1213 } 1214 1215 _LIBCPP_INLINE_VISIBILITY 1216 int max_length() const _NOEXCEPT 1217 { 1218 return do_max_length(); 1219 } 1220 1221 static locale::id id; 1222 1223protected: 1224 _LIBCPP_INLINE_VISIBILITY 1225 explicit codecvt(const char*, size_t __refs = 0) 1226 : locale::facet(__refs) {} 1227 1228 ~codecvt(); 1229 1230 virtual result do_out(state_type& __st, 1231 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1232 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1233 virtual result do_in(state_type& __st, 1234 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1235 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1236 virtual result do_unshift(state_type& __st, 1237 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1238 virtual int do_encoding() const _NOEXCEPT; 1239 virtual bool do_always_noconv() const _NOEXCEPT; 1240 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1241 virtual int do_max_length() const _NOEXCEPT; 1242}; 1243 1244// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname 1245 1246template <class _InternT, class _ExternT, class _StateT> 1247class _LIBCPP_TEMPLATE_VIS codecvt_byname 1248 : public codecvt<_InternT, _ExternT, _StateT> 1249{ 1250public: 1251 _LIBCPP_INLINE_VISIBILITY 1252 explicit codecvt_byname(const char* __nm, size_t __refs = 0) 1253 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} 1254 _LIBCPP_INLINE_VISIBILITY 1255 explicit codecvt_byname(const string& __nm, size_t __refs = 0) 1256 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} 1257protected: 1258 ~codecvt_byname(); 1259}; 1260 1261template <class _InternT, class _ExternT, class _StateT> 1262codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() 1263{ 1264} 1265 1266_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>) 1267_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>) 1268_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>) 1269_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>) 1270 1271template <size_t _Np> 1272struct __narrow_to_utf8 1273{ 1274 template <class _OutputIterator, class _CharT> 1275 _OutputIterator 1276 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; 1277}; 1278 1279template <> 1280struct __narrow_to_utf8<8> 1281{ 1282 template <class _OutputIterator, class _CharT> 1283 _LIBCPP_INLINE_VISIBILITY 1284 _OutputIterator 1285 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1286 { 1287 for (; __wb < __we; ++__wb, ++__s) 1288 *__s = *__wb; 1289 return __s; 1290 } 1291}; 1292 1293template <> 1294struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> 1295 : public codecvt<char16_t, char, mbstate_t> 1296{ 1297 _LIBCPP_INLINE_VISIBILITY 1298 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1299 1300 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); 1301 1302 template <class _OutputIterator, class _CharT> 1303 _LIBCPP_INLINE_VISIBILITY 1304 _OutputIterator 1305 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1306 { 1307 result __r = ok; 1308 mbstate_t __mb; 1309 while (__wb < __we && __r != error) 1310 { 1311 const int __sz = 32; 1312 char __buf[__sz]; 1313 char* __bn; 1314 const char16_t* __wn = (const char16_t*)__wb; 1315 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, 1316 __buf, __buf+__sz, __bn); 1317 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) 1318 __throw_runtime_error("locale not supported"); 1319 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1320 *__s = *__p; 1321 __wb = (const _CharT*)__wn; 1322 } 1323 return __s; 1324 } 1325}; 1326 1327template <> 1328struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> 1329 : public codecvt<char32_t, char, mbstate_t> 1330{ 1331 _LIBCPP_INLINE_VISIBILITY 1332 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1333 1334 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); 1335 1336 template <class _OutputIterator, class _CharT> 1337 _LIBCPP_INLINE_VISIBILITY 1338 _OutputIterator 1339 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1340 { 1341 result __r = ok; 1342 mbstate_t __mb; 1343 while (__wb < __we && __r != error) 1344 { 1345 const int __sz = 32; 1346 char __buf[__sz]; 1347 char* __bn; 1348 const char32_t* __wn = (const char32_t*)__wb; 1349 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, 1350 __buf, __buf+__sz, __bn); 1351 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) 1352 __throw_runtime_error("locale not supported"); 1353 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1354 *__s = *__p; 1355 __wb = (const _CharT*)__wn; 1356 } 1357 return __s; 1358 } 1359}; 1360 1361template <size_t _Np> 1362struct __widen_from_utf8 1363{ 1364 template <class _OutputIterator> 1365 _OutputIterator 1366 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; 1367}; 1368 1369template <> 1370struct __widen_from_utf8<8> 1371{ 1372 template <class _OutputIterator> 1373 _LIBCPP_INLINE_VISIBILITY 1374 _OutputIterator 1375 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1376 { 1377 for (; __nb < __ne; ++__nb, ++__s) 1378 *__s = *__nb; 1379 return __s; 1380 } 1381}; 1382 1383template <> 1384struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> 1385 : public codecvt<char16_t, char, mbstate_t> 1386{ 1387 _LIBCPP_INLINE_VISIBILITY 1388 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1389 1390 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); 1391 1392 template <class _OutputIterator> 1393 _LIBCPP_INLINE_VISIBILITY 1394 _OutputIterator 1395 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1396 { 1397 result __r = ok; 1398 mbstate_t __mb; 1399 while (__nb < __ne && __r != error) 1400 { 1401 const int __sz = 32; 1402 char16_t __buf[__sz]; 1403 char16_t* __bn; 1404 const char* __nn = __nb; 1405 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1406 __buf, __buf+__sz, __bn); 1407 if (__r == codecvt_base::error || __nn == __nb) 1408 __throw_runtime_error("locale not supported"); 1409 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) 1410 *__s = (wchar_t)*__p; 1411 __nb = __nn; 1412 } 1413 return __s; 1414 } 1415}; 1416 1417template <> 1418struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> 1419 : public codecvt<char32_t, char, mbstate_t> 1420{ 1421 _LIBCPP_INLINE_VISIBILITY 1422 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1423 1424 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); 1425 1426 template <class _OutputIterator> 1427 _LIBCPP_INLINE_VISIBILITY 1428 _OutputIterator 1429 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1430 { 1431 result __r = ok; 1432 mbstate_t __mb; 1433 while (__nb < __ne && __r != error) 1434 { 1435 const int __sz = 32; 1436 char32_t __buf[__sz]; 1437 char32_t* __bn; 1438 const char* __nn = __nb; 1439 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1440 __buf, __buf+__sz, __bn); 1441 if (__r == codecvt_base::error || __nn == __nb) 1442 __throw_runtime_error("locale not supported"); 1443 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) 1444 *__s = (wchar_t)*__p; 1445 __nb = __nn; 1446 } 1447 return __s; 1448 } 1449}; 1450 1451// template <class charT> class numpunct 1452 1453template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct; 1454 1455template <> 1456class _LIBCPP_TYPE_VIS numpunct<char> 1457 : public locale::facet 1458{ 1459public: 1460 typedef char char_type; 1461 typedef basic_string<char_type> string_type; 1462 1463 explicit numpunct(size_t __refs = 0); 1464 1465 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 1466 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 1467 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 1468 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} 1469 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} 1470 1471 static locale::id id; 1472 1473protected: 1474 ~numpunct(); 1475 virtual char_type do_decimal_point() const; 1476 virtual char_type do_thousands_sep() const; 1477 virtual string do_grouping() const; 1478 virtual string_type do_truename() const; 1479 virtual string_type do_falsename() const; 1480 1481 char_type __decimal_point_; 1482 char_type __thousands_sep_; 1483 string __grouping_; 1484}; 1485 1486template <> 1487class _LIBCPP_TYPE_VIS numpunct<wchar_t> 1488 : public locale::facet 1489{ 1490public: 1491 typedef wchar_t char_type; 1492 typedef basic_string<char_type> string_type; 1493 1494 explicit numpunct(size_t __refs = 0); 1495 1496 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 1497 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 1498 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 1499 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} 1500 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} 1501 1502 static locale::id id; 1503 1504protected: 1505 ~numpunct(); 1506 virtual char_type do_decimal_point() const; 1507 virtual char_type do_thousands_sep() const; 1508 virtual string do_grouping() const; 1509 virtual string_type do_truename() const; 1510 virtual string_type do_falsename() const; 1511 1512 char_type __decimal_point_; 1513 char_type __thousands_sep_; 1514 string __grouping_; 1515}; 1516 1517// template <class charT> class numpunct_byname 1518 1519template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname; 1520 1521template <> 1522class _LIBCPP_TYPE_VIS numpunct_byname<char> 1523: public numpunct<char> 1524{ 1525public: 1526 typedef char char_type; 1527 typedef basic_string<char_type> string_type; 1528 1529 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1530 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1531 1532protected: 1533 ~numpunct_byname(); 1534 1535private: 1536 void __init(const char*); 1537}; 1538 1539template <> 1540class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t> 1541: public numpunct<wchar_t> 1542{ 1543public: 1544 typedef wchar_t char_type; 1545 typedef basic_string<char_type> string_type; 1546 1547 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1548 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1549 1550protected: 1551 ~numpunct_byname(); 1552 1553private: 1554 void __init(const char*); 1555}; 1556 1557_LIBCPP_END_NAMESPACE_STD 1558 1559#endif // _LIBCPP___LOCALE 1560