blob: 8e584005da08a9917be0912bec6498458f0d2658 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===-------------------------- locale ------------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_LOCALE
11#define _LIBCPP_LOCALE
12
13/*
14 locale synopsis
15
16namespace std
17{
18
19class locale
20{
21public:
22 // types:
23 class facet;
24 class id;
25
26 typedef int category;
27 static const category // values assigned here are for exposition only
28 none = 0x000,
29 collate = 0x010,
30 ctype = 0x020,
31 monetary = 0x040,
32 numeric = 0x080,
33 time = 0x100,
34 messages = 0x200,
35 all = collate | ctype | monetary | numeric | time | messages;
36
37 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +000038 locale() noexcept;
39 locale(const locale& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000040 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
Howard Hinnant7c9e5732011-05-31 15:34:58 +000047 ~locale(); // not virtual
Howard Hinnantc51e1022010-05-11 19:42:16 +000048
Howard Hinnant7c9e5732011-05-31 15:34:58 +000049 const locale& operator=(const locale& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000050
51 template <class Facet> locale combine(const locale& other) const;
52
53 // locale operations:
54 basic_string<char> name() const;
55 bool operator==(const locale& other) const;
56 bool operator!=(const locale& other) const;
57 template <class charT, class Traits, class Allocator>
58 bool operator()(const basic_string<charT,Traits,Allocator>& s1,
59 const basic_string<charT,Traits,Allocator>& s2) const;
60
61 // global locale objects:
62 static locale global(const locale&);
63 static const locale& classic();
64};
65
66template <class Facet> const Facet& use_facet(const locale&);
Howard Hinnant7c9e5732011-05-31 15:34:58 +000067template <class Facet> bool has_facet(const locale&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000068
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);
Howard Hinnant9dd7e892010-05-31 20:58:54 +000083
84template<class Codecvt, class Elem = wchar_t,
85 class Wide_alloc = allocator<Elem>,
86 class Byte_alloc = allocator<char>>
87class wstring_convert
88{
89public:
90 typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
91 typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
92 typedef typename Codecvt::state_type state_type;
93 typedef typename wide_string::traits_type::int_type int_type;
94
Marek Kurdejcd0bd6a2021-01-19 08:21:09 +010095 wstring_convert(Codecvt* pcvt = new Codecvt); // before C++14
96 explicit wstring_convert(Codecvt* pcvt = new Codecvt); // before C++20
97 wstring_convert() : wstring_convert(new Codecvt) {} // C++20
98 explicit wstring_convert(Codecvt* pcvt); // C++20
99
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000100 wstring_convert(Codecvt* pcvt, state_type state);
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000101 explicit wstring_convert(const byte_string& byte_err, // explicit in C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000102 const wide_string& wide_err = wide_string());
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000103 wstring_convert(const wstring_convert&) = delete; // C++14
104 wstring_convert & operator=(const wstring_convert &) = delete; // C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000105 ~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
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000117 size_t converted() const; // noexcept in C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000118 state_type state() const;
119};
120
Howard Hinnantc51e1022010-05-11 19:42:16 +0000121template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000122class wbuffer_convert
123 : public basic_streambuf<Elem, Tr>
124{
125public:
126 typedef typename Tr::state_type state_type;
127
Marek Kurdejcd0bd6a2021-01-19 08:21:09 +0100128 wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
129 state_type state = state_type()); // before C++14
130 explicit wbuffer_convert(streambuf* bytebuf = nullptr, Codecvt* pcvt = new Codecvt,
131 state_type state = state_type()); // before C++20
132 wbuffer_convert() : wbuffer_convert(nullptr) {} // C++20
133 explicit wbuffer_convert(streambuf* bytebuf, Codecvt* pcvt = new Codecvt,
134 state_type state = state_type()); // C++20
135
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000136 wbuffer_convert(const wbuffer_convert&) = delete; // C++14
137 wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14
138 ~wbuffer_convert(); // C++14
Louis Dionne173f29e2019-05-29 16:01:36 +0000139
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000140 streambuf* rdbuf() const;
141 streambuf* rdbuf(streambuf* bytebuf);
142
143 state_type state() const;
144};
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145
146// 22.4.1 and 22.4.1.3, ctype:
147class ctype_base;
148template <class charT> class ctype;
149template <> class ctype<char>; // specialization
150template <class charT> class ctype_byname;
151template <> class ctype_byname<char>; // specialization
152
153class codecvt_base;
154template <class internT, class externT, class stateT> class codecvt;
155template <class internT, class externT, class stateT> class codecvt_byname;
156
157// 22.4.2 and 22.4.3, numeric:
158template <class charT, class InputIterator> class num_get;
159template <class charT, class OutputIterator> class num_put;
160template <class charT> class numpunct;
161template <class charT> class numpunct_byname;
162
163// 22.4.4, col lation:
164template <class charT> class collate;
165template <class charT> class collate_byname;
166
167// 22.4.5, date and time:
168class time_base;
169template <class charT, class InputIterator> class time_get;
170template <class charT, class InputIterator> class time_get_byname;
171template <class charT, class OutputIterator> class time_put;
172template <class charT, class OutputIterator> class time_put_byname;
173
174// 22.4.6, money:
175class money_base;
176template <class charT, class InputIterator> class money_get;
177template <class charT, class OutputIterator> class money_put;
178template <class charT, bool Intl> class moneypunct;
179template <class charT, bool Intl> class moneypunct_byname;
180
181// 22.4.7, message retrieval:
182class messages_base;
183template <class charT> class messages;
184template <class charT> class messages_byname;
185
186} // std
187
188*/
189
190#include <__config>
Eric Fiselier98e428d2016-06-19 06:58:22 +0000191#include <__debug>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400192#include <__locale>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000193#include <algorithm>
Marshall Clowdde4bfe2013-03-18 17:45:34 +0000194#ifndef __APPLE__
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400195# include <cstdarg>
Howard Hinnant155c2af2010-05-24 17:49:41 +0000196#endif
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400197#include <cstdio>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000198#include <cstdlib>
199#include <ctime>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400200#include <ios>
201#include <iterator>
202#include <limits>
203#include <memory>
204#include <streambuf>
205#include <version>
Mara Sophie Grosch60cbba82021-04-12 14:19:51 -0400206
207#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
208// Most unix variants have catopen. These are the specific ones that don't.
209# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION)
210# define _LIBCPP_HAS_CATOPEN 1
211# include <nl_types.h>
212# endif
Marshall Clow3477ec92014-07-10 15:20:28 +0000213#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000214
Ben Craig3756b922016-03-09 15:39:39 +0000215#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
216#include <__bsd_locale_defaults.h>
217#else
218#include <__bsd_locale_fallbacks.h>
219#endif
220
Eric Fiselierf4433a32017-05-31 22:07:49 +0000221#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
222#pragma GCC system_header
223#endif
224
225_LIBCPP_PUSH_MACROS
226#include <__undef_macros>
227
228
Howard Hinnantc51e1022010-05-11 19:42:16 +0000229_LIBCPP_BEGIN_NAMESPACE_STD
230
Marshall Clow82378c02013-03-18 19:34:07 +0000231#if defined(__APPLE__) || defined(__FreeBSD__)
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000232# define _LIBCPP_GET_C_LOCALE 0
Ed Schoutenaa497c82015-03-10 09:35:22 +0000233#elif defined(__CloudABI__) || defined(__NetBSD__)
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000234# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000235#else
236# define _LIBCPP_GET_C_LOCALE __cloc()
Howard Hinnantf312e3e2011-09-28 23:39:33 +0000237 // Get the C locale object
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000238 _LIBCPP_FUNC_VIS locale_t __cloc();
Howard Hinnantf312e3e2011-09-28 23:39:33 +0000239#define __cloc_defined
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000240#endif
241
Howard Hinnantc51e1022010-05-11 19:42:16 +0000242// __scan_keyword
243// Scans [__b, __e) until a match is found in the basic_strings range
244// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
245// __b will be incremented (visibly), consuming CharT until a match is found
246// or proved to not exist. A keyword may be "", in which will match anything.
247// If one keyword is a prefix of another, and the next CharT in the input
248// might match another keyword, the algorithm will attempt to find the longest
249// matching keyword. If the longer matching keyword ends up not matching, then
250// no keyword match is found. If no keyword match is found, __ke is returned
251// and failbit is set in __err.
252// Else an iterator pointing to the matching keyword is found. If more than
253// one keyword matches, an iterator to the first matching keyword is returned.
Alp Tokerb8a95f52014-05-15 11:27:39 +0000254// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000255// __ct is used to force to lower case before comparing characters.
256// Examples:
257// Keywords: "a", "abb"
258// If the input is "a", the first keyword matches and eofbit is set.
259// If the input is "abc", no match is found and "ab" are consumed.
260template <class _InputIterator, class _ForwardIterator, class _Ctype>
261_LIBCPP_HIDDEN
262_ForwardIterator
263__scan_keyword(_InputIterator& __b, _InputIterator __e,
264 _ForwardIterator __kb, _ForwardIterator __ke,
265 const _Ctype& __ct, ios_base::iostate& __err,
266 bool __case_sensitive = true)
267{
268 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
Howard Hinnant28b24882011-12-01 20:21:04 +0000269 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000270 const unsigned char __doesnt_match = '\0';
271 const unsigned char __might_match = '\1';
272 const unsigned char __does_match = '\2';
273 unsigned char __statbuf[100];
274 unsigned char* __status = __statbuf;
Bruce Mitchener170d8972020-11-24 12:53:53 -0500275 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(nullptr, free);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000276 if (__nkw > sizeof(__statbuf))
277 {
278 __status = (unsigned char*)malloc(__nkw);
Bruce Mitchener170d8972020-11-24 12:53:53 -0500279 if (__status == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000280 __throw_bad_alloc();
281 __stat_hold.reset(__status);
282 }
283 size_t __n_might_match = __nkw; // At this point, any keyword might match
284 size_t __n_does_match = 0; // but none of them definitely do
285 // Initialize all statuses to __might_match, except for "" keywords are __does_match
286 unsigned char* __st = __status;
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000287 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288 {
289 if (!__ky->empty())
290 *__st = __might_match;
291 else
292 {
293 *__st = __does_match;
294 --__n_might_match;
295 ++__n_does_match;
296 }
297 }
298 // While there might be a match, test keywords against the next CharT
299 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
300 {
301 // Peek at the next CharT but don't consume it
302 _CharT __c = *__b;
303 if (!__case_sensitive)
304 __c = __ct.toupper(__c);
305 bool __consume = false;
306 // For each keyword which might match, see if the __indx character is __c
307 // If a match if found, consume __c
308 // If a match is found, and that is the last character in the keyword,
309 // then that keyword matches.
310 // If the keyword doesn't match this character, then change the keyword
311 // to doesn't match
312 __st = __status;
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000313 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000314 {
315 if (*__st == __might_match)
316 {
317 _CharT __kc = (*__ky)[__indx];
318 if (!__case_sensitive)
319 __kc = __ct.toupper(__kc);
320 if (__c == __kc)
321 {
322 __consume = true;
323 if (__ky->size() == __indx+1)
324 {
325 *__st = __does_match;
326 --__n_might_match;
327 ++__n_does_match;
328 }
329 }
330 else
331 {
332 *__st = __doesnt_match;
333 --__n_might_match;
334 }
335 }
336 }
337 // consume if we matched a character
338 if (__consume)
339 {
340 ++__b;
341 // If we consumed a character and there might be a matched keyword that
342 // was marked matched on a previous iteration, then such keywords
343 // which are now marked as not matching.
344 if (__n_might_match + __n_does_match > 1)
345 {
346 __st = __status;
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000347 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000348 {
349 if (*__st == __does_match && __ky->size() != __indx+1)
350 {
351 *__st = __doesnt_match;
352 --__n_does_match;
353 }
354 }
355 }
356 }
357 }
358 // We've exited the loop because we hit eof and/or we have no more "might matches".
359 if (__b == __e)
360 __err |= ios_base::eofbit;
361 // Return the first matching result
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000362 for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000363 if (*__st == __does_match)
364 break;
365 if (__kb == __ke)
366 __err |= ios_base::failbit;
367 return __kb;
368}
369
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000370struct _LIBCPP_TYPE_VIS __num_get_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000371{
372 static const int __num_get_buf_sz = 40;
373
374 static int __get_base(ios_base&);
375 static const char __src[33];
376};
377
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000378_LIBCPP_FUNC_VIS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000379void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
380 ios_base::iostate& __err);
381
Howard Hinnantc51e1022010-05-11 19:42:16 +0000382template <class _CharT>
383struct __num_get
384 : protected __num_get_base
385{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
387 _CharT& __thousands_sep);
Aditya Kumaraa866182017-06-14 23:17:45 +0000388
Howard Hinnantc51e1022010-05-11 19:42:16 +0000389 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
390 char* __a, char*& __a_end,
391 _CharT __decimal_point, _CharT __thousands_sep,
392 const string& __grouping, unsigned* __g,
393 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
Aditya Kumaraa866182017-06-14 23:17:45 +0000394#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
395 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
396 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
397 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
398 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
399
400#else
401 static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep)
402 {
403 locale __loc = __iob.getloc();
404 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
405 __thousands_sep = __np.thousands_sep();
406 return __np.grouping();
407 }
408
409 const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const
410 {
411 return __do_widen_p(__iob, __atoms);
412 }
413
414
415 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
416 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
417 unsigned* __g, unsigned*& __g_end, const _CharT* __atoms);
418private:
419 template<typename T>
420 const T* __do_widen_p(ios_base& __iob, T* __atoms) const
421 {
422 locale __loc = __iob.getloc();
423 use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms);
424 return __atoms;
425 }
426
427 const char* __do_widen_p(ios_base& __iob, char* __atoms) const
428 {
429 (void)__iob;
430 (void)__atoms;
431 return __src;
432 }
433#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000434};
435
Aditya Kumaraa866182017-06-14 23:17:45 +0000436#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
Howard Hinnantc51e1022010-05-11 19:42:16 +0000437template <class _CharT>
438string
439__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
440{
441 locale __loc = __iob.getloc();
442 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
443 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
444 __thousands_sep = __np.thousands_sep();
445 return __np.grouping();
446}
Aditya Kumaraa866182017-06-14 23:17:45 +0000447#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000448
449template <class _CharT>
450string
451__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
452 _CharT& __thousands_sep)
453{
454 locale __loc = __iob.getloc();
455 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
456 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
457 __decimal_point = __np.decimal_point();
458 __thousands_sep = __np.thousands_sep();
459 return __np.grouping();
460}
461
462template <class _CharT>
463int
Aditya Kumaraa866182017-06-14 23:17:45 +0000464#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
Howard Hinnantc51e1022010-05-11 19:42:16 +0000465__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
466 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
467 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
Aditya Kumaraa866182017-06-14 23:17:45 +0000468#else
469__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
470 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
471 unsigned* __g, unsigned*& __g_end, const _CharT* __atoms)
472
473#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474{
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000475 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
476 {
477 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
478 __dc = 0;
479 return 0;
480 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000481 if (__grouping.size() != 0 && __ct == __thousands_sep)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000482 {
483 if (__g_end-__g < __num_get_buf_sz)
484 {
485 *__g_end++ = __dc;
486 __dc = 0;
487 }
488 return 0;
489 }
490 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000491 if (__f >= 24)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000492 return -1;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000493 switch (__base)
494 {
495 case 8:
496 case 10:
497 if (__f >= __base)
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000498 return -1;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000499 break;
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000500 case 16:
501 if (__f < 22)
502 break;
503 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
504 {
505 __dc = 0;
506 *__a_end++ = __src[__f];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000507 return 0;
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000508 }
509 return -1;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000510 }
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000511 *__a_end++ = __src[__f];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000512 ++__dc;
513 return 0;
514}
515
516template <class _CharT>
517int
518__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
519 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
520 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
521{
522 if (__ct == __decimal_point)
523 {
524 if (!__in_units)
525 return -1;
526 __in_units = false;
527 *__a_end++ = '.';
528 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
529 *__g_end++ = __dc;
530 return 0;
531 }
532 if (__ct == __thousands_sep && __grouping.size() != 0)
533 {
534 if (!__in_units)
535 return -1;
536 if (__g_end-__g < __num_get_buf_sz)
537 {
538 *__g_end++ = __dc;
539 __dc = 0;
540 }
541 return 0;
542 }
543 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
544 if (__f >= 32)
545 return -1;
546 char __x = __src[__f];
Howard Hinnant5132e192012-02-15 19:19:37 +0000547 if (__x == '-' || __x == '+')
548 {
Howard Hinnant21413152013-03-08 19:06:24 +0000549 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
Howard Hinnant5132e192012-02-15 19:19:37 +0000550 {
551 *__a_end++ = __x;
552 return 0;
553 }
554 return -1;
555 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000556 if (__x == 'x' || __x == 'X')
557 __exp = 'P';
Howard Hinnant21413152013-03-08 19:06:24 +0000558 else if ((__x & 0x5F) == __exp)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000559 {
Marshall Clow5ca73ad2019-02-01 21:59:27 +0000560 __exp |= (char) 0x80;
Howard Hinnant21413152013-03-08 19:06:24 +0000561 if (__in_units)
562 {
563 __in_units = false;
564 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
565 *__g_end++ = __dc;
566 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000567 }
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000568 *__a_end++ = __x;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000569 if (__f >= 22)
570 return 0;
571 ++__dc;
572 return 0;
573}
574
Louis Dionne9de5a672021-01-14 16:27:53 -0500575_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>)
576_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000577
578template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000579class _LIBCPP_TEMPLATE_VIS num_get
Howard Hinnantc51e1022010-05-11 19:42:16 +0000580 : public locale::facet,
581 private __num_get<_CharT>
582{
583public:
584 typedef _CharT char_type;
585 typedef _InputIterator iter_type;
586
Louis Dionne16fe2952018-07-11 23:14:33 +0000587 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000588 explicit num_get(size_t __refs = 0)
589 : locale::facet(__refs) {}
590
Louis Dionne16fe2952018-07-11 23:14:33 +0000591 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000592 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
593 ios_base::iostate& __err, bool& __v) const
594 {
595 return do_get(__b, __e, __iob, __err, __v);
596 }
597
Louis Dionne16fe2952018-07-11 23:14:33 +0000598 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000599 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
600 ios_base::iostate& __err, long& __v) const
601 {
602 return do_get(__b, __e, __iob, __err, __v);
603 }
604
Louis Dionne16fe2952018-07-11 23:14:33 +0000605 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000606 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
607 ios_base::iostate& __err, long long& __v) const
608 {
609 return do_get(__b, __e, __iob, __err, __v);
610 }
611
Louis Dionne16fe2952018-07-11 23:14:33 +0000612 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000613 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
614 ios_base::iostate& __err, unsigned short& __v) const
615 {
616 return do_get(__b, __e, __iob, __err, __v);
617 }
618
Louis Dionne16fe2952018-07-11 23:14:33 +0000619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000620 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
621 ios_base::iostate& __err, unsigned int& __v) const
622 {
623 return do_get(__b, __e, __iob, __err, __v);
624 }
625
Louis Dionne16fe2952018-07-11 23:14:33 +0000626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000627 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
628 ios_base::iostate& __err, unsigned long& __v) const
629 {
630 return do_get(__b, __e, __iob, __err, __v);
631 }
632
Louis Dionne16fe2952018-07-11 23:14:33 +0000633 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000634 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
635 ios_base::iostate& __err, unsigned long long& __v) const
636 {
637 return do_get(__b, __e, __iob, __err, __v);
638 }
639
Louis Dionne16fe2952018-07-11 23:14:33 +0000640 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000641 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
642 ios_base::iostate& __err, float& __v) const
643 {
644 return do_get(__b, __e, __iob, __err, __v);
645 }
646
Louis Dionne16fe2952018-07-11 23:14:33 +0000647 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000648 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
649 ios_base::iostate& __err, double& __v) const
650 {
651 return do_get(__b, __e, __iob, __err, __v);
652 }
653
Louis Dionne16fe2952018-07-11 23:14:33 +0000654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000655 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
656 ios_base::iostate& __err, long double& __v) const
657 {
658 return do_get(__b, __e, __iob, __err, __v);
659 }
660
Louis Dionne16fe2952018-07-11 23:14:33 +0000661 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000662 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
663 ios_base::iostate& __err, void*& __v) const
664 {
665 return do_get(__b, __e, __iob, __err, __v);
666 }
667
668 static locale::id id;
669
670protected:
Louis Dionne16fe2952018-07-11 23:14:33 +0000671 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +0000672 ~num_get() {}
673
Marshall Clowae385382013-11-05 14:28:52 +0000674 template <class _Fp>
Shoaib Meenai69c57412017-03-02 03:02:50 +0000675 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
676 iter_type __do_get_floating_point
Marshall Clowae385382013-11-05 14:28:52 +0000677 (iter_type __b, iter_type __e, ios_base& __iob,
678 ios_base::iostate& __err, _Fp& __v) const;
Marshall Clow96d86d82013-11-07 01:00:50 +0000679
680 template <class _Signed>
Shoaib Meenai69c57412017-03-02 03:02:50 +0000681 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
682 iter_type __do_get_signed
Marshall Clow96d86d82013-11-07 01:00:50 +0000683 (iter_type __b, iter_type __e, ios_base& __iob,
684 ios_base::iostate& __err, _Signed& __v) const;
685
686 template <class _Unsigned>
Shoaib Meenai69c57412017-03-02 03:02:50 +0000687 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
688 iter_type __do_get_unsigned
Marshall Clow96d86d82013-11-07 01:00:50 +0000689 (iter_type __b, iter_type __e, ios_base& __iob,
690 ios_base::iostate& __err, _Unsigned& __v) const;
691
692
693 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
694 ios_base::iostate& __err, bool& __v) const;
695
696 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
697 ios_base::iostate& __err, long& __v) const
698 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
699
700 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
701 ios_base::iostate& __err, long long& __v) const
702 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
703
704 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
705 ios_base::iostate& __err, unsigned short& __v) const
706 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
707
708 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
709 ios_base::iostate& __err, unsigned int& __v) const
710 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
711
712 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
713 ios_base::iostate& __err, unsigned long& __v) const
714 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
715
716 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
717 ios_base::iostate& __err, unsigned long long& __v) const
718 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
719
720 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
721 ios_base::iostate& __err, float& __v) const
722 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
723
724 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
725 ios_base::iostate& __err, double& __v) const
726 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
727
728 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
729 ios_base::iostate& __err, long double& __v) const
730 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
731
732 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
733 ios_base::iostate& __err, void*& __v) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000734};
735
736template <class _CharT, class _InputIterator>
737locale::id
738num_get<_CharT, _InputIterator>::id;
739
740template <class _Tp>
Louis Dionne9e70e362018-11-21 16:24:46 +0000741_LIBCPP_HIDDEN _Tp
Howard Hinnantc51e1022010-05-11 19:42:16 +0000742__num_get_signed_integral(const char* __a, const char* __a_end,
743 ios_base::iostate& __err, int __base)
744{
745 if (__a != __a_end)
746 {
Howard Hinnantca8923c2013-01-22 17:26:08 +0000747 typename remove_reference<decltype(errno)>::type __save_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000748 errno = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000749 char *__p2;
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000750 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
Howard Hinnantca8923c2013-01-22 17:26:08 +0000751 typename remove_reference<decltype(errno)>::type __current_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000752 if (__current_errno == 0)
753 errno = __save_errno;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000754 if (__p2 != __a_end)
755 {
756 __err = ios_base::failbit;
757 return 0;
758 }
Howard Hinnant05c71342011-02-25 19:52:41 +0000759 else if (__current_errno == ERANGE ||
760 __ll < numeric_limits<_Tp>::min() ||
761 numeric_limits<_Tp>::max() < __ll)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000762 {
763 __err = ios_base::failbit;
Howard Hinnant05c71342011-02-25 19:52:41 +0000764 if (__ll > 0)
765 return numeric_limits<_Tp>::max();
766 else
767 return numeric_limits<_Tp>::min();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000768 }
769 return static_cast<_Tp>(__ll);
770 }
771 __err = ios_base::failbit;
772 return 0;
773}
774
775template <class _Tp>
Louis Dionne9e70e362018-11-21 16:24:46 +0000776_LIBCPP_HIDDEN _Tp
Howard Hinnantc51e1022010-05-11 19:42:16 +0000777__num_get_unsigned_integral(const char* __a, const char* __a_end,
778 ios_base::iostate& __err, int __base)
779{
780 if (__a != __a_end)
781 {
Eric Fiselierc03318c2018-03-29 01:18:53 +0000782 const bool __negate = *__a == '-';
783 if (__negate && ++__a == __a_end) {
784 __err = ios_base::failbit;
785 return 0;
Howard Hinnant05c71342011-02-25 19:52:41 +0000786 }
Howard Hinnantca8923c2013-01-22 17:26:08 +0000787 typename remove_reference<decltype(errno)>::type __save_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000788 errno = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000789 char *__p2;
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000790 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
Howard Hinnantca8923c2013-01-22 17:26:08 +0000791 typename remove_reference<decltype(errno)>::type __current_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000792 if (__current_errno == 0)
793 errno = __save_errno;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000794 if (__p2 != __a_end)
795 {
796 __err = ios_base::failbit;
797 return 0;
798 }
Eric Fiselierc03318c2018-03-29 01:18:53 +0000799 else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000800 {
801 __err = ios_base::failbit;
802 return numeric_limits<_Tp>::max();
803 }
Eric Fiselierc03318c2018-03-29 01:18:53 +0000804 _Tp __res = static_cast<_Tp>(__ll);
805 if (__negate) __res = -__res;
806 return __res;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000807 }
808 __err = ios_base::failbit;
809 return 0;
810}
811
812template <class _Tp>
Eric Fiselier98e428d2016-06-19 06:58:22 +0000813_LIBCPP_INLINE_VISIBILITY
814_Tp __do_strtod(const char* __a, char** __p2);
815
816template <>
817inline _LIBCPP_INLINE_VISIBILITY
818float __do_strtod<float>(const char* __a, char** __p2) {
819 return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
820}
821
822template <>
823inline _LIBCPP_INLINE_VISIBILITY
824double __do_strtod<double>(const char* __a, char** __p2) {
825 return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
826}
827
828template <>
829inline _LIBCPP_INLINE_VISIBILITY
830long double __do_strtod<long double>(const char* __a, char** __p2) {
831 return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
832}
833
834template <class _Tp>
Shoaib Meenai54c6fd62016-12-24 18:05:32 +0000835_LIBCPP_HIDDEN
Howard Hinnantc51e1022010-05-11 19:42:16 +0000836_Tp
837__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
838{
839 if (__a != __a_end)
840 {
Howard Hinnantc9567812013-04-13 18:19:25 +0000841 typename remove_reference<decltype(errno)>::type __save_errno = errno;
842 errno = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000843 char *__p2;
Eric Fiselier98e428d2016-06-19 06:58:22 +0000844 _Tp __ld = __do_strtod<_Tp>(__a, &__p2);
Howard Hinnantc9567812013-04-13 18:19:25 +0000845 typename remove_reference<decltype(errno)>::type __current_errno = errno;
846 if (__current_errno == 0)
847 errno = __save_errno;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000848 if (__p2 != __a_end)
849 {
850 __err = ios_base::failbit;
851 return 0;
852 }
Howard Hinnantc9567812013-04-13 18:19:25 +0000853 else if (__current_errno == ERANGE)
854 __err = ios_base::failbit;
Eric Fiselier98e428d2016-06-19 06:58:22 +0000855 return __ld;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000856 }
857 __err = ios_base::failbit;
858 return 0;
859}
860
861template <class _CharT, class _InputIterator>
862_InputIterator
863num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
864 ios_base& __iob,
865 ios_base::iostate& __err,
866 bool& __v) const
867{
868 if ((__iob.flags() & ios_base::boolalpha) == 0)
869 {
870 long __lv = -1;
871 __b = do_get(__b, __e, __iob, __err, __lv);
872 switch (__lv)
873 {
874 case 0:
875 __v = false;
876 break;
877 case 1:
878 __v = true;
879 break;
880 default:
881 __v = true;
882 __err = ios_base::failbit;
883 break;
884 }
885 return __b;
886 }
887 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
888 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
889 typedef typename numpunct<_CharT>::string_type string_type;
890 const string_type __names[2] = {__np.truename(), __np.falsename()};
Arthur O'Dwyere75dcfa2020-11-22 13:21:11 -0500891 const string_type* __i = _VSTD::__scan_keyword(__b, __e, __names, __names+2,
892 __ct, __err);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000893 __v = __i == __names;
894 return __b;
895}
896
Marshall Clow96d86d82013-11-07 01:00:50 +0000897// signed
898
Howard Hinnantc51e1022010-05-11 19:42:16 +0000899template <class _CharT, class _InputIterator>
Marshall Clow96d86d82013-11-07 01:00:50 +0000900template <class _Signed>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000901_InputIterator
Marshall Clow96d86d82013-11-07 01:00:50 +0000902num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000903 ios_base& __iob,
904 ios_base::iostate& __err,
Marshall Clow96d86d82013-11-07 01:00:50 +0000905 _Signed& __v) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000906{
907 // Stage 1
908 int __base = this->__get_base(__iob);
909 // Stage 2
Howard Hinnantc51e1022010-05-11 19:42:16 +0000910 char_type __thousands_sep;
Aditya Kumaraa866182017-06-14 23:17:45 +0000911 const int __atoms_size = 26;
912#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
913 char_type __atoms1[__atoms_size];
914 const char_type *__atoms = this->__do_widen(__iob, __atoms1);
915 string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
916#else
917 char_type __atoms[__atoms_size];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000918 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
Aditya Kumaraa866182017-06-14 23:17:45 +0000919#endif
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000920 string __buf;
921 __buf.resize(__buf.capacity());
922 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000923 char* __a_end = __a;
924 unsigned __g[__num_get_base::__num_get_buf_sz];
925 unsigned* __g_end = __g;
926 unsigned __dc = 0;
927 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000928 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +0000929 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000930 {
931 size_t __tmp = __buf.size();
932 __buf.resize(2*__buf.size());
933 __buf.resize(__buf.capacity());
934 __a = &__buf[0];
935 __a_end = __a + __tmp;
936 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000937 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000938 __thousands_sep, __grouping, __g, __g_end,
939 __atoms))
940 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000941 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000942 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
943 *__g_end++ = __dc;
944 // Stage 3
Marshall Clow96d86d82013-11-07 01:00:50 +0000945 __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000946 // Digit grouping checked
947 __check_grouping(__grouping, __g, __g_end, __err);
948 // EOF checked
949 if (__b == __e)
950 __err |= ios_base::eofbit;
951 return __b;
952}
953
Marshall Clow96d86d82013-11-07 01:00:50 +0000954// unsigned
Howard Hinnantc51e1022010-05-11 19:42:16 +0000955
956template <class _CharT, class _InputIterator>
Marshall Clow96d86d82013-11-07 01:00:50 +0000957template <class _Unsigned>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000958_InputIterator
Marshall Clow96d86d82013-11-07 01:00:50 +0000959num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000960 ios_base& __iob,
961 ios_base::iostate& __err,
Marshall Clow96d86d82013-11-07 01:00:50 +0000962 _Unsigned& __v) const
Howard Hinnantc51e1022010-05-11 19:42:16 +0000963{
964 // Stage 1
965 int __base = this->__get_base(__iob);
966 // Stage 2
Howard Hinnantc51e1022010-05-11 19:42:16 +0000967 char_type __thousands_sep;
Aditya Kumaraa866182017-06-14 23:17:45 +0000968 const int __atoms_size = 26;
969#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
970 char_type __atoms1[__atoms_size];
971 const char_type *__atoms = this->__do_widen(__iob, __atoms1);
972 string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
973#else
974 char_type __atoms[__atoms_size];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000975 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
Aditya Kumaraa866182017-06-14 23:17:45 +0000976#endif
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000977 string __buf;
978 __buf.resize(__buf.capacity());
979 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000980 char* __a_end = __a;
981 unsigned __g[__num_get_base::__num_get_buf_sz];
982 unsigned* __g_end = __g;
983 unsigned __dc = 0;
984 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000985 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +0000986 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000987 {
988 size_t __tmp = __buf.size();
989 __buf.resize(2*__buf.size());
990 __buf.resize(__buf.capacity());
991 __a = &__buf[0];
992 __a_end = __a + __tmp;
993 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000994 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000995 __thousands_sep, __grouping, __g, __g_end,
996 __atoms))
997 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000998 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000999 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1000 *__g_end++ = __dc;
1001 // Stage 3
Marshall Clow96d86d82013-11-07 01:00:50 +00001002 __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001003 // Digit grouping checked
1004 __check_grouping(__grouping, __g, __g_end, __err);
1005 // EOF checked
1006 if (__b == __e)
1007 __err |= ios_base::eofbit;
1008 return __b;
1009}
1010
Marshall Clowae385382013-11-05 14:28:52 +00001011// floating point
1012
Howard Hinnantc51e1022010-05-11 19:42:16 +00001013template <class _CharT, class _InputIterator>
Marshall Clowae385382013-11-05 14:28:52 +00001014template <class _Fp>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001015_InputIterator
Marshall Clowae385382013-11-05 14:28:52 +00001016num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001017 ios_base& __iob,
1018 ios_base::iostate& __err,
Marshall Clowae385382013-11-05 14:28:52 +00001019 _Fp& __v) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001020{
1021 // Stage 1, nothing to do
1022 // Stage 2
1023 char_type __atoms[32];
1024 char_type __decimal_point;
1025 char_type __thousands_sep;
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001026 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1027 __decimal_point,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001028 __thousands_sep);
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001029 string __buf;
1030 __buf.resize(__buf.capacity());
1031 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +00001032 char* __a_end = __a;
1033 unsigned __g[__num_get_base::__num_get_buf_sz];
1034 unsigned* __g_end = __g;
1035 unsigned __dc = 0;
1036 bool __in_units = true;
1037 char __exp = 'E';
1038 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001039 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +00001040 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001041 {
1042 size_t __tmp = __buf.size();
1043 __buf.resize(2*__buf.size());
1044 __buf.resize(__buf.capacity());
1045 __a = &__buf[0];
1046 __a_end = __a + __tmp;
1047 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001048 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1049 __decimal_point, __thousands_sep,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001050 __grouping, __g, __g_end,
1051 __dc, __atoms))
1052 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001053 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001054 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1055 *__g_end++ = __dc;
1056 // Stage 3
Marshall Clowae385382013-11-05 14:28:52 +00001057 __v = __num_get_float<_Fp>(__a, __a_end, __err);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001058 // Digit grouping checked
1059 __check_grouping(__grouping, __g, __g_end, __err);
1060 // EOF checked
1061 if (__b == __e)
1062 __err |= ios_base::eofbit;
1063 return __b;
1064}
1065
1066template <class _CharT, class _InputIterator>
1067_InputIterator
1068num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1069 ios_base& __iob,
1070 ios_base::iostate& __err,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001071 void*& __v) const
1072{
1073 // Stage 1
1074 int __base = 16;
1075 // Stage 2
1076 char_type __atoms[26];
Howard Hinnant28b24882011-12-01 20:21:04 +00001077 char_type __thousands_sep = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001078 string __grouping;
1079 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1080 __num_get_base::__src + 26, __atoms);
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001081 string __buf;
1082 __buf.resize(__buf.capacity());
1083 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +00001084 char* __a_end = __a;
1085 unsigned __g[__num_get_base::__num_get_buf_sz];
1086 unsigned* __g_end = __g;
1087 unsigned __dc = 0;
1088 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001089 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +00001090 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001091 {
1092 size_t __tmp = __buf.size();
1093 __buf.resize(2*__buf.size());
1094 __buf.resize(__buf.capacity());
1095 __a = &__buf[0];
1096 __a_end = __a + __tmp;
1097 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001098 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1099 __thousands_sep, __grouping,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001100 __g, __g_end, __atoms))
1101 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001102 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001103 // Stage 3
Marshall Clow0db963d2014-05-21 16:02:20 +00001104 __buf.resize(__a_end - __a);
Ben Craig3756b922016-03-09 15:39:39 +00001105 if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001106 __err = ios_base::failbit;
1107 // EOF checked
1108 if (__b == __e)
1109 __err |= ios_base::eofbit;
1110 return __b;
1111}
1112
Louis Dionne9de5a672021-01-14 16:27:53 -05001113_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>)
1114_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001115
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001116struct _LIBCPP_TYPE_VIS __num_put_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00001117{
1118protected:
1119 static void __format_int(char* __fmt, const char* __len, bool __signd,
1120 ios_base::fmtflags __flags);
1121 static bool __format_float(char* __fmt, const char* __len,
1122 ios_base::fmtflags __flags);
1123 static char* __identify_padding(char* __nb, char* __ne,
1124 const ios_base& __iob);
1125};
1126
1127template <class _CharT>
1128struct __num_put
1129 : protected __num_put_base
1130{
1131 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1132 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1133 const locale& __loc);
1134 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1135 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1136 const locale& __loc);
1137};
1138
1139template <class _CharT>
1140void
1141__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1142 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1143 const locale& __loc)
1144{
1145 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1146 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1147 string __grouping = __npt.grouping();
1148 if (__grouping.empty())
1149 {
1150 __ct.widen(__nb, __ne, __ob);
1151 __oe = __ob + (__ne - __nb);
1152 }
1153 else
1154 {
1155 __oe = __ob;
1156 char* __nf = __nb;
1157 if (*__nf == '-' || *__nf == '+')
1158 *__oe++ = __ct.widen(*__nf++);
1159 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1160 __nf[1] == 'X'))
1161 {
1162 *__oe++ = __ct.widen(*__nf++);
1163 *__oe++ = __ct.widen(*__nf++);
1164 }
1165 reverse(__nf, __ne);
1166 _CharT __thousands_sep = __npt.thousands_sep();
1167 unsigned __dc = 0;
1168 unsigned __dg = 0;
1169 for (char* __p = __nf; __p < __ne; ++__p)
1170 {
1171 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1172 __dc == static_cast<unsigned>(__grouping[__dg]))
1173 {
1174 *__oe++ = __thousands_sep;
1175 __dc = 0;
1176 if (__dg < __grouping.size()-1)
1177 ++__dg;
1178 }
1179 *__oe++ = __ct.widen(*__p);
1180 ++__dc;
1181 }
1182 reverse(__ob + (__nf - __nb), __oe);
1183 }
1184 if (__np == __ne)
1185 __op = __oe;
1186 else
1187 __op = __ob + (__np - __nb);
1188}
1189
1190template <class _CharT>
1191void
1192__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1193 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1194 const locale& __loc)
1195{
1196 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1197 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1198 string __grouping = __npt.grouping();
1199 __oe = __ob;
1200 char* __nf = __nb;
1201 if (*__nf == '-' || *__nf == '+')
1202 *__oe++ = __ct.widen(*__nf++);
1203 char* __ns;
1204 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1205 __nf[1] == 'X'))
1206 {
1207 *__oe++ = __ct.widen(*__nf++);
1208 *__oe++ = __ct.widen(*__nf++);
1209 for (__ns = __nf; __ns < __ne; ++__ns)
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001210 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001211 break;
1212 }
1213 else
1214 {
1215 for (__ns = __nf; __ns < __ne; ++__ns)
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001216 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001217 break;
1218 }
1219 if (__grouping.empty())
1220 {
1221 __ct.widen(__nf, __ns, __oe);
1222 __oe += __ns - __nf;
1223 }
1224 else
1225 {
1226 reverse(__nf, __ns);
1227 _CharT __thousands_sep = __npt.thousands_sep();
1228 unsigned __dc = 0;
1229 unsigned __dg = 0;
1230 for (char* __p = __nf; __p < __ns; ++__p)
1231 {
1232 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1233 {
1234 *__oe++ = __thousands_sep;
1235 __dc = 0;
1236 if (__dg < __grouping.size()-1)
1237 ++__dg;
1238 }
1239 *__oe++ = __ct.widen(*__p);
1240 ++__dc;
1241 }
1242 reverse(__ob + (__nf - __nb), __oe);
1243 }
1244 for (__nf = __ns; __nf < __ne; ++__nf)
1245 {
1246 if (*__nf == '.')
1247 {
1248 *__oe++ = __npt.decimal_point();
1249 ++__nf;
1250 break;
1251 }
1252 else
1253 *__oe++ = __ct.widen(*__nf);
1254 }
1255 __ct.widen(__nf, __ne, __oe);
1256 __oe += __ne - __nf;
1257 if (__np == __ne)
1258 __op = __oe;
1259 else
1260 __op = __ob + (__np - __nb);
1261}
1262
Louis Dionne9de5a672021-01-14 16:27:53 -05001263_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>)
1264_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001265
1266template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001267class _LIBCPP_TEMPLATE_VIS num_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00001268 : public locale::facet,
1269 private __num_put<_CharT>
1270{
1271public:
1272 typedef _CharT char_type;
1273 typedef _OutputIterator iter_type;
1274
Louis Dionne16fe2952018-07-11 23:14:33 +00001275 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001276 explicit num_put(size_t __refs = 0)
1277 : locale::facet(__refs) {}
1278
Louis Dionne16fe2952018-07-11 23:14:33 +00001279 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001280 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1281 bool __v) const
1282 {
1283 return do_put(__s, __iob, __fl, __v);
1284 }
1285
Louis Dionne16fe2952018-07-11 23:14:33 +00001286 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001287 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1288 long __v) const
1289 {
1290 return do_put(__s, __iob, __fl, __v);
1291 }
1292
Louis Dionne16fe2952018-07-11 23:14:33 +00001293 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001294 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1295 long long __v) const
1296 {
1297 return do_put(__s, __iob, __fl, __v);
1298 }
1299
Louis Dionne16fe2952018-07-11 23:14:33 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001301 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1302 unsigned long __v) const
1303 {
1304 return do_put(__s, __iob, __fl, __v);
1305 }
1306
Louis Dionne16fe2952018-07-11 23:14:33 +00001307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001308 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1309 unsigned long long __v) const
1310 {
1311 return do_put(__s, __iob, __fl, __v);
1312 }
1313
Louis Dionne16fe2952018-07-11 23:14:33 +00001314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001315 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1316 double __v) const
1317 {
1318 return do_put(__s, __iob, __fl, __v);
1319 }
1320
Louis Dionne16fe2952018-07-11 23:14:33 +00001321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001322 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1323 long double __v) const
1324 {
1325 return do_put(__s, __iob, __fl, __v);
1326 }
1327
Louis Dionne16fe2952018-07-11 23:14:33 +00001328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001329 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1330 const void* __v) const
1331 {
1332 return do_put(__s, __iob, __fl, __v);
1333 }
1334
1335 static locale::id id;
1336
1337protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001339 ~num_put() {}
1340
1341 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1342 bool __v) const;
1343 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1344 long __v) const;
1345 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1346 long long __v) const;
1347 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1348 unsigned long) const;
1349 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1350 unsigned long long) const;
1351 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1352 double __v) const;
1353 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1354 long double __v) const;
1355 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1356 const void* __v) const;
1357};
1358
1359template <class _CharT, class _OutputIterator>
1360locale::id
1361num_put<_CharT, _OutputIterator>::id;
1362
1363template <class _CharT, class _OutputIterator>
1364_LIBCPP_HIDDEN
1365_OutputIterator
1366__pad_and_output(_OutputIterator __s,
1367 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1368 ios_base& __iob, _CharT __fl)
1369{
1370 streamsize __sz = __oe - __ob;
1371 streamsize __ns = __iob.width();
1372 if (__ns > __sz)
1373 __ns -= __sz;
1374 else
1375 __ns = 0;
1376 for (;__ob < __op; ++__ob, ++__s)
1377 *__s = *__ob;
1378 for (; __ns; --__ns, ++__s)
1379 *__s = __fl;
1380 for (; __ob < __oe; ++__ob, ++__s)
1381 *__s = *__ob;
1382 __iob.width(0);
1383 return __s;
1384}
1385
Howard Hinnant97955172012-09-19 19:14:15 +00001386template <class _CharT, class _Traits>
1387_LIBCPP_HIDDEN
1388ostreambuf_iterator<_CharT, _Traits>
1389__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1390 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1391 ios_base& __iob, _CharT __fl)
1392{
1393 if (__s.__sbuf_ == nullptr)
1394 return __s;
1395 streamsize __sz = __oe - __ob;
1396 streamsize __ns = __iob.width();
1397 if (__ns > __sz)
1398 __ns -= __sz;
1399 else
1400 __ns = 0;
1401 streamsize __np = __op - __ob;
1402 if (__np > 0)
1403 {
1404 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1405 {
1406 __s.__sbuf_ = nullptr;
1407 return __s;
1408 }
1409 }
1410 if (__ns > 0)
1411 {
1412 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1413 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1414 {
1415 __s.__sbuf_ = nullptr;
1416 return __s;
1417 }
1418 }
1419 __np = __oe - __op;
1420 if (__np > 0)
1421 {
1422 if (__s.__sbuf_->sputn(__op, __np) != __np)
1423 {
1424 __s.__sbuf_ = nullptr;
1425 return __s;
1426 }
1427 }
1428 __iob.width(0);
1429 return __s;
1430}
1431
Howard Hinnantc51e1022010-05-11 19:42:16 +00001432template <class _CharT, class _OutputIterator>
1433_OutputIterator
1434num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1435 char_type __fl, bool __v) const
1436{
1437 if ((__iob.flags() & ios_base::boolalpha) == 0)
1438 return do_put(__s, __iob, __fl, (unsigned long)__v);
1439 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1440 typedef typename numpunct<char_type>::string_type string_type;
Louis Dionneba400782020-10-02 15:02:52 -04001441#if _LIBCPP_DEBUG_LEVEL == 2
Howard Hinnant8ea98242013-08-23 17:37:05 +00001442 string_type __tmp(__v ? __np.truename() : __np.falsename());
1443 string_type __nm = _VSTD::move(__tmp);
1444#else
Howard Hinnantc51e1022010-05-11 19:42:16 +00001445 string_type __nm = __v ? __np.truename() : __np.falsename();
Howard Hinnant8ea98242013-08-23 17:37:05 +00001446#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001447 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1448 *__s = *__i;
1449 return __s;
1450}
1451
1452template <class _CharT, class _OutputIterator>
1453_OutputIterator
1454num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1455 char_type __fl, long __v) const
1456{
1457 // Stage 1 - Get number in narrow char
1458 char __fmt[6] = {'%', 0};
1459 const char* __len = "l";
1460 this->__format_int(__fmt+1, __len, true, __iob.flags());
Daniel McIntosh33dfba72021-06-02 11:44:07 -04001461 // Worst case is octal, with showbase enabled. Note that octal is always
1462 // printed as an unsigned value.
Daniel McIntosh30cb45e2021-06-08 13:59:11 -04001463 _LIBCPP_CONSTEXPR const unsigned __nbuf
1464 = (numeric_limits<unsigned long>::digits / 3) // 1 char per 3 bits
1465 + ((numeric_limits<unsigned long>::digits % 3) != 0) // round up
1466 + 2; // base prefix + terminating null character
Howard Hinnantc51e1022010-05-11 19:42:16 +00001467 char __nar[__nbuf];
Ben Craig3756b922016-03-09 15:39:39 +00001468 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001469 char* __ne = __nar + __nc;
1470 char* __np = this->__identify_padding(__nar, __ne, __iob);
1471 // Stage 2 - Widen __nar while adding thousands separators
1472 char_type __o[2*(__nbuf-1) - 1];
1473 char_type* __op; // pad here
1474 char_type* __oe; // end of output
1475 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1476 // [__o, __oe) contains thousands_sep'd wide number
1477 // Stage 3 & 4
1478 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1479}
1480
1481template <class _CharT, class _OutputIterator>
1482_OutputIterator
1483num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1484 char_type __fl, long long __v) const
1485{
1486 // Stage 1 - Get number in narrow char
1487 char __fmt[8] = {'%', 0};
1488 const char* __len = "ll";
1489 this->__format_int(__fmt+1, __len, true, __iob.flags());
Daniel McIntosh33dfba72021-06-02 11:44:07 -04001490 // Worst case is octal, with showbase enabled. Note that octal is always
1491 // printed as an unsigned value.
Daniel McIntosh30cb45e2021-06-08 13:59:11 -04001492 _LIBCPP_CONSTEXPR const unsigned __nbuf
1493 = (numeric_limits<unsigned long long>::digits / 3) // 1 char per 3 bits
1494 + ((numeric_limits<unsigned long long>::digits % 3) != 0) // round up
1495 + 2; // base prefix + terminating null character
Howard Hinnantc51e1022010-05-11 19:42:16 +00001496 char __nar[__nbuf];
Ben Craig3756b922016-03-09 15:39:39 +00001497 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001498 char* __ne = __nar + __nc;
1499 char* __np = this->__identify_padding(__nar, __ne, __iob);
1500 // Stage 2 - Widen __nar while adding thousands separators
1501 char_type __o[2*(__nbuf-1) - 1];
1502 char_type* __op; // pad here
1503 char_type* __oe; // end of output
1504 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1505 // [__o, __oe) contains thousands_sep'd wide number
1506 // Stage 3 & 4
1507 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1508}
1509
1510template <class _CharT, class _OutputIterator>
1511_OutputIterator
1512num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1513 char_type __fl, unsigned long __v) const
1514{
1515 // Stage 1 - Get number in narrow char
1516 char __fmt[6] = {'%', 0};
1517 const char* __len = "l";
1518 this->__format_int(__fmt+1, __len, false, __iob.flags());
Daniel McIntosh33dfba72021-06-02 11:44:07 -04001519 // Worst case is octal, with showbase enabled.
Daniel McIntosh30cb45e2021-06-08 13:59:11 -04001520 _LIBCPP_CONSTEXPR const unsigned __nbuf
1521 = (numeric_limits<unsigned long>::digits / 3) // 1 char per 3 bits
1522 + ((numeric_limits<unsigned long>::digits % 3) != 0) // round up
1523 + 2; // base prefix + terminating null character
Howard Hinnantc51e1022010-05-11 19:42:16 +00001524 char __nar[__nbuf];
Ben Craig3756b922016-03-09 15:39:39 +00001525 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001526 char* __ne = __nar + __nc;
1527 char* __np = this->__identify_padding(__nar, __ne, __iob);
1528 // Stage 2 - Widen __nar while adding thousands separators
1529 char_type __o[2*(__nbuf-1) - 1];
1530 char_type* __op; // pad here
1531 char_type* __oe; // end of output
1532 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1533 // [__o, __oe) contains thousands_sep'd wide number
1534 // Stage 3 & 4
1535 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1536}
1537
1538template <class _CharT, class _OutputIterator>
1539_OutputIterator
1540num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1541 char_type __fl, unsigned long long __v) const
1542{
1543 // Stage 1 - Get number in narrow char
1544 char __fmt[8] = {'%', 0};
1545 const char* __len = "ll";
1546 this->__format_int(__fmt+1, __len, false, __iob.flags());
Daniel McIntosh33dfba72021-06-02 11:44:07 -04001547 // Worst case is octal, with showbase enabled.
Daniel McIntosh30cb45e2021-06-08 13:59:11 -04001548 _LIBCPP_CONSTEXPR const unsigned __nbuf
1549 = (numeric_limits<unsigned long long>::digits / 3) // 1 char per 3 bits
1550 + ((numeric_limits<unsigned long long>::digits % 3) != 0) // round up
1551 + 2; // base prefix + terminating null character
Howard Hinnantc51e1022010-05-11 19:42:16 +00001552 char __nar[__nbuf];
Ben Craig3756b922016-03-09 15:39:39 +00001553 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001554 char* __ne = __nar + __nc;
1555 char* __np = this->__identify_padding(__nar, __ne, __iob);
1556 // Stage 2 - Widen __nar while adding thousands separators
1557 char_type __o[2*(__nbuf-1) - 1];
1558 char_type* __op; // pad here
1559 char_type* __oe; // end of output
1560 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1561 // [__o, __oe) contains thousands_sep'd wide number
1562 // Stage 3 & 4
1563 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1564}
1565
1566template <class _CharT, class _OutputIterator>
1567_OutputIterator
1568num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1569 char_type __fl, double __v) const
1570{
1571 // Stage 1 - Get number in narrow char
1572 char __fmt[8] = {'%', 0};
1573 const char* __len = "";
1574 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1575 const unsigned __nbuf = 30;
1576 char __nar[__nbuf];
1577 char* __nb = __nar;
1578 int __nc;
1579 if (__specify_precision)
Ben Craig3756b922016-03-09 15:39:39 +00001580 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
Howard Hinnant155c2af2010-05-24 17:49:41 +00001581 (int)__iob.precision(), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001582 else
Ben Craig3756b922016-03-09 15:39:39 +00001583 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Bruce Mitchener170d8972020-11-24 12:53:53 -05001584 unique_ptr<char, void(*)(void*)> __nbh(nullptr, free);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001585 if (__nc > static_cast<int>(__nbuf-1))
1586 {
1587 if (__specify_precision)
Ben Craig3756b922016-03-09 15:39:39 +00001588 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001589 else
Ben Craig3756b922016-03-09 15:39:39 +00001590 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Brad Smithaee2d992021-01-21 19:39:52 -05001591 if (__nc == -1)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001592 __throw_bad_alloc();
1593 __nbh.reset(__nb);
1594 }
1595 char* __ne = __nb + __nc;
1596 char* __np = this->__identify_padding(__nb, __ne, __iob);
1597 // Stage 2 - Widen __nar while adding thousands separators
1598 char_type __o[2*(__nbuf-1) - 1];
1599 char_type* __ob = __o;
1600 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1601 if (__nb != __nar)
1602 {
Howard Hinnant28b24882011-12-01 20:21:04 +00001603 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001604 if (__ob == 0)
1605 __throw_bad_alloc();
1606 __obh.reset(__ob);
1607 }
1608 char_type* __op; // pad here
1609 char_type* __oe; // end of output
1610 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1611 // [__o, __oe) contains thousands_sep'd wide number
1612 // Stage 3 & 4
1613 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1614 return __s;
1615}
1616
1617template <class _CharT, class _OutputIterator>
1618_OutputIterator
1619num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1620 char_type __fl, long double __v) const
1621{
1622 // Stage 1 - Get number in narrow char
1623 char __fmt[8] = {'%', 0};
1624 const char* __len = "L";
1625 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1626 const unsigned __nbuf = 30;
1627 char __nar[__nbuf];
1628 char* __nb = __nar;
1629 int __nc;
1630 if (__specify_precision)
Ben Craig3756b922016-03-09 15:39:39 +00001631 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
Howard Hinnant155c2af2010-05-24 17:49:41 +00001632 (int)__iob.precision(), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001633 else
Ben Craig3756b922016-03-09 15:39:39 +00001634 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Bruce Mitchener170d8972020-11-24 12:53:53 -05001635 unique_ptr<char, void(*)(void*)> __nbh(nullptr, free);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001636 if (__nc > static_cast<int>(__nbuf-1))
1637 {
1638 if (__specify_precision)
Ben Craig3756b922016-03-09 15:39:39 +00001639 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001640 else
Ben Craig3756b922016-03-09 15:39:39 +00001641 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Brad Smithaee2d992021-01-21 19:39:52 -05001642 if (__nc == -1)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001643 __throw_bad_alloc();
1644 __nbh.reset(__nb);
1645 }
1646 char* __ne = __nb + __nc;
1647 char* __np = this->__identify_padding(__nb, __ne, __iob);
1648 // Stage 2 - Widen __nar while adding thousands separators
1649 char_type __o[2*(__nbuf-1) - 1];
1650 char_type* __ob = __o;
1651 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1652 if (__nb != __nar)
1653 {
Howard Hinnant28b24882011-12-01 20:21:04 +00001654 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001655 if (__ob == 0)
1656 __throw_bad_alloc();
1657 __obh.reset(__ob);
1658 }
1659 char_type* __op; // pad here
1660 char_type* __oe; // end of output
1661 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1662 // [__o, __oe) contains thousands_sep'd wide number
1663 // Stage 3 & 4
1664 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1665 return __s;
1666}
1667
1668template <class _CharT, class _OutputIterator>
1669_OutputIterator
1670num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1671 char_type __fl, const void* __v) const
1672{
1673 // Stage 1 - Get pointer in narrow char
1674 char __fmt[6] = "%p";
1675 const unsigned __nbuf = 20;
1676 char __nar[__nbuf];
Ben Craig3756b922016-03-09 15:39:39 +00001677 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001678 char* __ne = __nar + __nc;
1679 char* __np = this->__identify_padding(__nar, __ne, __iob);
1680 // Stage 2 - Widen __nar
1681 char_type __o[2*(__nbuf-1) - 1];
1682 char_type* __op; // pad here
1683 char_type* __oe; // end of output
1684 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1685 __ct.widen(__nar, __ne, __o);
1686 __oe = __o + (__ne - __nar);
1687 if (__np == __ne)
1688 __op = __oe;
1689 else
1690 __op = __o + (__np - __nar);
1691 // [__o, __oe) contains wide number
1692 // Stage 3 & 4
1693 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1694}
1695
Louis Dionne9de5a672021-01-14 16:27:53 -05001696_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>)
1697_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001698
1699template <class _CharT, class _InputIterator>
1700_LIBCPP_HIDDEN
1701int
1702__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1703 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1704{
1705 // Precondition: __n >= 1
1706 if (__b == __e)
1707 {
1708 __err |= ios_base::eofbit | ios_base::failbit;
1709 return 0;
1710 }
1711 // get first digit
1712 _CharT __c = *__b;
1713 if (!__ct.is(ctype_base::digit, __c))
1714 {
1715 __err |= ios_base::failbit;
1716 return 0;
1717 }
1718 int __r = __ct.narrow(__c, 0) - '0';
Eric Fiseliera09a3b42014-10-27 19:28:20 +00001719 for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001720 {
1721 // get next digit
1722 __c = *__b;
1723 if (!__ct.is(ctype_base::digit, __c))
1724 return __r;
1725 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1726 }
1727 if (__b == __e)
1728 __err |= ios_base::eofbit;
1729 return __r;
1730}
1731
Howard Hinnant8331b762013-03-06 23:30:19 +00001732class _LIBCPP_TYPE_VIS time_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00001733{
1734public:
1735 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1736};
1737
1738template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001739class _LIBCPP_TEMPLATE_VIS __time_get_c_storage
Howard Hinnantc51e1022010-05-11 19:42:16 +00001740{
1741protected:
1742 typedef basic_string<_CharT> string_type;
1743
1744 virtual const string_type* __weeks() const;
1745 virtual const string_type* __months() const;
1746 virtual const string_type* __am_pm() const;
1747 virtual const string_type& __c() const;
1748 virtual const string_type& __r() const;
1749 virtual const string_type& __x() const;
1750 virtual const string_type& __X() const;
Eric Fiselier5eb6efc2015-08-18 19:39:35 +00001751
Louis Dionne16fe2952018-07-11 23:14:33 +00001752 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5eb6efc2015-08-18 19:39:35 +00001753 ~__time_get_c_storage() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00001754};
1755
Eric Fiselierf30c0af2017-05-08 00:29:32 +00001756template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const;
1757template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const;
1758template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const;
1759template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const;
1760template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const;
1761template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const;
1762template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const;
1763
1764template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
1765template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const;
1766template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
1767template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const;
1768template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const;
1769template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const;
1770template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const;
1771
Howard Hinnantc51e1022010-05-11 19:42:16 +00001772template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001773class _LIBCPP_TEMPLATE_VIS time_get
Howard Hinnantc51e1022010-05-11 19:42:16 +00001774 : public locale::facet,
1775 public time_base,
1776 private __time_get_c_storage<_CharT>
1777{
1778public:
1779 typedef _CharT char_type;
1780 typedef _InputIterator iter_type;
1781 typedef time_base::dateorder dateorder;
1782 typedef basic_string<char_type> string_type;
1783
Louis Dionne16fe2952018-07-11 23:14:33 +00001784 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001785 explicit time_get(size_t __refs = 0)
1786 : locale::facet(__refs) {}
1787
Louis Dionne16fe2952018-07-11 23:14:33 +00001788 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001789 dateorder date_order() const
1790 {
1791 return this->do_date_order();
1792 }
1793
Louis Dionne16fe2952018-07-11 23:14:33 +00001794 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001795 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1796 ios_base::iostate& __err, tm* __tm) const
1797 {
1798 return do_get_time(__b, __e, __iob, __err, __tm);
1799 }
1800
Louis Dionne16fe2952018-07-11 23:14:33 +00001801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001802 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1803 ios_base::iostate& __err, tm* __tm) const
1804 {
1805 return do_get_date(__b, __e, __iob, __err, __tm);
1806 }
1807
Louis Dionne16fe2952018-07-11 23:14:33 +00001808 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001809 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1810 ios_base::iostate& __err, tm* __tm) const
1811 {
1812 return do_get_weekday(__b, __e, __iob, __err, __tm);
1813 }
1814
Louis Dionne16fe2952018-07-11 23:14:33 +00001815 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001816 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1817 ios_base::iostate& __err, tm* __tm) const
1818 {
1819 return do_get_monthname(__b, __e, __iob, __err, __tm);
1820 }
1821
Louis Dionne16fe2952018-07-11 23:14:33 +00001822 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001823 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1824 ios_base::iostate& __err, tm* __tm) const
1825 {
1826 return do_get_year(__b, __e, __iob, __err, __tm);
1827 }
1828
Louis Dionne16fe2952018-07-11 23:14:33 +00001829 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001830 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1831 ios_base::iostate& __err, tm *__tm,
1832 char __fmt, char __mod = 0) const
1833 {
1834 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1835 }
1836
1837 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1838 ios_base::iostate& __err, tm* __tm,
1839 const char_type* __fmtb, const char_type* __fmte) const;
1840
1841 static locale::id id;
1842
1843protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00001844 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00001845 ~time_get() {}
1846
1847 virtual dateorder do_date_order() const;
1848 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1849 ios_base::iostate& __err, tm* __tm) const;
1850 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1851 ios_base::iostate& __err, tm* __tm) const;
1852 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1853 ios_base::iostate& __err, tm* __tm) const;
1854 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1855 ios_base::iostate& __err, tm* __tm) const;
1856 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1857 ios_base::iostate& __err, tm* __tm) const;
1858 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1859 ios_base::iostate& __err, tm* __tm,
1860 char __fmt, char __mod) const;
1861private:
1862 void __get_white_space(iter_type& __b, iter_type __e,
1863 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1864 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1865 const ctype<char_type>& __ct) const;
1866
1867 void __get_weekdayname(int& __m,
1868 iter_type& __b, iter_type __e,
1869 ios_base::iostate& __err,
1870 const ctype<char_type>& __ct) const;
1871 void __get_monthname(int& __m,
1872 iter_type& __b, iter_type __e,
1873 ios_base::iostate& __err,
1874 const ctype<char_type>& __ct) const;
1875 void __get_day(int& __d,
1876 iter_type& __b, iter_type __e,
1877 ios_base::iostate& __err,
1878 const ctype<char_type>& __ct) const;
1879 void __get_month(int& __m,
1880 iter_type& __b, iter_type __e,
1881 ios_base::iostate& __err,
1882 const ctype<char_type>& __ct) const;
1883 void __get_year(int& __y,
1884 iter_type& __b, iter_type __e,
1885 ios_base::iostate& __err,
1886 const ctype<char_type>& __ct) const;
1887 void __get_year4(int& __y,
1888 iter_type& __b, iter_type __e,
1889 ios_base::iostate& __err,
1890 const ctype<char_type>& __ct) const;
1891 void __get_hour(int& __d,
1892 iter_type& __b, iter_type __e,
1893 ios_base::iostate& __err,
1894 const ctype<char_type>& __ct) const;
1895 void __get_12_hour(int& __h,
1896 iter_type& __b, iter_type __e,
1897 ios_base::iostate& __err,
1898 const ctype<char_type>& __ct) const;
1899 void __get_am_pm(int& __h,
1900 iter_type& __b, iter_type __e,
1901 ios_base::iostate& __err,
1902 const ctype<char_type>& __ct) const;
1903 void __get_minute(int& __m,
1904 iter_type& __b, iter_type __e,
1905 ios_base::iostate& __err,
1906 const ctype<char_type>& __ct) const;
1907 void __get_second(int& __s,
1908 iter_type& __b, iter_type __e,
1909 ios_base::iostate& __err,
1910 const ctype<char_type>& __ct) const;
1911 void __get_weekday(int& __w,
1912 iter_type& __b, iter_type __e,
1913 ios_base::iostate& __err,
1914 const ctype<char_type>& __ct) const;
1915 void __get_day_year_num(int& __w,
1916 iter_type& __b, iter_type __e,
1917 ios_base::iostate& __err,
1918 const ctype<char_type>& __ct) const;
1919};
1920
1921template <class _CharT, class _InputIterator>
1922locale::id
1923time_get<_CharT, _InputIterator>::id;
1924
Alp Tokerb8a95f52014-05-15 11:27:39 +00001925// time_get primitives
Howard Hinnantc51e1022010-05-11 19:42:16 +00001926
1927template <class _CharT, class _InputIterator>
1928void
1929time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
1930 iter_type& __b, iter_type __e,
1931 ios_base::iostate& __err,
1932 const ctype<char_type>& __ct) const
1933{
1934 // Note: ignoring case comes from the POSIX strptime spec
1935 const string_type* __wk = this->__weeks();
Arthur O'Dwyere75dcfa2020-11-22 13:21:11 -05001936 ptrdiff_t __i = _VSTD::__scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001937 if (__i < 14)
1938 __w = __i % 7;
1939}
1940
1941template <class _CharT, class _InputIterator>
1942void
1943time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
1944 iter_type& __b, iter_type __e,
1945 ios_base::iostate& __err,
1946 const ctype<char_type>& __ct) const
1947{
1948 // Note: ignoring case comes from the POSIX strptime spec
1949 const string_type* __month = this->__months();
Arthur O'Dwyere75dcfa2020-11-22 13:21:11 -05001950 ptrdiff_t __i = _VSTD::__scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001951 if (__i < 24)
1952 __m = __i % 12;
1953}
1954
1955template <class _CharT, class _InputIterator>
1956void
1957time_get<_CharT, _InputIterator>::__get_day(int& __d,
1958 iter_type& __b, iter_type __e,
1959 ios_base::iostate& __err,
1960 const ctype<char_type>& __ct) const
1961{
Arthur O'Dwyere75dcfa2020-11-22 13:21:11 -05001962 int __t = _VSTD::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001963 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
1964 __d = __t;
1965 else
1966 __err |= ios_base::failbit;
1967}
1968
1969template <class _CharT, class _InputIterator>
1970void
1971time_get<_CharT, _InputIterator>::__get_month(int& __m,
1972 iter_type& __b, iter_type __e,
1973 ios_base::iostate& __err,
1974 const ctype<char_type>& __ct) const
1975{
1976 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
1977 if (!(__err & ios_base::failbit) && __t <= 11)
1978 __m = __t;
1979 else
1980 __err |= ios_base::failbit;
1981}
1982
1983template <class _CharT, class _InputIterator>
1984void
1985time_get<_CharT, _InputIterator>::__get_year(int& __y,
1986 iter_type& __b, iter_type __e,
1987 ios_base::iostate& __err,
1988 const ctype<char_type>& __ct) const
1989{
1990 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1991 if (!(__err & ios_base::failbit))
1992 {
1993 if (__t < 69)
1994 __t += 2000;
1995 else if (69 <= __t && __t <= 99)
1996 __t += 1900;
1997 __y = __t - 1900;
1998 }
1999}
2000
2001template <class _CharT, class _InputIterator>
2002void
2003time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2004 iter_type& __b, iter_type __e,
2005 ios_base::iostate& __err,
2006 const ctype<char_type>& __ct) const
2007{
2008 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2009 if (!(__err & ios_base::failbit))
2010 __y = __t - 1900;
2011}
2012
2013template <class _CharT, class _InputIterator>
2014void
2015time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2016 iter_type& __b, iter_type __e,
2017 ios_base::iostate& __err,
2018 const ctype<char_type>& __ct) const
2019{
2020 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2021 if (!(__err & ios_base::failbit) && __t <= 23)
2022 __h = __t;
2023 else
2024 __err |= ios_base::failbit;
2025}
2026
2027template <class _CharT, class _InputIterator>
2028void
2029time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2030 iter_type& __b, iter_type __e,
2031 ios_base::iostate& __err,
2032 const ctype<char_type>& __ct) const
2033{
2034 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2035 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2036 __h = __t;
2037 else
2038 __err |= ios_base::failbit;
2039}
2040
2041template <class _CharT, class _InputIterator>
2042void
2043time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2044 iter_type& __b, iter_type __e,
2045 ios_base::iostate& __err,
2046 const ctype<char_type>& __ct) const
2047{
2048 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2049 if (!(__err & ios_base::failbit) && __t <= 59)
2050 __m = __t;
2051 else
2052 __err |= ios_base::failbit;
2053}
2054
2055template <class _CharT, class _InputIterator>
2056void
2057time_get<_CharT, _InputIterator>::__get_second(int& __s,
2058 iter_type& __b, iter_type __e,
2059 ios_base::iostate& __err,
2060 const ctype<char_type>& __ct) const
2061{
2062 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2063 if (!(__err & ios_base::failbit) && __t <= 60)
2064 __s = __t;
2065 else
2066 __err |= ios_base::failbit;
2067}
2068
2069template <class _CharT, class _InputIterator>
2070void
2071time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2072 iter_type& __b, iter_type __e,
2073 ios_base::iostate& __err,
2074 const ctype<char_type>& __ct) const
2075{
2076 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2077 if (!(__err & ios_base::failbit) && __t <= 6)
2078 __w = __t;
2079 else
2080 __err |= ios_base::failbit;
2081}
2082
2083template <class _CharT, class _InputIterator>
2084void
2085time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2086 iter_type& __b, iter_type __e,
2087 ios_base::iostate& __err,
2088 const ctype<char_type>& __ct) const
2089{
2090 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2091 if (!(__err & ios_base::failbit) && __t <= 365)
2092 __d = __t;
2093 else
2094 __err |= ios_base::failbit;
2095}
2096
2097template <class _CharT, class _InputIterator>
2098void
2099time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2100 ios_base::iostate& __err,
2101 const ctype<char_type>& __ct) const
2102{
2103 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2104 ;
2105 if (__b == __e)
2106 __err |= ios_base::eofbit;
2107}
2108
2109template <class _CharT, class _InputIterator>
2110void
2111time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2112 iter_type& __b, iter_type __e,
2113 ios_base::iostate& __err,
2114 const ctype<char_type>& __ct) const
2115{
2116 const string_type* __ap = this->__am_pm();
2117 if (__ap[0].size() + __ap[1].size() == 0)
2118 {
2119 __err |= ios_base::failbit;
2120 return;
2121 }
Arthur O'Dwyere75dcfa2020-11-22 13:21:11 -05002122 ptrdiff_t __i = _VSTD::__scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002123 if (__i == 0 && __h == 12)
2124 __h = 0;
2125 else if (__i == 1 && __h < 12)
2126 __h += 12;
2127}
2128
2129template <class _CharT, class _InputIterator>
2130void
2131time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2132 ios_base::iostate& __err,
2133 const ctype<char_type>& __ct) const
2134{
2135 if (__b == __e)
2136 {
2137 __err |= ios_base::eofbit | ios_base::failbit;
2138 return;
2139 }
2140 if (__ct.narrow(*__b, 0) != '%')
2141 __err |= ios_base::failbit;
2142 else if(++__b == __e)
2143 __err |= ios_base::eofbit;
2144}
2145
Alp Tokerb8a95f52014-05-15 11:27:39 +00002146// time_get end primitives
Howard Hinnantc51e1022010-05-11 19:42:16 +00002147
2148template <class _CharT, class _InputIterator>
2149_InputIterator
2150time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2151 ios_base& __iob,
2152 ios_base::iostate& __err, tm* __tm,
2153 const char_type* __fmtb, const char_type* __fmte) const
2154{
2155 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2156 __err = ios_base::goodbit;
2157 while (__fmtb != __fmte && __err == ios_base::goodbit)
2158 {
2159 if (__b == __e)
2160 {
2161 __err = ios_base::failbit;
2162 break;
2163 }
2164 if (__ct.narrow(*__fmtb, 0) == '%')
2165 {
2166 if (++__fmtb == __fmte)
2167 {
2168 __err = ios_base::failbit;
2169 break;
2170 }
2171 char __cmd = __ct.narrow(*__fmtb, 0);
2172 char __opt = '\0';
2173 if (__cmd == 'E' || __cmd == '0')
2174 {
2175 if (++__fmtb == __fmte)
2176 {
2177 __err = ios_base::failbit;
2178 break;
2179 }
2180 __opt = __cmd;
2181 __cmd = __ct.narrow(*__fmtb, 0);
2182 }
2183 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2184 ++__fmtb;
2185 }
2186 else if (__ct.is(ctype_base::space, *__fmtb))
2187 {
2188 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2189 ;
2190 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2191 ;
2192 }
2193 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2194 {
2195 ++__b;
2196 ++__fmtb;
2197 }
2198 else
2199 __err = ios_base::failbit;
2200 }
2201 if (__b == __e)
2202 __err |= ios_base::eofbit;
2203 return __b;
2204}
2205
2206template <class _CharT, class _InputIterator>
2207typename time_get<_CharT, _InputIterator>::dateorder
2208time_get<_CharT, _InputIterator>::do_date_order() const
2209{
2210 return mdy;
2211}
2212
2213template <class _CharT, class _InputIterator>
2214_InputIterator
2215time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2216 ios_base& __iob,
2217 ios_base::iostate& __err,
2218 tm* __tm) const
2219{
2220 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2221 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2222}
2223
2224template <class _CharT, class _InputIterator>
2225_InputIterator
2226time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2227 ios_base& __iob,
2228 ios_base::iostate& __err,
2229 tm* __tm) const
2230{
Howard Hinnantc51e1022010-05-11 19:42:16 +00002231 const string_type& __fmt = this->__x();
2232 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2233}
2234
2235template <class _CharT, class _InputIterator>
2236_InputIterator
2237time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2238 ios_base& __iob,
2239 ios_base::iostate& __err,
2240 tm* __tm) const
2241{
2242 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2243 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2244 return __b;
2245}
2246
2247template <class _CharT, class _InputIterator>
2248_InputIterator
2249time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2250 ios_base& __iob,
2251 ios_base::iostate& __err,
2252 tm* __tm) const
2253{
2254 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2255 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2256 return __b;
2257}
2258
2259template <class _CharT, class _InputIterator>
2260_InputIterator
2261time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2262 ios_base& __iob,
2263 ios_base::iostate& __err,
2264 tm* __tm) const
2265{
2266 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2267 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2268 return __b;
2269}
2270
2271template <class _CharT, class _InputIterator>
2272_InputIterator
2273time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2274 ios_base& __iob,
2275 ios_base::iostate& __err, tm* __tm,
2276 char __fmt, char) const
2277{
2278 __err = ios_base::goodbit;
2279 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2280 switch (__fmt)
2281 {
2282 case 'a':
2283 case 'A':
2284 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2285 break;
2286 case 'b':
2287 case 'B':
2288 case 'h':
2289 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2290 break;
2291 case 'c':
2292 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002293 const string_type& __fm = this->__c();
2294 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002295 }
2296 break;
2297 case 'd':
2298 case 'e':
2299 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2300 break;
2301 case 'D':
2302 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002303 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2304 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002305 }
2306 break;
Howard Hinnantf60ff4e2011-04-10 17:54:14 +00002307 case 'F':
2308 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002309 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2310 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantf60ff4e2011-04-10 17:54:14 +00002311 }
2312 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002313 case 'H':
2314 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2315 break;
2316 case 'I':
2317 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2318 break;
2319 case 'j':
2320 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2321 break;
2322 case 'm':
2323 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2324 break;
2325 case 'M':
2326 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2327 break;
2328 case 'n':
2329 case 't':
2330 __get_white_space(__b, __e, __err, __ct);
2331 break;
2332 case 'p':
2333 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2334 break;
2335 case 'r':
2336 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002337 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2338 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002339 }
2340 break;
2341 case 'R':
2342 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002343 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2344 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002345 }
2346 break;
2347 case 'S':
2348 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2349 break;
2350 case 'T':
2351 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002352 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2353 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002354 }
2355 break;
2356 case 'w':
2357 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2358 break;
2359 case 'x':
2360 return do_get_date(__b, __e, __iob, __err, __tm);
2361 case 'X':
2362 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002363 const string_type& __fm = this->__X();
2364 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002365 }
2366 break;
2367 case 'y':
2368 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2369 break;
2370 case 'Y':
2371 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2372 break;
2373 case '%':
2374 __get_percent(__b, __e, __err, __ct);
2375 break;
2376 default:
2377 __err |= ios_base::failbit;
2378 }
2379 return __b;
2380}
2381
Louis Dionne9de5a672021-01-14 16:27:53 -05002382_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>)
2383_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002384
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002385class _LIBCPP_TYPE_VIS __time_get
Howard Hinnantc51e1022010-05-11 19:42:16 +00002386{
2387protected:
2388 locale_t __loc_;
2389
2390 __time_get(const char* __nm);
2391 __time_get(const string& __nm);
2392 ~__time_get();
2393};
2394
2395template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002396class _LIBCPP_TEMPLATE_VIS __time_get_storage
Howard Hinnantc51e1022010-05-11 19:42:16 +00002397 : public __time_get
2398{
2399protected:
2400 typedef basic_string<_CharT> string_type;
2401
2402 string_type __weeks_[14];
2403 string_type __months_[24];
2404 string_type __am_pm_[2];
2405 string_type __c_;
2406 string_type __r_;
2407 string_type __x_;
2408 string_type __X_;
2409
2410 explicit __time_get_storage(const char* __nm);
2411 explicit __time_get_storage(const string& __nm);
2412
Louis Dionne16fe2952018-07-11 23:14:33 +00002413 _LIBCPP_INLINE_VISIBILITY ~__time_get_storage() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002414
2415 time_base::dateorder __do_date_order() const;
2416
2417private:
2418 void init(const ctype<_CharT>&);
2419 string_type __analyze(char __fmt, const ctype<_CharT>&);
2420};
2421
Louis Dionne5254b372018-10-25 12:13:43 +00002422#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \
2423template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2424template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
2425template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
2426template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2427template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2428extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \
2429extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \
2430extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \
2431extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \
2432extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \
2433/**/
2434
2435_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
2436_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
2437#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
2438
Howard Hinnantc51e1022010-05-11 19:42:16 +00002439template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002440class _LIBCPP_TEMPLATE_VIS time_get_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00002441 : public time_get<_CharT, _InputIterator>,
2442 private __time_get_storage<_CharT>
2443{
2444public:
2445 typedef time_base::dateorder dateorder;
2446 typedef _InputIterator iter_type;
2447 typedef _CharT char_type;
2448 typedef basic_string<char_type> string_type;
2449
Howard Hinnant756c69b2010-09-22 16:48:34 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002451 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2452 : time_get<_CharT, _InputIterator>(__refs),
2453 __time_get_storage<_CharT>(__nm) {}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002455 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2456 : time_get<_CharT, _InputIterator>(__refs),
2457 __time_get_storage<_CharT>(__nm) {}
2458
2459protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002460 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002461 ~time_get_byname() {}
2462
Howard Hinnant756c69b2010-09-22 16:48:34 +00002463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002464 virtual dateorder do_date_order() const {return this->__do_date_order();}
2465private:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002467 virtual const string_type* __weeks() const {return this->__weeks_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002469 virtual const string_type* __months() const {return this->__months_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002470 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002471 virtual const string_type* __am_pm() const {return this->__am_pm_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002473 virtual const string_type& __c() const {return this->__c_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002475 virtual const string_type& __r() const {return this->__r_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002477 virtual const string_type& __x() const {return this->__x_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002479 virtual const string_type& __X() const {return this->__X_;}
2480};
2481
Louis Dionne9de5a672021-01-14 16:27:53 -05002482_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>)
2483_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002484
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002485class _LIBCPP_TYPE_VIS __time_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00002486{
2487 locale_t __loc_;
2488protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00002489 _LIBCPP_INLINE_VISIBILITY __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002490 __time_put(const char* __nm);
2491 __time_put(const string& __nm);
2492 ~__time_put();
2493 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2494 char __fmt, char __mod) const;
2495 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2496 char __fmt, char __mod) const;
2497};
2498
2499template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002500class _LIBCPP_TEMPLATE_VIS time_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00002501 : public locale::facet,
2502 private __time_put
2503{
2504public:
2505 typedef _CharT char_type;
2506 typedef _OutputIterator iter_type;
2507
Louis Dionne16fe2952018-07-11 23:14:33 +00002508 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002509 explicit time_put(size_t __refs = 0)
2510 : locale::facet(__refs) {}
2511
2512 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2513 const char_type* __pb, const char_type* __pe) const;
2514
Louis Dionne16fe2952018-07-11 23:14:33 +00002515 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002516 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2517 const tm* __tm, char __fmt, char __mod = 0) const
2518 {
2519 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2520 }
2521
2522 static locale::id id;
2523
2524protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00002525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002526 ~time_put() {}
2527 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2528 char __fmt, char __mod) const;
2529
Louis Dionne16fe2952018-07-11 23:14:33 +00002530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002531 explicit time_put(const char* __nm, size_t __refs)
2532 : locale::facet(__refs),
2533 __time_put(__nm) {}
Louis Dionne16fe2952018-07-11 23:14:33 +00002534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002535 explicit time_put(const string& __nm, size_t __refs)
2536 : locale::facet(__refs),
2537 __time_put(__nm) {}
2538};
2539
2540template <class _CharT, class _OutputIterator>
2541locale::id
2542time_put<_CharT, _OutputIterator>::id;
2543
2544template <class _CharT, class _OutputIterator>
2545_OutputIterator
2546time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2547 char_type __fl, const tm* __tm,
2548 const char_type* __pb,
2549 const char_type* __pe) const
2550{
2551 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2552 for (; __pb != __pe; ++__pb)
2553 {
2554 if (__ct.narrow(*__pb, 0) == '%')
2555 {
2556 if (++__pb == __pe)
2557 {
2558 *__s++ = __pb[-1];
2559 break;
2560 }
2561 char __mod = 0;
2562 char __fmt = __ct.narrow(*__pb, 0);
2563 if (__fmt == 'E' || __fmt == 'O')
2564 {
2565 if (++__pb == __pe)
2566 {
2567 *__s++ = __pb[-2];
2568 *__s++ = __pb[-1];
2569 break;
2570 }
2571 __mod = __fmt;
2572 __fmt = __ct.narrow(*__pb, 0);
2573 }
2574 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2575 }
2576 else
2577 *__s++ = *__pb;
2578 }
2579 return __s;
2580}
2581
2582template <class _CharT, class _OutputIterator>
2583_OutputIterator
Howard Hinnant28b24882011-12-01 20:21:04 +00002584time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002585 char_type, const tm* __tm,
2586 char __fmt, char __mod) const
2587{
2588 char_type __nar[100];
2589 char_type* __nb = __nar;
2590 char_type* __ne = __nb + 100;
2591 __do_put(__nb, __ne, __tm, __fmt, __mod);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002592 return _VSTD::copy(__nb, __ne, __s);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002593}
2594
Louis Dionne9de5a672021-01-14 16:27:53 -05002595_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>)
2596_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002597
2598template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002599class _LIBCPP_TEMPLATE_VIS time_put_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00002600 : public time_put<_CharT, _OutputIterator>
2601{
2602public:
Louis Dionne16fe2952018-07-11 23:14:33 +00002603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002604 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2605 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2606
Louis Dionne16fe2952018-07-11 23:14:33 +00002607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002608 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2609 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2610
2611protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00002612 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002613 ~time_put_byname() {}
2614};
2615
Louis Dionne9de5a672021-01-14 16:27:53 -05002616_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>)
2617_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002618
2619// money_base
2620
Howard Hinnant8331b762013-03-06 23:30:19 +00002621class _LIBCPP_TYPE_VIS money_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00002622{
2623public:
2624 enum part {none, space, symbol, sign, value};
2625 struct pattern {char field[4];};
2626
Louis Dionne16fe2952018-07-11 23:14:33 +00002627 _LIBCPP_INLINE_VISIBILITY money_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002628};
2629
2630// moneypunct
2631
2632template <class _CharT, bool _International = false>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002633class _LIBCPP_TEMPLATE_VIS moneypunct
Howard Hinnantc51e1022010-05-11 19:42:16 +00002634 : public locale::facet,
2635 public money_base
2636{
2637public:
2638 typedef _CharT char_type;
2639 typedef basic_string<char_type> string_type;
2640
Louis Dionne16fe2952018-07-11 23:14:33 +00002641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002642 explicit moneypunct(size_t __refs = 0)
2643 : locale::facet(__refs) {}
2644
Louis Dionne16fe2952018-07-11 23:14:33 +00002645 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
2646 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
2647 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();}
2648 _LIBCPP_INLINE_VISIBILITY string_type curr_symbol() const {return do_curr_symbol();}
2649 _LIBCPP_INLINE_VISIBILITY string_type positive_sign() const {return do_positive_sign();}
2650 _LIBCPP_INLINE_VISIBILITY string_type negative_sign() const {return do_negative_sign();}
2651 _LIBCPP_INLINE_VISIBILITY int frac_digits() const {return do_frac_digits();}
2652 _LIBCPP_INLINE_VISIBILITY pattern pos_format() const {return do_pos_format();}
2653 _LIBCPP_INLINE_VISIBILITY pattern neg_format() const {return do_neg_format();}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002654
2655 static locale::id id;
2656 static const bool intl = _International;
2657
2658protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00002659 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002660 ~moneypunct() {}
2661
2662 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2663 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2664 virtual string do_grouping() const {return string();}
2665 virtual string_type do_curr_symbol() const {return string_type();}
2666 virtual string_type do_positive_sign() const {return string_type();}
2667 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2668 virtual int do_frac_digits() const {return 0;}
2669 virtual pattern do_pos_format() const
Howard Hinnantb10e6cf2012-11-06 21:48:33 +00002670 {pattern __p = {{symbol, sign, none, value}}; return __p;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002671 virtual pattern do_neg_format() const
Howard Hinnantb10e6cf2012-11-06 21:48:33 +00002672 {pattern __p = {{symbol, sign, none, value}}; return __p;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002673};
2674
2675template <class _CharT, bool _International>
2676locale::id
2677moneypunct<_CharT, _International>::id;
2678
Howard Hinnant2c45cb42012-12-12 21:14:28 +00002679template <class _CharT, bool _International>
2680const bool
2681moneypunct<_CharT, _International>::intl;
2682
Louis Dionne9de5a672021-01-14 16:27:53 -05002683_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>)
2684_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>)
2685_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>)
2686_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002687
2688// moneypunct_byname
2689
2690template <class _CharT, bool _International = false>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002691class _LIBCPP_TEMPLATE_VIS moneypunct_byname
Howard Hinnant756c69b2010-09-22 16:48:34 +00002692 : public moneypunct<_CharT, _International>
Howard Hinnantc51e1022010-05-11 19:42:16 +00002693{
2694public:
2695 typedef money_base::pattern pattern;
2696 typedef _CharT char_type;
2697 typedef basic_string<char_type> string_type;
2698
Louis Dionne16fe2952018-07-11 23:14:33 +00002699 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002700 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2701 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2702
Louis Dionne16fe2952018-07-11 23:14:33 +00002703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002704 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2705 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2706
2707protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00002708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002709 ~moneypunct_byname() {}
2710
2711 virtual char_type do_decimal_point() const {return __decimal_point_;}
2712 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2713 virtual string do_grouping() const {return __grouping_;}
2714 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2715 virtual string_type do_positive_sign() const {return __positive_sign_;}
2716 virtual string_type do_negative_sign() const {return __negative_sign_;}
2717 virtual int do_frac_digits() const {return __frac_digits_;}
2718 virtual pattern do_pos_format() const {return __pos_format_;}
2719 virtual pattern do_neg_format() const {return __neg_format_;}
2720
2721private:
2722 char_type __decimal_point_;
2723 char_type __thousands_sep_;
2724 string __grouping_;
2725 string_type __curr_symbol_;
2726 string_type __positive_sign_;
2727 string_type __negative_sign_;
2728 int __frac_digits_;
2729 pattern __pos_format_;
2730 pattern __neg_format_;
2731
2732 void init(const char*);
2733};
2734
Shoaib Meenai094c3d22017-04-03 04:04:24 +00002735template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*);
2736template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*);
2737template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*);
2738template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002739
Louis Dionne9de5a672021-01-14 16:27:53 -05002740_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>)
2741_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>)
2742_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>)
2743_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002744
2745// money_get
2746
2747template <class _CharT>
2748class __money_get
2749{
2750protected:
2751 typedef _CharT char_type;
2752 typedef basic_string<char_type> string_type;
2753
Louis Dionne16fe2952018-07-11 23:14:33 +00002754 _LIBCPP_INLINE_VISIBILITY __money_get() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002755
2756 static void __gather_info(bool __intl, const locale& __loc,
2757 money_base::pattern& __pat, char_type& __dp,
2758 char_type& __ts, string& __grp,
2759 string_type& __sym, string_type& __psn,
2760 string_type& __nsn, int& __fd);
2761};
2762
2763template <class _CharT>
2764void
2765__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2766 money_base::pattern& __pat, char_type& __dp,
2767 char_type& __ts, string& __grp,
2768 string_type& __sym, string_type& __psn,
2769 string_type& __nsn, int& __fd)
2770{
2771 if (__intl)
2772 {
2773 const moneypunct<char_type, true>& __mp =
2774 use_facet<moneypunct<char_type, true> >(__loc);
2775 __pat = __mp.neg_format();
2776 __nsn = __mp.negative_sign();
2777 __psn = __mp.positive_sign();
2778 __dp = __mp.decimal_point();
2779 __ts = __mp.thousands_sep();
2780 __grp = __mp.grouping();
2781 __sym = __mp.curr_symbol();
2782 __fd = __mp.frac_digits();
2783 }
2784 else
2785 {
2786 const moneypunct<char_type, false>& __mp =
2787 use_facet<moneypunct<char_type, false> >(__loc);
2788 __pat = __mp.neg_format();
2789 __nsn = __mp.negative_sign();
2790 __psn = __mp.positive_sign();
2791 __dp = __mp.decimal_point();
2792 __ts = __mp.thousands_sep();
2793 __grp = __mp.grouping();
2794 __sym = __mp.curr_symbol();
2795 __fd = __mp.frac_digits();
2796 }
2797}
2798
Louis Dionne9de5a672021-01-14 16:27:53 -05002799_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>)
2800_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002801
2802template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002803class _LIBCPP_TEMPLATE_VIS money_get
Howard Hinnantc51e1022010-05-11 19:42:16 +00002804 : public locale::facet,
2805 private __money_get<_CharT>
2806{
2807public:
2808 typedef _CharT char_type;
2809 typedef _InputIterator iter_type;
2810 typedef basic_string<char_type> string_type;
2811
Louis Dionne16fe2952018-07-11 23:14:33 +00002812 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002813 explicit money_get(size_t __refs = 0)
2814 : locale::facet(__refs) {}
2815
Louis Dionne16fe2952018-07-11 23:14:33 +00002816 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002817 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2818 ios_base::iostate& __err, long double& __v) const
2819 {
2820 return do_get(__b, __e, __intl, __iob, __err, __v);
2821 }
2822
Louis Dionne16fe2952018-07-11 23:14:33 +00002823 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002824 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2825 ios_base::iostate& __err, string_type& __v) const
2826 {
2827 return do_get(__b, __e, __intl, __iob, __err, __v);
2828 }
2829
2830 static locale::id id;
2831
2832protected:
2833
Louis Dionne16fe2952018-07-11 23:14:33 +00002834 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002835 ~money_get() {}
Howard Hinnant3b6579a2010-08-22 00:02:43 +00002836
Howard Hinnantc51e1022010-05-11 19:42:16 +00002837 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2838 ios_base& __iob, ios_base::iostate& __err,
2839 long double& __v) const;
2840 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2841 ios_base& __iob, ios_base::iostate& __err,
2842 string_type& __v) const;
2843
2844private:
2845 static bool __do_get(iter_type& __b, iter_type __e,
2846 bool __intl, const locale& __loc,
2847 ios_base::fmtflags __flags, ios_base::iostate& __err,
2848 bool& __neg, const ctype<char_type>& __ct,
2849 unique_ptr<char_type, void(*)(void*)>& __wb,
2850 char_type*& __wn, char_type* __we);
2851};
2852
2853template <class _CharT, class _InputIterator>
2854locale::id
2855money_get<_CharT, _InputIterator>::id;
2856
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002857_LIBCPP_FUNC_VIS void __do_nothing(void*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002858
2859template <class _Tp>
2860_LIBCPP_HIDDEN
2861void
2862__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2863{
2864 bool __owns = __b.get_deleter() != __do_nothing;
Howard Hinnant28b24882011-12-01 20:21:04 +00002865 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002866 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2867 2 * __cur_cap : numeric_limits<size_t>::max();
Marshall Clow6c9ddc22014-10-27 19:08:10 +00002868 if (__new_cap == 0)
2869 __new_cap = sizeof(_Tp);
Howard Hinnant28b24882011-12-01 20:21:04 +00002870 size_t __n_off = static_cast<size_t>(__n - __b.get());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002871 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2872 if (__t == 0)
2873 __throw_bad_alloc();
2874 if (__owns)
2875 __b.release();
2876 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2877 __new_cap /= sizeof(_Tp);
2878 __n = __b.get() + __n_off;
2879 __e = __b.get() + __new_cap;
2880}
2881
2882// true == success
2883template <class _CharT, class _InputIterator>
2884bool
2885money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2886 bool __intl, const locale& __loc,
2887 ios_base::fmtflags __flags,
2888 ios_base::iostate& __err,
2889 bool& __neg,
2890 const ctype<char_type>& __ct,
2891 unique_ptr<char_type, void(*)(void*)>& __wb,
2892 char_type*& __wn, char_type* __we)
2893{
2894 const unsigned __bz = 100;
2895 unsigned __gbuf[__bz];
2896 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
2897 unsigned* __gn = __gb.get();
2898 unsigned* __ge = __gn + __bz;
2899 money_base::pattern __pat;
2900 char_type __dp;
2901 char_type __ts;
2902 string __grp;
2903 string_type __sym;
2904 string_type __psn;
2905 string_type __nsn;
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00002906 // Capture the spaces read into money_base::{space,none} so they
2907 // can be compared to initial spaces in __sym.
2908 string_type __spaces;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002909 int __fd;
2910 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
2911 __sym, __psn, __nsn, __fd);
2912 const string_type* __trailing_sign = 0;
2913 __wn = __wb.get();
2914 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
2915 {
2916 switch (__pat.field[__p])
2917 {
2918 case money_base::space:
2919 if (__p != 3)
2920 {
2921 if (__ct.is(ctype_base::space, *__b))
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00002922 __spaces.push_back(*__b++);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002923 else
2924 {
2925 __err |= ios_base::failbit;
2926 return false;
2927 }
2928 }
Eric Fiselier4db80032017-05-05 20:32:26 +00002929 _LIBCPP_FALLTHROUGH();
Howard Hinnantc51e1022010-05-11 19:42:16 +00002930 case money_base::none:
2931 if (__p != 3)
2932 {
2933 while (__b != __e && __ct.is(ctype_base::space, *__b))
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00002934 __spaces.push_back(*__b++);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002935 }
2936 break;
2937 case money_base::sign:
2938 if (__psn.size() + __nsn.size() > 0)
2939 {
2940 if (__psn.size() == 0 || __nsn.size() == 0)
2941 { // sign is optional
2942 if (__psn.size() > 0)
2943 { // __nsn.size() == 0
2944 if (*__b == __psn[0])
2945 {
2946 ++__b;
2947 if (__psn.size() > 1)
2948 __trailing_sign = &__psn;
2949 }
2950 else
2951 __neg = true;
2952 }
2953 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
2954 {
2955 ++__b;
2956 __neg = true;
2957 if (__nsn.size() > 1)
2958 __trailing_sign = &__nsn;
2959 }
2960 }
2961 else // sign is required
2962 {
2963 if (*__b == __psn[0])
2964 {
2965 ++__b;
2966 if (__psn.size() > 1)
2967 __trailing_sign = &__psn;
2968 }
2969 else if (*__b == __nsn[0])
2970 {
2971 ++__b;
2972 __neg = true;
2973 if (__nsn.size() > 1)
2974 __trailing_sign = &__nsn;
2975 }
2976 else
2977 {
2978 __err |= ios_base::failbit;
2979 return false;
2980 }
2981 }
2982 }
2983 break;
2984 case money_base::symbol:
2985 {
2986 bool __more_needed = __trailing_sign ||
2987 (__p < 2) ||
2988 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
Marshall Clowdfcbb432013-10-13 01:02:45 +00002989 bool __sb = (__flags & ios_base::showbase) != 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002990 if (__sb || __more_needed)
2991 {
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00002992 typename string_type::const_iterator __sym_space_end = __sym.begin();
2993 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
2994 __pat.field[__p - 1] == money_base::space)) {
2995 // Match spaces we've already read against spaces at
2996 // the beginning of __sym.
2997 while (__sym_space_end != __sym.end() &&
2998 __ct.is(ctype_base::space, *__sym_space_end))
2999 ++__sym_space_end;
3000 const size_t __num_spaces = __sym_space_end - __sym.begin();
3001 if (__num_spaces > __spaces.size() ||
3002 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3003 __sym.begin())) {
3004 // No match. Put __sym_space_end back at the
3005 // beginning of __sym, which will prevent a
3006 // match in the next loop.
3007 __sym_space_end = __sym.begin();
3008 }
3009 }
3010 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3011 while (__sym_curr_char != __sym.end() && __b != __e &&
3012 *__b == *__sym_curr_char) {
3013 ++__b;
3014 ++__sym_curr_char;
3015 }
3016 if (__sb && __sym_curr_char != __sym.end())
Howard Hinnantc51e1022010-05-11 19:42:16 +00003017 {
3018 __err |= ios_base::failbit;
3019 return false;
3020 }
3021 }
3022 }
3023 break;
3024 case money_base::value:
3025 {
3026 unsigned __ng = 0;
3027 for (; __b != __e; ++__b)
3028 {
3029 char_type __c = *__b;
3030 if (__ct.is(ctype_base::digit, __c))
3031 {
3032 if (__wn == __we)
3033 __double_or_nothing(__wb, __wn, __we);
3034 *__wn++ = __c;
3035 ++__ng;
3036 }
3037 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3038 {
3039 if (__gn == __ge)
3040 __double_or_nothing(__gb, __gn, __ge);
3041 *__gn++ = __ng;
3042 __ng = 0;
3043 }
3044 else
3045 break;
3046 }
3047 if (__gb.get() != __gn && __ng > 0)
3048 {
3049 if (__gn == __ge)
3050 __double_or_nothing(__gb, __gn, __ge);
3051 *__gn++ = __ng;
3052 }
3053 if (__fd > 0)
3054 {
3055 if (__b == __e || *__b != __dp)
3056 {
3057 __err |= ios_base::failbit;
3058 return false;
3059 }
3060 for (++__b; __fd > 0; --__fd, ++__b)
3061 {
3062 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3063 {
3064 __err |= ios_base::failbit;
3065 return false;
3066 }
3067 if (__wn == __we)
3068 __double_or_nothing(__wb, __wn, __we);
3069 *__wn++ = *__b;
3070 }
3071 }
3072 if (__wn == __wb.get())
3073 {
3074 __err |= ios_base::failbit;
3075 return false;
3076 }
3077 }
3078 break;
3079 }
3080 }
3081 if (__trailing_sign)
3082 {
3083 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3084 {
3085 if (__b == __e || *__b != (*__trailing_sign)[__i])
3086 {
3087 __err |= ios_base::failbit;
3088 return false;
3089 }
3090 }
3091 }
3092 if (__gb.get() != __gn)
3093 {
3094 ios_base::iostate __et = ios_base::goodbit;
3095 __check_grouping(__grp, __gb.get(), __gn, __et);
3096 if (__et)
3097 {
3098 __err |= ios_base::failbit;
3099 return false;
3100 }
3101 }
3102 return true;
3103}
3104
3105template <class _CharT, class _InputIterator>
3106_InputIterator
3107money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3108 bool __intl, ios_base& __iob,
3109 ios_base::iostate& __err,
3110 long double& __v) const
3111{
Howard Hinnant28b24882011-12-01 20:21:04 +00003112 const int __bz = 100;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003113 char_type __wbuf[__bz];
3114 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3115 char_type* __wn;
3116 char_type* __we = __wbuf + __bz;
3117 locale __loc = __iob.getloc();
3118 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3119 bool __neg = false;
3120 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3121 __wb, __wn, __we))
3122 {
3123 const char __src[] = "0123456789";
3124 char_type __atoms[sizeof(__src)-1];
3125 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3126 char __nbuf[__bz];
3127 char* __nc = __nbuf;
Bruce Mitchener170d8972020-11-24 12:53:53 -05003128 unique_ptr<char, void(*)(void*)> __h(nullptr, free);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003129 if (__wn - __wb.get() > __bz-2)
3130 {
Howard Hinnant28b24882011-12-01 20:21:04 +00003131 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
Bruce Mitchener170d8972020-11-24 12:53:53 -05003132 if (__h.get() == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003133 __throw_bad_alloc();
3134 __nc = __h.get();
3135 }
3136 if (__neg)
3137 *__nc++ = '-';
3138 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
Marshall Clow1e68fd42013-03-22 02:14:40 +00003139 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
Howard Hinnantc51e1022010-05-11 19:42:16 +00003140 *__nc = char();
3141 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3142 __throw_runtime_error("money_get error");
3143 }
3144 if (__b == __e)
3145 __err |= ios_base::eofbit;
3146 return __b;
3147}
3148
3149template <class _CharT, class _InputIterator>
3150_InputIterator
3151money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3152 bool __intl, ios_base& __iob,
3153 ios_base::iostate& __err,
3154 string_type& __v) const
3155{
Howard Hinnant28b24882011-12-01 20:21:04 +00003156 const int __bz = 100;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003157 char_type __wbuf[__bz];
3158 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3159 char_type* __wn;
3160 char_type* __we = __wbuf + __bz;
3161 locale __loc = __iob.getloc();
3162 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3163 bool __neg = false;
3164 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3165 __wb, __wn, __we))
3166 {
3167 __v.clear();
3168 if (__neg)
3169 __v.push_back(__ct.widen('-'));
3170 char_type __z = __ct.widen('0');
3171 char_type* __w;
3172 for (__w = __wb.get(); __w < __wn-1; ++__w)
3173 if (*__w != __z)
3174 break;
3175 __v.append(__w, __wn);
3176 }
3177 if (__b == __e)
3178 __err |= ios_base::eofbit;
3179 return __b;
3180}
3181
Louis Dionne9de5a672021-01-14 16:27:53 -05003182_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>)
3183_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003184
3185// money_put
3186
3187template <class _CharT>
3188class __money_put
3189{
3190protected:
3191 typedef _CharT char_type;
3192 typedef basic_string<char_type> string_type;
3193
Louis Dionne16fe2952018-07-11 23:14:33 +00003194 _LIBCPP_INLINE_VISIBILITY __money_put() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00003195
3196 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3197 money_base::pattern& __pat, char_type& __dp,
3198 char_type& __ts, string& __grp,
3199 string_type& __sym, string_type& __sn,
3200 int& __fd);
3201 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3202 ios_base::fmtflags __flags,
3203 const char_type* __db, const char_type* __de,
3204 const ctype<char_type>& __ct, bool __neg,
3205 const money_base::pattern& __pat, char_type __dp,
3206 char_type __ts, const string& __grp,
3207 const string_type& __sym, const string_type& __sn,
3208 int __fd);
3209};
3210
3211template <class _CharT>
3212void
3213__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3214 money_base::pattern& __pat, char_type& __dp,
3215 char_type& __ts, string& __grp,
3216 string_type& __sym, string_type& __sn,
3217 int& __fd)
3218{
3219 if (__intl)
3220 {
3221 const moneypunct<char_type, true>& __mp =
3222 use_facet<moneypunct<char_type, true> >(__loc);
3223 if (__neg)
3224 {
3225 __pat = __mp.neg_format();
3226 __sn = __mp.negative_sign();
3227 }
3228 else
3229 {
3230 __pat = __mp.pos_format();
3231 __sn = __mp.positive_sign();
3232 }
3233 __dp = __mp.decimal_point();
3234 __ts = __mp.thousands_sep();
3235 __grp = __mp.grouping();
3236 __sym = __mp.curr_symbol();
3237 __fd = __mp.frac_digits();
3238 }
3239 else
3240 {
3241 const moneypunct<char_type, false>& __mp =
3242 use_facet<moneypunct<char_type, false> >(__loc);
3243 if (__neg)
3244 {
3245 __pat = __mp.neg_format();
3246 __sn = __mp.negative_sign();
3247 }
3248 else
3249 {
3250 __pat = __mp.pos_format();
3251 __sn = __mp.positive_sign();
3252 }
3253 __dp = __mp.decimal_point();
3254 __ts = __mp.thousands_sep();
3255 __grp = __mp.grouping();
3256 __sym = __mp.curr_symbol();
3257 __fd = __mp.frac_digits();
3258 }
3259}
3260
3261template <class _CharT>
3262void
3263__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3264 ios_base::fmtflags __flags,
3265 const char_type* __db, const char_type* __de,
3266 const ctype<char_type>& __ct, bool __neg,
3267 const money_base::pattern& __pat, char_type __dp,
3268 char_type __ts, const string& __grp,
3269 const string_type& __sym, const string_type& __sn,
3270 int __fd)
3271{
3272 __me = __mb;
3273 for (unsigned __p = 0; __p < 4; ++__p)
3274 {
3275 switch (__pat.field[__p])
3276 {
3277 case money_base::none:
3278 __mi = __me;
3279 break;
3280 case money_base::space:
3281 __mi = __me;
3282 *__me++ = __ct.widen(' ');
3283 break;
3284 case money_base::sign:
3285 if (!__sn.empty())
3286 *__me++ = __sn[0];
3287 break;
3288 case money_base::symbol:
3289 if (!__sym.empty() && (__flags & ios_base::showbase))
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00003290 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003291 break;
3292 case money_base::value:
3293 {
3294 // remember start of value so we can reverse it
3295 char_type* __t = __me;
3296 // find beginning of digits
3297 if (__neg)
3298 ++__db;
3299 // find end of digits
3300 const char_type* __d;
3301 for (__d = __db; __d < __de; ++__d)
3302 if (!__ct.is(ctype_base::digit, *__d))
3303 break;
3304 // print fractional part
3305 if (__fd > 0)
3306 {
3307 int __f;
3308 for (__f = __fd; __d > __db && __f > 0; --__f)
3309 *__me++ = *--__d;
3310 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3311 for (; __f > 0; --__f)
3312 *__me++ = __z;
3313 *__me++ = __dp;
3314 }
3315 // print units part
3316 if (__d == __db)
3317 {
3318 *__me++ = __ct.widen('0');
3319 }
3320 else
3321 {
3322 unsigned __ng = 0;
3323 unsigned __ig = 0;
3324 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3325 : static_cast<unsigned>(__grp[__ig]);
3326 while (__d != __db)
3327 {
3328 if (__ng == __gl)
3329 {
3330 *__me++ = __ts;
3331 __ng = 0;
3332 if (++__ig < __grp.size())
3333 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3334 numeric_limits<unsigned>::max() :
3335 static_cast<unsigned>(__grp[__ig]);
3336 }
3337 *__me++ = *--__d;
3338 ++__ng;
3339 }
3340 }
3341 // reverse it
3342 reverse(__t, __me);
3343 }
3344 break;
3345 }
3346 }
3347 // print rest of sign, if any
3348 if (__sn.size() > 1)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00003349 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003350 // set alignment
3351 if ((__flags & ios_base::adjustfield) == ios_base::left)
3352 __mi = __me;
3353 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3354 __mi = __mb;
3355}
3356
Louis Dionne9de5a672021-01-14 16:27:53 -05003357_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>)
3358_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003359
3360template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00003361class _LIBCPP_TEMPLATE_VIS money_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00003362 : public locale::facet,
3363 private __money_put<_CharT>
3364{
3365public:
3366 typedef _CharT char_type;
3367 typedef _OutputIterator iter_type;
3368 typedef basic_string<char_type> string_type;
3369
Louis Dionne16fe2952018-07-11 23:14:33 +00003370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003371 explicit money_put(size_t __refs = 0)
3372 : locale::facet(__refs) {}
3373
Louis Dionne16fe2952018-07-11 23:14:33 +00003374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003375 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3376 long double __units) const
3377 {
3378 return do_put(__s, __intl, __iob, __fl, __units);
3379 }
3380
Louis Dionne16fe2952018-07-11 23:14:33 +00003381 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003382 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3383 const string_type& __digits) const
3384 {
3385 return do_put(__s, __intl, __iob, __fl, __digits);
3386 }
3387
3388 static locale::id id;
3389
3390protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00003391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003392 ~money_put() {}
3393
3394 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3395 char_type __fl, long double __units) const;
3396 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3397 char_type __fl, const string_type& __digits) const;
3398};
3399
3400template <class _CharT, class _OutputIterator>
3401locale::id
3402money_put<_CharT, _OutputIterator>::id;
3403
3404template <class _CharT, class _OutputIterator>
3405_OutputIterator
3406money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3407 ios_base& __iob, char_type __fl,
3408 long double __units) const
3409{
3410 // convert to char
3411 const size_t __bs = 100;
3412 char __buf[__bs];
3413 char* __bb = __buf;
3414 char_type __digits[__bs];
3415 char_type* __db = __digits;
Brad Smithaee2d992021-01-21 19:39:52 -05003416 int __n = snprintf(__bb, __bs, "%.0Lf", __units);
Bruce Mitchener170d8972020-11-24 12:53:53 -05003417 unique_ptr<char, void(*)(void*)> __hn(nullptr, free);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003418 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3419 // secure memory for digit storage
Brad Smithaee2d992021-01-21 19:39:52 -05003420 if (static_cast<size_t>(__n) > __bs-1)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003421 {
Brad Smithaee2d992021-01-21 19:39:52 -05003422 __n = __libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units);
3423 if (__n == -1)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003424 __throw_bad_alloc();
3425 __hn.reset(__bb);
Brad Smithaee2d992021-01-21 19:39:52 -05003426 __hd.reset((char_type*)malloc(static_cast<size_t>(__n) * sizeof(char_type)));
Howard Hinnant03de6f92012-03-07 20:37:43 +00003427 if (__hd == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003428 __throw_bad_alloc();
3429 __db = __hd.get();
3430 }
3431 // gather info
3432 locale __loc = __iob.getloc();
3433 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3434 __ct.widen(__bb, __bb + __n, __db);
3435 bool __neg = __n > 0 && __bb[0] == '-';
3436 money_base::pattern __pat;
3437 char_type __dp;
3438 char_type __ts;
3439 string __grp;
3440 string_type __sym;
3441 string_type __sn;
3442 int __fd;
3443 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3444 // secure memory for formatting
3445 char_type __mbuf[__bs];
3446 char_type* __mb = __mbuf;
3447 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
Brad Smithaee2d992021-01-21 19:39:52 -05003448 size_t __exn = __n > __fd ?
3449 (static_cast<size_t>(__n) - static_cast<size_t>(__fd)) * 2 +
3450 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
Howard Hinnant28b24882011-12-01 20:21:04 +00003451 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003452 if (__exn > __bs)
3453 {
3454 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3455 __mb = __hw.get();
3456 if (__mb == 0)
3457 __throw_bad_alloc();
3458 }
3459 // format
3460 char_type* __mi;
3461 char_type* __me;
3462 this->__format(__mb, __mi, __me, __iob.flags(),
3463 __db, __db + __n, __ct,
3464 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3465 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3466}
3467
3468template <class _CharT, class _OutputIterator>
3469_OutputIterator
3470money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3471 ios_base& __iob, char_type __fl,
3472 const string_type& __digits) const
3473{
3474 // gather info
3475 locale __loc = __iob.getloc();
3476 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3477 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3478 money_base::pattern __pat;
3479 char_type __dp;
3480 char_type __ts;
3481 string __grp;
3482 string_type __sym;
3483 string_type __sn;
3484 int __fd;
3485 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3486 // secure memory for formatting
3487 char_type __mbuf[100];
3488 char_type* __mb = __mbuf;
3489 unique_ptr<char_type, void(*)(void*)> __h(0, free);
Howard Hinnant28b24882011-12-01 20:21:04 +00003490 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3491 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3492 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3493 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003494 if (__exn > 100)
3495 {
3496 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3497 __mb = __h.get();
3498 if (__mb == 0)
3499 __throw_bad_alloc();
3500 }
3501 // format
3502 char_type* __mi;
3503 char_type* __me;
3504 this->__format(__mb, __mi, __me, __iob.flags(),
3505 __digits.data(), __digits.data() + __digits.size(), __ct,
3506 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3507 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3508}
3509
Louis Dionne9de5a672021-01-14 16:27:53 -05003510_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>)
3511_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003512
3513// messages
3514
Howard Hinnant8331b762013-03-06 23:30:19 +00003515class _LIBCPP_TYPE_VIS messages_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00003516{
3517public:
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003518 typedef ptrdiff_t catalog;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003519
Louis Dionne16fe2952018-07-11 23:14:33 +00003520 _LIBCPP_INLINE_VISIBILITY messages_base() {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00003521};
3522
3523template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00003524class _LIBCPP_TEMPLATE_VIS messages
Howard Hinnantc51e1022010-05-11 19:42:16 +00003525 : public locale::facet,
3526 public messages_base
3527{
3528public:
3529 typedef _CharT char_type;
3530 typedef basic_string<_CharT> string_type;
3531
Louis Dionne16fe2952018-07-11 23:14:33 +00003532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003533 explicit messages(size_t __refs = 0)
3534 : locale::facet(__refs) {}
3535
Louis Dionne16fe2952018-07-11 23:14:33 +00003536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003537 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3538 {
3539 return do_open(__nm, __loc);
3540 }
3541
Louis Dionne16fe2952018-07-11 23:14:33 +00003542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003543 string_type get(catalog __c, int __set, int __msgid,
3544 const string_type& __dflt) const
3545 {
3546 return do_get(__c, __set, __msgid, __dflt);
3547 }
3548
Louis Dionne16fe2952018-07-11 23:14:33 +00003549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003550 void close(catalog __c) const
3551 {
3552 do_close(__c);
3553 }
3554
3555 static locale::id id;
3556
3557protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00003558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003559 ~messages() {}
3560
3561 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3562 virtual string_type do_get(catalog, int __set, int __msgid,
3563 const string_type& __dflt) const;
3564 virtual void do_close(catalog) const;
3565};
3566
3567template <class _CharT>
3568locale::id
3569messages<_CharT>::id;
3570
3571template <class _CharT>
3572typename messages<_CharT>::catalog
3573messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3574{
Ed Schouten118b6032015-03-11 16:39:36 +00003575#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +00003576 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003577 if (__cat != -1)
3578 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3579 return __cat;
Ed Schouten118b6032015-03-11 16:39:36 +00003580#else // !_LIBCPP_HAS_CATOPEN
Arthur O'Dwyer61b40752021-04-18 22:17:44 -04003581 (void)__nm;
Ed Schouten118b6032015-03-11 16:39:36 +00003582 return -1;
3583#endif // _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003584}
3585
3586template <class _CharT>
3587typename messages<_CharT>::string_type
3588messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3589 const string_type& __dflt) const
3590{
Ed Schouten118b6032015-03-11 16:39:36 +00003591#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003592 string __ndflt;
3593 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3594 __dflt.c_str(),
3595 __dflt.c_str() + __dflt.size());
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003596 if (__c != -1)
3597 __c <<= 1;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +00003598 nl_catd __cat = (nl_catd)__c;
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003599 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
Howard Hinnantc51e1022010-05-11 19:42:16 +00003600 string_type __w;
3601 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
Arthur O'Dwyer22236632020-12-07 21:50:15 -05003602 __n, __n + _VSTD::strlen(__n));
Howard Hinnantc51e1022010-05-11 19:42:16 +00003603 return __w;
Ed Schouten118b6032015-03-11 16:39:36 +00003604#else // !_LIBCPP_HAS_CATOPEN
Arthur O'Dwyer61b40752021-04-18 22:17:44 -04003605 (void)__c;
3606 (void)__set;
3607 (void)__msgid;
Ed Schouten118b6032015-03-11 16:39:36 +00003608 return __dflt;
3609#endif // _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003610}
3611
3612template <class _CharT>
3613void
3614messages<_CharT>::do_close(catalog __c) const
3615{
Ed Schouten118b6032015-03-11 16:39:36 +00003616#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003617 if (__c != -1)
3618 __c <<= 1;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +00003619 nl_catd __cat = (nl_catd)__c;
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003620 catclose(__cat);
Petr Hosek399c5112019-01-13 22:15:37 +00003621#else // !_LIBCPP_HAS_CATOPEN
Arthur O'Dwyer61b40752021-04-18 22:17:44 -04003622 (void)__c;
Ed Schouten118b6032015-03-11 16:39:36 +00003623#endif // _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003624}
3625
Louis Dionne9de5a672021-01-14 16:27:53 -05003626_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>)
3627_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003628
3629template <class _CharT>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00003630class _LIBCPP_TEMPLATE_VIS messages_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00003631 : public messages<_CharT>
3632{
3633public:
3634 typedef messages_base::catalog catalog;
3635 typedef basic_string<_CharT> string_type;
3636
Louis Dionne16fe2952018-07-11 23:14:33 +00003637 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003638 explicit messages_byname(const char*, size_t __refs = 0)
3639 : messages<_CharT>(__refs) {}
3640
Louis Dionne16fe2952018-07-11 23:14:33 +00003641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003642 explicit messages_byname(const string&, size_t __refs = 0)
3643 : messages<_CharT>(__refs) {}
3644
3645protected:
Louis Dionne16fe2952018-07-11 23:14:33 +00003646 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00003647 ~messages_byname() {}
3648};
3649
Louis Dionne9de5a672021-01-14 16:27:53 -05003650_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>)
3651_LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003652
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003653template<class _Codecvt, class _Elem = wchar_t,
3654 class _Wide_alloc = allocator<_Elem>,
3655 class _Byte_alloc = allocator<char> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00003656class _LIBCPP_TEMPLATE_VIS wstring_convert
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003657{
3658public:
3659 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3660 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3661 typedef typename _Codecvt::state_type state_type;
3662 typedef typename wide_string::traits_type::int_type int_type;
3663
3664private:
3665 byte_string __byte_err_string_;
3666 wide_string __wide_err_string_;
3667 _Codecvt* __cvtptr_;
3668 state_type __cvtstate_;
3669 size_t __cvtcount_;
3670
3671 wstring_convert(const wstring_convert& __wc);
3672 wstring_convert& operator=(const wstring_convert& __wc);
3673public:
Marek Kurdejcd0bd6a2021-01-19 08:21:09 +01003674#ifndef _LIBCPP_CXX03_LANG
Louis Dionne16fe2952018-07-11 23:14:33 +00003675 _LIBCPP_INLINE_VISIBILITY
Marek Kurdejcd0bd6a2021-01-19 08:21:09 +01003676 wstring_convert() : wstring_convert(new _Codecvt) {}
3677 _LIBCPP_INLINE_VISIBILITY
3678 explicit wstring_convert(_Codecvt* __pcvt);
3679#else
3680 _LIBCPP_INLINE_VISIBILITY
3681 _LIBCPP_EXPLICIT_AFTER_CXX11
3682 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3683#endif
3684
Louis Dionne16fe2952018-07-11 23:14:33 +00003685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003686 wstring_convert(_Codecvt* __pcvt, state_type __state);
Marshall Clowccaa0fb2013-08-27 20:18:59 +00003687 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003688 const wide_string& __wide_err = wide_string());
Eric Fiselierf07d88c2017-04-19 01:34:08 +00003689#ifndef _LIBCPP_CXX03_LANG
Louis Dionne16fe2952018-07-11 23:14:33 +00003690 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003691 wstring_convert(wstring_convert&& __wc);
3692#endif
3693 ~wstring_convert();
3694
Louis Dionne16fe2952018-07-11 23:14:33 +00003695 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003696 wide_string from_bytes(char __byte)
3697 {return from_bytes(&__byte, &__byte+1);}
Louis Dionne16fe2952018-07-11 23:14:33 +00003698 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003699 wide_string from_bytes(const char* __ptr)
3700 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
Louis Dionne16fe2952018-07-11 23:14:33 +00003701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003702 wide_string from_bytes(const byte_string& __str)
3703 {return from_bytes(__str.data(), __str.data() + __str.size());}
3704 wide_string from_bytes(const char* __first, const char* __last);
3705
Louis Dionne16fe2952018-07-11 23:14:33 +00003706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003707 byte_string to_bytes(_Elem __wchar)
3708 {return to_bytes(&__wchar, &__wchar+1);}
Louis Dionne16fe2952018-07-11 23:14:33 +00003709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003710 byte_string to_bytes(const _Elem* __wptr)
3711 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
Louis Dionne16fe2952018-07-11 23:14:33 +00003712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003713 byte_string to_bytes(const wide_string& __wstr)
3714 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3715 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3716
Louis Dionne16fe2952018-07-11 23:14:33 +00003717 _LIBCPP_INLINE_VISIBILITY
Marshall Clowccaa0fb2013-08-27 20:18:59 +00003718 size_t converted() const _NOEXCEPT {return __cvtcount_;}
Louis Dionne16fe2952018-07-11 23:14:33 +00003719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003720 state_type state() const {return __cvtstate_;}
3721};
3722
3723template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00003724inline
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003725wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3726 wstring_convert(_Codecvt* __pcvt)
3727 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3728{
3729}
3730
3731template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00003732inline
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003733wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3734 wstring_convert(_Codecvt* __pcvt, state_type __state)
3735 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3736{
3737}
3738
3739template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3740wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3741 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3742 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3743 __cvtstate_(), __cvtcount_(0)
3744{
3745 __cvtptr_ = new _Codecvt;
3746}
3747
Eric Fiselierf07d88c2017-04-19 01:34:08 +00003748#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003749
3750template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00003751inline
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003752wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3753 wstring_convert(wstring_convert&& __wc)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00003754 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3755 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003756 __cvtptr_(__wc.__cvtptr_),
Eric Fiselier35c67232016-06-26 22:56:26 +00003757 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_)
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003758{
3759 __wc.__cvtptr_ = nullptr;
3760}
3761
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04003762#endif // _LIBCPP_CXX03_LANG
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003763
3764template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3765wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3766{
3767 delete __cvtptr_;
3768}
3769
3770template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3771typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3772wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3773 from_bytes(const char* __frm, const char* __frm_end)
3774{
3775 __cvtcount_ = 0;
3776 if (__cvtptr_ != nullptr)
3777 {
3778 wide_string __ws(2*(__frm_end - __frm), _Elem());
Howard Hinnant16d54f22012-07-12 18:07:41 +00003779 if (__frm != __frm_end)
3780 __ws.resize(__ws.capacity());
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003781 codecvt_base::result __r = codecvt_base::ok;
3782 state_type __st = __cvtstate_;
3783 if (__frm != __frm_end)
3784 {
3785 _Elem* __to = &__ws[0];
3786 _Elem* __to_end = __to + __ws.size();
3787 const char* __frm_nxt;
3788 do
3789 {
3790 _Elem* __to_nxt;
3791 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3792 __to, __to_end, __to_nxt);
3793 __cvtcount_ += __frm_nxt - __frm;
3794 if (__frm_nxt == __frm)
3795 {
3796 __r = codecvt_base::error;
3797 }
3798 else if (__r == codecvt_base::noconv)
3799 {
3800 __ws.resize(__to - &__ws[0]);
3801 // This only gets executed if _Elem is char
3802 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3803 __frm = __frm_nxt;
3804 __r = codecvt_base::ok;
3805 }
3806 else if (__r == codecvt_base::ok)
3807 {
3808 __ws.resize(__to_nxt - &__ws[0]);
3809 __frm = __frm_nxt;
3810 }
3811 else if (__r == codecvt_base::partial)
3812 {
3813 ptrdiff_t __s = __to_nxt - &__ws[0];
3814 __ws.resize(2 * __s);
3815 __to = &__ws[0] + __s;
3816 __to_end = &__ws[0] + __ws.size();
3817 __frm = __frm_nxt;
3818 }
3819 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3820 }
3821 if (__r == codecvt_base::ok)
3822 return __ws;
3823 }
Marshall Clow8fea1612016-08-25 15:09:01 +00003824
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003825 if (__wide_err_string_.empty())
Marshall Clow8fea1612016-08-25 15:09:01 +00003826 __throw_range_error("wstring_convert: from_bytes error");
3827
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003828 return __wide_err_string_;
3829}
3830
3831template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3832typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3833wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3834 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3835{
3836 __cvtcount_ = 0;
3837 if (__cvtptr_ != nullptr)
3838 {
3839 byte_string __bs(2*(__frm_end - __frm), char());
Howard Hinnant16d54f22012-07-12 18:07:41 +00003840 if (__frm != __frm_end)
3841 __bs.resize(__bs.capacity());
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003842 codecvt_base::result __r = codecvt_base::ok;
3843 state_type __st = __cvtstate_;
3844 if (__frm != __frm_end)
3845 {
3846 char* __to = &__bs[0];
3847 char* __to_end = __to + __bs.size();
3848 const _Elem* __frm_nxt;
3849 do
3850 {
3851 char* __to_nxt;
3852 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3853 __to, __to_end, __to_nxt);
3854 __cvtcount_ += __frm_nxt - __frm;
3855 if (__frm_nxt == __frm)
3856 {
3857 __r = codecvt_base::error;
3858 }
3859 else if (__r == codecvt_base::noconv)
3860 {
3861 __bs.resize(__to - &__bs[0]);
3862 // This only gets executed if _Elem is char
3863 __bs.append((const char*)__frm, (const char*)__frm_end);
3864 __frm = __frm_nxt;
3865 __r = codecvt_base::ok;
3866 }
3867 else if (__r == codecvt_base::ok)
3868 {
3869 __bs.resize(__to_nxt - &__bs[0]);
3870 __frm = __frm_nxt;
3871 }
3872 else if (__r == codecvt_base::partial)
3873 {
3874 ptrdiff_t __s = __to_nxt - &__bs[0];
3875 __bs.resize(2 * __s);
3876 __to = &__bs[0] + __s;
3877 __to_end = &__bs[0] + __bs.size();
3878 __frm = __frm_nxt;
3879 }
3880 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3881 }
3882 if (__r == codecvt_base::ok)
3883 {
3884 size_t __s = __bs.size();
3885 __bs.resize(__bs.capacity());
3886 char* __to = &__bs[0] + __s;
3887 char* __to_end = __to + __bs.size();
3888 do
3889 {
3890 char* __to_nxt;
3891 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3892 if (__r == codecvt_base::noconv)
3893 {
3894 __bs.resize(__to - &__bs[0]);
3895 __r = codecvt_base::ok;
3896 }
3897 else if (__r == codecvt_base::ok)
3898 {
3899 __bs.resize(__to_nxt - &__bs[0]);
3900 }
3901 else if (__r == codecvt_base::partial)
3902 {
Howard Hinnant28b24882011-12-01 20:21:04 +00003903 ptrdiff_t __sp = __to_nxt - &__bs[0];
3904 __bs.resize(2 * __sp);
3905 __to = &__bs[0] + __sp;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003906 __to_end = &__bs[0] + __bs.size();
3907 }
3908 } while (__r == codecvt_base::partial);
3909 if (__r == codecvt_base::ok)
3910 return __bs;
3911 }
3912 }
Marshall Clow8fea1612016-08-25 15:09:01 +00003913
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003914 if (__byte_err_string_.empty())
Marshall Clow8fea1612016-08-25 15:09:01 +00003915 __throw_range_error("wstring_convert: to_bytes error");
3916
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003917 return __byte_err_string_;
3918}
3919
3920template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00003921class _LIBCPP_TEMPLATE_VIS wbuffer_convert
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003922 : public basic_streambuf<_Elem, _Tr>
3923{
3924public:
3925 // types:
3926 typedef _Elem char_type;
3927 typedef _Tr traits_type;
3928 typedef typename traits_type::int_type int_type;
3929 typedef typename traits_type::pos_type pos_type;
3930 typedef typename traits_type::off_type off_type;
3931 typedef typename _Codecvt::state_type state_type;
3932
3933private:
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003934 char* __extbuf_;
3935 const char* __extbufnext_;
3936 const char* __extbufend_;
3937 char __extbuf_min_[8];
3938 size_t __ebs_;
3939 char_type* __intbuf_;
3940 size_t __ibs_;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003941 streambuf* __bufptr_;
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003942 _Codecvt* __cv_;
3943 state_type __st_;
3944 ios_base::openmode __cm_;
3945 bool __owns_eb_;
3946 bool __owns_ib_;
3947 bool __always_noconv_;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003948
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003949 wbuffer_convert(const wbuffer_convert&);
3950 wbuffer_convert& operator=(const wbuffer_convert&);
Marek Kurdejcd0bd6a2021-01-19 08:21:09 +01003951
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003952public:
Marek Kurdejcd0bd6a2021-01-19 08:21:09 +01003953#ifndef _LIBCPP_CXX03_LANG
3954 wbuffer_convert() : wbuffer_convert(nullptr) {}
3955 explicit wbuffer_convert(streambuf* __bytebuf,
3956 _Codecvt* __pcvt = new _Codecvt,
3957 state_type __state = state_type());
3958#else
3959 _LIBCPP_EXPLICIT_AFTER_CXX11
3960 wbuffer_convert(streambuf* __bytebuf = nullptr,
3961 _Codecvt* __pcvt = new _Codecvt,
3962 state_type __state = state_type());
3963#endif
3964
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003965 ~wbuffer_convert();
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003966
Howard Hinnant756c69b2010-09-22 16:48:34 +00003967 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003968 streambuf* rdbuf() const {return __bufptr_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00003969 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003970 streambuf* rdbuf(streambuf* __bytebuf)
3971 {
3972 streambuf* __r = __bufptr_;
3973 __bufptr_ = __bytebuf;
3974 return __r;
3975 }
3976
Howard Hinnant756c69b2010-09-22 16:48:34 +00003977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003978 state_type state() const {return __st_;}
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003979
3980protected:
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003981 virtual int_type underflow();
3982 virtual int_type pbackfail(int_type __c = traits_type::eof());
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003983 virtual int_type overflow (int_type __c = traits_type::eof());
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003984 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
3985 streamsize __n);
3986 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
3987 ios_base::openmode __wch = ios_base::in | ios_base::out);
3988 virtual pos_type seekpos(pos_type __sp,
3989 ios_base::openmode __wch = ios_base::in | ios_base::out);
3990 virtual int sync();
3991
3992private:
3993 bool __read_mode();
3994 void __write_mode();
3995 wbuffer_convert* __close();
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003996};
3997
3998template <class _Codecvt, class _Elem, class _Tr>
Howard Hinnant0ac182a2010-06-01 20:09:18 +00003999wbuffer_convert<_Codecvt, _Elem, _Tr>::
4000 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
Bruce Mitchener170d8972020-11-24 12:53:53 -05004001 : __extbuf_(nullptr),
4002 __extbufnext_(nullptr),
4003 __extbufend_(nullptr),
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004004 __ebs_(0),
4005 __intbuf_(0),
4006 __ibs_(0),
4007 __bufptr_(__bytebuf),
4008 __cv_(__pcvt),
4009 __st_(__state),
4010 __cm_(0),
4011 __owns_eb_(false),
4012 __owns_ib_(false),
4013 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4014{
4015 setbuf(0, 4096);
4016}
4017
4018template <class _Codecvt, class _Elem, class _Tr>
4019wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4020{
4021 __close();
4022 delete __cv_;
4023 if (__owns_eb_)
4024 delete [] __extbuf_;
4025 if (__owns_ib_)
4026 delete [] __intbuf_;
4027}
4028
4029template <class _Codecvt, class _Elem, class _Tr>
4030typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4031wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4032{
4033 if (__cv_ == 0 || __bufptr_ == 0)
4034 return traits_type::eof();
4035 bool __initial = __read_mode();
4036 char_type __1buf;
4037 if (this->gptr() == 0)
4038 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4039 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4040 int_type __c = traits_type::eof();
4041 if (this->gptr() == this->egptr())
4042 {
Arthur O'Dwyer22236632020-12-07 21:50:15 -05004043 _VSTD::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004044 if (__always_noconv_)
4045 {
4046 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4047 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4048 if (__nmemb != 0)
4049 {
4050 this->setg(this->eback(),
4051 this->eback() + __unget_sz,
4052 this->eback() + __unget_sz + __nmemb);
4053 __c = *this->gptr();
4054 }
4055 }
4056 else
4057 {
Eric Fiselier98e428d2016-06-19 06:58:22 +00004058 _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
4059 if (__extbufend_ != __extbufnext_)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05004060 _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004061 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4062 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00004063 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004064 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4065 codecvt_base::result __r;
Eric Fiselier6003c772016-12-23 23:37:52 +00004066 // FIXME: Do we ever need to restore the state here?
4067 //state_type __svs = __st_;
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004068 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4069 if (__nr != 0)
4070 {
4071 __extbufend_ = __extbufnext_ + __nr;
4072 char_type* __inext;
4073 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4074 this->eback() + __unget_sz,
4075 this->egptr(), __inext);
4076 if (__r == codecvt_base::noconv)
4077 {
Louis Dionne173f29e2019-05-29 16:01:36 +00004078 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_,
Marshall Clowbeda7142017-06-14 20:00:36 +00004079 (char_type*) const_cast<char *>(__extbufend_));
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004080 __c = *this->gptr();
4081 }
4082 else if (__inext != this->eback() + __unget_sz)
4083 {
4084 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4085 __c = *this->gptr();
4086 }
4087 }
4088 }
4089 }
4090 else
4091 __c = *this->gptr();
4092 if (this->eback() == &__1buf)
4093 this->setg(0, 0, 0);
4094 return __c;
4095}
4096
4097template <class _Codecvt, class _Elem, class _Tr>
4098typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4099wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4100{
4101 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4102 {
4103 if (traits_type::eq_int_type(__c, traits_type::eof()))
4104 {
4105 this->gbump(-1);
4106 return traits_type::not_eof(__c);
4107 }
4108 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4109 {
4110 this->gbump(-1);
4111 *this->gptr() = traits_type::to_char_type(__c);
4112 return __c;
4113 }
4114 }
4115 return traits_type::eof();
4116}
4117
4118template <class _Codecvt, class _Elem, class _Tr>
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004119typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4120wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4121{
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004122 if (__cv_ == 0 || __bufptr_ == 0)
4123 return traits_type::eof();
4124 __write_mode();
4125 char_type __1buf;
4126 char_type* __pb_save = this->pbase();
4127 char_type* __epb_save = this->epptr();
4128 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4129 {
4130 if (this->pptr() == 0)
4131 this->setp(&__1buf, &__1buf+1);
4132 *this->pptr() = traits_type::to_char_type(__c);
4133 this->pbump(1);
4134 }
4135 if (this->pptr() != this->pbase())
4136 {
4137 if (__always_noconv_)
4138 {
4139 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4140 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4141 return traits_type::eof();
4142 }
4143 else
4144 {
4145 char* __extbe = __extbuf_;
4146 codecvt_base::result __r;
4147 do
4148 {
4149 const char_type* __e;
4150 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4151 __extbuf_, __extbuf_ + __ebs_, __extbe);
4152 if (__e == this->pbase())
4153 return traits_type::eof();
4154 if (__r == codecvt_base::noconv)
4155 {
4156 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4157 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4158 return traits_type::eof();
4159 }
4160 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4161 {
4162 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4163 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4164 return traits_type::eof();
4165 if (__r == codecvt_base::partial)
4166 {
Marshall Clowbeda7142017-06-14 20:00:36 +00004167 this->setp(const_cast<char_type *>(__e), this->pptr());
Marshall Clow33932622017-09-12 15:00:43 +00004168 this->__pbump(this->epptr() - this->pbase());
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004169 }
4170 }
4171 else
4172 return traits_type::eof();
4173 } while (__r == codecvt_base::partial);
4174 }
4175 this->setp(__pb_save, __epb_save);
4176 }
4177 return traits_type::not_eof(__c);
4178}
4179
4180template <class _Codecvt, class _Elem, class _Tr>
4181basic_streambuf<_Elem, _Tr>*
4182wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4183{
4184 this->setg(0, 0, 0);
4185 this->setp(0, 0);
4186 if (__owns_eb_)
4187 delete [] __extbuf_;
4188 if (__owns_ib_)
4189 delete [] __intbuf_;
4190 __ebs_ = __n;
4191 if (__ebs_ > sizeof(__extbuf_min_))
4192 {
4193 if (__always_noconv_ && __s)
4194 {
4195 __extbuf_ = (char*)__s;
4196 __owns_eb_ = false;
4197 }
4198 else
4199 {
4200 __extbuf_ = new char[__ebs_];
4201 __owns_eb_ = true;
4202 }
4203 }
4204 else
4205 {
4206 __extbuf_ = __extbuf_min_;
4207 __ebs_ = sizeof(__extbuf_min_);
4208 __owns_eb_ = false;
4209 }
4210 if (!__always_noconv_)
4211 {
4212 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4213 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4214 {
4215 __intbuf_ = __s;
4216 __owns_ib_ = false;
4217 }
4218 else
4219 {
4220 __intbuf_ = new char_type[__ibs_];
4221 __owns_ib_ = true;
4222 }
4223 }
4224 else
4225 {
4226 __ibs_ = 0;
4227 __intbuf_ = 0;
4228 __owns_ib_ = false;
4229 }
4230 return this;
4231}
4232
4233template <class _Codecvt, class _Elem, class _Tr>
4234typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4235wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4236 ios_base::openmode __om)
4237{
4238 int __width = __cv_->encoding();
4239 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4240 return pos_type(off_type(-1));
Marshall Clowc2a72762015-08-27 14:37:22 +00004241 // __width > 0 || __off == 0, now check __way
4242 if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end)
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004243 return pos_type(off_type(-1));
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004244 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4245 __r.state(__st_);
4246 return __r;
4247}
4248
4249template <class _Codecvt, class _Elem, class _Tr>
4250typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4251wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4252{
4253 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4254 return pos_type(off_type(-1));
4255 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4256 return pos_type(off_type(-1));
4257 return __sp;
4258}
4259
4260template <class _Codecvt, class _Elem, class _Tr>
4261int
4262wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4263{
4264 if (__cv_ == 0 || __bufptr_ == 0)
4265 return 0;
4266 if (__cm_ & ios_base::out)
4267 {
4268 if (this->pptr() != this->pbase())
4269 if (overflow() == traits_type::eof())
4270 return -1;
4271 codecvt_base::result __r;
4272 do
4273 {
4274 char* __extbe;
4275 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4276 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4277 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4278 return -1;
4279 } while (__r == codecvt_base::partial);
4280 if (__r == codecvt_base::error)
4281 return -1;
4282 if (__bufptr_->pubsync())
4283 return -1;
4284 }
4285 else if (__cm_ & ios_base::in)
4286 {
4287 off_type __c;
4288 if (__always_noconv_)
4289 __c = this->egptr() - this->gptr();
4290 else
4291 {
4292 int __width = __cv_->encoding();
4293 __c = __extbufend_ - __extbufnext_;
4294 if (__width > 0)
4295 __c += __width * (this->egptr() - this->gptr());
4296 else
4297 {
4298 if (this->gptr() != this->egptr())
4299 {
4300 reverse(this->gptr(), this->egptr());
4301 codecvt_base::result __r;
4302 const char_type* __e = this->gptr();
4303 char* __extbe;
4304 do
4305 {
4306 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4307 __extbuf_, __extbuf_ + __ebs_, __extbe);
4308 switch (__r)
4309 {
4310 case codecvt_base::noconv:
4311 __c += this->egptr() - this->gptr();
4312 break;
4313 case codecvt_base::ok:
4314 case codecvt_base::partial:
4315 __c += __extbe - __extbuf_;
4316 break;
4317 default:
4318 return -1;
4319 }
4320 } while (__r == codecvt_base::partial);
4321 }
4322 }
4323 }
4324 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4325 return -1;
4326 this->setg(0, 0, 0);
4327 __cm_ = 0;
4328 }
4329 return 0;
4330}
4331
4332template <class _Codecvt, class _Elem, class _Tr>
4333bool
4334wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4335{
4336 if (!(__cm_ & ios_base::in))
4337 {
4338 this->setp(0, 0);
4339 if (__always_noconv_)
4340 this->setg((char_type*)__extbuf_,
4341 (char_type*)__extbuf_ + __ebs_,
4342 (char_type*)__extbuf_ + __ebs_);
4343 else
4344 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4345 __cm_ = ios_base::in;
4346 return true;
4347 }
4348 return false;
4349}
4350
4351template <class _Codecvt, class _Elem, class _Tr>
4352void
4353wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4354{
4355 if (!(__cm_ & ios_base::out))
4356 {
4357 this->setg(0, 0, 0);
4358 if (__ebs_ > sizeof(__extbuf_min_))
4359 {
4360 if (__always_noconv_)
4361 this->setp((char_type*)__extbuf_,
4362 (char_type*)__extbuf_ + (__ebs_ - 1));
4363 else
4364 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4365 }
4366 else
4367 this->setp(0, 0);
4368 __cm_ = ios_base::out;
4369 }
4370}
4371
4372template <class _Codecvt, class _Elem, class _Tr>
4373wbuffer_convert<_Codecvt, _Elem, _Tr>*
4374wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4375{
Bruce Mitchener170d8972020-11-24 12:53:53 -05004376 wbuffer_convert* __rt = nullptr;
4377 if (__cv_ != nullptr && __bufptr_ != nullptr)
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004378 {
4379 __rt = this;
4380 if ((__cm_ & ios_base::out) && sync())
Bruce Mitchener170d8972020-11-24 12:53:53 -05004381 __rt = nullptr;
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004382 }
4383 return __rt;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004384}
4385
Howard Hinnantc51e1022010-05-11 19:42:16 +00004386_LIBCPP_END_NAMESPACE_STD
4387
Eric Fiselierf4433a32017-05-31 22:07:49 +00004388_LIBCPP_POP_MACROS
4389
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04004390#endif // _LIBCPP_LOCALE