locale revision 241903
1// -*- C++ -*- 2//===-------------------------- locale ------------------------------------===// 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/* 15 locale synopsis 16 17namespace std 18{ 19 20class locale 21{ 22public: 23 // types: 24 class facet; 25 class id; 26 27 typedef int category; 28 static const category // values assigned here are for exposition only 29 none = 0x000, 30 collate = 0x010, 31 ctype = 0x020, 32 monetary = 0x040, 33 numeric = 0x080, 34 time = 0x100, 35 messages = 0x200, 36 all = collate | ctype | monetary | numeric | time | messages; 37 38 // construct/copy/destroy: 39 locale() noexcept; 40 locale(const locale& other) noexcept; 41 explicit locale(const char* std_name); 42 explicit locale(const string& std_name); 43 locale(const locale& other, const char* std_name, category); 44 locale(const locale& other, const string& std_name, category); 45 template <class Facet> locale(const locale& other, Facet* f); 46 locale(const locale& other, const locale& one, category); 47 48 ~locale(); // not virtual 49 50 const locale& operator=(const locale& other) noexcept; 51 52 template <class Facet> locale combine(const locale& other) const; 53 54 // locale operations: 55 basic_string<char> name() const; 56 bool operator==(const locale& other) const; 57 bool operator!=(const locale& other) const; 58 template <class charT, class Traits, class Allocator> 59 bool operator()(const basic_string<charT,Traits,Allocator>& s1, 60 const basic_string<charT,Traits,Allocator>& s2) const; 61 62 // global locale objects: 63 static locale global(const locale&); 64 static const locale& classic(); 65}; 66 67template <class Facet> const Facet& use_facet(const locale&); 68template <class Facet> bool has_facet(const locale&) noexcept; 69 70// 22.3.3, convenience interfaces: 71template <class charT> bool isspace (charT c, const locale& loc); 72template <class charT> bool isprint (charT c, const locale& loc); 73template <class charT> bool iscntrl (charT c, const locale& loc); 74template <class charT> bool isupper (charT c, const locale& loc); 75template <class charT> bool islower (charT c, const locale& loc); 76template <class charT> bool isalpha (charT c, const locale& loc); 77template <class charT> bool isdigit (charT c, const locale& loc); 78template <class charT> bool ispunct (charT c, const locale& loc); 79template <class charT> bool isxdigit(charT c, const locale& loc); 80template <class charT> bool isalnum (charT c, const locale& loc); 81template <class charT> bool isgraph (charT c, const locale& loc); 82template <class charT> charT toupper(charT c, const locale& loc); 83template <class charT> charT tolower(charT c, const locale& loc); 84 85template<class Codecvt, class Elem = wchar_t, 86 class Wide_alloc = allocator<Elem>, 87 class Byte_alloc = allocator<char>> 88class wstring_convert 89{ 90public: 91 typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string; 92 typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string; 93 typedef typename Codecvt::state_type state_type; 94 typedef typename wide_string::traits_type::int_type int_type; 95 96 wstring_convert(Codecvt* pcvt = new Codecvt); 97 wstring_convert(Codecvt* pcvt, state_type state); 98 wstring_convert(const byte_string& byte_err, 99 const wide_string& wide_err = wide_string()); 100 ~wstring_convert(); 101 102 wide_string from_bytes(char byte); 103 wide_string from_bytes(const char* ptr); 104 wide_string from_bytes(const byte_string& str); 105 wide_string from_bytes(const char* first, const char* last); 106 107 byte_string to_bytes(Elem wchar); 108 byte_string to_bytes(const Elem* wptr); 109 byte_string to_bytes(const wide_string& wstr); 110 byte_string to_bytes(const Elem* first, const Elem* last); 111 112 size_t converted() const; 113 state_type state() const; 114}; 115 116template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>> 117class wbuffer_convert 118 : public basic_streambuf<Elem, Tr> 119{ 120public: 121 typedef typename Tr::state_type state_type; 122 123 wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, 124 state_type state = state_type()); 125 126 streambuf* rdbuf() const; 127 streambuf* rdbuf(streambuf* bytebuf); 128 129 state_type state() const; 130}; 131 132// 22.4.1 and 22.4.1.3, ctype: 133class ctype_base; 134template <class charT> class ctype; 135template <> class ctype<char>; // specialization 136template <class charT> class ctype_byname; 137template <> class ctype_byname<char>; // specialization 138 139class codecvt_base; 140template <class internT, class externT, class stateT> class codecvt; 141template <class internT, class externT, class stateT> class codecvt_byname; 142 143// 22.4.2 and 22.4.3, numeric: 144template <class charT, class InputIterator> class num_get; 145template <class charT, class OutputIterator> class num_put; 146template <class charT> class numpunct; 147template <class charT> class numpunct_byname; 148 149// 22.4.4, col lation: 150template <class charT> class collate; 151template <class charT> class collate_byname; 152 153// 22.4.5, date and time: 154class time_base; 155template <class charT, class InputIterator> class time_get; 156template <class charT, class InputIterator> class time_get_byname; 157template <class charT, class OutputIterator> class time_put; 158template <class charT, class OutputIterator> class time_put_byname; 159 160// 22.4.6, money: 161class money_base; 162template <class charT, class InputIterator> class money_get; 163template <class charT, class OutputIterator> class money_put; 164template <class charT, bool Intl> class moneypunct; 165template <class charT, bool Intl> class moneypunct_byname; 166 167// 22.4.7, message retrieval: 168class messages_base; 169template <class charT> class messages; 170template <class charT> class messages_byname; 171 172} // std 173 174*/ 175 176#include <__config> 177#include <__locale> 178#include <algorithm> 179#include <memory> 180#include <ios> 181#include <streambuf> 182#include <iterator> 183#include <limits> 184#if !__APPLE__ 185#include <cstdarg> 186#endif 187#include <cstdlib> 188#include <ctime> 189#if _WIN32 190#include <support/win32/locale_win32.h> 191#else // _WIN32 192#include <nl_types.h> 193#endif // !_WIN32 194 195#include <__undef_min_max> 196 197#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 198#pragma GCC system_header 199#endif 200 201_LIBCPP_BEGIN_NAMESPACE_STD 202 203#if __APPLE__ || __FreeBSD__ 204# define _LIBCPP_GET_C_LOCALE 0 205#else 206# define _LIBCPP_GET_C_LOCALE __cloc() 207 // Get the C locale object 208 locale_t __cloc(); 209#define __cloc_defined 210#endif 211 212typedef _VSTD::remove_pointer<locale_t>::type __locale_struct; 213typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; 214#ifndef _LIBCPP_LOCALE__L_EXTENSIONS 215typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; 216#endif 217 218// OSX has nice foo_l() functions that let you turn off use of the global 219// locale. Linux, not so much. The following functions avoid the locale when 220// that's possible and otherwise do the wrong thing. FIXME. 221#ifdef __linux__ 222 223#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 224decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>())) 225inline _LIBCPP_INLINE_VISIBILITY 226__mb_cur_max_l(locale_t __l) 227{ 228 return MB_CUR_MAX_L(__l); 229} 230#else // _LIBCPP_LOCALE__L_EXTENSIONS 231_LIBCPP_ALWAYS_INLINE inline 232decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l) 233{ 234 __locale_raii __current(uselocale(__l), uselocale); 235 return MB_CUR_MAX; 236} 237#endif // _LIBCPP_LOCALE__L_EXTENSIONS 238 239_LIBCPP_ALWAYS_INLINE inline 240wint_t __btowc_l(int __c, locale_t __l) 241{ 242#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 243 return btowc_l(__c, __l); 244#else 245 __locale_raii __current(uselocale(__l), uselocale); 246 return btowc(__c); 247#endif 248} 249 250_LIBCPP_ALWAYS_INLINE inline 251int __wctob_l(wint_t __c, locale_t __l) 252{ 253#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 254 return wctob_l(__c, __l); 255#else 256 __locale_raii __current(uselocale(__l), uselocale); 257 return wctob(__c); 258#endif 259} 260 261_LIBCPP_ALWAYS_INLINE inline 262size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, 263 size_t __len, mbstate_t *__ps, locale_t __l) 264{ 265#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 266 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l); 267#else 268 __locale_raii __current(uselocale(__l), uselocale); 269 return wcsnrtombs(__dest, __src, __nwc, __len, __ps); 270#endif 271} 272 273_LIBCPP_ALWAYS_INLINE inline 274size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) 275{ 276#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 277 return wcrtomb_l(__s, __wc, __ps, __l); 278#else 279 __locale_raii __current(uselocale(__l), uselocale); 280 return wcrtomb(__s, __wc, __ps); 281#endif 282} 283 284_LIBCPP_ALWAYS_INLINE inline 285size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, 286 size_t __len, mbstate_t *__ps, locale_t __l) 287{ 288#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 289 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l); 290#else 291 __locale_raii __current(uselocale(__l), uselocale); 292 return mbsnrtowcs(__dest, __src, __nms, __len, __ps); 293#endif 294} 295 296_LIBCPP_ALWAYS_INLINE inline 297size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, 298 mbstate_t *__ps, locale_t __l) 299{ 300#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 301 return mbrtowc_l(__pwc, __s, __n, __ps, __l); 302#else 303 __locale_raii __current(uselocale(__l), uselocale); 304 return mbrtowc(__pwc, __s, __n, __ps); 305#endif 306} 307 308_LIBCPP_ALWAYS_INLINE inline 309int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) 310{ 311#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 312 return mbtowc_l(__pwc, __pmb, __max, __l); 313#else 314 __locale_raii __current(uselocale(__l), uselocale); 315 return mbtowc(__pwc, __pmb, __max); 316#endif 317} 318 319_LIBCPP_ALWAYS_INLINE inline 320size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) 321{ 322#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 323 return mbrlen_l(__s, __n, __ps, __l); 324#else 325 __locale_raii __current(uselocale(__l), uselocale); 326 return mbrlen(__s, __n, __ps); 327#endif 328} 329 330_LIBCPP_ALWAYS_INLINE inline 331lconv *__localeconv_l(locale_t __l) 332{ 333#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 334 return localeconv_l(__l); 335#else 336 __locale_raii __current(uselocale(__l), uselocale); 337 return localeconv(); 338#endif 339} 340 341_LIBCPP_ALWAYS_INLINE inline 342size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, 343 mbstate_t *__ps, locale_t __l) 344{ 345#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 346 return mbsrtowcs_l(__dest, __src, __len, __ps, __l); 347#else 348 __locale_raii __current(uselocale(__l), uselocale); 349 return mbsrtowcs(__dest, __src, __len, __ps); 350#endif 351} 352 353_LIBCPP_ALWAYS_INLINE inline 354int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) { 355 va_list __va; 356 va_start(__va, __format); 357#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 358 int __res = vsprintf_l(__s, __l, __format, __va); 359#else 360 __locale_raii __current(uselocale(__l), uselocale); 361 int __res = vsprintf(__s, __format, __va); 362#endif 363 va_end(__va); 364 return __res; 365} 366 367_LIBCPP_ALWAYS_INLINE inline 368int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { 369 va_list __va; 370 va_start(__va, __format); 371#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 372 int __res = vsnprintf_l(__s, __n, __l, __format, __va); 373#else 374 __locale_raii __current(uselocale(__l), uselocale); 375 int __res = vsnprintf(__s, __n, __format, __va); 376#endif 377 va_end(__va); 378 return __res; 379} 380 381_LIBCPP_ALWAYS_INLINE inline 382int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { 383 va_list __va; 384 va_start(__va, __format); 385#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 386 int __res = vasprintf_l(__s, __l, __format, __va); 387#else 388 __locale_raii __current(uselocale(__l), uselocale); 389 int __res = vasprintf(__s, __format, __va); 390#endif 391 va_end(__va); 392 return __res; 393} 394 395_LIBCPP_ALWAYS_INLINE inline 396int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { 397 va_list __va; 398 va_start(__va, __format); 399#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 400 int __res = vsscanf_l(__s, __l, __format, __va); 401#else 402 __locale_raii __current(uselocale(__l), uselocale); 403 int __res = vsscanf(__s, __format, __va); 404#endif 405 va_end(__va); 406 return __res; 407} 408 409#endif // __linux__ 410 411// __scan_keyword 412// Scans [__b, __e) until a match is found in the basic_strings range 413// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). 414// __b will be incremented (visibly), consuming CharT until a match is found 415// or proved to not exist. A keyword may be "", in which will match anything. 416// If one keyword is a prefix of another, and the next CharT in the input 417// might match another keyword, the algorithm will attempt to find the longest 418// matching keyword. If the longer matching keyword ends up not matching, then 419// no keyword match is found. If no keyword match is found, __ke is returned 420// and failbit is set in __err. 421// Else an iterator pointing to the matching keyword is found. If more than 422// one keyword matches, an iterator to the first matching keyword is returned. 423// If on exit __b == __e, eofbit is set in __err. If __case_senstive is false, 424// __ct is used to force to lower case before comparing characters. 425// Examples: 426// Keywords: "a", "abb" 427// If the input is "a", the first keyword matches and eofbit is set. 428// If the input is "abc", no match is found and "ab" are consumed. 429template <class _InputIterator, class _ForwardIterator, class _Ctype> 430_LIBCPP_HIDDEN 431_ForwardIterator 432__scan_keyword(_InputIterator& __b, _InputIterator __e, 433 _ForwardIterator __kb, _ForwardIterator __ke, 434 const _Ctype& __ct, ios_base::iostate& __err, 435 bool __case_sensitive = true) 436{ 437 typedef typename iterator_traits<_InputIterator>::value_type _CharT; 438 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke)); 439 const unsigned char __doesnt_match = '\0'; 440 const unsigned char __might_match = '\1'; 441 const unsigned char __does_match = '\2'; 442 unsigned char __statbuf[100]; 443 unsigned char* __status = __statbuf; 444 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free); 445 if (__nkw > sizeof(__statbuf)) 446 { 447 __status = (unsigned char*)malloc(__nkw); 448 if (__status == 0) 449 __throw_bad_alloc(); 450 __stat_hold.reset(__status); 451 } 452 size_t __n_might_match = __nkw; // At this point, any keyword might match 453 size_t __n_does_match = 0; // but none of them definitely do 454 // Initialize all statuses to __might_match, except for "" keywords are __does_match 455 unsigned char* __st = __status; 456 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st) 457 { 458 if (!__ky->empty()) 459 *__st = __might_match; 460 else 461 { 462 *__st = __does_match; 463 --__n_might_match; 464 ++__n_does_match; 465 } 466 } 467 // While there might be a match, test keywords against the next CharT 468 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) 469 { 470 // Peek at the next CharT but don't consume it 471 _CharT __c = *__b; 472 if (!__case_sensitive) 473 __c = __ct.toupper(__c); 474 bool __consume = false; 475 // For each keyword which might match, see if the __indx character is __c 476 // If a match if found, consume __c 477 // If a match is found, and that is the last character in the keyword, 478 // then that keyword matches. 479 // If the keyword doesn't match this character, then change the keyword 480 // to doesn't match 481 __st = __status; 482 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st) 483 { 484 if (*__st == __might_match) 485 { 486 _CharT __kc = (*__ky)[__indx]; 487 if (!__case_sensitive) 488 __kc = __ct.toupper(__kc); 489 if (__c == __kc) 490 { 491 __consume = true; 492 if (__ky->size() == __indx+1) 493 { 494 *__st = __does_match; 495 --__n_might_match; 496 ++__n_does_match; 497 } 498 } 499 else 500 { 501 *__st = __doesnt_match; 502 --__n_might_match; 503 } 504 } 505 } 506 // consume if we matched a character 507 if (__consume) 508 { 509 ++__b; 510 // If we consumed a character and there might be a matched keyword that 511 // was marked matched on a previous iteration, then such keywords 512 // which are now marked as not matching. 513 if (__n_might_match + __n_does_match > 1) 514 { 515 __st = __status; 516 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st) 517 { 518 if (*__st == __does_match && __ky->size() != __indx+1) 519 { 520 *__st = __doesnt_match; 521 --__n_does_match; 522 } 523 } 524 } 525 } 526 } 527 // We've exited the loop because we hit eof and/or we have no more "might matches". 528 if (__b == __e) 529 __err |= ios_base::eofbit; 530 // Return the first matching result 531 for (__st = __status; __kb != __ke; ++__kb, ++__st) 532 if (*__st == __does_match) 533 break; 534 if (__kb == __ke) 535 __err |= ios_base::failbit; 536 return __kb; 537} 538 539struct __num_get_base 540{ 541 static const int __num_get_buf_sz = 40; 542 543 static int __get_base(ios_base&); 544 static const char __src[33]; 545}; 546 547void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 548 ios_base::iostate& __err); 549 550template <class _CharT> 551struct __num_get 552 : protected __num_get_base 553{ 554 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); 555 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 556 _CharT& __thousands_sep); 557 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 558 unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 559 unsigned* __g, unsigned*& __g_end, _CharT* __atoms); 560 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, 561 char* __a, char*& __a_end, 562 _CharT __decimal_point, _CharT __thousands_sep, 563 const string& __grouping, unsigned* __g, 564 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); 565}; 566 567template <class _CharT> 568string 569__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) 570{ 571 locale __loc = __iob.getloc(); 572 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms); 573 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 574 __thousands_sep = __np.thousands_sep(); 575 return __np.grouping(); 576} 577 578template <class _CharT> 579string 580__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 581 _CharT& __thousands_sep) 582{ 583 locale __loc = __iob.getloc(); 584 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms); 585 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 586 __decimal_point = __np.decimal_point(); 587 __thousands_sep = __np.thousands_sep(); 588 return __np.grouping(); 589} 590 591template <class _CharT> 592int 593__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 594 unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 595 unsigned* __g, unsigned*& __g_end, _CharT* __atoms) 596{ 597 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) 598 { 599 *__a_end++ = __ct == __atoms[24] ? '+' : '-'; 600 __dc = 0; 601 return 0; 602 } 603 if (__grouping.size() != 0 && __ct == __thousands_sep) 604 { 605 if (__g_end-__g < __num_get_buf_sz) 606 { 607 *__g_end++ = __dc; 608 __dc = 0; 609 } 610 return 0; 611 } 612 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms; 613 if (__f >= 24) 614 return -1; 615 switch (__base) 616 { 617 case 8: 618 case 10: 619 if (__f >= __base) 620 return -1; 621 break; 622 case 16: 623 if (__f < 22) 624 break; 625 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') 626 { 627 __dc = 0; 628 *__a_end++ = __src[__f]; 629 return 0; 630 } 631 return -1; 632 } 633 if (__a_end-__a < __num_get_buf_sz - 1) 634 *__a_end++ = __src[__f]; 635 ++__dc; 636 return 0; 637} 638 639template <class _CharT> 640int 641__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end, 642 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, 643 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms) 644{ 645 if (__ct == __decimal_point) 646 { 647 if (!__in_units) 648 return -1; 649 __in_units = false; 650 *__a_end++ = '.'; 651 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 652 *__g_end++ = __dc; 653 return 0; 654 } 655 if (__ct == __thousands_sep && __grouping.size() != 0) 656 { 657 if (!__in_units) 658 return -1; 659 if (__g_end-__g < __num_get_buf_sz) 660 { 661 *__g_end++ = __dc; 662 __dc = 0; 663 } 664 return 0; 665 } 666 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms; 667 if (__f >= 32) 668 return -1; 669 char __x = __src[__f]; 670 if (__x == '-' || __x == '+') 671 { 672 if (__a_end == __a || (__a_end[-1] & 0xDF) == __exp) 673 { 674 *__a_end++ = __x; 675 return 0; 676 } 677 return -1; 678 } 679 if (__a_end-__a < __num_get_buf_sz - 1) 680 *__a_end++ = __x; 681 if (__x == 'x' || __x == 'X') 682 __exp = 'P'; 683 else if ((__x & 0xDF) == __exp) 684 { 685 __in_units = false; 686 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 687 *__g_end++ = __dc; 688 } 689 if (__f >= 22) 690 return 0; 691 ++__dc; 692 return 0; 693} 694 695extern template struct __num_get<char>; 696extern template struct __num_get<wchar_t>; 697 698template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 699class _LIBCPP_VISIBLE num_get 700 : public locale::facet, 701 private __num_get<_CharT> 702{ 703public: 704 typedef _CharT char_type; 705 typedef _InputIterator iter_type; 706 707 _LIBCPP_ALWAYS_INLINE 708 explicit num_get(size_t __refs = 0) 709 : locale::facet(__refs) {} 710 711 _LIBCPP_ALWAYS_INLINE 712 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 713 ios_base::iostate& __err, bool& __v) const 714 { 715 return do_get(__b, __e, __iob, __err, __v); 716 } 717 718 _LIBCPP_ALWAYS_INLINE 719 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 720 ios_base::iostate& __err, long& __v) const 721 { 722 return do_get(__b, __e, __iob, __err, __v); 723 } 724 725 _LIBCPP_ALWAYS_INLINE 726 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 727 ios_base::iostate& __err, long long& __v) const 728 { 729 return do_get(__b, __e, __iob, __err, __v); 730 } 731 732 _LIBCPP_ALWAYS_INLINE 733 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 734 ios_base::iostate& __err, unsigned short& __v) const 735 { 736 return do_get(__b, __e, __iob, __err, __v); 737 } 738 739 _LIBCPP_ALWAYS_INLINE 740 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 741 ios_base::iostate& __err, unsigned int& __v) const 742 { 743 return do_get(__b, __e, __iob, __err, __v); 744 } 745 746 _LIBCPP_ALWAYS_INLINE 747 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 748 ios_base::iostate& __err, unsigned long& __v) const 749 { 750 return do_get(__b, __e, __iob, __err, __v); 751 } 752 753 _LIBCPP_ALWAYS_INLINE 754 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 755 ios_base::iostate& __err, unsigned long long& __v) const 756 { 757 return do_get(__b, __e, __iob, __err, __v); 758 } 759 760 _LIBCPP_ALWAYS_INLINE 761 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 762 ios_base::iostate& __err, float& __v) const 763 { 764 return do_get(__b, __e, __iob, __err, __v); 765 } 766 767 _LIBCPP_ALWAYS_INLINE 768 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 769 ios_base::iostate& __err, double& __v) const 770 { 771 return do_get(__b, __e, __iob, __err, __v); 772 } 773 774 _LIBCPP_ALWAYS_INLINE 775 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 776 ios_base::iostate& __err, long double& __v) const 777 { 778 return do_get(__b, __e, __iob, __err, __v); 779 } 780 781 _LIBCPP_ALWAYS_INLINE 782 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 783 ios_base::iostate& __err, void*& __v) const 784 { 785 return do_get(__b, __e, __iob, __err, __v); 786 } 787 788 static locale::id id; 789 790protected: 791 _LIBCPP_ALWAYS_INLINE 792 ~num_get() {} 793 794 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 795 ios_base::iostate& __err, bool& __v) const; 796 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 797 ios_base::iostate& __err, long& __v) const; 798 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 799 ios_base::iostate& __err, long long& __v) const; 800 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 801 ios_base::iostate& __err, unsigned short& __v) const; 802 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 803 ios_base::iostate& __err, unsigned int& __v) const; 804 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 805 ios_base::iostate& __err, unsigned long& __v) const; 806 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 807 ios_base::iostate& __err, unsigned long long& __v) const; 808 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 809 ios_base::iostate& __err, float& __v) const; 810 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 811 ios_base::iostate& __err, double& __v) const; 812 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 813 ios_base::iostate& __err, long double& __v) const; 814 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 815 ios_base::iostate& __err, void*& __v) const; 816}; 817 818template <class _CharT, class _InputIterator> 819locale::id 820num_get<_CharT, _InputIterator>::id; 821 822template <class _Tp> 823_Tp 824__num_get_signed_integral(const char* __a, const char* __a_end, 825 ios_base::iostate& __err, int __base) 826{ 827 if (__a != __a_end) 828 { 829 int __save_errno = errno; 830 errno = 0; 831 char *__p2; 832 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 833 int __current_errno = errno; 834 if (__current_errno == 0) 835 errno = __save_errno; 836 if (__p2 != __a_end) 837 { 838 __err = ios_base::failbit; 839 return 0; 840 } 841 else if (__current_errno == ERANGE || 842 __ll < numeric_limits<_Tp>::min() || 843 numeric_limits<_Tp>::max() < __ll) 844 { 845 __err = ios_base::failbit; 846 if (__ll > 0) 847 return numeric_limits<_Tp>::max(); 848 else 849 return numeric_limits<_Tp>::min(); 850 } 851 return static_cast<_Tp>(__ll); 852 } 853 __err = ios_base::failbit; 854 return 0; 855} 856 857template <class _Tp> 858_Tp 859__num_get_unsigned_integral(const char* __a, const char* __a_end, 860 ios_base::iostate& __err, int __base) 861{ 862 if (__a != __a_end) 863 { 864 if (*__a == '-') 865 { 866 __err = ios_base::failbit; 867 return 0; 868 } 869 int __save_errno = errno; 870 errno = 0; 871 char *__p2; 872 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 873 int __current_errno = errno; 874 if (__current_errno == 0) 875 errno = __save_errno; 876 if (__p2 != __a_end) 877 { 878 __err = ios_base::failbit; 879 return 0; 880 } 881 else if (__current_errno == ERANGE || 882 numeric_limits<_Tp>::max() < __ll) 883 { 884 __err = ios_base::failbit; 885 return numeric_limits<_Tp>::max(); 886 } 887 return static_cast<_Tp>(__ll); 888 } 889 __err = ios_base::failbit; 890 return 0; 891} 892 893template <class _Tp> 894_Tp 895__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) 896{ 897 if (__a != __a_end) 898 { 899 char *__p2; 900 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); 901 if (__p2 != __a_end) 902 { 903 __err = ios_base::failbit; 904 return 0; 905 } 906 return static_cast<_Tp>(__ld); 907 } 908 __err = ios_base::failbit; 909 return 0; 910} 911 912template <class _CharT, class _InputIterator> 913_InputIterator 914num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 915 ios_base& __iob, 916 ios_base::iostate& __err, 917 bool& __v) const 918{ 919 if ((__iob.flags() & ios_base::boolalpha) == 0) 920 { 921 long __lv = -1; 922 __b = do_get(__b, __e, __iob, __err, __lv); 923 switch (__lv) 924 { 925 case 0: 926 __v = false; 927 break; 928 case 1: 929 __v = true; 930 break; 931 default: 932 __v = true; 933 __err = ios_base::failbit; 934 break; 935 } 936 return __b; 937 } 938 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc()); 939 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc()); 940 typedef typename numpunct<_CharT>::string_type string_type; 941 const string_type __names[2] = {__np.truename(), __np.falsename()}; 942 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2, 943 __ct, __err); 944 __v = __i == __names; 945 return __b; 946} 947 948template <class _CharT, class _InputIterator> 949_InputIterator 950num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 951 ios_base& __iob, 952 ios_base::iostate& __err, 953 long& __v) const 954{ 955 // Stage 1 956 int __base = this->__get_base(__iob); 957 // Stage 2 958 char_type __atoms[26]; 959 char_type __thousands_sep; 960 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 961 char __a[__num_get_base::__num_get_buf_sz] = {0}; 962 char* __a_end = __a; 963 unsigned __g[__num_get_base::__num_get_buf_sz]; 964 unsigned* __g_end = __g; 965 unsigned __dc = 0; 966 for (; __b != __e; ++__b) 967 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 968 __thousands_sep, __grouping, __g, __g_end, 969 __atoms)) 970 break; 971 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 972 *__g_end++ = __dc; 973 // Stage 3 974 __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base); 975 // Digit grouping checked 976 __check_grouping(__grouping, __g, __g_end, __err); 977 // EOF checked 978 if (__b == __e) 979 __err |= ios_base::eofbit; 980 return __b; 981} 982 983template <class _CharT, class _InputIterator> 984_InputIterator 985num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 986 ios_base& __iob, 987 ios_base::iostate& __err, 988 long long& __v) const 989{ 990 // Stage 1 991 int __base = this->__get_base(__iob); 992 // Stage 2 993 char_type __atoms[26]; 994 char_type __thousands_sep; 995 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 996 char __a[__num_get_base::__num_get_buf_sz] = {0}; 997 char* __a_end = __a; 998 unsigned __g[__num_get_base::__num_get_buf_sz]; 999 unsigned* __g_end = __g; 1000 unsigned __dc = 0; 1001 for (; __b != __e; ++__b) 1002 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1003 __thousands_sep, __grouping, __g, __g_end, 1004 __atoms)) 1005 break; 1006 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1007 *__g_end++ = __dc; 1008 // Stage 3 1009 __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base); 1010 // Digit grouping checked 1011 __check_grouping(__grouping, __g, __g_end, __err); 1012 // EOF checked 1013 if (__b == __e) 1014 __err |= ios_base::eofbit; 1015 return __b; 1016} 1017 1018template <class _CharT, class _InputIterator> 1019_InputIterator 1020num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1021 ios_base& __iob, 1022 ios_base::iostate& __err, 1023 unsigned short& __v) const 1024{ 1025 // Stage 1 1026 int __base = this->__get_base(__iob); 1027 // Stage 2 1028 char_type __atoms[26]; 1029 char_type __thousands_sep; 1030 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1031 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1032 char* __a_end = __a; 1033 unsigned __g[__num_get_base::__num_get_buf_sz]; 1034 unsigned* __g_end = __g; 1035 unsigned __dc = 0; 1036 for (; __b != __e; ++__b) 1037 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1038 __thousands_sep, __grouping, __g, __g_end, 1039 __atoms)) 1040 break; 1041 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1042 *__g_end++ = __dc; 1043 // Stage 3 1044 __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base); 1045 // Digit grouping checked 1046 __check_grouping(__grouping, __g, __g_end, __err); 1047 // EOF checked 1048 if (__b == __e) 1049 __err |= ios_base::eofbit; 1050 return __b; 1051} 1052 1053template <class _CharT, class _InputIterator> 1054_InputIterator 1055num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1056 ios_base& __iob, 1057 ios_base::iostate& __err, 1058 unsigned int& __v) const 1059{ 1060 // Stage 1 1061 int __base = this->__get_base(__iob); 1062 // Stage 2 1063 char_type __atoms[26]; 1064 char_type __thousands_sep; 1065 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1066 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1067 char* __a_end = __a; 1068 unsigned __g[__num_get_base::__num_get_buf_sz]; 1069 unsigned* __g_end = __g; 1070 unsigned __dc = 0; 1071 for (; __b != __e; ++__b) 1072 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1073 __thousands_sep, __grouping, __g, __g_end, 1074 __atoms)) 1075 break; 1076 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1077 *__g_end++ = __dc; 1078 // Stage 3 1079 __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base); 1080 // Digit grouping checked 1081 __check_grouping(__grouping, __g, __g_end, __err); 1082 // EOF checked 1083 if (__b == __e) 1084 __err |= ios_base::eofbit; 1085 return __b; 1086} 1087 1088template <class _CharT, class _InputIterator> 1089_InputIterator 1090num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1091 ios_base& __iob, 1092 ios_base::iostate& __err, 1093 unsigned long& __v) const 1094{ 1095 // Stage 1 1096 int __base = this->__get_base(__iob); 1097 // Stage 2 1098 char_type __atoms[26]; 1099 char_type __thousands_sep; 1100 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1101 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1102 char* __a_end = __a; 1103 unsigned __g[__num_get_base::__num_get_buf_sz]; 1104 unsigned* __g_end = __g; 1105 unsigned __dc = 0; 1106 for (; __b != __e; ++__b) 1107 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1108 __thousands_sep, __grouping, __g, __g_end, 1109 __atoms)) 1110 break; 1111 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1112 *__g_end++ = __dc; 1113 // Stage 3 1114 __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base); 1115 // Digit grouping checked 1116 __check_grouping(__grouping, __g, __g_end, __err); 1117 // EOF checked 1118 if (__b == __e) 1119 __err |= ios_base::eofbit; 1120 return __b; 1121} 1122 1123template <class _CharT, class _InputIterator> 1124_InputIterator 1125num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1126 ios_base& __iob, 1127 ios_base::iostate& __err, 1128 unsigned long long& __v) const 1129{ 1130 // Stage 1 1131 int __base = this->__get_base(__iob); 1132 // Stage 2 1133 char_type __atoms[26]; 1134 char_type __thousands_sep; 1135 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1136 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1137 char* __a_end = __a; 1138 unsigned __g[__num_get_base::__num_get_buf_sz]; 1139 unsigned* __g_end = __g; 1140 unsigned __dc = 0; 1141 for (; __b != __e; ++__b) 1142 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1143 __thousands_sep, __grouping, __g, __g_end, 1144 __atoms)) 1145 break; 1146 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1147 *__g_end++ = __dc; 1148 // Stage 3 1149 __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base); 1150 // Digit grouping checked 1151 __check_grouping(__grouping, __g, __g_end, __err); 1152 // EOF checked 1153 if (__b == __e) 1154 __err |= ios_base::eofbit; 1155 return __b; 1156} 1157 1158template <class _CharT, class _InputIterator> 1159_InputIterator 1160num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1161 ios_base& __iob, 1162 ios_base::iostate& __err, 1163 float& __v) const 1164{ 1165 // Stage 1, nothing to do 1166 // Stage 2 1167 char_type __atoms[32]; 1168 char_type __decimal_point; 1169 char_type __thousands_sep; 1170 string __grouping = this->__stage2_float_prep(__iob, __atoms, 1171 __decimal_point, 1172 __thousands_sep); 1173 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1174 char* __a_end = __a; 1175 unsigned __g[__num_get_base::__num_get_buf_sz]; 1176 unsigned* __g_end = __g; 1177 unsigned __dc = 0; 1178 bool __in_units = true; 1179 char __exp = 'E'; 1180 for (; __b != __e; ++__b) 1181 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1182 __decimal_point, __thousands_sep, 1183 __grouping, __g, __g_end, 1184 __dc, __atoms)) 1185 break; 1186 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1187 *__g_end++ = __dc; 1188 // Stage 3 1189 __v = __num_get_float<float>(__a, __a_end, __err); 1190 // Digit grouping checked 1191 __check_grouping(__grouping, __g, __g_end, __err); 1192 // EOF checked 1193 if (__b == __e) 1194 __err |= ios_base::eofbit; 1195 return __b; 1196} 1197 1198template <class _CharT, class _InputIterator> 1199_InputIterator 1200num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1201 ios_base& __iob, 1202 ios_base::iostate& __err, 1203 double& __v) const 1204{ 1205 // Stage 1, nothing to do 1206 // Stage 2 1207 char_type __atoms[32]; 1208 char_type __decimal_point; 1209 char_type __thousands_sep; 1210 string __grouping = this->__stage2_float_prep(__iob, __atoms, 1211 __decimal_point, 1212 __thousands_sep); 1213 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1214 char* __a_end = __a; 1215 unsigned __g[__num_get_base::__num_get_buf_sz]; 1216 unsigned* __g_end = __g; 1217 unsigned __dc = 0; 1218 bool __in_units = true; 1219 char __exp = 'E'; 1220 for (; __b != __e; ++__b) 1221 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1222 __decimal_point, __thousands_sep, 1223 __grouping, __g, __g_end, 1224 __dc, __atoms)) 1225 break; 1226 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1227 *__g_end++ = __dc; 1228 // Stage 3 1229 __v = __num_get_float<double>(__a, __a_end, __err); 1230 // Digit grouping checked 1231 __check_grouping(__grouping, __g, __g_end, __err); 1232 // EOF checked 1233 if (__b == __e) 1234 __err |= ios_base::eofbit; 1235 return __b; 1236} 1237 1238template <class _CharT, class _InputIterator> 1239_InputIterator 1240num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1241 ios_base& __iob, 1242 ios_base::iostate& __err, 1243 long double& __v) const 1244{ 1245 // Stage 1, nothing to do 1246 // Stage 2 1247 char_type __atoms[32]; 1248 char_type __decimal_point; 1249 char_type __thousands_sep; 1250 string __grouping = this->__stage2_float_prep(__iob, __atoms, 1251 __decimal_point, 1252 __thousands_sep); 1253 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1254 char* __a_end = __a; 1255 unsigned __g[__num_get_base::__num_get_buf_sz]; 1256 unsigned* __g_end = __g; 1257 unsigned __dc = 0; 1258 bool __in_units = true; 1259 char __exp = 'E'; 1260 for (; __b != __e; ++__b) 1261 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1262 __decimal_point, __thousands_sep, 1263 __grouping, __g, __g_end, 1264 __dc, __atoms)) 1265 break; 1266 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1267 *__g_end++ = __dc; 1268 // Stage 3 1269 __v = __num_get_float<long double>(__a, __a_end, __err); 1270 // Digit grouping checked 1271 __check_grouping(__grouping, __g, __g_end, __err); 1272 // EOF checked 1273 if (__b == __e) 1274 __err |= ios_base::eofbit; 1275 return __b; 1276} 1277 1278template <class _CharT, class _InputIterator> 1279_InputIterator 1280num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1281 ios_base& __iob, 1282 ios_base::iostate& __err, 1283 void*& __v) const 1284{ 1285 // Stage 1 1286 int __base = 16; 1287 // Stage 2 1288 char_type __atoms[26]; 1289 char_type __thousands_sep = 0; 1290 string __grouping; 1291 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src, 1292 __num_get_base::__src + 26, __atoms); 1293 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1294 char* __a_end = __a; 1295 unsigned __g[__num_get_base::__num_get_buf_sz]; 1296 unsigned* __g_end = __g; 1297 unsigned __dc = 0; 1298 for (; __b != __e; ++__b) 1299 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1300 __thousands_sep, __grouping, 1301 __g, __g_end, __atoms)) 1302 break; 1303 // Stage 3 1304 __a[sizeof(__a)-1] = 0; 1305#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1306 if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) 1307#else 1308 if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1) 1309#endif 1310 __err = ios_base::failbit; 1311 // EOF checked 1312 if (__b == __e) 1313 __err |= ios_base::eofbit; 1314 return __b; 1315} 1316 1317extern template class num_get<char>; 1318extern template class num_get<wchar_t>; 1319 1320struct __num_put_base 1321{ 1322protected: 1323 static void __format_int(char* __fmt, const char* __len, bool __signd, 1324 ios_base::fmtflags __flags); 1325 static bool __format_float(char* __fmt, const char* __len, 1326 ios_base::fmtflags __flags); 1327 static char* __identify_padding(char* __nb, char* __ne, 1328 const ios_base& __iob); 1329}; 1330 1331template <class _CharT> 1332struct __num_put 1333 : protected __num_put_base 1334{ 1335 static void __widen_and_group_int(char* __nb, char* __np, char* __ne, 1336 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1337 const locale& __loc); 1338 static void __widen_and_group_float(char* __nb, char* __np, char* __ne, 1339 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1340 const locale& __loc); 1341}; 1342 1343template <class _CharT> 1344void 1345__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne, 1346 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1347 const locale& __loc) 1348{ 1349 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 1350 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 1351 string __grouping = __npt.grouping(); 1352 if (__grouping.empty()) 1353 { 1354 __ct.widen(__nb, __ne, __ob); 1355 __oe = __ob + (__ne - __nb); 1356 } 1357 else 1358 { 1359 __oe = __ob; 1360 char* __nf = __nb; 1361 if (*__nf == '-' || *__nf == '+') 1362 *__oe++ = __ct.widen(*__nf++); 1363 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 1364 __nf[1] == 'X')) 1365 { 1366 *__oe++ = __ct.widen(*__nf++); 1367 *__oe++ = __ct.widen(*__nf++); 1368 } 1369 reverse(__nf, __ne); 1370 _CharT __thousands_sep = __npt.thousands_sep(); 1371 unsigned __dc = 0; 1372 unsigned __dg = 0; 1373 for (char* __p = __nf; __p < __ne; ++__p) 1374 { 1375 if (static_cast<unsigned>(__grouping[__dg]) > 0 && 1376 __dc == static_cast<unsigned>(__grouping[__dg])) 1377 { 1378 *__oe++ = __thousands_sep; 1379 __dc = 0; 1380 if (__dg < __grouping.size()-1) 1381 ++__dg; 1382 } 1383 *__oe++ = __ct.widen(*__p); 1384 ++__dc; 1385 } 1386 reverse(__ob + (__nf - __nb), __oe); 1387 } 1388 if (__np == __ne) 1389 __op = __oe; 1390 else 1391 __op = __ob + (__np - __nb); 1392} 1393 1394template <class _CharT> 1395void 1396__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, 1397 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1398 const locale& __loc) 1399{ 1400 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 1401 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 1402 string __grouping = __npt.grouping(); 1403 __oe = __ob; 1404 char* __nf = __nb; 1405 if (*__nf == '-' || *__nf == '+') 1406 *__oe++ = __ct.widen(*__nf++); 1407 char* __ns; 1408 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 1409 __nf[1] == 'X')) 1410 { 1411 *__oe++ = __ct.widen(*__nf++); 1412 *__oe++ = __ct.widen(*__nf++); 1413 for (__ns = __nf; __ns < __ne; ++__ns) 1414 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 1415 break; 1416 } 1417 else 1418 { 1419 for (__ns = __nf; __ns < __ne; ++__ns) 1420 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 1421 break; 1422 } 1423 if (__grouping.empty()) 1424 { 1425 __ct.widen(__nf, __ns, __oe); 1426 __oe += __ns - __nf; 1427 } 1428 else 1429 { 1430 reverse(__nf, __ns); 1431 _CharT __thousands_sep = __npt.thousands_sep(); 1432 unsigned __dc = 0; 1433 unsigned __dg = 0; 1434 for (char* __p = __nf; __p < __ns; ++__p) 1435 { 1436 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) 1437 { 1438 *__oe++ = __thousands_sep; 1439 __dc = 0; 1440 if (__dg < __grouping.size()-1) 1441 ++__dg; 1442 } 1443 *__oe++ = __ct.widen(*__p); 1444 ++__dc; 1445 } 1446 reverse(__ob + (__nf - __nb), __oe); 1447 } 1448 for (__nf = __ns; __nf < __ne; ++__nf) 1449 { 1450 if (*__nf == '.') 1451 { 1452 *__oe++ = __npt.decimal_point(); 1453 ++__nf; 1454 break; 1455 } 1456 else 1457 *__oe++ = __ct.widen(*__nf); 1458 } 1459 __ct.widen(__nf, __ne, __oe); 1460 __oe += __ne - __nf; 1461 if (__np == __ne) 1462 __op = __oe; 1463 else 1464 __op = __ob + (__np - __nb); 1465} 1466 1467extern template struct __num_put<char>; 1468extern template struct __num_put<wchar_t>; 1469 1470template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 1471class _LIBCPP_VISIBLE num_put 1472 : public locale::facet, 1473 private __num_put<_CharT> 1474{ 1475public: 1476 typedef _CharT char_type; 1477 typedef _OutputIterator iter_type; 1478 1479 _LIBCPP_ALWAYS_INLINE 1480 explicit num_put(size_t __refs = 0) 1481 : locale::facet(__refs) {} 1482 1483 _LIBCPP_ALWAYS_INLINE 1484 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1485 bool __v) const 1486 { 1487 return do_put(__s, __iob, __fl, __v); 1488 } 1489 1490 _LIBCPP_ALWAYS_INLINE 1491 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1492 long __v) const 1493 { 1494 return do_put(__s, __iob, __fl, __v); 1495 } 1496 1497 _LIBCPP_ALWAYS_INLINE 1498 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1499 long long __v) const 1500 { 1501 return do_put(__s, __iob, __fl, __v); 1502 } 1503 1504 _LIBCPP_ALWAYS_INLINE 1505 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1506 unsigned long __v) const 1507 { 1508 return do_put(__s, __iob, __fl, __v); 1509 } 1510 1511 _LIBCPP_ALWAYS_INLINE 1512 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1513 unsigned long long __v) const 1514 { 1515 return do_put(__s, __iob, __fl, __v); 1516 } 1517 1518 _LIBCPP_ALWAYS_INLINE 1519 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1520 double __v) const 1521 { 1522 return do_put(__s, __iob, __fl, __v); 1523 } 1524 1525 _LIBCPP_ALWAYS_INLINE 1526 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1527 long double __v) const 1528 { 1529 return do_put(__s, __iob, __fl, __v); 1530 } 1531 1532 _LIBCPP_ALWAYS_INLINE 1533 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1534 const void* __v) const 1535 { 1536 return do_put(__s, __iob, __fl, __v); 1537 } 1538 1539 static locale::id id; 1540 1541protected: 1542 _LIBCPP_ALWAYS_INLINE 1543 ~num_put() {} 1544 1545 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1546 bool __v) const; 1547 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1548 long __v) const; 1549 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1550 long long __v) const; 1551 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1552 unsigned long) const; 1553 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1554 unsigned long long) const; 1555 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1556 double __v) const; 1557 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1558 long double __v) const; 1559 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1560 const void* __v) const; 1561}; 1562 1563template <class _CharT, class _OutputIterator> 1564locale::id 1565num_put<_CharT, _OutputIterator>::id; 1566 1567template <class _CharT, class _OutputIterator> 1568_LIBCPP_HIDDEN 1569_OutputIterator 1570__pad_and_output(_OutputIterator __s, 1571 const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 1572 ios_base& __iob, _CharT __fl) 1573{ 1574 streamsize __sz = __oe - __ob; 1575 streamsize __ns = __iob.width(); 1576 if (__ns > __sz) 1577 __ns -= __sz; 1578 else 1579 __ns = 0; 1580 for (;__ob < __op; ++__ob, ++__s) 1581 *__s = *__ob; 1582 for (; __ns; --__ns, ++__s) 1583 *__s = __fl; 1584 for (; __ob < __oe; ++__ob, ++__s) 1585 *__s = *__ob; 1586 __iob.width(0); 1587 return __s; 1588} 1589 1590template <class _CharT, class _Traits> 1591_LIBCPP_HIDDEN 1592ostreambuf_iterator<_CharT, _Traits> 1593__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s, 1594 const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 1595 ios_base& __iob, _CharT __fl) 1596{ 1597 if (__s.__sbuf_ == nullptr) 1598 return __s; 1599 streamsize __sz = __oe - __ob; 1600 streamsize __ns = __iob.width(); 1601 if (__ns > __sz) 1602 __ns -= __sz; 1603 else 1604 __ns = 0; 1605 streamsize __np = __op - __ob; 1606 if (__np > 0) 1607 { 1608 if (__s.__sbuf_->sputn(__ob, __np) != __np) 1609 { 1610 __s.__sbuf_ = nullptr; 1611 return __s; 1612 } 1613 } 1614 if (__ns > 0) 1615 { 1616 basic_string<_CharT, _Traits> __sp(__ns, __fl); 1617 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns) 1618 { 1619 __s.__sbuf_ = nullptr; 1620 return __s; 1621 } 1622 } 1623 __np = __oe - __op; 1624 if (__np > 0) 1625 { 1626 if (__s.__sbuf_->sputn(__op, __np) != __np) 1627 { 1628 __s.__sbuf_ = nullptr; 1629 return __s; 1630 } 1631 } 1632 __iob.width(0); 1633 return __s; 1634} 1635 1636template <class _CharT, class _OutputIterator> 1637_OutputIterator 1638num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1639 char_type __fl, bool __v) const 1640{ 1641 if ((__iob.flags() & ios_base::boolalpha) == 0) 1642 return do_put(__s, __iob, __fl, (unsigned long)__v); 1643 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc()); 1644 typedef typename numpunct<char_type>::string_type string_type; 1645 string_type __nm = __v ? __np.truename() : __np.falsename(); 1646 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) 1647 *__s = *__i; 1648 return __s; 1649} 1650 1651template <class _CharT, class _OutputIterator> 1652_OutputIterator 1653num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1654 char_type __fl, long __v) const 1655{ 1656 // Stage 1 - Get number in narrow char 1657 char __fmt[6] = {'%', 0}; 1658 const char* __len = "l"; 1659 this->__format_int(__fmt+1, __len, true, __iob.flags()); 1660 const unsigned __nbuf = (numeric_limits<long>::digits / 3) 1661 + ((numeric_limits<long>::digits % 3) != 0) 1662 + 1; 1663 char __nar[__nbuf]; 1664#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1665 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1666#else 1667 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1668#endif 1669 char* __ne = __nar + __nc; 1670 char* __np = this->__identify_padding(__nar, __ne, __iob); 1671 // Stage 2 - Widen __nar while adding thousands separators 1672 char_type __o[2*(__nbuf-1) - 1]; 1673 char_type* __op; // pad here 1674 char_type* __oe; // end of output 1675 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1676 // [__o, __oe) contains thousands_sep'd wide number 1677 // Stage 3 & 4 1678 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1679} 1680 1681template <class _CharT, class _OutputIterator> 1682_OutputIterator 1683num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1684 char_type __fl, long long __v) const 1685{ 1686 // Stage 1 - Get number in narrow char 1687 char __fmt[8] = {'%', 0}; 1688 const char* __len = "ll"; 1689 this->__format_int(__fmt+1, __len, true, __iob.flags()); 1690 const unsigned __nbuf = (numeric_limits<long long>::digits / 3) 1691 + ((numeric_limits<long long>::digits % 3) != 0) 1692 + 1; 1693 char __nar[__nbuf]; 1694#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1695 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1696#else 1697 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1698#endif 1699 char* __ne = __nar + __nc; 1700 char* __np = this->__identify_padding(__nar, __ne, __iob); 1701 // Stage 2 - Widen __nar while adding thousands separators 1702 char_type __o[2*(__nbuf-1) - 1]; 1703 char_type* __op; // pad here 1704 char_type* __oe; // end of output 1705 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1706 // [__o, __oe) contains thousands_sep'd wide number 1707 // Stage 3 & 4 1708 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1709} 1710 1711template <class _CharT, class _OutputIterator> 1712_OutputIterator 1713num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1714 char_type __fl, unsigned long __v) const 1715{ 1716 // Stage 1 - Get number in narrow char 1717 char __fmt[6] = {'%', 0}; 1718 const char* __len = "l"; 1719 this->__format_int(__fmt+1, __len, false, __iob.flags()); 1720 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3) 1721 + ((numeric_limits<unsigned long>::digits % 3) != 0) 1722 + 1; 1723 char __nar[__nbuf]; 1724#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1725 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1726#else 1727 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1728#endif 1729 char* __ne = __nar + __nc; 1730 char* __np = this->__identify_padding(__nar, __ne, __iob); 1731 // Stage 2 - Widen __nar while adding thousands separators 1732 char_type __o[2*(__nbuf-1) - 1]; 1733 char_type* __op; // pad here 1734 char_type* __oe; // end of output 1735 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1736 // [__o, __oe) contains thousands_sep'd wide number 1737 // Stage 3 & 4 1738 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1739} 1740 1741template <class _CharT, class _OutputIterator> 1742_OutputIterator 1743num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1744 char_type __fl, unsigned long long __v) const 1745{ 1746 // Stage 1 - Get number in narrow char 1747 char __fmt[8] = {'%', 0}; 1748 const char* __len = "ll"; 1749 this->__format_int(__fmt+1, __len, false, __iob.flags()); 1750 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3) 1751 + ((numeric_limits<unsigned long long>::digits % 3) != 0) 1752 + 1; 1753 char __nar[__nbuf]; 1754#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1755 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1756#else 1757 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1758#endif 1759 char* __ne = __nar + __nc; 1760 char* __np = this->__identify_padding(__nar, __ne, __iob); 1761 // Stage 2 - Widen __nar while adding thousands separators 1762 char_type __o[2*(__nbuf-1) - 1]; 1763 char_type* __op; // pad here 1764 char_type* __oe; // end of output 1765 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1766 // [__o, __oe) contains thousands_sep'd wide number 1767 // Stage 3 & 4 1768 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1769} 1770 1771template <class _CharT, class _OutputIterator> 1772_OutputIterator 1773num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1774 char_type __fl, double __v) const 1775{ 1776 // Stage 1 - Get number in narrow char 1777 char __fmt[8] = {'%', 0}; 1778 const char* __len = ""; 1779 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1780 const unsigned __nbuf = 30; 1781 char __nar[__nbuf]; 1782 char* __nb = __nar; 1783 int __nc; 1784 if (__specify_precision) 1785#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1786 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1787 (int)__iob.precision(), __v); 1788#else 1789 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, 1790 (int)__iob.precision(), __v); 1791#endif 1792 else 1793#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1794 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1795#else 1796 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v); 1797#endif 1798 unique_ptr<char, void(*)(void*)> __nbh(0, free); 1799 if (__nc > static_cast<int>(__nbuf-1)) 1800 { 1801 if (__specify_precision) 1802#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1803 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1804#else 1805 __nc = __asprintf_l(&__nb, __cloc(), __fmt, 1806 (int)__iob.precision(), __v); 1807#endif 1808 else 1809#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1810 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1811#else 1812 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v); 1813#endif 1814 if (__nb == 0) 1815 __throw_bad_alloc(); 1816 __nbh.reset(__nb); 1817 } 1818 char* __ne = __nb + __nc; 1819 char* __np = this->__identify_padding(__nb, __ne, __iob); 1820 // Stage 2 - Widen __nar while adding thousands separators 1821 char_type __o[2*(__nbuf-1) - 1]; 1822 char_type* __ob = __o; 1823 unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1824 if (__nb != __nar) 1825 { 1826 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1827 if (__ob == 0) 1828 __throw_bad_alloc(); 1829 __obh.reset(__ob); 1830 } 1831 char_type* __op; // pad here 1832 char_type* __oe; // end of output 1833 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1834 // [__o, __oe) contains thousands_sep'd wide number 1835 // Stage 3 & 4 1836 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1837 return __s; 1838} 1839 1840template <class _CharT, class _OutputIterator> 1841_OutputIterator 1842num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1843 char_type __fl, long double __v) const 1844{ 1845 // Stage 1 - Get number in narrow char 1846 char __fmt[8] = {'%', 0}; 1847 const char* __len = "L"; 1848 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1849 const unsigned __nbuf = 30; 1850 char __nar[__nbuf]; 1851 char* __nb = __nar; 1852 int __nc; 1853 if (__specify_precision) 1854#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1855 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1856 (int)__iob.precision(), __v); 1857#else 1858 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, 1859 (int)__iob.precision(), __v); 1860#endif 1861 else 1862#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1863 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1864#else 1865 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v); 1866#endif 1867 unique_ptr<char, void(*)(void*)> __nbh(0, free); 1868 if (__nc > static_cast<int>(__nbuf-1)) 1869 { 1870 if (__specify_precision) 1871#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1872 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1873#else 1874 __nc = __asprintf_l(&__nb, __cloc(), __fmt, 1875 (int)__iob.precision(), __v); 1876#endif 1877 else 1878#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1879 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1880#else 1881 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v); 1882#endif 1883 if (__nb == 0) 1884 __throw_bad_alloc(); 1885 __nbh.reset(__nb); 1886 } 1887 char* __ne = __nb + __nc; 1888 char* __np = this->__identify_padding(__nb, __ne, __iob); 1889 // Stage 2 - Widen __nar while adding thousands separators 1890 char_type __o[2*(__nbuf-1) - 1]; 1891 char_type* __ob = __o; 1892 unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1893 if (__nb != __nar) 1894 { 1895 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1896 if (__ob == 0) 1897 __throw_bad_alloc(); 1898 __obh.reset(__ob); 1899 } 1900 char_type* __op; // pad here 1901 char_type* __oe; // end of output 1902 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1903 // [__o, __oe) contains thousands_sep'd wide number 1904 // Stage 3 & 4 1905 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1906 return __s; 1907} 1908 1909template <class _CharT, class _OutputIterator> 1910_OutputIterator 1911num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1912 char_type __fl, const void* __v) const 1913{ 1914 // Stage 1 - Get pointer in narrow char 1915 char __fmt[6] = "%p"; 1916 const unsigned __nbuf = 20; 1917 char __nar[__nbuf]; 1918#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1919 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1920#else 1921 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1922#endif 1923 char* __ne = __nar + __nc; 1924 char* __np = this->__identify_padding(__nar, __ne, __iob); 1925 // Stage 2 - Widen __nar 1926 char_type __o[2*(__nbuf-1) - 1]; 1927 char_type* __op; // pad here 1928 char_type* __oe; // end of output 1929 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 1930 __ct.widen(__nar, __ne, __o); 1931 __oe = __o + (__ne - __nar); 1932 if (__np == __ne) 1933 __op = __oe; 1934 else 1935 __op = __o + (__np - __nar); 1936 // [__o, __oe) contains wide number 1937 // Stage 3 & 4 1938 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1939} 1940 1941extern template class num_put<char>; 1942extern template class num_put<wchar_t>; 1943 1944template <class _CharT, class _InputIterator> 1945_LIBCPP_HIDDEN 1946int 1947__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, 1948 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) 1949{ 1950 // Precondition: __n >= 1 1951 if (__b == __e) 1952 { 1953 __err |= ios_base::eofbit | ios_base::failbit; 1954 return 0; 1955 } 1956 // get first digit 1957 _CharT __c = *__b; 1958 if (!__ct.is(ctype_base::digit, __c)) 1959 { 1960 __err |= ios_base::failbit; 1961 return 0; 1962 } 1963 int __r = __ct.narrow(__c, 0) - '0'; 1964 for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n) 1965 { 1966 // get next digit 1967 __c = *__b; 1968 if (!__ct.is(ctype_base::digit, __c)) 1969 return __r; 1970 __r = __r * 10 + __ct.narrow(__c, 0) - '0'; 1971 } 1972 if (__b == __e) 1973 __err |= ios_base::eofbit; 1974 return __r; 1975} 1976 1977class _LIBCPP_VISIBLE time_base 1978{ 1979public: 1980 enum dateorder {no_order, dmy, mdy, ymd, ydm}; 1981}; 1982 1983template <class _CharT> 1984class __time_get_c_storage // purposefully not decorated 1985{ 1986protected: 1987 typedef basic_string<_CharT> string_type; 1988 1989 virtual const string_type* __weeks() const; 1990 virtual const string_type* __months() const; 1991 virtual const string_type* __am_pm() const; 1992 virtual const string_type& __c() const; 1993 virtual const string_type& __r() const; 1994 virtual const string_type& __x() const; 1995 virtual const string_type& __X() const; 1996}; 1997 1998template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 1999class _LIBCPP_VISIBLE time_get 2000 : public locale::facet, 2001 public time_base, 2002 private __time_get_c_storage<_CharT> 2003{ 2004public: 2005 typedef _CharT char_type; 2006 typedef _InputIterator iter_type; 2007 typedef time_base::dateorder dateorder; 2008 typedef basic_string<char_type> string_type; 2009 2010 _LIBCPP_ALWAYS_INLINE 2011 explicit time_get(size_t __refs = 0) 2012 : locale::facet(__refs) {} 2013 2014 _LIBCPP_ALWAYS_INLINE 2015 dateorder date_order() const 2016 { 2017 return this->do_date_order(); 2018 } 2019 2020 _LIBCPP_ALWAYS_INLINE 2021 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, 2022 ios_base::iostate& __err, tm* __tm) const 2023 { 2024 return do_get_time(__b, __e, __iob, __err, __tm); 2025 } 2026 2027 _LIBCPP_ALWAYS_INLINE 2028 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, 2029 ios_base::iostate& __err, tm* __tm) const 2030 { 2031 return do_get_date(__b, __e, __iob, __err, __tm); 2032 } 2033 2034 _LIBCPP_ALWAYS_INLINE 2035 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 2036 ios_base::iostate& __err, tm* __tm) const 2037 { 2038 return do_get_weekday(__b, __e, __iob, __err, __tm); 2039 } 2040 2041 _LIBCPP_ALWAYS_INLINE 2042 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 2043 ios_base::iostate& __err, tm* __tm) const 2044 { 2045 return do_get_monthname(__b, __e, __iob, __err, __tm); 2046 } 2047 2048 _LIBCPP_ALWAYS_INLINE 2049 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, 2050 ios_base::iostate& __err, tm* __tm) const 2051 { 2052 return do_get_year(__b, __e, __iob, __err, __tm); 2053 } 2054 2055 _LIBCPP_ALWAYS_INLINE 2056 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 2057 ios_base::iostate& __err, tm *__tm, 2058 char __fmt, char __mod = 0) const 2059 { 2060 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); 2061 } 2062 2063 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 2064 ios_base::iostate& __err, tm* __tm, 2065 const char_type* __fmtb, const char_type* __fmte) const; 2066 2067 static locale::id id; 2068 2069protected: 2070 _LIBCPP_ALWAYS_INLINE 2071 ~time_get() {} 2072 2073 virtual dateorder do_date_order() const; 2074 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob, 2075 ios_base::iostate& __err, tm* __tm) const; 2076 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob, 2077 ios_base::iostate& __err, tm* __tm) const; 2078 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 2079 ios_base::iostate& __err, tm* __tm) const; 2080 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 2081 ios_base::iostate& __err, tm* __tm) const; 2082 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob, 2083 ios_base::iostate& __err, tm* __tm) const; 2084 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 2085 ios_base::iostate& __err, tm* __tm, 2086 char __fmt, char __mod) const; 2087private: 2088 void __get_white_space(iter_type& __b, iter_type __e, 2089 ios_base::iostate& __err, const ctype<char_type>& __ct) const; 2090 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, 2091 const ctype<char_type>& __ct) const; 2092 2093 void __get_weekdayname(int& __m, 2094 iter_type& __b, iter_type __e, 2095 ios_base::iostate& __err, 2096 const ctype<char_type>& __ct) const; 2097 void __get_monthname(int& __m, 2098 iter_type& __b, iter_type __e, 2099 ios_base::iostate& __err, 2100 const ctype<char_type>& __ct) const; 2101 void __get_day(int& __d, 2102 iter_type& __b, iter_type __e, 2103 ios_base::iostate& __err, 2104 const ctype<char_type>& __ct) const; 2105 void __get_month(int& __m, 2106 iter_type& __b, iter_type __e, 2107 ios_base::iostate& __err, 2108 const ctype<char_type>& __ct) const; 2109 void __get_year(int& __y, 2110 iter_type& __b, iter_type __e, 2111 ios_base::iostate& __err, 2112 const ctype<char_type>& __ct) const; 2113 void __get_year4(int& __y, 2114 iter_type& __b, iter_type __e, 2115 ios_base::iostate& __err, 2116 const ctype<char_type>& __ct) const; 2117 void __get_hour(int& __d, 2118 iter_type& __b, iter_type __e, 2119 ios_base::iostate& __err, 2120 const ctype<char_type>& __ct) const; 2121 void __get_12_hour(int& __h, 2122 iter_type& __b, iter_type __e, 2123 ios_base::iostate& __err, 2124 const ctype<char_type>& __ct) const; 2125 void __get_am_pm(int& __h, 2126 iter_type& __b, iter_type __e, 2127 ios_base::iostate& __err, 2128 const ctype<char_type>& __ct) const; 2129 void __get_minute(int& __m, 2130 iter_type& __b, iter_type __e, 2131 ios_base::iostate& __err, 2132 const ctype<char_type>& __ct) const; 2133 void __get_second(int& __s, 2134 iter_type& __b, iter_type __e, 2135 ios_base::iostate& __err, 2136 const ctype<char_type>& __ct) const; 2137 void __get_weekday(int& __w, 2138 iter_type& __b, iter_type __e, 2139 ios_base::iostate& __err, 2140 const ctype<char_type>& __ct) const; 2141 void __get_day_year_num(int& __w, 2142 iter_type& __b, iter_type __e, 2143 ios_base::iostate& __err, 2144 const ctype<char_type>& __ct) const; 2145}; 2146 2147template <class _CharT, class _InputIterator> 2148locale::id 2149time_get<_CharT, _InputIterator>::id; 2150 2151// time_get primatives 2152 2153template <class _CharT, class _InputIterator> 2154void 2155time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, 2156 iter_type& __b, iter_type __e, 2157 ios_base::iostate& __err, 2158 const ctype<char_type>& __ct) const 2159{ 2160 // Note: ignoring case comes from the POSIX strptime spec 2161 const string_type* __wk = this->__weeks(); 2162 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; 2163 if (__i < 14) 2164 __w = __i % 7; 2165} 2166 2167template <class _CharT, class _InputIterator> 2168void 2169time_get<_CharT, _InputIterator>::__get_monthname(int& __m, 2170 iter_type& __b, iter_type __e, 2171 ios_base::iostate& __err, 2172 const ctype<char_type>& __ct) const 2173{ 2174 // Note: ignoring case comes from the POSIX strptime spec 2175 const string_type* __month = this->__months(); 2176 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; 2177 if (__i < 24) 2178 __m = __i % 12; 2179} 2180 2181template <class _CharT, class _InputIterator> 2182void 2183time_get<_CharT, _InputIterator>::__get_day(int& __d, 2184 iter_type& __b, iter_type __e, 2185 ios_base::iostate& __err, 2186 const ctype<char_type>& __ct) const 2187{ 2188 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2189 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) 2190 __d = __t; 2191 else 2192 __err |= ios_base::failbit; 2193} 2194 2195template <class _CharT, class _InputIterator> 2196void 2197time_get<_CharT, _InputIterator>::__get_month(int& __m, 2198 iter_type& __b, iter_type __e, 2199 ios_base::iostate& __err, 2200 const ctype<char_type>& __ct) const 2201{ 2202 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; 2203 if (!(__err & ios_base::failbit) && __t <= 11) 2204 __m = __t; 2205 else 2206 __err |= ios_base::failbit; 2207} 2208 2209template <class _CharT, class _InputIterator> 2210void 2211time_get<_CharT, _InputIterator>::__get_year(int& __y, 2212 iter_type& __b, iter_type __e, 2213 ios_base::iostate& __err, 2214 const ctype<char_type>& __ct) const 2215{ 2216 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 2217 if (!(__err & ios_base::failbit)) 2218 { 2219 if (__t < 69) 2220 __t += 2000; 2221 else if (69 <= __t && __t <= 99) 2222 __t += 1900; 2223 __y = __t - 1900; 2224 } 2225} 2226 2227template <class _CharT, class _InputIterator> 2228void 2229time_get<_CharT, _InputIterator>::__get_year4(int& __y, 2230 iter_type& __b, iter_type __e, 2231 ios_base::iostate& __err, 2232 const ctype<char_type>& __ct) const 2233{ 2234 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 2235 if (!(__err & ios_base::failbit)) 2236 __y = __t - 1900; 2237} 2238 2239template <class _CharT, class _InputIterator> 2240void 2241time_get<_CharT, _InputIterator>::__get_hour(int& __h, 2242 iter_type& __b, iter_type __e, 2243 ios_base::iostate& __err, 2244 const ctype<char_type>& __ct) const 2245{ 2246 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2247 if (!(__err & ios_base::failbit) && __t <= 23) 2248 __h = __t; 2249 else 2250 __err |= ios_base::failbit; 2251} 2252 2253template <class _CharT, class _InputIterator> 2254void 2255time_get<_CharT, _InputIterator>::__get_12_hour(int& __h, 2256 iter_type& __b, iter_type __e, 2257 ios_base::iostate& __err, 2258 const ctype<char_type>& __ct) const 2259{ 2260 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2261 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) 2262 __h = __t; 2263 else 2264 __err |= ios_base::failbit; 2265} 2266 2267template <class _CharT, class _InputIterator> 2268void 2269time_get<_CharT, _InputIterator>::__get_minute(int& __m, 2270 iter_type& __b, iter_type __e, 2271 ios_base::iostate& __err, 2272 const ctype<char_type>& __ct) const 2273{ 2274 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2275 if (!(__err & ios_base::failbit) && __t <= 59) 2276 __m = __t; 2277 else 2278 __err |= ios_base::failbit; 2279} 2280 2281template <class _CharT, class _InputIterator> 2282void 2283time_get<_CharT, _InputIterator>::__get_second(int& __s, 2284 iter_type& __b, iter_type __e, 2285 ios_base::iostate& __err, 2286 const ctype<char_type>& __ct) const 2287{ 2288 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2289 if (!(__err & ios_base::failbit) && __t <= 60) 2290 __s = __t; 2291 else 2292 __err |= ios_base::failbit; 2293} 2294 2295template <class _CharT, class _InputIterator> 2296void 2297time_get<_CharT, _InputIterator>::__get_weekday(int& __w, 2298 iter_type& __b, iter_type __e, 2299 ios_base::iostate& __err, 2300 const ctype<char_type>& __ct) const 2301{ 2302 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1); 2303 if (!(__err & ios_base::failbit) && __t <= 6) 2304 __w = __t; 2305 else 2306 __err |= ios_base::failbit; 2307} 2308 2309template <class _CharT, class _InputIterator> 2310void 2311time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d, 2312 iter_type& __b, iter_type __e, 2313 ios_base::iostate& __err, 2314 const ctype<char_type>& __ct) const 2315{ 2316 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3); 2317 if (!(__err & ios_base::failbit) && __t <= 365) 2318 __d = __t; 2319 else 2320 __err |= ios_base::failbit; 2321} 2322 2323template <class _CharT, class _InputIterator> 2324void 2325time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e, 2326 ios_base::iostate& __err, 2327 const ctype<char_type>& __ct) const 2328{ 2329 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2330 ; 2331 if (__b == __e) 2332 __err |= ios_base::eofbit; 2333} 2334 2335template <class _CharT, class _InputIterator> 2336void 2337time_get<_CharT, _InputIterator>::__get_am_pm(int& __h, 2338 iter_type& __b, iter_type __e, 2339 ios_base::iostate& __err, 2340 const ctype<char_type>& __ct) const 2341{ 2342 const string_type* __ap = this->__am_pm(); 2343 if (__ap[0].size() + __ap[1].size() == 0) 2344 { 2345 __err |= ios_base::failbit; 2346 return; 2347 } 2348 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; 2349 if (__i == 0 && __h == 12) 2350 __h = 0; 2351 else if (__i == 1 && __h < 12) 2352 __h += 12; 2353} 2354 2355template <class _CharT, class _InputIterator> 2356void 2357time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e, 2358 ios_base::iostate& __err, 2359 const ctype<char_type>& __ct) const 2360{ 2361 if (__b == __e) 2362 { 2363 __err |= ios_base::eofbit | ios_base::failbit; 2364 return; 2365 } 2366 if (__ct.narrow(*__b, 0) != '%') 2367 __err |= ios_base::failbit; 2368 else if(++__b == __e) 2369 __err |= ios_base::eofbit; 2370} 2371 2372// time_get end primatives 2373 2374template <class _CharT, class _InputIterator> 2375_InputIterator 2376time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e, 2377 ios_base& __iob, 2378 ios_base::iostate& __err, tm* __tm, 2379 const char_type* __fmtb, const char_type* __fmte) const 2380{ 2381 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2382 __err = ios_base::goodbit; 2383 while (__fmtb != __fmte && __err == ios_base::goodbit) 2384 { 2385 if (__b == __e) 2386 { 2387 __err = ios_base::failbit; 2388 break; 2389 } 2390 if (__ct.narrow(*__fmtb, 0) == '%') 2391 { 2392 if (++__fmtb == __fmte) 2393 { 2394 __err = ios_base::failbit; 2395 break; 2396 } 2397 char __cmd = __ct.narrow(*__fmtb, 0); 2398 char __opt = '\0'; 2399 if (__cmd == 'E' || __cmd == '0') 2400 { 2401 if (++__fmtb == __fmte) 2402 { 2403 __err = ios_base::failbit; 2404 break; 2405 } 2406 __opt = __cmd; 2407 __cmd = __ct.narrow(*__fmtb, 0); 2408 } 2409 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); 2410 ++__fmtb; 2411 } 2412 else if (__ct.is(ctype_base::space, *__fmtb)) 2413 { 2414 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) 2415 ; 2416 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2417 ; 2418 } 2419 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) 2420 { 2421 ++__b; 2422 ++__fmtb; 2423 } 2424 else 2425 __err = ios_base::failbit; 2426 } 2427 if (__b == __e) 2428 __err |= ios_base::eofbit; 2429 return __b; 2430} 2431 2432template <class _CharT, class _InputIterator> 2433typename time_get<_CharT, _InputIterator>::dateorder 2434time_get<_CharT, _InputIterator>::do_date_order() const 2435{ 2436 return mdy; 2437} 2438 2439template <class _CharT, class _InputIterator> 2440_InputIterator 2441time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e, 2442 ios_base& __iob, 2443 ios_base::iostate& __err, 2444 tm* __tm) const 2445{ 2446 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2447 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); 2448} 2449 2450template <class _CharT, class _InputIterator> 2451_InputIterator 2452time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, 2453 ios_base& __iob, 2454 ios_base::iostate& __err, 2455 tm* __tm) const 2456{ 2457 const string_type& __fmt = this->__x(); 2458 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); 2459} 2460 2461template <class _CharT, class _InputIterator> 2462_InputIterator 2463time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e, 2464 ios_base& __iob, 2465 ios_base::iostate& __err, 2466 tm* __tm) const 2467{ 2468 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2469 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2470 return __b; 2471} 2472 2473template <class _CharT, class _InputIterator> 2474_InputIterator 2475time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e, 2476 ios_base& __iob, 2477 ios_base::iostate& __err, 2478 tm* __tm) const 2479{ 2480 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2481 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2482 return __b; 2483} 2484 2485template <class _CharT, class _InputIterator> 2486_InputIterator 2487time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e, 2488 ios_base& __iob, 2489 ios_base::iostate& __err, 2490 tm* __tm) const 2491{ 2492 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2493 __get_year(__tm->tm_year, __b, __e, __err, __ct); 2494 return __b; 2495} 2496 2497template <class _CharT, class _InputIterator> 2498_InputIterator 2499time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 2500 ios_base& __iob, 2501 ios_base::iostate& __err, tm* __tm, 2502 char __fmt, char) const 2503{ 2504 __err = ios_base::goodbit; 2505 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2506 switch (__fmt) 2507 { 2508 case 'a': 2509 case 'A': 2510 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2511 break; 2512 case 'b': 2513 case 'B': 2514 case 'h': 2515 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2516 break; 2517 case 'c': 2518 { 2519 const string_type& __fm = this->__c(); 2520 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2521 } 2522 break; 2523 case 'd': 2524 case 'e': 2525 __get_day(__tm->tm_mday, __b, __e, __err, __ct); 2526 break; 2527 case 'D': 2528 { 2529 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; 2530 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2531 } 2532 break; 2533 case 'F': 2534 { 2535 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; 2536 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2537 } 2538 break; 2539 case 'H': 2540 __get_hour(__tm->tm_hour, __b, __e, __err, __ct); 2541 break; 2542 case 'I': 2543 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); 2544 break; 2545 case 'j': 2546 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); 2547 break; 2548 case 'm': 2549 __get_month(__tm->tm_mon, __b, __e, __err, __ct); 2550 break; 2551 case 'M': 2552 __get_minute(__tm->tm_min, __b, __e, __err, __ct); 2553 break; 2554 case 'n': 2555 case 't': 2556 __get_white_space(__b, __e, __err, __ct); 2557 break; 2558 case 'p': 2559 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); 2560 break; 2561 case 'r': 2562 { 2563 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; 2564 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2565 } 2566 break; 2567 case 'R': 2568 { 2569 const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; 2570 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2571 } 2572 break; 2573 case 'S': 2574 __get_second(__tm->tm_sec, __b, __e, __err, __ct); 2575 break; 2576 case 'T': 2577 { 2578 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2579 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2580 } 2581 break; 2582 case 'w': 2583 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); 2584 break; 2585 case 'x': 2586 return do_get_date(__b, __e, __iob, __err, __tm); 2587 case 'X': 2588 { 2589 const string_type& __fm = this->__X(); 2590 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2591 } 2592 break; 2593 case 'y': 2594 __get_year(__tm->tm_year, __b, __e, __err, __ct); 2595 break; 2596 case 'Y': 2597 __get_year4(__tm->tm_year, __b, __e, __err, __ct); 2598 break; 2599 case '%': 2600 __get_percent(__b, __e, __err, __ct); 2601 break; 2602 default: 2603 __err |= ios_base::failbit; 2604 } 2605 return __b; 2606} 2607 2608extern template class time_get<char>; 2609extern template class time_get<wchar_t>; 2610 2611class __time_get 2612{ 2613protected: 2614 locale_t __loc_; 2615 2616 __time_get(const char* __nm); 2617 __time_get(const string& __nm); 2618 ~__time_get(); 2619}; 2620 2621template <class _CharT> 2622class __time_get_storage 2623 : public __time_get 2624{ 2625protected: 2626 typedef basic_string<_CharT> string_type; 2627 2628 string_type __weeks_[14]; 2629 string_type __months_[24]; 2630 string_type __am_pm_[2]; 2631 string_type __c_; 2632 string_type __r_; 2633 string_type __x_; 2634 string_type __X_; 2635 2636 explicit __time_get_storage(const char* __nm); 2637 explicit __time_get_storage(const string& __nm); 2638 2639 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {} 2640 2641 time_base::dateorder __do_date_order() const; 2642 2643private: 2644 void init(const ctype<_CharT>&); 2645 string_type __analyze(char __fmt, const ctype<_CharT>&); 2646}; 2647 2648template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2649class _LIBCPP_VISIBLE time_get_byname 2650 : public time_get<_CharT, _InputIterator>, 2651 private __time_get_storage<_CharT> 2652{ 2653public: 2654 typedef time_base::dateorder dateorder; 2655 typedef _InputIterator iter_type; 2656 typedef _CharT char_type; 2657 typedef basic_string<char_type> string_type; 2658 2659 _LIBCPP_INLINE_VISIBILITY 2660 explicit time_get_byname(const char* __nm, size_t __refs = 0) 2661 : time_get<_CharT, _InputIterator>(__refs), 2662 __time_get_storage<_CharT>(__nm) {} 2663 _LIBCPP_INLINE_VISIBILITY 2664 explicit time_get_byname(const string& __nm, size_t __refs = 0) 2665 : time_get<_CharT, _InputIterator>(__refs), 2666 __time_get_storage<_CharT>(__nm) {} 2667 2668protected: 2669 _LIBCPP_INLINE_VISIBILITY 2670 ~time_get_byname() {} 2671 2672 _LIBCPP_INLINE_VISIBILITY 2673 virtual dateorder do_date_order() const {return this->__do_date_order();} 2674private: 2675 _LIBCPP_INLINE_VISIBILITY 2676 virtual const string_type* __weeks() const {return this->__weeks_;} 2677 _LIBCPP_INLINE_VISIBILITY 2678 virtual const string_type* __months() const {return this->__months_;} 2679 _LIBCPP_INLINE_VISIBILITY 2680 virtual const string_type* __am_pm() const {return this->__am_pm_;} 2681 _LIBCPP_INLINE_VISIBILITY 2682 virtual const string_type& __c() const {return this->__c_;} 2683 _LIBCPP_INLINE_VISIBILITY 2684 virtual const string_type& __r() const {return this->__r_;} 2685 _LIBCPP_INLINE_VISIBILITY 2686 virtual const string_type& __x() const {return this->__x_;} 2687 _LIBCPP_INLINE_VISIBILITY 2688 virtual const string_type& __X() const {return this->__X_;} 2689}; 2690 2691extern template class time_get_byname<char>; 2692extern template class time_get_byname<wchar_t>; 2693 2694class __time_put 2695{ 2696 locale_t __loc_; 2697protected: 2698 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} 2699 __time_put(const char* __nm); 2700 __time_put(const string& __nm); 2701 ~__time_put(); 2702 void __do_put(char* __nb, char*& __ne, const tm* __tm, 2703 char __fmt, char __mod) const; 2704 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 2705 char __fmt, char __mod) const; 2706}; 2707 2708template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2709class _LIBCPP_VISIBLE time_put 2710 : public locale::facet, 2711 private __time_put 2712{ 2713public: 2714 typedef _CharT char_type; 2715 typedef _OutputIterator iter_type; 2716 2717 _LIBCPP_ALWAYS_INLINE 2718 explicit time_put(size_t __refs = 0) 2719 : locale::facet(__refs) {} 2720 2721 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, 2722 const char_type* __pb, const char_type* __pe) const; 2723 2724 _LIBCPP_ALWAYS_INLINE 2725 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 2726 const tm* __tm, char __fmt, char __mod = 0) const 2727 { 2728 return do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2729 } 2730 2731 static locale::id id; 2732 2733protected: 2734 _LIBCPP_ALWAYS_INLINE 2735 ~time_put() {} 2736 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, 2737 char __fmt, char __mod) const; 2738 2739 _LIBCPP_ALWAYS_INLINE 2740 explicit time_put(const char* __nm, size_t __refs) 2741 : locale::facet(__refs), 2742 __time_put(__nm) {} 2743 _LIBCPP_ALWAYS_INLINE 2744 explicit time_put(const string& __nm, size_t __refs) 2745 : locale::facet(__refs), 2746 __time_put(__nm) {} 2747}; 2748 2749template <class _CharT, class _OutputIterator> 2750locale::id 2751time_put<_CharT, _OutputIterator>::id; 2752 2753template <class _CharT, class _OutputIterator> 2754_OutputIterator 2755time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, 2756 char_type __fl, const tm* __tm, 2757 const char_type* __pb, 2758 const char_type* __pe) const 2759{ 2760 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2761 for (; __pb != __pe; ++__pb) 2762 { 2763 if (__ct.narrow(*__pb, 0) == '%') 2764 { 2765 if (++__pb == __pe) 2766 { 2767 *__s++ = __pb[-1]; 2768 break; 2769 } 2770 char __mod = 0; 2771 char __fmt = __ct.narrow(*__pb, 0); 2772 if (__fmt == 'E' || __fmt == 'O') 2773 { 2774 if (++__pb == __pe) 2775 { 2776 *__s++ = __pb[-2]; 2777 *__s++ = __pb[-1]; 2778 break; 2779 } 2780 __mod = __fmt; 2781 __fmt = __ct.narrow(*__pb, 0); 2782 } 2783 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2784 } 2785 else 2786 *__s++ = *__pb; 2787 } 2788 return __s; 2789} 2790 2791template <class _CharT, class _OutputIterator> 2792_OutputIterator 2793time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, 2794 char_type, const tm* __tm, 2795 char __fmt, char __mod) const 2796{ 2797 char_type __nar[100]; 2798 char_type* __nb = __nar; 2799 char_type* __ne = __nb + 100; 2800 __do_put(__nb, __ne, __tm, __fmt, __mod); 2801 return _VSTD::copy(__nb, __ne, __s); 2802} 2803 2804extern template class time_put<char>; 2805extern template class time_put<wchar_t>; 2806 2807template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2808class _LIBCPP_VISIBLE time_put_byname 2809 : public time_put<_CharT, _OutputIterator> 2810{ 2811public: 2812 _LIBCPP_ALWAYS_INLINE 2813 explicit time_put_byname(const char* __nm, size_t __refs = 0) 2814 : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2815 2816 _LIBCPP_ALWAYS_INLINE 2817 explicit time_put_byname(const string& __nm, size_t __refs = 0) 2818 : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2819 2820protected: 2821 _LIBCPP_ALWAYS_INLINE 2822 ~time_put_byname() {} 2823}; 2824 2825extern template class time_put_byname<char>; 2826extern template class time_put_byname<wchar_t>; 2827 2828// money_base 2829 2830class _LIBCPP_VISIBLE money_base 2831{ 2832public: 2833 enum part {none, space, symbol, sign, value}; 2834 struct pattern {char field[4];}; 2835 2836 _LIBCPP_ALWAYS_INLINE money_base() {} 2837}; 2838 2839// moneypunct 2840 2841template <class _CharT, bool _International = false> 2842class _LIBCPP_VISIBLE moneypunct 2843 : public locale::facet, 2844 public money_base 2845{ 2846public: 2847 typedef _CharT char_type; 2848 typedef basic_string<char_type> string_type; 2849 2850 _LIBCPP_ALWAYS_INLINE 2851 explicit moneypunct(size_t __refs = 0) 2852 : locale::facet(__refs) {} 2853 2854 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} 2855 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} 2856 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} 2857 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();} 2858 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();} 2859 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();} 2860 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();} 2861 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();} 2862 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();} 2863 2864 static locale::id id; 2865 static const bool intl = _International; 2866 2867protected: 2868 _LIBCPP_ALWAYS_INLINE 2869 ~moneypunct() {} 2870 2871 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();} 2872 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();} 2873 virtual string do_grouping() const {return string();} 2874 virtual string_type do_curr_symbol() const {return string_type();} 2875 virtual string_type do_positive_sign() const {return string_type();} 2876 virtual string_type do_negative_sign() const {return string_type(1, '-');} 2877 virtual int do_frac_digits() const {return 0;} 2878 virtual pattern do_pos_format() const 2879 {pattern __p = {symbol, sign, none, value}; return __p;} 2880 virtual pattern do_neg_format() const 2881 {pattern __p = {symbol, sign, none, value}; return __p;} 2882}; 2883 2884template <class _CharT, bool _International> 2885locale::id 2886moneypunct<_CharT, _International>::id; 2887 2888extern template class moneypunct<char, false>; 2889extern template class moneypunct<char, true>; 2890extern template class moneypunct<wchar_t, false>; 2891extern template class moneypunct<wchar_t, true>; 2892 2893// moneypunct_byname 2894 2895template <class _CharT, bool _International = false> 2896class _LIBCPP_VISIBLE moneypunct_byname 2897 : public moneypunct<_CharT, _International> 2898{ 2899public: 2900 typedef money_base::pattern pattern; 2901 typedef _CharT char_type; 2902 typedef basic_string<char_type> string_type; 2903 2904 _LIBCPP_ALWAYS_INLINE 2905 explicit moneypunct_byname(const char* __nm, size_t __refs = 0) 2906 : moneypunct<_CharT, _International>(__refs) {init(__nm);} 2907 2908 _LIBCPP_ALWAYS_INLINE 2909 explicit moneypunct_byname(const string& __nm, size_t __refs = 0) 2910 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} 2911 2912protected: 2913 _LIBCPP_ALWAYS_INLINE 2914 ~moneypunct_byname() {} 2915 2916 virtual char_type do_decimal_point() const {return __decimal_point_;} 2917 virtual char_type do_thousands_sep() const {return __thousands_sep_;} 2918 virtual string do_grouping() const {return __grouping_;} 2919 virtual string_type do_curr_symbol() const {return __curr_symbol_;} 2920 virtual string_type do_positive_sign() const {return __positive_sign_;} 2921 virtual string_type do_negative_sign() const {return __negative_sign_;} 2922 virtual int do_frac_digits() const {return __frac_digits_;} 2923 virtual pattern do_pos_format() const {return __pos_format_;} 2924 virtual pattern do_neg_format() const {return __neg_format_;} 2925 2926private: 2927 char_type __decimal_point_; 2928 char_type __thousands_sep_; 2929 string __grouping_; 2930 string_type __curr_symbol_; 2931 string_type __positive_sign_; 2932 string_type __negative_sign_; 2933 int __frac_digits_; 2934 pattern __pos_format_; 2935 pattern __neg_format_; 2936 2937 void init(const char*); 2938}; 2939 2940template<> void moneypunct_byname<char, false>::init(const char*); 2941template<> void moneypunct_byname<char, true>::init(const char*); 2942template<> void moneypunct_byname<wchar_t, false>::init(const char*); 2943template<> void moneypunct_byname<wchar_t, true>::init(const char*); 2944 2945extern template class moneypunct_byname<char, false>; 2946extern template class moneypunct_byname<char, true>; 2947extern template class moneypunct_byname<wchar_t, false>; 2948extern template class moneypunct_byname<wchar_t, true>; 2949 2950// money_get 2951 2952template <class _CharT> 2953class __money_get 2954{ 2955protected: 2956 typedef _CharT char_type; 2957 typedef basic_string<char_type> string_type; 2958 2959 _LIBCPP_ALWAYS_INLINE __money_get() {} 2960 2961 static void __gather_info(bool __intl, const locale& __loc, 2962 money_base::pattern& __pat, char_type& __dp, 2963 char_type& __ts, string& __grp, 2964 string_type& __sym, string_type& __psn, 2965 string_type& __nsn, int& __fd); 2966}; 2967 2968template <class _CharT> 2969void 2970__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, 2971 money_base::pattern& __pat, char_type& __dp, 2972 char_type& __ts, string& __grp, 2973 string_type& __sym, string_type& __psn, 2974 string_type& __nsn, int& __fd) 2975{ 2976 if (__intl) 2977 { 2978 const moneypunct<char_type, true>& __mp = 2979 use_facet<moneypunct<char_type, true> >(__loc); 2980 __pat = __mp.neg_format(); 2981 __nsn = __mp.negative_sign(); 2982 __psn = __mp.positive_sign(); 2983 __dp = __mp.decimal_point(); 2984 __ts = __mp.thousands_sep(); 2985 __grp = __mp.grouping(); 2986 __sym = __mp.curr_symbol(); 2987 __fd = __mp.frac_digits(); 2988 } 2989 else 2990 { 2991 const moneypunct<char_type, false>& __mp = 2992 use_facet<moneypunct<char_type, false> >(__loc); 2993 __pat = __mp.neg_format(); 2994 __nsn = __mp.negative_sign(); 2995 __psn = __mp.positive_sign(); 2996 __dp = __mp.decimal_point(); 2997 __ts = __mp.thousands_sep(); 2998 __grp = __mp.grouping(); 2999 __sym = __mp.curr_symbol(); 3000 __fd = __mp.frac_digits(); 3001 } 3002} 3003 3004extern template class __money_get<char>; 3005extern template class __money_get<wchar_t>; 3006 3007template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 3008class _LIBCPP_VISIBLE money_get 3009 : public locale::facet, 3010 private __money_get<_CharT> 3011{ 3012public: 3013 typedef _CharT char_type; 3014 typedef _InputIterator iter_type; 3015 typedef basic_string<char_type> string_type; 3016 3017 _LIBCPP_ALWAYS_INLINE 3018 explicit money_get(size_t __refs = 0) 3019 : locale::facet(__refs) {} 3020 3021 _LIBCPP_ALWAYS_INLINE 3022 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 3023 ios_base::iostate& __err, long double& __v) const 3024 { 3025 return do_get(__b, __e, __intl, __iob, __err, __v); 3026 } 3027 3028 _LIBCPP_ALWAYS_INLINE 3029 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 3030 ios_base::iostate& __err, string_type& __v) const 3031 { 3032 return do_get(__b, __e, __intl, __iob, __err, __v); 3033 } 3034 3035 static locale::id id; 3036 3037protected: 3038 3039 _LIBCPP_ALWAYS_INLINE 3040 ~money_get() {} 3041 3042 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 3043 ios_base& __iob, ios_base::iostate& __err, 3044 long double& __v) const; 3045 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 3046 ios_base& __iob, ios_base::iostate& __err, 3047 string_type& __v) const; 3048 3049private: 3050 static bool __do_get(iter_type& __b, iter_type __e, 3051 bool __intl, const locale& __loc, 3052 ios_base::fmtflags __flags, ios_base::iostate& __err, 3053 bool& __neg, const ctype<char_type>& __ct, 3054 unique_ptr<char_type, void(*)(void*)>& __wb, 3055 char_type*& __wn, char_type* __we); 3056}; 3057 3058template <class _CharT, class _InputIterator> 3059locale::id 3060money_get<_CharT, _InputIterator>::id; 3061 3062void __do_nothing(void*); 3063 3064template <class _Tp> 3065_LIBCPP_HIDDEN 3066void 3067__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) 3068{ 3069 bool __owns = __b.get_deleter() != __do_nothing; 3070 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp); 3071 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 3072 2 * __cur_cap : numeric_limits<size_t>::max(); 3073 size_t __n_off = static_cast<size_t>(__n - __b.get()); 3074 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); 3075 if (__t == 0) 3076 __throw_bad_alloc(); 3077 if (__owns) 3078 __b.release(); 3079 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); 3080 __new_cap /= sizeof(_Tp); 3081 __n = __b.get() + __n_off; 3082 __e = __b.get() + __new_cap; 3083} 3084 3085// true == success 3086template <class _CharT, class _InputIterator> 3087bool 3088money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, 3089 bool __intl, const locale& __loc, 3090 ios_base::fmtflags __flags, 3091 ios_base::iostate& __err, 3092 bool& __neg, 3093 const ctype<char_type>& __ct, 3094 unique_ptr<char_type, void(*)(void*)>& __wb, 3095 char_type*& __wn, char_type* __we) 3096{ 3097 const unsigned __bz = 100; 3098 unsigned __gbuf[__bz]; 3099 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing); 3100 unsigned* __gn = __gb.get(); 3101 unsigned* __ge = __gn + __bz; 3102 money_base::pattern __pat; 3103 char_type __dp; 3104 char_type __ts; 3105 string __grp; 3106 string_type __sym; 3107 string_type __psn; 3108 string_type __nsn; 3109 // Capture the spaces read into money_base::{space,none} so they 3110 // can be compared to initial spaces in __sym. 3111 string_type __spaces; 3112 int __fd; 3113 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, 3114 __sym, __psn, __nsn, __fd); 3115 const string_type* __trailing_sign = 0; 3116 __wn = __wb.get(); 3117 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) 3118 { 3119 switch (__pat.field[__p]) 3120 { 3121 case money_base::space: 3122 if (__p != 3) 3123 { 3124 if (__ct.is(ctype_base::space, *__b)) 3125 __spaces.push_back(*__b++); 3126 else 3127 { 3128 __err |= ios_base::failbit; 3129 return false; 3130 } 3131 } 3132 // drop through 3133 case money_base::none: 3134 if (__p != 3) 3135 { 3136 while (__b != __e && __ct.is(ctype_base::space, *__b)) 3137 __spaces.push_back(*__b++); 3138 } 3139 break; 3140 case money_base::sign: 3141 if (__psn.size() + __nsn.size() > 0) 3142 { 3143 if (__psn.size() == 0 || __nsn.size() == 0) 3144 { // sign is optional 3145 if (__psn.size() > 0) 3146 { // __nsn.size() == 0 3147 if (*__b == __psn[0]) 3148 { 3149 ++__b; 3150 if (__psn.size() > 1) 3151 __trailing_sign = &__psn; 3152 } 3153 else 3154 __neg = true; 3155 } 3156 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0 3157 { 3158 ++__b; 3159 __neg = true; 3160 if (__nsn.size() > 1) 3161 __trailing_sign = &__nsn; 3162 } 3163 } 3164 else // sign is required 3165 { 3166 if (*__b == __psn[0]) 3167 { 3168 ++__b; 3169 if (__psn.size() > 1) 3170 __trailing_sign = &__psn; 3171 } 3172 else if (*__b == __nsn[0]) 3173 { 3174 ++__b; 3175 __neg = true; 3176 if (__nsn.size() > 1) 3177 __trailing_sign = &__nsn; 3178 } 3179 else 3180 { 3181 __err |= ios_base::failbit; 3182 return false; 3183 } 3184 } 3185 } 3186 break; 3187 case money_base::symbol: 3188 { 3189 bool __more_needed = __trailing_sign || 3190 (__p < 2) || 3191 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none)); 3192 bool __sb = __flags & ios_base::showbase; 3193 if (__sb || __more_needed) 3194 { 3195 ios_base::iostate __et = ios_base::goodbit; 3196 typename string_type::const_iterator __sym_space_end = __sym.begin(); 3197 if (__p > 0 && (__pat.field[__p - 1] == money_base::none || 3198 __pat.field[__p - 1] == money_base::space)) { 3199 // Match spaces we've already read against spaces at 3200 // the beginning of __sym. 3201 while (__sym_space_end != __sym.end() && 3202 __ct.is(ctype_base::space, *__sym_space_end)) 3203 ++__sym_space_end; 3204 const size_t __num_spaces = __sym_space_end - __sym.begin(); 3205 if (__num_spaces > __spaces.size() || 3206 !equal(__spaces.end() - __num_spaces, __spaces.end(), 3207 __sym.begin())) { 3208 // No match. Put __sym_space_end back at the 3209 // beginning of __sym, which will prevent a 3210 // match in the next loop. 3211 __sym_space_end = __sym.begin(); 3212 } 3213 } 3214 typename string_type::const_iterator __sym_curr_char = __sym_space_end; 3215 while (__sym_curr_char != __sym.end() && __b != __e && 3216 *__b == *__sym_curr_char) { 3217 ++__b; 3218 ++__sym_curr_char; 3219 } 3220 if (__sb && __sym_curr_char != __sym.end()) 3221 { 3222 __err |= ios_base::failbit; 3223 return false; 3224 } 3225 } 3226 } 3227 break; 3228 case money_base::value: 3229 { 3230 unsigned __ng = 0; 3231 for (; __b != __e; ++__b) 3232 { 3233 char_type __c = *__b; 3234 if (__ct.is(ctype_base::digit, __c)) 3235 { 3236 if (__wn == __we) 3237 __double_or_nothing(__wb, __wn, __we); 3238 *__wn++ = __c; 3239 ++__ng; 3240 } 3241 else if (__grp.size() > 0 && __ng > 0 && __c == __ts) 3242 { 3243 if (__gn == __ge) 3244 __double_or_nothing(__gb, __gn, __ge); 3245 *__gn++ = __ng; 3246 __ng = 0; 3247 } 3248 else 3249 break; 3250 } 3251 if (__gb.get() != __gn && __ng > 0) 3252 { 3253 if (__gn == __ge) 3254 __double_or_nothing(__gb, __gn, __ge); 3255 *__gn++ = __ng; 3256 } 3257 if (__fd > 0) 3258 { 3259 if (__b == __e || *__b != __dp) 3260 { 3261 __err |= ios_base::failbit; 3262 return false; 3263 } 3264 for (++__b; __fd > 0; --__fd, ++__b) 3265 { 3266 if (__b == __e || !__ct.is(ctype_base::digit, *__b)) 3267 { 3268 __err |= ios_base::failbit; 3269 return false; 3270 } 3271 if (__wn == __we) 3272 __double_or_nothing(__wb, __wn, __we); 3273 *__wn++ = *__b; 3274 } 3275 } 3276 if (__wn == __wb.get()) 3277 { 3278 __err |= ios_base::failbit; 3279 return false; 3280 } 3281 } 3282 break; 3283 } 3284 } 3285 if (__trailing_sign) 3286 { 3287 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) 3288 { 3289 if (__b == __e || *__b != (*__trailing_sign)[__i]) 3290 { 3291 __err |= ios_base::failbit; 3292 return false; 3293 } 3294 } 3295 } 3296 if (__gb.get() != __gn) 3297 { 3298 ios_base::iostate __et = ios_base::goodbit; 3299 __check_grouping(__grp, __gb.get(), __gn, __et); 3300 if (__et) 3301 { 3302 __err |= ios_base::failbit; 3303 return false; 3304 } 3305 } 3306 return true; 3307} 3308 3309template <class _CharT, class _InputIterator> 3310_InputIterator 3311money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3312 bool __intl, ios_base& __iob, 3313 ios_base::iostate& __err, 3314 long double& __v) const 3315{ 3316 const int __bz = 100; 3317 char_type __wbuf[__bz]; 3318 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3319 char_type* __wn; 3320 char_type* __we = __wbuf + __bz; 3321 locale __loc = __iob.getloc(); 3322 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3323 bool __neg = false; 3324 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3325 __wb, __wn, __we)) 3326 { 3327 const char __src[] = "0123456789"; 3328 char_type __atoms[sizeof(__src)-1]; 3329 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms); 3330 char __nbuf[__bz]; 3331 char* __nc = __nbuf; 3332 unique_ptr<char, void(*)(void*)> __h(0, free); 3333 if (__wn - __wb.get() > __bz-2) 3334 { 3335 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); 3336 if (__h.get() == 0) 3337 __throw_bad_alloc(); 3338 __nc = __h.get(); 3339 } 3340 if (__neg) 3341 *__nc++ = '-'; 3342 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) 3343 *__nc = __src[find(__atoms, __atoms+sizeof(__atoms), *__w) - __atoms]; 3344 *__nc = char(); 3345 if (sscanf(__nbuf, "%Lf", &__v) != 1) 3346 __throw_runtime_error("money_get error"); 3347 } 3348 if (__b == __e) 3349 __err |= ios_base::eofbit; 3350 return __b; 3351} 3352 3353template <class _CharT, class _InputIterator> 3354_InputIterator 3355money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3356 bool __intl, ios_base& __iob, 3357 ios_base::iostate& __err, 3358 string_type& __v) const 3359{ 3360 const int __bz = 100; 3361 char_type __wbuf[__bz]; 3362 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3363 char_type* __wn; 3364 char_type* __we = __wbuf + __bz; 3365 locale __loc = __iob.getloc(); 3366 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3367 bool __neg = false; 3368 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3369 __wb, __wn, __we)) 3370 { 3371 __v.clear(); 3372 if (__neg) 3373 __v.push_back(__ct.widen('-')); 3374 char_type __z = __ct.widen('0'); 3375 char_type* __w; 3376 for (__w = __wb.get(); __w < __wn-1; ++__w) 3377 if (*__w != __z) 3378 break; 3379 __v.append(__w, __wn); 3380 } 3381 if (__b == __e) 3382 __err |= ios_base::eofbit; 3383 return __b; 3384} 3385 3386extern template class money_get<char>; 3387extern template class money_get<wchar_t>; 3388 3389// money_put 3390 3391template <class _CharT> 3392class __money_put 3393{ 3394protected: 3395 typedef _CharT char_type; 3396 typedef basic_string<char_type> string_type; 3397 3398 _LIBCPP_ALWAYS_INLINE __money_put() {} 3399 3400 static void __gather_info(bool __intl, bool __neg, const locale& __loc, 3401 money_base::pattern& __pat, char_type& __dp, 3402 char_type& __ts, string& __grp, 3403 string_type& __sym, string_type& __sn, 3404 int& __fd); 3405 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me, 3406 ios_base::fmtflags __flags, 3407 const char_type* __db, const char_type* __de, 3408 const ctype<char_type>& __ct, bool __neg, 3409 const money_base::pattern& __pat, char_type __dp, 3410 char_type __ts, const string& __grp, 3411 const string_type& __sym, const string_type& __sn, 3412 int __fd); 3413}; 3414 3415template <class _CharT> 3416void 3417__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc, 3418 money_base::pattern& __pat, char_type& __dp, 3419 char_type& __ts, string& __grp, 3420 string_type& __sym, string_type& __sn, 3421 int& __fd) 3422{ 3423 if (__intl) 3424 { 3425 const moneypunct<char_type, true>& __mp = 3426 use_facet<moneypunct<char_type, true> >(__loc); 3427 if (__neg) 3428 { 3429 __pat = __mp.neg_format(); 3430 __sn = __mp.negative_sign(); 3431 } 3432 else 3433 { 3434 __pat = __mp.pos_format(); 3435 __sn = __mp.positive_sign(); 3436 } 3437 __dp = __mp.decimal_point(); 3438 __ts = __mp.thousands_sep(); 3439 __grp = __mp.grouping(); 3440 __sym = __mp.curr_symbol(); 3441 __fd = __mp.frac_digits(); 3442 } 3443 else 3444 { 3445 const moneypunct<char_type, false>& __mp = 3446 use_facet<moneypunct<char_type, false> >(__loc); 3447 if (__neg) 3448 { 3449 __pat = __mp.neg_format(); 3450 __sn = __mp.negative_sign(); 3451 } 3452 else 3453 { 3454 __pat = __mp.pos_format(); 3455 __sn = __mp.positive_sign(); 3456 } 3457 __dp = __mp.decimal_point(); 3458 __ts = __mp.thousands_sep(); 3459 __grp = __mp.grouping(); 3460 __sym = __mp.curr_symbol(); 3461 __fd = __mp.frac_digits(); 3462 } 3463} 3464 3465template <class _CharT> 3466void 3467__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me, 3468 ios_base::fmtflags __flags, 3469 const char_type* __db, const char_type* __de, 3470 const ctype<char_type>& __ct, bool __neg, 3471 const money_base::pattern& __pat, char_type __dp, 3472 char_type __ts, const string& __grp, 3473 const string_type& __sym, const string_type& __sn, 3474 int __fd) 3475{ 3476 __me = __mb; 3477 for (unsigned __p = 0; __p < 4; ++__p) 3478 { 3479 switch (__pat.field[__p]) 3480 { 3481 case money_base::none: 3482 __mi = __me; 3483 break; 3484 case money_base::space: 3485 __mi = __me; 3486 *__me++ = __ct.widen(' '); 3487 break; 3488 case money_base::sign: 3489 if (!__sn.empty()) 3490 *__me++ = __sn[0]; 3491 break; 3492 case money_base::symbol: 3493 if (!__sym.empty() && (__flags & ios_base::showbase)) 3494 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me); 3495 break; 3496 case money_base::value: 3497 { 3498 // remember start of value so we can reverse it 3499 char_type* __t = __me; 3500 // find beginning of digits 3501 if (__neg) 3502 ++__db; 3503 // find end of digits 3504 const char_type* __d; 3505 for (__d = __db; __d < __de; ++__d) 3506 if (!__ct.is(ctype_base::digit, *__d)) 3507 break; 3508 // print fractional part 3509 if (__fd > 0) 3510 { 3511 int __f; 3512 for (__f = __fd; __d > __db && __f > 0; --__f) 3513 *__me++ = *--__d; 3514 char_type __z = __f > 0 ? __ct.widen('0') : char_type(); 3515 for (; __f > 0; --__f) 3516 *__me++ = __z; 3517 *__me++ = __dp; 3518 } 3519 // print units part 3520 if (__d == __db) 3521 { 3522 *__me++ = __ct.widen('0'); 3523 } 3524 else 3525 { 3526 unsigned __ng = 0; 3527 unsigned __ig = 0; 3528 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() 3529 : static_cast<unsigned>(__grp[__ig]); 3530 while (__d != __db) 3531 { 3532 if (__ng == __gl) 3533 { 3534 *__me++ = __ts; 3535 __ng = 0; 3536 if (++__ig < __grp.size()) 3537 __gl = __grp[__ig] == numeric_limits<char>::max() ? 3538 numeric_limits<unsigned>::max() : 3539 static_cast<unsigned>(__grp[__ig]); 3540 } 3541 *__me++ = *--__d; 3542 ++__ng; 3543 } 3544 } 3545 // reverse it 3546 reverse(__t, __me); 3547 } 3548 break; 3549 } 3550 } 3551 // print rest of sign, if any 3552 if (__sn.size() > 1) 3553 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me); 3554 // set alignment 3555 if ((__flags & ios_base::adjustfield) == ios_base::left) 3556 __mi = __me; 3557 else if ((__flags & ios_base::adjustfield) != ios_base::internal) 3558 __mi = __mb; 3559} 3560 3561extern template class __money_put<char>; 3562extern template class __money_put<wchar_t>; 3563 3564template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 3565class _LIBCPP_VISIBLE money_put 3566 : public locale::facet, 3567 private __money_put<_CharT> 3568{ 3569public: 3570 typedef _CharT char_type; 3571 typedef _OutputIterator iter_type; 3572 typedef basic_string<char_type> string_type; 3573 3574 _LIBCPP_ALWAYS_INLINE 3575 explicit money_put(size_t __refs = 0) 3576 : locale::facet(__refs) {} 3577 3578 _LIBCPP_ALWAYS_INLINE 3579 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3580 long double __units) const 3581 { 3582 return do_put(__s, __intl, __iob, __fl, __units); 3583 } 3584 3585 _LIBCPP_ALWAYS_INLINE 3586 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3587 const string_type& __digits) const 3588 { 3589 return do_put(__s, __intl, __iob, __fl, __digits); 3590 } 3591 3592 static locale::id id; 3593 3594protected: 3595 _LIBCPP_ALWAYS_INLINE 3596 ~money_put() {} 3597 3598 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3599 char_type __fl, long double __units) const; 3600 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3601 char_type __fl, const string_type& __digits) const; 3602}; 3603 3604template <class _CharT, class _OutputIterator> 3605locale::id 3606money_put<_CharT, _OutputIterator>::id; 3607 3608template <class _CharT, class _OutputIterator> 3609_OutputIterator 3610money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3611 ios_base& __iob, char_type __fl, 3612 long double __units) const 3613{ 3614 // convert to char 3615 const size_t __bs = 100; 3616 char __buf[__bs]; 3617 char* __bb = __buf; 3618 char_type __digits[__bs]; 3619 char_type* __db = __digits; 3620 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units)); 3621 unique_ptr<char, void(*)(void*)> __hn(0, free); 3622 unique_ptr<char_type, void(*)(void*)> __hd(0, free); 3623 // secure memory for digit storage 3624 if (__n > __bs-1) 3625 { 3626#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 3627 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); 3628#else 3629 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units); 3630#endif 3631 if (__bb == 0) 3632 __throw_bad_alloc(); 3633 __hn.reset(__bb); 3634 __hd.reset((char_type*)malloc(__n * sizeof(char_type))); 3635 if (__hd == nullptr) 3636 __throw_bad_alloc(); 3637 __db = __hd.get(); 3638 } 3639 // gather info 3640 locale __loc = __iob.getloc(); 3641 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3642 __ct.widen(__bb, __bb + __n, __db); 3643 bool __neg = __n > 0 && __bb[0] == '-'; 3644 money_base::pattern __pat; 3645 char_type __dp; 3646 char_type __ts; 3647 string __grp; 3648 string_type __sym; 3649 string_type __sn; 3650 int __fd; 3651 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3652 // secure memory for formatting 3653 char_type __mbuf[__bs]; 3654 char_type* __mb = __mbuf; 3655 unique_ptr<char_type, void(*)(void*)> __hw(0, free); 3656 size_t __exn = static_cast<int>(__n) > __fd ? 3657 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() + 3658 __sym.size() + static_cast<size_t>(__fd) + 1 3659 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3660 if (__exn > __bs) 3661 { 3662 __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); 3663 __mb = __hw.get(); 3664 if (__mb == 0) 3665 __throw_bad_alloc(); 3666 } 3667 // format 3668 char_type* __mi; 3669 char_type* __me; 3670 this->__format(__mb, __mi, __me, __iob.flags(), 3671 __db, __db + __n, __ct, 3672 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3673 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3674} 3675 3676template <class _CharT, class _OutputIterator> 3677_OutputIterator 3678money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3679 ios_base& __iob, char_type __fl, 3680 const string_type& __digits) const 3681{ 3682 // gather info 3683 locale __loc = __iob.getloc(); 3684 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3685 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); 3686 money_base::pattern __pat; 3687 char_type __dp; 3688 char_type __ts; 3689 string __grp; 3690 string_type __sym; 3691 string_type __sn; 3692 int __fd; 3693 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3694 // secure memory for formatting 3695 char_type __mbuf[100]; 3696 char_type* __mb = __mbuf; 3697 unique_ptr<char_type, void(*)(void*)> __h(0, free); 3698 size_t __exn = static_cast<int>(__digits.size()) > __fd ? 3699 (__digits.size() - static_cast<size_t>(__fd)) * 2 + 3700 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 3701 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3702 if (__exn > 100) 3703 { 3704 __h.reset((char_type*)malloc(__exn * sizeof(char_type))); 3705 __mb = __h.get(); 3706 if (__mb == 0) 3707 __throw_bad_alloc(); 3708 } 3709 // format 3710 char_type* __mi; 3711 char_type* __me; 3712 this->__format(__mb, __mi, __me, __iob.flags(), 3713 __digits.data(), __digits.data() + __digits.size(), __ct, 3714 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3715 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3716} 3717 3718extern template class money_put<char>; 3719extern template class money_put<wchar_t>; 3720 3721// messages 3722 3723class _LIBCPP_VISIBLE messages_base 3724{ 3725public: 3726 typedef ptrdiff_t catalog; 3727 3728 _LIBCPP_ALWAYS_INLINE messages_base() {} 3729}; 3730 3731template <class _CharT> 3732class _LIBCPP_VISIBLE messages 3733 : public locale::facet, 3734 public messages_base 3735{ 3736public: 3737 typedef _CharT char_type; 3738 typedef basic_string<_CharT> string_type; 3739 3740 _LIBCPP_ALWAYS_INLINE 3741 explicit messages(size_t __refs = 0) 3742 : locale::facet(__refs) {} 3743 3744 _LIBCPP_ALWAYS_INLINE 3745 catalog open(const basic_string<char>& __nm, const locale& __loc) const 3746 { 3747 return do_open(__nm, __loc); 3748 } 3749 3750 _LIBCPP_ALWAYS_INLINE 3751 string_type get(catalog __c, int __set, int __msgid, 3752 const string_type& __dflt) const 3753 { 3754 return do_get(__c, __set, __msgid, __dflt); 3755 } 3756 3757 _LIBCPP_ALWAYS_INLINE 3758 void close(catalog __c) const 3759 { 3760 do_close(__c); 3761 } 3762 3763 static locale::id id; 3764 3765protected: 3766 _LIBCPP_ALWAYS_INLINE 3767 ~messages() {} 3768 3769 virtual catalog do_open(const basic_string<char>&, const locale&) const; 3770 virtual string_type do_get(catalog, int __set, int __msgid, 3771 const string_type& __dflt) const; 3772 virtual void do_close(catalog) const; 3773}; 3774 3775template <class _CharT> 3776locale::id 3777messages<_CharT>::id; 3778 3779template <class _CharT> 3780typename messages<_CharT>::catalog 3781messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const 3782{ 3783#if _WIN32 3784 return -1; 3785#else // _WIN32 3786 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); 3787 if (__cat != -1) 3788 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); 3789 return __cat; 3790#endif // _WIN32 3791} 3792 3793template <class _CharT> 3794typename messages<_CharT>::string_type 3795messages<_CharT>::do_get(catalog __c, int __set, int __msgid, 3796 const string_type& __dflt) const 3797{ 3798#if _WIN32 3799 return __dflt; 3800#else // _WIN32 3801 string __ndflt; 3802 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt), 3803 __dflt.c_str(), 3804 __dflt.c_str() + __dflt.size()); 3805 if (__c != -1) 3806 __c <<= 1; 3807 nl_catd __cat = (nl_catd)__c; 3808 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); 3809 string_type __w; 3810 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w), 3811 __n, __n + strlen(__n)); 3812 return __w; 3813#endif // _WIN32 3814} 3815 3816template <class _CharT> 3817void 3818messages<_CharT>::do_close(catalog __c) const 3819{ 3820#if !_WIN32 3821 if (__c != -1) 3822 __c <<= 1; 3823 nl_catd __cat = (nl_catd)__c; 3824 catclose(__cat); 3825#endif // !_WIN32 3826} 3827 3828extern template class messages<char>; 3829extern template class messages<wchar_t>; 3830 3831template <class _CharT> 3832class _LIBCPP_VISIBLE messages_byname 3833 : public messages<_CharT> 3834{ 3835public: 3836 typedef messages_base::catalog catalog; 3837 typedef basic_string<_CharT> string_type; 3838 3839 _LIBCPP_ALWAYS_INLINE 3840 explicit messages_byname(const char*, size_t __refs = 0) 3841 : messages<_CharT>(__refs) {} 3842 3843 _LIBCPP_ALWAYS_INLINE 3844 explicit messages_byname(const string&, size_t __refs = 0) 3845 : messages<_CharT>(__refs) {} 3846 3847protected: 3848 _LIBCPP_ALWAYS_INLINE 3849 ~messages_byname() {} 3850}; 3851 3852extern template class messages_byname<char>; 3853extern template class messages_byname<wchar_t>; 3854 3855template<class _Codecvt, class _Elem = wchar_t, 3856 class _Wide_alloc = allocator<_Elem>, 3857 class _Byte_alloc = allocator<char> > 3858class _LIBCPP_VISIBLE wstring_convert 3859{ 3860public: 3861 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; 3862 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; 3863 typedef typename _Codecvt::state_type state_type; 3864 typedef typename wide_string::traits_type::int_type int_type; 3865 3866private: 3867 byte_string __byte_err_string_; 3868 wide_string __wide_err_string_; 3869 _Codecvt* __cvtptr_; 3870 state_type __cvtstate_; 3871 size_t __cvtcount_; 3872 3873 wstring_convert(const wstring_convert& __wc); 3874 wstring_convert& operator=(const wstring_convert& __wc); 3875public: 3876 wstring_convert(_Codecvt* __pcvt = new _Codecvt); 3877 wstring_convert(_Codecvt* __pcvt, state_type __state); 3878 wstring_convert(const byte_string& __byte_err, 3879 const wide_string& __wide_err = wide_string()); 3880#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 3881 wstring_convert(wstring_convert&& __wc); 3882#endif 3883 ~wstring_convert(); 3884 3885 _LIBCPP_ALWAYS_INLINE 3886 wide_string from_bytes(char __byte) 3887 {return from_bytes(&__byte, &__byte+1);} 3888 _LIBCPP_ALWAYS_INLINE 3889 wide_string from_bytes(const char* __ptr) 3890 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));} 3891 _LIBCPP_ALWAYS_INLINE 3892 wide_string from_bytes(const byte_string& __str) 3893 {return from_bytes(__str.data(), __str.data() + __str.size());} 3894 wide_string from_bytes(const char* __first, const char* __last); 3895 3896 _LIBCPP_ALWAYS_INLINE 3897 byte_string to_bytes(_Elem __wchar) 3898 {return to_bytes(&__wchar, &__wchar+1);} 3899 _LIBCPP_ALWAYS_INLINE 3900 byte_string to_bytes(const _Elem* __wptr) 3901 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} 3902 _LIBCPP_ALWAYS_INLINE 3903 byte_string to_bytes(const wide_string& __wstr) 3904 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} 3905 byte_string to_bytes(const _Elem* __first, const _Elem* __last); 3906 3907 _LIBCPP_ALWAYS_INLINE 3908 size_t converted() const {return __cvtcount_;} 3909 _LIBCPP_ALWAYS_INLINE 3910 state_type state() const {return __cvtstate_;} 3911}; 3912 3913template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3914inline _LIBCPP_ALWAYS_INLINE 3915wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3916 wstring_convert(_Codecvt* __pcvt) 3917 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) 3918{ 3919} 3920 3921template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3922inline _LIBCPP_ALWAYS_INLINE 3923wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3924 wstring_convert(_Codecvt* __pcvt, state_type __state) 3925 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) 3926{ 3927} 3928 3929template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3930wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3931 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) 3932 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), 3933 __cvtstate_(), __cvtcount_(0) 3934{ 3935 __cvtptr_ = new _Codecvt; 3936} 3937 3938#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 3939 3940template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3941inline _LIBCPP_ALWAYS_INLINE 3942wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3943 wstring_convert(wstring_convert&& __wc) 3944 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), 3945 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), 3946 __cvtptr_(__wc.__cvtptr_), 3947 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_) 3948{ 3949 __wc.__cvtptr_ = nullptr; 3950} 3951 3952#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 3953 3954template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3955wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() 3956{ 3957 delete __cvtptr_; 3958} 3959 3960template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3961typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string 3962wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3963 from_bytes(const char* __frm, const char* __frm_end) 3964{ 3965 __cvtcount_ = 0; 3966 if (__cvtptr_ != nullptr) 3967 { 3968 wide_string __ws(2*(__frm_end - __frm), _Elem()); 3969 if (__frm != __frm_end) 3970 __ws.resize(__ws.capacity()); 3971 codecvt_base::result __r = codecvt_base::ok; 3972 state_type __st = __cvtstate_; 3973 if (__frm != __frm_end) 3974 { 3975 _Elem* __to = &__ws[0]; 3976 _Elem* __to_end = __to + __ws.size(); 3977 const char* __frm_nxt; 3978 do 3979 { 3980 _Elem* __to_nxt; 3981 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, 3982 __to, __to_end, __to_nxt); 3983 __cvtcount_ += __frm_nxt - __frm; 3984 if (__frm_nxt == __frm) 3985 { 3986 __r = codecvt_base::error; 3987 } 3988 else if (__r == codecvt_base::noconv) 3989 { 3990 __ws.resize(__to - &__ws[0]); 3991 // This only gets executed if _Elem is char 3992 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); 3993 __frm = __frm_nxt; 3994 __r = codecvt_base::ok; 3995 } 3996 else if (__r == codecvt_base::ok) 3997 { 3998 __ws.resize(__to_nxt - &__ws[0]); 3999 __frm = __frm_nxt; 4000 } 4001 else if (__r == codecvt_base::partial) 4002 { 4003 ptrdiff_t __s = __to_nxt - &__ws[0]; 4004 __ws.resize(2 * __s); 4005 __to = &__ws[0] + __s; 4006 __to_end = &__ws[0] + __ws.size(); 4007 __frm = __frm_nxt; 4008 } 4009 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 4010 } 4011 if (__r == codecvt_base::ok) 4012 return __ws; 4013 } 4014#ifndef _LIBCPP_NO_EXCEPTIONS 4015 if (__wide_err_string_.empty()) 4016 throw range_error("wstring_convert: from_bytes error"); 4017#endif // _LIBCPP_NO_EXCEPTIONS 4018 return __wide_err_string_; 4019} 4020 4021template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 4022typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string 4023wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 4024 to_bytes(const _Elem* __frm, const _Elem* __frm_end) 4025{ 4026 __cvtcount_ = 0; 4027 if (__cvtptr_ != nullptr) 4028 { 4029 byte_string __bs(2*(__frm_end - __frm), char()); 4030 if (__frm != __frm_end) 4031 __bs.resize(__bs.capacity()); 4032 codecvt_base::result __r = codecvt_base::ok; 4033 state_type __st = __cvtstate_; 4034 if (__frm != __frm_end) 4035 { 4036 char* __to = &__bs[0]; 4037 char* __to_end = __to + __bs.size(); 4038 const _Elem* __frm_nxt; 4039 do 4040 { 4041 char* __to_nxt; 4042 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, 4043 __to, __to_end, __to_nxt); 4044 __cvtcount_ += __frm_nxt - __frm; 4045 if (__frm_nxt == __frm) 4046 { 4047 __r = codecvt_base::error; 4048 } 4049 else if (__r == codecvt_base::noconv) 4050 { 4051 __bs.resize(__to - &__bs[0]); 4052 // This only gets executed if _Elem is char 4053 __bs.append((const char*)__frm, (const char*)__frm_end); 4054 __frm = __frm_nxt; 4055 __r = codecvt_base::ok; 4056 } 4057 else if (__r == codecvt_base::ok) 4058 { 4059 __bs.resize(__to_nxt - &__bs[0]); 4060 __frm = __frm_nxt; 4061 } 4062 else if (__r == codecvt_base::partial) 4063 { 4064 ptrdiff_t __s = __to_nxt - &__bs[0]; 4065 __bs.resize(2 * __s); 4066 __to = &__bs[0] + __s; 4067 __to_end = &__bs[0] + __bs.size(); 4068 __frm = __frm_nxt; 4069 } 4070 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 4071 } 4072 if (__r == codecvt_base::ok) 4073 { 4074 size_t __s = __bs.size(); 4075 __bs.resize(__bs.capacity()); 4076 char* __to = &__bs[0] + __s; 4077 char* __to_end = __to + __bs.size(); 4078 do 4079 { 4080 char* __to_nxt; 4081 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); 4082 if (__r == codecvt_base::noconv) 4083 { 4084 __bs.resize(__to - &__bs[0]); 4085 __r = codecvt_base::ok; 4086 } 4087 else if (__r == codecvt_base::ok) 4088 { 4089 __bs.resize(__to_nxt - &__bs[0]); 4090 } 4091 else if (__r == codecvt_base::partial) 4092 { 4093 ptrdiff_t __sp = __to_nxt - &__bs[0]; 4094 __bs.resize(2 * __sp); 4095 __to = &__bs[0] + __sp; 4096 __to_end = &__bs[0] + __bs.size(); 4097 } 4098 } while (__r == codecvt_base::partial); 4099 if (__r == codecvt_base::ok) 4100 return __bs; 4101 } 4102 } 4103#ifndef _LIBCPP_NO_EXCEPTIONS 4104 if (__byte_err_string_.empty()) 4105 throw range_error("wstring_convert: to_bytes error"); 4106#endif // _LIBCPP_NO_EXCEPTIONS 4107 return __byte_err_string_; 4108} 4109 4110template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> > 4111class _LIBCPP_VISIBLE wbuffer_convert 4112 : public basic_streambuf<_Elem, _Tr> 4113{ 4114public: 4115 // types: 4116 typedef _Elem char_type; 4117 typedef _Tr traits_type; 4118 typedef typename traits_type::int_type int_type; 4119 typedef typename traits_type::pos_type pos_type; 4120 typedef typename traits_type::off_type off_type; 4121 typedef typename _Codecvt::state_type state_type; 4122 4123private: 4124 char* __extbuf_; 4125 const char* __extbufnext_; 4126 const char* __extbufend_; 4127 char __extbuf_min_[8]; 4128 size_t __ebs_; 4129 char_type* __intbuf_; 4130 size_t __ibs_; 4131 streambuf* __bufptr_; 4132 _Codecvt* __cv_; 4133 state_type __st_; 4134 ios_base::openmode __cm_; 4135 bool __owns_eb_; 4136 bool __owns_ib_; 4137 bool __always_noconv_; 4138 4139 wbuffer_convert(const wbuffer_convert&); 4140 wbuffer_convert& operator=(const wbuffer_convert&); 4141public: 4142 wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt, 4143 state_type __state = state_type()); 4144 ~wbuffer_convert(); 4145 4146 _LIBCPP_INLINE_VISIBILITY 4147 streambuf* rdbuf() const {return __bufptr_;} 4148 _LIBCPP_INLINE_VISIBILITY 4149 streambuf* rdbuf(streambuf* __bytebuf) 4150 { 4151 streambuf* __r = __bufptr_; 4152 __bufptr_ = __bytebuf; 4153 return __r; 4154 } 4155 4156 _LIBCPP_INLINE_VISIBILITY 4157 state_type state() const {return __st_;} 4158 4159protected: 4160 virtual int_type underflow(); 4161 virtual int_type pbackfail(int_type __c = traits_type::eof()); 4162 virtual int_type overflow (int_type __c = traits_type::eof()); 4163 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, 4164 streamsize __n); 4165 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 4166 ios_base::openmode __wch = ios_base::in | ios_base::out); 4167 virtual pos_type seekpos(pos_type __sp, 4168 ios_base::openmode __wch = ios_base::in | ios_base::out); 4169 virtual int sync(); 4170 4171private: 4172 bool __read_mode(); 4173 void __write_mode(); 4174 wbuffer_convert* __close(); 4175}; 4176 4177template <class _Codecvt, class _Elem, class _Tr> 4178wbuffer_convert<_Codecvt, _Elem, _Tr>:: 4179 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) 4180 : __extbuf_(0), 4181 __extbufnext_(0), 4182 __extbufend_(0), 4183 __ebs_(0), 4184 __intbuf_(0), 4185 __ibs_(0), 4186 __bufptr_(__bytebuf), 4187 __cv_(__pcvt), 4188 __st_(__state), 4189 __cm_(0), 4190 __owns_eb_(false), 4191 __owns_ib_(false), 4192 __always_noconv_(__cv_ ? __cv_->always_noconv() : false) 4193{ 4194 setbuf(0, 4096); 4195} 4196 4197template <class _Codecvt, class _Elem, class _Tr> 4198wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() 4199{ 4200 __close(); 4201 delete __cv_; 4202 if (__owns_eb_) 4203 delete [] __extbuf_; 4204 if (__owns_ib_) 4205 delete [] __intbuf_; 4206} 4207 4208template <class _Codecvt, class _Elem, class _Tr> 4209typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4210wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() 4211{ 4212 if (__cv_ == 0 || __bufptr_ == 0) 4213 return traits_type::eof(); 4214 bool __initial = __read_mode(); 4215 char_type __1buf; 4216 if (this->gptr() == 0) 4217 this->setg(&__1buf, &__1buf+1, &__1buf+1); 4218 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4); 4219 int_type __c = traits_type::eof(); 4220 if (this->gptr() == this->egptr()) 4221 { 4222 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 4223 if (__always_noconv_) 4224 { 4225 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz); 4226 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); 4227 if (__nmemb != 0) 4228 { 4229 this->setg(this->eback(), 4230 this->eback() + __unget_sz, 4231 this->eback() + __unget_sz + __nmemb); 4232 __c = *this->gptr(); 4233 } 4234 } 4235 else 4236 { 4237 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 4238 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 4239 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 4240 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), 4241 static_cast<streamsize>(__extbufend_ - __extbufnext_)); 4242 codecvt_base::result __r; 4243 state_type __svs = __st_; 4244 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); 4245 if (__nr != 0) 4246 { 4247 __extbufend_ = __extbufnext_ + __nr; 4248 char_type* __inext; 4249 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, 4250 this->eback() + __unget_sz, 4251 this->egptr(), __inext); 4252 if (__r == codecvt_base::noconv) 4253 { 4254 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_); 4255 __c = *this->gptr(); 4256 } 4257 else if (__inext != this->eback() + __unget_sz) 4258 { 4259 this->setg(this->eback(), this->eback() + __unget_sz, __inext); 4260 __c = *this->gptr(); 4261 } 4262 } 4263 } 4264 } 4265 else 4266 __c = *this->gptr(); 4267 if (this->eback() == &__1buf) 4268 this->setg(0, 0, 0); 4269 return __c; 4270} 4271 4272template <class _Codecvt, class _Elem, class _Tr> 4273typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4274wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) 4275{ 4276 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr()) 4277 { 4278 if (traits_type::eq_int_type(__c, traits_type::eof())) 4279 { 4280 this->gbump(-1); 4281 return traits_type::not_eof(__c); 4282 } 4283 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) 4284 { 4285 this->gbump(-1); 4286 *this->gptr() = traits_type::to_char_type(__c); 4287 return __c; 4288 } 4289 } 4290 return traits_type::eof(); 4291} 4292 4293template <class _Codecvt, class _Elem, class _Tr> 4294typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4295wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) 4296{ 4297 if (__cv_ == 0 || __bufptr_ == 0) 4298 return traits_type::eof(); 4299 __write_mode(); 4300 char_type __1buf; 4301 char_type* __pb_save = this->pbase(); 4302 char_type* __epb_save = this->epptr(); 4303 if (!traits_type::eq_int_type(__c, traits_type::eof())) 4304 { 4305 if (this->pptr() == 0) 4306 this->setp(&__1buf, &__1buf+1); 4307 *this->pptr() = traits_type::to_char_type(__c); 4308 this->pbump(1); 4309 } 4310 if (this->pptr() != this->pbase()) 4311 { 4312 if (__always_noconv_) 4313 { 4314 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase()); 4315 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4316 return traits_type::eof(); 4317 } 4318 else 4319 { 4320 char* __extbe = __extbuf_; 4321 codecvt_base::result __r; 4322 do 4323 { 4324 const char_type* __e; 4325 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, 4326 __extbuf_, __extbuf_ + __ebs_, __extbe); 4327 if (__e == this->pbase()) 4328 return traits_type::eof(); 4329 if (__r == codecvt_base::noconv) 4330 { 4331 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 4332 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4333 return traits_type::eof(); 4334 } 4335 else if (__r == codecvt_base::ok || __r == codecvt_base::partial) 4336 { 4337 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_); 4338 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4339 return traits_type::eof(); 4340 if (__r == codecvt_base::partial) 4341 { 4342 this->setp((char_type*)__e, this->pptr()); 4343 this->pbump(this->epptr() - this->pbase()); 4344 } 4345 } 4346 else 4347 return traits_type::eof(); 4348 } while (__r == codecvt_base::partial); 4349 } 4350 this->setp(__pb_save, __epb_save); 4351 } 4352 return traits_type::not_eof(__c); 4353} 4354 4355template <class _Codecvt, class _Elem, class _Tr> 4356basic_streambuf<_Elem, _Tr>* 4357wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) 4358{ 4359 this->setg(0, 0, 0); 4360 this->setp(0, 0); 4361 if (__owns_eb_) 4362 delete [] __extbuf_; 4363 if (__owns_ib_) 4364 delete [] __intbuf_; 4365 __ebs_ = __n; 4366 if (__ebs_ > sizeof(__extbuf_min_)) 4367 { 4368 if (__always_noconv_ && __s) 4369 { 4370 __extbuf_ = (char*)__s; 4371 __owns_eb_ = false; 4372 } 4373 else 4374 { 4375 __extbuf_ = new char[__ebs_]; 4376 __owns_eb_ = true; 4377 } 4378 } 4379 else 4380 { 4381 __extbuf_ = __extbuf_min_; 4382 __ebs_ = sizeof(__extbuf_min_); 4383 __owns_eb_ = false; 4384 } 4385 if (!__always_noconv_) 4386 { 4387 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 4388 if (__s && __ibs_ >= sizeof(__extbuf_min_)) 4389 { 4390 __intbuf_ = __s; 4391 __owns_ib_ = false; 4392 } 4393 else 4394 { 4395 __intbuf_ = new char_type[__ibs_]; 4396 __owns_ib_ = true; 4397 } 4398 } 4399 else 4400 { 4401 __ibs_ = 0; 4402 __intbuf_ = 0; 4403 __owns_ib_ = false; 4404 } 4405 return this; 4406} 4407 4408template <class _Codecvt, class _Elem, class _Tr> 4409typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4410wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, 4411 ios_base::openmode __om) 4412{ 4413 int __width = __cv_->encoding(); 4414 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync()) 4415 return pos_type(off_type(-1)); 4416 // __width > 0 || __off == 0 4417 switch (__way) 4418 { 4419 case ios_base::beg: 4420 break; 4421 case ios_base::cur: 4422 break; 4423 case ios_base::end: 4424 break; 4425 default: 4426 return pos_type(off_type(-1)); 4427 } 4428 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); 4429 __r.state(__st_); 4430 return __r; 4431} 4432 4433template <class _Codecvt, class _Elem, class _Tr> 4434typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4435wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) 4436{ 4437 if (__cv_ == 0 || __bufptr_ == 0 || sync()) 4438 return pos_type(off_type(-1)); 4439 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) 4440 return pos_type(off_type(-1)); 4441 return __sp; 4442} 4443 4444template <class _Codecvt, class _Elem, class _Tr> 4445int 4446wbuffer_convert<_Codecvt, _Elem, _Tr>::sync() 4447{ 4448 if (__cv_ == 0 || __bufptr_ == 0) 4449 return 0; 4450 if (__cm_ & ios_base::out) 4451 { 4452 if (this->pptr() != this->pbase()) 4453 if (overflow() == traits_type::eof()) 4454 return -1; 4455 codecvt_base::result __r; 4456 do 4457 { 4458 char* __extbe; 4459 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 4460 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_); 4461 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4462 return -1; 4463 } while (__r == codecvt_base::partial); 4464 if (__r == codecvt_base::error) 4465 return -1; 4466 if (__bufptr_->pubsync()) 4467 return -1; 4468 } 4469 else if (__cm_ & ios_base::in) 4470 { 4471 off_type __c; 4472 if (__always_noconv_) 4473 __c = this->egptr() - this->gptr(); 4474 else 4475 { 4476 int __width = __cv_->encoding(); 4477 __c = __extbufend_ - __extbufnext_; 4478 if (__width > 0) 4479 __c += __width * (this->egptr() - this->gptr()); 4480 else 4481 { 4482 if (this->gptr() != this->egptr()) 4483 { 4484 reverse(this->gptr(), this->egptr()); 4485 codecvt_base::result __r; 4486 const char_type* __e = this->gptr(); 4487 char* __extbe; 4488 do 4489 { 4490 __r = __cv_->out(__st_, __e, this->egptr(), __e, 4491 __extbuf_, __extbuf_ + __ebs_, __extbe); 4492 switch (__r) 4493 { 4494 case codecvt_base::noconv: 4495 __c += this->egptr() - this->gptr(); 4496 break; 4497 case codecvt_base::ok: 4498 case codecvt_base::partial: 4499 __c += __extbe - __extbuf_; 4500 break; 4501 default: 4502 return -1; 4503 } 4504 } while (__r == codecvt_base::partial); 4505 } 4506 } 4507 } 4508 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) 4509 return -1; 4510 this->setg(0, 0, 0); 4511 __cm_ = 0; 4512 } 4513 return 0; 4514} 4515 4516template <class _Codecvt, class _Elem, class _Tr> 4517bool 4518wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() 4519{ 4520 if (!(__cm_ & ios_base::in)) 4521 { 4522 this->setp(0, 0); 4523 if (__always_noconv_) 4524 this->setg((char_type*)__extbuf_, 4525 (char_type*)__extbuf_ + __ebs_, 4526 (char_type*)__extbuf_ + __ebs_); 4527 else 4528 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 4529 __cm_ = ios_base::in; 4530 return true; 4531 } 4532 return false; 4533} 4534 4535template <class _Codecvt, class _Elem, class _Tr> 4536void 4537wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() 4538{ 4539 if (!(__cm_ & ios_base::out)) 4540 { 4541 this->setg(0, 0, 0); 4542 if (__ebs_ > sizeof(__extbuf_min_)) 4543 { 4544 if (__always_noconv_) 4545 this->setp((char_type*)__extbuf_, 4546 (char_type*)__extbuf_ + (__ebs_ - 1)); 4547 else 4548 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 4549 } 4550 else 4551 this->setp(0, 0); 4552 __cm_ = ios_base::out; 4553 } 4554} 4555 4556template <class _Codecvt, class _Elem, class _Tr> 4557wbuffer_convert<_Codecvt, _Elem, _Tr>* 4558wbuffer_convert<_Codecvt, _Elem, _Tr>::__close() 4559{ 4560 wbuffer_convert* __rt = 0; 4561 if (__cv_ != 0 && __bufptr_ != 0) 4562 { 4563 __rt = this; 4564 if ((__cm_ & ios_base::out) && sync()) 4565 __rt = 0; 4566 } 4567 return __rt; 4568} 4569 4570_LIBCPP_END_NAMESPACE_STD 4571 4572#endif // _LIBCPP_LOCALE 4573