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