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 wstring_convert(Codecvt* pcvt = new Codecvt);
97 wstring_convert(Codecvt* pcvt, state_type state);
98 wstring_convert(const byte_string& byte_err,
99 const wide_string& wide_err = wide_string());
102 wide_string from_bytes(char byte);
103 wide_string from_bytes(const char* ptr);
104 wide_string from_bytes(const byte_string& str);
105 wide_string from_bytes(const char* first, const char* last);
107 byte_string to_bytes(Elem wchar);
108 byte_string to_bytes(const Elem* wptr);
109 byte_string to_bytes(const wide_string& wstr);
110 byte_string to_bytes(const Elem* first, const Elem* last);
112 size_t converted() const;
113 state_type state() const;
116 template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
117 class wbuffer_convert
118 : public basic_streambuf<Elem, Tr>
121 typedef typename Tr::state_type state_type;
123 wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
124 state_type state = state_type());
126 streambuf* rdbuf() const;
127 streambuf* rdbuf(streambuf* bytebuf);
129 state_type state() const;
132 // 22.4.1 and 22.4.1.3, ctype:
134 template <class charT> class ctype;
135 template <> class ctype<char>; // specialization
136 template <class charT> class ctype_byname;
137 template <> class ctype_byname<char>; // specialization
140 template <class internT, class externT, class stateT> class codecvt;
141 template <class internT, class externT, class stateT> class codecvt_byname;
143 // 22.4.2 and 22.4.3, numeric:
144 template <class charT, class InputIterator> class num_get;
145 template <class charT, class OutputIterator> class num_put;
146 template <class charT> class numpunct;
147 template <class charT> class numpunct_byname;
149 // 22.4.4, col lation:
150 template <class charT> class collate;
151 template <class charT> class collate_byname;
153 // 22.4.5, date and time:
155 template <class charT, class InputIterator> class time_get;
156 template <class charT, class InputIterator> class time_get_byname;
157 template <class charT, class OutputIterator> class time_put;
158 template <class charT, class OutputIterator> class time_put_byname;
162 template <class charT, class InputIterator> class money_get;
163 template <class charT, class OutputIterator> class money_put;
164 template <class charT, bool Intl> class moneypunct;
165 template <class charT, bool Intl> class moneypunct_byname;
167 // 22.4.7, message retrieval:
169 template <class charT> class messages;
170 template <class charT> class messages_byname;
190 #include <support/win32/locale_win32.h>
192 #include <nl_types.h>
195 #include <__undef_min_max>
197 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
198 #pragma GCC system_header
201 _LIBCPP_BEGIN_NAMESPACE_STD
203 #if __APPLE__ || __FreeBSD__
204 # define _LIBCPP_GET_C_LOCALE 0
206 # define _LIBCPP_GET_C_LOCALE __cloc()
207 // Get the C locale object
209 #define __cloc_defined
212 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
213 typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
214 #ifndef _LIBCPP_LOCALE__L_EXTENSIONS
215 typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
218 // OSX has nice foo_l() functions that let you turn off use of the global
219 // locale. Linux, not so much. The following functions avoid the locale when
220 // that's possible and otherwise do the wrong thing. FIXME.
223 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
224 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
225 inline _LIBCPP_INLINE_VISIBILITY
226 __mb_cur_max_l(locale_t __l)
228 return MB_CUR_MAX_L(__l);
230 #else // _LIBCPP_LOCALE__L_EXTENSIONS
231 _LIBCPP_ALWAYS_INLINE inline
232 decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
234 __locale_raii __current(uselocale(__l), uselocale);
237 #endif // _LIBCPP_LOCALE__L_EXTENSIONS
239 _LIBCPP_ALWAYS_INLINE inline
240 wint_t __btowc_l(int __c, locale_t __l)
242 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
243 return btowc_l(__c, __l);
245 __locale_raii __current(uselocale(__l), uselocale);
250 _LIBCPP_ALWAYS_INLINE inline
251 int __wctob_l(wint_t __c, locale_t __l)
253 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
254 return wctob_l(__c, __l);
256 __locale_raii __current(uselocale(__l), uselocale);
261 _LIBCPP_ALWAYS_INLINE inline
262 size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
263 size_t __len, mbstate_t *__ps, locale_t __l)
265 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
266 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
268 __locale_raii __current(uselocale(__l), uselocale);
269 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
273 _LIBCPP_ALWAYS_INLINE inline
274 size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
276 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
277 return wcrtomb_l(__s, __wc, __ps, __l);
279 __locale_raii __current(uselocale(__l), uselocale);
280 return wcrtomb(__s, __wc, __ps);
284 _LIBCPP_ALWAYS_INLINE inline
285 size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
286 size_t __len, mbstate_t *__ps, locale_t __l)
288 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
289 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
291 __locale_raii __current(uselocale(__l), uselocale);
292 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
296 _LIBCPP_ALWAYS_INLINE inline
297 size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
298 mbstate_t *__ps, locale_t __l)
300 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
301 return mbrtowc_l(__pwc, __s, __n, __ps, __l);
303 __locale_raii __current(uselocale(__l), uselocale);
304 return mbrtowc(__pwc, __s, __n, __ps);
308 _LIBCPP_ALWAYS_INLINE inline
309 int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
311 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
312 return mbtowc_l(__pwc, __pmb, __max, __l);
314 __locale_raii __current(uselocale(__l), uselocale);
315 return mbtowc(__pwc, __pmb, __max);
319 _LIBCPP_ALWAYS_INLINE inline
320 size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
322 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
323 return mbrlen_l(__s, __n, __ps, __l);
325 __locale_raii __current(uselocale(__l), uselocale);
326 return mbrlen(__s, __n, __ps);
330 _LIBCPP_ALWAYS_INLINE inline
331 lconv *__localeconv_l(locale_t __l)
333 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
334 return localeconv_l(__l);
336 __locale_raii __current(uselocale(__l), uselocale);
341 _LIBCPP_ALWAYS_INLINE inline
342 size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
343 mbstate_t *__ps, locale_t __l)
345 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
346 return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
348 __locale_raii __current(uselocale(__l), uselocale);
349 return mbsrtowcs(__dest, __src, __len, __ps);
353 _LIBCPP_ALWAYS_INLINE inline
354 int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) {
356 va_start(__va, __format);
357 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
358 int __res = vsprintf_l(__s, __l, __format, __va);
360 __locale_raii __current(uselocale(__l), uselocale);
361 int __res = vsprintf(__s, __format, __va);
367 _LIBCPP_ALWAYS_INLINE inline
368 int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
370 va_start(__va, __format);
371 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
372 int __res = vsnprintf_l(__s, __n, __l, __format, __va);
374 __locale_raii __current(uselocale(__l), uselocale);
375 int __res = vsnprintf(__s, __n, __format, __va);
381 _LIBCPP_ALWAYS_INLINE inline
382 int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
384 va_start(__va, __format);
385 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
386 int __res = vasprintf_l(__s, __l, __format, __va);
388 __locale_raii __current(uselocale(__l), uselocale);
389 int __res = vasprintf(__s, __format, __va);
395 _LIBCPP_ALWAYS_INLINE inline
396 int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
398 va_start(__va, __format);
399 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
400 int __res = vsscanf_l(__s, __l, __format, __va);
402 __locale_raii __current(uselocale(__l), uselocale);
403 int __res = vsscanf(__s, __format, __va);
412 // Scans [__b, __e) until a match is found in the basic_strings range
413 // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
414 // __b will be incremented (visibly), consuming CharT until a match is found
415 // or proved to not exist. A keyword may be "", in which will match anything.
416 // If one keyword is a prefix of another, and the next CharT in the input
417 // might match another keyword, the algorithm will attempt to find the longest
418 // matching keyword. If the longer matching keyword ends up not matching, then
419 // no keyword match is found. If no keyword match is found, __ke is returned
420 // and failbit is set in __err.
421 // Else an iterator pointing to the matching keyword is found. If more than
422 // one keyword matches, an iterator to the first matching keyword is returned.
423 // If on exit __b == __e, eofbit is set in __err. If __case_senstive is false,
424 // __ct is used to force to lower case before comparing characters.
426 // Keywords: "a", "abb"
427 // If the input is "a", the first keyword matches and eofbit is set.
428 // If the input is "abc", no match is found and "ab" are consumed.
429 template <class _InputIterator, class _ForwardIterator, class _Ctype>
432 __scan_keyword(_InputIterator& __b, _InputIterator __e,
433 _ForwardIterator __kb, _ForwardIterator __ke,
434 const _Ctype& __ct, ios_base::iostate& __err,
435 bool __case_sensitive = true)
437 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
438 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
439 const unsigned char __doesnt_match = '\0';
440 const unsigned char __might_match = '\1';
441 const unsigned char __does_match = '\2';
442 unsigned char __statbuf[100];
443 unsigned char* __status = __statbuf;
444 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
445 if (__nkw > sizeof(__statbuf))
447 __status = (unsigned char*)malloc(__nkw);
450 __stat_hold.reset(__status);
452 size_t __n_might_match = __nkw; // At this point, any keyword might match
453 size_t __n_does_match = 0; // but none of them definitely do
454 // Initialize all statuses to __might_match, except for "" keywords are __does_match
455 unsigned char* __st = __status;
456 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
459 *__st = __might_match;
462 *__st = __does_match;
467 // While there might be a match, test keywords against the next CharT
468 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
470 // Peek at the next CharT but don't consume it
472 if (!__case_sensitive)
473 __c = __ct.toupper(__c);
474 bool __consume = false;
475 // For each keyword which might match, see if the __indx character is __c
476 // If a match if found, consume __c
477 // If a match is found, and that is the last character in the keyword,
478 // then that keyword matches.
479 // If the keyword doesn't match this character, then change the keyword
482 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
484 if (*__st == __might_match)
486 _CharT __kc = (*__ky)[__indx];
487 if (!__case_sensitive)
488 __kc = __ct.toupper(__kc);
492 if (__ky->size() == __indx+1)
494 *__st = __does_match;
501 *__st = __doesnt_match;
506 // consume if we matched a character
510 // If we consumed a character and there might be a matched keyword that
511 // was marked matched on a previous iteration, then such keywords
512 // which are now marked as not matching.
513 if (__n_might_match + __n_does_match > 1)
516 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
518 if (*__st == __does_match && __ky->size() != __indx+1)
520 *__st = __doesnt_match;
527 // We've exited the loop because we hit eof and/or we have no more "might matches".
529 __err |= ios_base::eofbit;
530 // Return the first matching result
531 for (__st = __status; __kb != __ke; ++__kb, ++__st)
532 if (*__st == __does_match)
535 __err |= ios_base::failbit;
539 struct __num_get_base
541 static const int __num_get_buf_sz = 40;
543 static int __get_base(ios_base&);
544 static const char __src[33];
547 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
548 ios_base::iostate& __err);
550 template <class _CharT>
552 : protected __num_get_base
554 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
555 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
556 _CharT& __thousands_sep);
557 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
558 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
559 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
560 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
561 char* __a, char*& __a_end,
562 _CharT __decimal_point, _CharT __thousands_sep,
563 const string& __grouping, unsigned* __g,
564 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
567 template <class _CharT>
569 __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
571 locale __loc = __iob.getloc();
572 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
573 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
574 __thousands_sep = __np.thousands_sep();
575 return __np.grouping();
578 template <class _CharT>
580 __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
581 _CharT& __thousands_sep)
583 locale __loc = __iob.getloc();
584 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
585 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
586 __decimal_point = __np.decimal_point();
587 __thousands_sep = __np.thousands_sep();
588 return __np.grouping();
591 template <class _CharT>
593 __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
594 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
595 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
597 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
599 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
603 if (__grouping.size() != 0 && __ct == __thousands_sep)
605 if (__g_end-__g < __num_get_buf_sz)
612 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
625 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
628 *__a_end++ = __src[__f];
633 if (__a_end-__a < __num_get_buf_sz - 1)
634 *__a_end++ = __src[__f];
639 template <class _CharT>
641 __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
642 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
643 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
645 if (__ct == __decimal_point)
651 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
655 if (__ct == __thousands_sep && __grouping.size() != 0)
659 if (__g_end-__g < __num_get_buf_sz)
666 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
669 char __x = __src[__f];
670 if (__x == '-' || __x == '+')
672 if (__a_end == __a || (__a_end[-1] & 0xDF) == __exp)
679 if (__a_end-__a < __num_get_buf_sz - 1)
681 if (__x == 'x' || __x == 'X')
683 else if ((__x & 0xDF) == __exp)
686 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
695 extern template struct __num_get<char>;
696 extern template struct __num_get<wchar_t>;
698 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
699 class _LIBCPP_VISIBLE num_get
700 : public locale::facet,
701 private __num_get<_CharT>
704 typedef _CharT char_type;
705 typedef _InputIterator iter_type;
707 _LIBCPP_ALWAYS_INLINE
708 explicit num_get(size_t __refs = 0)
709 : locale::facet(__refs) {}
711 _LIBCPP_ALWAYS_INLINE
712 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
713 ios_base::iostate& __err, bool& __v) const
715 return do_get(__b, __e, __iob, __err, __v);
718 _LIBCPP_ALWAYS_INLINE
719 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
720 ios_base::iostate& __err, long& __v) const
722 return do_get(__b, __e, __iob, __err, __v);
725 _LIBCPP_ALWAYS_INLINE
726 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
727 ios_base::iostate& __err, long long& __v) const
729 return do_get(__b, __e, __iob, __err, __v);
732 _LIBCPP_ALWAYS_INLINE
733 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
734 ios_base::iostate& __err, unsigned short& __v) const
736 return do_get(__b, __e, __iob, __err, __v);
739 _LIBCPP_ALWAYS_INLINE
740 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
741 ios_base::iostate& __err, unsigned int& __v) const
743 return do_get(__b, __e, __iob, __err, __v);
746 _LIBCPP_ALWAYS_INLINE
747 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
748 ios_base::iostate& __err, unsigned long& __v) const
750 return do_get(__b, __e, __iob, __err, __v);
753 _LIBCPP_ALWAYS_INLINE
754 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
755 ios_base::iostate& __err, unsigned long long& __v) const
757 return do_get(__b, __e, __iob, __err, __v);
760 _LIBCPP_ALWAYS_INLINE
761 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
762 ios_base::iostate& __err, float& __v) const
764 return do_get(__b, __e, __iob, __err, __v);
767 _LIBCPP_ALWAYS_INLINE
768 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
769 ios_base::iostate& __err, double& __v) const
771 return do_get(__b, __e, __iob, __err, __v);
774 _LIBCPP_ALWAYS_INLINE
775 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
776 ios_base::iostate& __err, long double& __v) const
778 return do_get(__b, __e, __iob, __err, __v);
781 _LIBCPP_ALWAYS_INLINE
782 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
783 ios_base::iostate& __err, void*& __v) const
785 return do_get(__b, __e, __iob, __err, __v);
788 static locale::id id;
791 _LIBCPP_ALWAYS_INLINE
794 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
795 ios_base::iostate& __err, bool& __v) const;
796 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
797 ios_base::iostate& __err, long& __v) const;
798 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
799 ios_base::iostate& __err, long long& __v) const;
800 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
801 ios_base::iostate& __err, unsigned short& __v) const;
802 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
803 ios_base::iostate& __err, unsigned int& __v) const;
804 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
805 ios_base::iostate& __err, unsigned long& __v) const;
806 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
807 ios_base::iostate& __err, unsigned long long& __v) const;
808 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
809 ios_base::iostate& __err, float& __v) const;
810 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
811 ios_base::iostate& __err, double& __v) const;
812 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
813 ios_base::iostate& __err, long double& __v) const;
814 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
815 ios_base::iostate& __err, void*& __v) const;
818 template <class _CharT, class _InputIterator>
820 num_get<_CharT, _InputIterator>::id;
824 __num_get_signed_integral(const char* __a, const char* __a_end,
825 ios_base::iostate& __err, int __base)
829 int __save_errno = errno;
832 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
833 int __current_errno = errno;
834 if (__current_errno == 0)
835 errno = __save_errno;
838 __err = ios_base::failbit;
841 else if (__current_errno == ERANGE ||
842 __ll < numeric_limits<_Tp>::min() ||
843 numeric_limits<_Tp>::max() < __ll)
845 __err = ios_base::failbit;
847 return numeric_limits<_Tp>::max();
849 return numeric_limits<_Tp>::min();
851 return static_cast<_Tp>(__ll);
853 __err = ios_base::failbit;
859 __num_get_unsigned_integral(const char* __a, const char* __a_end,
860 ios_base::iostate& __err, int __base)
866 __err = ios_base::failbit;
869 int __save_errno = errno;
872 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
873 int __current_errno = errno;
874 if (__current_errno == 0)
875 errno = __save_errno;
878 __err = ios_base::failbit;
881 else if (__current_errno == ERANGE ||
882 numeric_limits<_Tp>::max() < __ll)
884 __err = ios_base::failbit;
885 return numeric_limits<_Tp>::max();
887 return static_cast<_Tp>(__ll);
889 __err = ios_base::failbit;
895 __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
900 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
903 __err = ios_base::failbit;
906 return static_cast<_Tp>(__ld);
908 __err = ios_base::failbit;
912 template <class _CharT, class _InputIterator>
914 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
916 ios_base::iostate& __err,
919 if ((__iob.flags() & ios_base::boolalpha) == 0)
922 __b = do_get(__b, __e, __iob, __err, __lv);
933 __err = ios_base::failbit;
938 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
939 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
940 typedef typename numpunct<_CharT>::string_type string_type;
941 const string_type __names[2] = {__np.truename(), __np.falsename()};
942 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
944 __v = __i == __names;
948 template <class _CharT, class _InputIterator>
950 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
952 ios_base::iostate& __err,
956 int __base = this->__get_base(__iob);
958 char_type __atoms[26];
959 char_type __thousands_sep;
960 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
961 char __a[__num_get_base::__num_get_buf_sz] = {0};
963 unsigned __g[__num_get_base::__num_get_buf_sz];
964 unsigned* __g_end = __g;
966 for (; __b != __e; ++__b)
967 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
968 __thousands_sep, __grouping, __g, __g_end,
971 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
974 __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base);
975 // Digit grouping checked
976 __check_grouping(__grouping, __g, __g_end, __err);
979 __err |= ios_base::eofbit;
983 template <class _CharT, class _InputIterator>
985 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
987 ios_base::iostate& __err,
988 long long& __v) const
991 int __base = this->__get_base(__iob);
993 char_type __atoms[26];
994 char_type __thousands_sep;
995 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
996 char __a[__num_get_base::__num_get_buf_sz] = {0};
998 unsigned __g[__num_get_base::__num_get_buf_sz];
999 unsigned* __g_end = __g;
1001 for (; __b != __e; ++__b)
1002 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1003 __thousands_sep, __grouping, __g, __g_end,
1006 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1009 __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base);
1010 // Digit grouping checked
1011 __check_grouping(__grouping, __g, __g_end, __err);
1014 __err |= ios_base::eofbit;
1018 template <class _CharT, class _InputIterator>
1020 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1022 ios_base::iostate& __err,
1023 unsigned short& __v) const
1026 int __base = this->__get_base(__iob);
1028 char_type __atoms[26];
1029 char_type __thousands_sep;
1030 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1031 char __a[__num_get_base::__num_get_buf_sz] = {0};
1032 char* __a_end = __a;
1033 unsigned __g[__num_get_base::__num_get_buf_sz];
1034 unsigned* __g_end = __g;
1036 for (; __b != __e; ++__b)
1037 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1038 __thousands_sep, __grouping, __g, __g_end,
1041 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1044 __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base);
1045 // Digit grouping checked
1046 __check_grouping(__grouping, __g, __g_end, __err);
1049 __err |= ios_base::eofbit;
1053 template <class _CharT, class _InputIterator>
1055 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1057 ios_base::iostate& __err,
1058 unsigned int& __v) const
1061 int __base = this->__get_base(__iob);
1063 char_type __atoms[26];
1064 char_type __thousands_sep;
1065 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1066 char __a[__num_get_base::__num_get_buf_sz] = {0};
1067 char* __a_end = __a;
1068 unsigned __g[__num_get_base::__num_get_buf_sz];
1069 unsigned* __g_end = __g;
1071 for (; __b != __e; ++__b)
1072 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1073 __thousands_sep, __grouping, __g, __g_end,
1076 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1079 __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base);
1080 // Digit grouping checked
1081 __check_grouping(__grouping, __g, __g_end, __err);
1084 __err |= ios_base::eofbit;
1088 template <class _CharT, class _InputIterator>
1090 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1092 ios_base::iostate& __err,
1093 unsigned long& __v) const
1096 int __base = this->__get_base(__iob);
1098 char_type __atoms[26];
1099 char_type __thousands_sep;
1100 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1101 char __a[__num_get_base::__num_get_buf_sz] = {0};
1102 char* __a_end = __a;
1103 unsigned __g[__num_get_base::__num_get_buf_sz];
1104 unsigned* __g_end = __g;
1106 for (; __b != __e; ++__b)
1107 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1108 __thousands_sep, __grouping, __g, __g_end,
1111 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1114 __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base);
1115 // Digit grouping checked
1116 __check_grouping(__grouping, __g, __g_end, __err);
1119 __err |= ios_base::eofbit;
1123 template <class _CharT, class _InputIterator>
1125 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1127 ios_base::iostate& __err,
1128 unsigned long long& __v) const
1131 int __base = this->__get_base(__iob);
1133 char_type __atoms[26];
1134 char_type __thousands_sep;
1135 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1136 char __a[__num_get_base::__num_get_buf_sz] = {0};
1137 char* __a_end = __a;
1138 unsigned __g[__num_get_base::__num_get_buf_sz];
1139 unsigned* __g_end = __g;
1141 for (; __b != __e; ++__b)
1142 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1143 __thousands_sep, __grouping, __g, __g_end,
1146 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1149 __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base);
1150 // Digit grouping checked
1151 __check_grouping(__grouping, __g, __g_end, __err);
1154 __err |= ios_base::eofbit;
1158 template <class _CharT, class _InputIterator>
1160 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1162 ios_base::iostate& __err,
1165 // Stage 1, nothing to do
1167 char_type __atoms[32];
1168 char_type __decimal_point;
1169 char_type __thousands_sep;
1170 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1173 char __a[__num_get_base::__num_get_buf_sz] = {0};
1174 char* __a_end = __a;
1175 unsigned __g[__num_get_base::__num_get_buf_sz];
1176 unsigned* __g_end = __g;
1178 bool __in_units = true;
1180 for (; __b != __e; ++__b)
1181 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1182 __decimal_point, __thousands_sep,
1183 __grouping, __g, __g_end,
1186 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1189 __v = __num_get_float<float>(__a, __a_end, __err);
1190 // Digit grouping checked
1191 __check_grouping(__grouping, __g, __g_end, __err);
1194 __err |= ios_base::eofbit;
1198 template <class _CharT, class _InputIterator>
1200 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1202 ios_base::iostate& __err,
1205 // Stage 1, nothing to do
1207 char_type __atoms[32];
1208 char_type __decimal_point;
1209 char_type __thousands_sep;
1210 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1213 char __a[__num_get_base::__num_get_buf_sz] = {0};
1214 char* __a_end = __a;
1215 unsigned __g[__num_get_base::__num_get_buf_sz];
1216 unsigned* __g_end = __g;
1218 bool __in_units = true;
1220 for (; __b != __e; ++__b)
1221 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1222 __decimal_point, __thousands_sep,
1223 __grouping, __g, __g_end,
1226 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1229 __v = __num_get_float<double>(__a, __a_end, __err);
1230 // Digit grouping checked
1231 __check_grouping(__grouping, __g, __g_end, __err);
1234 __err |= ios_base::eofbit;
1238 template <class _CharT, class _InputIterator>
1240 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1242 ios_base::iostate& __err,
1243 long double& __v) const
1245 // Stage 1, nothing to do
1247 char_type __atoms[32];
1248 char_type __decimal_point;
1249 char_type __thousands_sep;
1250 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1253 char __a[__num_get_base::__num_get_buf_sz] = {0};
1254 char* __a_end = __a;
1255 unsigned __g[__num_get_base::__num_get_buf_sz];
1256 unsigned* __g_end = __g;
1258 bool __in_units = true;
1260 for (; __b != __e; ++__b)
1261 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1262 __decimal_point, __thousands_sep,
1263 __grouping, __g, __g_end,
1266 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1269 __v = __num_get_float<long double>(__a, __a_end, __err);
1270 // Digit grouping checked
1271 __check_grouping(__grouping, __g, __g_end, __err);
1274 __err |= ios_base::eofbit;
1278 template <class _CharT, class _InputIterator>
1280 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1282 ios_base::iostate& __err,
1288 char_type __atoms[26];
1289 char_type __thousands_sep = 0;
1291 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1292 __num_get_base::__src + 26, __atoms);
1293 char __a[__num_get_base::__num_get_buf_sz] = {0};
1294 char* __a_end = __a;
1295 unsigned __g[__num_get_base::__num_get_buf_sz];
1296 unsigned* __g_end = __g;
1298 for (; __b != __e; ++__b)
1299 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1300 __thousands_sep, __grouping,
1301 __g, __g_end, __atoms))
1304 __a[sizeof(__a)-1] = 0;
1305 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1306 if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1308 if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1)
1310 __err = ios_base::failbit;
1313 __err |= ios_base::eofbit;
1317 extern template class num_get<char>;
1318 extern template class num_get<wchar_t>;
1320 struct __num_put_base
1323 static void __format_int(char* __fmt, const char* __len, bool __signd,
1324 ios_base::fmtflags __flags);
1325 static bool __format_float(char* __fmt, const char* __len,
1326 ios_base::fmtflags __flags);
1327 static char* __identify_padding(char* __nb, char* __ne,
1328 const ios_base& __iob);
1331 template <class _CharT>
1333 : protected __num_put_base
1335 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1336 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1337 const locale& __loc);
1338 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1339 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1340 const locale& __loc);
1343 template <class _CharT>
1345 __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1346 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1347 const locale& __loc)
1349 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1350 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1351 string __grouping = __npt.grouping();
1352 if (__grouping.empty())
1354 __ct.widen(__nb, __ne, __ob);
1355 __oe = __ob + (__ne - __nb);
1361 if (*__nf == '-' || *__nf == '+')
1362 *__oe++ = __ct.widen(*__nf++);
1363 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1366 *__oe++ = __ct.widen(*__nf++);
1367 *__oe++ = __ct.widen(*__nf++);
1369 reverse(__nf, __ne);
1370 _CharT __thousands_sep = __npt.thousands_sep();
1373 for (char* __p = __nf; __p < __ne; ++__p)
1375 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1376 __dc == static_cast<unsigned>(__grouping[__dg]))
1378 *__oe++ = __thousands_sep;
1380 if (__dg < __grouping.size()-1)
1383 *__oe++ = __ct.widen(*__p);
1386 reverse(__ob + (__nf - __nb), __oe);
1391 __op = __ob + (__np - __nb);
1394 template <class _CharT>
1396 __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1397 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1398 const locale& __loc)
1400 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1401 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1402 string __grouping = __npt.grouping();
1405 if (*__nf == '-' || *__nf == '+')
1406 *__oe++ = __ct.widen(*__nf++);
1408 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1411 *__oe++ = __ct.widen(*__nf++);
1412 *__oe++ = __ct.widen(*__nf++);
1413 for (__ns = __nf; __ns < __ne; ++__ns)
1414 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1419 for (__ns = __nf; __ns < __ne; ++__ns)
1420 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1423 if (__grouping.empty())
1425 __ct.widen(__nf, __ns, __oe);
1426 __oe += __ns - __nf;
1430 reverse(__nf, __ns);
1431 _CharT __thousands_sep = __npt.thousands_sep();
1434 for (char* __p = __nf; __p < __ns; ++__p)
1436 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1438 *__oe++ = __thousands_sep;
1440 if (__dg < __grouping.size()-1)
1443 *__oe++ = __ct.widen(*__p);
1446 reverse(__ob + (__nf - __nb), __oe);
1448 for (__nf = __ns; __nf < __ne; ++__nf)
1452 *__oe++ = __npt.decimal_point();
1457 *__oe++ = __ct.widen(*__nf);
1459 __ct.widen(__nf, __ne, __oe);
1460 __oe += __ne - __nf;
1464 __op = __ob + (__np - __nb);
1467 extern template struct __num_put<char>;
1468 extern template struct __num_put<wchar_t>;
1470 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1471 class _LIBCPP_VISIBLE num_put
1472 : public locale::facet,
1473 private __num_put<_CharT>
1476 typedef _CharT char_type;
1477 typedef _OutputIterator iter_type;
1479 _LIBCPP_ALWAYS_INLINE
1480 explicit num_put(size_t __refs = 0)
1481 : locale::facet(__refs) {}
1483 _LIBCPP_ALWAYS_INLINE
1484 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1487 return do_put(__s, __iob, __fl, __v);
1490 _LIBCPP_ALWAYS_INLINE
1491 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1494 return do_put(__s, __iob, __fl, __v);
1497 _LIBCPP_ALWAYS_INLINE
1498 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1499 long long __v) const
1501 return do_put(__s, __iob, __fl, __v);
1504 _LIBCPP_ALWAYS_INLINE
1505 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1506 unsigned long __v) const
1508 return do_put(__s, __iob, __fl, __v);
1511 _LIBCPP_ALWAYS_INLINE
1512 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1513 unsigned long long __v) const
1515 return do_put(__s, __iob, __fl, __v);
1518 _LIBCPP_ALWAYS_INLINE
1519 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1522 return do_put(__s, __iob, __fl, __v);
1525 _LIBCPP_ALWAYS_INLINE
1526 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1527 long double __v) const
1529 return do_put(__s, __iob, __fl, __v);
1532 _LIBCPP_ALWAYS_INLINE
1533 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1534 const void* __v) const
1536 return do_put(__s, __iob, __fl, __v);
1539 static locale::id id;
1542 _LIBCPP_ALWAYS_INLINE
1545 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1547 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1549 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1550 long long __v) const;
1551 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1552 unsigned long) const;
1553 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1554 unsigned long long) const;
1555 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1557 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1558 long double __v) const;
1559 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1560 const void* __v) const;
1563 template <class _CharT, class _OutputIterator>
1565 num_put<_CharT, _OutputIterator>::id;
1567 template <class _CharT, class _OutputIterator>
1570 __pad_and_output(_OutputIterator __s,
1571 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1572 ios_base& __iob, _CharT __fl)
1574 streamsize __sz = __oe - __ob;
1575 streamsize __ns = __iob.width();
1580 for (;__ob < __op; ++__ob, ++__s)
1582 for (; __ns; --__ns, ++__s)
1584 for (; __ob < __oe; ++__ob, ++__s)
1590 template <class _CharT, class _Traits>
1592 ostreambuf_iterator<_CharT, _Traits>
1593 __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1594 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1595 ios_base& __iob, _CharT __fl)
1597 if (__s.__sbuf_ == nullptr)
1599 streamsize __sz = __oe - __ob;
1600 streamsize __ns = __iob.width();
1605 streamsize __np = __op - __ob;
1608 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1610 __s.__sbuf_ = nullptr;
1616 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1617 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1619 __s.__sbuf_ = nullptr;
1626 if (__s.__sbuf_->sputn(__op, __np) != __np)
1628 __s.__sbuf_ = nullptr;
1636 template <class _CharT, class _OutputIterator>
1638 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1639 char_type __fl, bool __v) const
1641 if ((__iob.flags() & ios_base::boolalpha) == 0)
1642 return do_put(__s, __iob, __fl, (unsigned long)__v);
1643 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1644 typedef typename numpunct<char_type>::string_type string_type;
1645 string_type __nm = __v ? __np.truename() : __np.falsename();
1646 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1651 template <class _CharT, class _OutputIterator>
1653 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1654 char_type __fl, long __v) const
1656 // Stage 1 - Get number in narrow char
1657 char __fmt[6] = {'%', 0};
1658 const char* __len = "l";
1659 this->__format_int(__fmt+1, __len, true, __iob.flags());
1660 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1661 + ((numeric_limits<long>::digits % 3) != 0)
1664 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1665 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1667 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1669 char* __ne = __nar + __nc;
1670 char* __np = this->__identify_padding(__nar, __ne, __iob);
1671 // Stage 2 - Widen __nar while adding thousands separators
1672 char_type __o[2*(__nbuf-1) - 1];
1673 char_type* __op; // pad here
1674 char_type* __oe; // end of output
1675 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1676 // [__o, __oe) contains thousands_sep'd wide number
1678 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1681 template <class _CharT, class _OutputIterator>
1683 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1684 char_type __fl, long long __v) const
1686 // Stage 1 - Get number in narrow char
1687 char __fmt[8] = {'%', 0};
1688 const char* __len = "ll";
1689 this->__format_int(__fmt+1, __len, true, __iob.flags());
1690 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1691 + ((numeric_limits<long long>::digits % 3) != 0)
1694 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1695 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1697 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1699 char* __ne = __nar + __nc;
1700 char* __np = this->__identify_padding(__nar, __ne, __iob);
1701 // Stage 2 - Widen __nar while adding thousands separators
1702 char_type __o[2*(__nbuf-1) - 1];
1703 char_type* __op; // pad here
1704 char_type* __oe; // end of output
1705 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1706 // [__o, __oe) contains thousands_sep'd wide number
1708 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1711 template <class _CharT, class _OutputIterator>
1713 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1714 char_type __fl, unsigned long __v) const
1716 // Stage 1 - Get number in narrow char
1717 char __fmt[6] = {'%', 0};
1718 const char* __len = "l";
1719 this->__format_int(__fmt+1, __len, false, __iob.flags());
1720 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1721 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1724 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1725 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1727 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1729 char* __ne = __nar + __nc;
1730 char* __np = this->__identify_padding(__nar, __ne, __iob);
1731 // Stage 2 - Widen __nar while adding thousands separators
1732 char_type __o[2*(__nbuf-1) - 1];
1733 char_type* __op; // pad here
1734 char_type* __oe; // end of output
1735 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1736 // [__o, __oe) contains thousands_sep'd wide number
1738 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1741 template <class _CharT, class _OutputIterator>
1743 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1744 char_type __fl, unsigned long long __v) const
1746 // Stage 1 - Get number in narrow char
1747 char __fmt[8] = {'%', 0};
1748 const char* __len = "ll";
1749 this->__format_int(__fmt+1, __len, false, __iob.flags());
1750 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1751 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1754 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1755 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1757 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1759 char* __ne = __nar + __nc;
1760 char* __np = this->__identify_padding(__nar, __ne, __iob);
1761 // Stage 2 - Widen __nar while adding thousands separators
1762 char_type __o[2*(__nbuf-1) - 1];
1763 char_type* __op; // pad here
1764 char_type* __oe; // end of output
1765 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1766 // [__o, __oe) contains thousands_sep'd wide number
1768 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1771 template <class _CharT, class _OutputIterator>
1773 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1774 char_type __fl, double __v) const
1776 // Stage 1 - Get number in narrow char
1777 char __fmt[8] = {'%', 0};
1778 const char* __len = "";
1779 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1780 const unsigned __nbuf = 30;
1784 if (__specify_precision)
1785 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1786 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1787 (int)__iob.precision(), __v);
1789 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1790 (int)__iob.precision(), __v);
1793 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1794 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1796 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1798 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1799 if (__nc > static_cast<int>(__nbuf-1))
1801 if (__specify_precision)
1802 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1803 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1805 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1806 (int)__iob.precision(), __v);
1809 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1810 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1812 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
1815 __throw_bad_alloc();
1818 char* __ne = __nb + __nc;
1819 char* __np = this->__identify_padding(__nb, __ne, __iob);
1820 // Stage 2 - Widen __nar while adding thousands separators
1821 char_type __o[2*(__nbuf-1) - 1];
1822 char_type* __ob = __o;
1823 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1826 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1828 __throw_bad_alloc();
1831 char_type* __op; // pad here
1832 char_type* __oe; // end of output
1833 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1834 // [__o, __oe) contains thousands_sep'd wide number
1836 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1840 template <class _CharT, class _OutputIterator>
1842 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1843 char_type __fl, long double __v) const
1845 // Stage 1 - Get number in narrow char
1846 char __fmt[8] = {'%', 0};
1847 const char* __len = "L";
1848 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1849 const unsigned __nbuf = 30;
1853 if (__specify_precision)
1854 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1855 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1856 (int)__iob.precision(), __v);
1858 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1859 (int)__iob.precision(), __v);
1862 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1863 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1865 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1867 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1868 if (__nc > static_cast<int>(__nbuf-1))
1870 if (__specify_precision)
1871 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1872 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1874 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1875 (int)__iob.precision(), __v);
1878 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1879 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1881 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
1884 __throw_bad_alloc();
1887 char* __ne = __nb + __nc;
1888 char* __np = this->__identify_padding(__nb, __ne, __iob);
1889 // Stage 2 - Widen __nar while adding thousands separators
1890 char_type __o[2*(__nbuf-1) - 1];
1891 char_type* __ob = __o;
1892 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1895 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1897 __throw_bad_alloc();
1900 char_type* __op; // pad here
1901 char_type* __oe; // end of output
1902 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1903 // [__o, __oe) contains thousands_sep'd wide number
1905 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1909 template <class _CharT, class _OutputIterator>
1911 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1912 char_type __fl, const void* __v) const
1914 // Stage 1 - Get pointer in narrow char
1915 char __fmt[6] = "%p";
1916 const unsigned __nbuf = 20;
1918 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1919 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1921 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1923 char* __ne = __nar + __nc;
1924 char* __np = this->__identify_padding(__nar, __ne, __iob);
1925 // Stage 2 - Widen __nar
1926 char_type __o[2*(__nbuf-1) - 1];
1927 char_type* __op; // pad here
1928 char_type* __oe; // end of output
1929 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1930 __ct.widen(__nar, __ne, __o);
1931 __oe = __o + (__ne - __nar);
1935 __op = __o + (__np - __nar);
1936 // [__o, __oe) contains wide number
1938 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1941 extern template class num_put<char>;
1942 extern template class num_put<wchar_t>;
1944 template <class _CharT, class _InputIterator>
1947 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1948 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1950 // Precondition: __n >= 1
1953 __err |= ios_base::eofbit | ios_base::failbit;
1958 if (!__ct.is(ctype_base::digit, __c))
1960 __err |= ios_base::failbit;
1963 int __r = __ct.narrow(__c, 0) - '0';
1964 for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
1968 if (!__ct.is(ctype_base::digit, __c))
1970 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1973 __err |= ios_base::eofbit;
1977 class _LIBCPP_VISIBLE time_base
1980 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1983 template <class _CharT>
1984 class __time_get_c_storage // purposefully not decorated
1987 typedef basic_string<_CharT> string_type;
1989 virtual const string_type* __weeks() const;
1990 virtual const string_type* __months() const;
1991 virtual const string_type* __am_pm() const;
1992 virtual const string_type& __c() const;
1993 virtual const string_type& __r() const;
1994 virtual const string_type& __x() const;
1995 virtual const string_type& __X() const;
1998 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1999 class _LIBCPP_VISIBLE time_get
2000 : public locale::facet,
2002 private __time_get_c_storage<_CharT>
2005 typedef _CharT char_type;
2006 typedef _InputIterator iter_type;
2007 typedef time_base::dateorder dateorder;
2008 typedef basic_string<char_type> string_type;
2010 _LIBCPP_ALWAYS_INLINE
2011 explicit time_get(size_t __refs = 0)
2012 : locale::facet(__refs) {}
2014 _LIBCPP_ALWAYS_INLINE
2015 dateorder date_order() const
2017 return this->do_date_order();
2020 _LIBCPP_ALWAYS_INLINE
2021 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
2022 ios_base::iostate& __err, tm* __tm) const
2024 return do_get_time(__b, __e, __iob, __err, __tm);
2027 _LIBCPP_ALWAYS_INLINE
2028 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
2029 ios_base::iostate& __err, tm* __tm) const
2031 return do_get_date(__b, __e, __iob, __err, __tm);
2034 _LIBCPP_ALWAYS_INLINE
2035 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2036 ios_base::iostate& __err, tm* __tm) const
2038 return do_get_weekday(__b, __e, __iob, __err, __tm);
2041 _LIBCPP_ALWAYS_INLINE
2042 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2043 ios_base::iostate& __err, tm* __tm) const
2045 return do_get_monthname(__b, __e, __iob, __err, __tm);
2048 _LIBCPP_ALWAYS_INLINE
2049 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
2050 ios_base::iostate& __err, tm* __tm) const
2052 return do_get_year(__b, __e, __iob, __err, __tm);
2055 _LIBCPP_ALWAYS_INLINE
2056 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2057 ios_base::iostate& __err, tm *__tm,
2058 char __fmt, char __mod = 0) const
2060 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
2063 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2064 ios_base::iostate& __err, tm* __tm,
2065 const char_type* __fmtb, const char_type* __fmte) const;
2067 static locale::id id;
2070 _LIBCPP_ALWAYS_INLINE
2073 virtual dateorder do_date_order() const;
2074 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
2075 ios_base::iostate& __err, tm* __tm) const;
2076 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
2077 ios_base::iostate& __err, tm* __tm) const;
2078 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2079 ios_base::iostate& __err, tm* __tm) const;
2080 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2081 ios_base::iostate& __err, tm* __tm) const;
2082 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
2083 ios_base::iostate& __err, tm* __tm) const;
2084 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
2085 ios_base::iostate& __err, tm* __tm,
2086 char __fmt, char __mod) const;
2088 void __get_white_space(iter_type& __b, iter_type __e,
2089 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
2090 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
2091 const ctype<char_type>& __ct) const;
2093 void __get_weekdayname(int& __m,
2094 iter_type& __b, iter_type __e,
2095 ios_base::iostate& __err,
2096 const ctype<char_type>& __ct) const;
2097 void __get_monthname(int& __m,
2098 iter_type& __b, iter_type __e,
2099 ios_base::iostate& __err,
2100 const ctype<char_type>& __ct) const;
2101 void __get_day(int& __d,
2102 iter_type& __b, iter_type __e,
2103 ios_base::iostate& __err,
2104 const ctype<char_type>& __ct) const;
2105 void __get_month(int& __m,
2106 iter_type& __b, iter_type __e,
2107 ios_base::iostate& __err,
2108 const ctype<char_type>& __ct) const;
2109 void __get_year(int& __y,
2110 iter_type& __b, iter_type __e,
2111 ios_base::iostate& __err,
2112 const ctype<char_type>& __ct) const;
2113 void __get_year4(int& __y,
2114 iter_type& __b, iter_type __e,
2115 ios_base::iostate& __err,
2116 const ctype<char_type>& __ct) const;
2117 void __get_hour(int& __d,
2118 iter_type& __b, iter_type __e,
2119 ios_base::iostate& __err,
2120 const ctype<char_type>& __ct) const;
2121 void __get_12_hour(int& __h,
2122 iter_type& __b, iter_type __e,
2123 ios_base::iostate& __err,
2124 const ctype<char_type>& __ct) const;
2125 void __get_am_pm(int& __h,
2126 iter_type& __b, iter_type __e,
2127 ios_base::iostate& __err,
2128 const ctype<char_type>& __ct) const;
2129 void __get_minute(int& __m,
2130 iter_type& __b, iter_type __e,
2131 ios_base::iostate& __err,
2132 const ctype<char_type>& __ct) const;
2133 void __get_second(int& __s,
2134 iter_type& __b, iter_type __e,
2135 ios_base::iostate& __err,
2136 const ctype<char_type>& __ct) const;
2137 void __get_weekday(int& __w,
2138 iter_type& __b, iter_type __e,
2139 ios_base::iostate& __err,
2140 const ctype<char_type>& __ct) const;
2141 void __get_day_year_num(int& __w,
2142 iter_type& __b, iter_type __e,
2143 ios_base::iostate& __err,
2144 const ctype<char_type>& __ct) const;
2147 template <class _CharT, class _InputIterator>
2149 time_get<_CharT, _InputIterator>::id;
2151 // time_get primatives
2153 template <class _CharT, class _InputIterator>
2155 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2156 iter_type& __b, iter_type __e,
2157 ios_base::iostate& __err,
2158 const ctype<char_type>& __ct) const
2160 // Note: ignoring case comes from the POSIX strptime spec
2161 const string_type* __wk = this->__weeks();
2162 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
2167 template <class _CharT, class _InputIterator>
2169 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2170 iter_type& __b, iter_type __e,
2171 ios_base::iostate& __err,
2172 const ctype<char_type>& __ct) const
2174 // Note: ignoring case comes from the POSIX strptime spec
2175 const string_type* __month = this->__months();
2176 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
2181 template <class _CharT, class _InputIterator>
2183 time_get<_CharT, _InputIterator>::__get_day(int& __d,
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) && 1 <= __t && __t <= 31)
2192 __err |= ios_base::failbit;
2195 template <class _CharT, class _InputIterator>
2197 time_get<_CharT, _InputIterator>::__get_month(int& __m,
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, 2) - 1;
2203 if (!(__err & ios_base::failbit) && __t <= 11)
2206 __err |= ios_base::failbit;
2209 template <class _CharT, class _InputIterator>
2211 time_get<_CharT, _InputIterator>::__get_year(int& __y,
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, 4);
2217 if (!(__err & ios_base::failbit))
2221 else if (69 <= __t && __t <= 99)
2227 template <class _CharT, class _InputIterator>
2229 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2230 iter_type& __b, iter_type __e,
2231 ios_base::iostate& __err,
2232 const ctype<char_type>& __ct) const
2234 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2235 if (!(__err & ios_base::failbit))
2239 template <class _CharT, class _InputIterator>
2241 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2242 iter_type& __b, iter_type __e,
2243 ios_base::iostate& __err,
2244 const ctype<char_type>& __ct) const
2246 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2247 if (!(__err & ios_base::failbit) && __t <= 23)
2250 __err |= ios_base::failbit;
2253 template <class _CharT, class _InputIterator>
2255 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2256 iter_type& __b, iter_type __e,
2257 ios_base::iostate& __err,
2258 const ctype<char_type>& __ct) const
2260 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2261 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2264 __err |= ios_base::failbit;
2267 template <class _CharT, class _InputIterator>
2269 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2270 iter_type& __b, iter_type __e,
2271 ios_base::iostate& __err,
2272 const ctype<char_type>& __ct) const
2274 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2275 if (!(__err & ios_base::failbit) && __t <= 59)
2278 __err |= ios_base::failbit;
2281 template <class _CharT, class _InputIterator>
2283 time_get<_CharT, _InputIterator>::__get_second(int& __s,
2284 iter_type& __b, iter_type __e,
2285 ios_base::iostate& __err,
2286 const ctype<char_type>& __ct) const
2288 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2289 if (!(__err & ios_base::failbit) && __t <= 60)
2292 __err |= ios_base::failbit;
2295 template <class _CharT, class _InputIterator>
2297 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2298 iter_type& __b, iter_type __e,
2299 ios_base::iostate& __err,
2300 const ctype<char_type>& __ct) const
2302 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2303 if (!(__err & ios_base::failbit) && __t <= 6)
2306 __err |= ios_base::failbit;
2309 template <class _CharT, class _InputIterator>
2311 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2312 iter_type& __b, iter_type __e,
2313 ios_base::iostate& __err,
2314 const ctype<char_type>& __ct) const
2316 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2317 if (!(__err & ios_base::failbit) && __t <= 365)
2320 __err |= ios_base::failbit;
2323 template <class _CharT, class _InputIterator>
2325 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2326 ios_base::iostate& __err,
2327 const ctype<char_type>& __ct) const
2329 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2332 __err |= ios_base::eofbit;
2335 template <class _CharT, class _InputIterator>
2337 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2338 iter_type& __b, iter_type __e,
2339 ios_base::iostate& __err,
2340 const ctype<char_type>& __ct) const
2342 const string_type* __ap = this->__am_pm();
2343 if (__ap[0].size() + __ap[1].size() == 0)
2345 __err |= ios_base::failbit;
2348 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2349 if (__i == 0 && __h == 12)
2351 else if (__i == 1 && __h < 12)
2355 template <class _CharT, class _InputIterator>
2357 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2358 ios_base::iostate& __err,
2359 const ctype<char_type>& __ct) const
2363 __err |= ios_base::eofbit | ios_base::failbit;
2366 if (__ct.narrow(*__b, 0) != '%')
2367 __err |= ios_base::failbit;
2368 else if(++__b == __e)
2369 __err |= ios_base::eofbit;
2372 // time_get end primatives
2374 template <class _CharT, class _InputIterator>
2376 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2378 ios_base::iostate& __err, tm* __tm,
2379 const char_type* __fmtb, const char_type* __fmte) const
2381 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2382 __err = ios_base::goodbit;
2383 while (__fmtb != __fmte && __err == ios_base::goodbit)
2387 __err = ios_base::failbit;
2390 if (__ct.narrow(*__fmtb, 0) == '%')
2392 if (++__fmtb == __fmte)
2394 __err = ios_base::failbit;
2397 char __cmd = __ct.narrow(*__fmtb, 0);
2399 if (__cmd == 'E' || __cmd == '0')
2401 if (++__fmtb == __fmte)
2403 __err = ios_base::failbit;
2407 __cmd = __ct.narrow(*__fmtb, 0);
2409 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2412 else if (__ct.is(ctype_base::space, *__fmtb))
2414 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2416 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2419 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2425 __err = ios_base::failbit;
2428 __err |= ios_base::eofbit;
2432 template <class _CharT, class _InputIterator>
2433 typename time_get<_CharT, _InputIterator>::dateorder
2434 time_get<_CharT, _InputIterator>::do_date_order() const
2439 template <class _CharT, class _InputIterator>
2441 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2443 ios_base::iostate& __err,
2446 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2447 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2450 template <class _CharT, class _InputIterator>
2452 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2454 ios_base::iostate& __err,
2457 const string_type& __fmt = this->__x();
2458 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2461 template <class _CharT, class _InputIterator>
2463 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2465 ios_base::iostate& __err,
2468 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2469 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2473 template <class _CharT, class _InputIterator>
2475 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2477 ios_base::iostate& __err,
2480 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2481 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2485 template <class _CharT, class _InputIterator>
2487 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2489 ios_base::iostate& __err,
2492 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2493 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2497 template <class _CharT, class _InputIterator>
2499 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2501 ios_base::iostate& __err, tm* __tm,
2502 char __fmt, char) const
2504 __err = ios_base::goodbit;
2505 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2510 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2515 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2519 const string_type& __fm = this->__c();
2520 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2525 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2529 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2530 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2535 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2536 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2540 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2543 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2546 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2549 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2552 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2556 __get_white_space(__b, __e, __err, __ct);
2559 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2563 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2564 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2569 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2570 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2574 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2578 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2579 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2583 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2586 return do_get_date(__b, __e, __iob, __err, __tm);
2589 const string_type& __fm = this->__X();
2590 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2594 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2597 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2600 __get_percent(__b, __e, __err, __ct);
2603 __err |= ios_base::failbit;
2608 extern template class time_get<char>;
2609 extern template class time_get<wchar_t>;
2616 __time_get(const char* __nm);
2617 __time_get(const string& __nm);
2621 template <class _CharT>
2622 class __time_get_storage
2626 typedef basic_string<_CharT> string_type;
2628 string_type __weeks_[14];
2629 string_type __months_[24];
2630 string_type __am_pm_[2];
2636 explicit __time_get_storage(const char* __nm);
2637 explicit __time_get_storage(const string& __nm);
2639 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2641 time_base::dateorder __do_date_order() const;
2644 void init(const ctype<_CharT>&);
2645 string_type __analyze(char __fmt, const ctype<_CharT>&);
2648 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2649 class _LIBCPP_VISIBLE time_get_byname
2650 : public time_get<_CharT, _InputIterator>,
2651 private __time_get_storage<_CharT>
2654 typedef time_base::dateorder dateorder;
2655 typedef _InputIterator iter_type;
2656 typedef _CharT char_type;
2657 typedef basic_string<char_type> string_type;
2659 _LIBCPP_INLINE_VISIBILITY
2660 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2661 : time_get<_CharT, _InputIterator>(__refs),
2662 __time_get_storage<_CharT>(__nm) {}
2663 _LIBCPP_INLINE_VISIBILITY
2664 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2665 : time_get<_CharT, _InputIterator>(__refs),
2666 __time_get_storage<_CharT>(__nm) {}
2669 _LIBCPP_INLINE_VISIBILITY
2670 ~time_get_byname() {}
2672 _LIBCPP_INLINE_VISIBILITY
2673 virtual dateorder do_date_order() const {return this->__do_date_order();}
2675 _LIBCPP_INLINE_VISIBILITY
2676 virtual const string_type* __weeks() const {return this->__weeks_;}
2677 _LIBCPP_INLINE_VISIBILITY
2678 virtual const string_type* __months() const {return this->__months_;}
2679 _LIBCPP_INLINE_VISIBILITY
2680 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2681 _LIBCPP_INLINE_VISIBILITY
2682 virtual const string_type& __c() const {return this->__c_;}
2683 _LIBCPP_INLINE_VISIBILITY
2684 virtual const string_type& __r() const {return this->__r_;}
2685 _LIBCPP_INLINE_VISIBILITY
2686 virtual const string_type& __x() const {return this->__x_;}
2687 _LIBCPP_INLINE_VISIBILITY
2688 virtual const string_type& __X() const {return this->__X_;}
2691 extern template class time_get_byname<char>;
2692 extern template class time_get_byname<wchar_t>;
2698 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2699 __time_put(const char* __nm);
2700 __time_put(const string& __nm);
2702 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2703 char __fmt, char __mod) const;
2704 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2705 char __fmt, char __mod) const;
2708 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2709 class _LIBCPP_VISIBLE time_put
2710 : public locale::facet,
2714 typedef _CharT char_type;
2715 typedef _OutputIterator iter_type;
2717 _LIBCPP_ALWAYS_INLINE
2718 explicit time_put(size_t __refs = 0)
2719 : locale::facet(__refs) {}
2721 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2722 const char_type* __pb, const char_type* __pe) const;
2724 _LIBCPP_ALWAYS_INLINE
2725 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2726 const tm* __tm, char __fmt, char __mod = 0) const
2728 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2731 static locale::id id;
2734 _LIBCPP_ALWAYS_INLINE
2736 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2737 char __fmt, char __mod) const;
2739 _LIBCPP_ALWAYS_INLINE
2740 explicit time_put(const char* __nm, size_t __refs)
2741 : locale::facet(__refs),
2743 _LIBCPP_ALWAYS_INLINE
2744 explicit time_put(const string& __nm, size_t __refs)
2745 : locale::facet(__refs),
2749 template <class _CharT, class _OutputIterator>
2751 time_put<_CharT, _OutputIterator>::id;
2753 template <class _CharT, class _OutputIterator>
2755 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2756 char_type __fl, const tm* __tm,
2757 const char_type* __pb,
2758 const char_type* __pe) const
2760 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2761 for (; __pb != __pe; ++__pb)
2763 if (__ct.narrow(*__pb, 0) == '%')
2771 char __fmt = __ct.narrow(*__pb, 0);
2772 if (__fmt == 'E' || __fmt == 'O')
2781 __fmt = __ct.narrow(*__pb, 0);
2783 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2791 template <class _CharT, class _OutputIterator>
2793 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2794 char_type, const tm* __tm,
2795 char __fmt, char __mod) const
2797 char_type __nar[100];
2798 char_type* __nb = __nar;
2799 char_type* __ne = __nb + 100;
2800 __do_put(__nb, __ne, __tm, __fmt, __mod);
2801 return _VSTD::copy(__nb, __ne, __s);
2804 extern template class time_put<char>;
2805 extern template class time_put<wchar_t>;
2807 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2808 class _LIBCPP_VISIBLE time_put_byname
2809 : public time_put<_CharT, _OutputIterator>
2812 _LIBCPP_ALWAYS_INLINE
2813 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2814 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2816 _LIBCPP_ALWAYS_INLINE
2817 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2818 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2821 _LIBCPP_ALWAYS_INLINE
2822 ~time_put_byname() {}
2825 extern template class time_put_byname<char>;
2826 extern template class time_put_byname<wchar_t>;
2830 class _LIBCPP_VISIBLE money_base
2833 enum part {none, space, symbol, sign, value};
2834 struct pattern {char field[4];};
2836 _LIBCPP_ALWAYS_INLINE money_base() {}
2841 template <class _CharT, bool _International = false>
2842 class _LIBCPP_VISIBLE moneypunct
2843 : public locale::facet,
2847 typedef _CharT char_type;
2848 typedef basic_string<char_type> string_type;
2850 _LIBCPP_ALWAYS_INLINE
2851 explicit moneypunct(size_t __refs = 0)
2852 : locale::facet(__refs) {}
2854 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2855 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2856 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2857 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2858 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2859 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2860 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2861 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2862 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2864 static locale::id id;
2865 static const bool intl = _International;
2868 _LIBCPP_ALWAYS_INLINE
2871 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2872 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2873 virtual string do_grouping() const {return string();}
2874 virtual string_type do_curr_symbol() const {return string_type();}
2875 virtual string_type do_positive_sign() const {return string_type();}
2876 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2877 virtual int do_frac_digits() const {return 0;}
2878 virtual pattern do_pos_format() const
2879 {pattern __p = {symbol, sign, none, value}; return __p;}
2880 virtual pattern do_neg_format() const
2881 {pattern __p = {symbol, sign, none, value}; return __p;}
2884 template <class _CharT, bool _International>
2886 moneypunct<_CharT, _International>::id;
2888 extern template class moneypunct<char, false>;
2889 extern template class moneypunct<char, true>;
2890 extern template class moneypunct<wchar_t, false>;
2891 extern template class moneypunct<wchar_t, true>;
2893 // moneypunct_byname
2895 template <class _CharT, bool _International = false>
2896 class _LIBCPP_VISIBLE moneypunct_byname
2897 : public moneypunct<_CharT, _International>
2900 typedef money_base::pattern pattern;
2901 typedef _CharT char_type;
2902 typedef basic_string<char_type> string_type;
2904 _LIBCPP_ALWAYS_INLINE
2905 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2906 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2908 _LIBCPP_ALWAYS_INLINE
2909 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2910 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2913 _LIBCPP_ALWAYS_INLINE
2914 ~moneypunct_byname() {}
2916 virtual char_type do_decimal_point() const {return __decimal_point_;}
2917 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2918 virtual string do_grouping() const {return __grouping_;}
2919 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2920 virtual string_type do_positive_sign() const {return __positive_sign_;}
2921 virtual string_type do_negative_sign() const {return __negative_sign_;}
2922 virtual int do_frac_digits() const {return __frac_digits_;}
2923 virtual pattern do_pos_format() const {return __pos_format_;}
2924 virtual pattern do_neg_format() const {return __neg_format_;}
2927 char_type __decimal_point_;
2928 char_type __thousands_sep_;
2930 string_type __curr_symbol_;
2931 string_type __positive_sign_;
2932 string_type __negative_sign_;
2934 pattern __pos_format_;
2935 pattern __neg_format_;
2937 void init(const char*);
2940 template<> void moneypunct_byname<char, false>::init(const char*);
2941 template<> void moneypunct_byname<char, true>::init(const char*);
2942 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2943 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2945 extern template class moneypunct_byname<char, false>;
2946 extern template class moneypunct_byname<char, true>;
2947 extern template class moneypunct_byname<wchar_t, false>;
2948 extern template class moneypunct_byname<wchar_t, true>;
2952 template <class _CharT>
2956 typedef _CharT char_type;
2957 typedef basic_string<char_type> string_type;
2959 _LIBCPP_ALWAYS_INLINE __money_get() {}
2961 static void __gather_info(bool __intl, const locale& __loc,
2962 money_base::pattern& __pat, char_type& __dp,
2963 char_type& __ts, string& __grp,
2964 string_type& __sym, string_type& __psn,
2965 string_type& __nsn, int& __fd);
2968 template <class _CharT>
2970 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2971 money_base::pattern& __pat, char_type& __dp,
2972 char_type& __ts, string& __grp,
2973 string_type& __sym, string_type& __psn,
2974 string_type& __nsn, int& __fd)
2978 const moneypunct<char_type, true>& __mp =
2979 use_facet<moneypunct<char_type, true> >(__loc);
2980 __pat = __mp.neg_format();
2981 __nsn = __mp.negative_sign();
2982 __psn = __mp.positive_sign();
2983 __dp = __mp.decimal_point();
2984 __ts = __mp.thousands_sep();
2985 __grp = __mp.grouping();
2986 __sym = __mp.curr_symbol();
2987 __fd = __mp.frac_digits();
2991 const moneypunct<char_type, false>& __mp =
2992 use_facet<moneypunct<char_type, false> >(__loc);
2993 __pat = __mp.neg_format();
2994 __nsn = __mp.negative_sign();
2995 __psn = __mp.positive_sign();
2996 __dp = __mp.decimal_point();
2997 __ts = __mp.thousands_sep();
2998 __grp = __mp.grouping();
2999 __sym = __mp.curr_symbol();
3000 __fd = __mp.frac_digits();
3004 extern template class __money_get<char>;
3005 extern template class __money_get<wchar_t>;
3007 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
3008 class _LIBCPP_VISIBLE money_get
3009 : public locale::facet,
3010 private __money_get<_CharT>
3013 typedef _CharT char_type;
3014 typedef _InputIterator iter_type;
3015 typedef basic_string<char_type> string_type;
3017 _LIBCPP_ALWAYS_INLINE
3018 explicit money_get(size_t __refs = 0)
3019 : locale::facet(__refs) {}
3021 _LIBCPP_ALWAYS_INLINE
3022 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
3023 ios_base::iostate& __err, long double& __v) const
3025 return do_get(__b, __e, __intl, __iob, __err, __v);
3028 _LIBCPP_ALWAYS_INLINE
3029 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
3030 ios_base::iostate& __err, string_type& __v) const
3032 return do_get(__b, __e, __intl, __iob, __err, __v);
3035 static locale::id id;
3039 _LIBCPP_ALWAYS_INLINE
3042 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3043 ios_base& __iob, ios_base::iostate& __err,
3044 long double& __v) const;
3045 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3046 ios_base& __iob, ios_base::iostate& __err,
3047 string_type& __v) const;
3050 static bool __do_get(iter_type& __b, iter_type __e,
3051 bool __intl, const locale& __loc,
3052 ios_base::fmtflags __flags, ios_base::iostate& __err,
3053 bool& __neg, const ctype<char_type>& __ct,
3054 unique_ptr<char_type, void(*)(void*)>& __wb,
3055 char_type*& __wn, char_type* __we);
3058 template <class _CharT, class _InputIterator>
3060 money_get<_CharT, _InputIterator>::id;
3062 void __do_nothing(void*);
3064 template <class _Tp>
3067 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
3069 bool __owns = __b.get_deleter() != __do_nothing;
3070 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
3071 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
3072 2 * __cur_cap : numeric_limits<size_t>::max();
3073 size_t __n_off = static_cast<size_t>(__n - __b.get());
3074 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
3076 __throw_bad_alloc();
3079 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
3080 __new_cap /= sizeof(_Tp);
3081 __n = __b.get() + __n_off;
3082 __e = __b.get() + __new_cap;
3086 template <class _CharT, class _InputIterator>
3088 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
3089 bool __intl, const locale& __loc,
3090 ios_base::fmtflags __flags,
3091 ios_base::iostate& __err,
3093 const ctype<char_type>& __ct,
3094 unique_ptr<char_type, void(*)(void*)>& __wb,
3095 char_type*& __wn, char_type* __we)
3097 const unsigned __bz = 100;
3098 unsigned __gbuf[__bz];
3099 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3100 unsigned* __gn = __gb.get();
3101 unsigned* __ge = __gn + __bz;
3102 money_base::pattern __pat;
3109 // Capture the spaces read into money_base::{space,none} so they
3110 // can be compared to initial spaces in __sym.
3111 string_type __spaces;
3113 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3114 __sym, __psn, __nsn, __fd);
3115 const string_type* __trailing_sign = 0;
3117 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3119 switch (__pat.field[__p])
3121 case money_base::space:
3124 if (__ct.is(ctype_base::space, *__b))
3125 __spaces.push_back(*__b++);
3128 __err |= ios_base::failbit;
3133 case money_base::none:
3136 while (__b != __e && __ct.is(ctype_base::space, *__b))
3137 __spaces.push_back(*__b++);
3140 case money_base::sign:
3141 if (__psn.size() + __nsn.size() > 0)
3143 if (__psn.size() == 0 || __nsn.size() == 0)
3144 { // sign is optional
3145 if (__psn.size() > 0)
3146 { // __nsn.size() == 0
3147 if (*__b == __psn[0])
3150 if (__psn.size() > 1)
3151 __trailing_sign = &__psn;
3156 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
3160 if (__nsn.size() > 1)
3161 __trailing_sign = &__nsn;
3164 else // sign is required
3166 if (*__b == __psn[0])
3169 if (__psn.size() > 1)
3170 __trailing_sign = &__psn;
3172 else if (*__b == __nsn[0])
3176 if (__nsn.size() > 1)
3177 __trailing_sign = &__nsn;
3181 __err |= ios_base::failbit;
3187 case money_base::symbol:
3189 bool __more_needed = __trailing_sign ||
3191 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
3192 bool __sb = __flags & ios_base::showbase;
3193 if (__sb || __more_needed)
3195 ios_base::iostate __et = ios_base::goodbit;
3196 typename string_type::const_iterator __sym_space_end = __sym.begin();
3197 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3198 __pat.field[__p - 1] == money_base::space)) {
3199 // Match spaces we've already read against spaces at
3200 // the beginning of __sym.
3201 while (__sym_space_end != __sym.end() &&
3202 __ct.is(ctype_base::space, *__sym_space_end))
3204 const size_t __num_spaces = __sym_space_end - __sym.begin();
3205 if (__num_spaces > __spaces.size() ||
3206 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3208 // No match. Put __sym_space_end back at the
3209 // beginning of __sym, which will prevent a
3210 // match in the next loop.
3211 __sym_space_end = __sym.begin();
3214 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3215 while (__sym_curr_char != __sym.end() && __b != __e &&
3216 *__b == *__sym_curr_char) {
3220 if (__sb && __sym_curr_char != __sym.end())
3222 __err |= ios_base::failbit;
3228 case money_base::value:
3231 for (; __b != __e; ++__b)
3233 char_type __c = *__b;
3234 if (__ct.is(ctype_base::digit, __c))
3237 __double_or_nothing(__wb, __wn, __we);
3241 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3244 __double_or_nothing(__gb, __gn, __ge);
3251 if (__gb.get() != __gn && __ng > 0)
3254 __double_or_nothing(__gb, __gn, __ge);
3259 if (__b == __e || *__b != __dp)
3261 __err |= ios_base::failbit;
3264 for (++__b; __fd > 0; --__fd, ++__b)
3266 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3268 __err |= ios_base::failbit;
3272 __double_or_nothing(__wb, __wn, __we);
3276 if (__wn == __wb.get())
3278 __err |= ios_base::failbit;
3285 if (__trailing_sign)
3287 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3289 if (__b == __e || *__b != (*__trailing_sign)[__i])
3291 __err |= ios_base::failbit;
3296 if (__gb.get() != __gn)
3298 ios_base::iostate __et = ios_base::goodbit;
3299 __check_grouping(__grp, __gb.get(), __gn, __et);
3302 __err |= ios_base::failbit;
3309 template <class _CharT, class _InputIterator>
3311 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3312 bool __intl, ios_base& __iob,
3313 ios_base::iostate& __err,
3314 long double& __v) const
3316 const int __bz = 100;
3317 char_type __wbuf[__bz];
3318 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3320 char_type* __we = __wbuf + __bz;
3321 locale __loc = __iob.getloc();
3322 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3324 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3327 const char __src[] = "0123456789";
3328 char_type __atoms[sizeof(__src)-1];
3329 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3331 char* __nc = __nbuf;
3332 unique_ptr<char, void(*)(void*)> __h(0, free);
3333 if (__wn - __wb.get() > __bz-2)
3335 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3337 __throw_bad_alloc();
3342 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3343 *__nc = __src[find(__atoms, __atoms+sizeof(__atoms), *__w) - __atoms];
3345 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3346 __throw_runtime_error("money_get error");
3349 __err |= ios_base::eofbit;
3353 template <class _CharT, class _InputIterator>
3355 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3356 bool __intl, ios_base& __iob,
3357 ios_base::iostate& __err,
3358 string_type& __v) const
3360 const int __bz = 100;
3361 char_type __wbuf[__bz];
3362 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3364 char_type* __we = __wbuf + __bz;
3365 locale __loc = __iob.getloc();
3366 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3368 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3373 __v.push_back(__ct.widen('-'));
3374 char_type __z = __ct.widen('0');
3376 for (__w = __wb.get(); __w < __wn-1; ++__w)
3379 __v.append(__w, __wn);
3382 __err |= ios_base::eofbit;
3386 extern template class money_get<char>;
3387 extern template class money_get<wchar_t>;
3391 template <class _CharT>
3395 typedef _CharT char_type;
3396 typedef basic_string<char_type> string_type;
3398 _LIBCPP_ALWAYS_INLINE __money_put() {}
3400 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3401 money_base::pattern& __pat, char_type& __dp,
3402 char_type& __ts, string& __grp,
3403 string_type& __sym, string_type& __sn,
3405 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3406 ios_base::fmtflags __flags,
3407 const char_type* __db, const char_type* __de,
3408 const ctype<char_type>& __ct, bool __neg,
3409 const money_base::pattern& __pat, char_type __dp,
3410 char_type __ts, const string& __grp,
3411 const string_type& __sym, const string_type& __sn,
3415 template <class _CharT>
3417 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3418 money_base::pattern& __pat, char_type& __dp,
3419 char_type& __ts, string& __grp,
3420 string_type& __sym, string_type& __sn,
3425 const moneypunct<char_type, true>& __mp =
3426 use_facet<moneypunct<char_type, true> >(__loc);
3429 __pat = __mp.neg_format();
3430 __sn = __mp.negative_sign();
3434 __pat = __mp.pos_format();
3435 __sn = __mp.positive_sign();
3437 __dp = __mp.decimal_point();
3438 __ts = __mp.thousands_sep();
3439 __grp = __mp.grouping();
3440 __sym = __mp.curr_symbol();
3441 __fd = __mp.frac_digits();
3445 const moneypunct<char_type, false>& __mp =
3446 use_facet<moneypunct<char_type, false> >(__loc);
3449 __pat = __mp.neg_format();
3450 __sn = __mp.negative_sign();
3454 __pat = __mp.pos_format();
3455 __sn = __mp.positive_sign();
3457 __dp = __mp.decimal_point();
3458 __ts = __mp.thousands_sep();
3459 __grp = __mp.grouping();
3460 __sym = __mp.curr_symbol();
3461 __fd = __mp.frac_digits();
3465 template <class _CharT>
3467 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3468 ios_base::fmtflags __flags,
3469 const char_type* __db, const char_type* __de,
3470 const ctype<char_type>& __ct, bool __neg,
3471 const money_base::pattern& __pat, char_type __dp,
3472 char_type __ts, const string& __grp,
3473 const string_type& __sym, const string_type& __sn,
3477 for (unsigned __p = 0; __p < 4; ++__p)
3479 switch (__pat.field[__p])
3481 case money_base::none:
3484 case money_base::space:
3486 *__me++ = __ct.widen(' ');
3488 case money_base::sign:
3492 case money_base::symbol:
3493 if (!__sym.empty() && (__flags & ios_base::showbase))
3494 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3496 case money_base::value:
3498 // remember start of value so we can reverse it
3499 char_type* __t = __me;
3500 // find beginning of digits
3503 // find end of digits
3504 const char_type* __d;
3505 for (__d = __db; __d < __de; ++__d)
3506 if (!__ct.is(ctype_base::digit, *__d))
3508 // print fractional part
3512 for (__f = __fd; __d > __db && __f > 0; --__f)
3514 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3515 for (; __f > 0; --__f)
3522 *__me++ = __ct.widen('0');
3528 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3529 : static_cast<unsigned>(__grp[__ig]);
3536 if (++__ig < __grp.size())
3537 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3538 numeric_limits<unsigned>::max() :
3539 static_cast<unsigned>(__grp[__ig]);
3551 // print rest of sign, if any
3552 if (__sn.size() > 1)
3553 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3555 if ((__flags & ios_base::adjustfield) == ios_base::left)
3557 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3561 extern template class __money_put<char>;
3562 extern template class __money_put<wchar_t>;
3564 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3565 class _LIBCPP_VISIBLE money_put
3566 : public locale::facet,
3567 private __money_put<_CharT>
3570 typedef _CharT char_type;
3571 typedef _OutputIterator iter_type;
3572 typedef basic_string<char_type> string_type;
3574 _LIBCPP_ALWAYS_INLINE
3575 explicit money_put(size_t __refs = 0)
3576 : locale::facet(__refs) {}
3578 _LIBCPP_ALWAYS_INLINE
3579 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3580 long double __units) const
3582 return do_put(__s, __intl, __iob, __fl, __units);
3585 _LIBCPP_ALWAYS_INLINE
3586 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3587 const string_type& __digits) const
3589 return do_put(__s, __intl, __iob, __fl, __digits);
3592 static locale::id id;
3595 _LIBCPP_ALWAYS_INLINE
3598 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3599 char_type __fl, long double __units) const;
3600 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3601 char_type __fl, const string_type& __digits) const;
3604 template <class _CharT, class _OutputIterator>
3606 money_put<_CharT, _OutputIterator>::id;
3608 template <class _CharT, class _OutputIterator>
3610 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3611 ios_base& __iob, char_type __fl,
3612 long double __units) const
3615 const size_t __bs = 100;
3618 char_type __digits[__bs];
3619 char_type* __db = __digits;
3620 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3621 unique_ptr<char, void(*)(void*)> __hn(0, free);
3622 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3623 // secure memory for digit storage
3626 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
3627 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3629 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
3632 __throw_bad_alloc();
3634 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3635 if (__hd == nullptr)
3636 __throw_bad_alloc();
3640 locale __loc = __iob.getloc();
3641 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3642 __ct.widen(__bb, __bb + __n, __db);
3643 bool __neg = __n > 0 && __bb[0] == '-';
3644 money_base::pattern __pat;
3651 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3652 // secure memory for formatting
3653 char_type __mbuf[__bs];
3654 char_type* __mb = __mbuf;
3655 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3656 size_t __exn = static_cast<int>(__n) > __fd ?
3657 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3658 __sym.size() + static_cast<size_t>(__fd) + 1
3659 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3662 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3665 __throw_bad_alloc();
3670 this->__format(__mb, __mi, __me, __iob.flags(),
3671 __db, __db + __n, __ct,
3672 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3673 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3676 template <class _CharT, class _OutputIterator>
3678 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3679 ios_base& __iob, char_type __fl,
3680 const string_type& __digits) const
3683 locale __loc = __iob.getloc();
3684 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3685 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3686 money_base::pattern __pat;
3693 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3694 // secure memory for formatting
3695 char_type __mbuf[100];
3696 char_type* __mb = __mbuf;
3697 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3698 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3699 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3700 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3701 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3704 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3707 __throw_bad_alloc();
3712 this->__format(__mb, __mi, __me, __iob.flags(),
3713 __digits.data(), __digits.data() + __digits.size(), __ct,
3714 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3715 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3718 extern template class money_put<char>;
3719 extern template class money_put<wchar_t>;
3723 class _LIBCPP_VISIBLE messages_base
3726 typedef ptrdiff_t catalog;
3728 _LIBCPP_ALWAYS_INLINE messages_base() {}
3731 template <class _CharT>
3732 class _LIBCPP_VISIBLE messages
3733 : public locale::facet,
3734 public messages_base
3737 typedef _CharT char_type;
3738 typedef basic_string<_CharT> string_type;
3740 _LIBCPP_ALWAYS_INLINE
3741 explicit messages(size_t __refs = 0)
3742 : locale::facet(__refs) {}
3744 _LIBCPP_ALWAYS_INLINE
3745 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3747 return do_open(__nm, __loc);
3750 _LIBCPP_ALWAYS_INLINE
3751 string_type get(catalog __c, int __set, int __msgid,
3752 const string_type& __dflt) const
3754 return do_get(__c, __set, __msgid, __dflt);
3757 _LIBCPP_ALWAYS_INLINE
3758 void close(catalog __c) const
3763 static locale::id id;
3766 _LIBCPP_ALWAYS_INLINE
3769 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3770 virtual string_type do_get(catalog, int __set, int __msgid,
3771 const string_type& __dflt) const;
3772 virtual void do_close(catalog) const;
3775 template <class _CharT>
3777 messages<_CharT>::id;
3779 template <class _CharT>
3780 typename messages<_CharT>::catalog
3781 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3786 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3788 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3793 template <class _CharT>
3794 typename messages<_CharT>::string_type
3795 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3796 const string_type& __dflt) const
3802 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3804 __dflt.c_str() + __dflt.size());
3807 nl_catd __cat = (nl_catd)__c;
3808 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3810 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3811 __n, __n + strlen(__n));
3816 template <class _CharT>
3818 messages<_CharT>::do_close(catalog __c) const
3823 nl_catd __cat = (nl_catd)__c;
3828 extern template class messages<char>;
3829 extern template class messages<wchar_t>;
3831 template <class _CharT>
3832 class _LIBCPP_VISIBLE messages_byname
3833 : public messages<_CharT>
3836 typedef messages_base::catalog catalog;
3837 typedef basic_string<_CharT> string_type;
3839 _LIBCPP_ALWAYS_INLINE
3840 explicit messages_byname(const char*, size_t __refs = 0)
3841 : messages<_CharT>(__refs) {}
3843 _LIBCPP_ALWAYS_INLINE
3844 explicit messages_byname(const string&, size_t __refs = 0)
3845 : messages<_CharT>(__refs) {}
3848 _LIBCPP_ALWAYS_INLINE
3849 ~messages_byname() {}
3852 extern template class messages_byname<char>;
3853 extern template class messages_byname<wchar_t>;
3855 template<class _Codecvt, class _Elem = wchar_t,
3856 class _Wide_alloc = allocator<_Elem>,
3857 class _Byte_alloc = allocator<char> >
3858 class _LIBCPP_VISIBLE wstring_convert
3861 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3862 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3863 typedef typename _Codecvt::state_type state_type;
3864 typedef typename wide_string::traits_type::int_type int_type;
3867 byte_string __byte_err_string_;
3868 wide_string __wide_err_string_;
3869 _Codecvt* __cvtptr_;
3870 state_type __cvtstate_;
3873 wstring_convert(const wstring_convert& __wc);
3874 wstring_convert& operator=(const wstring_convert& __wc);
3876 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3877 wstring_convert(_Codecvt* __pcvt, state_type __state);
3878 wstring_convert(const byte_string& __byte_err,
3879 const wide_string& __wide_err = wide_string());
3880 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3881 wstring_convert(wstring_convert&& __wc);
3885 _LIBCPP_ALWAYS_INLINE
3886 wide_string from_bytes(char __byte)
3887 {return from_bytes(&__byte, &__byte+1);}
3888 _LIBCPP_ALWAYS_INLINE
3889 wide_string from_bytes(const char* __ptr)
3890 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3891 _LIBCPP_ALWAYS_INLINE
3892 wide_string from_bytes(const byte_string& __str)
3893 {return from_bytes(__str.data(), __str.data() + __str.size());}
3894 wide_string from_bytes(const char* __first, const char* __last);
3896 _LIBCPP_ALWAYS_INLINE
3897 byte_string to_bytes(_Elem __wchar)
3898 {return to_bytes(&__wchar, &__wchar+1);}
3899 _LIBCPP_ALWAYS_INLINE
3900 byte_string to_bytes(const _Elem* __wptr)
3901 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3902 _LIBCPP_ALWAYS_INLINE
3903 byte_string to_bytes(const wide_string& __wstr)
3904 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3905 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3907 _LIBCPP_ALWAYS_INLINE
3908 size_t converted() const {return __cvtcount_;}
3909 _LIBCPP_ALWAYS_INLINE
3910 state_type state() const {return __cvtstate_;}
3913 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3914 inline _LIBCPP_ALWAYS_INLINE
3915 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3916 wstring_convert(_Codecvt* __pcvt)
3917 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3921 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3922 inline _LIBCPP_ALWAYS_INLINE
3923 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3924 wstring_convert(_Codecvt* __pcvt, state_type __state)
3925 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3929 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3930 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3931 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3932 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3933 __cvtstate_(), __cvtcount_(0)
3935 __cvtptr_ = new _Codecvt;
3938 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3940 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3941 inline _LIBCPP_ALWAYS_INLINE
3942 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3943 wstring_convert(wstring_convert&& __wc)
3944 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3945 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3946 __cvtptr_(__wc.__cvtptr_),
3947 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
3949 __wc.__cvtptr_ = nullptr;
3952 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3954 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3955 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3960 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3961 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3962 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3963 from_bytes(const char* __frm, const char* __frm_end)
3966 if (__cvtptr_ != nullptr)
3968 wide_string __ws(2*(__frm_end - __frm), _Elem());
3969 if (__frm != __frm_end)
3970 __ws.resize(__ws.capacity());
3971 codecvt_base::result __r = codecvt_base::ok;
3972 state_type __st = __cvtstate_;
3973 if (__frm != __frm_end)
3975 _Elem* __to = &__ws[0];
3976 _Elem* __to_end = __to + __ws.size();
3977 const char* __frm_nxt;
3981 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3982 __to, __to_end, __to_nxt);
3983 __cvtcount_ += __frm_nxt - __frm;
3984 if (__frm_nxt == __frm)
3986 __r = codecvt_base::error;
3988 else if (__r == codecvt_base::noconv)
3990 __ws.resize(__to - &__ws[0]);
3991 // This only gets executed if _Elem is char
3992 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3994 __r = codecvt_base::ok;
3996 else if (__r == codecvt_base::ok)
3998 __ws.resize(__to_nxt - &__ws[0]);
4001 else if (__r == codecvt_base::partial)
4003 ptrdiff_t __s = __to_nxt - &__ws[0];
4004 __ws.resize(2 * __s);
4005 __to = &__ws[0] + __s;
4006 __to_end = &__ws[0] + __ws.size();
4009 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4011 if (__r == codecvt_base::ok)
4014 #ifndef _LIBCPP_NO_EXCEPTIONS
4015 if (__wide_err_string_.empty())
4016 throw range_error("wstring_convert: from_bytes error");
4017 #endif // _LIBCPP_NO_EXCEPTIONS
4018 return __wide_err_string_;
4021 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4022 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
4023 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4024 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
4027 if (__cvtptr_ != nullptr)
4029 byte_string __bs(2*(__frm_end - __frm), char());
4030 if (__frm != __frm_end)
4031 __bs.resize(__bs.capacity());
4032 codecvt_base::result __r = codecvt_base::ok;
4033 state_type __st = __cvtstate_;
4034 if (__frm != __frm_end)
4036 char* __to = &__bs[0];
4037 char* __to_end = __to + __bs.size();
4038 const _Elem* __frm_nxt;
4042 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
4043 __to, __to_end, __to_nxt);
4044 __cvtcount_ += __frm_nxt - __frm;
4045 if (__frm_nxt == __frm)
4047 __r = codecvt_base::error;
4049 else if (__r == codecvt_base::noconv)
4051 __bs.resize(__to - &__bs[0]);
4052 // This only gets executed if _Elem is char
4053 __bs.append((const char*)__frm, (const char*)__frm_end);
4055 __r = codecvt_base::ok;
4057 else if (__r == codecvt_base::ok)
4059 __bs.resize(__to_nxt - &__bs[0]);
4062 else if (__r == codecvt_base::partial)
4064 ptrdiff_t __s = __to_nxt - &__bs[0];
4065 __bs.resize(2 * __s);
4066 __to = &__bs[0] + __s;
4067 __to_end = &__bs[0] + __bs.size();
4070 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4072 if (__r == codecvt_base::ok)
4074 size_t __s = __bs.size();
4075 __bs.resize(__bs.capacity());
4076 char* __to = &__bs[0] + __s;
4077 char* __to_end = __to + __bs.size();
4081 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
4082 if (__r == codecvt_base::noconv)
4084 __bs.resize(__to - &__bs[0]);
4085 __r = codecvt_base::ok;
4087 else if (__r == codecvt_base::ok)
4089 __bs.resize(__to_nxt - &__bs[0]);
4091 else if (__r == codecvt_base::partial)
4093 ptrdiff_t __sp = __to_nxt - &__bs[0];
4094 __bs.resize(2 * __sp);
4095 __to = &__bs[0] + __sp;
4096 __to_end = &__bs[0] + __bs.size();
4098 } while (__r == codecvt_base::partial);
4099 if (__r == codecvt_base::ok)
4103 #ifndef _LIBCPP_NO_EXCEPTIONS
4104 if (__byte_err_string_.empty())
4105 throw range_error("wstring_convert: to_bytes error");
4106 #endif // _LIBCPP_NO_EXCEPTIONS
4107 return __byte_err_string_;
4110 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
4111 class _LIBCPP_VISIBLE wbuffer_convert
4112 : public basic_streambuf<_Elem, _Tr>
4116 typedef _Elem char_type;
4117 typedef _Tr traits_type;
4118 typedef typename traits_type::int_type int_type;
4119 typedef typename traits_type::pos_type pos_type;
4120 typedef typename traits_type::off_type off_type;
4121 typedef typename _Codecvt::state_type state_type;
4125 const char* __extbufnext_;
4126 const char* __extbufend_;
4127 char __extbuf_min_[8];
4129 char_type* __intbuf_;
4131 streambuf* __bufptr_;
4134 ios_base::openmode __cm_;
4137 bool __always_noconv_;
4139 wbuffer_convert(const wbuffer_convert&);
4140 wbuffer_convert& operator=(const wbuffer_convert&);
4142 wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
4143 state_type __state = state_type());
4146 _LIBCPP_INLINE_VISIBILITY
4147 streambuf* rdbuf() const {return __bufptr_;}
4148 _LIBCPP_INLINE_VISIBILITY
4149 streambuf* rdbuf(streambuf* __bytebuf)
4151 streambuf* __r = __bufptr_;
4152 __bufptr_ = __bytebuf;
4156 _LIBCPP_INLINE_VISIBILITY
4157 state_type state() const {return __st_;}
4160 virtual int_type underflow();
4161 virtual int_type pbackfail(int_type __c = traits_type::eof());
4162 virtual int_type overflow (int_type __c = traits_type::eof());
4163 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4165 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4166 ios_base::openmode __wch = ios_base::in | ios_base::out);
4167 virtual pos_type seekpos(pos_type __sp,
4168 ios_base::openmode __wch = ios_base::in | ios_base::out);
4173 void __write_mode();
4174 wbuffer_convert* __close();
4177 template <class _Codecvt, class _Elem, class _Tr>
4178 wbuffer_convert<_Codecvt, _Elem, _Tr>::
4179 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4186 __bufptr_(__bytebuf),
4192 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4197 template <class _Codecvt, class _Elem, class _Tr>
4198 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4203 delete [] __extbuf_;
4205 delete [] __intbuf_;
4208 template <class _Codecvt, class _Elem, class _Tr>
4209 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4210 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4212 if (__cv_ == 0 || __bufptr_ == 0)
4213 return traits_type::eof();
4214 bool __initial = __read_mode();
4216 if (this->gptr() == 0)
4217 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4218 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4219 int_type __c = traits_type::eof();
4220 if (this->gptr() == this->egptr())
4222 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4223 if (__always_noconv_)
4225 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4226 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4229 this->setg(this->eback(),
4230 this->eback() + __unget_sz,
4231 this->eback() + __unget_sz + __nmemb);
4232 __c = *this->gptr();
4237 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4238 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4239 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
4240 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
4241 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4242 codecvt_base::result __r;
4243 state_type __svs = __st_;
4244 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4247 __extbufend_ = __extbufnext_ + __nr;
4249 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4250 this->eback() + __unget_sz,
4251 this->egptr(), __inext);
4252 if (__r == codecvt_base::noconv)
4254 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4255 __c = *this->gptr();
4257 else if (__inext != this->eback() + __unget_sz)
4259 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4260 __c = *this->gptr();
4266 __c = *this->gptr();
4267 if (this->eback() == &__1buf)
4268 this->setg(0, 0, 0);
4272 template <class _Codecvt, class _Elem, class _Tr>
4273 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4274 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4276 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4278 if (traits_type::eq_int_type(__c, traits_type::eof()))
4281 return traits_type::not_eof(__c);
4283 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4286 *this->gptr() = traits_type::to_char_type(__c);
4290 return traits_type::eof();
4293 template <class _Codecvt, class _Elem, class _Tr>
4294 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4295 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4297 if (__cv_ == 0 || __bufptr_ == 0)
4298 return traits_type::eof();
4301 char_type* __pb_save = this->pbase();
4302 char_type* __epb_save = this->epptr();
4303 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4305 if (this->pptr() == 0)
4306 this->setp(&__1buf, &__1buf+1);
4307 *this->pptr() = traits_type::to_char_type(__c);
4310 if (this->pptr() != this->pbase())
4312 if (__always_noconv_)
4314 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4315 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4316 return traits_type::eof();
4320 char* __extbe = __extbuf_;
4321 codecvt_base::result __r;
4324 const char_type* __e;
4325 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4326 __extbuf_, __extbuf_ + __ebs_, __extbe);
4327 if (__e == this->pbase())
4328 return traits_type::eof();
4329 if (__r == codecvt_base::noconv)
4331 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4332 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4333 return traits_type::eof();
4335 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4337 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4338 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4339 return traits_type::eof();
4340 if (__r == codecvt_base::partial)
4342 this->setp((char_type*)__e, this->pptr());
4343 this->pbump(this->epptr() - this->pbase());
4347 return traits_type::eof();
4348 } while (__r == codecvt_base::partial);
4350 this->setp(__pb_save, __epb_save);
4352 return traits_type::not_eof(__c);
4355 template <class _Codecvt, class _Elem, class _Tr>
4356 basic_streambuf<_Elem, _Tr>*
4357 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4359 this->setg(0, 0, 0);
4362 delete [] __extbuf_;
4364 delete [] __intbuf_;
4366 if (__ebs_ > sizeof(__extbuf_min_))
4368 if (__always_noconv_ && __s)
4370 __extbuf_ = (char*)__s;
4375 __extbuf_ = new char[__ebs_];
4381 __extbuf_ = __extbuf_min_;
4382 __ebs_ = sizeof(__extbuf_min_);
4385 if (!__always_noconv_)
4387 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4388 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4395 __intbuf_ = new char_type[__ibs_];
4408 template <class _Codecvt, class _Elem, class _Tr>
4409 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4410 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4411 ios_base::openmode __om)
4413 int __width = __cv_->encoding();
4414 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4415 return pos_type(off_type(-1));
4416 // __width > 0 || __off == 0
4426 return pos_type(off_type(-1));
4428 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4433 template <class _Codecvt, class _Elem, class _Tr>
4434 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4435 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4437 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4438 return pos_type(off_type(-1));
4439 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4440 return pos_type(off_type(-1));
4444 template <class _Codecvt, class _Elem, class _Tr>
4446 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4448 if (__cv_ == 0 || __bufptr_ == 0)
4450 if (__cm_ & ios_base::out)
4452 if (this->pptr() != this->pbase())
4453 if (overflow() == traits_type::eof())
4455 codecvt_base::result __r;
4459 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4460 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4461 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4463 } while (__r == codecvt_base::partial);
4464 if (__r == codecvt_base::error)
4466 if (__bufptr_->pubsync())
4469 else if (__cm_ & ios_base::in)
4472 if (__always_noconv_)
4473 __c = this->egptr() - this->gptr();
4476 int __width = __cv_->encoding();
4477 __c = __extbufend_ - __extbufnext_;
4479 __c += __width * (this->egptr() - this->gptr());
4482 if (this->gptr() != this->egptr())
4484 reverse(this->gptr(), this->egptr());
4485 codecvt_base::result __r;
4486 const char_type* __e = this->gptr();
4490 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4491 __extbuf_, __extbuf_ + __ebs_, __extbe);
4494 case codecvt_base::noconv:
4495 __c += this->egptr() - this->gptr();
4497 case codecvt_base::ok:
4498 case codecvt_base::partial:
4499 __c += __extbe - __extbuf_;
4504 } while (__r == codecvt_base::partial);
4508 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4510 this->setg(0, 0, 0);
4516 template <class _Codecvt, class _Elem, class _Tr>
4518 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4520 if (!(__cm_ & ios_base::in))
4523 if (__always_noconv_)
4524 this->setg((char_type*)__extbuf_,
4525 (char_type*)__extbuf_ + __ebs_,
4526 (char_type*)__extbuf_ + __ebs_);
4528 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4529 __cm_ = ios_base::in;
4535 template <class _Codecvt, class _Elem, class _Tr>
4537 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4539 if (!(__cm_ & ios_base::out))
4541 this->setg(0, 0, 0);
4542 if (__ebs_ > sizeof(__extbuf_min_))
4544 if (__always_noconv_)
4545 this->setp((char_type*)__extbuf_,
4546 (char_type*)__extbuf_ + (__ebs_ - 1));
4548 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4552 __cm_ = ios_base::out;
4556 template <class _Codecvt, class _Elem, class _Tr>
4557 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4558 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4560 wbuffer_convert* __rt = 0;
4561 if (__cv_ != 0 && __bufptr_ != 0)
4564 if ((__cm_ & ios_base::out) && sync())
4570 _LIBCPP_END_NAMESPACE_STD
4572 #endif // _LIBCPP_LOCALE