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