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