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