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