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