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