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