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