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