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