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 <__locale> 192#include <__debug> 193#include <algorithm> 194#include <memory> 195#include <ios> 196#include <streambuf> 197#include <iterator> 198#include <limits> 199#include <version> 200#ifndef __APPLE__ 201#include <cstdarg> 202#endif 203#include <cstdlib> 204#include <ctime> 205#include <cstdio> 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 const unsigned __nbuf = (numeric_limits<long>::digits / 3) 1462 + ((numeric_limits<long>::digits % 3) != 0) 1463 + ((__iob.flags() & ios_base::showbase) != 0) 1464 + 2; 1465 char __nar[__nbuf]; 1466 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1467 char* __ne = __nar + __nc; 1468 char* __np = this->__identify_padding(__nar, __ne, __iob); 1469 // Stage 2 - Widen __nar while adding thousands separators 1470 char_type __o[2*(__nbuf-1) - 1]; 1471 char_type* __op; // pad here 1472 char_type* __oe; // end of output 1473 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1474 // [__o, __oe) contains thousands_sep'd wide number 1475 // Stage 3 & 4 1476 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1477} 1478 1479template <class _CharT, class _OutputIterator> 1480_OutputIterator 1481num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1482 char_type __fl, long long __v) const 1483{ 1484 // Stage 1 - Get number in narrow char 1485 char __fmt[8] = {'%', 0}; 1486 const char* __len = "ll"; 1487 this->__format_int(__fmt+1, __len, true, __iob.flags()); 1488 const unsigned __nbuf = (numeric_limits<long long>::digits / 3) 1489 + ((numeric_limits<long long>::digits % 3) != 0) 1490 + ((__iob.flags() & ios_base::showbase) != 0) 1491 + 2; 1492 char __nar[__nbuf]; 1493 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1494 char* __ne = __nar + __nc; 1495 char* __np = this->__identify_padding(__nar, __ne, __iob); 1496 // Stage 2 - Widen __nar while adding thousands separators 1497 char_type __o[2*(__nbuf-1) - 1]; 1498 char_type* __op; // pad here 1499 char_type* __oe; // end of output 1500 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1501 // [__o, __oe) contains thousands_sep'd wide number 1502 // Stage 3 & 4 1503 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1504} 1505 1506template <class _CharT, class _OutputIterator> 1507_OutputIterator 1508num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1509 char_type __fl, unsigned long __v) const 1510{ 1511 // Stage 1 - Get number in narrow char 1512 char __fmt[6] = {'%', 0}; 1513 const char* __len = "l"; 1514 this->__format_int(__fmt+1, __len, false, __iob.flags()); 1515 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3) 1516 + ((numeric_limits<unsigned long>::digits % 3) != 0) 1517 + ((__iob.flags() & ios_base::showbase) != 0) 1518 + 1; 1519 char __nar[__nbuf]; 1520 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1521 char* __ne = __nar + __nc; 1522 char* __np = this->__identify_padding(__nar, __ne, __iob); 1523 // Stage 2 - Widen __nar while adding thousands separators 1524 char_type __o[2*(__nbuf-1) - 1]; 1525 char_type* __op; // pad here 1526 char_type* __oe; // end of output 1527 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1528 // [__o, __oe) contains thousands_sep'd wide number 1529 // Stage 3 & 4 1530 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1531} 1532 1533template <class _CharT, class _OutputIterator> 1534_OutputIterator 1535num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1536 char_type __fl, unsigned long long __v) const 1537{ 1538 // Stage 1 - Get number in narrow char 1539 char __fmt[8] = {'%', 0}; 1540 const char* __len = "ll"; 1541 this->__format_int(__fmt+1, __len, false, __iob.flags()); 1542 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3) 1543 + ((numeric_limits<unsigned long long>::digits % 3) != 0) 1544 + ((__iob.flags() & ios_base::showbase) != 0) 1545 + 1; 1546 char __nar[__nbuf]; 1547 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1548 char* __ne = __nar + __nc; 1549 char* __np = this->__identify_padding(__nar, __ne, __iob); 1550 // Stage 2 - Widen __nar while adding thousands separators 1551 char_type __o[2*(__nbuf-1) - 1]; 1552 char_type* __op; // pad here 1553 char_type* __oe; // end of output 1554 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1555 // [__o, __oe) contains thousands_sep'd wide number 1556 // Stage 3 & 4 1557 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1558} 1559 1560template <class _CharT, class _OutputIterator> 1561_OutputIterator 1562num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1563 char_type __fl, double __v) const 1564{ 1565 // Stage 1 - Get number in narrow char 1566 char __fmt[8] = {'%', 0}; 1567 const char* __len = ""; 1568 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1569 const unsigned __nbuf = 30; 1570 char __nar[__nbuf]; 1571 char* __nb = __nar; 1572 int __nc; 1573 if (__specify_precision) 1574 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1575 (int)__iob.precision(), __v); 1576 else 1577 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1578 unique_ptr<char, void(*)(void*)> __nbh(nullptr, free); 1579 if (__nc > static_cast<int>(__nbuf-1)) 1580 { 1581 if (__specify_precision) 1582 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1583 else 1584 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1585 if (__nc == -1) 1586 __throw_bad_alloc(); 1587 __nbh.reset(__nb); 1588 } 1589 char* __ne = __nb + __nc; 1590 char* __np = this->__identify_padding(__nb, __ne, __iob); 1591 // Stage 2 - Widen __nar while adding thousands separators 1592 char_type __o[2*(__nbuf-1) - 1]; 1593 char_type* __ob = __o; 1594 unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1595 if (__nb != __nar) 1596 { 1597 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1598 if (__ob == 0) 1599 __throw_bad_alloc(); 1600 __obh.reset(__ob); 1601 } 1602 char_type* __op; // pad here 1603 char_type* __oe; // end of output 1604 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1605 // [__o, __oe) contains thousands_sep'd wide number 1606 // Stage 3 & 4 1607 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1608 return __s; 1609} 1610 1611template <class _CharT, class _OutputIterator> 1612_OutputIterator 1613num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1614 char_type __fl, long double __v) const 1615{ 1616 // Stage 1 - Get number in narrow char 1617 char __fmt[8] = {'%', 0}; 1618 const char* __len = "L"; 1619 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1620 const unsigned __nbuf = 30; 1621 char __nar[__nbuf]; 1622 char* __nb = __nar; 1623 int __nc; 1624 if (__specify_precision) 1625 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1626 (int)__iob.precision(), __v); 1627 else 1628 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1629 unique_ptr<char, void(*)(void*)> __nbh(nullptr, free); 1630 if (__nc > static_cast<int>(__nbuf-1)) 1631 { 1632 if (__specify_precision) 1633 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1634 else 1635 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1636 if (__nc == -1) 1637 __throw_bad_alloc(); 1638 __nbh.reset(__nb); 1639 } 1640 char* __ne = __nb + __nc; 1641 char* __np = this->__identify_padding(__nb, __ne, __iob); 1642 // Stage 2 - Widen __nar while adding thousands separators 1643 char_type __o[2*(__nbuf-1) - 1]; 1644 char_type* __ob = __o; 1645 unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1646 if (__nb != __nar) 1647 { 1648 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1649 if (__ob == 0) 1650 __throw_bad_alloc(); 1651 __obh.reset(__ob); 1652 } 1653 char_type* __op; // pad here 1654 char_type* __oe; // end of output 1655 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1656 // [__o, __oe) contains thousands_sep'd wide number 1657 // Stage 3 & 4 1658 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1659 return __s; 1660} 1661 1662template <class _CharT, class _OutputIterator> 1663_OutputIterator 1664num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1665 char_type __fl, const void* __v) const 1666{ 1667 // Stage 1 - Get pointer in narrow char 1668 char __fmt[6] = "%p"; 1669 const unsigned __nbuf = 20; 1670 char __nar[__nbuf]; 1671 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); 1672 char* __ne = __nar + __nc; 1673 char* __np = this->__identify_padding(__nar, __ne, __iob); 1674 // Stage 2 - Widen __nar 1675 char_type __o[2*(__nbuf-1) - 1]; 1676 char_type* __op; // pad here 1677 char_type* __oe; // end of output 1678 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 1679 __ct.widen(__nar, __ne, __o); 1680 __oe = __o + (__ne - __nar); 1681 if (__np == __ne) 1682 __op = __oe; 1683 else 1684 __op = __o + (__np - __nar); 1685 // [__o, __oe) contains wide number 1686 // Stage 3 & 4 1687 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1688} 1689 1690_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>) 1691_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>) 1692 1693template <class _CharT, class _InputIterator> 1694_LIBCPP_HIDDEN 1695int 1696__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, 1697 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) 1698{ 1699 // Precondition: __n >= 1 1700 if (__b == __e) 1701 { 1702 __err |= ios_base::eofbit | ios_base::failbit; 1703 return 0; 1704 } 1705 // get first digit 1706 _CharT __c = *__b; 1707 if (!__ct.is(ctype_base::digit, __c)) 1708 { 1709 __err |= ios_base::failbit; 1710 return 0; 1711 } 1712 int __r = __ct.narrow(__c, 0) - '0'; 1713 for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n) 1714 { 1715 // get next digit 1716 __c = *__b; 1717 if (!__ct.is(ctype_base::digit, __c)) 1718 return __r; 1719 __r = __r * 10 + __ct.narrow(__c, 0) - '0'; 1720 } 1721 if (__b == __e) 1722 __err |= ios_base::eofbit; 1723 return __r; 1724} 1725 1726class _LIBCPP_TYPE_VIS time_base 1727{ 1728public: 1729 enum dateorder {no_order, dmy, mdy, ymd, ydm}; 1730}; 1731 1732template <class _CharT> 1733class _LIBCPP_TEMPLATE_VIS __time_get_c_storage 1734{ 1735protected: 1736 typedef basic_string<_CharT> string_type; 1737 1738 virtual const string_type* __weeks() const; 1739 virtual const string_type* __months() const; 1740 virtual const string_type* __am_pm() const; 1741 virtual const string_type& __c() const; 1742 virtual const string_type& __r() const; 1743 virtual const string_type& __x() const; 1744 virtual const string_type& __X() const; 1745 1746 _LIBCPP_INLINE_VISIBILITY 1747 ~__time_get_c_storage() {} 1748}; 1749 1750template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const; 1751template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const; 1752template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const; 1753template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const; 1754template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const; 1755template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const; 1756template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const; 1757 1758template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const; 1759template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const; 1760template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; 1761template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const; 1762template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const; 1763template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const; 1764template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const; 1765 1766template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 1767class _LIBCPP_TEMPLATE_VIS time_get 1768 : public locale::facet, 1769 public time_base, 1770 private __time_get_c_storage<_CharT> 1771{ 1772public: 1773 typedef _CharT char_type; 1774 typedef _InputIterator iter_type; 1775 typedef time_base::dateorder dateorder; 1776 typedef basic_string<char_type> string_type; 1777 1778 _LIBCPP_INLINE_VISIBILITY 1779 explicit time_get(size_t __refs = 0) 1780 : locale::facet(__refs) {} 1781 1782 _LIBCPP_INLINE_VISIBILITY 1783 dateorder date_order() const 1784 { 1785 return this->do_date_order(); 1786 } 1787 1788 _LIBCPP_INLINE_VISIBILITY 1789 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, 1790 ios_base::iostate& __err, tm* __tm) const 1791 { 1792 return do_get_time(__b, __e, __iob, __err, __tm); 1793 } 1794 1795 _LIBCPP_INLINE_VISIBILITY 1796 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, 1797 ios_base::iostate& __err, tm* __tm) const 1798 { 1799 return do_get_date(__b, __e, __iob, __err, __tm); 1800 } 1801 1802 _LIBCPP_INLINE_VISIBILITY 1803 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 1804 ios_base::iostate& __err, tm* __tm) const 1805 { 1806 return do_get_weekday(__b, __e, __iob, __err, __tm); 1807 } 1808 1809 _LIBCPP_INLINE_VISIBILITY 1810 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 1811 ios_base::iostate& __err, tm* __tm) const 1812 { 1813 return do_get_monthname(__b, __e, __iob, __err, __tm); 1814 } 1815 1816 _LIBCPP_INLINE_VISIBILITY 1817 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, 1818 ios_base::iostate& __err, tm* __tm) const 1819 { 1820 return do_get_year(__b, __e, __iob, __err, __tm); 1821 } 1822 1823 _LIBCPP_INLINE_VISIBILITY 1824 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 1825 ios_base::iostate& __err, tm *__tm, 1826 char __fmt, char __mod = 0) const 1827 { 1828 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); 1829 } 1830 1831 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 1832 ios_base::iostate& __err, tm* __tm, 1833 const char_type* __fmtb, const char_type* __fmte) const; 1834 1835 static locale::id id; 1836 1837protected: 1838 _LIBCPP_INLINE_VISIBILITY 1839 ~time_get() {} 1840 1841 virtual dateorder do_date_order() const; 1842 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob, 1843 ios_base::iostate& __err, tm* __tm) const; 1844 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob, 1845 ios_base::iostate& __err, tm* __tm) const; 1846 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 1847 ios_base::iostate& __err, tm* __tm) const; 1848 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 1849 ios_base::iostate& __err, tm* __tm) const; 1850 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob, 1851 ios_base::iostate& __err, tm* __tm) const; 1852 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 1853 ios_base::iostate& __err, tm* __tm, 1854 char __fmt, char __mod) const; 1855private: 1856 void __get_white_space(iter_type& __b, iter_type __e, 1857 ios_base::iostate& __err, const ctype<char_type>& __ct) const; 1858 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, 1859 const ctype<char_type>& __ct) const; 1860 1861 void __get_weekdayname(int& __m, 1862 iter_type& __b, iter_type __e, 1863 ios_base::iostate& __err, 1864 const ctype<char_type>& __ct) const; 1865 void __get_monthname(int& __m, 1866 iter_type& __b, iter_type __e, 1867 ios_base::iostate& __err, 1868 const ctype<char_type>& __ct) const; 1869 void __get_day(int& __d, 1870 iter_type& __b, iter_type __e, 1871 ios_base::iostate& __err, 1872 const ctype<char_type>& __ct) const; 1873 void __get_month(int& __m, 1874 iter_type& __b, iter_type __e, 1875 ios_base::iostate& __err, 1876 const ctype<char_type>& __ct) const; 1877 void __get_year(int& __y, 1878 iter_type& __b, iter_type __e, 1879 ios_base::iostate& __err, 1880 const ctype<char_type>& __ct) const; 1881 void __get_year4(int& __y, 1882 iter_type& __b, iter_type __e, 1883 ios_base::iostate& __err, 1884 const ctype<char_type>& __ct) const; 1885 void __get_hour(int& __d, 1886 iter_type& __b, iter_type __e, 1887 ios_base::iostate& __err, 1888 const ctype<char_type>& __ct) const; 1889 void __get_12_hour(int& __h, 1890 iter_type& __b, iter_type __e, 1891 ios_base::iostate& __err, 1892 const ctype<char_type>& __ct) const; 1893 void __get_am_pm(int& __h, 1894 iter_type& __b, iter_type __e, 1895 ios_base::iostate& __err, 1896 const ctype<char_type>& __ct) const; 1897 void __get_minute(int& __m, 1898 iter_type& __b, iter_type __e, 1899 ios_base::iostate& __err, 1900 const ctype<char_type>& __ct) const; 1901 void __get_second(int& __s, 1902 iter_type& __b, iter_type __e, 1903 ios_base::iostate& __err, 1904 const ctype<char_type>& __ct) const; 1905 void __get_weekday(int& __w, 1906 iter_type& __b, iter_type __e, 1907 ios_base::iostate& __err, 1908 const ctype<char_type>& __ct) const; 1909 void __get_day_year_num(int& __w, 1910 iter_type& __b, iter_type __e, 1911 ios_base::iostate& __err, 1912 const ctype<char_type>& __ct) const; 1913}; 1914 1915template <class _CharT, class _InputIterator> 1916locale::id 1917time_get<_CharT, _InputIterator>::id; 1918 1919// time_get primitives 1920 1921template <class _CharT, class _InputIterator> 1922void 1923time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, 1924 iter_type& __b, iter_type __e, 1925 ios_base::iostate& __err, 1926 const ctype<char_type>& __ct) const 1927{ 1928 // Note: ignoring case comes from the POSIX strptime spec 1929 const string_type* __wk = this->__weeks(); 1930 ptrdiff_t __i = _VSTD::__scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; 1931 if (__i < 14) 1932 __w = __i % 7; 1933} 1934 1935template <class _CharT, class _InputIterator> 1936void 1937time_get<_CharT, _InputIterator>::__get_monthname(int& __m, 1938 iter_type& __b, iter_type __e, 1939 ios_base::iostate& __err, 1940 const ctype<char_type>& __ct) const 1941{ 1942 // Note: ignoring case comes from the POSIX strptime spec 1943 const string_type* __month = this->__months(); 1944 ptrdiff_t __i = _VSTD::__scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; 1945 if (__i < 24) 1946 __m = __i % 12; 1947} 1948 1949template <class _CharT, class _InputIterator> 1950void 1951time_get<_CharT, _InputIterator>::__get_day(int& __d, 1952 iter_type& __b, iter_type __e, 1953 ios_base::iostate& __err, 1954 const ctype<char_type>& __ct) const 1955{ 1956 int __t = _VSTD::__get_up_to_n_digits(__b, __e, __err, __ct, 2); 1957 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) 1958 __d = __t; 1959 else 1960 __err |= ios_base::failbit; 1961} 1962 1963template <class _CharT, class _InputIterator> 1964void 1965time_get<_CharT, _InputIterator>::__get_month(int& __m, 1966 iter_type& __b, iter_type __e, 1967 ios_base::iostate& __err, 1968 const ctype<char_type>& __ct) const 1969{ 1970 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; 1971 if (!(__err & ios_base::failbit) && __t <= 11) 1972 __m = __t; 1973 else 1974 __err |= ios_base::failbit; 1975} 1976 1977template <class _CharT, class _InputIterator> 1978void 1979time_get<_CharT, _InputIterator>::__get_year(int& __y, 1980 iter_type& __b, iter_type __e, 1981 ios_base::iostate& __err, 1982 const ctype<char_type>& __ct) const 1983{ 1984 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 1985 if (!(__err & ios_base::failbit)) 1986 { 1987 if (__t < 69) 1988 __t += 2000; 1989 else if (69 <= __t && __t <= 99) 1990 __t += 1900; 1991 __y = __t - 1900; 1992 } 1993} 1994 1995template <class _CharT, class _InputIterator> 1996void 1997time_get<_CharT, _InputIterator>::__get_year4(int& __y, 1998 iter_type& __b, iter_type __e, 1999 ios_base::iostate& __err, 2000 const ctype<char_type>& __ct) const 2001{ 2002 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 2003 if (!(__err & ios_base::failbit)) 2004 __y = __t - 1900; 2005} 2006 2007template <class _CharT, class _InputIterator> 2008void 2009time_get<_CharT, _InputIterator>::__get_hour(int& __h, 2010 iter_type& __b, iter_type __e, 2011 ios_base::iostate& __err, 2012 const ctype<char_type>& __ct) const 2013{ 2014 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2015 if (!(__err & ios_base::failbit) && __t <= 23) 2016 __h = __t; 2017 else 2018 __err |= ios_base::failbit; 2019} 2020 2021template <class _CharT, class _InputIterator> 2022void 2023time_get<_CharT, _InputIterator>::__get_12_hour(int& __h, 2024 iter_type& __b, iter_type __e, 2025 ios_base::iostate& __err, 2026 const ctype<char_type>& __ct) const 2027{ 2028 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2029 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) 2030 __h = __t; 2031 else 2032 __err |= ios_base::failbit; 2033} 2034 2035template <class _CharT, class _InputIterator> 2036void 2037time_get<_CharT, _InputIterator>::__get_minute(int& __m, 2038 iter_type& __b, iter_type __e, 2039 ios_base::iostate& __err, 2040 const ctype<char_type>& __ct) const 2041{ 2042 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2043 if (!(__err & ios_base::failbit) && __t <= 59) 2044 __m = __t; 2045 else 2046 __err |= ios_base::failbit; 2047} 2048 2049template <class _CharT, class _InputIterator> 2050void 2051time_get<_CharT, _InputIterator>::__get_second(int& __s, 2052 iter_type& __b, iter_type __e, 2053 ios_base::iostate& __err, 2054 const ctype<char_type>& __ct) const 2055{ 2056 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2057 if (!(__err & ios_base::failbit) && __t <= 60) 2058 __s = __t; 2059 else 2060 __err |= ios_base::failbit; 2061} 2062 2063template <class _CharT, class _InputIterator> 2064void 2065time_get<_CharT, _InputIterator>::__get_weekday(int& __w, 2066 iter_type& __b, iter_type __e, 2067 ios_base::iostate& __err, 2068 const ctype<char_type>& __ct) const 2069{ 2070 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1); 2071 if (!(__err & ios_base::failbit) && __t <= 6) 2072 __w = __t; 2073 else 2074 __err |= ios_base::failbit; 2075} 2076 2077template <class _CharT, class _InputIterator> 2078void 2079time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d, 2080 iter_type& __b, iter_type __e, 2081 ios_base::iostate& __err, 2082 const ctype<char_type>& __ct) const 2083{ 2084 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3); 2085 if (!(__err & ios_base::failbit) && __t <= 365) 2086 __d = __t; 2087 else 2088 __err |= ios_base::failbit; 2089} 2090 2091template <class _CharT, class _InputIterator> 2092void 2093time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e, 2094 ios_base::iostate& __err, 2095 const ctype<char_type>& __ct) const 2096{ 2097 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2098 ; 2099 if (__b == __e) 2100 __err |= ios_base::eofbit; 2101} 2102 2103template <class _CharT, class _InputIterator> 2104void 2105time_get<_CharT, _InputIterator>::__get_am_pm(int& __h, 2106 iter_type& __b, iter_type __e, 2107 ios_base::iostate& __err, 2108 const ctype<char_type>& __ct) const 2109{ 2110 const string_type* __ap = this->__am_pm(); 2111 if (__ap[0].size() + __ap[1].size() == 0) 2112 { 2113 __err |= ios_base::failbit; 2114 return; 2115 } 2116 ptrdiff_t __i = _VSTD::__scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; 2117 if (__i == 0 && __h == 12) 2118 __h = 0; 2119 else if (__i == 1 && __h < 12) 2120 __h += 12; 2121} 2122 2123template <class _CharT, class _InputIterator> 2124void 2125time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e, 2126 ios_base::iostate& __err, 2127 const ctype<char_type>& __ct) const 2128{ 2129 if (__b == __e) 2130 { 2131 __err |= ios_base::eofbit | ios_base::failbit; 2132 return; 2133 } 2134 if (__ct.narrow(*__b, 0) != '%') 2135 __err |= ios_base::failbit; 2136 else if(++__b == __e) 2137 __err |= ios_base::eofbit; 2138} 2139 2140// time_get end primitives 2141 2142template <class _CharT, class _InputIterator> 2143_InputIterator 2144time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e, 2145 ios_base& __iob, 2146 ios_base::iostate& __err, tm* __tm, 2147 const char_type* __fmtb, const char_type* __fmte) const 2148{ 2149 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2150 __err = ios_base::goodbit; 2151 while (__fmtb != __fmte && __err == ios_base::goodbit) 2152 { 2153 if (__b == __e) 2154 { 2155 __err = ios_base::failbit; 2156 break; 2157 } 2158 if (__ct.narrow(*__fmtb, 0) == '%') 2159 { 2160 if (++__fmtb == __fmte) 2161 { 2162 __err = ios_base::failbit; 2163 break; 2164 } 2165 char __cmd = __ct.narrow(*__fmtb, 0); 2166 char __opt = '\0'; 2167 if (__cmd == 'E' || __cmd == '0') 2168 { 2169 if (++__fmtb == __fmte) 2170 { 2171 __err = ios_base::failbit; 2172 break; 2173 } 2174 __opt = __cmd; 2175 __cmd = __ct.narrow(*__fmtb, 0); 2176 } 2177 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); 2178 ++__fmtb; 2179 } 2180 else if (__ct.is(ctype_base::space, *__fmtb)) 2181 { 2182 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) 2183 ; 2184 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2185 ; 2186 } 2187 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) 2188 { 2189 ++__b; 2190 ++__fmtb; 2191 } 2192 else 2193 __err = ios_base::failbit; 2194 } 2195 if (__b == __e) 2196 __err |= ios_base::eofbit; 2197 return __b; 2198} 2199 2200template <class _CharT, class _InputIterator> 2201typename time_get<_CharT, _InputIterator>::dateorder 2202time_get<_CharT, _InputIterator>::do_date_order() const 2203{ 2204 return mdy; 2205} 2206 2207template <class _CharT, class _InputIterator> 2208_InputIterator 2209time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e, 2210 ios_base& __iob, 2211 ios_base::iostate& __err, 2212 tm* __tm) const 2213{ 2214 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2215 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); 2216} 2217 2218template <class _CharT, class _InputIterator> 2219_InputIterator 2220time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, 2221 ios_base& __iob, 2222 ios_base::iostate& __err, 2223 tm* __tm) const 2224{ 2225 const string_type& __fmt = this->__x(); 2226 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); 2227} 2228 2229template <class _CharT, class _InputIterator> 2230_InputIterator 2231time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e, 2232 ios_base& __iob, 2233 ios_base::iostate& __err, 2234 tm* __tm) const 2235{ 2236 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2237 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2238 return __b; 2239} 2240 2241template <class _CharT, class _InputIterator> 2242_InputIterator 2243time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e, 2244 ios_base& __iob, 2245 ios_base::iostate& __err, 2246 tm* __tm) const 2247{ 2248 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2249 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2250 return __b; 2251} 2252 2253template <class _CharT, class _InputIterator> 2254_InputIterator 2255time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e, 2256 ios_base& __iob, 2257 ios_base::iostate& __err, 2258 tm* __tm) const 2259{ 2260 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2261 __get_year(__tm->tm_year, __b, __e, __err, __ct); 2262 return __b; 2263} 2264 2265template <class _CharT, class _InputIterator> 2266_InputIterator 2267time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 2268 ios_base& __iob, 2269 ios_base::iostate& __err, tm* __tm, 2270 char __fmt, char) const 2271{ 2272 __err = ios_base::goodbit; 2273 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2274 switch (__fmt) 2275 { 2276 case 'a': 2277 case 'A': 2278 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2279 break; 2280 case 'b': 2281 case 'B': 2282 case 'h': 2283 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2284 break; 2285 case 'c': 2286 { 2287 const string_type& __fm = this->__c(); 2288 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2289 } 2290 break; 2291 case 'd': 2292 case 'e': 2293 __get_day(__tm->tm_mday, __b, __e, __err, __ct); 2294 break; 2295 case 'D': 2296 { 2297 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; 2298 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2299 } 2300 break; 2301 case 'F': 2302 { 2303 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; 2304 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2305 } 2306 break; 2307 case 'H': 2308 __get_hour(__tm->tm_hour, __b, __e, __err, __ct); 2309 break; 2310 case 'I': 2311 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); 2312 break; 2313 case 'j': 2314 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); 2315 break; 2316 case 'm': 2317 __get_month(__tm->tm_mon, __b, __e, __err, __ct); 2318 break; 2319 case 'M': 2320 __get_minute(__tm->tm_min, __b, __e, __err, __ct); 2321 break; 2322 case 'n': 2323 case 't': 2324 __get_white_space(__b, __e, __err, __ct); 2325 break; 2326 case 'p': 2327 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); 2328 break; 2329 case 'r': 2330 { 2331 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; 2332 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2333 } 2334 break; 2335 case 'R': 2336 { 2337 const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; 2338 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2339 } 2340 break; 2341 case 'S': 2342 __get_second(__tm->tm_sec, __b, __e, __err, __ct); 2343 break; 2344 case 'T': 2345 { 2346 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2347 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2348 } 2349 break; 2350 case 'w': 2351 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); 2352 break; 2353 case 'x': 2354 return do_get_date(__b, __e, __iob, __err, __tm); 2355 case 'X': 2356 { 2357 const string_type& __fm = this->__X(); 2358 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2359 } 2360 break; 2361 case 'y': 2362 __get_year(__tm->tm_year, __b, __e, __err, __ct); 2363 break; 2364 case 'Y': 2365 __get_year4(__tm->tm_year, __b, __e, __err, __ct); 2366 break; 2367 case '%': 2368 __get_percent(__b, __e, __err, __ct); 2369 break; 2370 default: 2371 __err |= ios_base::failbit; 2372 } 2373 return __b; 2374} 2375 2376_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>) 2377_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>) 2378 2379class _LIBCPP_TYPE_VIS __time_get 2380{ 2381protected: 2382 locale_t __loc_; 2383 2384 __time_get(const char* __nm); 2385 __time_get(const string& __nm); 2386 ~__time_get(); 2387}; 2388 2389template <class _CharT> 2390class _LIBCPP_TEMPLATE_VIS __time_get_storage 2391 : public __time_get 2392{ 2393protected: 2394 typedef basic_string<_CharT> string_type; 2395 2396 string_type __weeks_[14]; 2397 string_type __months_[24]; 2398 string_type __am_pm_[2]; 2399 string_type __c_; 2400 string_type __r_; 2401 string_type __x_; 2402 string_type __X_; 2403 2404 explicit __time_get_storage(const char* __nm); 2405 explicit __time_get_storage(const string& __nm); 2406 2407 _LIBCPP_INLINE_VISIBILITY ~__time_get_storage() {} 2408 2409 time_base::dateorder __do_date_order() const; 2410 2411private: 2412 void init(const ctype<_CharT>&); 2413 string_type __analyze(char __fmt, const ctype<_CharT>&); 2414}; 2415 2416#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ 2417template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2418template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2419template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2420template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2421template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 2422extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ 2423extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ 2424extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ 2425extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ 2426extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ 2427/**/ 2428 2429_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) 2430_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t) 2431#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION 2432 2433template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2434class _LIBCPP_TEMPLATE_VIS time_get_byname 2435 : public time_get<_CharT, _InputIterator>, 2436 private __time_get_storage<_CharT> 2437{ 2438public: 2439 typedef time_base::dateorder dateorder; 2440 typedef _InputIterator iter_type; 2441 typedef _CharT char_type; 2442 typedef basic_string<char_type> string_type; 2443 2444 _LIBCPP_INLINE_VISIBILITY 2445 explicit time_get_byname(const char* __nm, size_t __refs = 0) 2446 : time_get<_CharT, _InputIterator>(__refs), 2447 __time_get_storage<_CharT>(__nm) {} 2448 _LIBCPP_INLINE_VISIBILITY 2449 explicit time_get_byname(const string& __nm, size_t __refs = 0) 2450 : time_get<_CharT, _InputIterator>(__refs), 2451 __time_get_storage<_CharT>(__nm) {} 2452 2453protected: 2454 _LIBCPP_INLINE_VISIBILITY 2455 ~time_get_byname() {} 2456 2457 _LIBCPP_INLINE_VISIBILITY 2458 virtual dateorder do_date_order() const {return this->__do_date_order();} 2459private: 2460 _LIBCPP_INLINE_VISIBILITY 2461 virtual const string_type* __weeks() const {return this->__weeks_;} 2462 _LIBCPP_INLINE_VISIBILITY 2463 virtual const string_type* __months() const {return this->__months_;} 2464 _LIBCPP_INLINE_VISIBILITY 2465 virtual const string_type* __am_pm() const {return this->__am_pm_;} 2466 _LIBCPP_INLINE_VISIBILITY 2467 virtual const string_type& __c() const {return this->__c_;} 2468 _LIBCPP_INLINE_VISIBILITY 2469 virtual const string_type& __r() const {return this->__r_;} 2470 _LIBCPP_INLINE_VISIBILITY 2471 virtual const string_type& __x() const {return this->__x_;} 2472 _LIBCPP_INLINE_VISIBILITY 2473 virtual const string_type& __X() const {return this->__X_;} 2474}; 2475 2476_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>) 2477_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>) 2478 2479class _LIBCPP_TYPE_VIS __time_put 2480{ 2481 locale_t __loc_; 2482protected: 2483 _LIBCPP_INLINE_VISIBILITY __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} 2484 __time_put(const char* __nm); 2485 __time_put(const string& __nm); 2486 ~__time_put(); 2487 void __do_put(char* __nb, char*& __ne, const tm* __tm, 2488 char __fmt, char __mod) const; 2489 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 2490 char __fmt, char __mod) const; 2491}; 2492 2493template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2494class _LIBCPP_TEMPLATE_VIS time_put 2495 : public locale::facet, 2496 private __time_put 2497{ 2498public: 2499 typedef _CharT char_type; 2500 typedef _OutputIterator iter_type; 2501 2502 _LIBCPP_INLINE_VISIBILITY 2503 explicit time_put(size_t __refs = 0) 2504 : locale::facet(__refs) {} 2505 2506 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, 2507 const char_type* __pb, const char_type* __pe) const; 2508 2509 _LIBCPP_INLINE_VISIBILITY 2510 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 2511 const tm* __tm, char __fmt, char __mod = 0) const 2512 { 2513 return do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2514 } 2515 2516 static locale::id id; 2517 2518protected: 2519 _LIBCPP_INLINE_VISIBILITY 2520 ~time_put() {} 2521 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, 2522 char __fmt, char __mod) const; 2523 2524 _LIBCPP_INLINE_VISIBILITY 2525 explicit time_put(const char* __nm, size_t __refs) 2526 : locale::facet(__refs), 2527 __time_put(__nm) {} 2528 _LIBCPP_INLINE_VISIBILITY 2529 explicit time_put(const string& __nm, size_t __refs) 2530 : locale::facet(__refs), 2531 __time_put(__nm) {} 2532}; 2533 2534template <class _CharT, class _OutputIterator> 2535locale::id 2536time_put<_CharT, _OutputIterator>::id; 2537 2538template <class _CharT, class _OutputIterator> 2539_OutputIterator 2540time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, 2541 char_type __fl, const tm* __tm, 2542 const char_type* __pb, 2543 const char_type* __pe) const 2544{ 2545 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2546 for (; __pb != __pe; ++__pb) 2547 { 2548 if (__ct.narrow(*__pb, 0) == '%') 2549 { 2550 if (++__pb == __pe) 2551 { 2552 *__s++ = __pb[-1]; 2553 break; 2554 } 2555 char __mod = 0; 2556 char __fmt = __ct.narrow(*__pb, 0); 2557 if (__fmt == 'E' || __fmt == 'O') 2558 { 2559 if (++__pb == __pe) 2560 { 2561 *__s++ = __pb[-2]; 2562 *__s++ = __pb[-1]; 2563 break; 2564 } 2565 __mod = __fmt; 2566 __fmt = __ct.narrow(*__pb, 0); 2567 } 2568 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2569 } 2570 else 2571 *__s++ = *__pb; 2572 } 2573 return __s; 2574} 2575 2576template <class _CharT, class _OutputIterator> 2577_OutputIterator 2578time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, 2579 char_type, const tm* __tm, 2580 char __fmt, char __mod) const 2581{ 2582 char_type __nar[100]; 2583 char_type* __nb = __nar; 2584 char_type* __ne = __nb + 100; 2585 __do_put(__nb, __ne, __tm, __fmt, __mod); 2586 return _VSTD::copy(__nb, __ne, __s); 2587} 2588 2589_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>) 2590_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>) 2591 2592template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2593class _LIBCPP_TEMPLATE_VIS time_put_byname 2594 : public time_put<_CharT, _OutputIterator> 2595{ 2596public: 2597 _LIBCPP_INLINE_VISIBILITY 2598 explicit time_put_byname(const char* __nm, size_t __refs = 0) 2599 : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2600 2601 _LIBCPP_INLINE_VISIBILITY 2602 explicit time_put_byname(const string& __nm, size_t __refs = 0) 2603 : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2604 2605protected: 2606 _LIBCPP_INLINE_VISIBILITY 2607 ~time_put_byname() {} 2608}; 2609 2610_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>) 2611_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>) 2612 2613// money_base 2614 2615class _LIBCPP_TYPE_VIS money_base 2616{ 2617public: 2618 enum part {none, space, symbol, sign, value}; 2619 struct pattern {char field[4];}; 2620 2621 _LIBCPP_INLINE_VISIBILITY money_base() {} 2622}; 2623 2624// moneypunct 2625 2626template <class _CharT, bool _International = false> 2627class _LIBCPP_TEMPLATE_VIS moneypunct 2628 : public locale::facet, 2629 public money_base 2630{ 2631public: 2632 typedef _CharT char_type; 2633 typedef basic_string<char_type> string_type; 2634 2635 _LIBCPP_INLINE_VISIBILITY 2636 explicit moneypunct(size_t __refs = 0) 2637 : locale::facet(__refs) {} 2638 2639 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 2640 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 2641 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 2642 _LIBCPP_INLINE_VISIBILITY string_type curr_symbol() const {return do_curr_symbol();} 2643 _LIBCPP_INLINE_VISIBILITY string_type positive_sign() const {return do_positive_sign();} 2644 _LIBCPP_INLINE_VISIBILITY string_type negative_sign() const {return do_negative_sign();} 2645 _LIBCPP_INLINE_VISIBILITY int frac_digits() const {return do_frac_digits();} 2646 _LIBCPP_INLINE_VISIBILITY pattern pos_format() const {return do_pos_format();} 2647 _LIBCPP_INLINE_VISIBILITY pattern neg_format() const {return do_neg_format();} 2648 2649 static locale::id id; 2650 static const bool intl = _International; 2651 2652protected: 2653 _LIBCPP_INLINE_VISIBILITY 2654 ~moneypunct() {} 2655 2656 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();} 2657 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();} 2658 virtual string do_grouping() const {return string();} 2659 virtual string_type do_curr_symbol() const {return string_type();} 2660 virtual string_type do_positive_sign() const {return string_type();} 2661 virtual string_type do_negative_sign() const {return string_type(1, '-');} 2662 virtual int do_frac_digits() const {return 0;} 2663 virtual pattern do_pos_format() const 2664 {pattern __p = {{symbol, sign, none, value}}; return __p;} 2665 virtual pattern do_neg_format() const 2666 {pattern __p = {{symbol, sign, none, value}}; return __p;} 2667}; 2668 2669template <class _CharT, bool _International> 2670locale::id 2671moneypunct<_CharT, _International>::id; 2672 2673template <class _CharT, bool _International> 2674const bool 2675moneypunct<_CharT, _International>::intl; 2676 2677_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>) 2678_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>) 2679_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>) 2680_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>) 2681 2682// moneypunct_byname 2683 2684template <class _CharT, bool _International = false> 2685class _LIBCPP_TEMPLATE_VIS moneypunct_byname 2686 : public moneypunct<_CharT, _International> 2687{ 2688public: 2689 typedef money_base::pattern pattern; 2690 typedef _CharT char_type; 2691 typedef basic_string<char_type> string_type; 2692 2693 _LIBCPP_INLINE_VISIBILITY 2694 explicit moneypunct_byname(const char* __nm, size_t __refs = 0) 2695 : moneypunct<_CharT, _International>(__refs) {init(__nm);} 2696 2697 _LIBCPP_INLINE_VISIBILITY 2698 explicit moneypunct_byname(const string& __nm, size_t __refs = 0) 2699 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} 2700 2701protected: 2702 _LIBCPP_INLINE_VISIBILITY 2703 ~moneypunct_byname() {} 2704 2705 virtual char_type do_decimal_point() const {return __decimal_point_;} 2706 virtual char_type do_thousands_sep() const {return __thousands_sep_;} 2707 virtual string do_grouping() const {return __grouping_;} 2708 virtual string_type do_curr_symbol() const {return __curr_symbol_;} 2709 virtual string_type do_positive_sign() const {return __positive_sign_;} 2710 virtual string_type do_negative_sign() const {return __negative_sign_;} 2711 virtual int do_frac_digits() const {return __frac_digits_;} 2712 virtual pattern do_pos_format() const {return __pos_format_;} 2713 virtual pattern do_neg_format() const {return __neg_format_;} 2714 2715private: 2716 char_type __decimal_point_; 2717 char_type __thousands_sep_; 2718 string __grouping_; 2719 string_type __curr_symbol_; 2720 string_type __positive_sign_; 2721 string_type __negative_sign_; 2722 int __frac_digits_; 2723 pattern __pos_format_; 2724 pattern __neg_format_; 2725 2726 void init(const char*); 2727}; 2728 2729template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*); 2730template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*); 2731template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*); 2732template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*); 2733 2734_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>) 2735_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>) 2736_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>) 2737_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>) 2738 2739// money_get 2740 2741template <class _CharT> 2742class __money_get 2743{ 2744protected: 2745 typedef _CharT char_type; 2746 typedef basic_string<char_type> string_type; 2747 2748 _LIBCPP_INLINE_VISIBILITY __money_get() {} 2749 2750 static void __gather_info(bool __intl, const locale& __loc, 2751 money_base::pattern& __pat, char_type& __dp, 2752 char_type& __ts, string& __grp, 2753 string_type& __sym, string_type& __psn, 2754 string_type& __nsn, int& __fd); 2755}; 2756 2757template <class _CharT> 2758void 2759__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, 2760 money_base::pattern& __pat, char_type& __dp, 2761 char_type& __ts, string& __grp, 2762 string_type& __sym, string_type& __psn, 2763 string_type& __nsn, int& __fd) 2764{ 2765 if (__intl) 2766 { 2767 const moneypunct<char_type, true>& __mp = 2768 use_facet<moneypunct<char_type, true> >(__loc); 2769 __pat = __mp.neg_format(); 2770 __nsn = __mp.negative_sign(); 2771 __psn = __mp.positive_sign(); 2772 __dp = __mp.decimal_point(); 2773 __ts = __mp.thousands_sep(); 2774 __grp = __mp.grouping(); 2775 __sym = __mp.curr_symbol(); 2776 __fd = __mp.frac_digits(); 2777 } 2778 else 2779 { 2780 const moneypunct<char_type, false>& __mp = 2781 use_facet<moneypunct<char_type, false> >(__loc); 2782 __pat = __mp.neg_format(); 2783 __nsn = __mp.negative_sign(); 2784 __psn = __mp.positive_sign(); 2785 __dp = __mp.decimal_point(); 2786 __ts = __mp.thousands_sep(); 2787 __grp = __mp.grouping(); 2788 __sym = __mp.curr_symbol(); 2789 __fd = __mp.frac_digits(); 2790 } 2791} 2792 2793_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>) 2794_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>) 2795 2796template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2797class _LIBCPP_TEMPLATE_VIS money_get 2798 : public locale::facet, 2799 private __money_get<_CharT> 2800{ 2801public: 2802 typedef _CharT char_type; 2803 typedef _InputIterator iter_type; 2804 typedef basic_string<char_type> string_type; 2805 2806 _LIBCPP_INLINE_VISIBILITY 2807 explicit money_get(size_t __refs = 0) 2808 : locale::facet(__refs) {} 2809 2810 _LIBCPP_INLINE_VISIBILITY 2811 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 2812 ios_base::iostate& __err, long double& __v) const 2813 { 2814 return do_get(__b, __e, __intl, __iob, __err, __v); 2815 } 2816 2817 _LIBCPP_INLINE_VISIBILITY 2818 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 2819 ios_base::iostate& __err, string_type& __v) const 2820 { 2821 return do_get(__b, __e, __intl, __iob, __err, __v); 2822 } 2823 2824 static locale::id id; 2825 2826protected: 2827 2828 _LIBCPP_INLINE_VISIBILITY 2829 ~money_get() {} 2830 2831 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 2832 ios_base& __iob, ios_base::iostate& __err, 2833 long double& __v) const; 2834 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 2835 ios_base& __iob, ios_base::iostate& __err, 2836 string_type& __v) const; 2837 2838private: 2839 static bool __do_get(iter_type& __b, iter_type __e, 2840 bool __intl, const locale& __loc, 2841 ios_base::fmtflags __flags, ios_base::iostate& __err, 2842 bool& __neg, const ctype<char_type>& __ct, 2843 unique_ptr<char_type, void(*)(void*)>& __wb, 2844 char_type*& __wn, char_type* __we); 2845}; 2846 2847template <class _CharT, class _InputIterator> 2848locale::id 2849money_get<_CharT, _InputIterator>::id; 2850 2851_LIBCPP_FUNC_VIS void __do_nothing(void*); 2852 2853template <class _Tp> 2854_LIBCPP_HIDDEN 2855void 2856__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) 2857{ 2858 bool __owns = __b.get_deleter() != __do_nothing; 2859 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp); 2860 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 2861 2 * __cur_cap : numeric_limits<size_t>::max(); 2862 if (__new_cap == 0) 2863 __new_cap = sizeof(_Tp); 2864 size_t __n_off = static_cast<size_t>(__n - __b.get()); 2865 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); 2866 if (__t == 0) 2867 __throw_bad_alloc(); 2868 if (__owns) 2869 __b.release(); 2870 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); 2871 __new_cap /= sizeof(_Tp); 2872 __n = __b.get() + __n_off; 2873 __e = __b.get() + __new_cap; 2874} 2875 2876// true == success 2877template <class _CharT, class _InputIterator> 2878bool 2879money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, 2880 bool __intl, const locale& __loc, 2881 ios_base::fmtflags __flags, 2882 ios_base::iostate& __err, 2883 bool& __neg, 2884 const ctype<char_type>& __ct, 2885 unique_ptr<char_type, void(*)(void*)>& __wb, 2886 char_type*& __wn, char_type* __we) 2887{ 2888 const unsigned __bz = 100; 2889 unsigned __gbuf[__bz]; 2890 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing); 2891 unsigned* __gn = __gb.get(); 2892 unsigned* __ge = __gn + __bz; 2893 money_base::pattern __pat; 2894 char_type __dp; 2895 char_type __ts; 2896 string __grp; 2897 string_type __sym; 2898 string_type __psn; 2899 string_type __nsn; 2900 // Capture the spaces read into money_base::{space,none} so they 2901 // can be compared to initial spaces in __sym. 2902 string_type __spaces; 2903 int __fd; 2904 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, 2905 __sym, __psn, __nsn, __fd); 2906 const string_type* __trailing_sign = 0; 2907 __wn = __wb.get(); 2908 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) 2909 { 2910 switch (__pat.field[__p]) 2911 { 2912 case money_base::space: 2913 if (__p != 3) 2914 { 2915 if (__ct.is(ctype_base::space, *__b)) 2916 __spaces.push_back(*__b++); 2917 else 2918 { 2919 __err |= ios_base::failbit; 2920 return false; 2921 } 2922 } 2923 _LIBCPP_FALLTHROUGH(); 2924 case money_base::none: 2925 if (__p != 3) 2926 { 2927 while (__b != __e && __ct.is(ctype_base::space, *__b)) 2928 __spaces.push_back(*__b++); 2929 } 2930 break; 2931 case money_base::sign: 2932 if (__psn.size() + __nsn.size() > 0) 2933 { 2934 if (__psn.size() == 0 || __nsn.size() == 0) 2935 { // sign is optional 2936 if (__psn.size() > 0) 2937 { // __nsn.size() == 0 2938 if (*__b == __psn[0]) 2939 { 2940 ++__b; 2941 if (__psn.size() > 1) 2942 __trailing_sign = &__psn; 2943 } 2944 else 2945 __neg = true; 2946 } 2947 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0 2948 { 2949 ++__b; 2950 __neg = true; 2951 if (__nsn.size() > 1) 2952 __trailing_sign = &__nsn; 2953 } 2954 } 2955 else // sign is required 2956 { 2957 if (*__b == __psn[0]) 2958 { 2959 ++__b; 2960 if (__psn.size() > 1) 2961 __trailing_sign = &__psn; 2962 } 2963 else if (*__b == __nsn[0]) 2964 { 2965 ++__b; 2966 __neg = true; 2967 if (__nsn.size() > 1) 2968 __trailing_sign = &__nsn; 2969 } 2970 else 2971 { 2972 __err |= ios_base::failbit; 2973 return false; 2974 } 2975 } 2976 } 2977 break; 2978 case money_base::symbol: 2979 { 2980 bool __more_needed = __trailing_sign || 2981 (__p < 2) || 2982 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none)); 2983 bool __sb = (__flags & ios_base::showbase) != 0; 2984 if (__sb || __more_needed) 2985 { 2986 typename string_type::const_iterator __sym_space_end = __sym.begin(); 2987 if (__p > 0 && (__pat.field[__p - 1] == money_base::none || 2988 __pat.field[__p - 1] == money_base::space)) { 2989 // Match spaces we've already read against spaces at 2990 // the beginning of __sym. 2991 while (__sym_space_end != __sym.end() && 2992 __ct.is(ctype_base::space, *__sym_space_end)) 2993 ++__sym_space_end; 2994 const size_t __num_spaces = __sym_space_end - __sym.begin(); 2995 if (__num_spaces > __spaces.size() || 2996 !equal(__spaces.end() - __num_spaces, __spaces.end(), 2997 __sym.begin())) { 2998 // No match. Put __sym_space_end back at the 2999 // beginning of __sym, which will prevent a 3000 // match in the next loop. 3001 __sym_space_end = __sym.begin(); 3002 } 3003 } 3004 typename string_type::const_iterator __sym_curr_char = __sym_space_end; 3005 while (__sym_curr_char != __sym.end() && __b != __e && 3006 *__b == *__sym_curr_char) { 3007 ++__b; 3008 ++__sym_curr_char; 3009 } 3010 if (__sb && __sym_curr_char != __sym.end()) 3011 { 3012 __err |= ios_base::failbit; 3013 return false; 3014 } 3015 } 3016 } 3017 break; 3018 case money_base::value: 3019 { 3020 unsigned __ng = 0; 3021 for (; __b != __e; ++__b) 3022 { 3023 char_type __c = *__b; 3024 if (__ct.is(ctype_base::digit, __c)) 3025 { 3026 if (__wn == __we) 3027 __double_or_nothing(__wb, __wn, __we); 3028 *__wn++ = __c; 3029 ++__ng; 3030 } 3031 else if (__grp.size() > 0 && __ng > 0 && __c == __ts) 3032 { 3033 if (__gn == __ge) 3034 __double_or_nothing(__gb, __gn, __ge); 3035 *__gn++ = __ng; 3036 __ng = 0; 3037 } 3038 else 3039 break; 3040 } 3041 if (__gb.get() != __gn && __ng > 0) 3042 { 3043 if (__gn == __ge) 3044 __double_or_nothing(__gb, __gn, __ge); 3045 *__gn++ = __ng; 3046 } 3047 if (__fd > 0) 3048 { 3049 if (__b == __e || *__b != __dp) 3050 { 3051 __err |= ios_base::failbit; 3052 return false; 3053 } 3054 for (++__b; __fd > 0; --__fd, ++__b) 3055 { 3056 if (__b == __e || !__ct.is(ctype_base::digit, *__b)) 3057 { 3058 __err |= ios_base::failbit; 3059 return false; 3060 } 3061 if (__wn == __we) 3062 __double_or_nothing(__wb, __wn, __we); 3063 *__wn++ = *__b; 3064 } 3065 } 3066 if (__wn == __wb.get()) 3067 { 3068 __err |= ios_base::failbit; 3069 return false; 3070 } 3071 } 3072 break; 3073 } 3074 } 3075 if (__trailing_sign) 3076 { 3077 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) 3078 { 3079 if (__b == __e || *__b != (*__trailing_sign)[__i]) 3080 { 3081 __err |= ios_base::failbit; 3082 return false; 3083 } 3084 } 3085 } 3086 if (__gb.get() != __gn) 3087 { 3088 ios_base::iostate __et = ios_base::goodbit; 3089 __check_grouping(__grp, __gb.get(), __gn, __et); 3090 if (__et) 3091 { 3092 __err |= ios_base::failbit; 3093 return false; 3094 } 3095 } 3096 return true; 3097} 3098 3099template <class _CharT, class _InputIterator> 3100_InputIterator 3101money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3102 bool __intl, ios_base& __iob, 3103 ios_base::iostate& __err, 3104 long double& __v) const 3105{ 3106 const int __bz = 100; 3107 char_type __wbuf[__bz]; 3108 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3109 char_type* __wn; 3110 char_type* __we = __wbuf + __bz; 3111 locale __loc = __iob.getloc(); 3112 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3113 bool __neg = false; 3114 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3115 __wb, __wn, __we)) 3116 { 3117 const char __src[] = "0123456789"; 3118 char_type __atoms[sizeof(__src)-1]; 3119 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms); 3120 char __nbuf[__bz]; 3121 char* __nc = __nbuf; 3122 unique_ptr<char, void(*)(void*)> __h(nullptr, free); 3123 if (__wn - __wb.get() > __bz-2) 3124 { 3125 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); 3126 if (__h.get() == nullptr) 3127 __throw_bad_alloc(); 3128 __nc = __h.get(); 3129 } 3130 if (__neg) 3131 *__nc++ = '-'; 3132 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) 3133 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms]; 3134 *__nc = char(); 3135 if (sscanf(__nbuf, "%Lf", &__v) != 1) 3136 __throw_runtime_error("money_get error"); 3137 } 3138 if (__b == __e) 3139 __err |= ios_base::eofbit; 3140 return __b; 3141} 3142 3143template <class _CharT, class _InputIterator> 3144_InputIterator 3145money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3146 bool __intl, ios_base& __iob, 3147 ios_base::iostate& __err, 3148 string_type& __v) const 3149{ 3150 const int __bz = 100; 3151 char_type __wbuf[__bz]; 3152 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3153 char_type* __wn; 3154 char_type* __we = __wbuf + __bz; 3155 locale __loc = __iob.getloc(); 3156 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3157 bool __neg = false; 3158 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3159 __wb, __wn, __we)) 3160 { 3161 __v.clear(); 3162 if (__neg) 3163 __v.push_back(__ct.widen('-')); 3164 char_type __z = __ct.widen('0'); 3165 char_type* __w; 3166 for (__w = __wb.get(); __w < __wn-1; ++__w) 3167 if (*__w != __z) 3168 break; 3169 __v.append(__w, __wn); 3170 } 3171 if (__b == __e) 3172 __err |= ios_base::eofbit; 3173 return __b; 3174} 3175 3176_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>) 3177_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>) 3178 3179// money_put 3180 3181template <class _CharT> 3182class __money_put 3183{ 3184protected: 3185 typedef _CharT char_type; 3186 typedef basic_string<char_type> string_type; 3187 3188 _LIBCPP_INLINE_VISIBILITY __money_put() {} 3189 3190 static void __gather_info(bool __intl, bool __neg, const locale& __loc, 3191 money_base::pattern& __pat, char_type& __dp, 3192 char_type& __ts, string& __grp, 3193 string_type& __sym, string_type& __sn, 3194 int& __fd); 3195 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me, 3196 ios_base::fmtflags __flags, 3197 const char_type* __db, const char_type* __de, 3198 const ctype<char_type>& __ct, bool __neg, 3199 const money_base::pattern& __pat, char_type __dp, 3200 char_type __ts, const string& __grp, 3201 const string_type& __sym, const string_type& __sn, 3202 int __fd); 3203}; 3204 3205template <class _CharT> 3206void 3207__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc, 3208 money_base::pattern& __pat, char_type& __dp, 3209 char_type& __ts, string& __grp, 3210 string_type& __sym, string_type& __sn, 3211 int& __fd) 3212{ 3213 if (__intl) 3214 { 3215 const moneypunct<char_type, true>& __mp = 3216 use_facet<moneypunct<char_type, true> >(__loc); 3217 if (__neg) 3218 { 3219 __pat = __mp.neg_format(); 3220 __sn = __mp.negative_sign(); 3221 } 3222 else 3223 { 3224 __pat = __mp.pos_format(); 3225 __sn = __mp.positive_sign(); 3226 } 3227 __dp = __mp.decimal_point(); 3228 __ts = __mp.thousands_sep(); 3229 __grp = __mp.grouping(); 3230 __sym = __mp.curr_symbol(); 3231 __fd = __mp.frac_digits(); 3232 } 3233 else 3234 { 3235 const moneypunct<char_type, false>& __mp = 3236 use_facet<moneypunct<char_type, false> >(__loc); 3237 if (__neg) 3238 { 3239 __pat = __mp.neg_format(); 3240 __sn = __mp.negative_sign(); 3241 } 3242 else 3243 { 3244 __pat = __mp.pos_format(); 3245 __sn = __mp.positive_sign(); 3246 } 3247 __dp = __mp.decimal_point(); 3248 __ts = __mp.thousands_sep(); 3249 __grp = __mp.grouping(); 3250 __sym = __mp.curr_symbol(); 3251 __fd = __mp.frac_digits(); 3252 } 3253} 3254 3255template <class _CharT> 3256void 3257__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me, 3258 ios_base::fmtflags __flags, 3259 const char_type* __db, const char_type* __de, 3260 const ctype<char_type>& __ct, bool __neg, 3261 const money_base::pattern& __pat, char_type __dp, 3262 char_type __ts, const string& __grp, 3263 const string_type& __sym, const string_type& __sn, 3264 int __fd) 3265{ 3266 __me = __mb; 3267 for (unsigned __p = 0; __p < 4; ++__p) 3268 { 3269 switch (__pat.field[__p]) 3270 { 3271 case money_base::none: 3272 __mi = __me; 3273 break; 3274 case money_base::space: 3275 __mi = __me; 3276 *__me++ = __ct.widen(' '); 3277 break; 3278 case money_base::sign: 3279 if (!__sn.empty()) 3280 *__me++ = __sn[0]; 3281 break; 3282 case money_base::symbol: 3283 if (!__sym.empty() && (__flags & ios_base::showbase)) 3284 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me); 3285 break; 3286 case money_base::value: 3287 { 3288 // remember start of value so we can reverse it 3289 char_type* __t = __me; 3290 // find beginning of digits 3291 if (__neg) 3292 ++__db; 3293 // find end of digits 3294 const char_type* __d; 3295 for (__d = __db; __d < __de; ++__d) 3296 if (!__ct.is(ctype_base::digit, *__d)) 3297 break; 3298 // print fractional part 3299 if (__fd > 0) 3300 { 3301 int __f; 3302 for (__f = __fd; __d > __db && __f > 0; --__f) 3303 *__me++ = *--__d; 3304 char_type __z = __f > 0 ? __ct.widen('0') : char_type(); 3305 for (; __f > 0; --__f) 3306 *__me++ = __z; 3307 *__me++ = __dp; 3308 } 3309 // print units part 3310 if (__d == __db) 3311 { 3312 *__me++ = __ct.widen('0'); 3313 } 3314 else 3315 { 3316 unsigned __ng = 0; 3317 unsigned __ig = 0; 3318 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() 3319 : static_cast<unsigned>(__grp[__ig]); 3320 while (__d != __db) 3321 { 3322 if (__ng == __gl) 3323 { 3324 *__me++ = __ts; 3325 __ng = 0; 3326 if (++__ig < __grp.size()) 3327 __gl = __grp[__ig] == numeric_limits<char>::max() ? 3328 numeric_limits<unsigned>::max() : 3329 static_cast<unsigned>(__grp[__ig]); 3330 } 3331 *__me++ = *--__d; 3332 ++__ng; 3333 } 3334 } 3335 // reverse it 3336 reverse(__t, __me); 3337 } 3338 break; 3339 } 3340 } 3341 // print rest of sign, if any 3342 if (__sn.size() > 1) 3343 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me); 3344 // set alignment 3345 if ((__flags & ios_base::adjustfield) == ios_base::left) 3346 __mi = __me; 3347 else if ((__flags & ios_base::adjustfield) != ios_base::internal) 3348 __mi = __mb; 3349} 3350 3351_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>) 3352_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>) 3353 3354template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 3355class _LIBCPP_TEMPLATE_VIS money_put 3356 : public locale::facet, 3357 private __money_put<_CharT> 3358{ 3359public: 3360 typedef _CharT char_type; 3361 typedef _OutputIterator iter_type; 3362 typedef basic_string<char_type> string_type; 3363 3364 _LIBCPP_INLINE_VISIBILITY 3365 explicit money_put(size_t __refs = 0) 3366 : locale::facet(__refs) {} 3367 3368 _LIBCPP_INLINE_VISIBILITY 3369 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3370 long double __units) const 3371 { 3372 return do_put(__s, __intl, __iob, __fl, __units); 3373 } 3374 3375 _LIBCPP_INLINE_VISIBILITY 3376 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3377 const string_type& __digits) const 3378 { 3379 return do_put(__s, __intl, __iob, __fl, __digits); 3380 } 3381 3382 static locale::id id; 3383 3384protected: 3385 _LIBCPP_INLINE_VISIBILITY 3386 ~money_put() {} 3387 3388 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3389 char_type __fl, long double __units) const; 3390 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3391 char_type __fl, const string_type& __digits) const; 3392}; 3393 3394template <class _CharT, class _OutputIterator> 3395locale::id 3396money_put<_CharT, _OutputIterator>::id; 3397 3398template <class _CharT, class _OutputIterator> 3399_OutputIterator 3400money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3401 ios_base& __iob, char_type __fl, 3402 long double __units) const 3403{ 3404 // convert to char 3405 const size_t __bs = 100; 3406 char __buf[__bs]; 3407 char* __bb = __buf; 3408 char_type __digits[__bs]; 3409 char_type* __db = __digits; 3410 int __n = snprintf(__bb, __bs, "%.0Lf", __units); 3411 unique_ptr<char, void(*)(void*)> __hn(nullptr, free); 3412 unique_ptr<char_type, void(*)(void*)> __hd(0, free); 3413 // secure memory for digit storage 3414 if (static_cast<size_t>(__n) > __bs-1) 3415 { 3416 __n = __libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); 3417 if (__n == -1) 3418 __throw_bad_alloc(); 3419 __hn.reset(__bb); 3420 __hd.reset((char_type*)malloc(static_cast<size_t>(__n) * sizeof(char_type))); 3421 if (__hd == nullptr) 3422 __throw_bad_alloc(); 3423 __db = __hd.get(); 3424 } 3425 // gather info 3426 locale __loc = __iob.getloc(); 3427 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3428 __ct.widen(__bb, __bb + __n, __db); 3429 bool __neg = __n > 0 && __bb[0] == '-'; 3430 money_base::pattern __pat; 3431 char_type __dp; 3432 char_type __ts; 3433 string __grp; 3434 string_type __sym; 3435 string_type __sn; 3436 int __fd; 3437 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3438 // secure memory for formatting 3439 char_type __mbuf[__bs]; 3440 char_type* __mb = __mbuf; 3441 unique_ptr<char_type, void(*)(void*)> __hw(0, free); 3442 size_t __exn = __n > __fd ? 3443 (static_cast<size_t>(__n) - static_cast<size_t>(__fd)) * 2 + 3444 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 3445 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3446 if (__exn > __bs) 3447 { 3448 __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); 3449 __mb = __hw.get(); 3450 if (__mb == 0) 3451 __throw_bad_alloc(); 3452 } 3453 // format 3454 char_type* __mi; 3455 char_type* __me; 3456 this->__format(__mb, __mi, __me, __iob.flags(), 3457 __db, __db + __n, __ct, 3458 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3459 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3460} 3461 3462template <class _CharT, class _OutputIterator> 3463_OutputIterator 3464money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3465 ios_base& __iob, char_type __fl, 3466 const string_type& __digits) const 3467{ 3468 // gather info 3469 locale __loc = __iob.getloc(); 3470 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3471 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); 3472 money_base::pattern __pat; 3473 char_type __dp; 3474 char_type __ts; 3475 string __grp; 3476 string_type __sym; 3477 string_type __sn; 3478 int __fd; 3479 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3480 // secure memory for formatting 3481 char_type __mbuf[100]; 3482 char_type* __mb = __mbuf; 3483 unique_ptr<char_type, void(*)(void*)> __h(0, free); 3484 size_t __exn = static_cast<int>(__digits.size()) > __fd ? 3485 (__digits.size() - static_cast<size_t>(__fd)) * 2 + 3486 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 3487 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3488 if (__exn > 100) 3489 { 3490 __h.reset((char_type*)malloc(__exn * sizeof(char_type))); 3491 __mb = __h.get(); 3492 if (__mb == 0) 3493 __throw_bad_alloc(); 3494 } 3495 // format 3496 char_type* __mi; 3497 char_type* __me; 3498 this->__format(__mb, __mi, __me, __iob.flags(), 3499 __digits.data(), __digits.data() + __digits.size(), __ct, 3500 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3501 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3502} 3503 3504_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>) 3505_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>) 3506 3507// messages 3508 3509class _LIBCPP_TYPE_VIS messages_base 3510{ 3511public: 3512 typedef ptrdiff_t catalog; 3513 3514 _LIBCPP_INLINE_VISIBILITY messages_base() {} 3515}; 3516 3517template <class _CharT> 3518class _LIBCPP_TEMPLATE_VIS messages 3519 : public locale::facet, 3520 public messages_base 3521{ 3522public: 3523 typedef _CharT char_type; 3524 typedef basic_string<_CharT> string_type; 3525 3526 _LIBCPP_INLINE_VISIBILITY 3527 explicit messages(size_t __refs = 0) 3528 : locale::facet(__refs) {} 3529 3530 _LIBCPP_INLINE_VISIBILITY 3531 catalog open(const basic_string<char>& __nm, const locale& __loc) const 3532 { 3533 return do_open(__nm, __loc); 3534 } 3535 3536 _LIBCPP_INLINE_VISIBILITY 3537 string_type get(catalog __c, int __set, int __msgid, 3538 const string_type& __dflt) const 3539 { 3540 return do_get(__c, __set, __msgid, __dflt); 3541 } 3542 3543 _LIBCPP_INLINE_VISIBILITY 3544 void close(catalog __c) const 3545 { 3546 do_close(__c); 3547 } 3548 3549 static locale::id id; 3550 3551protected: 3552 _LIBCPP_INLINE_VISIBILITY 3553 ~messages() {} 3554 3555 virtual catalog do_open(const basic_string<char>&, const locale&) const; 3556 virtual string_type do_get(catalog, int __set, int __msgid, 3557 const string_type& __dflt) const; 3558 virtual void do_close(catalog) const; 3559}; 3560 3561template <class _CharT> 3562locale::id 3563messages<_CharT>::id; 3564 3565template <class _CharT> 3566typename messages<_CharT>::catalog 3567messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const 3568{ 3569#ifdef _LIBCPP_HAS_CATOPEN 3570 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); 3571 if (__cat != -1) 3572 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); 3573 return __cat; 3574#else // !_LIBCPP_HAS_CATOPEN 3575 (void)__nm; 3576 return -1; 3577#endif // _LIBCPP_HAS_CATOPEN 3578} 3579 3580template <class _CharT> 3581typename messages<_CharT>::string_type 3582messages<_CharT>::do_get(catalog __c, int __set, int __msgid, 3583 const string_type& __dflt) const 3584{ 3585#ifdef _LIBCPP_HAS_CATOPEN 3586 string __ndflt; 3587 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt), 3588 __dflt.c_str(), 3589 __dflt.c_str() + __dflt.size()); 3590 if (__c != -1) 3591 __c <<= 1; 3592 nl_catd __cat = (nl_catd)__c; 3593 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); 3594 string_type __w; 3595 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w), 3596 __n, __n + _VSTD::strlen(__n)); 3597 return __w; 3598#else // !_LIBCPP_HAS_CATOPEN 3599 (void)__c; 3600 (void)__set; 3601 (void)__msgid; 3602 return __dflt; 3603#endif // _LIBCPP_HAS_CATOPEN 3604} 3605 3606template <class _CharT> 3607void 3608messages<_CharT>::do_close(catalog __c) const 3609{ 3610#ifdef _LIBCPP_HAS_CATOPEN 3611 if (__c != -1) 3612 __c <<= 1; 3613 nl_catd __cat = (nl_catd)__c; 3614 catclose(__cat); 3615#else // !_LIBCPP_HAS_CATOPEN 3616 (void)__c; 3617#endif // _LIBCPP_HAS_CATOPEN 3618} 3619 3620_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>) 3621_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>) 3622 3623template <class _CharT> 3624class _LIBCPP_TEMPLATE_VIS messages_byname 3625 : public messages<_CharT> 3626{ 3627public: 3628 typedef messages_base::catalog catalog; 3629 typedef basic_string<_CharT> string_type; 3630 3631 _LIBCPP_INLINE_VISIBILITY 3632 explicit messages_byname(const char*, size_t __refs = 0) 3633 : messages<_CharT>(__refs) {} 3634 3635 _LIBCPP_INLINE_VISIBILITY 3636 explicit messages_byname(const string&, size_t __refs = 0) 3637 : messages<_CharT>(__refs) {} 3638 3639protected: 3640 _LIBCPP_INLINE_VISIBILITY 3641 ~messages_byname() {} 3642}; 3643 3644_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>) 3645_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>) 3646 3647template<class _Codecvt, class _Elem = wchar_t, 3648 class _Wide_alloc = allocator<_Elem>, 3649 class _Byte_alloc = allocator<char> > 3650class _LIBCPP_TEMPLATE_VIS wstring_convert 3651{ 3652public: 3653 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; 3654 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; 3655 typedef typename _Codecvt::state_type state_type; 3656 typedef typename wide_string::traits_type::int_type int_type; 3657 3658private: 3659 byte_string __byte_err_string_; 3660 wide_string __wide_err_string_; 3661 _Codecvt* __cvtptr_; 3662 state_type __cvtstate_; 3663 size_t __cvtcount_; 3664 3665 wstring_convert(const wstring_convert& __wc); 3666 wstring_convert& operator=(const wstring_convert& __wc); 3667public: 3668#ifndef _LIBCPP_CXX03_LANG 3669 _LIBCPP_INLINE_VISIBILITY 3670 wstring_convert() : wstring_convert(new _Codecvt) {} 3671 _LIBCPP_INLINE_VISIBILITY 3672 explicit wstring_convert(_Codecvt* __pcvt); 3673#else 3674 _LIBCPP_INLINE_VISIBILITY 3675 _LIBCPP_EXPLICIT_AFTER_CXX11 3676 wstring_convert(_Codecvt* __pcvt = new _Codecvt); 3677#endif 3678 3679 _LIBCPP_INLINE_VISIBILITY 3680 wstring_convert(_Codecvt* __pcvt, state_type __state); 3681 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err, 3682 const wide_string& __wide_err = wide_string()); 3683#ifndef _LIBCPP_CXX03_LANG 3684 _LIBCPP_INLINE_VISIBILITY 3685 wstring_convert(wstring_convert&& __wc); 3686#endif 3687 ~wstring_convert(); 3688 3689 _LIBCPP_INLINE_VISIBILITY 3690 wide_string from_bytes(char __byte) 3691 {return from_bytes(&__byte, &__byte+1);} 3692 _LIBCPP_INLINE_VISIBILITY 3693 wide_string from_bytes(const char* __ptr) 3694 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));} 3695 _LIBCPP_INLINE_VISIBILITY 3696 wide_string from_bytes(const byte_string& __str) 3697 {return from_bytes(__str.data(), __str.data() + __str.size());} 3698 wide_string from_bytes(const char* __first, const char* __last); 3699 3700 _LIBCPP_INLINE_VISIBILITY 3701 byte_string to_bytes(_Elem __wchar) 3702 {return to_bytes(&__wchar, &__wchar+1);} 3703 _LIBCPP_INLINE_VISIBILITY 3704 byte_string to_bytes(const _Elem* __wptr) 3705 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} 3706 _LIBCPP_INLINE_VISIBILITY 3707 byte_string to_bytes(const wide_string& __wstr) 3708 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} 3709 byte_string to_bytes(const _Elem* __first, const _Elem* __last); 3710 3711 _LIBCPP_INLINE_VISIBILITY 3712 size_t converted() const _NOEXCEPT {return __cvtcount_;} 3713 _LIBCPP_INLINE_VISIBILITY 3714 state_type state() const {return __cvtstate_;} 3715}; 3716 3717template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3718inline 3719wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3720 wstring_convert(_Codecvt* __pcvt) 3721 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) 3722{ 3723} 3724 3725template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3726inline 3727wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3728 wstring_convert(_Codecvt* __pcvt, state_type __state) 3729 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) 3730{ 3731} 3732 3733template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3734wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3735 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) 3736 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), 3737 __cvtstate_(), __cvtcount_(0) 3738{ 3739 __cvtptr_ = new _Codecvt; 3740} 3741 3742#ifndef _LIBCPP_CXX03_LANG 3743 3744template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3745inline 3746wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3747 wstring_convert(wstring_convert&& __wc) 3748 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), 3749 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), 3750 __cvtptr_(__wc.__cvtptr_), 3751 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_) 3752{ 3753 __wc.__cvtptr_ = nullptr; 3754} 3755 3756#endif // _LIBCPP_CXX03_LANG 3757 3758template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3759wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() 3760{ 3761 delete __cvtptr_; 3762} 3763 3764template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3765typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string 3766wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3767 from_bytes(const char* __frm, const char* __frm_end) 3768{ 3769 __cvtcount_ = 0; 3770 if (__cvtptr_ != nullptr) 3771 { 3772 wide_string __ws(2*(__frm_end - __frm), _Elem()); 3773 if (__frm != __frm_end) 3774 __ws.resize(__ws.capacity()); 3775 codecvt_base::result __r = codecvt_base::ok; 3776 state_type __st = __cvtstate_; 3777 if (__frm != __frm_end) 3778 { 3779 _Elem* __to = &__ws[0]; 3780 _Elem* __to_end = __to + __ws.size(); 3781 const char* __frm_nxt; 3782 do 3783 { 3784 _Elem* __to_nxt; 3785 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, 3786 __to, __to_end, __to_nxt); 3787 __cvtcount_ += __frm_nxt - __frm; 3788 if (__frm_nxt == __frm) 3789 { 3790 __r = codecvt_base::error; 3791 } 3792 else if (__r == codecvt_base::noconv) 3793 { 3794 __ws.resize(__to - &__ws[0]); 3795 // This only gets executed if _Elem is char 3796 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); 3797 __frm = __frm_nxt; 3798 __r = codecvt_base::ok; 3799 } 3800 else if (__r == codecvt_base::ok) 3801 { 3802 __ws.resize(__to_nxt - &__ws[0]); 3803 __frm = __frm_nxt; 3804 } 3805 else if (__r == codecvt_base::partial) 3806 { 3807 ptrdiff_t __s = __to_nxt - &__ws[0]; 3808 __ws.resize(2 * __s); 3809 __to = &__ws[0] + __s; 3810 __to_end = &__ws[0] + __ws.size(); 3811 __frm = __frm_nxt; 3812 } 3813 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 3814 } 3815 if (__r == codecvt_base::ok) 3816 return __ws; 3817 } 3818 3819 if (__wide_err_string_.empty()) 3820 __throw_range_error("wstring_convert: from_bytes error"); 3821 3822 return __wide_err_string_; 3823} 3824 3825template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3826typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string 3827wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3828 to_bytes(const _Elem* __frm, const _Elem* __frm_end) 3829{ 3830 __cvtcount_ = 0; 3831 if (__cvtptr_ != nullptr) 3832 { 3833 byte_string __bs(2*(__frm_end - __frm), char()); 3834 if (__frm != __frm_end) 3835 __bs.resize(__bs.capacity()); 3836 codecvt_base::result __r = codecvt_base::ok; 3837 state_type __st = __cvtstate_; 3838 if (__frm != __frm_end) 3839 { 3840 char* __to = &__bs[0]; 3841 char* __to_end = __to + __bs.size(); 3842 const _Elem* __frm_nxt; 3843 do 3844 { 3845 char* __to_nxt; 3846 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, 3847 __to, __to_end, __to_nxt); 3848 __cvtcount_ += __frm_nxt - __frm; 3849 if (__frm_nxt == __frm) 3850 { 3851 __r = codecvt_base::error; 3852 } 3853 else if (__r == codecvt_base::noconv) 3854 { 3855 __bs.resize(__to - &__bs[0]); 3856 // This only gets executed if _Elem is char 3857 __bs.append((const char*)__frm, (const char*)__frm_end); 3858 __frm = __frm_nxt; 3859 __r = codecvt_base::ok; 3860 } 3861 else if (__r == codecvt_base::ok) 3862 { 3863 __bs.resize(__to_nxt - &__bs[0]); 3864 __frm = __frm_nxt; 3865 } 3866 else if (__r == codecvt_base::partial) 3867 { 3868 ptrdiff_t __s = __to_nxt - &__bs[0]; 3869 __bs.resize(2 * __s); 3870 __to = &__bs[0] + __s; 3871 __to_end = &__bs[0] + __bs.size(); 3872 __frm = __frm_nxt; 3873 } 3874 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 3875 } 3876 if (__r == codecvt_base::ok) 3877 { 3878 size_t __s = __bs.size(); 3879 __bs.resize(__bs.capacity()); 3880 char* __to = &__bs[0] + __s; 3881 char* __to_end = __to + __bs.size(); 3882 do 3883 { 3884 char* __to_nxt; 3885 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); 3886 if (__r == codecvt_base::noconv) 3887 { 3888 __bs.resize(__to - &__bs[0]); 3889 __r = codecvt_base::ok; 3890 } 3891 else if (__r == codecvt_base::ok) 3892 { 3893 __bs.resize(__to_nxt - &__bs[0]); 3894 } 3895 else if (__r == codecvt_base::partial) 3896 { 3897 ptrdiff_t __sp = __to_nxt - &__bs[0]; 3898 __bs.resize(2 * __sp); 3899 __to = &__bs[0] + __sp; 3900 __to_end = &__bs[0] + __bs.size(); 3901 } 3902 } while (__r == codecvt_base::partial); 3903 if (__r == codecvt_base::ok) 3904 return __bs; 3905 } 3906 } 3907 3908 if (__byte_err_string_.empty()) 3909 __throw_range_error("wstring_convert: to_bytes error"); 3910 3911 return __byte_err_string_; 3912} 3913 3914template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> > 3915class _LIBCPP_TEMPLATE_VIS wbuffer_convert 3916 : public basic_streambuf<_Elem, _Tr> 3917{ 3918public: 3919 // types: 3920 typedef _Elem char_type; 3921 typedef _Tr traits_type; 3922 typedef typename traits_type::int_type int_type; 3923 typedef typename traits_type::pos_type pos_type; 3924 typedef typename traits_type::off_type off_type; 3925 typedef typename _Codecvt::state_type state_type; 3926 3927private: 3928 char* __extbuf_; 3929 const char* __extbufnext_; 3930 const char* __extbufend_; 3931 char __extbuf_min_[8]; 3932 size_t __ebs_; 3933 char_type* __intbuf_; 3934 size_t __ibs_; 3935 streambuf* __bufptr_; 3936 _Codecvt* __cv_; 3937 state_type __st_; 3938 ios_base::openmode __cm_; 3939 bool __owns_eb_; 3940 bool __owns_ib_; 3941 bool __always_noconv_; 3942 3943 wbuffer_convert(const wbuffer_convert&); 3944 wbuffer_convert& operator=(const wbuffer_convert&); 3945 3946public: 3947#ifndef _LIBCPP_CXX03_LANG 3948 wbuffer_convert() : wbuffer_convert(nullptr) {} 3949 explicit wbuffer_convert(streambuf* __bytebuf, 3950 _Codecvt* __pcvt = new _Codecvt, 3951 state_type __state = state_type()); 3952#else 3953 _LIBCPP_EXPLICIT_AFTER_CXX11 3954 wbuffer_convert(streambuf* __bytebuf = nullptr, 3955 _Codecvt* __pcvt = new _Codecvt, 3956 state_type __state = state_type()); 3957#endif 3958 3959 ~wbuffer_convert(); 3960 3961 _LIBCPP_INLINE_VISIBILITY 3962 streambuf* rdbuf() const {return __bufptr_;} 3963 _LIBCPP_INLINE_VISIBILITY 3964 streambuf* rdbuf(streambuf* __bytebuf) 3965 { 3966 streambuf* __r = __bufptr_; 3967 __bufptr_ = __bytebuf; 3968 return __r; 3969 } 3970 3971 _LIBCPP_INLINE_VISIBILITY 3972 state_type state() const {return __st_;} 3973 3974protected: 3975 virtual int_type underflow(); 3976 virtual int_type pbackfail(int_type __c = traits_type::eof()); 3977 virtual int_type overflow (int_type __c = traits_type::eof()); 3978 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, 3979 streamsize __n); 3980 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 3981 ios_base::openmode __wch = ios_base::in | ios_base::out); 3982 virtual pos_type seekpos(pos_type __sp, 3983 ios_base::openmode __wch = ios_base::in | ios_base::out); 3984 virtual int sync(); 3985 3986private: 3987 bool __read_mode(); 3988 void __write_mode(); 3989 wbuffer_convert* __close(); 3990}; 3991 3992template <class _Codecvt, class _Elem, class _Tr> 3993wbuffer_convert<_Codecvt, _Elem, _Tr>:: 3994 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) 3995 : __extbuf_(nullptr), 3996 __extbufnext_(nullptr), 3997 __extbufend_(nullptr), 3998 __ebs_(0), 3999 __intbuf_(0), 4000 __ibs_(0), 4001 __bufptr_(__bytebuf), 4002 __cv_(__pcvt), 4003 __st_(__state), 4004 __cm_(0), 4005 __owns_eb_(false), 4006 __owns_ib_(false), 4007 __always_noconv_(__cv_ ? __cv_->always_noconv() : false) 4008{ 4009 setbuf(0, 4096); 4010} 4011 4012template <class _Codecvt, class _Elem, class _Tr> 4013wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() 4014{ 4015 __close(); 4016 delete __cv_; 4017 if (__owns_eb_) 4018 delete [] __extbuf_; 4019 if (__owns_ib_) 4020 delete [] __intbuf_; 4021} 4022 4023template <class _Codecvt, class _Elem, class _Tr> 4024typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4025wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() 4026{ 4027 if (__cv_ == 0 || __bufptr_ == 0) 4028 return traits_type::eof(); 4029 bool __initial = __read_mode(); 4030 char_type __1buf; 4031 if (this->gptr() == 0) 4032 this->setg(&__1buf, &__1buf+1, &__1buf+1); 4033 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4); 4034 int_type __c = traits_type::eof(); 4035 if (this->gptr() == this->egptr()) 4036 { 4037 _VSTD::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 4038 if (__always_noconv_) 4039 { 4040 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz); 4041 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); 4042 if (__nmemb != 0) 4043 { 4044 this->setg(this->eback(), 4045 this->eback() + __unget_sz, 4046 this->eback() + __unget_sz + __nmemb); 4047 __c = *this->gptr(); 4048 } 4049 } 4050 else 4051 { 4052 _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); 4053 if (__extbufend_ != __extbufnext_) 4054 _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 4055 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 4056 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 4057 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), 4058 static_cast<streamsize>(__extbufend_ - __extbufnext_)); 4059 codecvt_base::result __r; 4060 // FIXME: Do we ever need to restore the state here? 4061 //state_type __svs = __st_; 4062 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); 4063 if (__nr != 0) 4064 { 4065 __extbufend_ = __extbufnext_ + __nr; 4066 char_type* __inext; 4067 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, 4068 this->eback() + __unget_sz, 4069 this->egptr(), __inext); 4070 if (__r == codecvt_base::noconv) 4071 { 4072 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, 4073 (char_type*) const_cast<char *>(__extbufend_)); 4074 __c = *this->gptr(); 4075 } 4076 else if (__inext != this->eback() + __unget_sz) 4077 { 4078 this->setg(this->eback(), this->eback() + __unget_sz, __inext); 4079 __c = *this->gptr(); 4080 } 4081 } 4082 } 4083 } 4084 else 4085 __c = *this->gptr(); 4086 if (this->eback() == &__1buf) 4087 this->setg(0, 0, 0); 4088 return __c; 4089} 4090 4091template <class _Codecvt, class _Elem, class _Tr> 4092typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4093wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) 4094{ 4095 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr()) 4096 { 4097 if (traits_type::eq_int_type(__c, traits_type::eof())) 4098 { 4099 this->gbump(-1); 4100 return traits_type::not_eof(__c); 4101 } 4102 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) 4103 { 4104 this->gbump(-1); 4105 *this->gptr() = traits_type::to_char_type(__c); 4106 return __c; 4107 } 4108 } 4109 return traits_type::eof(); 4110} 4111 4112template <class _Codecvt, class _Elem, class _Tr> 4113typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4114wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) 4115{ 4116 if (__cv_ == 0 || __bufptr_ == 0) 4117 return traits_type::eof(); 4118 __write_mode(); 4119 char_type __1buf; 4120 char_type* __pb_save = this->pbase(); 4121 char_type* __epb_save = this->epptr(); 4122 if (!traits_type::eq_int_type(__c, traits_type::eof())) 4123 { 4124 if (this->pptr() == 0) 4125 this->setp(&__1buf, &__1buf+1); 4126 *this->pptr() = traits_type::to_char_type(__c); 4127 this->pbump(1); 4128 } 4129 if (this->pptr() != this->pbase()) 4130 { 4131 if (__always_noconv_) 4132 { 4133 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase()); 4134 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4135 return traits_type::eof(); 4136 } 4137 else 4138 { 4139 char* __extbe = __extbuf_; 4140 codecvt_base::result __r; 4141 do 4142 { 4143 const char_type* __e; 4144 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, 4145 __extbuf_, __extbuf_ + __ebs_, __extbe); 4146 if (__e == this->pbase()) 4147 return traits_type::eof(); 4148 if (__r == codecvt_base::noconv) 4149 { 4150 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 4151 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4152 return traits_type::eof(); 4153 } 4154 else if (__r == codecvt_base::ok || __r == codecvt_base::partial) 4155 { 4156 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_); 4157 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4158 return traits_type::eof(); 4159 if (__r == codecvt_base::partial) 4160 { 4161 this->setp(const_cast<char_type *>(__e), this->pptr()); 4162 this->__pbump(this->epptr() - this->pbase()); 4163 } 4164 } 4165 else 4166 return traits_type::eof(); 4167 } while (__r == codecvt_base::partial); 4168 } 4169 this->setp(__pb_save, __epb_save); 4170 } 4171 return traits_type::not_eof(__c); 4172} 4173 4174template <class _Codecvt, class _Elem, class _Tr> 4175basic_streambuf<_Elem, _Tr>* 4176wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) 4177{ 4178 this->setg(0, 0, 0); 4179 this->setp(0, 0); 4180 if (__owns_eb_) 4181 delete [] __extbuf_; 4182 if (__owns_ib_) 4183 delete [] __intbuf_; 4184 __ebs_ = __n; 4185 if (__ebs_ > sizeof(__extbuf_min_)) 4186 { 4187 if (__always_noconv_ && __s) 4188 { 4189 __extbuf_ = (char*)__s; 4190 __owns_eb_ = false; 4191 } 4192 else 4193 { 4194 __extbuf_ = new char[__ebs_]; 4195 __owns_eb_ = true; 4196 } 4197 } 4198 else 4199 { 4200 __extbuf_ = __extbuf_min_; 4201 __ebs_ = sizeof(__extbuf_min_); 4202 __owns_eb_ = false; 4203 } 4204 if (!__always_noconv_) 4205 { 4206 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 4207 if (__s && __ibs_ >= sizeof(__extbuf_min_)) 4208 { 4209 __intbuf_ = __s; 4210 __owns_ib_ = false; 4211 } 4212 else 4213 { 4214 __intbuf_ = new char_type[__ibs_]; 4215 __owns_ib_ = true; 4216 } 4217 } 4218 else 4219 { 4220 __ibs_ = 0; 4221 __intbuf_ = 0; 4222 __owns_ib_ = false; 4223 } 4224 return this; 4225} 4226 4227template <class _Codecvt, class _Elem, class _Tr> 4228typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4229wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, 4230 ios_base::openmode __om) 4231{ 4232 int __width = __cv_->encoding(); 4233 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync()) 4234 return pos_type(off_type(-1)); 4235 // __width > 0 || __off == 0, now check __way 4236 if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end) 4237 return pos_type(off_type(-1)); 4238 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); 4239 __r.state(__st_); 4240 return __r; 4241} 4242 4243template <class _Codecvt, class _Elem, class _Tr> 4244typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4245wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) 4246{ 4247 if (__cv_ == 0 || __bufptr_ == 0 || sync()) 4248 return pos_type(off_type(-1)); 4249 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) 4250 return pos_type(off_type(-1)); 4251 return __sp; 4252} 4253 4254template <class _Codecvt, class _Elem, class _Tr> 4255int 4256wbuffer_convert<_Codecvt, _Elem, _Tr>::sync() 4257{ 4258 if (__cv_ == 0 || __bufptr_ == 0) 4259 return 0; 4260 if (__cm_ & ios_base::out) 4261 { 4262 if (this->pptr() != this->pbase()) 4263 if (overflow() == traits_type::eof()) 4264 return -1; 4265 codecvt_base::result __r; 4266 do 4267 { 4268 char* __extbe; 4269 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 4270 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_); 4271 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4272 return -1; 4273 } while (__r == codecvt_base::partial); 4274 if (__r == codecvt_base::error) 4275 return -1; 4276 if (__bufptr_->pubsync()) 4277 return -1; 4278 } 4279 else if (__cm_ & ios_base::in) 4280 { 4281 off_type __c; 4282 if (__always_noconv_) 4283 __c = this->egptr() - this->gptr(); 4284 else 4285 { 4286 int __width = __cv_->encoding(); 4287 __c = __extbufend_ - __extbufnext_; 4288 if (__width > 0) 4289 __c += __width * (this->egptr() - this->gptr()); 4290 else 4291 { 4292 if (this->gptr() != this->egptr()) 4293 { 4294 reverse(this->gptr(), this->egptr()); 4295 codecvt_base::result __r; 4296 const char_type* __e = this->gptr(); 4297 char* __extbe; 4298 do 4299 { 4300 __r = __cv_->out(__st_, __e, this->egptr(), __e, 4301 __extbuf_, __extbuf_ + __ebs_, __extbe); 4302 switch (__r) 4303 { 4304 case codecvt_base::noconv: 4305 __c += this->egptr() - this->gptr(); 4306 break; 4307 case codecvt_base::ok: 4308 case codecvt_base::partial: 4309 __c += __extbe - __extbuf_; 4310 break; 4311 default: 4312 return -1; 4313 } 4314 } while (__r == codecvt_base::partial); 4315 } 4316 } 4317 } 4318 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) 4319 return -1; 4320 this->setg(0, 0, 0); 4321 __cm_ = 0; 4322 } 4323 return 0; 4324} 4325 4326template <class _Codecvt, class _Elem, class _Tr> 4327bool 4328wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() 4329{ 4330 if (!(__cm_ & ios_base::in)) 4331 { 4332 this->setp(0, 0); 4333 if (__always_noconv_) 4334 this->setg((char_type*)__extbuf_, 4335 (char_type*)__extbuf_ + __ebs_, 4336 (char_type*)__extbuf_ + __ebs_); 4337 else 4338 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 4339 __cm_ = ios_base::in; 4340 return true; 4341 } 4342 return false; 4343} 4344 4345template <class _Codecvt, class _Elem, class _Tr> 4346void 4347wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() 4348{ 4349 if (!(__cm_ & ios_base::out)) 4350 { 4351 this->setg(0, 0, 0); 4352 if (__ebs_ > sizeof(__extbuf_min_)) 4353 { 4354 if (__always_noconv_) 4355 this->setp((char_type*)__extbuf_, 4356 (char_type*)__extbuf_ + (__ebs_ - 1)); 4357 else 4358 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 4359 } 4360 else 4361 this->setp(0, 0); 4362 __cm_ = ios_base::out; 4363 } 4364} 4365 4366template <class _Codecvt, class _Elem, class _Tr> 4367wbuffer_convert<_Codecvt, _Elem, _Tr>* 4368wbuffer_convert<_Codecvt, _Elem, _Tr>::__close() 4369{ 4370 wbuffer_convert* __rt = nullptr; 4371 if (__cv_ != nullptr && __bufptr_ != nullptr) 4372 { 4373 __rt = this; 4374 if ((__cm_ & ios_base::out) && sync()) 4375 __rt = nullptr; 4376 } 4377 return __rt; 4378} 4379 4380_LIBCPP_END_NAMESPACE_STD 4381 4382_LIBCPP_POP_MACROS 4383 4384#endif // _LIBCPP_LOCALE 4385