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