2 //===-------------------------- locale ------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_LOCALE
12 #define _LIBCPP_LOCALE
28 static const category // values assigned here are for exposition only
36 all = collate | ctype | monetary | numeric | time | messages;
38 // construct/copy/destroy:
40 locale(const locale& other) noexcept;
41 explicit locale(const char* std_name);
42 explicit locale(const string& std_name);
43 locale(const locale& other, const char* std_name, category);
44 locale(const locale& other, const string& std_name, category);
45 template <class Facet> locale(const locale& other, Facet* f);
46 locale(const locale& other, const locale& one, category);
48 ~locale(); // not virtual
50 const locale& operator=(const locale& other) noexcept;
52 template <class Facet> locale combine(const locale& other) const;
55 basic_string<char> name() const;
56 bool operator==(const locale& other) const;
57 bool operator!=(const locale& other) const;
58 template <class charT, class Traits, class Allocator>
59 bool operator()(const basic_string<charT,Traits,Allocator>& s1,
60 const basic_string<charT,Traits,Allocator>& s2) const;
62 // global locale objects:
63 static locale global(const locale&);
64 static const locale& classic();
67 template <class Facet> const Facet& use_facet(const locale&);
68 template <class Facet> bool has_facet(const locale&) noexcept;
70 // 22.3.3, convenience interfaces:
71 template <class charT> bool isspace (charT c, const locale& loc);
72 template <class charT> bool isprint (charT c, const locale& loc);
73 template <class charT> bool iscntrl (charT c, const locale& loc);
74 template <class charT> bool isupper (charT c, const locale& loc);
75 template <class charT> bool islower (charT c, const locale& loc);
76 template <class charT> bool isalpha (charT c, const locale& loc);
77 template <class charT> bool isdigit (charT c, const locale& loc);
78 template <class charT> bool ispunct (charT c, const locale& loc);
79 template <class charT> bool isxdigit(charT c, const locale& loc);
80 template <class charT> bool isalnum (charT c, const locale& loc);
81 template <class charT> bool isgraph (charT c, const locale& loc);
82 template <class charT> charT toupper(charT c, const locale& loc);
83 template <class charT> charT tolower(charT c, const locale& loc);
85 template<class Codecvt, class Elem = wchar_t,
86 class Wide_alloc = allocator<Elem>,
87 class Byte_alloc = allocator<char>>
91 typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
92 typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
93 typedef typename Codecvt::state_type state_type;
94 typedef typename wide_string::traits_type::int_type int_type;
96 explicit wstring_convert(Codecvt* pcvt = new Codecvt); // explicit in C++14
97 wstring_convert(Codecvt* pcvt, state_type state);
98 explicit wstring_convert(const byte_string& byte_err, // explicit in C++14
99 const wide_string& wide_err = wide_string());
100 wstring_convert(const wstring_convert&) = delete; // C++14
101 wstring_convert & operator=(const wstring_convert &) = delete; // C++14
104 wide_string from_bytes(char byte);
105 wide_string from_bytes(const char* ptr);
106 wide_string from_bytes(const byte_string& str);
107 wide_string from_bytes(const char* first, const char* last);
109 byte_string to_bytes(Elem wchar);
110 byte_string to_bytes(const Elem* wptr);
111 byte_string to_bytes(const wide_string& wstr);
112 byte_string to_bytes(const Elem* first, const Elem* last);
114 size_t converted() const; // noexcept in C++14
115 state_type state() const;
118 template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
119 class wbuffer_convert
120 : public basic_streambuf<Elem, Tr>
123 typedef typename Tr::state_type state_type;
125 explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
126 state_type state = state_type()); // explicit in C++14
127 wbuffer_convert(const wbuffer_convert&) = delete; // C++14
128 wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14
129 ~wbuffer_convert(); // C++14
131 streambuf* rdbuf() const;
132 streambuf* rdbuf(streambuf* bytebuf);
134 state_type state() const;
137 // 22.4.1 and 22.4.1.3, ctype:
139 template <class charT> class ctype;
140 template <> class ctype<char>; // specialization
141 template <class charT> class ctype_byname;
142 template <> class ctype_byname<char>; // specialization
145 template <class internT, class externT, class stateT> class codecvt;
146 template <class internT, class externT, class stateT> class codecvt_byname;
148 // 22.4.2 and 22.4.3, numeric:
149 template <class charT, class InputIterator> class num_get;
150 template <class charT, class OutputIterator> class num_put;
151 template <class charT> class numpunct;
152 template <class charT> class numpunct_byname;
154 // 22.4.4, col lation:
155 template <class charT> class collate;
156 template <class charT> class collate_byname;
158 // 22.4.5, date and time:
160 template <class charT, class InputIterator> class time_get;
161 template <class charT, class InputIterator> class time_get_byname;
162 template <class charT, class OutputIterator> class time_put;
163 template <class charT, class OutputIterator> class time_put_byname;
167 template <class charT, class InputIterator> class money_get;
168 template <class charT, class OutputIterator> class money_put;
169 template <class charT, bool Intl> class moneypunct;
170 template <class charT, bool Intl> class moneypunct_byname;
172 // 22.4.7, message retrieval:
174 template <class charT> class messages;
175 template <class charT> class messages_byname;
194 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
195 #include <support/win32/locale_win32.h>
196 #elif defined(_NEWLIB_VERSION)
197 // FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an
198 // include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html
199 // has had a chance to bake for a bit
200 #include <support/newlib/xlocale.h>
202 #ifdef _LIBCPP_HAS_CATOPEN
203 #include <nl_types.h>
207 #include <Availability.h>
210 #include <__undef_min_max>
212 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
213 #pragma GCC system_header
216 _LIBCPP_BEGIN_NAMESPACE_STD
218 #if defined(__APPLE__) || defined(__FreeBSD__)
219 # define _LIBCPP_GET_C_LOCALE 0
220 #elif defined(__CloudABI__) || defined(__NetBSD__)
221 # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
223 # define _LIBCPP_GET_C_LOCALE __cloc()
224 // Get the C locale object
225 _LIBCPP_FUNC_VIS locale_t __cloc();
226 #define __cloc_defined
229 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
230 typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
231 #ifndef _LIBCPP_LOCALE__L_EXTENSIONS
232 typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
235 // OSX has nice foo_l() functions that let you turn off use of the global
236 // locale. Linux, not so much. The following functions avoid the locale when
237 // that's possible and otherwise do the wrong thing. FIXME.
238 #if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \
239 defined(_NEWLIB_VERSION) || defined(__GLIBC__)
241 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
242 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
243 inline _LIBCPP_INLINE_VISIBILITY
244 __mb_cur_max_l(locale_t __l)
246 return MB_CUR_MAX_L(__l);
248 #else // _LIBCPP_LOCALE__L_EXTENSIONS
249 inline _LIBCPP_ALWAYS_INLINE
250 decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
252 __locale_raii __current(uselocale(__l), uselocale);
255 #endif // _LIBCPP_LOCALE__L_EXTENSIONS
257 inline _LIBCPP_ALWAYS_INLINE
258 wint_t __btowc_l(int __c, locale_t __l)
260 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
261 return btowc_l(__c, __l);
263 __locale_raii __current(uselocale(__l), uselocale);
268 inline _LIBCPP_ALWAYS_INLINE
269 int __wctob_l(wint_t __c, locale_t __l)
271 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
272 return wctob_l(__c, __l);
274 __locale_raii __current(uselocale(__l), uselocale);
279 inline _LIBCPP_ALWAYS_INLINE
280 size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
281 size_t __len, mbstate_t *__ps, locale_t __l)
283 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
284 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
286 __locale_raii __current(uselocale(__l), uselocale);
287 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
291 inline _LIBCPP_ALWAYS_INLINE
292 size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
294 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
295 return wcrtomb_l(__s, __wc, __ps, __l);
297 __locale_raii __current(uselocale(__l), uselocale);
298 return wcrtomb(__s, __wc, __ps);
302 inline _LIBCPP_ALWAYS_INLINE
303 size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
304 size_t __len, mbstate_t *__ps, locale_t __l)
306 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
307 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
309 __locale_raii __current(uselocale(__l), uselocale);
310 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
314 inline _LIBCPP_ALWAYS_INLINE
315 size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
316 mbstate_t *__ps, locale_t __l)
318 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
319 return mbrtowc_l(__pwc, __s, __n, __ps, __l);
321 __locale_raii __current(uselocale(__l), uselocale);
322 return mbrtowc(__pwc, __s, __n, __ps);
326 inline _LIBCPP_ALWAYS_INLINE
327 int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
329 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
330 return mbtowc_l(__pwc, __pmb, __max, __l);
332 __locale_raii __current(uselocale(__l), uselocale);
333 return mbtowc(__pwc, __pmb, __max);
337 inline _LIBCPP_ALWAYS_INLINE
338 size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
340 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
341 return mbrlen_l(__s, __n, __ps, __l);
343 __locale_raii __current(uselocale(__l), uselocale);
344 return mbrlen(__s, __n, __ps);
348 inline _LIBCPP_ALWAYS_INLINE
349 lconv *__localeconv_l(locale_t __l)
351 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
352 return localeconv_l(__l);
354 __locale_raii __current(uselocale(__l), uselocale);
359 inline _LIBCPP_ALWAYS_INLINE
360 size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
361 mbstate_t *__ps, locale_t __l)
363 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
364 return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
366 __locale_raii __current(uselocale(__l), uselocale);
367 return mbsrtowcs(__dest, __src, __len, __ps);
372 int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
374 va_start(__va, __format);
375 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
376 int __res = vsnprintf_l(__s, __n, __l, __format, __va);
378 __locale_raii __current(uselocale(__l), uselocale);
379 int __res = vsnprintf(__s, __n, __format, __va);
386 int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
388 va_start(__va, __format);
389 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
390 int __res = vasprintf_l(__s, __l, __format, __va);
392 __locale_raii __current(uselocale(__l), uselocale);
393 int __res = vasprintf(__s, __format, __va);
400 int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
402 va_start(__va, __format);
403 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
404 int __res = vsscanf_l(__s, __l, __format, __va);
406 __locale_raii __current(uselocale(__l), uselocale);
407 int __res = vsscanf(__s, __format, __va);
416 // Scans [__b, __e) until a match is found in the basic_strings range
417 // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
418 // __b will be incremented (visibly), consuming CharT until a match is found
419 // or proved to not exist. A keyword may be "", in which will match anything.
420 // If one keyword is a prefix of another, and the next CharT in the input
421 // might match another keyword, the algorithm will attempt to find the longest
422 // matching keyword. If the longer matching keyword ends up not matching, then
423 // no keyword match is found. If no keyword match is found, __ke is returned
424 // and failbit is set in __err.
425 // Else an iterator pointing to the matching keyword is found. If more than
426 // one keyword matches, an iterator to the first matching keyword is returned.
427 // If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
428 // __ct is used to force to lower case before comparing characters.
430 // Keywords: "a", "abb"
431 // If the input is "a", the first keyword matches and eofbit is set.
432 // If the input is "abc", no match is found and "ab" are consumed.
433 template <class _InputIterator, class _ForwardIterator, class _Ctype>
436 __scan_keyword(_InputIterator& __b, _InputIterator __e,
437 _ForwardIterator __kb, _ForwardIterator __ke,
438 const _Ctype& __ct, ios_base::iostate& __err,
439 bool __case_sensitive = true)
441 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
442 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
443 const unsigned char __doesnt_match = '\0';
444 const unsigned char __might_match = '\1';
445 const unsigned char __does_match = '\2';
446 unsigned char __statbuf[100];
447 unsigned char* __status = __statbuf;
448 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
449 if (__nkw > sizeof(__statbuf))
451 __status = (unsigned char*)malloc(__nkw);
454 __stat_hold.reset(__status);
456 size_t __n_might_match = __nkw; // At this point, any keyword might match
457 size_t __n_does_match = 0; // but none of them definitely do
458 // Initialize all statuses to __might_match, except for "" keywords are __does_match
459 unsigned char* __st = __status;
460 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
463 *__st = __might_match;
466 *__st = __does_match;
471 // While there might be a match, test keywords against the next CharT
472 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
474 // Peek at the next CharT but don't consume it
476 if (!__case_sensitive)
477 __c = __ct.toupper(__c);
478 bool __consume = false;
479 // For each keyword which might match, see if the __indx character is __c
480 // If a match if found, consume __c
481 // If a match is found, and that is the last character in the keyword,
482 // then that keyword matches.
483 // If the keyword doesn't match this character, then change the keyword
486 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
488 if (*__st == __might_match)
490 _CharT __kc = (*__ky)[__indx];
491 if (!__case_sensitive)
492 __kc = __ct.toupper(__kc);
496 if (__ky->size() == __indx+1)
498 *__st = __does_match;
505 *__st = __doesnt_match;
510 // consume if we matched a character
514 // If we consumed a character and there might be a matched keyword that
515 // was marked matched on a previous iteration, then such keywords
516 // which are now marked as not matching.
517 if (__n_might_match + __n_does_match > 1)
520 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
522 if (*__st == __does_match && __ky->size() != __indx+1)
524 *__st = __doesnt_match;
531 // We've exited the loop because we hit eof and/or we have no more "might matches".
533 __err |= ios_base::eofbit;
534 // Return the first matching result
535 for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
536 if (*__st == __does_match)
539 __err |= ios_base::failbit;
543 struct _LIBCPP_TYPE_VIS __num_get_base
545 static const int __num_get_buf_sz = 40;
547 static int __get_base(ios_base&);
548 static const char __src[33];
552 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
553 ios_base::iostate& __err);
555 template <class _CharT>
557 : protected __num_get_base
559 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
560 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
561 _CharT& __thousands_sep);
562 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
563 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
564 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
565 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
566 char* __a, char*& __a_end,
567 _CharT __decimal_point, _CharT __thousands_sep,
568 const string& __grouping, unsigned* __g,
569 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
572 template <class _CharT>
574 __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
576 locale __loc = __iob.getloc();
577 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
578 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
579 __thousands_sep = __np.thousands_sep();
580 return __np.grouping();
583 template <class _CharT>
585 __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
586 _CharT& __thousands_sep)
588 locale __loc = __iob.getloc();
589 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
590 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
591 __decimal_point = __np.decimal_point();
592 __thousands_sep = __np.thousands_sep();
593 return __np.grouping();
596 template <class _CharT>
598 __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
599 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
600 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
602 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
604 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
608 if (__grouping.size() != 0 && __ct == __thousands_sep)
610 if (__g_end-__g < __num_get_buf_sz)
617 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
630 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
633 *__a_end++ = __src[__f];
638 *__a_end++ = __src[__f];
643 template <class _CharT>
645 __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
646 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
647 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
649 if (__ct == __decimal_point)
655 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
659 if (__ct == __thousands_sep && __grouping.size() != 0)
663 if (__g_end-__g < __num_get_buf_sz)
670 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
673 char __x = __src[__f];
674 if (__x == '-' || __x == '+')
676 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
683 if (__x == 'x' || __x == 'X')
685 else if ((__x & 0x5F) == __exp)
691 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
702 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
703 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
705 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
706 class _LIBCPP_TYPE_VIS_ONLY num_get
707 : public locale::facet,
708 private __num_get<_CharT>
711 typedef _CharT char_type;
712 typedef _InputIterator iter_type;
714 _LIBCPP_ALWAYS_INLINE
715 explicit num_get(size_t __refs = 0)
716 : locale::facet(__refs) {}
718 _LIBCPP_ALWAYS_INLINE
719 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
720 ios_base::iostate& __err, bool& __v) const
722 return do_get(__b, __e, __iob, __err, __v);
725 _LIBCPP_ALWAYS_INLINE
726 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
727 ios_base::iostate& __err, long& __v) const
729 return do_get(__b, __e, __iob, __err, __v);
732 _LIBCPP_ALWAYS_INLINE
733 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
734 ios_base::iostate& __err, long long& __v) const
736 return do_get(__b, __e, __iob, __err, __v);
739 _LIBCPP_ALWAYS_INLINE
740 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
741 ios_base::iostate& __err, unsigned short& __v) const
743 return do_get(__b, __e, __iob, __err, __v);
746 _LIBCPP_ALWAYS_INLINE
747 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
748 ios_base::iostate& __err, unsigned int& __v) const
750 return do_get(__b, __e, __iob, __err, __v);
753 _LIBCPP_ALWAYS_INLINE
754 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
755 ios_base::iostate& __err, unsigned long& __v) const
757 return do_get(__b, __e, __iob, __err, __v);
760 _LIBCPP_ALWAYS_INLINE
761 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
762 ios_base::iostate& __err, unsigned long long& __v) const
764 return do_get(__b, __e, __iob, __err, __v);
767 _LIBCPP_ALWAYS_INLINE
768 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
769 ios_base::iostate& __err, float& __v) const
771 return do_get(__b, __e, __iob, __err, __v);
774 _LIBCPP_ALWAYS_INLINE
775 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
776 ios_base::iostate& __err, double& __v) const
778 return do_get(__b, __e, __iob, __err, __v);
781 _LIBCPP_ALWAYS_INLINE
782 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
783 ios_base::iostate& __err, long double& __v) const
785 return do_get(__b, __e, __iob, __err, __v);
788 _LIBCPP_ALWAYS_INLINE
789 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
790 ios_base::iostate& __err, void*& __v) const
792 return do_get(__b, __e, __iob, __err, __v);
795 static locale::id id;
798 _LIBCPP_ALWAYS_INLINE
802 iter_type __do_get_floating_point
803 (iter_type __b, iter_type __e, ios_base& __iob,
804 ios_base::iostate& __err, _Fp& __v) const;
806 template <class _Signed>
807 iter_type __do_get_signed
808 (iter_type __b, iter_type __e, ios_base& __iob,
809 ios_base::iostate& __err, _Signed& __v) const;
811 template <class _Unsigned>
812 iter_type __do_get_unsigned
813 (iter_type __b, iter_type __e, ios_base& __iob,
814 ios_base::iostate& __err, _Unsigned& __v) const;
817 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
818 ios_base::iostate& __err, bool& __v) const;
820 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
821 ios_base::iostate& __err, long& __v) const
822 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
824 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
825 ios_base::iostate& __err, long long& __v) const
826 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
828 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
829 ios_base::iostate& __err, unsigned short& __v) const
830 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
832 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
833 ios_base::iostate& __err, unsigned int& __v) const
834 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
836 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
837 ios_base::iostate& __err, unsigned long& __v) const
838 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
840 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
841 ios_base::iostate& __err, unsigned long long& __v) const
842 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
844 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
845 ios_base::iostate& __err, float& __v) const
846 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
848 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
849 ios_base::iostate& __err, double& __v) const
850 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
852 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
853 ios_base::iostate& __err, long double& __v) const
854 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
856 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
857 ios_base::iostate& __err, void*& __v) const;
860 template <class _CharT, class _InputIterator>
862 num_get<_CharT, _InputIterator>::id;
866 __num_get_signed_integral(const char* __a, const char* __a_end,
867 ios_base::iostate& __err, int __base)
871 typename remove_reference<decltype(errno)>::type __save_errno = errno;
874 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
875 typename remove_reference<decltype(errno)>::type __current_errno = errno;
876 if (__current_errno == 0)
877 errno = __save_errno;
880 __err = ios_base::failbit;
883 else if (__current_errno == ERANGE ||
884 __ll < numeric_limits<_Tp>::min() ||
885 numeric_limits<_Tp>::max() < __ll)
887 __err = ios_base::failbit;
889 return numeric_limits<_Tp>::max();
891 return numeric_limits<_Tp>::min();
893 return static_cast<_Tp>(__ll);
895 __err = ios_base::failbit;
901 __num_get_unsigned_integral(const char* __a, const char* __a_end,
902 ios_base::iostate& __err, int __base)
908 __err = ios_base::failbit;
911 typename remove_reference<decltype(errno)>::type __save_errno = errno;
914 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
915 typename remove_reference<decltype(errno)>::type __current_errno = errno;
916 if (__current_errno == 0)
917 errno = __save_errno;
920 __err = ios_base::failbit;
923 else if (__current_errno == ERANGE ||
924 numeric_limits<_Tp>::max() < __ll)
926 __err = ios_base::failbit;
927 return numeric_limits<_Tp>::max();
929 return static_cast<_Tp>(__ll);
931 __err = ios_base::failbit;
937 __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
941 typename remove_reference<decltype(errno)>::type __save_errno = errno;
944 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
945 typename remove_reference<decltype(errno)>::type __current_errno = errno;
946 if (__current_errno == 0)
947 errno = __save_errno;
950 __err = ios_base::failbit;
953 else if (__current_errno == ERANGE)
954 __err = ios_base::failbit;
955 return static_cast<_Tp>(__ld);
957 __err = ios_base::failbit;
961 template <class _CharT, class _InputIterator>
963 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
965 ios_base::iostate& __err,
968 if ((__iob.flags() & ios_base::boolalpha) == 0)
971 __b = do_get(__b, __e, __iob, __err, __lv);
982 __err = ios_base::failbit;
987 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
988 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
989 typedef typename numpunct<_CharT>::string_type string_type;
990 const string_type __names[2] = {__np.truename(), __np.falsename()};
991 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
993 __v = __i == __names;
999 template <class _CharT, class _InputIterator>
1000 template <class _Signed>
1002 num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
1004 ios_base::iostate& __err,
1008 int __base = this->__get_base(__iob);
1010 char_type __atoms[26];
1011 char_type __thousands_sep;
1012 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1014 __buf.resize(__buf.capacity());
1015 char* __a = &__buf[0];
1016 char* __a_end = __a;
1017 unsigned __g[__num_get_base::__num_get_buf_sz];
1018 unsigned* __g_end = __g;
1020 for (; __b != __e; ++__b)
1022 if (__a_end == __a + __buf.size())
1024 size_t __tmp = __buf.size();
1025 __buf.resize(2*__buf.size());
1026 __buf.resize(__buf.capacity());
1028 __a_end = __a + __tmp;
1030 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1031 __thousands_sep, __grouping, __g, __g_end,
1035 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1038 __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
1039 // Digit grouping checked
1040 __check_grouping(__grouping, __g, __g_end, __err);
1043 __err |= ios_base::eofbit;
1049 template <class _CharT, class _InputIterator>
1050 template <class _Unsigned>
1052 num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
1054 ios_base::iostate& __err,
1055 _Unsigned& __v) const
1058 int __base = this->__get_base(__iob);
1060 char_type __atoms[26];
1061 char_type __thousands_sep;
1062 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1064 __buf.resize(__buf.capacity());
1065 char* __a = &__buf[0];
1066 char* __a_end = __a;
1067 unsigned __g[__num_get_base::__num_get_buf_sz];
1068 unsigned* __g_end = __g;
1070 for (; __b != __e; ++__b)
1072 if (__a_end == __a + __buf.size())
1074 size_t __tmp = __buf.size();
1075 __buf.resize(2*__buf.size());
1076 __buf.resize(__buf.capacity());
1078 __a_end = __a + __tmp;
1080 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1081 __thousands_sep, __grouping, __g, __g_end,
1085 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1088 __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
1089 // Digit grouping checked
1090 __check_grouping(__grouping, __g, __g_end, __err);
1093 __err |= ios_base::eofbit;
1099 template <class _CharT, class _InputIterator>
1100 template <class _Fp>
1102 num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
1104 ios_base::iostate& __err,
1107 // Stage 1, nothing to do
1109 char_type __atoms[32];
1110 char_type __decimal_point;
1111 char_type __thousands_sep;
1112 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1116 __buf.resize(__buf.capacity());
1117 char* __a = &__buf[0];
1118 char* __a_end = __a;
1119 unsigned __g[__num_get_base::__num_get_buf_sz];
1120 unsigned* __g_end = __g;
1122 bool __in_units = true;
1124 for (; __b != __e; ++__b)
1126 if (__a_end == __a + __buf.size())
1128 size_t __tmp = __buf.size();
1129 __buf.resize(2*__buf.size());
1130 __buf.resize(__buf.capacity());
1132 __a_end = __a + __tmp;
1134 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1135 __decimal_point, __thousands_sep,
1136 __grouping, __g, __g_end,
1140 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1143 __v = __num_get_float<_Fp>(__a, __a_end, __err);
1144 // Digit grouping checked
1145 __check_grouping(__grouping, __g, __g_end, __err);
1148 __err |= ios_base::eofbit;
1152 template <class _CharT, class _InputIterator>
1154 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1156 ios_base::iostate& __err,
1162 char_type __atoms[26];
1163 char_type __thousands_sep = 0;
1165 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1166 __num_get_base::__src + 26, __atoms);
1168 __buf.resize(__buf.capacity());
1169 char* __a = &__buf[0];
1170 char* __a_end = __a;
1171 unsigned __g[__num_get_base::__num_get_buf_sz];
1172 unsigned* __g_end = __g;
1174 for (; __b != __e; ++__b)
1176 if (__a_end == __a + __buf.size())
1178 size_t __tmp = __buf.size();
1179 __buf.resize(2*__buf.size());
1180 __buf.resize(__buf.capacity());
1182 __a_end = __a + __tmp;
1184 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1185 __thousands_sep, __grouping,
1186 __g, __g_end, __atoms))
1190 __buf.resize(__a_end - __a);
1191 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1192 if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1194 if (__sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1196 __err = ios_base::failbit;
1199 __err |= ios_base::eofbit;
1203 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
1204 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
1206 struct _LIBCPP_TYPE_VIS __num_put_base
1209 static void __format_int(char* __fmt, const char* __len, bool __signd,
1210 ios_base::fmtflags __flags);
1211 static bool __format_float(char* __fmt, const char* __len,
1212 ios_base::fmtflags __flags);
1213 static char* __identify_padding(char* __nb, char* __ne,
1214 const ios_base& __iob);
1217 template <class _CharT>
1219 : protected __num_put_base
1221 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1222 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1223 const locale& __loc);
1224 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1225 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1226 const locale& __loc);
1229 template <class _CharT>
1231 __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1232 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1233 const locale& __loc)
1235 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1236 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1237 string __grouping = __npt.grouping();
1238 if (__grouping.empty())
1240 __ct.widen(__nb, __ne, __ob);
1241 __oe = __ob + (__ne - __nb);
1247 if (*__nf == '-' || *__nf == '+')
1248 *__oe++ = __ct.widen(*__nf++);
1249 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1252 *__oe++ = __ct.widen(*__nf++);
1253 *__oe++ = __ct.widen(*__nf++);
1255 reverse(__nf, __ne);
1256 _CharT __thousands_sep = __npt.thousands_sep();
1259 for (char* __p = __nf; __p < __ne; ++__p)
1261 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1262 __dc == static_cast<unsigned>(__grouping[__dg]))
1264 *__oe++ = __thousands_sep;
1266 if (__dg < __grouping.size()-1)
1269 *__oe++ = __ct.widen(*__p);
1272 reverse(__ob + (__nf - __nb), __oe);
1277 __op = __ob + (__np - __nb);
1280 template <class _CharT>
1282 __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1283 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1284 const locale& __loc)
1286 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1287 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1288 string __grouping = __npt.grouping();
1291 if (*__nf == '-' || *__nf == '+')
1292 *__oe++ = __ct.widen(*__nf++);
1294 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1297 *__oe++ = __ct.widen(*__nf++);
1298 *__oe++ = __ct.widen(*__nf++);
1299 for (__ns = __nf; __ns < __ne; ++__ns)
1300 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1305 for (__ns = __nf; __ns < __ne; ++__ns)
1306 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1309 if (__grouping.empty())
1311 __ct.widen(__nf, __ns, __oe);
1312 __oe += __ns - __nf;
1316 reverse(__nf, __ns);
1317 _CharT __thousands_sep = __npt.thousands_sep();
1320 for (char* __p = __nf; __p < __ns; ++__p)
1322 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1324 *__oe++ = __thousands_sep;
1326 if (__dg < __grouping.size()-1)
1329 *__oe++ = __ct.widen(*__p);
1332 reverse(__ob + (__nf - __nb), __oe);
1334 for (__nf = __ns; __nf < __ne; ++__nf)
1338 *__oe++ = __npt.decimal_point();
1343 *__oe++ = __ct.widen(*__nf);
1345 __ct.widen(__nf, __ne, __oe);
1346 __oe += __ne - __nf;
1350 __op = __ob + (__np - __nb);
1353 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
1354 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
1356 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1357 class _LIBCPP_TYPE_VIS_ONLY num_put
1358 : public locale::facet,
1359 private __num_put<_CharT>
1362 typedef _CharT char_type;
1363 typedef _OutputIterator iter_type;
1365 _LIBCPP_ALWAYS_INLINE
1366 explicit num_put(size_t __refs = 0)
1367 : locale::facet(__refs) {}
1369 _LIBCPP_ALWAYS_INLINE
1370 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1373 return do_put(__s, __iob, __fl, __v);
1376 _LIBCPP_ALWAYS_INLINE
1377 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1380 return do_put(__s, __iob, __fl, __v);
1383 _LIBCPP_ALWAYS_INLINE
1384 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1385 long long __v) const
1387 return do_put(__s, __iob, __fl, __v);
1390 _LIBCPP_ALWAYS_INLINE
1391 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1392 unsigned long __v) const
1394 return do_put(__s, __iob, __fl, __v);
1397 _LIBCPP_ALWAYS_INLINE
1398 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1399 unsigned long long __v) const
1401 return do_put(__s, __iob, __fl, __v);
1404 _LIBCPP_ALWAYS_INLINE
1405 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1408 return do_put(__s, __iob, __fl, __v);
1411 _LIBCPP_ALWAYS_INLINE
1412 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1413 long double __v) const
1415 return do_put(__s, __iob, __fl, __v);
1418 _LIBCPP_ALWAYS_INLINE
1419 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1420 const void* __v) const
1422 return do_put(__s, __iob, __fl, __v);
1425 static locale::id id;
1428 _LIBCPP_ALWAYS_INLINE
1431 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1433 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1435 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1436 long long __v) const;
1437 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1438 unsigned long) const;
1439 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1440 unsigned long long) const;
1441 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1443 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1444 long double __v) const;
1445 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1446 const void* __v) const;
1449 template <class _CharT, class _OutputIterator>
1451 num_put<_CharT, _OutputIterator>::id;
1453 template <class _CharT, class _OutputIterator>
1456 __pad_and_output(_OutputIterator __s,
1457 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1458 ios_base& __iob, _CharT __fl)
1460 streamsize __sz = __oe - __ob;
1461 streamsize __ns = __iob.width();
1466 for (;__ob < __op; ++__ob, ++__s)
1468 for (; __ns; --__ns, ++__s)
1470 for (; __ob < __oe; ++__ob, ++__s)
1476 #if !defined(__APPLE__) || \
1477 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1478 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1480 template <class _CharT, class _Traits>
1482 ostreambuf_iterator<_CharT, _Traits>
1483 __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1484 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1485 ios_base& __iob, _CharT __fl)
1487 if (__s.__sbuf_ == nullptr)
1489 streamsize __sz = __oe - __ob;
1490 streamsize __ns = __iob.width();
1495 streamsize __np = __op - __ob;
1498 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1500 __s.__sbuf_ = nullptr;
1506 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1507 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1509 __s.__sbuf_ = nullptr;
1516 if (__s.__sbuf_->sputn(__op, __np) != __np)
1518 __s.__sbuf_ = nullptr;
1528 template <class _CharT, class _OutputIterator>
1530 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1531 char_type __fl, bool __v) const
1533 if ((__iob.flags() & ios_base::boolalpha) == 0)
1534 return do_put(__s, __iob, __fl, (unsigned long)__v);
1535 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1536 typedef typename numpunct<char_type>::string_type string_type;
1537 #if _LIBCPP_DEBUG_LEVEL >= 2
1538 string_type __tmp(__v ? __np.truename() : __np.falsename());
1539 string_type __nm = _VSTD::move(__tmp);
1541 string_type __nm = __v ? __np.truename() : __np.falsename();
1543 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1548 template <class _CharT, class _OutputIterator>
1550 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1551 char_type __fl, long __v) const
1553 // Stage 1 - Get number in narrow char
1554 char __fmt[6] = {'%', 0};
1555 const char* __len = "l";
1556 this->__format_int(__fmt+1, __len, true, __iob.flags());
1557 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1558 + ((numeric_limits<long>::digits % 3) != 0)
1561 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1562 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1564 int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1566 char* __ne = __nar + __nc;
1567 char* __np = this->__identify_padding(__nar, __ne, __iob);
1568 // Stage 2 - Widen __nar while adding thousands separators
1569 char_type __o[2*(__nbuf-1) - 1];
1570 char_type* __op; // pad here
1571 char_type* __oe; // end of output
1572 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1573 // [__o, __oe) contains thousands_sep'd wide number
1575 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1578 template <class _CharT, class _OutputIterator>
1580 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1581 char_type __fl, long long __v) const
1583 // Stage 1 - Get number in narrow char
1584 char __fmt[8] = {'%', 0};
1585 const char* __len = "ll";
1586 this->__format_int(__fmt+1, __len, true, __iob.flags());
1587 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1588 + ((numeric_limits<long long>::digits % 3) != 0)
1591 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1592 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1594 int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1596 char* __ne = __nar + __nc;
1597 char* __np = this->__identify_padding(__nar, __ne, __iob);
1598 // Stage 2 - Widen __nar while adding thousands separators
1599 char_type __o[2*(__nbuf-1) - 1];
1600 char_type* __op; // pad here
1601 char_type* __oe; // end of output
1602 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1603 // [__o, __oe) contains thousands_sep'd wide number
1605 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1608 template <class _CharT, class _OutputIterator>
1610 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1611 char_type __fl, unsigned long __v) const
1613 // Stage 1 - Get number in narrow char
1614 char __fmt[6] = {'%', 0};
1615 const char* __len = "l";
1616 this->__format_int(__fmt+1, __len, false, __iob.flags());
1617 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1618 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1621 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1622 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1624 int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1626 char* __ne = __nar + __nc;
1627 char* __np = this->__identify_padding(__nar, __ne, __iob);
1628 // Stage 2 - Widen __nar while adding thousands separators
1629 char_type __o[2*(__nbuf-1) - 1];
1630 char_type* __op; // pad here
1631 char_type* __oe; // end of output
1632 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1633 // [__o, __oe) contains thousands_sep'd wide number
1635 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1638 template <class _CharT, class _OutputIterator>
1640 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1641 char_type __fl, unsigned long long __v) const
1643 // Stage 1 - Get number in narrow char
1644 char __fmt[8] = {'%', 0};
1645 const char* __len = "ll";
1646 this->__format_int(__fmt+1, __len, false, __iob.flags());
1647 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1648 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1651 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1652 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1654 int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1656 char* __ne = __nar + __nc;
1657 char* __np = this->__identify_padding(__nar, __ne, __iob);
1658 // Stage 2 - Widen __nar while adding thousands separators
1659 char_type __o[2*(__nbuf-1) - 1];
1660 char_type* __op; // pad here
1661 char_type* __oe; // end of output
1662 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1663 // [__o, __oe) contains thousands_sep'd wide number
1665 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1668 template <class _CharT, class _OutputIterator>
1670 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1671 char_type __fl, double __v) const
1673 // Stage 1 - Get number in narrow char
1674 char __fmt[8] = {'%', 0};
1675 const char* __len = "";
1676 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1677 const unsigned __nbuf = 30;
1681 if (__specify_precision)
1682 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1683 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1684 (int)__iob.precision(), __v);
1686 __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1687 (int)__iob.precision(), __v);
1690 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1691 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1693 __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1695 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1696 if (__nc > static_cast<int>(__nbuf-1))
1698 if (__specify_precision)
1699 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1700 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1702 __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1705 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1706 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1708 __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1711 __throw_bad_alloc();
1714 char* __ne = __nb + __nc;
1715 char* __np = this->__identify_padding(__nb, __ne, __iob);
1716 // Stage 2 - Widen __nar while adding thousands separators
1717 char_type __o[2*(__nbuf-1) - 1];
1718 char_type* __ob = __o;
1719 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1722 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1724 __throw_bad_alloc();
1727 char_type* __op; // pad here
1728 char_type* __oe; // end of output
1729 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1730 // [__o, __oe) contains thousands_sep'd wide number
1732 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1736 template <class _CharT, class _OutputIterator>
1738 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1739 char_type __fl, long double __v) const
1741 // Stage 1 - Get number in narrow char
1742 char __fmt[8] = {'%', 0};
1743 const char* __len = "L";
1744 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1745 const unsigned __nbuf = 30;
1749 if (__specify_precision)
1750 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1751 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1752 (int)__iob.precision(), __v);
1754 __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1755 (int)__iob.precision(), __v);
1758 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1759 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1761 __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1763 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1764 if (__nc > static_cast<int>(__nbuf-1))
1766 if (__specify_precision)
1767 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1768 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1770 __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1773 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1774 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1776 __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1779 __throw_bad_alloc();
1782 char* __ne = __nb + __nc;
1783 char* __np = this->__identify_padding(__nb, __ne, __iob);
1784 // Stage 2 - Widen __nar while adding thousands separators
1785 char_type __o[2*(__nbuf-1) - 1];
1786 char_type* __ob = __o;
1787 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1790 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1792 __throw_bad_alloc();
1795 char_type* __op; // pad here
1796 char_type* __oe; // end of output
1797 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1798 // [__o, __oe) contains thousands_sep'd wide number
1800 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1804 template <class _CharT, class _OutputIterator>
1806 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1807 char_type __fl, const void* __v) const
1809 // Stage 1 - Get pointer in narrow char
1810 char __fmt[6] = "%p";
1811 const unsigned __nbuf = 20;
1813 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1814 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1816 int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1818 char* __ne = __nar + __nc;
1819 char* __np = this->__identify_padding(__nar, __ne, __iob);
1820 // Stage 2 - Widen __nar
1821 char_type __o[2*(__nbuf-1) - 1];
1822 char_type* __op; // pad here
1823 char_type* __oe; // end of output
1824 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1825 __ct.widen(__nar, __ne, __o);
1826 __oe = __o + (__ne - __nar);
1830 __op = __o + (__np - __nar);
1831 // [__o, __oe) contains wide number
1833 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1836 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)
1837 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
1839 template <class _CharT, class _InputIterator>
1842 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1843 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1845 // Precondition: __n >= 1
1848 __err |= ios_base::eofbit | ios_base::failbit;
1853 if (!__ct.is(ctype_base::digit, __c))
1855 __err |= ios_base::failbit;
1858 int __r = __ct.narrow(__c, 0) - '0';
1859 for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
1863 if (!__ct.is(ctype_base::digit, __c))
1865 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1868 __err |= ios_base::eofbit;
1872 class _LIBCPP_TYPE_VIS time_base
1875 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1878 template <class _CharT>
1879 class _LIBCPP_TYPE_VIS_ONLY __time_get_c_storage
1882 typedef basic_string<_CharT> string_type;
1884 virtual const string_type* __weeks() const;
1885 virtual const string_type* __months() const;
1886 virtual const string_type* __am_pm() const;
1887 virtual const string_type& __c() const;
1888 virtual const string_type& __r() const;
1889 virtual const string_type& __x() const;
1890 virtual const string_type& __X() const;
1893 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1894 class _LIBCPP_TYPE_VIS_ONLY time_get
1895 : public locale::facet,
1897 private __time_get_c_storage<_CharT>
1900 typedef _CharT char_type;
1901 typedef _InputIterator iter_type;
1902 typedef time_base::dateorder dateorder;
1903 typedef basic_string<char_type> string_type;
1905 _LIBCPP_ALWAYS_INLINE
1906 explicit time_get(size_t __refs = 0)
1907 : locale::facet(__refs) {}
1909 _LIBCPP_ALWAYS_INLINE
1910 dateorder date_order() const
1912 return this->do_date_order();
1915 _LIBCPP_ALWAYS_INLINE
1916 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1917 ios_base::iostate& __err, tm* __tm) const
1919 return do_get_time(__b, __e, __iob, __err, __tm);
1922 _LIBCPP_ALWAYS_INLINE
1923 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1924 ios_base::iostate& __err, tm* __tm) const
1926 return do_get_date(__b, __e, __iob, __err, __tm);
1929 _LIBCPP_ALWAYS_INLINE
1930 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1931 ios_base::iostate& __err, tm* __tm) const
1933 return do_get_weekday(__b, __e, __iob, __err, __tm);
1936 _LIBCPP_ALWAYS_INLINE
1937 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1938 ios_base::iostate& __err, tm* __tm) const
1940 return do_get_monthname(__b, __e, __iob, __err, __tm);
1943 _LIBCPP_ALWAYS_INLINE
1944 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1945 ios_base::iostate& __err, tm* __tm) const
1947 return do_get_year(__b, __e, __iob, __err, __tm);
1950 _LIBCPP_ALWAYS_INLINE
1951 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1952 ios_base::iostate& __err, tm *__tm,
1953 char __fmt, char __mod = 0) const
1955 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1958 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1959 ios_base::iostate& __err, tm* __tm,
1960 const char_type* __fmtb, const char_type* __fmte) const;
1962 static locale::id id;
1965 _LIBCPP_ALWAYS_INLINE
1968 virtual dateorder do_date_order() const;
1969 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1970 ios_base::iostate& __err, tm* __tm) const;
1971 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1972 ios_base::iostate& __err, tm* __tm) const;
1973 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1974 ios_base::iostate& __err, tm* __tm) const;
1975 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1976 ios_base::iostate& __err, tm* __tm) const;
1977 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1978 ios_base::iostate& __err, tm* __tm) const;
1979 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1980 ios_base::iostate& __err, tm* __tm,
1981 char __fmt, char __mod) const;
1983 void __get_white_space(iter_type& __b, iter_type __e,
1984 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1985 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1986 const ctype<char_type>& __ct) const;
1988 void __get_weekdayname(int& __m,
1989 iter_type& __b, iter_type __e,
1990 ios_base::iostate& __err,
1991 const ctype<char_type>& __ct) const;
1992 void __get_monthname(int& __m,
1993 iter_type& __b, iter_type __e,
1994 ios_base::iostate& __err,
1995 const ctype<char_type>& __ct) const;
1996 void __get_day(int& __d,
1997 iter_type& __b, iter_type __e,
1998 ios_base::iostate& __err,
1999 const ctype<char_type>& __ct) const;
2000 void __get_month(int& __m,
2001 iter_type& __b, iter_type __e,
2002 ios_base::iostate& __err,
2003 const ctype<char_type>& __ct) const;
2004 void __get_year(int& __y,
2005 iter_type& __b, iter_type __e,
2006 ios_base::iostate& __err,
2007 const ctype<char_type>& __ct) const;
2008 void __get_year4(int& __y,
2009 iter_type& __b, iter_type __e,
2010 ios_base::iostate& __err,
2011 const ctype<char_type>& __ct) const;
2012 void __get_hour(int& __d,
2013 iter_type& __b, iter_type __e,
2014 ios_base::iostate& __err,
2015 const ctype<char_type>& __ct) const;
2016 void __get_12_hour(int& __h,
2017 iter_type& __b, iter_type __e,
2018 ios_base::iostate& __err,
2019 const ctype<char_type>& __ct) const;
2020 void __get_am_pm(int& __h,
2021 iter_type& __b, iter_type __e,
2022 ios_base::iostate& __err,
2023 const ctype<char_type>& __ct) const;
2024 void __get_minute(int& __m,
2025 iter_type& __b, iter_type __e,
2026 ios_base::iostate& __err,
2027 const ctype<char_type>& __ct) const;
2028 void __get_second(int& __s,
2029 iter_type& __b, iter_type __e,
2030 ios_base::iostate& __err,
2031 const ctype<char_type>& __ct) const;
2032 void __get_weekday(int& __w,
2033 iter_type& __b, iter_type __e,
2034 ios_base::iostate& __err,
2035 const ctype<char_type>& __ct) const;
2036 void __get_day_year_num(int& __w,
2037 iter_type& __b, iter_type __e,
2038 ios_base::iostate& __err,
2039 const ctype<char_type>& __ct) const;
2042 template <class _CharT, class _InputIterator>
2044 time_get<_CharT, _InputIterator>::id;
2046 // time_get primitives
2048 template <class _CharT, class _InputIterator>
2050 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2051 iter_type& __b, iter_type __e,
2052 ios_base::iostate& __err,
2053 const ctype<char_type>& __ct) const
2055 // Note: ignoring case comes from the POSIX strptime spec
2056 const string_type* __wk = this->__weeks();
2057 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
2062 template <class _CharT, class _InputIterator>
2064 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2065 iter_type& __b, iter_type __e,
2066 ios_base::iostate& __err,
2067 const ctype<char_type>& __ct) const
2069 // Note: ignoring case comes from the POSIX strptime spec
2070 const string_type* __month = this->__months();
2071 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
2076 template <class _CharT, class _InputIterator>
2078 time_get<_CharT, _InputIterator>::__get_day(int& __d,
2079 iter_type& __b, iter_type __e,
2080 ios_base::iostate& __err,
2081 const ctype<char_type>& __ct) const
2083 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2084 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
2087 __err |= ios_base::failbit;
2090 template <class _CharT, class _InputIterator>
2092 time_get<_CharT, _InputIterator>::__get_month(int& __m,
2093 iter_type& __b, iter_type __e,
2094 ios_base::iostate& __err,
2095 const ctype<char_type>& __ct) const
2097 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
2098 if (!(__err & ios_base::failbit) && __t <= 11)
2101 __err |= ios_base::failbit;
2104 template <class _CharT, class _InputIterator>
2106 time_get<_CharT, _InputIterator>::__get_year(int& __y,
2107 iter_type& __b, iter_type __e,
2108 ios_base::iostate& __err,
2109 const ctype<char_type>& __ct) const
2111 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2112 if (!(__err & ios_base::failbit))
2116 else if (69 <= __t && __t <= 99)
2122 template <class _CharT, class _InputIterator>
2124 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2125 iter_type& __b, iter_type __e,
2126 ios_base::iostate& __err,
2127 const ctype<char_type>& __ct) const
2129 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2130 if (!(__err & ios_base::failbit))
2134 template <class _CharT, class _InputIterator>
2136 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2137 iter_type& __b, iter_type __e,
2138 ios_base::iostate& __err,
2139 const ctype<char_type>& __ct) const
2141 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2142 if (!(__err & ios_base::failbit) && __t <= 23)
2145 __err |= ios_base::failbit;
2148 template <class _CharT, class _InputIterator>
2150 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2151 iter_type& __b, iter_type __e,
2152 ios_base::iostate& __err,
2153 const ctype<char_type>& __ct) const
2155 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2156 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2159 __err |= ios_base::failbit;
2162 template <class _CharT, class _InputIterator>
2164 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2165 iter_type& __b, iter_type __e,
2166 ios_base::iostate& __err,
2167 const ctype<char_type>& __ct) const
2169 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2170 if (!(__err & ios_base::failbit) && __t <= 59)
2173 __err |= ios_base::failbit;
2176 template <class _CharT, class _InputIterator>
2178 time_get<_CharT, _InputIterator>::__get_second(int& __s,
2179 iter_type& __b, iter_type __e,
2180 ios_base::iostate& __err,
2181 const ctype<char_type>& __ct) const
2183 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2184 if (!(__err & ios_base::failbit) && __t <= 60)
2187 __err |= ios_base::failbit;
2190 template <class _CharT, class _InputIterator>
2192 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2193 iter_type& __b, iter_type __e,
2194 ios_base::iostate& __err,
2195 const ctype<char_type>& __ct) const
2197 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2198 if (!(__err & ios_base::failbit) && __t <= 6)
2201 __err |= ios_base::failbit;
2204 template <class _CharT, class _InputIterator>
2206 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2207 iter_type& __b, iter_type __e,
2208 ios_base::iostate& __err,
2209 const ctype<char_type>& __ct) const
2211 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2212 if (!(__err & ios_base::failbit) && __t <= 365)
2215 __err |= ios_base::failbit;
2218 template <class _CharT, class _InputIterator>
2220 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2221 ios_base::iostate& __err,
2222 const ctype<char_type>& __ct) const
2224 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2227 __err |= ios_base::eofbit;
2230 template <class _CharT, class _InputIterator>
2232 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2233 iter_type& __b, iter_type __e,
2234 ios_base::iostate& __err,
2235 const ctype<char_type>& __ct) const
2237 const string_type* __ap = this->__am_pm();
2238 if (__ap[0].size() + __ap[1].size() == 0)
2240 __err |= ios_base::failbit;
2243 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2244 if (__i == 0 && __h == 12)
2246 else if (__i == 1 && __h < 12)
2250 template <class _CharT, class _InputIterator>
2252 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2253 ios_base::iostate& __err,
2254 const ctype<char_type>& __ct) const
2258 __err |= ios_base::eofbit | ios_base::failbit;
2261 if (__ct.narrow(*__b, 0) != '%')
2262 __err |= ios_base::failbit;
2263 else if(++__b == __e)
2264 __err |= ios_base::eofbit;
2267 // time_get end primitives
2269 template <class _CharT, class _InputIterator>
2271 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2273 ios_base::iostate& __err, tm* __tm,
2274 const char_type* __fmtb, const char_type* __fmte) const
2276 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2277 __err = ios_base::goodbit;
2278 while (__fmtb != __fmte && __err == ios_base::goodbit)
2282 __err = ios_base::failbit;
2285 if (__ct.narrow(*__fmtb, 0) == '%')
2287 if (++__fmtb == __fmte)
2289 __err = ios_base::failbit;
2292 char __cmd = __ct.narrow(*__fmtb, 0);
2294 if (__cmd == 'E' || __cmd == '0')
2296 if (++__fmtb == __fmte)
2298 __err = ios_base::failbit;
2302 __cmd = __ct.narrow(*__fmtb, 0);
2304 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2307 else if (__ct.is(ctype_base::space, *__fmtb))
2309 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2311 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2314 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2320 __err = ios_base::failbit;
2323 __err |= ios_base::eofbit;
2327 template <class _CharT, class _InputIterator>
2328 typename time_get<_CharT, _InputIterator>::dateorder
2329 time_get<_CharT, _InputIterator>::do_date_order() const
2334 template <class _CharT, class _InputIterator>
2336 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2338 ios_base::iostate& __err,
2341 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2342 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2345 template <class _CharT, class _InputIterator>
2347 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2349 ios_base::iostate& __err,
2352 const string_type& __fmt = this->__x();
2353 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2356 template <class _CharT, class _InputIterator>
2358 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2360 ios_base::iostate& __err,
2363 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2364 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2368 template <class _CharT, class _InputIterator>
2370 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2372 ios_base::iostate& __err,
2375 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2376 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2380 template <class _CharT, class _InputIterator>
2382 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2384 ios_base::iostate& __err,
2387 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2388 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2392 template <class _CharT, class _InputIterator>
2394 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2396 ios_base::iostate& __err, tm* __tm,
2397 char __fmt, char) const
2399 __err = ios_base::goodbit;
2400 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2405 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2410 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2414 const string_type& __fm = this->__c();
2415 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2420 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2424 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2425 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2430 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2431 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2435 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2438 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2441 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2444 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2447 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2451 __get_white_space(__b, __e, __err, __ct);
2454 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2458 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2459 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2464 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2465 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2469 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2473 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2474 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2478 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2481 return do_get_date(__b, __e, __iob, __err, __tm);
2484 const string_type& __fm = this->__X();
2485 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2489 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2492 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2495 __get_percent(__b, __e, __err, __ct);
2498 __err |= ios_base::failbit;
2503 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
2504 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
2506 class _LIBCPP_TYPE_VIS __time_get
2511 __time_get(const char* __nm);
2512 __time_get(const string& __nm);
2516 template <class _CharT>
2517 class _LIBCPP_TYPE_VIS_ONLY __time_get_storage
2521 typedef basic_string<_CharT> string_type;
2523 string_type __weeks_[14];
2524 string_type __months_[24];
2525 string_type __am_pm_[2];
2531 explicit __time_get_storage(const char* __nm);
2532 explicit __time_get_storage(const string& __nm);
2534 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2536 time_base::dateorder __do_date_order() const;
2539 void init(const ctype<_CharT>&);
2540 string_type __analyze(char __fmt, const ctype<_CharT>&);
2543 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2544 class _LIBCPP_TYPE_VIS_ONLY time_get_byname
2545 : public time_get<_CharT, _InputIterator>,
2546 private __time_get_storage<_CharT>
2549 typedef time_base::dateorder dateorder;
2550 typedef _InputIterator iter_type;
2551 typedef _CharT char_type;
2552 typedef basic_string<char_type> string_type;
2554 _LIBCPP_INLINE_VISIBILITY
2555 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2556 : time_get<_CharT, _InputIterator>(__refs),
2557 __time_get_storage<_CharT>(__nm) {}
2558 _LIBCPP_INLINE_VISIBILITY
2559 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2560 : time_get<_CharT, _InputIterator>(__refs),
2561 __time_get_storage<_CharT>(__nm) {}
2564 _LIBCPP_INLINE_VISIBILITY
2565 ~time_get_byname() {}
2567 _LIBCPP_INLINE_VISIBILITY
2568 virtual dateorder do_date_order() const {return this->__do_date_order();}
2570 _LIBCPP_INLINE_VISIBILITY
2571 virtual const string_type* __weeks() const {return this->__weeks_;}
2572 _LIBCPP_INLINE_VISIBILITY
2573 virtual const string_type* __months() const {return this->__months_;}
2574 _LIBCPP_INLINE_VISIBILITY
2575 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2576 _LIBCPP_INLINE_VISIBILITY
2577 virtual const string_type& __c() const {return this->__c_;}
2578 _LIBCPP_INLINE_VISIBILITY
2579 virtual const string_type& __r() const {return this->__r_;}
2580 _LIBCPP_INLINE_VISIBILITY
2581 virtual const string_type& __x() const {return this->__x_;}
2582 _LIBCPP_INLINE_VISIBILITY
2583 virtual const string_type& __X() const {return this->__X_;}
2586 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
2587 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
2589 class _LIBCPP_TYPE_VIS __time_put
2593 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2594 __time_put(const char* __nm);
2595 __time_put(const string& __nm);
2597 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2598 char __fmt, char __mod) const;
2599 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2600 char __fmt, char __mod) const;
2603 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2604 class _LIBCPP_TYPE_VIS_ONLY time_put
2605 : public locale::facet,
2609 typedef _CharT char_type;
2610 typedef _OutputIterator iter_type;
2612 _LIBCPP_ALWAYS_INLINE
2613 explicit time_put(size_t __refs = 0)
2614 : locale::facet(__refs) {}
2616 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2617 const char_type* __pb, const char_type* __pe) const;
2619 _LIBCPP_ALWAYS_INLINE
2620 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2621 const tm* __tm, char __fmt, char __mod = 0) const
2623 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2626 static locale::id id;
2629 _LIBCPP_ALWAYS_INLINE
2631 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2632 char __fmt, char __mod) const;
2634 _LIBCPP_ALWAYS_INLINE
2635 explicit time_put(const char* __nm, size_t __refs)
2636 : locale::facet(__refs),
2638 _LIBCPP_ALWAYS_INLINE
2639 explicit time_put(const string& __nm, size_t __refs)
2640 : locale::facet(__refs),
2644 template <class _CharT, class _OutputIterator>
2646 time_put<_CharT, _OutputIterator>::id;
2648 template <class _CharT, class _OutputIterator>
2650 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2651 char_type __fl, const tm* __tm,
2652 const char_type* __pb,
2653 const char_type* __pe) const
2655 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2656 for (; __pb != __pe; ++__pb)
2658 if (__ct.narrow(*__pb, 0) == '%')
2666 char __fmt = __ct.narrow(*__pb, 0);
2667 if (__fmt == 'E' || __fmt == 'O')
2676 __fmt = __ct.narrow(*__pb, 0);
2678 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2686 template <class _CharT, class _OutputIterator>
2688 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2689 char_type, const tm* __tm,
2690 char __fmt, char __mod) const
2692 char_type __nar[100];
2693 char_type* __nb = __nar;
2694 char_type* __ne = __nb + 100;
2695 __do_put(__nb, __ne, __tm, __fmt, __mod);
2696 return _VSTD::copy(__nb, __ne, __s);
2699 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
2700 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
2702 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2703 class _LIBCPP_TYPE_VIS_ONLY time_put_byname
2704 : public time_put<_CharT, _OutputIterator>
2707 _LIBCPP_ALWAYS_INLINE
2708 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2709 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2711 _LIBCPP_ALWAYS_INLINE
2712 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2713 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2716 _LIBCPP_ALWAYS_INLINE
2717 ~time_put_byname() {}
2720 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
2721 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
2725 class _LIBCPP_TYPE_VIS money_base
2728 enum part {none, space, symbol, sign, value};
2729 struct pattern {char field[4];};
2731 _LIBCPP_ALWAYS_INLINE money_base() {}
2736 template <class _CharT, bool _International = false>
2737 class _LIBCPP_TYPE_VIS_ONLY moneypunct
2738 : public locale::facet,
2742 typedef _CharT char_type;
2743 typedef basic_string<char_type> string_type;
2745 _LIBCPP_ALWAYS_INLINE
2746 explicit moneypunct(size_t __refs = 0)
2747 : locale::facet(__refs) {}
2749 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2750 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2751 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2752 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2753 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2754 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2755 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2756 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2757 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2759 static locale::id id;
2760 static const bool intl = _International;
2763 _LIBCPP_ALWAYS_INLINE
2766 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2767 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2768 virtual string do_grouping() const {return string();}
2769 virtual string_type do_curr_symbol() const {return string_type();}
2770 virtual string_type do_positive_sign() const {return string_type();}
2771 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2772 virtual int do_frac_digits() const {return 0;}
2773 virtual pattern do_pos_format() const
2774 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2775 virtual pattern do_neg_format() const
2776 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2779 template <class _CharT, bool _International>
2781 moneypunct<_CharT, _International>::id;
2783 template <class _CharT, bool _International>
2785 moneypunct<_CharT, _International>::intl;
2787 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
2788 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
2789 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
2790 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
2792 // moneypunct_byname
2794 template <class _CharT, bool _International = false>
2795 class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname
2796 : public moneypunct<_CharT, _International>
2799 typedef money_base::pattern pattern;
2800 typedef _CharT char_type;
2801 typedef basic_string<char_type> string_type;
2803 _LIBCPP_ALWAYS_INLINE
2804 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2805 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2807 _LIBCPP_ALWAYS_INLINE
2808 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2809 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2812 _LIBCPP_ALWAYS_INLINE
2813 ~moneypunct_byname() {}
2815 virtual char_type do_decimal_point() const {return __decimal_point_;}
2816 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2817 virtual string do_grouping() const {return __grouping_;}
2818 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2819 virtual string_type do_positive_sign() const {return __positive_sign_;}
2820 virtual string_type do_negative_sign() const {return __negative_sign_;}
2821 virtual int do_frac_digits() const {return __frac_digits_;}
2822 virtual pattern do_pos_format() const {return __pos_format_;}
2823 virtual pattern do_neg_format() const {return __neg_format_;}
2826 char_type __decimal_point_;
2827 char_type __thousands_sep_;
2829 string_type __curr_symbol_;
2830 string_type __positive_sign_;
2831 string_type __negative_sign_;
2833 pattern __pos_format_;
2834 pattern __neg_format_;
2836 void init(const char*);
2839 template<> void moneypunct_byname<char, false>::init(const char*);
2840 template<> void moneypunct_byname<char, true>::init(const char*);
2841 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2842 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2844 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
2845 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
2846 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
2847 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
2851 template <class _CharT>
2855 typedef _CharT char_type;
2856 typedef basic_string<char_type> string_type;
2858 _LIBCPP_ALWAYS_INLINE __money_get() {}
2860 static void __gather_info(bool __intl, const locale& __loc,
2861 money_base::pattern& __pat, char_type& __dp,
2862 char_type& __ts, string& __grp,
2863 string_type& __sym, string_type& __psn,
2864 string_type& __nsn, int& __fd);
2867 template <class _CharT>
2869 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2870 money_base::pattern& __pat, char_type& __dp,
2871 char_type& __ts, string& __grp,
2872 string_type& __sym, string_type& __psn,
2873 string_type& __nsn, int& __fd)
2877 const moneypunct<char_type, true>& __mp =
2878 use_facet<moneypunct<char_type, true> >(__loc);
2879 __pat = __mp.neg_format();
2880 __nsn = __mp.negative_sign();
2881 __psn = __mp.positive_sign();
2882 __dp = __mp.decimal_point();
2883 __ts = __mp.thousands_sep();
2884 __grp = __mp.grouping();
2885 __sym = __mp.curr_symbol();
2886 __fd = __mp.frac_digits();
2890 const moneypunct<char_type, false>& __mp =
2891 use_facet<moneypunct<char_type, false> >(__loc);
2892 __pat = __mp.neg_format();
2893 __nsn = __mp.negative_sign();
2894 __psn = __mp.positive_sign();
2895 __dp = __mp.decimal_point();
2896 __ts = __mp.thousands_sep();
2897 __grp = __mp.grouping();
2898 __sym = __mp.curr_symbol();
2899 __fd = __mp.frac_digits();
2903 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
2904 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
2906 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2907 class _LIBCPP_TYPE_VIS_ONLY money_get
2908 : public locale::facet,
2909 private __money_get<_CharT>
2912 typedef _CharT char_type;
2913 typedef _InputIterator iter_type;
2914 typedef basic_string<char_type> string_type;
2916 _LIBCPP_ALWAYS_INLINE
2917 explicit money_get(size_t __refs = 0)
2918 : locale::facet(__refs) {}
2920 _LIBCPP_ALWAYS_INLINE
2921 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2922 ios_base::iostate& __err, long double& __v) const
2924 return do_get(__b, __e, __intl, __iob, __err, __v);
2927 _LIBCPP_ALWAYS_INLINE
2928 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2929 ios_base::iostate& __err, string_type& __v) const
2931 return do_get(__b, __e, __intl, __iob, __err, __v);
2934 static locale::id id;
2938 _LIBCPP_ALWAYS_INLINE
2941 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2942 ios_base& __iob, ios_base::iostate& __err,
2943 long double& __v) const;
2944 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2945 ios_base& __iob, ios_base::iostate& __err,
2946 string_type& __v) const;
2949 static bool __do_get(iter_type& __b, iter_type __e,
2950 bool __intl, const locale& __loc,
2951 ios_base::fmtflags __flags, ios_base::iostate& __err,
2952 bool& __neg, const ctype<char_type>& __ct,
2953 unique_ptr<char_type, void(*)(void*)>& __wb,
2954 char_type*& __wn, char_type* __we);
2957 template <class _CharT, class _InputIterator>
2959 money_get<_CharT, _InputIterator>::id;
2961 _LIBCPP_FUNC_VIS void __do_nothing(void*);
2963 template <class _Tp>
2966 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2968 bool __owns = __b.get_deleter() != __do_nothing;
2969 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
2970 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2971 2 * __cur_cap : numeric_limits<size_t>::max();
2973 __new_cap = sizeof(_Tp);
2974 size_t __n_off = static_cast<size_t>(__n - __b.get());
2975 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2977 __throw_bad_alloc();
2980 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2981 __new_cap /= sizeof(_Tp);
2982 __n = __b.get() + __n_off;
2983 __e = __b.get() + __new_cap;
2987 template <class _CharT, class _InputIterator>
2989 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2990 bool __intl, const locale& __loc,
2991 ios_base::fmtflags __flags,
2992 ios_base::iostate& __err,
2994 const ctype<char_type>& __ct,
2995 unique_ptr<char_type, void(*)(void*)>& __wb,
2996 char_type*& __wn, char_type* __we)
2998 const unsigned __bz = 100;
2999 unsigned __gbuf[__bz];
3000 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3001 unsigned* __gn = __gb.get();
3002 unsigned* __ge = __gn + __bz;
3003 money_base::pattern __pat;
3010 // Capture the spaces read into money_base::{space,none} so they
3011 // can be compared to initial spaces in __sym.
3012 string_type __spaces;
3014 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3015 __sym, __psn, __nsn, __fd);
3016 const string_type* __trailing_sign = 0;
3018 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3020 switch (__pat.field[__p])
3022 case money_base::space:
3025 if (__ct.is(ctype_base::space, *__b))
3026 __spaces.push_back(*__b++);
3029 __err |= ios_base::failbit;
3034 case money_base::none:
3037 while (__b != __e && __ct.is(ctype_base::space, *__b))
3038 __spaces.push_back(*__b++);
3041 case money_base::sign:
3042 if (__psn.size() + __nsn.size() > 0)
3044 if (__psn.size() == 0 || __nsn.size() == 0)
3045 { // sign is optional
3046 if (__psn.size() > 0)
3047 { // __nsn.size() == 0
3048 if (*__b == __psn[0])
3051 if (__psn.size() > 1)
3052 __trailing_sign = &__psn;
3057 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
3061 if (__nsn.size() > 1)
3062 __trailing_sign = &__nsn;
3065 else // sign is required
3067 if (*__b == __psn[0])
3070 if (__psn.size() > 1)
3071 __trailing_sign = &__psn;
3073 else if (*__b == __nsn[0])
3077 if (__nsn.size() > 1)
3078 __trailing_sign = &__nsn;
3082 __err |= ios_base::failbit;
3088 case money_base::symbol:
3090 bool __more_needed = __trailing_sign ||
3092 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
3093 bool __sb = (__flags & ios_base::showbase) != 0;
3094 if (__sb || __more_needed)
3096 typename string_type::const_iterator __sym_space_end = __sym.begin();
3097 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3098 __pat.field[__p - 1] == money_base::space)) {
3099 // Match spaces we've already read against spaces at
3100 // the beginning of __sym.
3101 while (__sym_space_end != __sym.end() &&
3102 __ct.is(ctype_base::space, *__sym_space_end))
3104 const size_t __num_spaces = __sym_space_end - __sym.begin();
3105 if (__num_spaces > __spaces.size() ||
3106 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3108 // No match. Put __sym_space_end back at the
3109 // beginning of __sym, which will prevent a
3110 // match in the next loop.
3111 __sym_space_end = __sym.begin();
3114 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3115 while (__sym_curr_char != __sym.end() && __b != __e &&
3116 *__b == *__sym_curr_char) {
3120 if (__sb && __sym_curr_char != __sym.end())
3122 __err |= ios_base::failbit;
3128 case money_base::value:
3131 for (; __b != __e; ++__b)
3133 char_type __c = *__b;
3134 if (__ct.is(ctype_base::digit, __c))
3137 __double_or_nothing(__wb, __wn, __we);
3141 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3144 __double_or_nothing(__gb, __gn, __ge);
3151 if (__gb.get() != __gn && __ng > 0)
3154 __double_or_nothing(__gb, __gn, __ge);
3159 if (__b == __e || *__b != __dp)
3161 __err |= ios_base::failbit;
3164 for (++__b; __fd > 0; --__fd, ++__b)
3166 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3168 __err |= ios_base::failbit;
3172 __double_or_nothing(__wb, __wn, __we);
3176 if (__wn == __wb.get())
3178 __err |= ios_base::failbit;
3185 if (__trailing_sign)
3187 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3189 if (__b == __e || *__b != (*__trailing_sign)[__i])
3191 __err |= ios_base::failbit;
3196 if (__gb.get() != __gn)
3198 ios_base::iostate __et = ios_base::goodbit;
3199 __check_grouping(__grp, __gb.get(), __gn, __et);
3202 __err |= ios_base::failbit;
3209 template <class _CharT, class _InputIterator>
3211 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3212 bool __intl, ios_base& __iob,
3213 ios_base::iostate& __err,
3214 long double& __v) const
3216 const int __bz = 100;
3217 char_type __wbuf[__bz];
3218 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3220 char_type* __we = __wbuf + __bz;
3221 locale __loc = __iob.getloc();
3222 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3224 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3227 const char __src[] = "0123456789";
3228 char_type __atoms[sizeof(__src)-1];
3229 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3231 char* __nc = __nbuf;
3232 unique_ptr<char, void(*)(void*)> __h(0, free);
3233 if (__wn - __wb.get() > __bz-2)
3235 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3237 __throw_bad_alloc();
3242 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3243 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3245 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3246 __throw_runtime_error("money_get error");
3249 __err |= ios_base::eofbit;
3253 template <class _CharT, class _InputIterator>
3255 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3256 bool __intl, ios_base& __iob,
3257 ios_base::iostate& __err,
3258 string_type& __v) const
3260 const int __bz = 100;
3261 char_type __wbuf[__bz];
3262 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3264 char_type* __we = __wbuf + __bz;
3265 locale __loc = __iob.getloc();
3266 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3268 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3273 __v.push_back(__ct.widen('-'));
3274 char_type __z = __ct.widen('0');
3276 for (__w = __wb.get(); __w < __wn-1; ++__w)
3279 __v.append(__w, __wn);
3282 __err |= ios_base::eofbit;
3286 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
3287 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
3291 template <class _CharT>
3295 typedef _CharT char_type;
3296 typedef basic_string<char_type> string_type;
3298 _LIBCPP_ALWAYS_INLINE __money_put() {}
3300 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3301 money_base::pattern& __pat, char_type& __dp,
3302 char_type& __ts, string& __grp,
3303 string_type& __sym, string_type& __sn,
3305 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3306 ios_base::fmtflags __flags,
3307 const char_type* __db, const char_type* __de,
3308 const ctype<char_type>& __ct, bool __neg,
3309 const money_base::pattern& __pat, char_type __dp,
3310 char_type __ts, const string& __grp,
3311 const string_type& __sym, const string_type& __sn,
3315 template <class _CharT>
3317 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3318 money_base::pattern& __pat, char_type& __dp,
3319 char_type& __ts, string& __grp,
3320 string_type& __sym, string_type& __sn,
3325 const moneypunct<char_type, true>& __mp =
3326 use_facet<moneypunct<char_type, true> >(__loc);
3329 __pat = __mp.neg_format();
3330 __sn = __mp.negative_sign();
3334 __pat = __mp.pos_format();
3335 __sn = __mp.positive_sign();
3337 __dp = __mp.decimal_point();
3338 __ts = __mp.thousands_sep();
3339 __grp = __mp.grouping();
3340 __sym = __mp.curr_symbol();
3341 __fd = __mp.frac_digits();
3345 const moneypunct<char_type, false>& __mp =
3346 use_facet<moneypunct<char_type, false> >(__loc);
3349 __pat = __mp.neg_format();
3350 __sn = __mp.negative_sign();
3354 __pat = __mp.pos_format();
3355 __sn = __mp.positive_sign();
3357 __dp = __mp.decimal_point();
3358 __ts = __mp.thousands_sep();
3359 __grp = __mp.grouping();
3360 __sym = __mp.curr_symbol();
3361 __fd = __mp.frac_digits();
3365 template <class _CharT>
3367 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3368 ios_base::fmtflags __flags,
3369 const char_type* __db, const char_type* __de,
3370 const ctype<char_type>& __ct, bool __neg,
3371 const money_base::pattern& __pat, char_type __dp,
3372 char_type __ts, const string& __grp,
3373 const string_type& __sym, const string_type& __sn,
3377 for (unsigned __p = 0; __p < 4; ++__p)
3379 switch (__pat.field[__p])
3381 case money_base::none:
3384 case money_base::space:
3386 *__me++ = __ct.widen(' ');
3388 case money_base::sign:
3392 case money_base::symbol:
3393 if (!__sym.empty() && (__flags & ios_base::showbase))
3394 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3396 case money_base::value:
3398 // remember start of value so we can reverse it
3399 char_type* __t = __me;
3400 // find beginning of digits
3403 // find end of digits
3404 const char_type* __d;
3405 for (__d = __db; __d < __de; ++__d)
3406 if (!__ct.is(ctype_base::digit, *__d))
3408 // print fractional part
3412 for (__f = __fd; __d > __db && __f > 0; --__f)
3414 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3415 for (; __f > 0; --__f)
3422 *__me++ = __ct.widen('0');
3428 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3429 : static_cast<unsigned>(__grp[__ig]);
3436 if (++__ig < __grp.size())
3437 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3438 numeric_limits<unsigned>::max() :
3439 static_cast<unsigned>(__grp[__ig]);
3451 // print rest of sign, if any
3452 if (__sn.size() > 1)
3453 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3455 if ((__flags & ios_base::adjustfield) == ios_base::left)
3457 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3461 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
3462 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
3464 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3465 class _LIBCPP_TYPE_VIS_ONLY money_put
3466 : public locale::facet,
3467 private __money_put<_CharT>
3470 typedef _CharT char_type;
3471 typedef _OutputIterator iter_type;
3472 typedef basic_string<char_type> string_type;
3474 _LIBCPP_ALWAYS_INLINE
3475 explicit money_put(size_t __refs = 0)
3476 : locale::facet(__refs) {}
3478 _LIBCPP_ALWAYS_INLINE
3479 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3480 long double __units) const
3482 return do_put(__s, __intl, __iob, __fl, __units);
3485 _LIBCPP_ALWAYS_INLINE
3486 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3487 const string_type& __digits) const
3489 return do_put(__s, __intl, __iob, __fl, __digits);
3492 static locale::id id;
3495 _LIBCPP_ALWAYS_INLINE
3498 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3499 char_type __fl, long double __units) const;
3500 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3501 char_type __fl, const string_type& __digits) const;
3504 template <class _CharT, class _OutputIterator>
3506 money_put<_CharT, _OutputIterator>::id;
3508 template <class _CharT, class _OutputIterator>
3510 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3511 ios_base& __iob, char_type __fl,
3512 long double __units) const
3515 const size_t __bs = 100;
3518 char_type __digits[__bs];
3519 char_type* __db = __digits;
3520 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3521 unique_ptr<char, void(*)(void*)> __hn(0, free);
3522 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3523 // secure memory for digit storage
3526 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
3527 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3529 __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units);
3532 __throw_bad_alloc();
3534 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3535 if (__hd == nullptr)
3536 __throw_bad_alloc();
3540 locale __loc = __iob.getloc();
3541 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3542 __ct.widen(__bb, __bb + __n, __db);
3543 bool __neg = __n > 0 && __bb[0] == '-';
3544 money_base::pattern __pat;
3551 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3552 // secure memory for formatting
3553 char_type __mbuf[__bs];
3554 char_type* __mb = __mbuf;
3555 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3556 size_t __exn = static_cast<int>(__n) > __fd ?
3557 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3558 __sym.size() + static_cast<size_t>(__fd) + 1
3559 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3562 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3565 __throw_bad_alloc();
3570 this->__format(__mb, __mi, __me, __iob.flags(),
3571 __db, __db + __n, __ct,
3572 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3573 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3576 template <class _CharT, class _OutputIterator>
3578 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3579 ios_base& __iob, char_type __fl,
3580 const string_type& __digits) const
3583 locale __loc = __iob.getloc();
3584 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3585 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3586 money_base::pattern __pat;
3593 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3594 // secure memory for formatting
3595 char_type __mbuf[100];
3596 char_type* __mb = __mbuf;
3597 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3598 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3599 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3600 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3601 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3604 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3607 __throw_bad_alloc();
3612 this->__format(__mb, __mi, __me, __iob.flags(),
3613 __digits.data(), __digits.data() + __digits.size(), __ct,
3614 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3615 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3618 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
3619 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
3623 class _LIBCPP_TYPE_VIS messages_base
3626 typedef ptrdiff_t catalog;
3628 _LIBCPP_ALWAYS_INLINE messages_base() {}
3631 template <class _CharT>
3632 class _LIBCPP_TYPE_VIS_ONLY messages
3633 : public locale::facet,
3634 public messages_base
3637 typedef _CharT char_type;
3638 typedef basic_string<_CharT> string_type;
3640 _LIBCPP_ALWAYS_INLINE
3641 explicit messages(size_t __refs = 0)
3642 : locale::facet(__refs) {}
3644 _LIBCPP_ALWAYS_INLINE
3645 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3647 return do_open(__nm, __loc);
3650 _LIBCPP_ALWAYS_INLINE
3651 string_type get(catalog __c, int __set, int __msgid,
3652 const string_type& __dflt) const
3654 return do_get(__c, __set, __msgid, __dflt);
3657 _LIBCPP_ALWAYS_INLINE
3658 void close(catalog __c) const
3663 static locale::id id;
3666 _LIBCPP_ALWAYS_INLINE
3669 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3670 virtual string_type do_get(catalog, int __set, int __msgid,
3671 const string_type& __dflt) const;
3672 virtual void do_close(catalog) const;
3675 template <class _CharT>
3677 messages<_CharT>::id;
3679 template <class _CharT>
3680 typename messages<_CharT>::catalog
3681 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3683 #ifdef _LIBCPP_HAS_CATOPEN
3684 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3686 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3688 #else // !_LIBCPP_HAS_CATOPEN
3690 #endif // _LIBCPP_HAS_CATOPEN
3693 template <class _CharT>
3694 typename messages<_CharT>::string_type
3695 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3696 const string_type& __dflt) const
3698 #ifdef _LIBCPP_HAS_CATOPEN
3700 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3702 __dflt.c_str() + __dflt.size());
3705 nl_catd __cat = (nl_catd)__c;
3706 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3708 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3709 __n, __n + strlen(__n));
3711 #else // !_LIBCPP_HAS_CATOPEN
3713 #endif // _LIBCPP_HAS_CATOPEN
3716 template <class _CharT>
3718 messages<_CharT>::do_close(catalog __c) const
3720 #ifdef _LIBCPP_HAS_CATOPEN
3723 nl_catd __cat = (nl_catd)__c;
3725 #endif // _LIBCPP_HAS_CATOPEN
3728 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
3729 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
3731 template <class _CharT>
3732 class _LIBCPP_TYPE_VIS_ONLY messages_byname
3733 : public messages<_CharT>
3736 typedef messages_base::catalog catalog;
3737 typedef basic_string<_CharT> string_type;
3739 _LIBCPP_ALWAYS_INLINE
3740 explicit messages_byname(const char*, size_t __refs = 0)
3741 : messages<_CharT>(__refs) {}
3743 _LIBCPP_ALWAYS_INLINE
3744 explicit messages_byname(const string&, size_t __refs = 0)
3745 : messages<_CharT>(__refs) {}
3748 _LIBCPP_ALWAYS_INLINE
3749 ~messages_byname() {}
3752 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
3753 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
3755 template<class _Codecvt, class _Elem = wchar_t,
3756 class _Wide_alloc = allocator<_Elem>,
3757 class _Byte_alloc = allocator<char> >
3758 class _LIBCPP_TYPE_VIS_ONLY wstring_convert
3761 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3762 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3763 typedef typename _Codecvt::state_type state_type;
3764 typedef typename wide_string::traits_type::int_type int_type;
3767 byte_string __byte_err_string_;
3768 wide_string __wide_err_string_;
3769 _Codecvt* __cvtptr_;
3770 state_type __cvtstate_;
3773 wstring_convert(const wstring_convert& __wc);
3774 wstring_convert& operator=(const wstring_convert& __wc);
3776 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3777 wstring_convert(_Codecvt* __pcvt, state_type __state);
3778 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
3779 const wide_string& __wide_err = wide_string());
3780 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3781 wstring_convert(wstring_convert&& __wc);
3785 _LIBCPP_ALWAYS_INLINE
3786 wide_string from_bytes(char __byte)
3787 {return from_bytes(&__byte, &__byte+1);}
3788 _LIBCPP_ALWAYS_INLINE
3789 wide_string from_bytes(const char* __ptr)
3790 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3791 _LIBCPP_ALWAYS_INLINE
3792 wide_string from_bytes(const byte_string& __str)
3793 {return from_bytes(__str.data(), __str.data() + __str.size());}
3794 wide_string from_bytes(const char* __first, const char* __last);
3796 _LIBCPP_ALWAYS_INLINE
3797 byte_string to_bytes(_Elem __wchar)
3798 {return to_bytes(&__wchar, &__wchar+1);}
3799 _LIBCPP_ALWAYS_INLINE
3800 byte_string to_bytes(const _Elem* __wptr)
3801 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3802 _LIBCPP_ALWAYS_INLINE
3803 byte_string to_bytes(const wide_string& __wstr)
3804 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3805 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3807 _LIBCPP_ALWAYS_INLINE
3808 size_t converted() const _NOEXCEPT {return __cvtcount_;}
3809 _LIBCPP_ALWAYS_INLINE
3810 state_type state() const {return __cvtstate_;}
3813 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3814 inline _LIBCPP_ALWAYS_INLINE
3815 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3816 wstring_convert(_Codecvt* __pcvt)
3817 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3821 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3822 inline _LIBCPP_ALWAYS_INLINE
3823 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3824 wstring_convert(_Codecvt* __pcvt, state_type __state)
3825 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3829 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3830 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3831 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3832 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3833 __cvtstate_(), __cvtcount_(0)
3835 __cvtptr_ = new _Codecvt;
3838 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3840 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3841 inline _LIBCPP_ALWAYS_INLINE
3842 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3843 wstring_convert(wstring_convert&& __wc)
3844 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3845 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3846 __cvtptr_(__wc.__cvtptr_),
3847 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
3849 __wc.__cvtptr_ = nullptr;
3852 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3854 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3855 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3860 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3861 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3862 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3863 from_bytes(const char* __frm, const char* __frm_end)
3866 if (__cvtptr_ != nullptr)
3868 wide_string __ws(2*(__frm_end - __frm), _Elem());
3869 if (__frm != __frm_end)
3870 __ws.resize(__ws.capacity());
3871 codecvt_base::result __r = codecvt_base::ok;
3872 state_type __st = __cvtstate_;
3873 if (__frm != __frm_end)
3875 _Elem* __to = &__ws[0];
3876 _Elem* __to_end = __to + __ws.size();
3877 const char* __frm_nxt;
3881 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3882 __to, __to_end, __to_nxt);
3883 __cvtcount_ += __frm_nxt - __frm;
3884 if (__frm_nxt == __frm)
3886 __r = codecvt_base::error;
3888 else if (__r == codecvt_base::noconv)
3890 __ws.resize(__to - &__ws[0]);
3891 // This only gets executed if _Elem is char
3892 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3894 __r = codecvt_base::ok;
3896 else if (__r == codecvt_base::ok)
3898 __ws.resize(__to_nxt - &__ws[0]);
3901 else if (__r == codecvt_base::partial)
3903 ptrdiff_t __s = __to_nxt - &__ws[0];
3904 __ws.resize(2 * __s);
3905 __to = &__ws[0] + __s;
3906 __to_end = &__ws[0] + __ws.size();
3909 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3911 if (__r == codecvt_base::ok)
3914 #ifndef _LIBCPP_NO_EXCEPTIONS
3915 if (__wide_err_string_.empty())
3916 throw range_error("wstring_convert: from_bytes error");
3917 #endif // _LIBCPP_NO_EXCEPTIONS
3918 return __wide_err_string_;
3921 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3922 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3923 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3924 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3927 if (__cvtptr_ != nullptr)
3929 byte_string __bs(2*(__frm_end - __frm), char());
3930 if (__frm != __frm_end)
3931 __bs.resize(__bs.capacity());
3932 codecvt_base::result __r = codecvt_base::ok;
3933 state_type __st = __cvtstate_;
3934 if (__frm != __frm_end)
3936 char* __to = &__bs[0];
3937 char* __to_end = __to + __bs.size();
3938 const _Elem* __frm_nxt;
3942 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3943 __to, __to_end, __to_nxt);
3944 __cvtcount_ += __frm_nxt - __frm;
3945 if (__frm_nxt == __frm)
3947 __r = codecvt_base::error;
3949 else if (__r == codecvt_base::noconv)
3951 __bs.resize(__to - &__bs[0]);
3952 // This only gets executed if _Elem is char
3953 __bs.append((const char*)__frm, (const char*)__frm_end);
3955 __r = codecvt_base::ok;
3957 else if (__r == codecvt_base::ok)
3959 __bs.resize(__to_nxt - &__bs[0]);
3962 else if (__r == codecvt_base::partial)
3964 ptrdiff_t __s = __to_nxt - &__bs[0];
3965 __bs.resize(2 * __s);
3966 __to = &__bs[0] + __s;
3967 __to_end = &__bs[0] + __bs.size();
3970 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3972 if (__r == codecvt_base::ok)
3974 size_t __s = __bs.size();
3975 __bs.resize(__bs.capacity());
3976 char* __to = &__bs[0] + __s;
3977 char* __to_end = __to + __bs.size();
3981 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3982 if (__r == codecvt_base::noconv)
3984 __bs.resize(__to - &__bs[0]);
3985 __r = codecvt_base::ok;
3987 else if (__r == codecvt_base::ok)
3989 __bs.resize(__to_nxt - &__bs[0]);
3991 else if (__r == codecvt_base::partial)
3993 ptrdiff_t __sp = __to_nxt - &__bs[0];
3994 __bs.resize(2 * __sp);
3995 __to = &__bs[0] + __sp;
3996 __to_end = &__bs[0] + __bs.size();
3998 } while (__r == codecvt_base::partial);
3999 if (__r == codecvt_base::ok)
4003 #ifndef _LIBCPP_NO_EXCEPTIONS
4004 if (__byte_err_string_.empty())
4005 throw range_error("wstring_convert: to_bytes error");
4006 #endif // _LIBCPP_NO_EXCEPTIONS
4007 return __byte_err_string_;
4010 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
4011 class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert
4012 : public basic_streambuf<_Elem, _Tr>
4016 typedef _Elem char_type;
4017 typedef _Tr traits_type;
4018 typedef typename traits_type::int_type int_type;
4019 typedef typename traits_type::pos_type pos_type;
4020 typedef typename traits_type::off_type off_type;
4021 typedef typename _Codecvt::state_type state_type;
4025 const char* __extbufnext_;
4026 const char* __extbufend_;
4027 char __extbuf_min_[8];
4029 char_type* __intbuf_;
4031 streambuf* __bufptr_;
4034 ios_base::openmode __cm_;
4037 bool __always_noconv_;
4039 wbuffer_convert(const wbuffer_convert&);
4040 wbuffer_convert& operator=(const wbuffer_convert&);
4042 _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0,
4043 _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
4046 _LIBCPP_INLINE_VISIBILITY
4047 streambuf* rdbuf() const {return __bufptr_;}
4048 _LIBCPP_INLINE_VISIBILITY
4049 streambuf* rdbuf(streambuf* __bytebuf)
4051 streambuf* __r = __bufptr_;
4052 __bufptr_ = __bytebuf;
4056 _LIBCPP_INLINE_VISIBILITY
4057 state_type state() const {return __st_;}
4060 virtual int_type underflow();
4061 virtual int_type pbackfail(int_type __c = traits_type::eof());
4062 virtual int_type overflow (int_type __c = traits_type::eof());
4063 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4065 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4066 ios_base::openmode __wch = ios_base::in | ios_base::out);
4067 virtual pos_type seekpos(pos_type __sp,
4068 ios_base::openmode __wch = ios_base::in | ios_base::out);
4073 void __write_mode();
4074 wbuffer_convert* __close();
4077 template <class _Codecvt, class _Elem, class _Tr>
4078 wbuffer_convert<_Codecvt, _Elem, _Tr>::
4079 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4086 __bufptr_(__bytebuf),
4092 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4097 template <class _Codecvt, class _Elem, class _Tr>
4098 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4103 delete [] __extbuf_;
4105 delete [] __intbuf_;
4108 template <class _Codecvt, class _Elem, class _Tr>
4109 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4110 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4112 if (__cv_ == 0 || __bufptr_ == 0)
4113 return traits_type::eof();
4114 bool __initial = __read_mode();
4116 if (this->gptr() == 0)
4117 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4118 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4119 int_type __c = traits_type::eof();
4120 if (this->gptr() == this->egptr())
4122 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4123 if (__always_noconv_)
4125 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4126 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4129 this->setg(this->eback(),
4130 this->eback() + __unget_sz,
4131 this->eback() + __unget_sz + __nmemb);
4132 __c = *this->gptr();
4137 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4138 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4139 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
4140 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
4141 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4142 codecvt_base::result __r;
4143 state_type __svs = __st_;
4144 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4147 __extbufend_ = __extbufnext_ + __nr;
4149 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4150 this->eback() + __unget_sz,
4151 this->egptr(), __inext);
4152 if (__r == codecvt_base::noconv)
4154 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4155 __c = *this->gptr();
4157 else if (__inext != this->eback() + __unget_sz)
4159 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4160 __c = *this->gptr();
4166 __c = *this->gptr();
4167 if (this->eback() == &__1buf)
4168 this->setg(0, 0, 0);
4172 template <class _Codecvt, class _Elem, class _Tr>
4173 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4174 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4176 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4178 if (traits_type::eq_int_type(__c, traits_type::eof()))
4181 return traits_type::not_eof(__c);
4183 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4186 *this->gptr() = traits_type::to_char_type(__c);
4190 return traits_type::eof();
4193 template <class _Codecvt, class _Elem, class _Tr>
4194 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4195 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4197 if (__cv_ == 0 || __bufptr_ == 0)
4198 return traits_type::eof();
4201 char_type* __pb_save = this->pbase();
4202 char_type* __epb_save = this->epptr();
4203 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4205 if (this->pptr() == 0)
4206 this->setp(&__1buf, &__1buf+1);
4207 *this->pptr() = traits_type::to_char_type(__c);
4210 if (this->pptr() != this->pbase())
4212 if (__always_noconv_)
4214 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4215 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4216 return traits_type::eof();
4220 char* __extbe = __extbuf_;
4221 codecvt_base::result __r;
4224 const char_type* __e;
4225 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4226 __extbuf_, __extbuf_ + __ebs_, __extbe);
4227 if (__e == this->pbase())
4228 return traits_type::eof();
4229 if (__r == codecvt_base::noconv)
4231 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4232 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4233 return traits_type::eof();
4235 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4237 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4238 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4239 return traits_type::eof();
4240 if (__r == codecvt_base::partial)
4242 this->setp((char_type*)__e, this->pptr());
4243 this->pbump(this->epptr() - this->pbase());
4247 return traits_type::eof();
4248 } while (__r == codecvt_base::partial);
4250 this->setp(__pb_save, __epb_save);
4252 return traits_type::not_eof(__c);
4255 template <class _Codecvt, class _Elem, class _Tr>
4256 basic_streambuf<_Elem, _Tr>*
4257 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4259 this->setg(0, 0, 0);
4262 delete [] __extbuf_;
4264 delete [] __intbuf_;
4266 if (__ebs_ > sizeof(__extbuf_min_))
4268 if (__always_noconv_ && __s)
4270 __extbuf_ = (char*)__s;
4275 __extbuf_ = new char[__ebs_];
4281 __extbuf_ = __extbuf_min_;
4282 __ebs_ = sizeof(__extbuf_min_);
4285 if (!__always_noconv_)
4287 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4288 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4295 __intbuf_ = new char_type[__ibs_];
4308 template <class _Codecvt, class _Elem, class _Tr>
4309 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4310 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4311 ios_base::openmode __om)
4313 int __width = __cv_->encoding();
4314 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4315 return pos_type(off_type(-1));
4316 // __width > 0 || __off == 0
4326 return pos_type(off_type(-1));
4328 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4333 template <class _Codecvt, class _Elem, class _Tr>
4334 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4335 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4337 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4338 return pos_type(off_type(-1));
4339 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4340 return pos_type(off_type(-1));
4344 template <class _Codecvt, class _Elem, class _Tr>
4346 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4348 if (__cv_ == 0 || __bufptr_ == 0)
4350 if (__cm_ & ios_base::out)
4352 if (this->pptr() != this->pbase())
4353 if (overflow() == traits_type::eof())
4355 codecvt_base::result __r;
4359 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4360 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4361 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4363 } while (__r == codecvt_base::partial);
4364 if (__r == codecvt_base::error)
4366 if (__bufptr_->pubsync())
4369 else if (__cm_ & ios_base::in)
4372 if (__always_noconv_)
4373 __c = this->egptr() - this->gptr();
4376 int __width = __cv_->encoding();
4377 __c = __extbufend_ - __extbufnext_;
4379 __c += __width * (this->egptr() - this->gptr());
4382 if (this->gptr() != this->egptr())
4384 reverse(this->gptr(), this->egptr());
4385 codecvt_base::result __r;
4386 const char_type* __e = this->gptr();
4390 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4391 __extbuf_, __extbuf_ + __ebs_, __extbe);
4394 case codecvt_base::noconv:
4395 __c += this->egptr() - this->gptr();
4397 case codecvt_base::ok:
4398 case codecvt_base::partial:
4399 __c += __extbe - __extbuf_;
4404 } while (__r == codecvt_base::partial);
4408 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4410 this->setg(0, 0, 0);
4416 template <class _Codecvt, class _Elem, class _Tr>
4418 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4420 if (!(__cm_ & ios_base::in))
4423 if (__always_noconv_)
4424 this->setg((char_type*)__extbuf_,
4425 (char_type*)__extbuf_ + __ebs_,
4426 (char_type*)__extbuf_ + __ebs_);
4428 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4429 __cm_ = ios_base::in;
4435 template <class _Codecvt, class _Elem, class _Tr>
4437 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4439 if (!(__cm_ & ios_base::out))
4441 this->setg(0, 0, 0);
4442 if (__ebs_ > sizeof(__extbuf_min_))
4444 if (__always_noconv_)
4445 this->setp((char_type*)__extbuf_,
4446 (char_type*)__extbuf_ + (__ebs_ - 1));
4448 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4452 __cm_ = ios_base::out;
4456 template <class _Codecvt, class _Elem, class _Tr>
4457 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4458 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4460 wbuffer_convert* __rt = 0;
4461 if (__cv_ != 0 && __bufptr_ != 0)
4464 if ((__cm_ & ios_base::out) && sync())
4470 _LIBCPP_END_NAMESPACE_STD
4472 #endif // _LIBCPP_LOCALE