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>
201 #elif !defined(__ANDROID__)
202 #include <nl_types.h>
206 #include <Availability.h>
209 #include <__undef_min_max>
211 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
212 #pragma GCC system_header
215 _LIBCPP_BEGIN_NAMESPACE_STD
217 #if defined(__APPLE__) || defined(__FreeBSD__)
218 # define _LIBCPP_GET_C_LOCALE 0
219 #elif defined(__NetBSD__)
220 # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
222 # define _LIBCPP_GET_C_LOCALE __cloc()
223 // Get the C locale object
224 _LIBCPP_FUNC_VIS locale_t __cloc();
225 #define __cloc_defined
228 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
229 typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
230 #ifndef _LIBCPP_LOCALE__L_EXTENSIONS
231 typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
234 // OSX has nice foo_l() functions that let you turn off use of the global
235 // locale. Linux, not so much. The following functions avoid the locale when
236 // that's possible and otherwise do the wrong thing. FIXME.
237 #if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \
238 defined(_NEWLIB_VERSION)
240 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
241 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
242 inline _LIBCPP_INLINE_VISIBILITY
243 __mb_cur_max_l(locale_t __l)
245 return MB_CUR_MAX_L(__l);
247 #else // _LIBCPP_LOCALE__L_EXTENSIONS
248 inline _LIBCPP_ALWAYS_INLINE
249 decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
251 __locale_raii __current(uselocale(__l), uselocale);
254 #endif // _LIBCPP_LOCALE__L_EXTENSIONS
256 inline _LIBCPP_ALWAYS_INLINE
257 wint_t __btowc_l(int __c, locale_t __l)
259 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
260 return btowc_l(__c, __l);
262 __locale_raii __current(uselocale(__l), uselocale);
267 inline _LIBCPP_ALWAYS_INLINE
268 int __wctob_l(wint_t __c, locale_t __l)
270 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
271 return wctob_l(__c, __l);
273 __locale_raii __current(uselocale(__l), uselocale);
278 inline _LIBCPP_ALWAYS_INLINE
279 size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
280 size_t __len, mbstate_t *__ps, locale_t __l)
282 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
283 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
285 __locale_raii __current(uselocale(__l), uselocale);
286 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
290 inline _LIBCPP_ALWAYS_INLINE
291 size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
293 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
294 return wcrtomb_l(__s, __wc, __ps, __l);
296 __locale_raii __current(uselocale(__l), uselocale);
297 return wcrtomb(__s, __wc, __ps);
301 inline _LIBCPP_ALWAYS_INLINE
302 size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
303 size_t __len, mbstate_t *__ps, locale_t __l)
305 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
306 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
308 __locale_raii __current(uselocale(__l), uselocale);
309 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
313 inline _LIBCPP_ALWAYS_INLINE
314 size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
315 mbstate_t *__ps, locale_t __l)
317 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
318 return mbrtowc_l(__pwc, __s, __n, __ps, __l);
320 __locale_raii __current(uselocale(__l), uselocale);
321 return mbrtowc(__pwc, __s, __n, __ps);
325 inline _LIBCPP_ALWAYS_INLINE
326 int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
328 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
329 return mbtowc_l(__pwc, __pmb, __max, __l);
331 __locale_raii __current(uselocale(__l), uselocale);
332 return mbtowc(__pwc, __pmb, __max);
336 inline _LIBCPP_ALWAYS_INLINE
337 size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
339 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
340 return mbrlen_l(__s, __n, __ps, __l);
342 __locale_raii __current(uselocale(__l), uselocale);
343 return mbrlen(__s, __n, __ps);
347 inline _LIBCPP_ALWAYS_INLINE
348 lconv *__localeconv_l(locale_t __l)
350 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
351 return localeconv_l(__l);
353 __locale_raii __current(uselocale(__l), uselocale);
358 inline _LIBCPP_ALWAYS_INLINE
359 size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
360 mbstate_t *__ps, locale_t __l)
362 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
363 return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
365 __locale_raii __current(uselocale(__l), uselocale);
366 return mbsrtowcs(__dest, __src, __len, __ps);
371 int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
373 va_start(__va, __format);
374 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
375 int __res = vsnprintf_l(__s, __n, __l, __format, __va);
377 __locale_raii __current(uselocale(__l), uselocale);
378 int __res = vsnprintf(__s, __n, __format, __va);
385 int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
387 va_start(__va, __format);
388 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
389 int __res = vasprintf_l(__s, __l, __format, __va);
391 __locale_raii __current(uselocale(__l), uselocale);
392 int __res = vasprintf(__s, __format, __va);
399 int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
401 va_start(__va, __format);
402 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
403 int __res = vsscanf_l(__s, __l, __format, __va);
405 __locale_raii __current(uselocale(__l), uselocale);
406 int __res = vsscanf(__s, __format, __va);
415 // Scans [__b, __e) until a match is found in the basic_strings range
416 // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
417 // __b will be incremented (visibly), consuming CharT until a match is found
418 // or proved to not exist. A keyword may be "", in which will match anything.
419 // If one keyword is a prefix of another, and the next CharT in the input
420 // might match another keyword, the algorithm will attempt to find the longest
421 // matching keyword. If the longer matching keyword ends up not matching, then
422 // no keyword match is found. If no keyword match is found, __ke is returned
423 // and failbit is set in __err.
424 // Else an iterator pointing to the matching keyword is found. If more than
425 // one keyword matches, an iterator to the first matching keyword is returned.
426 // If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
427 // __ct is used to force to lower case before comparing characters.
429 // Keywords: "a", "abb"
430 // If the input is "a", the first keyword matches and eofbit is set.
431 // If the input is "abc", no match is found and "ab" are consumed.
432 template <class _InputIterator, class _ForwardIterator, class _Ctype>
435 __scan_keyword(_InputIterator& __b, _InputIterator __e,
436 _ForwardIterator __kb, _ForwardIterator __ke,
437 const _Ctype& __ct, ios_base::iostate& __err,
438 bool __case_sensitive = true)
440 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
441 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
442 const unsigned char __doesnt_match = '\0';
443 const unsigned char __might_match = '\1';
444 const unsigned char __does_match = '\2';
445 unsigned char __statbuf[100];
446 unsigned char* __status = __statbuf;
447 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
448 if (__nkw > sizeof(__statbuf))
450 __status = (unsigned char*)malloc(__nkw);
453 __stat_hold.reset(__status);
455 size_t __n_might_match = __nkw; // At this point, any keyword might match
456 size_t __n_does_match = 0; // but none of them definitely do
457 // Initialize all statuses to __might_match, except for "" keywords are __does_match
458 unsigned char* __st = __status;
459 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
462 *__st = __might_match;
465 *__st = __does_match;
470 // While there might be a match, test keywords against the next CharT
471 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
473 // Peek at the next CharT but don't consume it
475 if (!__case_sensitive)
476 __c = __ct.toupper(__c);
477 bool __consume = false;
478 // For each keyword which might match, see if the __indx character is __c
479 // If a match if found, consume __c
480 // If a match is found, and that is the last character in the keyword,
481 // then that keyword matches.
482 // If the keyword doesn't match this character, then change the keyword
485 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
487 if (*__st == __might_match)
489 _CharT __kc = (*__ky)[__indx];
490 if (!__case_sensitive)
491 __kc = __ct.toupper(__kc);
495 if (__ky->size() == __indx+1)
497 *__st = __does_match;
504 *__st = __doesnt_match;
509 // consume if we matched a character
513 // If we consumed a character and there might be a matched keyword that
514 // was marked matched on a previous iteration, then such keywords
515 // which are now marked as not matching.
516 if (__n_might_match + __n_does_match > 1)
519 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
521 if (*__st == __does_match && __ky->size() != __indx+1)
523 *__st = __doesnt_match;
530 // We've exited the loop because we hit eof and/or we have no more "might matches".
532 __err |= ios_base::eofbit;
533 // Return the first matching result
534 for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
535 if (*__st == __does_match)
538 __err |= ios_base::failbit;
542 struct _LIBCPP_TYPE_VIS __num_get_base
544 static const int __num_get_buf_sz = 40;
546 static int __get_base(ios_base&);
547 static const char __src[33];
551 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
552 ios_base::iostate& __err);
554 template <class _CharT>
556 : protected __num_get_base
558 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
559 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
560 _CharT& __thousands_sep);
561 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
562 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
563 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
564 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
565 char* __a, char*& __a_end,
566 _CharT __decimal_point, _CharT __thousands_sep,
567 const string& __grouping, unsigned* __g,
568 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
571 template <class _CharT>
573 __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
575 locale __loc = __iob.getloc();
576 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
577 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
578 __thousands_sep = __np.thousands_sep();
579 return __np.grouping();
582 template <class _CharT>
584 __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
585 _CharT& __thousands_sep)
587 locale __loc = __iob.getloc();
588 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
589 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
590 __decimal_point = __np.decimal_point();
591 __thousands_sep = __np.thousands_sep();
592 return __np.grouping();
595 template <class _CharT>
597 __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
598 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
599 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
601 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
603 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
607 if (__grouping.size() != 0 && __ct == __thousands_sep)
609 if (__g_end-__g < __num_get_buf_sz)
616 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
629 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
632 *__a_end++ = __src[__f];
637 *__a_end++ = __src[__f];
642 template <class _CharT>
644 __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
645 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
646 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
648 if (__ct == __decimal_point)
654 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
658 if (__ct == __thousands_sep && __grouping.size() != 0)
662 if (__g_end-__g < __num_get_buf_sz)
669 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
672 char __x = __src[__f];
673 if (__x == '-' || __x == '+')
675 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
682 if (__x == 'x' || __x == 'X')
684 else if ((__x & 0x5F) == __exp)
690 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
701 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
702 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
704 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
705 class _LIBCPP_TYPE_VIS_ONLY num_get
706 : public locale::facet,
707 private __num_get<_CharT>
710 typedef _CharT char_type;
711 typedef _InputIterator iter_type;
713 _LIBCPP_ALWAYS_INLINE
714 explicit num_get(size_t __refs = 0)
715 : locale::facet(__refs) {}
717 _LIBCPP_ALWAYS_INLINE
718 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
719 ios_base::iostate& __err, bool& __v) const
721 return do_get(__b, __e, __iob, __err, __v);
724 _LIBCPP_ALWAYS_INLINE
725 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
726 ios_base::iostate& __err, long& __v) const
728 return do_get(__b, __e, __iob, __err, __v);
731 _LIBCPP_ALWAYS_INLINE
732 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
733 ios_base::iostate& __err, long long& __v) const
735 return do_get(__b, __e, __iob, __err, __v);
738 _LIBCPP_ALWAYS_INLINE
739 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
740 ios_base::iostate& __err, unsigned short& __v) const
742 return do_get(__b, __e, __iob, __err, __v);
745 _LIBCPP_ALWAYS_INLINE
746 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
747 ios_base::iostate& __err, unsigned int& __v) const
749 return do_get(__b, __e, __iob, __err, __v);
752 _LIBCPP_ALWAYS_INLINE
753 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
754 ios_base::iostate& __err, unsigned long& __v) const
756 return do_get(__b, __e, __iob, __err, __v);
759 _LIBCPP_ALWAYS_INLINE
760 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
761 ios_base::iostate& __err, unsigned long long& __v) const
763 return do_get(__b, __e, __iob, __err, __v);
766 _LIBCPP_ALWAYS_INLINE
767 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
768 ios_base::iostate& __err, float& __v) const
770 return do_get(__b, __e, __iob, __err, __v);
773 _LIBCPP_ALWAYS_INLINE
774 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
775 ios_base::iostate& __err, double& __v) const
777 return do_get(__b, __e, __iob, __err, __v);
780 _LIBCPP_ALWAYS_INLINE
781 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
782 ios_base::iostate& __err, long double& __v) const
784 return do_get(__b, __e, __iob, __err, __v);
787 _LIBCPP_ALWAYS_INLINE
788 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
789 ios_base::iostate& __err, void*& __v) const
791 return do_get(__b, __e, __iob, __err, __v);
794 static locale::id id;
797 _LIBCPP_ALWAYS_INLINE
801 iter_type __do_get_floating_point
802 (iter_type __b, iter_type __e, ios_base& __iob,
803 ios_base::iostate& __err, _Fp& __v) const;
805 template <class _Signed>
806 iter_type __do_get_signed
807 (iter_type __b, iter_type __e, ios_base& __iob,
808 ios_base::iostate& __err, _Signed& __v) const;
810 template <class _Unsigned>
811 iter_type __do_get_unsigned
812 (iter_type __b, iter_type __e, ios_base& __iob,
813 ios_base::iostate& __err, _Unsigned& __v) const;
816 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
817 ios_base::iostate& __err, bool& __v) const;
819 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
820 ios_base::iostate& __err, long& __v) const
821 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
823 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
824 ios_base::iostate& __err, long long& __v) const
825 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
827 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
828 ios_base::iostate& __err, unsigned short& __v) const
829 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
831 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
832 ios_base::iostate& __err, unsigned int& __v) const
833 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
835 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
836 ios_base::iostate& __err, unsigned long& __v) const
837 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
839 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
840 ios_base::iostate& __err, unsigned long long& __v) const
841 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
843 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
844 ios_base::iostate& __err, float& __v) const
845 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
847 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
848 ios_base::iostate& __err, double& __v) const
849 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
851 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
852 ios_base::iostate& __err, long double& __v) const
853 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
855 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
856 ios_base::iostate& __err, void*& __v) const;
859 template <class _CharT, class _InputIterator>
861 num_get<_CharT, _InputIterator>::id;
865 __num_get_signed_integral(const char* __a, const char* __a_end,
866 ios_base::iostate& __err, int __base)
870 typename remove_reference<decltype(errno)>::type __save_errno = errno;
873 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
874 typename remove_reference<decltype(errno)>::type __current_errno = errno;
875 if (__current_errno == 0)
876 errno = __save_errno;
879 __err = ios_base::failbit;
882 else if (__current_errno == ERANGE ||
883 __ll < numeric_limits<_Tp>::min() ||
884 numeric_limits<_Tp>::max() < __ll)
886 __err = ios_base::failbit;
888 return numeric_limits<_Tp>::max();
890 return numeric_limits<_Tp>::min();
892 return static_cast<_Tp>(__ll);
894 __err = ios_base::failbit;
900 __num_get_unsigned_integral(const char* __a, const char* __a_end,
901 ios_base::iostate& __err, int __base)
907 __err = ios_base::failbit;
910 typename remove_reference<decltype(errno)>::type __save_errno = errno;
913 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
914 typename remove_reference<decltype(errno)>::type __current_errno = errno;
915 if (__current_errno == 0)
916 errno = __save_errno;
919 __err = ios_base::failbit;
922 else if (__current_errno == ERANGE ||
923 numeric_limits<_Tp>::max() < __ll)
925 __err = ios_base::failbit;
926 return numeric_limits<_Tp>::max();
928 return static_cast<_Tp>(__ll);
930 __err = ios_base::failbit;
936 __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
940 typename remove_reference<decltype(errno)>::type __save_errno = errno;
943 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
944 typename remove_reference<decltype(errno)>::type __current_errno = errno;
945 if (__current_errno == 0)
946 errno = __save_errno;
949 __err = ios_base::failbit;
952 else if (__current_errno == ERANGE)
953 __err = ios_base::failbit;
954 return static_cast<_Tp>(__ld);
956 __err = ios_base::failbit;
960 template <class _CharT, class _InputIterator>
962 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
964 ios_base::iostate& __err,
967 if ((__iob.flags() & ios_base::boolalpha) == 0)
970 __b = do_get(__b, __e, __iob, __err, __lv);
981 __err = ios_base::failbit;
986 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
987 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
988 typedef typename numpunct<_CharT>::string_type string_type;
989 const string_type __names[2] = {__np.truename(), __np.falsename()};
990 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
992 __v = __i == __names;
998 template <class _CharT, class _InputIterator>
999 template <class _Signed>
1001 num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
1003 ios_base::iostate& __err,
1007 int __base = this->__get_base(__iob);
1009 char_type __atoms[26];
1010 char_type __thousands_sep;
1011 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1013 __buf.resize(__buf.capacity());
1014 char* __a = &__buf[0];
1015 char* __a_end = __a;
1016 unsigned __g[__num_get_base::__num_get_buf_sz];
1017 unsigned* __g_end = __g;
1019 for (; __b != __e; ++__b)
1021 if (__a_end == __a + __buf.size())
1023 size_t __tmp = __buf.size();
1024 __buf.resize(2*__buf.size());
1025 __buf.resize(__buf.capacity());
1027 __a_end = __a + __tmp;
1029 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1030 __thousands_sep, __grouping, __g, __g_end,
1034 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1037 __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
1038 // Digit grouping checked
1039 __check_grouping(__grouping, __g, __g_end, __err);
1042 __err |= ios_base::eofbit;
1048 template <class _CharT, class _InputIterator>
1049 template <class _Unsigned>
1051 num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
1053 ios_base::iostate& __err,
1054 _Unsigned& __v) const
1057 int __base = this->__get_base(__iob);
1059 char_type __atoms[26];
1060 char_type __thousands_sep;
1061 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1063 __buf.resize(__buf.capacity());
1064 char* __a = &__buf[0];
1065 char* __a_end = __a;
1066 unsigned __g[__num_get_base::__num_get_buf_sz];
1067 unsigned* __g_end = __g;
1069 for (; __b != __e; ++__b)
1071 if (__a_end == __a + __buf.size())
1073 size_t __tmp = __buf.size();
1074 __buf.resize(2*__buf.size());
1075 __buf.resize(__buf.capacity());
1077 __a_end = __a + __tmp;
1079 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1080 __thousands_sep, __grouping, __g, __g_end,
1084 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1087 __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
1088 // Digit grouping checked
1089 __check_grouping(__grouping, __g, __g_end, __err);
1092 __err |= ios_base::eofbit;
1098 template <class _CharT, class _InputIterator>
1099 template <class _Fp>
1101 num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
1103 ios_base::iostate& __err,
1106 // Stage 1, nothing to do
1108 char_type __atoms[32];
1109 char_type __decimal_point;
1110 char_type __thousands_sep;
1111 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1115 __buf.resize(__buf.capacity());
1116 char* __a = &__buf[0];
1117 char* __a_end = __a;
1118 unsigned __g[__num_get_base::__num_get_buf_sz];
1119 unsigned* __g_end = __g;
1121 bool __in_units = true;
1123 for (; __b != __e; ++__b)
1125 if (__a_end == __a + __buf.size())
1127 size_t __tmp = __buf.size();
1128 __buf.resize(2*__buf.size());
1129 __buf.resize(__buf.capacity());
1131 __a_end = __a + __tmp;
1133 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1134 __decimal_point, __thousands_sep,
1135 __grouping, __g, __g_end,
1139 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1142 __v = __num_get_float<_Fp>(__a, __a_end, __err);
1143 // Digit grouping checked
1144 __check_grouping(__grouping, __g, __g_end, __err);
1147 __err |= ios_base::eofbit;
1151 template <class _CharT, class _InputIterator>
1153 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1155 ios_base::iostate& __err,
1161 char_type __atoms[26];
1162 char_type __thousands_sep = 0;
1164 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1165 __num_get_base::__src + 26, __atoms);
1167 __buf.resize(__buf.capacity());
1168 char* __a = &__buf[0];
1169 char* __a_end = __a;
1170 unsigned __g[__num_get_base::__num_get_buf_sz];
1171 unsigned* __g_end = __g;
1173 for (; __b != __e; ++__b)
1175 if (__a_end == __a + __buf.size())
1177 size_t __tmp = __buf.size();
1178 __buf.resize(2*__buf.size());
1179 __buf.resize(__buf.capacity());
1181 __a_end = __a + __tmp;
1183 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1184 __thousands_sep, __grouping,
1185 __g, __g_end, __atoms))
1189 __buf.resize(__a_end - __a);
1190 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1191 if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1193 if (__sscanf_l(__buf.c_str(), __cloc(), "%p", &__v) != 1)
1195 __err = ios_base::failbit;
1198 __err |= ios_base::eofbit;
1202 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
1203 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
1205 struct _LIBCPP_TYPE_VIS __num_put_base
1208 static void __format_int(char* __fmt, const char* __len, bool __signd,
1209 ios_base::fmtflags __flags);
1210 static bool __format_float(char* __fmt, const char* __len,
1211 ios_base::fmtflags __flags);
1212 static char* __identify_padding(char* __nb, char* __ne,
1213 const ios_base& __iob);
1216 template <class _CharT>
1218 : protected __num_put_base
1220 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1221 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1222 const locale& __loc);
1223 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1224 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1225 const locale& __loc);
1228 template <class _CharT>
1230 __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1231 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1232 const locale& __loc)
1234 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1235 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1236 string __grouping = __npt.grouping();
1237 if (__grouping.empty())
1239 __ct.widen(__nb, __ne, __ob);
1240 __oe = __ob + (__ne - __nb);
1246 if (*__nf == '-' || *__nf == '+')
1247 *__oe++ = __ct.widen(*__nf++);
1248 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1251 *__oe++ = __ct.widen(*__nf++);
1252 *__oe++ = __ct.widen(*__nf++);
1254 reverse(__nf, __ne);
1255 _CharT __thousands_sep = __npt.thousands_sep();
1258 for (char* __p = __nf; __p < __ne; ++__p)
1260 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1261 __dc == static_cast<unsigned>(__grouping[__dg]))
1263 *__oe++ = __thousands_sep;
1265 if (__dg < __grouping.size()-1)
1268 *__oe++ = __ct.widen(*__p);
1271 reverse(__ob + (__nf - __nb), __oe);
1276 __op = __ob + (__np - __nb);
1279 template <class _CharT>
1281 __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1282 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1283 const locale& __loc)
1285 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1286 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1287 string __grouping = __npt.grouping();
1290 if (*__nf == '-' || *__nf == '+')
1291 *__oe++ = __ct.widen(*__nf++);
1293 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1296 *__oe++ = __ct.widen(*__nf++);
1297 *__oe++ = __ct.widen(*__nf++);
1298 for (__ns = __nf; __ns < __ne; ++__ns)
1299 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1304 for (__ns = __nf; __ns < __ne; ++__ns)
1305 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1308 if (__grouping.empty())
1310 __ct.widen(__nf, __ns, __oe);
1311 __oe += __ns - __nf;
1315 reverse(__nf, __ns);
1316 _CharT __thousands_sep = __npt.thousands_sep();
1319 for (char* __p = __nf; __p < __ns; ++__p)
1321 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1323 *__oe++ = __thousands_sep;
1325 if (__dg < __grouping.size()-1)
1328 *__oe++ = __ct.widen(*__p);
1331 reverse(__ob + (__nf - __nb), __oe);
1333 for (__nf = __ns; __nf < __ne; ++__nf)
1337 *__oe++ = __npt.decimal_point();
1342 *__oe++ = __ct.widen(*__nf);
1344 __ct.widen(__nf, __ne, __oe);
1345 __oe += __ne - __nf;
1349 __op = __ob + (__np - __nb);
1352 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
1353 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
1355 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1356 class _LIBCPP_TYPE_VIS_ONLY num_put
1357 : public locale::facet,
1358 private __num_put<_CharT>
1361 typedef _CharT char_type;
1362 typedef _OutputIterator iter_type;
1364 _LIBCPP_ALWAYS_INLINE
1365 explicit num_put(size_t __refs = 0)
1366 : locale::facet(__refs) {}
1368 _LIBCPP_ALWAYS_INLINE
1369 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1372 return do_put(__s, __iob, __fl, __v);
1375 _LIBCPP_ALWAYS_INLINE
1376 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1379 return do_put(__s, __iob, __fl, __v);
1382 _LIBCPP_ALWAYS_INLINE
1383 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1384 long long __v) const
1386 return do_put(__s, __iob, __fl, __v);
1389 _LIBCPP_ALWAYS_INLINE
1390 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1391 unsigned long __v) const
1393 return do_put(__s, __iob, __fl, __v);
1396 _LIBCPP_ALWAYS_INLINE
1397 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1398 unsigned long long __v) const
1400 return do_put(__s, __iob, __fl, __v);
1403 _LIBCPP_ALWAYS_INLINE
1404 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1407 return do_put(__s, __iob, __fl, __v);
1410 _LIBCPP_ALWAYS_INLINE
1411 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1412 long double __v) const
1414 return do_put(__s, __iob, __fl, __v);
1417 _LIBCPP_ALWAYS_INLINE
1418 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1419 const void* __v) const
1421 return do_put(__s, __iob, __fl, __v);
1424 static locale::id id;
1427 _LIBCPP_ALWAYS_INLINE
1430 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1432 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1434 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1435 long long __v) const;
1436 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1437 unsigned long) const;
1438 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1439 unsigned long long) const;
1440 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1442 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1443 long double __v) const;
1444 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1445 const void* __v) const;
1448 template <class _CharT, class _OutputIterator>
1450 num_put<_CharT, _OutputIterator>::id;
1452 template <class _CharT, class _OutputIterator>
1455 __pad_and_output(_OutputIterator __s,
1456 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1457 ios_base& __iob, _CharT __fl)
1459 streamsize __sz = __oe - __ob;
1460 streamsize __ns = __iob.width();
1465 for (;__ob < __op; ++__ob, ++__s)
1467 for (; __ns; --__ns, ++__s)
1469 for (; __ob < __oe; ++__ob, ++__s)
1475 #if !defined(__APPLE__) || \
1476 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1477 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1479 template <class _CharT, class _Traits>
1481 ostreambuf_iterator<_CharT, _Traits>
1482 __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1483 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1484 ios_base& __iob, _CharT __fl)
1486 if (__s.__sbuf_ == nullptr)
1488 streamsize __sz = __oe - __ob;
1489 streamsize __ns = __iob.width();
1494 streamsize __np = __op - __ob;
1497 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1499 __s.__sbuf_ = nullptr;
1505 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1506 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1508 __s.__sbuf_ = nullptr;
1515 if (__s.__sbuf_->sputn(__op, __np) != __np)
1517 __s.__sbuf_ = nullptr;
1527 template <class _CharT, class _OutputIterator>
1529 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1530 char_type __fl, bool __v) const
1532 if ((__iob.flags() & ios_base::boolalpha) == 0)
1533 return do_put(__s, __iob, __fl, (unsigned long)__v);
1534 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1535 typedef typename numpunct<char_type>::string_type string_type;
1536 #if _LIBCPP_DEBUG_LEVEL >= 2
1537 string_type __tmp(__v ? __np.truename() : __np.falsename());
1538 string_type __nm = _VSTD::move(__tmp);
1540 string_type __nm = __v ? __np.truename() : __np.falsename();
1542 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1547 template <class _CharT, class _OutputIterator>
1549 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1550 char_type __fl, long __v) const
1552 // Stage 1 - Get number in narrow char
1553 char __fmt[6] = {'%', 0};
1554 const char* __len = "l";
1555 this->__format_int(__fmt+1, __len, true, __iob.flags());
1556 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1557 + ((numeric_limits<long>::digits % 3) != 0)
1558 + ((__iob.flags() & ios_base::showbase) != 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), __cloc(), __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)
1589 + ((__iob.flags() & ios_base::showbase) != 0)
1592 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1593 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1595 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1597 char* __ne = __nar + __nc;
1598 char* __np = this->__identify_padding(__nar, __ne, __iob);
1599 // Stage 2 - Widen __nar while adding thousands separators
1600 char_type __o[2*(__nbuf-1) - 1];
1601 char_type* __op; // pad here
1602 char_type* __oe; // end of output
1603 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1604 // [__o, __oe) contains thousands_sep'd wide number
1606 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1609 template <class _CharT, class _OutputIterator>
1611 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1612 char_type __fl, unsigned long __v) const
1614 // Stage 1 - Get number in narrow char
1615 char __fmt[6] = {'%', 0};
1616 const char* __len = "l";
1617 this->__format_int(__fmt+1, __len, false, __iob.flags());
1618 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1619 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1620 + ((__iob.flags() & ios_base::showbase) != 0)
1623 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1624 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1626 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1628 char* __ne = __nar + __nc;
1629 char* __np = this->__identify_padding(__nar, __ne, __iob);
1630 // Stage 2 - Widen __nar while adding thousands separators
1631 char_type __o[2*(__nbuf-1) - 1];
1632 char_type* __op; // pad here
1633 char_type* __oe; // end of output
1634 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1635 // [__o, __oe) contains thousands_sep'd wide number
1637 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1640 template <class _CharT, class _OutputIterator>
1642 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1643 char_type __fl, unsigned long long __v) const
1645 // Stage 1 - Get number in narrow char
1646 char __fmt[8] = {'%', 0};
1647 const char* __len = "ll";
1648 this->__format_int(__fmt+1, __len, false, __iob.flags());
1649 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1650 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1651 + ((__iob.flags() & ios_base::showbase) != 0)
1654 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1655 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1657 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1659 char* __ne = __nar + __nc;
1660 char* __np = this->__identify_padding(__nar, __ne, __iob);
1661 // Stage 2 - Widen __nar while adding thousands separators
1662 char_type __o[2*(__nbuf-1) - 1];
1663 char_type* __op; // pad here
1664 char_type* __oe; // end of output
1665 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1666 // [__o, __oe) contains thousands_sep'd wide number
1668 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1671 template <class _CharT, class _OutputIterator>
1673 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1674 char_type __fl, double __v) const
1676 // Stage 1 - Get number in narrow char
1677 char __fmt[8] = {'%', 0};
1678 const char* __len = "";
1679 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1680 const unsigned __nbuf = 30;
1684 if (__specify_precision)
1685 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1686 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1687 (int)__iob.precision(), __v);
1689 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1690 (int)__iob.precision(), __v);
1693 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1694 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1696 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1698 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1699 if (__nc > static_cast<int>(__nbuf-1))
1701 if (__specify_precision)
1702 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1703 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1705 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1706 (int)__iob.precision(), __v);
1709 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1710 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1712 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
1715 __throw_bad_alloc();
1718 char* __ne = __nb + __nc;
1719 char* __np = this->__identify_padding(__nb, __ne, __iob);
1720 // Stage 2 - Widen __nar while adding thousands separators
1721 char_type __o[2*(__nbuf-1) - 1];
1722 char_type* __ob = __o;
1723 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1726 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1728 __throw_bad_alloc();
1731 char_type* __op; // pad here
1732 char_type* __oe; // end of output
1733 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1734 // [__o, __oe) contains thousands_sep'd wide number
1736 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1740 template <class _CharT, class _OutputIterator>
1742 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1743 char_type __fl, long double __v) const
1745 // Stage 1 - Get number in narrow char
1746 char __fmt[8] = {'%', 0};
1747 const char* __len = "L";
1748 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1749 const unsigned __nbuf = 30;
1753 if (__specify_precision)
1754 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1755 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1756 (int)__iob.precision(), __v);
1758 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1759 (int)__iob.precision(), __v);
1762 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1763 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1765 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1767 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1768 if (__nc > static_cast<int>(__nbuf-1))
1770 if (__specify_precision)
1771 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1772 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1774 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1775 (int)__iob.precision(), __v);
1778 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1779 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1781 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
1784 __throw_bad_alloc();
1787 char* __ne = __nb + __nc;
1788 char* __np = this->__identify_padding(__nb, __ne, __iob);
1789 // Stage 2 - Widen __nar while adding thousands separators
1790 char_type __o[2*(__nbuf-1) - 1];
1791 char_type* __ob = __o;
1792 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1795 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1797 __throw_bad_alloc();
1800 char_type* __op; // pad here
1801 char_type* __oe; // end of output
1802 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1803 // [__o, __oe) contains thousands_sep'd wide number
1805 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1809 template <class _CharT, class _OutputIterator>
1811 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1812 char_type __fl, const void* __v) const
1814 // Stage 1 - Get pointer in narrow char
1815 char __fmt[6] = "%p";
1816 const unsigned __nbuf = 20;
1818 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1819 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1821 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1823 char* __ne = __nar + __nc;
1824 char* __np = this->__identify_padding(__nar, __ne, __iob);
1825 // Stage 2 - Widen __nar
1826 char_type __o[2*(__nbuf-1) - 1];
1827 char_type* __op; // pad here
1828 char_type* __oe; // end of output
1829 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1830 __ct.widen(__nar, __ne, __o);
1831 __oe = __o + (__ne - __nar);
1835 __op = __o + (__np - __nar);
1836 // [__o, __oe) contains wide number
1838 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1841 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)
1842 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
1844 template <class _CharT, class _InputIterator>
1847 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1848 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1850 // Precondition: __n >= 1
1853 __err |= ios_base::eofbit | ios_base::failbit;
1858 if (!__ct.is(ctype_base::digit, __c))
1860 __err |= ios_base::failbit;
1863 int __r = __ct.narrow(__c, 0) - '0';
1864 for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
1868 if (!__ct.is(ctype_base::digit, __c))
1870 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1873 __err |= ios_base::eofbit;
1877 class _LIBCPP_TYPE_VIS time_base
1880 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1883 template <class _CharT>
1884 class _LIBCPP_TYPE_VIS_ONLY __time_get_c_storage
1887 typedef basic_string<_CharT> string_type;
1889 virtual const string_type* __weeks() const;
1890 virtual const string_type* __months() const;
1891 virtual const string_type* __am_pm() const;
1892 virtual const string_type& __c() const;
1893 virtual const string_type& __r() const;
1894 virtual const string_type& __x() const;
1895 virtual const string_type& __X() const;
1898 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1899 class _LIBCPP_TYPE_VIS_ONLY time_get
1900 : public locale::facet,
1902 private __time_get_c_storage<_CharT>
1905 typedef _CharT char_type;
1906 typedef _InputIterator iter_type;
1907 typedef time_base::dateorder dateorder;
1908 typedef basic_string<char_type> string_type;
1910 _LIBCPP_ALWAYS_INLINE
1911 explicit time_get(size_t __refs = 0)
1912 : locale::facet(__refs) {}
1914 _LIBCPP_ALWAYS_INLINE
1915 dateorder date_order() const
1917 return this->do_date_order();
1920 _LIBCPP_ALWAYS_INLINE
1921 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1922 ios_base::iostate& __err, tm* __tm) const
1924 return do_get_time(__b, __e, __iob, __err, __tm);
1927 _LIBCPP_ALWAYS_INLINE
1928 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1929 ios_base::iostate& __err, tm* __tm) const
1931 return do_get_date(__b, __e, __iob, __err, __tm);
1934 _LIBCPP_ALWAYS_INLINE
1935 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1936 ios_base::iostate& __err, tm* __tm) const
1938 return do_get_weekday(__b, __e, __iob, __err, __tm);
1941 _LIBCPP_ALWAYS_INLINE
1942 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1943 ios_base::iostate& __err, tm* __tm) const
1945 return do_get_monthname(__b, __e, __iob, __err, __tm);
1948 _LIBCPP_ALWAYS_INLINE
1949 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1950 ios_base::iostate& __err, tm* __tm) const
1952 return do_get_year(__b, __e, __iob, __err, __tm);
1955 _LIBCPP_ALWAYS_INLINE
1956 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1957 ios_base::iostate& __err, tm *__tm,
1958 char __fmt, char __mod = 0) const
1960 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1963 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1964 ios_base::iostate& __err, tm* __tm,
1965 const char_type* __fmtb, const char_type* __fmte) const;
1967 static locale::id id;
1970 _LIBCPP_ALWAYS_INLINE
1973 virtual dateorder do_date_order() const;
1974 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1975 ios_base::iostate& __err, tm* __tm) const;
1976 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1977 ios_base::iostate& __err, tm* __tm) const;
1978 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1979 ios_base::iostate& __err, tm* __tm) const;
1980 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1981 ios_base::iostate& __err, tm* __tm) const;
1982 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1983 ios_base::iostate& __err, tm* __tm) const;
1984 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1985 ios_base::iostate& __err, tm* __tm,
1986 char __fmt, char __mod) const;
1988 void __get_white_space(iter_type& __b, iter_type __e,
1989 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1990 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1991 const ctype<char_type>& __ct) const;
1993 void __get_weekdayname(int& __m,
1994 iter_type& __b, iter_type __e,
1995 ios_base::iostate& __err,
1996 const ctype<char_type>& __ct) const;
1997 void __get_monthname(int& __m,
1998 iter_type& __b, iter_type __e,
1999 ios_base::iostate& __err,
2000 const ctype<char_type>& __ct) const;
2001 void __get_day(int& __d,
2002 iter_type& __b, iter_type __e,
2003 ios_base::iostate& __err,
2004 const ctype<char_type>& __ct) const;
2005 void __get_month(int& __m,
2006 iter_type& __b, iter_type __e,
2007 ios_base::iostate& __err,
2008 const ctype<char_type>& __ct) const;
2009 void __get_year(int& __y,
2010 iter_type& __b, iter_type __e,
2011 ios_base::iostate& __err,
2012 const ctype<char_type>& __ct) const;
2013 void __get_year4(int& __y,
2014 iter_type& __b, iter_type __e,
2015 ios_base::iostate& __err,
2016 const ctype<char_type>& __ct) const;
2017 void __get_hour(int& __d,
2018 iter_type& __b, iter_type __e,
2019 ios_base::iostate& __err,
2020 const ctype<char_type>& __ct) const;
2021 void __get_12_hour(int& __h,
2022 iter_type& __b, iter_type __e,
2023 ios_base::iostate& __err,
2024 const ctype<char_type>& __ct) const;
2025 void __get_am_pm(int& __h,
2026 iter_type& __b, iter_type __e,
2027 ios_base::iostate& __err,
2028 const ctype<char_type>& __ct) const;
2029 void __get_minute(int& __m,
2030 iter_type& __b, iter_type __e,
2031 ios_base::iostate& __err,
2032 const ctype<char_type>& __ct) const;
2033 void __get_second(int& __s,
2034 iter_type& __b, iter_type __e,
2035 ios_base::iostate& __err,
2036 const ctype<char_type>& __ct) const;
2037 void __get_weekday(int& __w,
2038 iter_type& __b, iter_type __e,
2039 ios_base::iostate& __err,
2040 const ctype<char_type>& __ct) const;
2041 void __get_day_year_num(int& __w,
2042 iter_type& __b, iter_type __e,
2043 ios_base::iostate& __err,
2044 const ctype<char_type>& __ct) const;
2047 template <class _CharT, class _InputIterator>
2049 time_get<_CharT, _InputIterator>::id;
2051 // time_get primitives
2053 template <class _CharT, class _InputIterator>
2055 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2056 iter_type& __b, iter_type __e,
2057 ios_base::iostate& __err,
2058 const ctype<char_type>& __ct) const
2060 // Note: ignoring case comes from the POSIX strptime spec
2061 const string_type* __wk = this->__weeks();
2062 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
2067 template <class _CharT, class _InputIterator>
2069 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2070 iter_type& __b, iter_type __e,
2071 ios_base::iostate& __err,
2072 const ctype<char_type>& __ct) const
2074 // Note: ignoring case comes from the POSIX strptime spec
2075 const string_type* __month = this->__months();
2076 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
2081 template <class _CharT, class _InputIterator>
2083 time_get<_CharT, _InputIterator>::__get_day(int& __d,
2084 iter_type& __b, iter_type __e,
2085 ios_base::iostate& __err,
2086 const ctype<char_type>& __ct) const
2088 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2089 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
2092 __err |= ios_base::failbit;
2095 template <class _CharT, class _InputIterator>
2097 time_get<_CharT, _InputIterator>::__get_month(int& __m,
2098 iter_type& __b, iter_type __e,
2099 ios_base::iostate& __err,
2100 const ctype<char_type>& __ct) const
2102 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
2103 if (!(__err & ios_base::failbit) && __t <= 11)
2106 __err |= ios_base::failbit;
2109 template <class _CharT, class _InputIterator>
2111 time_get<_CharT, _InputIterator>::__get_year(int& __y,
2112 iter_type& __b, iter_type __e,
2113 ios_base::iostate& __err,
2114 const ctype<char_type>& __ct) const
2116 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2117 if (!(__err & ios_base::failbit))
2121 else if (69 <= __t && __t <= 99)
2127 template <class _CharT, class _InputIterator>
2129 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2130 iter_type& __b, iter_type __e,
2131 ios_base::iostate& __err,
2132 const ctype<char_type>& __ct) const
2134 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2135 if (!(__err & ios_base::failbit))
2139 template <class _CharT, class _InputIterator>
2141 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2142 iter_type& __b, iter_type __e,
2143 ios_base::iostate& __err,
2144 const ctype<char_type>& __ct) const
2146 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2147 if (!(__err & ios_base::failbit) && __t <= 23)
2150 __err |= ios_base::failbit;
2153 template <class _CharT, class _InputIterator>
2155 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2156 iter_type& __b, iter_type __e,
2157 ios_base::iostate& __err,
2158 const ctype<char_type>& __ct) const
2160 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2161 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2164 __err |= ios_base::failbit;
2167 template <class _CharT, class _InputIterator>
2169 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2170 iter_type& __b, iter_type __e,
2171 ios_base::iostate& __err,
2172 const ctype<char_type>& __ct) const
2174 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2175 if (!(__err & ios_base::failbit) && __t <= 59)
2178 __err |= ios_base::failbit;
2181 template <class _CharT, class _InputIterator>
2183 time_get<_CharT, _InputIterator>::__get_second(int& __s,
2184 iter_type& __b, iter_type __e,
2185 ios_base::iostate& __err,
2186 const ctype<char_type>& __ct) const
2188 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2189 if (!(__err & ios_base::failbit) && __t <= 60)
2192 __err |= ios_base::failbit;
2195 template <class _CharT, class _InputIterator>
2197 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2198 iter_type& __b, iter_type __e,
2199 ios_base::iostate& __err,
2200 const ctype<char_type>& __ct) const
2202 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2203 if (!(__err & ios_base::failbit) && __t <= 6)
2206 __err |= ios_base::failbit;
2209 template <class _CharT, class _InputIterator>
2211 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2212 iter_type& __b, iter_type __e,
2213 ios_base::iostate& __err,
2214 const ctype<char_type>& __ct) const
2216 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2217 if (!(__err & ios_base::failbit) && __t <= 365)
2220 __err |= ios_base::failbit;
2223 template <class _CharT, class _InputIterator>
2225 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2226 ios_base::iostate& __err,
2227 const ctype<char_type>& __ct) const
2229 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2232 __err |= ios_base::eofbit;
2235 template <class _CharT, class _InputIterator>
2237 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2238 iter_type& __b, iter_type __e,
2239 ios_base::iostate& __err,
2240 const ctype<char_type>& __ct) const
2242 const string_type* __ap = this->__am_pm();
2243 if (__ap[0].size() + __ap[1].size() == 0)
2245 __err |= ios_base::failbit;
2248 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2249 if (__i == 0 && __h == 12)
2251 else if (__i == 1 && __h < 12)
2255 template <class _CharT, class _InputIterator>
2257 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2258 ios_base::iostate& __err,
2259 const ctype<char_type>& __ct) const
2263 __err |= ios_base::eofbit | ios_base::failbit;
2266 if (__ct.narrow(*__b, 0) != '%')
2267 __err |= ios_base::failbit;
2268 else if(++__b == __e)
2269 __err |= ios_base::eofbit;
2272 // time_get end primitives
2274 template <class _CharT, class _InputIterator>
2276 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2278 ios_base::iostate& __err, tm* __tm,
2279 const char_type* __fmtb, const char_type* __fmte) const
2281 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2282 __err = ios_base::goodbit;
2283 while (__fmtb != __fmte && __err == ios_base::goodbit)
2287 __err = ios_base::failbit;
2290 if (__ct.narrow(*__fmtb, 0) == '%')
2292 if (++__fmtb == __fmte)
2294 __err = ios_base::failbit;
2297 char __cmd = __ct.narrow(*__fmtb, 0);
2299 if (__cmd == 'E' || __cmd == '0')
2301 if (++__fmtb == __fmte)
2303 __err = ios_base::failbit;
2307 __cmd = __ct.narrow(*__fmtb, 0);
2309 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2312 else if (__ct.is(ctype_base::space, *__fmtb))
2314 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2316 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2319 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2325 __err = ios_base::failbit;
2328 __err |= ios_base::eofbit;
2332 template <class _CharT, class _InputIterator>
2333 typename time_get<_CharT, _InputIterator>::dateorder
2334 time_get<_CharT, _InputIterator>::do_date_order() const
2339 template <class _CharT, class _InputIterator>
2341 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2343 ios_base::iostate& __err,
2346 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2347 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2350 template <class _CharT, class _InputIterator>
2352 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2354 ios_base::iostate& __err,
2357 const string_type& __fmt = this->__x();
2358 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2361 template <class _CharT, class _InputIterator>
2363 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2365 ios_base::iostate& __err,
2368 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2369 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2373 template <class _CharT, class _InputIterator>
2375 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2377 ios_base::iostate& __err,
2380 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2381 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2385 template <class _CharT, class _InputIterator>
2387 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2389 ios_base::iostate& __err,
2392 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2393 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2397 template <class _CharT, class _InputIterator>
2399 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2401 ios_base::iostate& __err, tm* __tm,
2402 char __fmt, char) const
2404 __err = ios_base::goodbit;
2405 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2410 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2415 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2419 const string_type& __fm = this->__c();
2420 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2425 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2429 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2430 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2435 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2436 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2440 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2443 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2446 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2449 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2452 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2456 __get_white_space(__b, __e, __err, __ct);
2459 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2463 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2464 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2469 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2470 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2474 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2478 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2479 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2483 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2486 return do_get_date(__b, __e, __iob, __err, __tm);
2489 const string_type& __fm = this->__X();
2490 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2494 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2497 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2500 __get_percent(__b, __e, __err, __ct);
2503 __err |= ios_base::failbit;
2508 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
2509 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
2511 class _LIBCPP_TYPE_VIS __time_get
2516 __time_get(const char* __nm);
2517 __time_get(const string& __nm);
2521 template <class _CharT>
2522 class _LIBCPP_TYPE_VIS_ONLY __time_get_storage
2526 typedef basic_string<_CharT> string_type;
2528 string_type __weeks_[14];
2529 string_type __months_[24];
2530 string_type __am_pm_[2];
2536 explicit __time_get_storage(const char* __nm);
2537 explicit __time_get_storage(const string& __nm);
2539 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2541 time_base::dateorder __do_date_order() const;
2544 void init(const ctype<_CharT>&);
2545 string_type __analyze(char __fmt, const ctype<_CharT>&);
2548 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2549 class _LIBCPP_TYPE_VIS_ONLY time_get_byname
2550 : public time_get<_CharT, _InputIterator>,
2551 private __time_get_storage<_CharT>
2554 typedef time_base::dateorder dateorder;
2555 typedef _InputIterator iter_type;
2556 typedef _CharT char_type;
2557 typedef basic_string<char_type> string_type;
2559 _LIBCPP_INLINE_VISIBILITY
2560 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2561 : time_get<_CharT, _InputIterator>(__refs),
2562 __time_get_storage<_CharT>(__nm) {}
2563 _LIBCPP_INLINE_VISIBILITY
2564 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2565 : time_get<_CharT, _InputIterator>(__refs),
2566 __time_get_storage<_CharT>(__nm) {}
2569 _LIBCPP_INLINE_VISIBILITY
2570 ~time_get_byname() {}
2572 _LIBCPP_INLINE_VISIBILITY
2573 virtual dateorder do_date_order() const {return this->__do_date_order();}
2575 _LIBCPP_INLINE_VISIBILITY
2576 virtual const string_type* __weeks() const {return this->__weeks_;}
2577 _LIBCPP_INLINE_VISIBILITY
2578 virtual const string_type* __months() const {return this->__months_;}
2579 _LIBCPP_INLINE_VISIBILITY
2580 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2581 _LIBCPP_INLINE_VISIBILITY
2582 virtual const string_type& __c() const {return this->__c_;}
2583 _LIBCPP_INLINE_VISIBILITY
2584 virtual const string_type& __r() const {return this->__r_;}
2585 _LIBCPP_INLINE_VISIBILITY
2586 virtual const string_type& __x() const {return this->__x_;}
2587 _LIBCPP_INLINE_VISIBILITY
2588 virtual const string_type& __X() const {return this->__X_;}
2591 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
2592 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
2594 class _LIBCPP_TYPE_VIS __time_put
2598 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2599 __time_put(const char* __nm);
2600 __time_put(const string& __nm);
2602 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2603 char __fmt, char __mod) const;
2604 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2605 char __fmt, char __mod) const;
2608 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2609 class _LIBCPP_TYPE_VIS_ONLY time_put
2610 : public locale::facet,
2614 typedef _CharT char_type;
2615 typedef _OutputIterator iter_type;
2617 _LIBCPP_ALWAYS_INLINE
2618 explicit time_put(size_t __refs = 0)
2619 : locale::facet(__refs) {}
2621 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2622 const char_type* __pb, const char_type* __pe) const;
2624 _LIBCPP_ALWAYS_INLINE
2625 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2626 const tm* __tm, char __fmt, char __mod = 0) const
2628 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2631 static locale::id id;
2634 _LIBCPP_ALWAYS_INLINE
2636 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2637 char __fmt, char __mod) const;
2639 _LIBCPP_ALWAYS_INLINE
2640 explicit time_put(const char* __nm, size_t __refs)
2641 : locale::facet(__refs),
2643 _LIBCPP_ALWAYS_INLINE
2644 explicit time_put(const string& __nm, size_t __refs)
2645 : locale::facet(__refs),
2649 template <class _CharT, class _OutputIterator>
2651 time_put<_CharT, _OutputIterator>::id;
2653 template <class _CharT, class _OutputIterator>
2655 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2656 char_type __fl, const tm* __tm,
2657 const char_type* __pb,
2658 const char_type* __pe) const
2660 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2661 for (; __pb != __pe; ++__pb)
2663 if (__ct.narrow(*__pb, 0) == '%')
2671 char __fmt = __ct.narrow(*__pb, 0);
2672 if (__fmt == 'E' || __fmt == 'O')
2681 __fmt = __ct.narrow(*__pb, 0);
2683 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2691 template <class _CharT, class _OutputIterator>
2693 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2694 char_type, const tm* __tm,
2695 char __fmt, char __mod) const
2697 char_type __nar[100];
2698 char_type* __nb = __nar;
2699 char_type* __ne = __nb + 100;
2700 __do_put(__nb, __ne, __tm, __fmt, __mod);
2701 return _VSTD::copy(__nb, __ne, __s);
2704 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
2705 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
2707 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2708 class _LIBCPP_TYPE_VIS_ONLY time_put_byname
2709 : public time_put<_CharT, _OutputIterator>
2712 _LIBCPP_ALWAYS_INLINE
2713 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2714 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2716 _LIBCPP_ALWAYS_INLINE
2717 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2718 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2721 _LIBCPP_ALWAYS_INLINE
2722 ~time_put_byname() {}
2725 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
2726 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
2730 class _LIBCPP_TYPE_VIS money_base
2733 enum part {none, space, symbol, sign, value};
2734 struct pattern {char field[4];};
2736 _LIBCPP_ALWAYS_INLINE money_base() {}
2741 template <class _CharT, bool _International = false>
2742 class _LIBCPP_TYPE_VIS_ONLY moneypunct
2743 : public locale::facet,
2747 typedef _CharT char_type;
2748 typedef basic_string<char_type> string_type;
2750 _LIBCPP_ALWAYS_INLINE
2751 explicit moneypunct(size_t __refs = 0)
2752 : locale::facet(__refs) {}
2754 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2755 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2756 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2757 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2758 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2759 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2760 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2761 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2762 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2764 static locale::id id;
2765 static const bool intl = _International;
2768 _LIBCPP_ALWAYS_INLINE
2771 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2772 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2773 virtual string do_grouping() const {return string();}
2774 virtual string_type do_curr_symbol() const {return string_type();}
2775 virtual string_type do_positive_sign() const {return string_type();}
2776 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2777 virtual int do_frac_digits() const {return 0;}
2778 virtual pattern do_pos_format() const
2779 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2780 virtual pattern do_neg_format() const
2781 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2784 template <class _CharT, bool _International>
2786 moneypunct<_CharT, _International>::id;
2788 template <class _CharT, bool _International>
2790 moneypunct<_CharT, _International>::intl;
2792 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
2793 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
2794 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
2795 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
2797 // moneypunct_byname
2799 template <class _CharT, bool _International = false>
2800 class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname
2801 : public moneypunct<_CharT, _International>
2804 typedef money_base::pattern pattern;
2805 typedef _CharT char_type;
2806 typedef basic_string<char_type> string_type;
2808 _LIBCPP_ALWAYS_INLINE
2809 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2810 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2812 _LIBCPP_ALWAYS_INLINE
2813 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2814 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2817 _LIBCPP_ALWAYS_INLINE
2818 ~moneypunct_byname() {}
2820 virtual char_type do_decimal_point() const {return __decimal_point_;}
2821 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2822 virtual string do_grouping() const {return __grouping_;}
2823 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2824 virtual string_type do_positive_sign() const {return __positive_sign_;}
2825 virtual string_type do_negative_sign() const {return __negative_sign_;}
2826 virtual int do_frac_digits() const {return __frac_digits_;}
2827 virtual pattern do_pos_format() const {return __pos_format_;}
2828 virtual pattern do_neg_format() const {return __neg_format_;}
2831 char_type __decimal_point_;
2832 char_type __thousands_sep_;
2834 string_type __curr_symbol_;
2835 string_type __positive_sign_;
2836 string_type __negative_sign_;
2838 pattern __pos_format_;
2839 pattern __neg_format_;
2841 void init(const char*);
2844 template<> void moneypunct_byname<char, false>::init(const char*);
2845 template<> void moneypunct_byname<char, true>::init(const char*);
2846 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2847 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2849 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
2850 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
2851 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
2852 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
2856 template <class _CharT>
2860 typedef _CharT char_type;
2861 typedef basic_string<char_type> string_type;
2863 _LIBCPP_ALWAYS_INLINE __money_get() {}
2865 static void __gather_info(bool __intl, const locale& __loc,
2866 money_base::pattern& __pat, char_type& __dp,
2867 char_type& __ts, string& __grp,
2868 string_type& __sym, string_type& __psn,
2869 string_type& __nsn, int& __fd);
2872 template <class _CharT>
2874 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2875 money_base::pattern& __pat, char_type& __dp,
2876 char_type& __ts, string& __grp,
2877 string_type& __sym, string_type& __psn,
2878 string_type& __nsn, int& __fd)
2882 const moneypunct<char_type, true>& __mp =
2883 use_facet<moneypunct<char_type, true> >(__loc);
2884 __pat = __mp.neg_format();
2885 __nsn = __mp.negative_sign();
2886 __psn = __mp.positive_sign();
2887 __dp = __mp.decimal_point();
2888 __ts = __mp.thousands_sep();
2889 __grp = __mp.grouping();
2890 __sym = __mp.curr_symbol();
2891 __fd = __mp.frac_digits();
2895 const moneypunct<char_type, false>& __mp =
2896 use_facet<moneypunct<char_type, false> >(__loc);
2897 __pat = __mp.neg_format();
2898 __nsn = __mp.negative_sign();
2899 __psn = __mp.positive_sign();
2900 __dp = __mp.decimal_point();
2901 __ts = __mp.thousands_sep();
2902 __grp = __mp.grouping();
2903 __sym = __mp.curr_symbol();
2904 __fd = __mp.frac_digits();
2908 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
2909 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
2911 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2912 class _LIBCPP_TYPE_VIS_ONLY money_get
2913 : public locale::facet,
2914 private __money_get<_CharT>
2917 typedef _CharT char_type;
2918 typedef _InputIterator iter_type;
2919 typedef basic_string<char_type> string_type;
2921 _LIBCPP_ALWAYS_INLINE
2922 explicit money_get(size_t __refs = 0)
2923 : locale::facet(__refs) {}
2925 _LIBCPP_ALWAYS_INLINE
2926 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2927 ios_base::iostate& __err, long double& __v) const
2929 return do_get(__b, __e, __intl, __iob, __err, __v);
2932 _LIBCPP_ALWAYS_INLINE
2933 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2934 ios_base::iostate& __err, string_type& __v) const
2936 return do_get(__b, __e, __intl, __iob, __err, __v);
2939 static locale::id id;
2943 _LIBCPP_ALWAYS_INLINE
2946 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2947 ios_base& __iob, ios_base::iostate& __err,
2948 long double& __v) const;
2949 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2950 ios_base& __iob, ios_base::iostate& __err,
2951 string_type& __v) const;
2954 static bool __do_get(iter_type& __b, iter_type __e,
2955 bool __intl, const locale& __loc,
2956 ios_base::fmtflags __flags, ios_base::iostate& __err,
2957 bool& __neg, const ctype<char_type>& __ct,
2958 unique_ptr<char_type, void(*)(void*)>& __wb,
2959 char_type*& __wn, char_type* __we);
2962 template <class _CharT, class _InputIterator>
2964 money_get<_CharT, _InputIterator>::id;
2966 _LIBCPP_FUNC_VIS void __do_nothing(void*);
2968 template <class _Tp>
2971 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2973 bool __owns = __b.get_deleter() != __do_nothing;
2974 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
2975 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2976 2 * __cur_cap : numeric_limits<size_t>::max();
2978 __new_cap = sizeof(_Tp);
2979 size_t __n_off = static_cast<size_t>(__n - __b.get());
2980 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2982 __throw_bad_alloc();
2985 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2986 __new_cap /= sizeof(_Tp);
2987 __n = __b.get() + __n_off;
2988 __e = __b.get() + __new_cap;
2992 template <class _CharT, class _InputIterator>
2994 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2995 bool __intl, const locale& __loc,
2996 ios_base::fmtflags __flags,
2997 ios_base::iostate& __err,
2999 const ctype<char_type>& __ct,
3000 unique_ptr<char_type, void(*)(void*)>& __wb,
3001 char_type*& __wn, char_type* __we)
3003 const unsigned __bz = 100;
3004 unsigned __gbuf[__bz];
3005 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3006 unsigned* __gn = __gb.get();
3007 unsigned* __ge = __gn + __bz;
3008 money_base::pattern __pat;
3015 // Capture the spaces read into money_base::{space,none} so they
3016 // can be compared to initial spaces in __sym.
3017 string_type __spaces;
3019 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3020 __sym, __psn, __nsn, __fd);
3021 const string_type* __trailing_sign = 0;
3023 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3025 switch (__pat.field[__p])
3027 case money_base::space:
3030 if (__ct.is(ctype_base::space, *__b))
3031 __spaces.push_back(*__b++);
3034 __err |= ios_base::failbit;
3039 case money_base::none:
3042 while (__b != __e && __ct.is(ctype_base::space, *__b))
3043 __spaces.push_back(*__b++);
3046 case money_base::sign:
3047 if (__psn.size() + __nsn.size() > 0)
3049 if (__psn.size() == 0 || __nsn.size() == 0)
3050 { // sign is optional
3051 if (__psn.size() > 0)
3052 { // __nsn.size() == 0
3053 if (*__b == __psn[0])
3056 if (__psn.size() > 1)
3057 __trailing_sign = &__psn;
3062 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
3066 if (__nsn.size() > 1)
3067 __trailing_sign = &__nsn;
3070 else // sign is required
3072 if (*__b == __psn[0])
3075 if (__psn.size() > 1)
3076 __trailing_sign = &__psn;
3078 else if (*__b == __nsn[0])
3082 if (__nsn.size() > 1)
3083 __trailing_sign = &__nsn;
3087 __err |= ios_base::failbit;
3093 case money_base::symbol:
3095 bool __more_needed = __trailing_sign ||
3097 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
3098 bool __sb = (__flags & ios_base::showbase) != 0;
3099 if (__sb || __more_needed)
3101 typename string_type::const_iterator __sym_space_end = __sym.begin();
3102 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3103 __pat.field[__p - 1] == money_base::space)) {
3104 // Match spaces we've already read against spaces at
3105 // the beginning of __sym.
3106 while (__sym_space_end != __sym.end() &&
3107 __ct.is(ctype_base::space, *__sym_space_end))
3109 const size_t __num_spaces = __sym_space_end - __sym.begin();
3110 if (__num_spaces > __spaces.size() ||
3111 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3113 // No match. Put __sym_space_end back at the
3114 // beginning of __sym, which will prevent a
3115 // match in the next loop.
3116 __sym_space_end = __sym.begin();
3119 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3120 while (__sym_curr_char != __sym.end() && __b != __e &&
3121 *__b == *__sym_curr_char) {
3125 if (__sb && __sym_curr_char != __sym.end())
3127 __err |= ios_base::failbit;
3133 case money_base::value:
3136 for (; __b != __e; ++__b)
3138 char_type __c = *__b;
3139 if (__ct.is(ctype_base::digit, __c))
3142 __double_or_nothing(__wb, __wn, __we);
3146 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3149 __double_or_nothing(__gb, __gn, __ge);
3156 if (__gb.get() != __gn && __ng > 0)
3159 __double_or_nothing(__gb, __gn, __ge);
3164 if (__b == __e || *__b != __dp)
3166 __err |= ios_base::failbit;
3169 for (++__b; __fd > 0; --__fd, ++__b)
3171 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3173 __err |= ios_base::failbit;
3177 __double_or_nothing(__wb, __wn, __we);
3181 if (__wn == __wb.get())
3183 __err |= ios_base::failbit;
3190 if (__trailing_sign)
3192 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3194 if (__b == __e || *__b != (*__trailing_sign)[__i])
3196 __err |= ios_base::failbit;
3201 if (__gb.get() != __gn)
3203 ios_base::iostate __et = ios_base::goodbit;
3204 __check_grouping(__grp, __gb.get(), __gn, __et);
3207 __err |= ios_base::failbit;
3214 template <class _CharT, class _InputIterator>
3216 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3217 bool __intl, ios_base& __iob,
3218 ios_base::iostate& __err,
3219 long double& __v) const
3221 const int __bz = 100;
3222 char_type __wbuf[__bz];
3223 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3225 char_type* __we = __wbuf + __bz;
3226 locale __loc = __iob.getloc();
3227 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3229 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3232 const char __src[] = "0123456789";
3233 char_type __atoms[sizeof(__src)-1];
3234 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3236 char* __nc = __nbuf;
3237 unique_ptr<char, void(*)(void*)> __h(0, free);
3238 if (__wn - __wb.get() > __bz-2)
3240 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3242 __throw_bad_alloc();
3247 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3248 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3250 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3251 __throw_runtime_error("money_get error");
3254 __err |= ios_base::eofbit;
3258 template <class _CharT, class _InputIterator>
3260 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3261 bool __intl, ios_base& __iob,
3262 ios_base::iostate& __err,
3263 string_type& __v) const
3265 const int __bz = 100;
3266 char_type __wbuf[__bz];
3267 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3269 char_type* __we = __wbuf + __bz;
3270 locale __loc = __iob.getloc();
3271 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3273 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3278 __v.push_back(__ct.widen('-'));
3279 char_type __z = __ct.widen('0');
3281 for (__w = __wb.get(); __w < __wn-1; ++__w)
3284 __v.append(__w, __wn);
3287 __err |= ios_base::eofbit;
3291 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
3292 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
3296 template <class _CharT>
3300 typedef _CharT char_type;
3301 typedef basic_string<char_type> string_type;
3303 _LIBCPP_ALWAYS_INLINE __money_put() {}
3305 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3306 money_base::pattern& __pat, char_type& __dp,
3307 char_type& __ts, string& __grp,
3308 string_type& __sym, string_type& __sn,
3310 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3311 ios_base::fmtflags __flags,
3312 const char_type* __db, const char_type* __de,
3313 const ctype<char_type>& __ct, bool __neg,
3314 const money_base::pattern& __pat, char_type __dp,
3315 char_type __ts, const string& __grp,
3316 const string_type& __sym, const string_type& __sn,
3320 template <class _CharT>
3322 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3323 money_base::pattern& __pat, char_type& __dp,
3324 char_type& __ts, string& __grp,
3325 string_type& __sym, string_type& __sn,
3330 const moneypunct<char_type, true>& __mp =
3331 use_facet<moneypunct<char_type, true> >(__loc);
3334 __pat = __mp.neg_format();
3335 __sn = __mp.negative_sign();
3339 __pat = __mp.pos_format();
3340 __sn = __mp.positive_sign();
3342 __dp = __mp.decimal_point();
3343 __ts = __mp.thousands_sep();
3344 __grp = __mp.grouping();
3345 __sym = __mp.curr_symbol();
3346 __fd = __mp.frac_digits();
3350 const moneypunct<char_type, false>& __mp =
3351 use_facet<moneypunct<char_type, false> >(__loc);
3354 __pat = __mp.neg_format();
3355 __sn = __mp.negative_sign();
3359 __pat = __mp.pos_format();
3360 __sn = __mp.positive_sign();
3362 __dp = __mp.decimal_point();
3363 __ts = __mp.thousands_sep();
3364 __grp = __mp.grouping();
3365 __sym = __mp.curr_symbol();
3366 __fd = __mp.frac_digits();
3370 template <class _CharT>
3372 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3373 ios_base::fmtflags __flags,
3374 const char_type* __db, const char_type* __de,
3375 const ctype<char_type>& __ct, bool __neg,
3376 const money_base::pattern& __pat, char_type __dp,
3377 char_type __ts, const string& __grp,
3378 const string_type& __sym, const string_type& __sn,
3382 for (unsigned __p = 0; __p < 4; ++__p)
3384 switch (__pat.field[__p])
3386 case money_base::none:
3389 case money_base::space:
3391 *__me++ = __ct.widen(' ');
3393 case money_base::sign:
3397 case money_base::symbol:
3398 if (!__sym.empty() && (__flags & ios_base::showbase))
3399 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3401 case money_base::value:
3403 // remember start of value so we can reverse it
3404 char_type* __t = __me;
3405 // find beginning of digits
3408 // find end of digits
3409 const char_type* __d;
3410 for (__d = __db; __d < __de; ++__d)
3411 if (!__ct.is(ctype_base::digit, *__d))
3413 // print fractional part
3417 for (__f = __fd; __d > __db && __f > 0; --__f)
3419 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3420 for (; __f > 0; --__f)
3427 *__me++ = __ct.widen('0');
3433 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3434 : static_cast<unsigned>(__grp[__ig]);
3441 if (++__ig < __grp.size())
3442 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3443 numeric_limits<unsigned>::max() :
3444 static_cast<unsigned>(__grp[__ig]);
3456 // print rest of sign, if any
3457 if (__sn.size() > 1)
3458 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3460 if ((__flags & ios_base::adjustfield) == ios_base::left)
3462 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3466 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
3467 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
3469 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3470 class _LIBCPP_TYPE_VIS_ONLY money_put
3471 : public locale::facet,
3472 private __money_put<_CharT>
3475 typedef _CharT char_type;
3476 typedef _OutputIterator iter_type;
3477 typedef basic_string<char_type> string_type;
3479 _LIBCPP_ALWAYS_INLINE
3480 explicit money_put(size_t __refs = 0)
3481 : locale::facet(__refs) {}
3483 _LIBCPP_ALWAYS_INLINE
3484 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3485 long double __units) const
3487 return do_put(__s, __intl, __iob, __fl, __units);
3490 _LIBCPP_ALWAYS_INLINE
3491 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3492 const string_type& __digits) const
3494 return do_put(__s, __intl, __iob, __fl, __digits);
3497 static locale::id id;
3500 _LIBCPP_ALWAYS_INLINE
3503 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3504 char_type __fl, long double __units) const;
3505 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3506 char_type __fl, const string_type& __digits) const;
3509 template <class _CharT, class _OutputIterator>
3511 money_put<_CharT, _OutputIterator>::id;
3513 template <class _CharT, class _OutputIterator>
3515 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3516 ios_base& __iob, char_type __fl,
3517 long double __units) const
3520 const size_t __bs = 100;
3523 char_type __digits[__bs];
3524 char_type* __db = __digits;
3525 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3526 unique_ptr<char, void(*)(void*)> __hn(0, free);
3527 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3528 // secure memory for digit storage
3531 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
3532 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3534 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
3537 __throw_bad_alloc();
3539 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3540 if (__hd == nullptr)
3541 __throw_bad_alloc();
3545 locale __loc = __iob.getloc();
3546 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3547 __ct.widen(__bb, __bb + __n, __db);
3548 bool __neg = __n > 0 && __bb[0] == '-';
3549 money_base::pattern __pat;
3556 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3557 // secure memory for formatting
3558 char_type __mbuf[__bs];
3559 char_type* __mb = __mbuf;
3560 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3561 size_t __exn = static_cast<int>(__n) > __fd ?
3562 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3563 __sym.size() + static_cast<size_t>(__fd) + 1
3564 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3567 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3570 __throw_bad_alloc();
3575 this->__format(__mb, __mi, __me, __iob.flags(),
3576 __db, __db + __n, __ct,
3577 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3578 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3581 template <class _CharT, class _OutputIterator>
3583 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3584 ios_base& __iob, char_type __fl,
3585 const string_type& __digits) const
3588 locale __loc = __iob.getloc();
3589 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3590 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3591 money_base::pattern __pat;
3598 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3599 // secure memory for formatting
3600 char_type __mbuf[100];
3601 char_type* __mb = __mbuf;
3602 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3603 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3604 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3605 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3606 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3609 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3612 __throw_bad_alloc();
3617 this->__format(__mb, __mi, __me, __iob.flags(),
3618 __digits.data(), __digits.data() + __digits.size(), __ct,
3619 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3620 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3623 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
3624 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
3628 class _LIBCPP_TYPE_VIS messages_base
3631 typedef ptrdiff_t catalog;
3633 _LIBCPP_ALWAYS_INLINE messages_base() {}
3636 template <class _CharT>
3637 class _LIBCPP_TYPE_VIS_ONLY messages
3638 : public locale::facet,
3639 public messages_base
3642 typedef _CharT char_type;
3643 typedef basic_string<_CharT> string_type;
3645 _LIBCPP_ALWAYS_INLINE
3646 explicit messages(size_t __refs = 0)
3647 : locale::facet(__refs) {}
3649 _LIBCPP_ALWAYS_INLINE
3650 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3652 return do_open(__nm, __loc);
3655 _LIBCPP_ALWAYS_INLINE
3656 string_type get(catalog __c, int __set, int __msgid,
3657 const string_type& __dflt) const
3659 return do_get(__c, __set, __msgid, __dflt);
3662 _LIBCPP_ALWAYS_INLINE
3663 void close(catalog __c) const
3668 static locale::id id;
3671 _LIBCPP_ALWAYS_INLINE
3674 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3675 virtual string_type do_get(catalog, int __set, int __msgid,
3676 const string_type& __dflt) const;
3677 virtual void do_close(catalog) const;
3680 template <class _CharT>
3682 messages<_CharT>::id;
3684 template <class _CharT>
3685 typename messages<_CharT>::catalog
3686 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3688 #if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION)
3690 #else // _WIN32 || __ANDROID__
3691 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3693 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3695 #endif // _WIN32 || __ANDROID__
3698 template <class _CharT>
3699 typename messages<_CharT>::string_type
3700 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3701 const string_type& __dflt) const
3703 #if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION)
3707 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3709 __dflt.c_str() + __dflt.size());
3712 nl_catd __cat = (nl_catd)__c;
3713 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3715 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3716 __n, __n + strlen(__n));
3721 template <class _CharT>
3723 messages<_CharT>::do_close(catalog __c) const
3725 #if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION)
3728 nl_catd __cat = (nl_catd)__c;
3733 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
3734 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
3736 template <class _CharT>
3737 class _LIBCPP_TYPE_VIS_ONLY messages_byname
3738 : public messages<_CharT>
3741 typedef messages_base::catalog catalog;
3742 typedef basic_string<_CharT> string_type;
3744 _LIBCPP_ALWAYS_INLINE
3745 explicit messages_byname(const char*, size_t __refs = 0)
3746 : messages<_CharT>(__refs) {}
3748 _LIBCPP_ALWAYS_INLINE
3749 explicit messages_byname(const string&, size_t __refs = 0)
3750 : messages<_CharT>(__refs) {}
3753 _LIBCPP_ALWAYS_INLINE
3754 ~messages_byname() {}
3757 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
3758 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
3760 template<class _Codecvt, class _Elem = wchar_t,
3761 class _Wide_alloc = allocator<_Elem>,
3762 class _Byte_alloc = allocator<char> >
3763 class _LIBCPP_TYPE_VIS_ONLY wstring_convert
3766 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3767 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3768 typedef typename _Codecvt::state_type state_type;
3769 typedef typename wide_string::traits_type::int_type int_type;
3772 byte_string __byte_err_string_;
3773 wide_string __wide_err_string_;
3774 _Codecvt* __cvtptr_;
3775 state_type __cvtstate_;
3778 wstring_convert(const wstring_convert& __wc);
3779 wstring_convert& operator=(const wstring_convert& __wc);
3781 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3782 wstring_convert(_Codecvt* __pcvt, state_type __state);
3783 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
3784 const wide_string& __wide_err = wide_string());
3785 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3786 wstring_convert(wstring_convert&& __wc);
3790 _LIBCPP_ALWAYS_INLINE
3791 wide_string from_bytes(char __byte)
3792 {return from_bytes(&__byte, &__byte+1);}
3793 _LIBCPP_ALWAYS_INLINE
3794 wide_string from_bytes(const char* __ptr)
3795 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3796 _LIBCPP_ALWAYS_INLINE
3797 wide_string from_bytes(const byte_string& __str)
3798 {return from_bytes(__str.data(), __str.data() + __str.size());}
3799 wide_string from_bytes(const char* __first, const char* __last);
3801 _LIBCPP_ALWAYS_INLINE
3802 byte_string to_bytes(_Elem __wchar)
3803 {return to_bytes(&__wchar, &__wchar+1);}
3804 _LIBCPP_ALWAYS_INLINE
3805 byte_string to_bytes(const _Elem* __wptr)
3806 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3807 _LIBCPP_ALWAYS_INLINE
3808 byte_string to_bytes(const wide_string& __wstr)
3809 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3810 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3812 _LIBCPP_ALWAYS_INLINE
3813 size_t converted() const _NOEXCEPT {return __cvtcount_;}
3814 _LIBCPP_ALWAYS_INLINE
3815 state_type state() const {return __cvtstate_;}
3818 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3819 inline _LIBCPP_ALWAYS_INLINE
3820 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3821 wstring_convert(_Codecvt* __pcvt)
3822 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3826 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3827 inline _LIBCPP_ALWAYS_INLINE
3828 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3829 wstring_convert(_Codecvt* __pcvt, state_type __state)
3830 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3834 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3835 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3836 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3837 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3838 __cvtstate_(), __cvtcount_(0)
3840 __cvtptr_ = new _Codecvt;
3843 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3845 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3846 inline _LIBCPP_ALWAYS_INLINE
3847 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3848 wstring_convert(wstring_convert&& __wc)
3849 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3850 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3851 __cvtptr_(__wc.__cvtptr_),
3852 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
3854 __wc.__cvtptr_ = nullptr;
3857 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3859 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3860 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3865 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3866 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3867 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3868 from_bytes(const char* __frm, const char* __frm_end)
3871 if (__cvtptr_ != nullptr)
3873 wide_string __ws(2*(__frm_end - __frm), _Elem());
3874 if (__frm != __frm_end)
3875 __ws.resize(__ws.capacity());
3876 codecvt_base::result __r = codecvt_base::ok;
3877 state_type __st = __cvtstate_;
3878 if (__frm != __frm_end)
3880 _Elem* __to = &__ws[0];
3881 _Elem* __to_end = __to + __ws.size();
3882 const char* __frm_nxt;
3886 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3887 __to, __to_end, __to_nxt);
3888 __cvtcount_ += __frm_nxt - __frm;
3889 if (__frm_nxt == __frm)
3891 __r = codecvt_base::error;
3893 else if (__r == codecvt_base::noconv)
3895 __ws.resize(__to - &__ws[0]);
3896 // This only gets executed if _Elem is char
3897 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3899 __r = codecvt_base::ok;
3901 else if (__r == codecvt_base::ok)
3903 __ws.resize(__to_nxt - &__ws[0]);
3906 else if (__r == codecvt_base::partial)
3908 ptrdiff_t __s = __to_nxt - &__ws[0];
3909 __ws.resize(2 * __s);
3910 __to = &__ws[0] + __s;
3911 __to_end = &__ws[0] + __ws.size();
3914 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3916 if (__r == codecvt_base::ok)
3919 #ifndef _LIBCPP_NO_EXCEPTIONS
3920 if (__wide_err_string_.empty())
3921 throw range_error("wstring_convert: from_bytes error");
3922 #endif // _LIBCPP_NO_EXCEPTIONS
3923 return __wide_err_string_;
3926 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3927 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3928 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3929 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3932 if (__cvtptr_ != nullptr)
3934 byte_string __bs(2*(__frm_end - __frm), char());
3935 if (__frm != __frm_end)
3936 __bs.resize(__bs.capacity());
3937 codecvt_base::result __r = codecvt_base::ok;
3938 state_type __st = __cvtstate_;
3939 if (__frm != __frm_end)
3941 char* __to = &__bs[0];
3942 char* __to_end = __to + __bs.size();
3943 const _Elem* __frm_nxt;
3947 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3948 __to, __to_end, __to_nxt);
3949 __cvtcount_ += __frm_nxt - __frm;
3950 if (__frm_nxt == __frm)
3952 __r = codecvt_base::error;
3954 else if (__r == codecvt_base::noconv)
3956 __bs.resize(__to - &__bs[0]);
3957 // This only gets executed if _Elem is char
3958 __bs.append((const char*)__frm, (const char*)__frm_end);
3960 __r = codecvt_base::ok;
3962 else if (__r == codecvt_base::ok)
3964 __bs.resize(__to_nxt - &__bs[0]);
3967 else if (__r == codecvt_base::partial)
3969 ptrdiff_t __s = __to_nxt - &__bs[0];
3970 __bs.resize(2 * __s);
3971 __to = &__bs[0] + __s;
3972 __to_end = &__bs[0] + __bs.size();
3975 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3977 if (__r == codecvt_base::ok)
3979 size_t __s = __bs.size();
3980 __bs.resize(__bs.capacity());
3981 char* __to = &__bs[0] + __s;
3982 char* __to_end = __to + __bs.size();
3986 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3987 if (__r == codecvt_base::noconv)
3989 __bs.resize(__to - &__bs[0]);
3990 __r = codecvt_base::ok;
3992 else if (__r == codecvt_base::ok)
3994 __bs.resize(__to_nxt - &__bs[0]);
3996 else if (__r == codecvt_base::partial)
3998 ptrdiff_t __sp = __to_nxt - &__bs[0];
3999 __bs.resize(2 * __sp);
4000 __to = &__bs[0] + __sp;
4001 __to_end = &__bs[0] + __bs.size();
4003 } while (__r == codecvt_base::partial);
4004 if (__r == codecvt_base::ok)
4008 #ifndef _LIBCPP_NO_EXCEPTIONS
4009 if (__byte_err_string_.empty())
4010 throw range_error("wstring_convert: to_bytes error");
4011 #endif // _LIBCPP_NO_EXCEPTIONS
4012 return __byte_err_string_;
4015 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
4016 class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert
4017 : public basic_streambuf<_Elem, _Tr>
4021 typedef _Elem char_type;
4022 typedef _Tr traits_type;
4023 typedef typename traits_type::int_type int_type;
4024 typedef typename traits_type::pos_type pos_type;
4025 typedef typename traits_type::off_type off_type;
4026 typedef typename _Codecvt::state_type state_type;
4030 const char* __extbufnext_;
4031 const char* __extbufend_;
4032 char __extbuf_min_[8];
4034 char_type* __intbuf_;
4036 streambuf* __bufptr_;
4039 ios_base::openmode __cm_;
4042 bool __always_noconv_;
4044 wbuffer_convert(const wbuffer_convert&);
4045 wbuffer_convert& operator=(const wbuffer_convert&);
4047 _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0,
4048 _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
4051 _LIBCPP_INLINE_VISIBILITY
4052 streambuf* rdbuf() const {return __bufptr_;}
4053 _LIBCPP_INLINE_VISIBILITY
4054 streambuf* rdbuf(streambuf* __bytebuf)
4056 streambuf* __r = __bufptr_;
4057 __bufptr_ = __bytebuf;
4061 _LIBCPP_INLINE_VISIBILITY
4062 state_type state() const {return __st_;}
4065 virtual int_type underflow();
4066 virtual int_type pbackfail(int_type __c = traits_type::eof());
4067 virtual int_type overflow (int_type __c = traits_type::eof());
4068 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4070 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4071 ios_base::openmode __wch = ios_base::in | ios_base::out);
4072 virtual pos_type seekpos(pos_type __sp,
4073 ios_base::openmode __wch = ios_base::in | ios_base::out);
4078 void __write_mode();
4079 wbuffer_convert* __close();
4082 template <class _Codecvt, class _Elem, class _Tr>
4083 wbuffer_convert<_Codecvt, _Elem, _Tr>::
4084 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4091 __bufptr_(__bytebuf),
4097 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4102 template <class _Codecvt, class _Elem, class _Tr>
4103 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4108 delete [] __extbuf_;
4110 delete [] __intbuf_;
4113 template <class _Codecvt, class _Elem, class _Tr>
4114 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4115 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4117 if (__cv_ == 0 || __bufptr_ == 0)
4118 return traits_type::eof();
4119 bool __initial = __read_mode();
4121 if (this->gptr() == 0)
4122 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4123 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4124 int_type __c = traits_type::eof();
4125 if (this->gptr() == this->egptr())
4127 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4128 if (__always_noconv_)
4130 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4131 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4134 this->setg(this->eback(),
4135 this->eback() + __unget_sz,
4136 this->eback() + __unget_sz + __nmemb);
4137 __c = *this->gptr();
4142 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4143 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4144 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
4145 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
4146 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4147 codecvt_base::result __r;
4148 state_type __svs = __st_;
4149 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4152 __extbufend_ = __extbufnext_ + __nr;
4154 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4155 this->eback() + __unget_sz,
4156 this->egptr(), __inext);
4157 if (__r == codecvt_base::noconv)
4159 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4160 __c = *this->gptr();
4162 else if (__inext != this->eback() + __unget_sz)
4164 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4165 __c = *this->gptr();
4171 __c = *this->gptr();
4172 if (this->eback() == &__1buf)
4173 this->setg(0, 0, 0);
4177 template <class _Codecvt, class _Elem, class _Tr>
4178 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4179 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4181 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4183 if (traits_type::eq_int_type(__c, traits_type::eof()))
4186 return traits_type::not_eof(__c);
4188 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4191 *this->gptr() = traits_type::to_char_type(__c);
4195 return traits_type::eof();
4198 template <class _Codecvt, class _Elem, class _Tr>
4199 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4200 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4202 if (__cv_ == 0 || __bufptr_ == 0)
4203 return traits_type::eof();
4206 char_type* __pb_save = this->pbase();
4207 char_type* __epb_save = this->epptr();
4208 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4210 if (this->pptr() == 0)
4211 this->setp(&__1buf, &__1buf+1);
4212 *this->pptr() = traits_type::to_char_type(__c);
4215 if (this->pptr() != this->pbase())
4217 if (__always_noconv_)
4219 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4220 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4221 return traits_type::eof();
4225 char* __extbe = __extbuf_;
4226 codecvt_base::result __r;
4229 const char_type* __e;
4230 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4231 __extbuf_, __extbuf_ + __ebs_, __extbe);
4232 if (__e == this->pbase())
4233 return traits_type::eof();
4234 if (__r == codecvt_base::noconv)
4236 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4237 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4238 return traits_type::eof();
4240 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4242 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4243 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4244 return traits_type::eof();
4245 if (__r == codecvt_base::partial)
4247 this->setp((char_type*)__e, this->pptr());
4248 this->pbump(this->epptr() - this->pbase());
4252 return traits_type::eof();
4253 } while (__r == codecvt_base::partial);
4255 this->setp(__pb_save, __epb_save);
4257 return traits_type::not_eof(__c);
4260 template <class _Codecvt, class _Elem, class _Tr>
4261 basic_streambuf<_Elem, _Tr>*
4262 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4264 this->setg(0, 0, 0);
4267 delete [] __extbuf_;
4269 delete [] __intbuf_;
4271 if (__ebs_ > sizeof(__extbuf_min_))
4273 if (__always_noconv_ && __s)
4275 __extbuf_ = (char*)__s;
4280 __extbuf_ = new char[__ebs_];
4286 __extbuf_ = __extbuf_min_;
4287 __ebs_ = sizeof(__extbuf_min_);
4290 if (!__always_noconv_)
4292 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4293 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4300 __intbuf_ = new char_type[__ibs_];
4313 template <class _Codecvt, class _Elem, class _Tr>
4314 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4315 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4316 ios_base::openmode __om)
4318 int __width = __cv_->encoding();
4319 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4320 return pos_type(off_type(-1));
4321 // __width > 0 || __off == 0
4331 return pos_type(off_type(-1));
4333 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4338 template <class _Codecvt, class _Elem, class _Tr>
4339 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4340 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4342 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4343 return pos_type(off_type(-1));
4344 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4345 return pos_type(off_type(-1));
4349 template <class _Codecvt, class _Elem, class _Tr>
4351 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4353 if (__cv_ == 0 || __bufptr_ == 0)
4355 if (__cm_ & ios_base::out)
4357 if (this->pptr() != this->pbase())
4358 if (overflow() == traits_type::eof())
4360 codecvt_base::result __r;
4364 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4365 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4366 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4368 } while (__r == codecvt_base::partial);
4369 if (__r == codecvt_base::error)
4371 if (__bufptr_->pubsync())
4374 else if (__cm_ & ios_base::in)
4377 if (__always_noconv_)
4378 __c = this->egptr() - this->gptr();
4381 int __width = __cv_->encoding();
4382 __c = __extbufend_ - __extbufnext_;
4384 __c += __width * (this->egptr() - this->gptr());
4387 if (this->gptr() != this->egptr())
4389 reverse(this->gptr(), this->egptr());
4390 codecvt_base::result __r;
4391 const char_type* __e = this->gptr();
4395 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4396 __extbuf_, __extbuf_ + __ebs_, __extbe);
4399 case codecvt_base::noconv:
4400 __c += this->egptr() - this->gptr();
4402 case codecvt_base::ok:
4403 case codecvt_base::partial:
4404 __c += __extbe - __extbuf_;
4409 } while (__r == codecvt_base::partial);
4413 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4415 this->setg(0, 0, 0);
4421 template <class _Codecvt, class _Elem, class _Tr>
4423 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4425 if (!(__cm_ & ios_base::in))
4428 if (__always_noconv_)
4429 this->setg((char_type*)__extbuf_,
4430 (char_type*)__extbuf_ + __ebs_,
4431 (char_type*)__extbuf_ + __ebs_);
4433 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4434 __cm_ = ios_base::in;
4440 template <class _Codecvt, class _Elem, class _Tr>
4442 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4444 if (!(__cm_ & ios_base::out))
4446 this->setg(0, 0, 0);
4447 if (__ebs_ > sizeof(__extbuf_min_))
4449 if (__always_noconv_)
4450 this->setp((char_type*)__extbuf_,
4451 (char_type*)__extbuf_ + (__ebs_ - 1));
4453 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4457 __cm_ = ios_base::out;
4461 template <class _Codecvt, class _Elem, class _Tr>
4462 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4463 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4465 wbuffer_convert* __rt = 0;
4466 if (__cv_ != 0 && __bufptr_ != 0)
4469 if ((__cm_ & ios_base::out) && sync())
4475 _LIBCPP_END_NAMESPACE_STD
4477 #endif // _LIBCPP_LOCALE