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