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 _OutputIterator>
1592 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1593 char_type __fl, bool __v) const
1595 if ((__iob.flags() & ios_base::boolalpha) == 0)
1596 return do_put(__s, __iob, __fl, (unsigned long)__v);
1597 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1598 typedef typename numpunct<char_type>::string_type string_type;
1599 string_type __nm = __v ? __np.truename() : __np.falsename();
1600 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1605 template <class _CharT, class _OutputIterator>
1607 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1608 char_type __fl, long __v) const
1610 // Stage 1 - Get number in narrow char
1611 char __fmt[6] = {'%', 0};
1612 const char* __len = "l";
1613 this->__format_int(__fmt+1, __len, true, __iob.flags());
1614 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1615 + ((numeric_limits<long>::digits % 3) != 0)
1618 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1619 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1621 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1623 char* __ne = __nar + __nc;
1624 char* __np = this->__identify_padding(__nar, __ne, __iob);
1625 // Stage 2 - Widen __nar while adding thousands separators
1626 char_type __o[2*(__nbuf-1) - 1];
1627 char_type* __op; // pad here
1628 char_type* __oe; // end of output
1629 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1630 // [__o, __oe) contains thousands_sep'd wide number
1632 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1635 template <class _CharT, class _OutputIterator>
1637 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1638 char_type __fl, long long __v) const
1640 // Stage 1 - Get number in narrow char
1641 char __fmt[8] = {'%', 0};
1642 const char* __len = "ll";
1643 this->__format_int(__fmt+1, __len, true, __iob.flags());
1644 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1645 + ((numeric_limits<long long>::digits % 3) != 0)
1648 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1649 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1651 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1653 char* __ne = __nar + __nc;
1654 char* __np = this->__identify_padding(__nar, __ne, __iob);
1655 // Stage 2 - Widen __nar while adding thousands separators
1656 char_type __o[2*(__nbuf-1) - 1];
1657 char_type* __op; // pad here
1658 char_type* __oe; // end of output
1659 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1660 // [__o, __oe) contains thousands_sep'd wide number
1662 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1665 template <class _CharT, class _OutputIterator>
1667 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1668 char_type __fl, unsigned long __v) const
1670 // Stage 1 - Get number in narrow char
1671 char __fmt[6] = {'%', 0};
1672 const char* __len = "l";
1673 this->__format_int(__fmt+1, __len, false, __iob.flags());
1674 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1675 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1678 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1679 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1681 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1683 char* __ne = __nar + __nc;
1684 char* __np = this->__identify_padding(__nar, __ne, __iob);
1685 // Stage 2 - Widen __nar while adding thousands separators
1686 char_type __o[2*(__nbuf-1) - 1];
1687 char_type* __op; // pad here
1688 char_type* __oe; // end of output
1689 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1690 // [__o, __oe) contains thousands_sep'd wide number
1692 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1695 template <class _CharT, class _OutputIterator>
1697 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1698 char_type __fl, unsigned long long __v) const
1700 // Stage 1 - Get number in narrow char
1701 char __fmt[8] = {'%', 0};
1702 const char* __len = "ll";
1703 this->__format_int(__fmt+1, __len, false, __iob.flags());
1704 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1705 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1708 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1709 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1711 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1713 char* __ne = __nar + __nc;
1714 char* __np = this->__identify_padding(__nar, __ne, __iob);
1715 // Stage 2 - Widen __nar while adding thousands separators
1716 char_type __o[2*(__nbuf-1) - 1];
1717 char_type* __op; // pad here
1718 char_type* __oe; // end of output
1719 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1720 // [__o, __oe) contains thousands_sep'd wide number
1722 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1725 template <class _CharT, class _OutputIterator>
1727 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1728 char_type __fl, double __v) const
1730 // Stage 1 - Get number in narrow char
1731 char __fmt[8] = {'%', 0};
1732 const char* __len = "";
1733 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1734 const unsigned __nbuf = 30;
1738 if (__specify_precision)
1739 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1740 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1741 (int)__iob.precision(), __v);
1743 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1744 (int)__iob.precision(), __v);
1747 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1748 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1750 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1752 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1753 if (__nc > static_cast<int>(__nbuf-1))
1755 if (__specify_precision)
1756 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1757 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1759 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1760 (int)__iob.precision(), __v);
1763 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1764 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1766 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
1769 __throw_bad_alloc();
1772 char* __ne = __nb + __nc;
1773 char* __np = this->__identify_padding(__nb, __ne, __iob);
1774 // Stage 2 - Widen __nar while adding thousands separators
1775 char_type __o[2*(__nbuf-1) - 1];
1776 char_type* __ob = __o;
1777 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1780 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1782 __throw_bad_alloc();
1785 char_type* __op; // pad here
1786 char_type* __oe; // end of output
1787 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1788 // [__o, __oe) contains thousands_sep'd wide number
1790 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1794 template <class _CharT, class _OutputIterator>
1796 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1797 char_type __fl, long double __v) const
1799 // Stage 1 - Get number in narrow char
1800 char __fmt[8] = {'%', 0};
1801 const char* __len = "L";
1802 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1803 const unsigned __nbuf = 30;
1807 if (__specify_precision)
1808 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1809 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1810 (int)__iob.precision(), __v);
1812 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1813 (int)__iob.precision(), __v);
1816 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1817 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1819 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1821 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1822 if (__nc > static_cast<int>(__nbuf-1))
1824 if (__specify_precision)
1825 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1826 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1828 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1829 (int)__iob.precision(), __v);
1832 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1833 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1835 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
1838 __throw_bad_alloc();
1841 char* __ne = __nb + __nc;
1842 char* __np = this->__identify_padding(__nb, __ne, __iob);
1843 // Stage 2 - Widen __nar while adding thousands separators
1844 char_type __o[2*(__nbuf-1) - 1];
1845 char_type* __ob = __o;
1846 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1849 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1851 __throw_bad_alloc();
1854 char_type* __op; // pad here
1855 char_type* __oe; // end of output
1856 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1857 // [__o, __oe) contains thousands_sep'd wide number
1859 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1863 template <class _CharT, class _OutputIterator>
1865 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1866 char_type __fl, const void* __v) const
1868 // Stage 1 - Get pointer in narrow char
1869 char __fmt[6] = "%p";
1870 const unsigned __nbuf = 20;
1872 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1873 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1875 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
1877 char* __ne = __nar + __nc;
1878 char* __np = this->__identify_padding(__nar, __ne, __iob);
1879 // Stage 2 - Widen __nar
1880 char_type __o[2*(__nbuf-1) - 1];
1881 char_type* __op; // pad here
1882 char_type* __oe; // end of output
1883 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1884 __ct.widen(__nar, __ne, __o);
1885 __oe = __o + (__ne - __nar);
1889 __op = __o + (__np - __nar);
1890 // [__o, __oe) contains wide number
1892 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1895 extern template class num_put<char>;
1896 extern template class num_put<wchar_t>;
1898 template <class _CharT, class _InputIterator>
1901 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1902 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1904 // Precondition: __n >= 1
1907 __err |= ios_base::eofbit | ios_base::failbit;
1912 if (!__ct.is(ctype_base::digit, __c))
1914 __err |= ios_base::failbit;
1917 int __r = __ct.narrow(__c, 0) - '0';
1918 for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
1922 if (!__ct.is(ctype_base::digit, __c))
1924 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1927 __err |= ios_base::eofbit;
1931 class _LIBCPP_VISIBLE time_base
1934 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1937 template <class _CharT>
1938 class __time_get_c_storage // purposefully not decorated
1941 typedef basic_string<_CharT> string_type;
1943 virtual const string_type* __weeks() const;
1944 virtual const string_type* __months() const;
1945 virtual const string_type* __am_pm() const;
1946 virtual const string_type& __c() const;
1947 virtual const string_type& __r() const;
1948 virtual const string_type& __x() const;
1949 virtual const string_type& __X() const;
1952 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1953 class _LIBCPP_VISIBLE time_get
1954 : public locale::facet,
1956 private __time_get_c_storage<_CharT>
1959 typedef _CharT char_type;
1960 typedef _InputIterator iter_type;
1961 typedef time_base::dateorder dateorder;
1962 typedef basic_string<char_type> string_type;
1964 _LIBCPP_ALWAYS_INLINE
1965 explicit time_get(size_t __refs = 0)
1966 : locale::facet(__refs) {}
1968 _LIBCPP_ALWAYS_INLINE
1969 dateorder date_order() const
1971 return this->do_date_order();
1974 _LIBCPP_ALWAYS_INLINE
1975 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1976 ios_base::iostate& __err, tm* __tm) const
1978 return do_get_time(__b, __e, __iob, __err, __tm);
1981 _LIBCPP_ALWAYS_INLINE
1982 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1983 ios_base::iostate& __err, tm* __tm) const
1985 return do_get_date(__b, __e, __iob, __err, __tm);
1988 _LIBCPP_ALWAYS_INLINE
1989 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1990 ios_base::iostate& __err, tm* __tm) const
1992 return do_get_weekday(__b, __e, __iob, __err, __tm);
1995 _LIBCPP_ALWAYS_INLINE
1996 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1997 ios_base::iostate& __err, tm* __tm) const
1999 return do_get_monthname(__b, __e, __iob, __err, __tm);
2002 _LIBCPP_ALWAYS_INLINE
2003 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
2004 ios_base::iostate& __err, tm* __tm) const
2006 return do_get_year(__b, __e, __iob, __err, __tm);
2009 _LIBCPP_ALWAYS_INLINE
2010 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2011 ios_base::iostate& __err, tm *__tm,
2012 char __fmt, char __mod = 0) const
2014 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
2017 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2018 ios_base::iostate& __err, tm* __tm,
2019 const char_type* __fmtb, const char_type* __fmte) const;
2021 static locale::id id;
2024 _LIBCPP_ALWAYS_INLINE
2027 virtual dateorder do_date_order() const;
2028 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
2029 ios_base::iostate& __err, tm* __tm) const;
2030 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
2031 ios_base::iostate& __err, tm* __tm) const;
2032 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2033 ios_base::iostate& __err, tm* __tm) const;
2034 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2035 ios_base::iostate& __err, tm* __tm) const;
2036 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
2037 ios_base::iostate& __err, tm* __tm) const;
2038 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
2039 ios_base::iostate& __err, tm* __tm,
2040 char __fmt, char __mod) const;
2042 void __get_white_space(iter_type& __b, iter_type __e,
2043 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
2044 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
2045 const ctype<char_type>& __ct) const;
2047 void __get_weekdayname(int& __m,
2048 iter_type& __b, iter_type __e,
2049 ios_base::iostate& __err,
2050 const ctype<char_type>& __ct) const;
2051 void __get_monthname(int& __m,
2052 iter_type& __b, iter_type __e,
2053 ios_base::iostate& __err,
2054 const ctype<char_type>& __ct) const;
2055 void __get_day(int& __d,
2056 iter_type& __b, iter_type __e,
2057 ios_base::iostate& __err,
2058 const ctype<char_type>& __ct) const;
2059 void __get_month(int& __m,
2060 iter_type& __b, iter_type __e,
2061 ios_base::iostate& __err,
2062 const ctype<char_type>& __ct) const;
2063 void __get_year(int& __y,
2064 iter_type& __b, iter_type __e,
2065 ios_base::iostate& __err,
2066 const ctype<char_type>& __ct) const;
2067 void __get_year4(int& __y,
2068 iter_type& __b, iter_type __e,
2069 ios_base::iostate& __err,
2070 const ctype<char_type>& __ct) const;
2071 void __get_hour(int& __d,
2072 iter_type& __b, iter_type __e,
2073 ios_base::iostate& __err,
2074 const ctype<char_type>& __ct) const;
2075 void __get_12_hour(int& __h,
2076 iter_type& __b, iter_type __e,
2077 ios_base::iostate& __err,
2078 const ctype<char_type>& __ct) const;
2079 void __get_am_pm(int& __h,
2080 iter_type& __b, iter_type __e,
2081 ios_base::iostate& __err,
2082 const ctype<char_type>& __ct) const;
2083 void __get_minute(int& __m,
2084 iter_type& __b, iter_type __e,
2085 ios_base::iostate& __err,
2086 const ctype<char_type>& __ct) const;
2087 void __get_second(int& __s,
2088 iter_type& __b, iter_type __e,
2089 ios_base::iostate& __err,
2090 const ctype<char_type>& __ct) const;
2091 void __get_weekday(int& __w,
2092 iter_type& __b, iter_type __e,
2093 ios_base::iostate& __err,
2094 const ctype<char_type>& __ct) const;
2095 void __get_day_year_num(int& __w,
2096 iter_type& __b, iter_type __e,
2097 ios_base::iostate& __err,
2098 const ctype<char_type>& __ct) const;
2101 template <class _CharT, class _InputIterator>
2103 time_get<_CharT, _InputIterator>::id;
2105 // time_get primatives
2107 template <class _CharT, class _InputIterator>
2109 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2110 iter_type& __b, iter_type __e,
2111 ios_base::iostate& __err,
2112 const ctype<char_type>& __ct) const
2114 // Note: ignoring case comes from the POSIX strptime spec
2115 const string_type* __wk = this->__weeks();
2116 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
2121 template <class _CharT, class _InputIterator>
2123 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2124 iter_type& __b, iter_type __e,
2125 ios_base::iostate& __err,
2126 const ctype<char_type>& __ct) const
2128 // Note: ignoring case comes from the POSIX strptime spec
2129 const string_type* __month = this->__months();
2130 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
2135 template <class _CharT, class _InputIterator>
2137 time_get<_CharT, _InputIterator>::__get_day(int& __d,
2138 iter_type& __b, iter_type __e,
2139 ios_base::iostate& __err,
2140 const ctype<char_type>& __ct) const
2142 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2143 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
2146 __err |= ios_base::failbit;
2149 template <class _CharT, class _InputIterator>
2151 time_get<_CharT, _InputIterator>::__get_month(int& __m,
2152 iter_type& __b, iter_type __e,
2153 ios_base::iostate& __err,
2154 const ctype<char_type>& __ct) const
2156 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
2157 if (!(__err & ios_base::failbit) && __t <= 11)
2160 __err |= ios_base::failbit;
2163 template <class _CharT, class _InputIterator>
2165 time_get<_CharT, _InputIterator>::__get_year(int& __y,
2166 iter_type& __b, iter_type __e,
2167 ios_base::iostate& __err,
2168 const ctype<char_type>& __ct) const
2170 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2171 if (!(__err & ios_base::failbit))
2175 else if (69 <= __t && __t <= 99)
2181 template <class _CharT, class _InputIterator>
2183 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
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, 4);
2189 if (!(__err & ios_base::failbit))
2193 template <class _CharT, class _InputIterator>
2195 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2196 iter_type& __b, iter_type __e,
2197 ios_base::iostate& __err,
2198 const ctype<char_type>& __ct) const
2200 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2201 if (!(__err & ios_base::failbit) && __t <= 23)
2204 __err |= ios_base::failbit;
2207 template <class _CharT, class _InputIterator>
2209 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2210 iter_type& __b, iter_type __e,
2211 ios_base::iostate& __err,
2212 const ctype<char_type>& __ct) const
2214 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2215 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2218 __err |= ios_base::failbit;
2221 template <class _CharT, class _InputIterator>
2223 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2224 iter_type& __b, iter_type __e,
2225 ios_base::iostate& __err,
2226 const ctype<char_type>& __ct) const
2228 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2229 if (!(__err & ios_base::failbit) && __t <= 59)
2232 __err |= ios_base::failbit;
2235 template <class _CharT, class _InputIterator>
2237 time_get<_CharT, _InputIterator>::__get_second(int& __s,
2238 iter_type& __b, iter_type __e,
2239 ios_base::iostate& __err,
2240 const ctype<char_type>& __ct) const
2242 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2243 if (!(__err & ios_base::failbit) && __t <= 60)
2246 __err |= ios_base::failbit;
2249 template <class _CharT, class _InputIterator>
2251 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2252 iter_type& __b, iter_type __e,
2253 ios_base::iostate& __err,
2254 const ctype<char_type>& __ct) const
2256 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2257 if (!(__err & ios_base::failbit) && __t <= 6)
2260 __err |= ios_base::failbit;
2263 template <class _CharT, class _InputIterator>
2265 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2266 iter_type& __b, iter_type __e,
2267 ios_base::iostate& __err,
2268 const ctype<char_type>& __ct) const
2270 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2271 if (!(__err & ios_base::failbit) && __t <= 365)
2274 __err |= ios_base::failbit;
2277 template <class _CharT, class _InputIterator>
2279 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2280 ios_base::iostate& __err,
2281 const ctype<char_type>& __ct) const
2283 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2286 __err |= ios_base::eofbit;
2289 template <class _CharT, class _InputIterator>
2291 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2292 iter_type& __b, iter_type __e,
2293 ios_base::iostate& __err,
2294 const ctype<char_type>& __ct) const
2296 const string_type* __ap = this->__am_pm();
2297 if (__ap[0].size() + __ap[1].size() == 0)
2299 __err |= ios_base::failbit;
2302 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2303 if (__i == 0 && __h == 12)
2305 else if (__i == 1 && __h < 12)
2309 template <class _CharT, class _InputIterator>
2311 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2312 ios_base::iostate& __err,
2313 const ctype<char_type>& __ct) const
2317 __err |= ios_base::eofbit | ios_base::failbit;
2320 if (__ct.narrow(*__b, 0) != '%')
2321 __err |= ios_base::failbit;
2322 else if(++__b == __e)
2323 __err |= ios_base::eofbit;
2326 // time_get end primatives
2328 template <class _CharT, class _InputIterator>
2330 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2332 ios_base::iostate& __err, tm* __tm,
2333 const char_type* __fmtb, const char_type* __fmte) const
2335 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2336 __err = ios_base::goodbit;
2337 while (__fmtb != __fmte && __err == ios_base::goodbit)
2341 __err = ios_base::failbit;
2344 if (__ct.narrow(*__fmtb, 0) == '%')
2346 if (++__fmtb == __fmte)
2348 __err = ios_base::failbit;
2351 char __cmd = __ct.narrow(*__fmtb, 0);
2353 if (__cmd == 'E' || __cmd == '0')
2355 if (++__fmtb == __fmte)
2357 __err = ios_base::failbit;
2361 __cmd = __ct.narrow(*__fmtb, 0);
2363 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2366 else if (__ct.is(ctype_base::space, *__fmtb))
2368 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2370 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2373 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2379 __err = ios_base::failbit;
2382 __err |= ios_base::eofbit;
2386 template <class _CharT, class _InputIterator>
2387 typename time_get<_CharT, _InputIterator>::dateorder
2388 time_get<_CharT, _InputIterator>::do_date_order() const
2393 template <class _CharT, class _InputIterator>
2395 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2397 ios_base::iostate& __err,
2400 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2401 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2404 template <class _CharT, class _InputIterator>
2406 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2408 ios_base::iostate& __err,
2411 const string_type& __fmt = this->__x();
2412 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2415 template <class _CharT, class _InputIterator>
2417 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2419 ios_base::iostate& __err,
2422 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2423 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2427 template <class _CharT, class _InputIterator>
2429 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2431 ios_base::iostate& __err,
2434 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2435 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2439 template <class _CharT, class _InputIterator>
2441 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2443 ios_base::iostate& __err,
2446 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2447 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2451 template <class _CharT, class _InputIterator>
2453 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2455 ios_base::iostate& __err, tm* __tm,
2456 char __fmt, char) const
2458 __err = ios_base::goodbit;
2459 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2464 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2469 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2473 const string_type& __fm = this->__c();
2474 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2479 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2483 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2484 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2489 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2490 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2494 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2497 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2500 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2503 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2506 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2510 __get_white_space(__b, __e, __err, __ct);
2513 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2517 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2518 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2523 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2524 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2528 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2532 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2533 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2537 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2540 return do_get_date(__b, __e, __iob, __err, __tm);
2543 const string_type& __fm = this->__X();
2544 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2548 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2551 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2554 __get_percent(__b, __e, __err, __ct);
2557 __err |= ios_base::failbit;
2562 extern template class time_get<char>;
2563 extern template class time_get<wchar_t>;
2570 __time_get(const char* __nm);
2571 __time_get(const string& __nm);
2575 template <class _CharT>
2576 class __time_get_storage
2580 typedef basic_string<_CharT> string_type;
2582 string_type __weeks_[14];
2583 string_type __months_[24];
2584 string_type __am_pm_[2];
2590 explicit __time_get_storage(const char* __nm);
2591 explicit __time_get_storage(const string& __nm);
2593 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2595 time_base::dateorder __do_date_order() const;
2598 void init(const ctype<_CharT>&);
2599 string_type __analyze(char __fmt, const ctype<_CharT>&);
2602 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2603 class _LIBCPP_VISIBLE time_get_byname
2604 : public time_get<_CharT, _InputIterator>,
2605 private __time_get_storage<_CharT>
2608 typedef time_base::dateorder dateorder;
2609 typedef _InputIterator iter_type;
2610 typedef _CharT char_type;
2611 typedef basic_string<char_type> string_type;
2613 _LIBCPP_INLINE_VISIBILITY
2614 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2615 : time_get<_CharT, _InputIterator>(__refs),
2616 __time_get_storage<_CharT>(__nm) {}
2617 _LIBCPP_INLINE_VISIBILITY
2618 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2619 : time_get<_CharT, _InputIterator>(__refs),
2620 __time_get_storage<_CharT>(__nm) {}
2623 _LIBCPP_INLINE_VISIBILITY
2624 ~time_get_byname() {}
2626 _LIBCPP_INLINE_VISIBILITY
2627 virtual dateorder do_date_order() const {return this->__do_date_order();}
2629 _LIBCPP_INLINE_VISIBILITY
2630 virtual const string_type* __weeks() const {return this->__weeks_;}
2631 _LIBCPP_INLINE_VISIBILITY
2632 virtual const string_type* __months() const {return this->__months_;}
2633 _LIBCPP_INLINE_VISIBILITY
2634 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2635 _LIBCPP_INLINE_VISIBILITY
2636 virtual const string_type& __c() const {return this->__c_;}
2637 _LIBCPP_INLINE_VISIBILITY
2638 virtual const string_type& __r() const {return this->__r_;}
2639 _LIBCPP_INLINE_VISIBILITY
2640 virtual const string_type& __x() const {return this->__x_;}
2641 _LIBCPP_INLINE_VISIBILITY
2642 virtual const string_type& __X() const {return this->__X_;}
2645 extern template class time_get_byname<char>;
2646 extern template class time_get_byname<wchar_t>;
2652 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2653 __time_put(const char* __nm);
2654 __time_put(const string& __nm);
2656 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2657 char __fmt, char __mod) const;
2658 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2659 char __fmt, char __mod) const;
2662 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2663 class _LIBCPP_VISIBLE time_put
2664 : public locale::facet,
2668 typedef _CharT char_type;
2669 typedef _OutputIterator iter_type;
2671 _LIBCPP_ALWAYS_INLINE
2672 explicit time_put(size_t __refs = 0)
2673 : locale::facet(__refs) {}
2675 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2676 const char_type* __pb, const char_type* __pe) const;
2678 _LIBCPP_ALWAYS_INLINE
2679 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2680 const tm* __tm, char __fmt, char __mod = 0) const
2682 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2685 static locale::id id;
2688 _LIBCPP_ALWAYS_INLINE
2690 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2691 char __fmt, char __mod) const;
2693 _LIBCPP_ALWAYS_INLINE
2694 explicit time_put(const char* __nm, size_t __refs)
2695 : locale::facet(__refs),
2697 _LIBCPP_ALWAYS_INLINE
2698 explicit time_put(const string& __nm, size_t __refs)
2699 : locale::facet(__refs),
2703 template <class _CharT, class _OutputIterator>
2705 time_put<_CharT, _OutputIterator>::id;
2707 template <class _CharT, class _OutputIterator>
2709 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2710 char_type __fl, const tm* __tm,
2711 const char_type* __pb,
2712 const char_type* __pe) const
2714 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2715 for (; __pb != __pe; ++__pb)
2717 if (__ct.narrow(*__pb, 0) == '%')
2725 char __fmt = __ct.narrow(*__pb, 0);
2726 if (__fmt == 'E' || __fmt == 'O')
2735 __fmt = __ct.narrow(*__pb, 0);
2737 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2745 template <class _CharT, class _OutputIterator>
2747 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2748 char_type, const tm* __tm,
2749 char __fmt, char __mod) const
2751 char_type __nar[100];
2752 char_type* __nb = __nar;
2753 char_type* __ne = __nb + 100;
2754 __do_put(__nb, __ne, __tm, __fmt, __mod);
2755 return _VSTD::copy(__nb, __ne, __s);
2758 extern template class time_put<char>;
2759 extern template class time_put<wchar_t>;
2761 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2762 class _LIBCPP_VISIBLE time_put_byname
2763 : public time_put<_CharT, _OutputIterator>
2766 _LIBCPP_ALWAYS_INLINE
2767 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2768 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2770 _LIBCPP_ALWAYS_INLINE
2771 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2772 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2775 _LIBCPP_ALWAYS_INLINE
2776 ~time_put_byname() {}
2779 extern template class time_put_byname<char>;
2780 extern template class time_put_byname<wchar_t>;
2784 class _LIBCPP_VISIBLE money_base
2787 enum part {none, space, symbol, sign, value};
2788 struct pattern {char field[4];};
2790 _LIBCPP_ALWAYS_INLINE money_base() {}
2795 template <class _CharT, bool _International = false>
2796 class _LIBCPP_VISIBLE moneypunct
2797 : public locale::facet,
2801 typedef _CharT char_type;
2802 typedef basic_string<char_type> string_type;
2804 _LIBCPP_ALWAYS_INLINE
2805 explicit moneypunct(size_t __refs = 0)
2806 : locale::facet(__refs) {}
2808 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2809 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2810 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2811 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2812 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2813 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2814 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2815 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2816 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2818 static locale::id id;
2819 static const bool intl = _International;
2822 _LIBCPP_ALWAYS_INLINE
2825 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2826 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2827 virtual string do_grouping() const {return string();}
2828 virtual string_type do_curr_symbol() const {return string_type();}
2829 virtual string_type do_positive_sign() const {return string_type();}
2830 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2831 virtual int do_frac_digits() const {return 0;}
2832 virtual pattern do_pos_format() const
2833 {pattern __p = {symbol, sign, none, value}; return __p;}
2834 virtual pattern do_neg_format() const
2835 {pattern __p = {symbol, sign, none, value}; return __p;}
2838 template <class _CharT, bool _International>
2840 moneypunct<_CharT, _International>::id;
2842 extern template class moneypunct<char, false>;
2843 extern template class moneypunct<char, true>;
2844 extern template class moneypunct<wchar_t, false>;
2845 extern template class moneypunct<wchar_t, true>;
2847 // moneypunct_byname
2849 template <class _CharT, bool _International = false>
2850 class _LIBCPP_VISIBLE moneypunct_byname
2851 : public moneypunct<_CharT, _International>
2854 typedef money_base::pattern pattern;
2855 typedef _CharT char_type;
2856 typedef basic_string<char_type> string_type;
2858 _LIBCPP_ALWAYS_INLINE
2859 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2860 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2862 _LIBCPP_ALWAYS_INLINE
2863 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2864 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2867 _LIBCPP_ALWAYS_INLINE
2868 ~moneypunct_byname() {}
2870 virtual char_type do_decimal_point() const {return __decimal_point_;}
2871 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2872 virtual string do_grouping() const {return __grouping_;}
2873 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2874 virtual string_type do_positive_sign() const {return __positive_sign_;}
2875 virtual string_type do_negative_sign() const {return __negative_sign_;}
2876 virtual int do_frac_digits() const {return __frac_digits_;}
2877 virtual pattern do_pos_format() const {return __pos_format_;}
2878 virtual pattern do_neg_format() const {return __neg_format_;}
2881 char_type __decimal_point_;
2882 char_type __thousands_sep_;
2884 string_type __curr_symbol_;
2885 string_type __positive_sign_;
2886 string_type __negative_sign_;
2888 pattern __pos_format_;
2889 pattern __neg_format_;
2891 void init(const char*);
2894 template<> void moneypunct_byname<char, false>::init(const char*);
2895 template<> void moneypunct_byname<char, true>::init(const char*);
2896 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2897 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2899 extern template class moneypunct_byname<char, false>;
2900 extern template class moneypunct_byname<char, true>;
2901 extern template class moneypunct_byname<wchar_t, false>;
2902 extern template class moneypunct_byname<wchar_t, true>;
2906 template <class _CharT>
2910 typedef _CharT char_type;
2911 typedef basic_string<char_type> string_type;
2913 _LIBCPP_ALWAYS_INLINE __money_get() {}
2915 static void __gather_info(bool __intl, const locale& __loc,
2916 money_base::pattern& __pat, char_type& __dp,
2917 char_type& __ts, string& __grp,
2918 string_type& __sym, string_type& __psn,
2919 string_type& __nsn, int& __fd);
2922 template <class _CharT>
2924 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2925 money_base::pattern& __pat, char_type& __dp,
2926 char_type& __ts, string& __grp,
2927 string_type& __sym, string_type& __psn,
2928 string_type& __nsn, int& __fd)
2932 const moneypunct<char_type, true>& __mp =
2933 use_facet<moneypunct<char_type, true> >(__loc);
2934 __pat = __mp.neg_format();
2935 __nsn = __mp.negative_sign();
2936 __psn = __mp.positive_sign();
2937 __dp = __mp.decimal_point();
2938 __ts = __mp.thousands_sep();
2939 __grp = __mp.grouping();
2940 __sym = __mp.curr_symbol();
2941 __fd = __mp.frac_digits();
2945 const moneypunct<char_type, false>& __mp =
2946 use_facet<moneypunct<char_type, false> >(__loc);
2947 __pat = __mp.neg_format();
2948 __nsn = __mp.negative_sign();
2949 __psn = __mp.positive_sign();
2950 __dp = __mp.decimal_point();
2951 __ts = __mp.thousands_sep();
2952 __grp = __mp.grouping();
2953 __sym = __mp.curr_symbol();
2954 __fd = __mp.frac_digits();
2958 extern template class __money_get<char>;
2959 extern template class __money_get<wchar_t>;
2961 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2962 class _LIBCPP_VISIBLE money_get
2963 : public locale::facet,
2964 private __money_get<_CharT>
2967 typedef _CharT char_type;
2968 typedef _InputIterator iter_type;
2969 typedef basic_string<char_type> string_type;
2971 _LIBCPP_ALWAYS_INLINE
2972 explicit money_get(size_t __refs = 0)
2973 : locale::facet(__refs) {}
2975 _LIBCPP_ALWAYS_INLINE
2976 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2977 ios_base::iostate& __err, long double& __v) const
2979 return do_get(__b, __e, __intl, __iob, __err, __v);
2982 _LIBCPP_ALWAYS_INLINE
2983 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2984 ios_base::iostate& __err, string_type& __v) const
2986 return do_get(__b, __e, __intl, __iob, __err, __v);
2989 static locale::id id;
2993 _LIBCPP_ALWAYS_INLINE
2996 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2997 ios_base& __iob, ios_base::iostate& __err,
2998 long double& __v) const;
2999 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3000 ios_base& __iob, ios_base::iostate& __err,
3001 string_type& __v) const;
3004 static bool __do_get(iter_type& __b, iter_type __e,
3005 bool __intl, const locale& __loc,
3006 ios_base::fmtflags __flags, ios_base::iostate& __err,
3007 bool& __neg, const ctype<char_type>& __ct,
3008 unique_ptr<char_type, void(*)(void*)>& __wb,
3009 char_type*& __wn, char_type* __we);
3012 template <class _CharT, class _InputIterator>
3014 money_get<_CharT, _InputIterator>::id;
3016 void __do_nothing(void*);
3018 template <class _Tp>
3021 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
3023 bool __owns = __b.get_deleter() != __do_nothing;
3024 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
3025 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
3026 2 * __cur_cap : numeric_limits<size_t>::max();
3027 size_t __n_off = static_cast<size_t>(__n - __b.get());
3028 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
3030 __throw_bad_alloc();
3033 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
3034 __new_cap /= sizeof(_Tp);
3035 __n = __b.get() + __n_off;
3036 __e = __b.get() + __new_cap;
3040 template <class _CharT, class _InputIterator>
3042 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
3043 bool __intl, const locale& __loc,
3044 ios_base::fmtflags __flags,
3045 ios_base::iostate& __err,
3047 const ctype<char_type>& __ct,
3048 unique_ptr<char_type, void(*)(void*)>& __wb,
3049 char_type*& __wn, char_type* __we)
3051 const unsigned __bz = 100;
3052 unsigned __gbuf[__bz];
3053 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3054 unsigned* __gn = __gb.get();
3055 unsigned* __ge = __gn + __bz;
3056 money_base::pattern __pat;
3063 // Capture the spaces read into money_base::{space,none} so they
3064 // can be compared to initial spaces in __sym.
3065 string_type __spaces;
3067 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3068 __sym, __psn, __nsn, __fd);
3069 const string_type* __trailing_sign = 0;
3071 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3073 switch (__pat.field[__p])
3075 case money_base::space:
3078 if (__ct.is(ctype_base::space, *__b))
3079 __spaces.push_back(*__b++);
3082 __err |= ios_base::failbit;
3087 case money_base::none:
3090 while (__b != __e && __ct.is(ctype_base::space, *__b))
3091 __spaces.push_back(*__b++);
3094 case money_base::sign:
3095 if (__psn.size() + __nsn.size() > 0)
3097 if (__psn.size() == 0 || __nsn.size() == 0)
3098 { // sign is optional
3099 if (__psn.size() > 0)
3100 { // __nsn.size() == 0
3101 if (*__b == __psn[0])
3104 if (__psn.size() > 1)
3105 __trailing_sign = &__psn;
3110 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
3114 if (__nsn.size() > 1)
3115 __trailing_sign = &__nsn;
3118 else // sign is required
3120 if (*__b == __psn[0])
3123 if (__psn.size() > 1)
3124 __trailing_sign = &__psn;
3126 else if (*__b == __nsn[0])
3130 if (__nsn.size() > 1)
3131 __trailing_sign = &__nsn;
3135 __err |= ios_base::failbit;
3141 case money_base::symbol:
3143 bool __more_needed = __trailing_sign ||
3145 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
3146 bool __sb = __flags & ios_base::showbase;
3147 if (__sb || __more_needed)
3149 ios_base::iostate __et = ios_base::goodbit;
3150 typename string_type::const_iterator __sym_space_end = __sym.begin();
3151 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3152 __pat.field[__p - 1] == money_base::space)) {
3153 // Match spaces we've already read against spaces at
3154 // the beginning of __sym.
3155 while (__sym_space_end != __sym.end() &&
3156 __ct.is(ctype_base::space, *__sym_space_end))
3158 const size_t __num_spaces = __sym_space_end - __sym.begin();
3159 if (__num_spaces > __spaces.size() ||
3160 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3162 // No match. Put __sym_space_end back at the
3163 // beginning of __sym, which will prevent a
3164 // match in the next loop.
3165 __sym_space_end = __sym.begin();
3168 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3169 while (__sym_curr_char != __sym.end() && __b != __e &&
3170 *__b == *__sym_curr_char) {
3174 if (__sb && __sym_curr_char != __sym.end())
3176 __err |= ios_base::failbit;
3182 case money_base::value:
3185 for (; __b != __e; ++__b)
3187 char_type __c = *__b;
3188 if (__ct.is(ctype_base::digit, __c))
3191 __double_or_nothing(__wb, __wn, __we);
3195 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3198 __double_or_nothing(__gb, __gn, __ge);
3205 if (__gb.get() != __gn && __ng > 0)
3208 __double_or_nothing(__gb, __gn, __ge);
3213 if (__b == __e || *__b != __dp)
3215 __err |= ios_base::failbit;
3218 for (++__b; __fd > 0; --__fd, ++__b)
3220 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3222 __err |= ios_base::failbit;
3226 __double_or_nothing(__wb, __wn, __we);
3230 if (__wn == __wb.get())
3232 __err |= ios_base::failbit;
3239 if (__trailing_sign)
3241 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3243 if (__b == __e || *__b != (*__trailing_sign)[__i])
3245 __err |= ios_base::failbit;
3250 if (__gb.get() != __gn)
3252 ios_base::iostate __et = ios_base::goodbit;
3253 __check_grouping(__grp, __gb.get(), __gn, __et);
3256 __err |= ios_base::failbit;
3263 template <class _CharT, class _InputIterator>
3265 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3266 bool __intl, ios_base& __iob,
3267 ios_base::iostate& __err,
3268 long double& __v) const
3270 const int __bz = 100;
3271 char_type __wbuf[__bz];
3272 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3274 char_type* __we = __wbuf + __bz;
3275 locale __loc = __iob.getloc();
3276 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3278 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3281 const char __src[] = "0123456789";
3282 char_type __atoms[sizeof(__src)-1];
3283 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3285 char* __nc = __nbuf;
3286 unique_ptr<char, void(*)(void*)> __h(0, free);
3287 if (__wn - __wb.get() > __bz-2)
3289 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3291 __throw_bad_alloc();
3296 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3297 *__nc = __src[find(__atoms, __atoms+sizeof(__atoms), *__w) - __atoms];
3299 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3300 __throw_runtime_error("money_get error");
3303 __err |= ios_base::eofbit;
3307 template <class _CharT, class _InputIterator>
3309 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3310 bool __intl, ios_base& __iob,
3311 ios_base::iostate& __err,
3312 string_type& __v) const
3314 const int __bz = 100;
3315 char_type __wbuf[__bz];
3316 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3318 char_type* __we = __wbuf + __bz;
3319 locale __loc = __iob.getloc();
3320 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3322 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3327 __v.push_back(__ct.widen('-'));
3328 char_type __z = __ct.widen('0');
3330 for (__w = __wb.get(); __w < __wn-1; ++__w)
3333 __v.append(__w, __wn);
3336 __err |= ios_base::eofbit;
3340 extern template class money_get<char>;
3341 extern template class money_get<wchar_t>;
3345 template <class _CharT>
3349 typedef _CharT char_type;
3350 typedef basic_string<char_type> string_type;
3352 _LIBCPP_ALWAYS_INLINE __money_put() {}
3354 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3355 money_base::pattern& __pat, char_type& __dp,
3356 char_type& __ts, string& __grp,
3357 string_type& __sym, string_type& __sn,
3359 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3360 ios_base::fmtflags __flags,
3361 const char_type* __db, const char_type* __de,
3362 const ctype<char_type>& __ct, bool __neg,
3363 const money_base::pattern& __pat, char_type __dp,
3364 char_type __ts, const string& __grp,
3365 const string_type& __sym, const string_type& __sn,
3369 template <class _CharT>
3371 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3372 money_base::pattern& __pat, char_type& __dp,
3373 char_type& __ts, string& __grp,
3374 string_type& __sym, string_type& __sn,
3379 const moneypunct<char_type, true>& __mp =
3380 use_facet<moneypunct<char_type, true> >(__loc);
3383 __pat = __mp.neg_format();
3384 __sn = __mp.negative_sign();
3388 __pat = __mp.pos_format();
3389 __sn = __mp.positive_sign();
3391 __dp = __mp.decimal_point();
3392 __ts = __mp.thousands_sep();
3393 __grp = __mp.grouping();
3394 __sym = __mp.curr_symbol();
3395 __fd = __mp.frac_digits();
3399 const moneypunct<char_type, false>& __mp =
3400 use_facet<moneypunct<char_type, false> >(__loc);
3403 __pat = __mp.neg_format();
3404 __sn = __mp.negative_sign();
3408 __pat = __mp.pos_format();
3409 __sn = __mp.positive_sign();
3411 __dp = __mp.decimal_point();
3412 __ts = __mp.thousands_sep();
3413 __grp = __mp.grouping();
3414 __sym = __mp.curr_symbol();
3415 __fd = __mp.frac_digits();
3419 template <class _CharT>
3421 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3422 ios_base::fmtflags __flags,
3423 const char_type* __db, const char_type* __de,
3424 const ctype<char_type>& __ct, bool __neg,
3425 const money_base::pattern& __pat, char_type __dp,
3426 char_type __ts, const string& __grp,
3427 const string_type& __sym, const string_type& __sn,
3431 for (unsigned __p = 0; __p < 4; ++__p)
3433 switch (__pat.field[__p])
3435 case money_base::none:
3438 case money_base::space:
3440 *__me++ = __ct.widen(' ');
3442 case money_base::sign:
3446 case money_base::symbol:
3447 if (!__sym.empty() && (__flags & ios_base::showbase))
3448 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3450 case money_base::value:
3452 // remember start of value so we can reverse it
3453 char_type* __t = __me;
3454 // find beginning of digits
3457 // find end of digits
3458 const char_type* __d;
3459 for (__d = __db; __d < __de; ++__d)
3460 if (!__ct.is(ctype_base::digit, *__d))
3462 // print fractional part
3466 for (__f = __fd; __d > __db && __f > 0; --__f)
3468 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3469 for (; __f > 0; --__f)
3476 *__me++ = __ct.widen('0');
3482 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3483 : static_cast<unsigned>(__grp[__ig]);
3490 if (++__ig < __grp.size())
3491 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3492 numeric_limits<unsigned>::max() :
3493 static_cast<unsigned>(__grp[__ig]);
3505 // print rest of sign, if any
3506 if (__sn.size() > 1)
3507 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3509 if ((__flags & ios_base::adjustfield) == ios_base::left)
3511 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3515 extern template class __money_put<char>;
3516 extern template class __money_put<wchar_t>;
3518 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3519 class _LIBCPP_VISIBLE money_put
3520 : public locale::facet,
3521 private __money_put<_CharT>
3524 typedef _CharT char_type;
3525 typedef _OutputIterator iter_type;
3526 typedef basic_string<char_type> string_type;
3528 _LIBCPP_ALWAYS_INLINE
3529 explicit money_put(size_t __refs = 0)
3530 : locale::facet(__refs) {}
3532 _LIBCPP_ALWAYS_INLINE
3533 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3534 long double __units) const
3536 return do_put(__s, __intl, __iob, __fl, __units);
3539 _LIBCPP_ALWAYS_INLINE
3540 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3541 const string_type& __digits) const
3543 return do_put(__s, __intl, __iob, __fl, __digits);
3546 static locale::id id;
3549 _LIBCPP_ALWAYS_INLINE
3552 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3553 char_type __fl, long double __units) const;
3554 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3555 char_type __fl, const string_type& __digits) const;
3558 template <class _CharT, class _OutputIterator>
3560 money_put<_CharT, _OutputIterator>::id;
3562 template <class _CharT, class _OutputIterator>
3564 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3565 ios_base& __iob, char_type __fl,
3566 long double __units) const
3569 const size_t __bs = 100;
3572 char_type __digits[__bs];
3573 char_type* __db = __digits;
3574 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3575 unique_ptr<char, void(*)(void*)> __hn(0, free);
3576 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3577 // secure memory for digit storage
3580 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
3581 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3583 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
3586 __throw_bad_alloc();
3588 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3589 if (__hd == nullptr)
3590 __throw_bad_alloc();
3594 locale __loc = __iob.getloc();
3595 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3596 __ct.widen(__bb, __bb + __n, __db);
3597 bool __neg = __n > 0 && __bb[0] == '-';
3598 money_base::pattern __pat;
3605 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3606 // secure memory for formatting
3607 char_type __mbuf[__bs];
3608 char_type* __mb = __mbuf;
3609 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3610 size_t __exn = static_cast<int>(__n) > __fd ?
3611 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3612 __sym.size() + static_cast<size_t>(__fd) + 1
3613 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3616 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3619 __throw_bad_alloc();
3624 this->__format(__mb, __mi, __me, __iob.flags(),
3625 __db, __db + __n, __ct,
3626 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3627 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3630 template <class _CharT, class _OutputIterator>
3632 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3633 ios_base& __iob, char_type __fl,
3634 const string_type& __digits) const
3637 locale __loc = __iob.getloc();
3638 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3639 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3640 money_base::pattern __pat;
3647 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3648 // secure memory for formatting
3649 char_type __mbuf[100];
3650 char_type* __mb = __mbuf;
3651 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3652 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3653 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3654 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3655 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3658 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3661 __throw_bad_alloc();
3666 this->__format(__mb, __mi, __me, __iob.flags(),
3667 __digits.data(), __digits.data() + __digits.size(), __ct,
3668 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3669 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3672 extern template class money_put<char>;
3673 extern template class money_put<wchar_t>;
3677 class _LIBCPP_VISIBLE messages_base
3680 typedef ptrdiff_t catalog;
3682 _LIBCPP_ALWAYS_INLINE messages_base() {}
3685 template <class _CharT>
3686 class _LIBCPP_VISIBLE messages
3687 : public locale::facet,
3688 public messages_base
3691 typedef _CharT char_type;
3692 typedef basic_string<_CharT> string_type;
3694 _LIBCPP_ALWAYS_INLINE
3695 explicit messages(size_t __refs = 0)
3696 : locale::facet(__refs) {}
3698 _LIBCPP_ALWAYS_INLINE
3699 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3701 return do_open(__nm, __loc);
3704 _LIBCPP_ALWAYS_INLINE
3705 string_type get(catalog __c, int __set, int __msgid,
3706 const string_type& __dflt) const
3708 return do_get(__c, __set, __msgid, __dflt);
3711 _LIBCPP_ALWAYS_INLINE
3712 void close(catalog __c) const
3717 static locale::id id;
3720 _LIBCPP_ALWAYS_INLINE
3723 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3724 virtual string_type do_get(catalog, int __set, int __msgid,
3725 const string_type& __dflt) const;
3726 virtual void do_close(catalog) const;
3729 template <class _CharT>
3731 messages<_CharT>::id;
3733 template <class _CharT>
3734 typename messages<_CharT>::catalog
3735 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3740 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3742 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3747 template <class _CharT>
3748 typename messages<_CharT>::string_type
3749 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3750 const string_type& __dflt) const
3756 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3758 __dflt.c_str() + __dflt.size());
3761 nl_catd __cat = (nl_catd)__c;
3762 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3764 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3765 __n, __n + strlen(__n));
3770 template <class _CharT>
3772 messages<_CharT>::do_close(catalog __c) const
3777 nl_catd __cat = (nl_catd)__c;
3782 extern template class messages<char>;
3783 extern template class messages<wchar_t>;
3785 template <class _CharT>
3786 class _LIBCPP_VISIBLE messages_byname
3787 : public messages<_CharT>
3790 typedef messages_base::catalog catalog;
3791 typedef basic_string<_CharT> string_type;
3793 _LIBCPP_ALWAYS_INLINE
3794 explicit messages_byname(const char*, size_t __refs = 0)
3795 : messages<_CharT>(__refs) {}
3797 _LIBCPP_ALWAYS_INLINE
3798 explicit messages_byname(const string&, size_t __refs = 0)
3799 : messages<_CharT>(__refs) {}
3802 _LIBCPP_ALWAYS_INLINE
3803 ~messages_byname() {}
3806 extern template class messages_byname<char>;
3807 extern template class messages_byname<wchar_t>;
3809 template<class _Codecvt, class _Elem = wchar_t,
3810 class _Wide_alloc = allocator<_Elem>,
3811 class _Byte_alloc = allocator<char> >
3812 class _LIBCPP_VISIBLE wstring_convert
3815 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3816 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3817 typedef typename _Codecvt::state_type state_type;
3818 typedef typename wide_string::traits_type::int_type int_type;
3821 byte_string __byte_err_string_;
3822 wide_string __wide_err_string_;
3823 _Codecvt* __cvtptr_;
3824 state_type __cvtstate_;
3827 wstring_convert(const wstring_convert& __wc);
3828 wstring_convert& operator=(const wstring_convert& __wc);
3830 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3831 wstring_convert(_Codecvt* __pcvt, state_type __state);
3832 wstring_convert(const byte_string& __byte_err,
3833 const wide_string& __wide_err = wide_string());
3834 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3835 wstring_convert(wstring_convert&& __wc);
3839 _LIBCPP_ALWAYS_INLINE
3840 wide_string from_bytes(char __byte)
3841 {return from_bytes(&__byte, &__byte+1);}
3842 _LIBCPP_ALWAYS_INLINE
3843 wide_string from_bytes(const char* __ptr)
3844 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3845 _LIBCPP_ALWAYS_INLINE
3846 wide_string from_bytes(const byte_string& __str)
3847 {return from_bytes(__str.data(), __str.data() + __str.size());}
3848 wide_string from_bytes(const char* __first, const char* __last);
3850 _LIBCPP_ALWAYS_INLINE
3851 byte_string to_bytes(_Elem __wchar)
3852 {return to_bytes(&__wchar, &__wchar+1);}
3853 _LIBCPP_ALWAYS_INLINE
3854 byte_string to_bytes(const _Elem* __wptr)
3855 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3856 _LIBCPP_ALWAYS_INLINE
3857 byte_string to_bytes(const wide_string& __wstr)
3858 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3859 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3861 _LIBCPP_ALWAYS_INLINE
3862 size_t converted() const {return __cvtcount_;}
3863 _LIBCPP_ALWAYS_INLINE
3864 state_type state() const {return __cvtstate_;}
3867 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3868 inline _LIBCPP_ALWAYS_INLINE
3869 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3870 wstring_convert(_Codecvt* __pcvt)
3871 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3875 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3876 inline _LIBCPP_ALWAYS_INLINE
3877 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3878 wstring_convert(_Codecvt* __pcvt, state_type __state)
3879 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3883 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3884 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3885 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3886 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3887 __cvtstate_(), __cvtcount_(0)
3889 __cvtptr_ = new _Codecvt;
3892 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3894 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3895 inline _LIBCPP_ALWAYS_INLINE
3896 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3897 wstring_convert(wstring_convert&& __wc)
3898 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3899 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3900 __cvtptr_(__wc.__cvtptr_),
3901 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
3903 __wc.__cvtptr_ = nullptr;
3906 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3908 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3909 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3914 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3915 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3916 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3917 from_bytes(const char* __frm, const char* __frm_end)
3920 if (__cvtptr_ != nullptr)
3922 wide_string __ws(2*(__frm_end - __frm), _Elem());
3923 __ws.resize(__ws.capacity());
3924 codecvt_base::result __r = codecvt_base::ok;
3925 state_type __st = __cvtstate_;
3926 if (__frm != __frm_end)
3928 _Elem* __to = &__ws[0];
3929 _Elem* __to_end = __to + __ws.size();
3930 const char* __frm_nxt;
3934 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3935 __to, __to_end, __to_nxt);
3936 __cvtcount_ += __frm_nxt - __frm;
3937 if (__frm_nxt == __frm)
3939 __r = codecvt_base::error;
3941 else if (__r == codecvt_base::noconv)
3943 __ws.resize(__to - &__ws[0]);
3944 // This only gets executed if _Elem is char
3945 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3947 __r = codecvt_base::ok;
3949 else if (__r == codecvt_base::ok)
3951 __ws.resize(__to_nxt - &__ws[0]);
3954 else if (__r == codecvt_base::partial)
3956 ptrdiff_t __s = __to_nxt - &__ws[0];
3957 __ws.resize(2 * __s);
3958 __to = &__ws[0] + __s;
3959 __to_end = &__ws[0] + __ws.size();
3962 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3964 if (__r == codecvt_base::ok)
3967 #ifndef _LIBCPP_NO_EXCEPTIONS
3968 if (__wide_err_string_.empty())
3969 throw range_error("wstring_convert: from_bytes error");
3970 #endif // _LIBCPP_NO_EXCEPTIONS
3971 return __wide_err_string_;
3974 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3975 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3976 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3977 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3980 if (__cvtptr_ != nullptr)
3982 byte_string __bs(2*(__frm_end - __frm), char());
3983 __bs.resize(__bs.capacity());
3984 codecvt_base::result __r = codecvt_base::ok;
3985 state_type __st = __cvtstate_;
3986 if (__frm != __frm_end)
3988 char* __to = &__bs[0];
3989 char* __to_end = __to + __bs.size();
3990 const _Elem* __frm_nxt;
3994 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3995 __to, __to_end, __to_nxt);
3996 __cvtcount_ += __frm_nxt - __frm;
3997 if (__frm_nxt == __frm)
3999 __r = codecvt_base::error;
4001 else if (__r == codecvt_base::noconv)
4003 __bs.resize(__to - &__bs[0]);
4004 // This only gets executed if _Elem is char
4005 __bs.append((const char*)__frm, (const char*)__frm_end);
4007 __r = codecvt_base::ok;
4009 else if (__r == codecvt_base::ok)
4011 __bs.resize(__to_nxt - &__bs[0]);
4014 else if (__r == codecvt_base::partial)
4016 ptrdiff_t __s = __to_nxt - &__bs[0];
4017 __bs.resize(2 * __s);
4018 __to = &__bs[0] + __s;
4019 __to_end = &__bs[0] + __bs.size();
4022 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4024 if (__r == codecvt_base::ok)
4026 size_t __s = __bs.size();
4027 __bs.resize(__bs.capacity());
4028 char* __to = &__bs[0] + __s;
4029 char* __to_end = __to + __bs.size();
4033 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
4034 if (__r == codecvt_base::noconv)
4036 __bs.resize(__to - &__bs[0]);
4037 __r = codecvt_base::ok;
4039 else if (__r == codecvt_base::ok)
4041 __bs.resize(__to_nxt - &__bs[0]);
4043 else if (__r == codecvt_base::partial)
4045 ptrdiff_t __sp = __to_nxt - &__bs[0];
4046 __bs.resize(2 * __sp);
4047 __to = &__bs[0] + __sp;
4048 __to_end = &__bs[0] + __bs.size();
4050 } while (__r == codecvt_base::partial);
4051 if (__r == codecvt_base::ok)
4055 #ifndef _LIBCPP_NO_EXCEPTIONS
4056 if (__byte_err_string_.empty())
4057 throw range_error("wstring_convert: to_bytes error");
4058 #endif // _LIBCPP_NO_EXCEPTIONS
4059 return __byte_err_string_;
4062 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
4063 class _LIBCPP_VISIBLE wbuffer_convert
4064 : public basic_streambuf<_Elem, _Tr>
4068 typedef _Elem char_type;
4069 typedef _Tr traits_type;
4070 typedef typename traits_type::int_type int_type;
4071 typedef typename traits_type::pos_type pos_type;
4072 typedef typename traits_type::off_type off_type;
4073 typedef typename _Codecvt::state_type state_type;
4077 const char* __extbufnext_;
4078 const char* __extbufend_;
4079 char __extbuf_min_[8];
4081 char_type* __intbuf_;
4083 streambuf* __bufptr_;
4086 ios_base::openmode __cm_;
4089 bool __always_noconv_;
4091 wbuffer_convert(const wbuffer_convert&);
4092 wbuffer_convert& operator=(const wbuffer_convert&);
4094 wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
4095 state_type __state = state_type());
4098 _LIBCPP_INLINE_VISIBILITY
4099 streambuf* rdbuf() const {return __bufptr_;}
4100 _LIBCPP_INLINE_VISIBILITY
4101 streambuf* rdbuf(streambuf* __bytebuf)
4103 streambuf* __r = __bufptr_;
4104 __bufptr_ = __bytebuf;
4108 _LIBCPP_INLINE_VISIBILITY
4109 state_type state() const {return __st_;}
4112 virtual int_type underflow();
4113 virtual int_type pbackfail(int_type __c = traits_type::eof());
4114 virtual int_type overflow (int_type __c = traits_type::eof());
4115 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4117 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4118 ios_base::openmode __wch = ios_base::in | ios_base::out);
4119 virtual pos_type seekpos(pos_type __sp,
4120 ios_base::openmode __wch = ios_base::in | ios_base::out);
4125 void __write_mode();
4126 wbuffer_convert* __close();
4129 template <class _Codecvt, class _Elem, class _Tr>
4130 wbuffer_convert<_Codecvt, _Elem, _Tr>::
4131 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4138 __bufptr_(__bytebuf),
4144 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4149 template <class _Codecvt, class _Elem, class _Tr>
4150 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4155 delete [] __extbuf_;
4157 delete [] __intbuf_;
4160 template <class _Codecvt, class _Elem, class _Tr>
4161 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4162 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4164 if (__cv_ == 0 || __bufptr_ == 0)
4165 return traits_type::eof();
4166 bool __initial = __read_mode();
4168 if (this->gptr() == 0)
4169 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4170 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4171 int_type __c = traits_type::eof();
4172 if (this->gptr() == this->egptr())
4174 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4175 if (__always_noconv_)
4177 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4178 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4181 this->setg(this->eback(),
4182 this->eback() + __unget_sz,
4183 this->eback() + __unget_sz + __nmemb);
4184 __c = *this->gptr();
4189 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4190 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4191 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
4192 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
4193 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4194 codecvt_base::result __r;
4195 state_type __svs = __st_;
4196 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4199 __extbufend_ = __extbufnext_ + __nr;
4201 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4202 this->eback() + __unget_sz,
4203 this->egptr(), __inext);
4204 if (__r == codecvt_base::noconv)
4206 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4207 __c = *this->gptr();
4209 else if (__inext != this->eback() + __unget_sz)
4211 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4212 __c = *this->gptr();
4218 __c = *this->gptr();
4219 if (this->eback() == &__1buf)
4220 this->setg(0, 0, 0);
4224 template <class _Codecvt, class _Elem, class _Tr>
4225 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4226 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4228 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4230 if (traits_type::eq_int_type(__c, traits_type::eof()))
4233 return traits_type::not_eof(__c);
4235 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4238 *this->gptr() = traits_type::to_char_type(__c);
4242 return traits_type::eof();
4245 template <class _Codecvt, class _Elem, class _Tr>
4246 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4247 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4249 if (__cv_ == 0 || __bufptr_ == 0)
4250 return traits_type::eof();
4253 char_type* __pb_save = this->pbase();
4254 char_type* __epb_save = this->epptr();
4255 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4257 if (this->pptr() == 0)
4258 this->setp(&__1buf, &__1buf+1);
4259 *this->pptr() = traits_type::to_char_type(__c);
4262 if (this->pptr() != this->pbase())
4264 if (__always_noconv_)
4266 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4267 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4268 return traits_type::eof();
4272 char* __extbe = __extbuf_;
4273 codecvt_base::result __r;
4276 const char_type* __e;
4277 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4278 __extbuf_, __extbuf_ + __ebs_, __extbe);
4279 if (__e == this->pbase())
4280 return traits_type::eof();
4281 if (__r == codecvt_base::noconv)
4283 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4284 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4285 return traits_type::eof();
4287 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4289 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4290 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4291 return traits_type::eof();
4292 if (__r == codecvt_base::partial)
4294 this->setp((char_type*)__e, this->pptr());
4295 this->pbump(this->epptr() - this->pbase());
4299 return traits_type::eof();
4300 } while (__r == codecvt_base::partial);
4302 this->setp(__pb_save, __epb_save);
4304 return traits_type::not_eof(__c);
4307 template <class _Codecvt, class _Elem, class _Tr>
4308 basic_streambuf<_Elem, _Tr>*
4309 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4311 this->setg(0, 0, 0);
4314 delete [] __extbuf_;
4316 delete [] __intbuf_;
4318 if (__ebs_ > sizeof(__extbuf_min_))
4320 if (__always_noconv_ && __s)
4322 __extbuf_ = (char*)__s;
4327 __extbuf_ = new char[__ebs_];
4333 __extbuf_ = __extbuf_min_;
4334 __ebs_ = sizeof(__extbuf_min_);
4337 if (!__always_noconv_)
4339 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4340 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4347 __intbuf_ = new char_type[__ibs_];
4360 template <class _Codecvt, class _Elem, class _Tr>
4361 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4362 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4363 ios_base::openmode __om)
4365 int __width = __cv_->encoding();
4366 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4367 return pos_type(off_type(-1));
4368 // __width > 0 || __off == 0
4378 return pos_type(off_type(-1));
4380 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4385 template <class _Codecvt, class _Elem, class _Tr>
4386 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4387 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4389 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4390 return pos_type(off_type(-1));
4391 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4392 return pos_type(off_type(-1));
4396 template <class _Codecvt, class _Elem, class _Tr>
4398 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4400 if (__cv_ == 0 || __bufptr_ == 0)
4402 if (__cm_ & ios_base::out)
4404 if (this->pptr() != this->pbase())
4405 if (overflow() == traits_type::eof())
4407 codecvt_base::result __r;
4411 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4412 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4413 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4415 } while (__r == codecvt_base::partial);
4416 if (__r == codecvt_base::error)
4418 if (__bufptr_->pubsync())
4421 else if (__cm_ & ios_base::in)
4424 if (__always_noconv_)
4425 __c = this->egptr() - this->gptr();
4428 int __width = __cv_->encoding();
4429 __c = __extbufend_ - __extbufnext_;
4431 __c += __width * (this->egptr() - this->gptr());
4434 if (this->gptr() != this->egptr())
4436 reverse(this->gptr(), this->egptr());
4437 codecvt_base::result __r;
4438 const char_type* __e = this->gptr();
4442 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4443 __extbuf_, __extbuf_ + __ebs_, __extbe);
4446 case codecvt_base::noconv:
4447 __c += this->egptr() - this->gptr();
4449 case codecvt_base::ok:
4450 case codecvt_base::partial:
4451 __c += __extbe - __extbuf_;
4456 } while (__r == codecvt_base::partial);
4460 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4462 this->setg(0, 0, 0);
4468 template <class _Codecvt, class _Elem, class _Tr>
4470 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4472 if (!(__cm_ & ios_base::in))
4475 if (__always_noconv_)
4476 this->setg((char_type*)__extbuf_,
4477 (char_type*)__extbuf_ + __ebs_,
4478 (char_type*)__extbuf_ + __ebs_);
4480 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4481 __cm_ = ios_base::in;
4487 template <class _Codecvt, class _Elem, class _Tr>
4489 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4491 if (!(__cm_ & ios_base::out))
4493 this->setg(0, 0, 0);
4494 if (__ebs_ > sizeof(__extbuf_min_))
4496 if (__always_noconv_)
4497 this->setp((char_type*)__extbuf_,
4498 (char_type*)__extbuf_ + (__ebs_ - 1));
4500 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4504 __cm_ = ios_base::out;
4508 template <class _Codecvt, class _Elem, class _Tr>
4509 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4510 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4512 wbuffer_convert* __rt = 0;
4513 if (__cv_ != 0 && __bufptr_ != 0)
4516 if ((__cm_ & ios_base::out) && sync())
4522 _LIBCPP_END_NAMESPACE_STD
4524 #endif // _LIBCPP_LOCALE