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