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