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