2 //===-------------------------- locale ------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_LOCALE
12 #define _LIBCPP_LOCALE
28 static const category // values assigned here are for exposition only
36 all = collate | ctype | monetary | numeric | time | messages;
38 // construct/copy/destroy:
40 locale(const locale& other) noexcept;
41 explicit locale(const char* std_name);
42 explicit locale(const string& std_name);
43 locale(const locale& other, const char* std_name, category);
44 locale(const locale& other, const string& std_name, category);
45 template <class Facet> locale(const locale& other, Facet* f);
46 locale(const locale& other, const locale& one, category);
48 ~locale(); // not virtual
50 const locale& operator=(const locale& other) noexcept;
52 template <class Facet> locale combine(const locale& other) const;
55 basic_string<char> name() const;
56 bool operator==(const locale& other) const;
57 bool operator!=(const locale& other) const;
58 template <class charT, class Traits, class Allocator>
59 bool operator()(const basic_string<charT,Traits,Allocator>& s1,
60 const basic_string<charT,Traits,Allocator>& s2) const;
62 // global locale objects:
63 static locale global(const locale&);
64 static const locale& classic();
67 template <class Facet> const Facet& use_facet(const locale&);
68 template <class Facet> bool has_facet(const locale&) noexcept;
70 // 22.3.3, convenience interfaces:
71 template <class charT> bool isspace (charT c, const locale& loc);
72 template <class charT> bool isprint (charT c, const locale& loc);
73 template <class charT> bool iscntrl (charT c, const locale& loc);
74 template <class charT> bool isupper (charT c, const locale& loc);
75 template <class charT> bool islower (charT c, const locale& loc);
76 template <class charT> bool isalpha (charT c, const locale& loc);
77 template <class charT> bool isdigit (charT c, const locale& loc);
78 template <class charT> bool ispunct (charT c, const locale& loc);
79 template <class charT> bool isxdigit(charT c, const locale& loc);
80 template <class charT> bool isalnum (charT c, const locale& loc);
81 template <class charT> bool isgraph (charT c, const locale& loc);
82 template <class charT> charT toupper(charT c, const locale& loc);
83 template <class charT> charT tolower(charT c, const locale& loc);
85 template<class Codecvt, class Elem = wchar_t,
86 class Wide_alloc = allocator<Elem>,
87 class Byte_alloc = allocator<char>>
91 typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
92 typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
93 typedef typename Codecvt::state_type state_type;
94 typedef typename wide_string::traits_type::int_type int_type;
96 explicit wstring_convert(Codecvt* pcvt = new Codecvt); // explicit in C++14
97 wstring_convert(Codecvt* pcvt, state_type state);
98 explicit wstring_convert(const byte_string& byte_err, // explicit in C++14
99 const wide_string& wide_err = wide_string());
100 wstring_convert(const wstring_convert&) = delete; // C++14
101 wstring_convert & operator=(const wstring_convert &) = delete; // C++14
104 wide_string from_bytes(char byte);
105 wide_string from_bytes(const char* ptr);
106 wide_string from_bytes(const byte_string& str);
107 wide_string from_bytes(const char* first, const char* last);
109 byte_string to_bytes(Elem wchar);
110 byte_string to_bytes(const Elem* wptr);
111 byte_string to_bytes(const wide_string& wstr);
112 byte_string to_bytes(const Elem* first, const Elem* last);
114 size_t converted() const; // noexcept in C++14
115 state_type state() const;
118 template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
119 class wbuffer_convert
120 : public basic_streambuf<Elem, Tr>
123 typedef typename Tr::state_type state_type;
125 explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
126 state_type state = state_type()); // explicit in C++14
127 wbuffer_convert(const wbuffer_convert&) = delete; // C++14
128 wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14
129 ~wbuffer_convert(); // C++14
131 streambuf* rdbuf() const;
132 streambuf* rdbuf(streambuf* bytebuf);
134 state_type state() const;
137 // 22.4.1 and 22.4.1.3, ctype:
139 template <class charT> class ctype;
140 template <> class ctype<char>; // specialization
141 template <class charT> class ctype_byname;
142 template <> class ctype_byname<char>; // specialization
145 template <class internT, class externT, class stateT> class codecvt;
146 template <class internT, class externT, class stateT> class codecvt_byname;
148 // 22.4.2 and 22.4.3, numeric:
149 template <class charT, class InputIterator> class num_get;
150 template <class charT, class OutputIterator> class num_put;
151 template <class charT> class numpunct;
152 template <class charT> class numpunct_byname;
154 // 22.4.4, col lation:
155 template <class charT> class collate;
156 template <class charT> class collate_byname;
158 // 22.4.5, date and time:
160 template <class charT, class InputIterator> class time_get;
161 template <class charT, class InputIterator> class time_get_byname;
162 template <class charT, class OutputIterator> class time_put;
163 template <class charT, class OutputIterator> class time_put_byname;
167 template <class charT, class InputIterator> class money_get;
168 template <class charT, class OutputIterator> class money_put;
169 template <class charT, bool Intl> class moneypunct;
170 template <class charT, bool Intl> class moneypunct_byname;
172 // 22.4.7, message retrieval:
174 template <class charT> class messages;
175 template <class charT> class messages_byname;
196 #ifdef _LIBCPP_HAS_CATOPEN
197 #include <nl_types.h>
201 #include <Availability.h>
204 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
205 #include <__bsd_locale_defaults.h>
207 #include <__bsd_locale_fallbacks.h>
210 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
211 #pragma GCC system_header
215 #include <__undef_macros>
218 _LIBCPP_BEGIN_NAMESPACE_STD
220 #if defined(__APPLE__) || defined(__FreeBSD__)
221 # define _LIBCPP_GET_C_LOCALE 0
222 #elif defined(__CloudABI__) || defined(__NetBSD__)
223 # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
225 # define _LIBCPP_GET_C_LOCALE __cloc()
226 // Get the C locale object
227 _LIBCPP_FUNC_VIS locale_t __cloc();
228 #define __cloc_defined
232 // Scans [__b, __e) until a match is found in the basic_strings range
233 // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
234 // __b will be incremented (visibly), consuming CharT until a match is found
235 // or proved to not exist. A keyword may be "", in which will match anything.
236 // If one keyword is a prefix of another, and the next CharT in the input
237 // might match another keyword, the algorithm will attempt to find the longest
238 // matching keyword. If the longer matching keyword ends up not matching, then
239 // no keyword match is found. If no keyword match is found, __ke is returned
240 // and failbit is set in __err.
241 // Else an iterator pointing to the matching keyword is found. If more than
242 // one keyword matches, an iterator to the first matching keyword is returned.
243 // If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
244 // __ct is used to force to lower case before comparing characters.
246 // Keywords: "a", "abb"
247 // If the input is "a", the first keyword matches and eofbit is set.
248 // If the input is "abc", no match is found and "ab" are consumed.
249 template <class _InputIterator, class _ForwardIterator, class _Ctype>
252 __scan_keyword(_InputIterator& __b, _InputIterator __e,
253 _ForwardIterator __kb, _ForwardIterator __ke,
254 const _Ctype& __ct, ios_base::iostate& __err,
255 bool __case_sensitive = true)
257 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
258 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
259 const unsigned char __doesnt_match = '\0';
260 const unsigned char __might_match = '\1';
261 const unsigned char __does_match = '\2';
262 unsigned char __statbuf[100];
263 unsigned char* __status = __statbuf;
264 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
265 if (__nkw > sizeof(__statbuf))
267 __status = (unsigned char*)malloc(__nkw);
270 __stat_hold.reset(__status);
272 size_t __n_might_match = __nkw; // At this point, any keyword might match
273 size_t __n_does_match = 0; // but none of them definitely do
274 // Initialize all statuses to __might_match, except for "" keywords are __does_match
275 unsigned char* __st = __status;
276 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
279 *__st = __might_match;
282 *__st = __does_match;
287 // While there might be a match, test keywords against the next CharT
288 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
290 // Peek at the next CharT but don't consume it
292 if (!__case_sensitive)
293 __c = __ct.toupper(__c);
294 bool __consume = false;
295 // For each keyword which might match, see if the __indx character is __c
296 // If a match if found, consume __c
297 // If a match is found, and that is the last character in the keyword,
298 // then that keyword matches.
299 // If the keyword doesn't match this character, then change the keyword
302 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
304 if (*__st == __might_match)
306 _CharT __kc = (*__ky)[__indx];
307 if (!__case_sensitive)
308 __kc = __ct.toupper(__kc);
312 if (__ky->size() == __indx+1)
314 *__st = __does_match;
321 *__st = __doesnt_match;
326 // consume if we matched a character
330 // If we consumed a character and there might be a matched keyword that
331 // was marked matched on a previous iteration, then such keywords
332 // which are now marked as not matching.
333 if (__n_might_match + __n_does_match > 1)
336 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
338 if (*__st == __does_match && __ky->size() != __indx+1)
340 *__st = __doesnt_match;
347 // We've exited the loop because we hit eof and/or we have no more "might matches".
349 __err |= ios_base::eofbit;
350 // Return the first matching result
351 for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
352 if (*__st == __does_match)
355 __err |= ios_base::failbit;
359 struct _LIBCPP_TYPE_VIS __num_get_base
361 static const int __num_get_buf_sz = 40;
363 static int __get_base(ios_base&);
364 static const char __src[33];
368 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
369 ios_base::iostate& __err);
371 template <class _CharT>
373 : protected __num_get_base
375 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
376 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
377 _CharT& __thousands_sep);
378 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
379 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
380 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
381 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
382 char* __a, char*& __a_end,
383 _CharT __decimal_point, _CharT __thousands_sep,
384 const string& __grouping, unsigned* __g,
385 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
388 template <class _CharT>
390 __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
392 locale __loc = __iob.getloc();
393 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
394 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
395 __thousands_sep = __np.thousands_sep();
396 return __np.grouping();
399 template <class _CharT>
401 __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
402 _CharT& __thousands_sep)
404 locale __loc = __iob.getloc();
405 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
406 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
407 __decimal_point = __np.decimal_point();
408 __thousands_sep = __np.thousands_sep();
409 return __np.grouping();
412 template <class _CharT>
414 __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
415 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
416 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
418 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
420 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
424 if (__grouping.size() != 0 && __ct == __thousands_sep)
426 if (__g_end-__g < __num_get_buf_sz)
433 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
446 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
449 *__a_end++ = __src[__f];
454 *__a_end++ = __src[__f];
459 template <class _CharT>
461 __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
462 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
463 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
465 if (__ct == __decimal_point)
471 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
475 if (__ct == __thousands_sep && __grouping.size() != 0)
479 if (__g_end-__g < __num_get_buf_sz)
486 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
489 char __x = __src[__f];
490 if (__x == '-' || __x == '+')
492 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
499 if (__x == 'x' || __x == 'X')
501 else if ((__x & 0x5F) == __exp)
507 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
518 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>)
519 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>)
521 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
522 class _LIBCPP_TEMPLATE_VIS num_get
523 : public locale::facet,
524 private __num_get<_CharT>
527 typedef _CharT char_type;
528 typedef _InputIterator iter_type;
530 _LIBCPP_ALWAYS_INLINE
531 explicit num_get(size_t __refs = 0)
532 : locale::facet(__refs) {}
534 _LIBCPP_ALWAYS_INLINE
535 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
536 ios_base::iostate& __err, bool& __v) const
538 return do_get(__b, __e, __iob, __err, __v);
541 _LIBCPP_ALWAYS_INLINE
542 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
543 ios_base::iostate& __err, long& __v) const
545 return do_get(__b, __e, __iob, __err, __v);
548 _LIBCPP_ALWAYS_INLINE
549 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
550 ios_base::iostate& __err, long long& __v) const
552 return do_get(__b, __e, __iob, __err, __v);
555 _LIBCPP_ALWAYS_INLINE
556 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
557 ios_base::iostate& __err, unsigned short& __v) const
559 return do_get(__b, __e, __iob, __err, __v);
562 _LIBCPP_ALWAYS_INLINE
563 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
564 ios_base::iostate& __err, unsigned int& __v) const
566 return do_get(__b, __e, __iob, __err, __v);
569 _LIBCPP_ALWAYS_INLINE
570 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
571 ios_base::iostate& __err, unsigned long& __v) const
573 return do_get(__b, __e, __iob, __err, __v);
576 _LIBCPP_ALWAYS_INLINE
577 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
578 ios_base::iostate& __err, unsigned long long& __v) const
580 return do_get(__b, __e, __iob, __err, __v);
583 _LIBCPP_ALWAYS_INLINE
584 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
585 ios_base::iostate& __err, float& __v) const
587 return do_get(__b, __e, __iob, __err, __v);
590 _LIBCPP_ALWAYS_INLINE
591 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
592 ios_base::iostate& __err, double& __v) const
594 return do_get(__b, __e, __iob, __err, __v);
597 _LIBCPP_ALWAYS_INLINE
598 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
599 ios_base::iostate& __err, long double& __v) const
601 return do_get(__b, __e, __iob, __err, __v);
604 _LIBCPP_ALWAYS_INLINE
605 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
606 ios_base::iostate& __err, void*& __v) const
608 return do_get(__b, __e, __iob, __err, __v);
611 static locale::id id;
614 _LIBCPP_ALWAYS_INLINE
618 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
619 iter_type __do_get_floating_point
620 (iter_type __b, iter_type __e, ios_base& __iob,
621 ios_base::iostate& __err, _Fp& __v) const;
623 template <class _Signed>
624 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
625 iter_type __do_get_signed
626 (iter_type __b, iter_type __e, ios_base& __iob,
627 ios_base::iostate& __err, _Signed& __v) const;
629 template <class _Unsigned>
630 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
631 iter_type __do_get_unsigned
632 (iter_type __b, iter_type __e, ios_base& __iob,
633 ios_base::iostate& __err, _Unsigned& __v) const;
636 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
637 ios_base::iostate& __err, bool& __v) const;
639 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
640 ios_base::iostate& __err, long& __v) const
641 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
643 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
644 ios_base::iostate& __err, long long& __v) const
645 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
647 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
648 ios_base::iostate& __err, unsigned short& __v) const
649 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
651 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
652 ios_base::iostate& __err, unsigned int& __v) const
653 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
655 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
656 ios_base::iostate& __err, unsigned long& __v) const
657 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
659 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
660 ios_base::iostate& __err, unsigned long long& __v) const
661 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
663 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
664 ios_base::iostate& __err, float& __v) const
665 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
667 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
668 ios_base::iostate& __err, double& __v) const
669 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
671 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
672 ios_base::iostate& __err, long double& __v) const
673 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
675 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
676 ios_base::iostate& __err, void*& __v) const;
679 template <class _CharT, class _InputIterator>
681 num_get<_CharT, _InputIterator>::id;
685 __num_get_signed_integral(const char* __a, const char* __a_end,
686 ios_base::iostate& __err, int __base)
690 typename remove_reference<decltype(errno)>::type __save_errno = errno;
693 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
694 typename remove_reference<decltype(errno)>::type __current_errno = errno;
695 if (__current_errno == 0)
696 errno = __save_errno;
699 __err = ios_base::failbit;
702 else if (__current_errno == ERANGE ||
703 __ll < numeric_limits<_Tp>::min() ||
704 numeric_limits<_Tp>::max() < __ll)
706 __err = ios_base::failbit;
708 return numeric_limits<_Tp>::max();
710 return numeric_limits<_Tp>::min();
712 return static_cast<_Tp>(__ll);
714 __err = ios_base::failbit;
720 __num_get_unsigned_integral(const char* __a, const char* __a_end,
721 ios_base::iostate& __err, int __base)
727 __err = ios_base::failbit;
730 typename remove_reference<decltype(errno)>::type __save_errno = errno;
733 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
734 typename remove_reference<decltype(errno)>::type __current_errno = errno;
735 if (__current_errno == 0)
736 errno = __save_errno;
739 __err = ios_base::failbit;
742 else if (__current_errno == ERANGE ||
743 numeric_limits<_Tp>::max() < __ll)
745 __err = ios_base::failbit;
746 return numeric_limits<_Tp>::max();
748 return static_cast<_Tp>(__ll);
750 __err = ios_base::failbit;
755 _LIBCPP_INLINE_VISIBILITY
756 _Tp __do_strtod(const char* __a, char** __p2);
759 inline _LIBCPP_INLINE_VISIBILITY
760 float __do_strtod<float>(const char* __a, char** __p2) {
761 return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
765 inline _LIBCPP_INLINE_VISIBILITY
766 double __do_strtod<double>(const char* __a, char** __p2) {
767 return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
771 inline _LIBCPP_INLINE_VISIBILITY
772 long double __do_strtod<long double>(const char* __a, char** __p2) {
773 return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
779 __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
783 typename remove_reference<decltype(errno)>::type __save_errno = errno;
786 _Tp __ld = __do_strtod<_Tp>(__a, &__p2);
787 typename remove_reference<decltype(errno)>::type __current_errno = errno;
788 if (__current_errno == 0)
789 errno = __save_errno;
792 __err = ios_base::failbit;
795 else if (__current_errno == ERANGE)
796 __err = ios_base::failbit;
799 __err = ios_base::failbit;
803 template <class _CharT, class _InputIterator>
805 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
807 ios_base::iostate& __err,
810 if ((__iob.flags() & ios_base::boolalpha) == 0)
813 __b = do_get(__b, __e, __iob, __err, __lv);
824 __err = ios_base::failbit;
829 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
830 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
831 typedef typename numpunct<_CharT>::string_type string_type;
832 const string_type __names[2] = {__np.truename(), __np.falsename()};
833 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
835 __v = __i == __names;
841 template <class _CharT, class _InputIterator>
842 template <class _Signed>
844 num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
846 ios_base::iostate& __err,
850 int __base = this->__get_base(__iob);
852 char_type __atoms[26];
853 char_type __thousands_sep;
854 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
856 __buf.resize(__buf.capacity());
857 char* __a = &__buf[0];
859 unsigned __g[__num_get_base::__num_get_buf_sz];
860 unsigned* __g_end = __g;
862 for (; __b != __e; ++__b)
864 if (__a_end == __a + __buf.size())
866 size_t __tmp = __buf.size();
867 __buf.resize(2*__buf.size());
868 __buf.resize(__buf.capacity());
870 __a_end = __a + __tmp;
872 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
873 __thousands_sep, __grouping, __g, __g_end,
877 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
880 __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
881 // Digit grouping checked
882 __check_grouping(__grouping, __g, __g_end, __err);
885 __err |= ios_base::eofbit;
891 template <class _CharT, class _InputIterator>
892 template <class _Unsigned>
894 num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
896 ios_base::iostate& __err,
897 _Unsigned& __v) const
900 int __base = this->__get_base(__iob);
902 char_type __atoms[26];
903 char_type __thousands_sep;
904 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
906 __buf.resize(__buf.capacity());
907 char* __a = &__buf[0];
909 unsigned __g[__num_get_base::__num_get_buf_sz];
910 unsigned* __g_end = __g;
912 for (; __b != __e; ++__b)
914 if (__a_end == __a + __buf.size())
916 size_t __tmp = __buf.size();
917 __buf.resize(2*__buf.size());
918 __buf.resize(__buf.capacity());
920 __a_end = __a + __tmp;
922 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
923 __thousands_sep, __grouping, __g, __g_end,
927 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
930 __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
931 // Digit grouping checked
932 __check_grouping(__grouping, __g, __g_end, __err);
935 __err |= ios_base::eofbit;
941 template <class _CharT, class _InputIterator>
944 num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
946 ios_base::iostate& __err,
949 // Stage 1, nothing to do
951 char_type __atoms[32];
952 char_type __decimal_point;
953 char_type __thousands_sep;
954 string __grouping = this->__stage2_float_prep(__iob, __atoms,
958 __buf.resize(__buf.capacity());
959 char* __a = &__buf[0];
961 unsigned __g[__num_get_base::__num_get_buf_sz];
962 unsigned* __g_end = __g;
964 bool __in_units = true;
966 for (; __b != __e; ++__b)
968 if (__a_end == __a + __buf.size())
970 size_t __tmp = __buf.size();
971 __buf.resize(2*__buf.size());
972 __buf.resize(__buf.capacity());
974 __a_end = __a + __tmp;
976 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
977 __decimal_point, __thousands_sep,
978 __grouping, __g, __g_end,
982 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
985 __v = __num_get_float<_Fp>(__a, __a_end, __err);
986 // Digit grouping checked
987 __check_grouping(__grouping, __g, __g_end, __err);
990 __err |= ios_base::eofbit;
994 template <class _CharT, class _InputIterator>
996 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
998 ios_base::iostate& __err,
1004 char_type __atoms[26];
1005 char_type __thousands_sep = 0;
1007 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1008 __num_get_base::__src + 26, __atoms);
1010 __buf.resize(__buf.capacity());
1011 char* __a = &__buf[0];
1012 char* __a_end = __a;
1013 unsigned __g[__num_get_base::__num_get_buf_sz];
1014 unsigned* __g_end = __g;
1016 for (; __b != __e; ++__b)
1018 if (__a_end == __a + __buf.size())
1020 size_t __tmp = __buf.size();
1021 __buf.resize(2*__buf.size());
1022 __buf.resize(__buf.capacity());
1024 __a_end = __a + __tmp;
1026 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1027 __thousands_sep, __grouping,
1028 __g, __g_end, __atoms))
1032 __buf.resize(__a_end - __a);
1033 if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1034 __err = ios_base::failbit;
1037 __err |= ios_base::eofbit;
1041 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>)
1042 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>)
1044 struct _LIBCPP_TYPE_VIS __num_put_base
1047 static void __format_int(char* __fmt, const char* __len, bool __signd,
1048 ios_base::fmtflags __flags);
1049 static bool __format_float(char* __fmt, const char* __len,
1050 ios_base::fmtflags __flags);
1051 static char* __identify_padding(char* __nb, char* __ne,
1052 const ios_base& __iob);
1055 template <class _CharT>
1057 : protected __num_put_base
1059 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1060 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1061 const locale& __loc);
1062 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1063 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1064 const locale& __loc);
1067 template <class _CharT>
1069 __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1070 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1071 const locale& __loc)
1073 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1074 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1075 string __grouping = __npt.grouping();
1076 if (__grouping.empty())
1078 __ct.widen(__nb, __ne, __ob);
1079 __oe = __ob + (__ne - __nb);
1085 if (*__nf == '-' || *__nf == '+')
1086 *__oe++ = __ct.widen(*__nf++);
1087 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1090 *__oe++ = __ct.widen(*__nf++);
1091 *__oe++ = __ct.widen(*__nf++);
1093 reverse(__nf, __ne);
1094 _CharT __thousands_sep = __npt.thousands_sep();
1097 for (char* __p = __nf; __p < __ne; ++__p)
1099 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1100 __dc == static_cast<unsigned>(__grouping[__dg]))
1102 *__oe++ = __thousands_sep;
1104 if (__dg < __grouping.size()-1)
1107 *__oe++ = __ct.widen(*__p);
1110 reverse(__ob + (__nf - __nb), __oe);
1115 __op = __ob + (__np - __nb);
1118 template <class _CharT>
1120 __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1121 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1122 const locale& __loc)
1124 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1125 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1126 string __grouping = __npt.grouping();
1129 if (*__nf == '-' || *__nf == '+')
1130 *__oe++ = __ct.widen(*__nf++);
1132 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1135 *__oe++ = __ct.widen(*__nf++);
1136 *__oe++ = __ct.widen(*__nf++);
1137 for (__ns = __nf; __ns < __ne; ++__ns)
1138 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1143 for (__ns = __nf; __ns < __ne; ++__ns)
1144 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1147 if (__grouping.empty())
1149 __ct.widen(__nf, __ns, __oe);
1150 __oe += __ns - __nf;
1154 reverse(__nf, __ns);
1155 _CharT __thousands_sep = __npt.thousands_sep();
1158 for (char* __p = __nf; __p < __ns; ++__p)
1160 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1162 *__oe++ = __thousands_sep;
1164 if (__dg < __grouping.size()-1)
1167 *__oe++ = __ct.widen(*__p);
1170 reverse(__ob + (__nf - __nb), __oe);
1172 for (__nf = __ns; __nf < __ne; ++__nf)
1176 *__oe++ = __npt.decimal_point();
1181 *__oe++ = __ct.widen(*__nf);
1183 __ct.widen(__nf, __ne, __oe);
1184 __oe += __ne - __nf;
1188 __op = __ob + (__np - __nb);
1191 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>)
1192 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>)
1194 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1195 class _LIBCPP_TEMPLATE_VIS num_put
1196 : public locale::facet,
1197 private __num_put<_CharT>
1200 typedef _CharT char_type;
1201 typedef _OutputIterator iter_type;
1203 _LIBCPP_ALWAYS_INLINE
1204 explicit num_put(size_t __refs = 0)
1205 : locale::facet(__refs) {}
1207 _LIBCPP_ALWAYS_INLINE
1208 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1211 return do_put(__s, __iob, __fl, __v);
1214 _LIBCPP_ALWAYS_INLINE
1215 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1218 return do_put(__s, __iob, __fl, __v);
1221 _LIBCPP_ALWAYS_INLINE
1222 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1223 long long __v) const
1225 return do_put(__s, __iob, __fl, __v);
1228 _LIBCPP_ALWAYS_INLINE
1229 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1230 unsigned long __v) const
1232 return do_put(__s, __iob, __fl, __v);
1235 _LIBCPP_ALWAYS_INLINE
1236 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1237 unsigned long long __v) const
1239 return do_put(__s, __iob, __fl, __v);
1242 _LIBCPP_ALWAYS_INLINE
1243 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1246 return do_put(__s, __iob, __fl, __v);
1249 _LIBCPP_ALWAYS_INLINE
1250 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1251 long double __v) const
1253 return do_put(__s, __iob, __fl, __v);
1256 _LIBCPP_ALWAYS_INLINE
1257 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1258 const void* __v) const
1260 return do_put(__s, __iob, __fl, __v);
1263 static locale::id id;
1266 _LIBCPP_ALWAYS_INLINE
1269 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1271 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1273 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1274 long long __v) const;
1275 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1276 unsigned long) const;
1277 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1278 unsigned long long) const;
1279 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1281 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1282 long double __v) const;
1283 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1284 const void* __v) const;
1287 template <class _CharT, class _OutputIterator>
1289 num_put<_CharT, _OutputIterator>::id;
1291 template <class _CharT, class _OutputIterator>
1294 __pad_and_output(_OutputIterator __s,
1295 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1296 ios_base& __iob, _CharT __fl)
1298 streamsize __sz = __oe - __ob;
1299 streamsize __ns = __iob.width();
1304 for (;__ob < __op; ++__ob, ++__s)
1306 for (; __ns; --__ns, ++__s)
1308 for (; __ob < __oe; ++__ob, ++__s)
1314 #if !defined(__APPLE__) || \
1315 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1316 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1318 template <class _CharT, class _Traits>
1320 ostreambuf_iterator<_CharT, _Traits>
1321 __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1322 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1323 ios_base& __iob, _CharT __fl)
1325 if (__s.__sbuf_ == nullptr)
1327 streamsize __sz = __oe - __ob;
1328 streamsize __ns = __iob.width();
1333 streamsize __np = __op - __ob;
1336 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1338 __s.__sbuf_ = nullptr;
1344 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1345 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1347 __s.__sbuf_ = nullptr;
1354 if (__s.__sbuf_->sputn(__op, __np) != __np)
1356 __s.__sbuf_ = nullptr;
1366 template <class _CharT, class _OutputIterator>
1368 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1369 char_type __fl, bool __v) const
1371 if ((__iob.flags() & ios_base::boolalpha) == 0)
1372 return do_put(__s, __iob, __fl, (unsigned long)__v);
1373 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1374 typedef typename numpunct<char_type>::string_type string_type;
1375 #if _LIBCPP_DEBUG_LEVEL >= 2
1376 string_type __tmp(__v ? __np.truename() : __np.falsename());
1377 string_type __nm = _VSTD::move(__tmp);
1379 string_type __nm = __v ? __np.truename() : __np.falsename();
1381 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1386 template <class _CharT, class _OutputIterator>
1388 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1389 char_type __fl, long __v) const
1391 // Stage 1 - Get number in narrow char
1392 char __fmt[6] = {'%', 0};
1393 const char* __len = "l";
1394 this->__format_int(__fmt+1, __len, true, __iob.flags());
1395 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1396 + ((numeric_limits<long>::digits % 3) != 0)
1397 + ((__iob.flags() & ios_base::showbase) != 0)
1400 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1401 char* __ne = __nar + __nc;
1402 char* __np = this->__identify_padding(__nar, __ne, __iob);
1403 // Stage 2 - Widen __nar while adding thousands separators
1404 char_type __o[2*(__nbuf-1) - 1];
1405 char_type* __op; // pad here
1406 char_type* __oe; // end of output
1407 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1408 // [__o, __oe) contains thousands_sep'd wide number
1410 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1413 template <class _CharT, class _OutputIterator>
1415 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1416 char_type __fl, long long __v) const
1418 // Stage 1 - Get number in narrow char
1419 char __fmt[8] = {'%', 0};
1420 const char* __len = "ll";
1421 this->__format_int(__fmt+1, __len, true, __iob.flags());
1422 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1423 + ((numeric_limits<long long>::digits % 3) != 0)
1424 + ((__iob.flags() & ios_base::showbase) != 0)
1427 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1428 char* __ne = __nar + __nc;
1429 char* __np = this->__identify_padding(__nar, __ne, __iob);
1430 // Stage 2 - Widen __nar while adding thousands separators
1431 char_type __o[2*(__nbuf-1) - 1];
1432 char_type* __op; // pad here
1433 char_type* __oe; // end of output
1434 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1435 // [__o, __oe) contains thousands_sep'd wide number
1437 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1440 template <class _CharT, class _OutputIterator>
1442 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1443 char_type __fl, unsigned long __v) const
1445 // Stage 1 - Get number in narrow char
1446 char __fmt[6] = {'%', 0};
1447 const char* __len = "l";
1448 this->__format_int(__fmt+1, __len, false, __iob.flags());
1449 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1450 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1451 + ((__iob.flags() & ios_base::showbase) != 0)
1454 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1455 char* __ne = __nar + __nc;
1456 char* __np = this->__identify_padding(__nar, __ne, __iob);
1457 // Stage 2 - Widen __nar while adding thousands separators
1458 char_type __o[2*(__nbuf-1) - 1];
1459 char_type* __op; // pad here
1460 char_type* __oe; // end of output
1461 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1462 // [__o, __oe) contains thousands_sep'd wide number
1464 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1467 template <class _CharT, class _OutputIterator>
1469 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1470 char_type __fl, unsigned long long __v) const
1472 // Stage 1 - Get number in narrow char
1473 char __fmt[8] = {'%', 0};
1474 const char* __len = "ll";
1475 this->__format_int(__fmt+1, __len, false, __iob.flags());
1476 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1477 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1478 + ((__iob.flags() & ios_base::showbase) != 0)
1481 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1482 char* __ne = __nar + __nc;
1483 char* __np = this->__identify_padding(__nar, __ne, __iob);
1484 // Stage 2 - Widen __nar while adding thousands separators
1485 char_type __o[2*(__nbuf-1) - 1];
1486 char_type* __op; // pad here
1487 char_type* __oe; // end of output
1488 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1489 // [__o, __oe) contains thousands_sep'd wide number
1491 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1494 template <class _CharT, class _OutputIterator>
1496 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1497 char_type __fl, double __v) const
1499 // Stage 1 - Get number in narrow char
1500 char __fmt[8] = {'%', 0};
1501 const char* __len = "";
1502 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1503 const unsigned __nbuf = 30;
1507 if (__specify_precision)
1508 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1509 (int)__iob.precision(), __v);
1511 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1512 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1513 if (__nc > static_cast<int>(__nbuf-1))
1515 if (__specify_precision)
1516 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1518 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1520 __throw_bad_alloc();
1523 char* __ne = __nb + __nc;
1524 char* __np = this->__identify_padding(__nb, __ne, __iob);
1525 // Stage 2 - Widen __nar while adding thousands separators
1526 char_type __o[2*(__nbuf-1) - 1];
1527 char_type* __ob = __o;
1528 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1531 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1533 __throw_bad_alloc();
1536 char_type* __op; // pad here
1537 char_type* __oe; // end of output
1538 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1539 // [__o, __oe) contains thousands_sep'd wide number
1541 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1545 template <class _CharT, class _OutputIterator>
1547 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1548 char_type __fl, long double __v) const
1550 // Stage 1 - Get number in narrow char
1551 char __fmt[8] = {'%', 0};
1552 const char* __len = "L";
1553 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1554 const unsigned __nbuf = 30;
1558 if (__specify_precision)
1559 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1560 (int)__iob.precision(), __v);
1562 __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1563 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1564 if (__nc > static_cast<int>(__nbuf-1))
1566 if (__specify_precision)
1567 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1569 __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1571 __throw_bad_alloc();
1574 char* __ne = __nb + __nc;
1575 char* __np = this->__identify_padding(__nb, __ne, __iob);
1576 // Stage 2 - Widen __nar while adding thousands separators
1577 char_type __o[2*(__nbuf-1) - 1];
1578 char_type* __ob = __o;
1579 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1582 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1584 __throw_bad_alloc();
1587 char_type* __op; // pad here
1588 char_type* __oe; // end of output
1589 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1590 // [__o, __oe) contains thousands_sep'd wide number
1592 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1596 template <class _CharT, class _OutputIterator>
1598 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1599 char_type __fl, const void* __v) const
1601 // Stage 1 - Get pointer in narrow char
1602 char __fmt[6] = "%p";
1603 const unsigned __nbuf = 20;
1605 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1606 char* __ne = __nar + __nc;
1607 char* __np = this->__identify_padding(__nar, __ne, __iob);
1608 // Stage 2 - Widen __nar
1609 char_type __o[2*(__nbuf-1) - 1];
1610 char_type* __op; // pad here
1611 char_type* __oe; // end of output
1612 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1613 __ct.widen(__nar, __ne, __o);
1614 __oe = __o + (__ne - __nar);
1618 __op = __o + (__np - __nar);
1619 // [__o, __oe) contains wide number
1621 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1624 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>)
1625 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>)
1627 template <class _CharT, class _InputIterator>
1630 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1631 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1633 // Precondition: __n >= 1
1636 __err |= ios_base::eofbit | ios_base::failbit;
1641 if (!__ct.is(ctype_base::digit, __c))
1643 __err |= ios_base::failbit;
1646 int __r = __ct.narrow(__c, 0) - '0';
1647 for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
1651 if (!__ct.is(ctype_base::digit, __c))
1653 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1656 __err |= ios_base::eofbit;
1660 class _LIBCPP_TYPE_VIS time_base
1663 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1666 template <class _CharT>
1667 class _LIBCPP_TEMPLATE_VIS __time_get_c_storage
1670 typedef basic_string<_CharT> string_type;
1672 virtual const string_type* __weeks() const;
1673 virtual const string_type* __months() const;
1674 virtual const string_type* __am_pm() const;
1675 virtual const string_type& __c() const;
1676 virtual const string_type& __r() const;
1677 virtual const string_type& __x() const;
1678 virtual const string_type& __X() const;
1680 _LIBCPP_ALWAYS_INLINE
1681 ~__time_get_c_storage() {}
1684 template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const;
1685 template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const;
1686 template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const;
1687 template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const;
1688 template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const;
1689 template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const;
1690 template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const;
1692 template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
1693 template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const;
1694 template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
1695 template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const;
1696 template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const;
1697 template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const;
1698 template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const;
1700 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1701 class _LIBCPP_TEMPLATE_VIS time_get
1702 : public locale::facet,
1704 private __time_get_c_storage<_CharT>
1707 typedef _CharT char_type;
1708 typedef _InputIterator iter_type;
1709 typedef time_base::dateorder dateorder;
1710 typedef basic_string<char_type> string_type;
1712 _LIBCPP_ALWAYS_INLINE
1713 explicit time_get(size_t __refs = 0)
1714 : locale::facet(__refs) {}
1716 _LIBCPP_ALWAYS_INLINE
1717 dateorder date_order() const
1719 return this->do_date_order();
1722 _LIBCPP_ALWAYS_INLINE
1723 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1724 ios_base::iostate& __err, tm* __tm) const
1726 return do_get_time(__b, __e, __iob, __err, __tm);
1729 _LIBCPP_ALWAYS_INLINE
1730 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1731 ios_base::iostate& __err, tm* __tm) const
1733 return do_get_date(__b, __e, __iob, __err, __tm);
1736 _LIBCPP_ALWAYS_INLINE
1737 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1738 ios_base::iostate& __err, tm* __tm) const
1740 return do_get_weekday(__b, __e, __iob, __err, __tm);
1743 _LIBCPP_ALWAYS_INLINE
1744 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1745 ios_base::iostate& __err, tm* __tm) const
1747 return do_get_monthname(__b, __e, __iob, __err, __tm);
1750 _LIBCPP_ALWAYS_INLINE
1751 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1752 ios_base::iostate& __err, tm* __tm) const
1754 return do_get_year(__b, __e, __iob, __err, __tm);
1757 _LIBCPP_ALWAYS_INLINE
1758 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1759 ios_base::iostate& __err, tm *__tm,
1760 char __fmt, char __mod = 0) const
1762 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1765 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1766 ios_base::iostate& __err, tm* __tm,
1767 const char_type* __fmtb, const char_type* __fmte) const;
1769 static locale::id id;
1772 _LIBCPP_ALWAYS_INLINE
1775 virtual dateorder do_date_order() const;
1776 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1777 ios_base::iostate& __err, tm* __tm) const;
1778 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1779 ios_base::iostate& __err, tm* __tm) const;
1780 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1781 ios_base::iostate& __err, tm* __tm) const;
1782 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1783 ios_base::iostate& __err, tm* __tm) const;
1784 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1785 ios_base::iostate& __err, tm* __tm) const;
1786 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1787 ios_base::iostate& __err, tm* __tm,
1788 char __fmt, char __mod) const;
1790 void __get_white_space(iter_type& __b, iter_type __e,
1791 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1792 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1793 const ctype<char_type>& __ct) const;
1795 void __get_weekdayname(int& __m,
1796 iter_type& __b, iter_type __e,
1797 ios_base::iostate& __err,
1798 const ctype<char_type>& __ct) const;
1799 void __get_monthname(int& __m,
1800 iter_type& __b, iter_type __e,
1801 ios_base::iostate& __err,
1802 const ctype<char_type>& __ct) const;
1803 void __get_day(int& __d,
1804 iter_type& __b, iter_type __e,
1805 ios_base::iostate& __err,
1806 const ctype<char_type>& __ct) const;
1807 void __get_month(int& __m,
1808 iter_type& __b, iter_type __e,
1809 ios_base::iostate& __err,
1810 const ctype<char_type>& __ct) const;
1811 void __get_year(int& __y,
1812 iter_type& __b, iter_type __e,
1813 ios_base::iostate& __err,
1814 const ctype<char_type>& __ct) const;
1815 void __get_year4(int& __y,
1816 iter_type& __b, iter_type __e,
1817 ios_base::iostate& __err,
1818 const ctype<char_type>& __ct) const;
1819 void __get_hour(int& __d,
1820 iter_type& __b, iter_type __e,
1821 ios_base::iostate& __err,
1822 const ctype<char_type>& __ct) const;
1823 void __get_12_hour(int& __h,
1824 iter_type& __b, iter_type __e,
1825 ios_base::iostate& __err,
1826 const ctype<char_type>& __ct) const;
1827 void __get_am_pm(int& __h,
1828 iter_type& __b, iter_type __e,
1829 ios_base::iostate& __err,
1830 const ctype<char_type>& __ct) const;
1831 void __get_minute(int& __m,
1832 iter_type& __b, iter_type __e,
1833 ios_base::iostate& __err,
1834 const ctype<char_type>& __ct) const;
1835 void __get_second(int& __s,
1836 iter_type& __b, iter_type __e,
1837 ios_base::iostate& __err,
1838 const ctype<char_type>& __ct) const;
1839 void __get_weekday(int& __w,
1840 iter_type& __b, iter_type __e,
1841 ios_base::iostate& __err,
1842 const ctype<char_type>& __ct) const;
1843 void __get_day_year_num(int& __w,
1844 iter_type& __b, iter_type __e,
1845 ios_base::iostate& __err,
1846 const ctype<char_type>& __ct) const;
1849 template <class _CharT, class _InputIterator>
1851 time_get<_CharT, _InputIterator>::id;
1853 // time_get primitives
1855 template <class _CharT, class _InputIterator>
1857 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
1858 iter_type& __b, iter_type __e,
1859 ios_base::iostate& __err,
1860 const ctype<char_type>& __ct) const
1862 // Note: ignoring case comes from the POSIX strptime spec
1863 const string_type* __wk = this->__weeks();
1864 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
1869 template <class _CharT, class _InputIterator>
1871 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
1872 iter_type& __b, iter_type __e,
1873 ios_base::iostate& __err,
1874 const ctype<char_type>& __ct) const
1876 // Note: ignoring case comes from the POSIX strptime spec
1877 const string_type* __month = this->__months();
1878 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
1883 template <class _CharT, class _InputIterator>
1885 time_get<_CharT, _InputIterator>::__get_day(int& __d,
1886 iter_type& __b, iter_type __e,
1887 ios_base::iostate& __err,
1888 const ctype<char_type>& __ct) const
1890 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1891 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
1894 __err |= ios_base::failbit;
1897 template <class _CharT, class _InputIterator>
1899 time_get<_CharT, _InputIterator>::__get_month(int& __m,
1900 iter_type& __b, iter_type __e,
1901 ios_base::iostate& __err,
1902 const ctype<char_type>& __ct) const
1904 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
1905 if (!(__err & ios_base::failbit) && __t <= 11)
1908 __err |= ios_base::failbit;
1911 template <class _CharT, class _InputIterator>
1913 time_get<_CharT, _InputIterator>::__get_year(int& __y,
1914 iter_type& __b, iter_type __e,
1915 ios_base::iostate& __err,
1916 const ctype<char_type>& __ct) const
1918 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1919 if (!(__err & ios_base::failbit))
1923 else if (69 <= __t && __t <= 99)
1929 template <class _CharT, class _InputIterator>
1931 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
1932 iter_type& __b, iter_type __e,
1933 ios_base::iostate& __err,
1934 const ctype<char_type>& __ct) const
1936 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1937 if (!(__err & ios_base::failbit))
1941 template <class _CharT, class _InputIterator>
1943 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
1944 iter_type& __b, iter_type __e,
1945 ios_base::iostate& __err,
1946 const ctype<char_type>& __ct) const
1948 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1949 if (!(__err & ios_base::failbit) && __t <= 23)
1952 __err |= ios_base::failbit;
1955 template <class _CharT, class _InputIterator>
1957 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
1958 iter_type& __b, iter_type __e,
1959 ios_base::iostate& __err,
1960 const ctype<char_type>& __ct) const
1962 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1963 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
1966 __err |= ios_base::failbit;
1969 template <class _CharT, class _InputIterator>
1971 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
1972 iter_type& __b, iter_type __e,
1973 ios_base::iostate& __err,
1974 const ctype<char_type>& __ct) const
1976 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1977 if (!(__err & ios_base::failbit) && __t <= 59)
1980 __err |= ios_base::failbit;
1983 template <class _CharT, class _InputIterator>
1985 time_get<_CharT, _InputIterator>::__get_second(int& __s,
1986 iter_type& __b, iter_type __e,
1987 ios_base::iostate& __err,
1988 const ctype<char_type>& __ct) const
1990 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1991 if (!(__err & ios_base::failbit) && __t <= 60)
1994 __err |= ios_base::failbit;
1997 template <class _CharT, class _InputIterator>
1999 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2000 iter_type& __b, iter_type __e,
2001 ios_base::iostate& __err,
2002 const ctype<char_type>& __ct) const
2004 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2005 if (!(__err & ios_base::failbit) && __t <= 6)
2008 __err |= ios_base::failbit;
2011 template <class _CharT, class _InputIterator>
2013 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2014 iter_type& __b, iter_type __e,
2015 ios_base::iostate& __err,
2016 const ctype<char_type>& __ct) const
2018 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2019 if (!(__err & ios_base::failbit) && __t <= 365)
2022 __err |= ios_base::failbit;
2025 template <class _CharT, class _InputIterator>
2027 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2028 ios_base::iostate& __err,
2029 const ctype<char_type>& __ct) const
2031 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2034 __err |= ios_base::eofbit;
2037 template <class _CharT, class _InputIterator>
2039 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2040 iter_type& __b, iter_type __e,
2041 ios_base::iostate& __err,
2042 const ctype<char_type>& __ct) const
2044 const string_type* __ap = this->__am_pm();
2045 if (__ap[0].size() + __ap[1].size() == 0)
2047 __err |= ios_base::failbit;
2050 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2051 if (__i == 0 && __h == 12)
2053 else if (__i == 1 && __h < 12)
2057 template <class _CharT, class _InputIterator>
2059 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2060 ios_base::iostate& __err,
2061 const ctype<char_type>& __ct) const
2065 __err |= ios_base::eofbit | ios_base::failbit;
2068 if (__ct.narrow(*__b, 0) != '%')
2069 __err |= ios_base::failbit;
2070 else if(++__b == __e)
2071 __err |= ios_base::eofbit;
2074 // time_get end primitives
2076 template <class _CharT, class _InputIterator>
2078 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2080 ios_base::iostate& __err, tm* __tm,
2081 const char_type* __fmtb, const char_type* __fmte) const
2083 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2084 __err = ios_base::goodbit;
2085 while (__fmtb != __fmte && __err == ios_base::goodbit)
2089 __err = ios_base::failbit;
2092 if (__ct.narrow(*__fmtb, 0) == '%')
2094 if (++__fmtb == __fmte)
2096 __err = ios_base::failbit;
2099 char __cmd = __ct.narrow(*__fmtb, 0);
2101 if (__cmd == 'E' || __cmd == '0')
2103 if (++__fmtb == __fmte)
2105 __err = ios_base::failbit;
2109 __cmd = __ct.narrow(*__fmtb, 0);
2111 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2114 else if (__ct.is(ctype_base::space, *__fmtb))
2116 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2118 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2121 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2127 __err = ios_base::failbit;
2130 __err |= ios_base::eofbit;
2134 template <class _CharT, class _InputIterator>
2135 typename time_get<_CharT, _InputIterator>::dateorder
2136 time_get<_CharT, _InputIterator>::do_date_order() const
2141 template <class _CharT, class _InputIterator>
2143 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2145 ios_base::iostate& __err,
2148 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2149 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2152 template <class _CharT, class _InputIterator>
2154 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2156 ios_base::iostate& __err,
2159 const string_type& __fmt = this->__x();
2160 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2163 template <class _CharT, class _InputIterator>
2165 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2167 ios_base::iostate& __err,
2170 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2171 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2175 template <class _CharT, class _InputIterator>
2177 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2179 ios_base::iostate& __err,
2182 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2183 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2187 template <class _CharT, class _InputIterator>
2189 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2191 ios_base::iostate& __err,
2194 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2195 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2199 template <class _CharT, class _InputIterator>
2201 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2203 ios_base::iostate& __err, tm* __tm,
2204 char __fmt, char) const
2206 __err = ios_base::goodbit;
2207 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2212 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2217 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2221 const string_type& __fm = this->__c();
2222 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2227 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2231 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2232 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2237 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2238 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2242 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2245 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2248 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2251 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2254 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2258 __get_white_space(__b, __e, __err, __ct);
2261 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2265 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2266 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2271 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2272 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2276 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2280 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2281 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2285 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2288 return do_get_date(__b, __e, __iob, __err, __tm);
2291 const string_type& __fm = this->__X();
2292 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2296 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2299 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2302 __get_percent(__b, __e, __err, __ct);
2305 __err |= ios_base::failbit;
2310 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>)
2311 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>)
2313 class _LIBCPP_TYPE_VIS __time_get
2318 __time_get(const char* __nm);
2319 __time_get(const string& __nm);
2323 template <class _CharT>
2324 class _LIBCPP_TEMPLATE_VIS __time_get_storage
2328 typedef basic_string<_CharT> string_type;
2330 string_type __weeks_[14];
2331 string_type __months_[24];
2332 string_type __am_pm_[2];
2338 explicit __time_get_storage(const char* __nm);
2339 explicit __time_get_storage(const string& __nm);
2341 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2343 time_base::dateorder __do_date_order() const;
2346 void init(const ctype<_CharT>&);
2347 string_type __analyze(char __fmt, const ctype<_CharT>&);
2350 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2351 class _LIBCPP_TEMPLATE_VIS time_get_byname
2352 : public time_get<_CharT, _InputIterator>,
2353 private __time_get_storage<_CharT>
2356 typedef time_base::dateorder dateorder;
2357 typedef _InputIterator iter_type;
2358 typedef _CharT char_type;
2359 typedef basic_string<char_type> string_type;
2361 _LIBCPP_INLINE_VISIBILITY
2362 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2363 : time_get<_CharT, _InputIterator>(__refs),
2364 __time_get_storage<_CharT>(__nm) {}
2365 _LIBCPP_INLINE_VISIBILITY
2366 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2367 : time_get<_CharT, _InputIterator>(__refs),
2368 __time_get_storage<_CharT>(__nm) {}
2371 _LIBCPP_INLINE_VISIBILITY
2372 ~time_get_byname() {}
2374 _LIBCPP_INLINE_VISIBILITY
2375 virtual dateorder do_date_order() const {return this->__do_date_order();}
2377 _LIBCPP_INLINE_VISIBILITY
2378 virtual const string_type* __weeks() const {return this->__weeks_;}
2379 _LIBCPP_INLINE_VISIBILITY
2380 virtual const string_type* __months() const {return this->__months_;}
2381 _LIBCPP_INLINE_VISIBILITY
2382 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2383 _LIBCPP_INLINE_VISIBILITY
2384 virtual const string_type& __c() const {return this->__c_;}
2385 _LIBCPP_INLINE_VISIBILITY
2386 virtual const string_type& __r() const {return this->__r_;}
2387 _LIBCPP_INLINE_VISIBILITY
2388 virtual const string_type& __x() const {return this->__x_;}
2389 _LIBCPP_INLINE_VISIBILITY
2390 virtual const string_type& __X() const {return this->__X_;}
2393 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>)
2394 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>)
2396 class _LIBCPP_TYPE_VIS __time_put
2400 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2401 __time_put(const char* __nm);
2402 __time_put(const string& __nm);
2404 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2405 char __fmt, char __mod) const;
2406 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2407 char __fmt, char __mod) const;
2410 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2411 class _LIBCPP_TEMPLATE_VIS time_put
2412 : public locale::facet,
2416 typedef _CharT char_type;
2417 typedef _OutputIterator iter_type;
2419 _LIBCPP_ALWAYS_INLINE
2420 explicit time_put(size_t __refs = 0)
2421 : locale::facet(__refs) {}
2423 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2424 const char_type* __pb, const char_type* __pe) const;
2426 _LIBCPP_ALWAYS_INLINE
2427 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2428 const tm* __tm, char __fmt, char __mod = 0) const
2430 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2433 static locale::id id;
2436 _LIBCPP_ALWAYS_INLINE
2438 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2439 char __fmt, char __mod) const;
2441 _LIBCPP_ALWAYS_INLINE
2442 explicit time_put(const char* __nm, size_t __refs)
2443 : locale::facet(__refs),
2445 _LIBCPP_ALWAYS_INLINE
2446 explicit time_put(const string& __nm, size_t __refs)
2447 : locale::facet(__refs),
2451 template <class _CharT, class _OutputIterator>
2453 time_put<_CharT, _OutputIterator>::id;
2455 template <class _CharT, class _OutputIterator>
2457 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2458 char_type __fl, const tm* __tm,
2459 const char_type* __pb,
2460 const char_type* __pe) const
2462 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2463 for (; __pb != __pe; ++__pb)
2465 if (__ct.narrow(*__pb, 0) == '%')
2473 char __fmt = __ct.narrow(*__pb, 0);
2474 if (__fmt == 'E' || __fmt == 'O')
2483 __fmt = __ct.narrow(*__pb, 0);
2485 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2493 template <class _CharT, class _OutputIterator>
2495 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2496 char_type, const tm* __tm,
2497 char __fmt, char __mod) const
2499 char_type __nar[100];
2500 char_type* __nb = __nar;
2501 char_type* __ne = __nb + 100;
2502 __do_put(__nb, __ne, __tm, __fmt, __mod);
2503 return _VSTD::copy(__nb, __ne, __s);
2506 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>)
2507 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>)
2509 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2510 class _LIBCPP_TEMPLATE_VIS time_put_byname
2511 : public time_put<_CharT, _OutputIterator>
2514 _LIBCPP_ALWAYS_INLINE
2515 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2516 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2518 _LIBCPP_ALWAYS_INLINE
2519 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2520 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2523 _LIBCPP_ALWAYS_INLINE
2524 ~time_put_byname() {}
2527 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>)
2528 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>)
2532 class _LIBCPP_TYPE_VIS money_base
2535 enum part {none, space, symbol, sign, value};
2536 struct pattern {char field[4];};
2538 _LIBCPP_ALWAYS_INLINE money_base() {}
2543 template <class _CharT, bool _International = false>
2544 class _LIBCPP_TEMPLATE_VIS moneypunct
2545 : public locale::facet,
2549 typedef _CharT char_type;
2550 typedef basic_string<char_type> string_type;
2552 _LIBCPP_ALWAYS_INLINE
2553 explicit moneypunct(size_t __refs = 0)
2554 : locale::facet(__refs) {}
2556 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2557 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2558 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2559 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2560 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2561 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2562 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2563 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2564 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2566 static locale::id id;
2567 static const bool intl = _International;
2570 _LIBCPP_ALWAYS_INLINE
2573 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2574 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2575 virtual string do_grouping() const {return string();}
2576 virtual string_type do_curr_symbol() const {return string_type();}
2577 virtual string_type do_positive_sign() const {return string_type();}
2578 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2579 virtual int do_frac_digits() const {return 0;}
2580 virtual pattern do_pos_format() const
2581 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2582 virtual pattern do_neg_format() const
2583 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2586 template <class _CharT, bool _International>
2588 moneypunct<_CharT, _International>::id;
2590 template <class _CharT, bool _International>
2592 moneypunct<_CharT, _International>::intl;
2594 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>)
2595 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>)
2596 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>)
2597 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>)
2599 // moneypunct_byname
2601 template <class _CharT, bool _International = false>
2602 class _LIBCPP_TEMPLATE_VIS moneypunct_byname
2603 : public moneypunct<_CharT, _International>
2606 typedef money_base::pattern pattern;
2607 typedef _CharT char_type;
2608 typedef basic_string<char_type> string_type;
2610 _LIBCPP_ALWAYS_INLINE
2611 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2612 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2614 _LIBCPP_ALWAYS_INLINE
2615 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2616 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2619 _LIBCPP_ALWAYS_INLINE
2620 ~moneypunct_byname() {}
2622 virtual char_type do_decimal_point() const {return __decimal_point_;}
2623 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2624 virtual string do_grouping() const {return __grouping_;}
2625 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2626 virtual string_type do_positive_sign() const {return __positive_sign_;}
2627 virtual string_type do_negative_sign() const {return __negative_sign_;}
2628 virtual int do_frac_digits() const {return __frac_digits_;}
2629 virtual pattern do_pos_format() const {return __pos_format_;}
2630 virtual pattern do_neg_format() const {return __neg_format_;}
2633 char_type __decimal_point_;
2634 char_type __thousands_sep_;
2636 string_type __curr_symbol_;
2637 string_type __positive_sign_;
2638 string_type __negative_sign_;
2640 pattern __pos_format_;
2641 pattern __neg_format_;
2643 void init(const char*);
2646 template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*);
2647 template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*);
2648 template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*);
2649 template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*);
2651 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>)
2652 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>)
2653 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>)
2654 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>)
2658 template <class _CharT>
2662 typedef _CharT char_type;
2663 typedef basic_string<char_type> string_type;
2665 _LIBCPP_ALWAYS_INLINE __money_get() {}
2667 static void __gather_info(bool __intl, const locale& __loc,
2668 money_base::pattern& __pat, char_type& __dp,
2669 char_type& __ts, string& __grp,
2670 string_type& __sym, string_type& __psn,
2671 string_type& __nsn, int& __fd);
2674 template <class _CharT>
2676 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2677 money_base::pattern& __pat, char_type& __dp,
2678 char_type& __ts, string& __grp,
2679 string_type& __sym, string_type& __psn,
2680 string_type& __nsn, int& __fd)
2684 const moneypunct<char_type, true>& __mp =
2685 use_facet<moneypunct<char_type, true> >(__loc);
2686 __pat = __mp.neg_format();
2687 __nsn = __mp.negative_sign();
2688 __psn = __mp.positive_sign();
2689 __dp = __mp.decimal_point();
2690 __ts = __mp.thousands_sep();
2691 __grp = __mp.grouping();
2692 __sym = __mp.curr_symbol();
2693 __fd = __mp.frac_digits();
2697 const moneypunct<char_type, false>& __mp =
2698 use_facet<moneypunct<char_type, false> >(__loc);
2699 __pat = __mp.neg_format();
2700 __nsn = __mp.negative_sign();
2701 __psn = __mp.positive_sign();
2702 __dp = __mp.decimal_point();
2703 __ts = __mp.thousands_sep();
2704 __grp = __mp.grouping();
2705 __sym = __mp.curr_symbol();
2706 __fd = __mp.frac_digits();
2710 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>)
2711 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>)
2713 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2714 class _LIBCPP_TEMPLATE_VIS money_get
2715 : public locale::facet,
2716 private __money_get<_CharT>
2719 typedef _CharT char_type;
2720 typedef _InputIterator iter_type;
2721 typedef basic_string<char_type> string_type;
2723 _LIBCPP_ALWAYS_INLINE
2724 explicit money_get(size_t __refs = 0)
2725 : locale::facet(__refs) {}
2727 _LIBCPP_ALWAYS_INLINE
2728 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2729 ios_base::iostate& __err, long double& __v) const
2731 return do_get(__b, __e, __intl, __iob, __err, __v);
2734 _LIBCPP_ALWAYS_INLINE
2735 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2736 ios_base::iostate& __err, string_type& __v) const
2738 return do_get(__b, __e, __intl, __iob, __err, __v);
2741 static locale::id id;
2745 _LIBCPP_ALWAYS_INLINE
2748 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2749 ios_base& __iob, ios_base::iostate& __err,
2750 long double& __v) const;
2751 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2752 ios_base& __iob, ios_base::iostate& __err,
2753 string_type& __v) const;
2756 static bool __do_get(iter_type& __b, iter_type __e,
2757 bool __intl, const locale& __loc,
2758 ios_base::fmtflags __flags, ios_base::iostate& __err,
2759 bool& __neg, const ctype<char_type>& __ct,
2760 unique_ptr<char_type, void(*)(void*)>& __wb,
2761 char_type*& __wn, char_type* __we);
2764 template <class _CharT, class _InputIterator>
2766 money_get<_CharT, _InputIterator>::id;
2768 _LIBCPP_FUNC_VIS void __do_nothing(void*);
2770 template <class _Tp>
2773 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2775 bool __owns = __b.get_deleter() != __do_nothing;
2776 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
2777 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2778 2 * __cur_cap : numeric_limits<size_t>::max();
2780 __new_cap = sizeof(_Tp);
2781 size_t __n_off = static_cast<size_t>(__n - __b.get());
2782 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2784 __throw_bad_alloc();
2787 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2788 __new_cap /= sizeof(_Tp);
2789 __n = __b.get() + __n_off;
2790 __e = __b.get() + __new_cap;
2794 template <class _CharT, class _InputIterator>
2796 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2797 bool __intl, const locale& __loc,
2798 ios_base::fmtflags __flags,
2799 ios_base::iostate& __err,
2801 const ctype<char_type>& __ct,
2802 unique_ptr<char_type, void(*)(void*)>& __wb,
2803 char_type*& __wn, char_type* __we)
2805 const unsigned __bz = 100;
2806 unsigned __gbuf[__bz];
2807 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
2808 unsigned* __gn = __gb.get();
2809 unsigned* __ge = __gn + __bz;
2810 money_base::pattern __pat;
2817 // Capture the spaces read into money_base::{space,none} so they
2818 // can be compared to initial spaces in __sym.
2819 string_type __spaces;
2821 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
2822 __sym, __psn, __nsn, __fd);
2823 const string_type* __trailing_sign = 0;
2825 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
2827 switch (__pat.field[__p])
2829 case money_base::space:
2832 if (__ct.is(ctype_base::space, *__b))
2833 __spaces.push_back(*__b++);
2836 __err |= ios_base::failbit;
2840 _LIBCPP_FALLTHROUGH();
2841 case money_base::none:
2844 while (__b != __e && __ct.is(ctype_base::space, *__b))
2845 __spaces.push_back(*__b++);
2848 case money_base::sign:
2849 if (__psn.size() + __nsn.size() > 0)
2851 if (__psn.size() == 0 || __nsn.size() == 0)
2852 { // sign is optional
2853 if (__psn.size() > 0)
2854 { // __nsn.size() == 0
2855 if (*__b == __psn[0])
2858 if (__psn.size() > 1)
2859 __trailing_sign = &__psn;
2864 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
2868 if (__nsn.size() > 1)
2869 __trailing_sign = &__nsn;
2872 else // sign is required
2874 if (*__b == __psn[0])
2877 if (__psn.size() > 1)
2878 __trailing_sign = &__psn;
2880 else if (*__b == __nsn[0])
2884 if (__nsn.size() > 1)
2885 __trailing_sign = &__nsn;
2889 __err |= ios_base::failbit;
2895 case money_base::symbol:
2897 bool __more_needed = __trailing_sign ||
2899 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
2900 bool __sb = (__flags & ios_base::showbase) != 0;
2901 if (__sb || __more_needed)
2903 typename string_type::const_iterator __sym_space_end = __sym.begin();
2904 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
2905 __pat.field[__p - 1] == money_base::space)) {
2906 // Match spaces we've already read against spaces at
2907 // the beginning of __sym.
2908 while (__sym_space_end != __sym.end() &&
2909 __ct.is(ctype_base::space, *__sym_space_end))
2911 const size_t __num_spaces = __sym_space_end - __sym.begin();
2912 if (__num_spaces > __spaces.size() ||
2913 !equal(__spaces.end() - __num_spaces, __spaces.end(),
2915 // No match. Put __sym_space_end back at the
2916 // beginning of __sym, which will prevent a
2917 // match in the next loop.
2918 __sym_space_end = __sym.begin();
2921 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
2922 while (__sym_curr_char != __sym.end() && __b != __e &&
2923 *__b == *__sym_curr_char) {
2927 if (__sb && __sym_curr_char != __sym.end())
2929 __err |= ios_base::failbit;
2935 case money_base::value:
2938 for (; __b != __e; ++__b)
2940 char_type __c = *__b;
2941 if (__ct.is(ctype_base::digit, __c))
2944 __double_or_nothing(__wb, __wn, __we);
2948 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
2951 __double_or_nothing(__gb, __gn, __ge);
2958 if (__gb.get() != __gn && __ng > 0)
2961 __double_or_nothing(__gb, __gn, __ge);
2966 if (__b == __e || *__b != __dp)
2968 __err |= ios_base::failbit;
2971 for (++__b; __fd > 0; --__fd, ++__b)
2973 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
2975 __err |= ios_base::failbit;
2979 __double_or_nothing(__wb, __wn, __we);
2983 if (__wn == __wb.get())
2985 __err |= ios_base::failbit;
2992 if (__trailing_sign)
2994 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
2996 if (__b == __e || *__b != (*__trailing_sign)[__i])
2998 __err |= ios_base::failbit;
3003 if (__gb.get() != __gn)
3005 ios_base::iostate __et = ios_base::goodbit;
3006 __check_grouping(__grp, __gb.get(), __gn, __et);
3009 __err |= ios_base::failbit;
3016 template <class _CharT, class _InputIterator>
3018 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3019 bool __intl, ios_base& __iob,
3020 ios_base::iostate& __err,
3021 long double& __v) const
3023 const int __bz = 100;
3024 char_type __wbuf[__bz];
3025 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3027 char_type* __we = __wbuf + __bz;
3028 locale __loc = __iob.getloc();
3029 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3031 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3034 const char __src[] = "0123456789";
3035 char_type __atoms[sizeof(__src)-1];
3036 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3038 char* __nc = __nbuf;
3039 unique_ptr<char, void(*)(void*)> __h(0, free);
3040 if (__wn - __wb.get() > __bz-2)
3042 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3044 __throw_bad_alloc();
3049 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3050 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3052 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3053 __throw_runtime_error("money_get error");
3056 __err |= ios_base::eofbit;
3060 template <class _CharT, class _InputIterator>
3062 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3063 bool __intl, ios_base& __iob,
3064 ios_base::iostate& __err,
3065 string_type& __v) const
3067 const int __bz = 100;
3068 char_type __wbuf[__bz];
3069 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3071 char_type* __we = __wbuf + __bz;
3072 locale __loc = __iob.getloc();
3073 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3075 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3080 __v.push_back(__ct.widen('-'));
3081 char_type __z = __ct.widen('0');
3083 for (__w = __wb.get(); __w < __wn-1; ++__w)
3086 __v.append(__w, __wn);
3089 __err |= ios_base::eofbit;
3093 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>)
3094 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>)
3098 template <class _CharT>
3102 typedef _CharT char_type;
3103 typedef basic_string<char_type> string_type;
3105 _LIBCPP_ALWAYS_INLINE __money_put() {}
3107 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3108 money_base::pattern& __pat, char_type& __dp,
3109 char_type& __ts, string& __grp,
3110 string_type& __sym, string_type& __sn,
3112 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3113 ios_base::fmtflags __flags,
3114 const char_type* __db, const char_type* __de,
3115 const ctype<char_type>& __ct, bool __neg,
3116 const money_base::pattern& __pat, char_type __dp,
3117 char_type __ts, const string& __grp,
3118 const string_type& __sym, const string_type& __sn,
3122 template <class _CharT>
3124 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3125 money_base::pattern& __pat, char_type& __dp,
3126 char_type& __ts, string& __grp,
3127 string_type& __sym, string_type& __sn,
3132 const moneypunct<char_type, true>& __mp =
3133 use_facet<moneypunct<char_type, true> >(__loc);
3136 __pat = __mp.neg_format();
3137 __sn = __mp.negative_sign();
3141 __pat = __mp.pos_format();
3142 __sn = __mp.positive_sign();
3144 __dp = __mp.decimal_point();
3145 __ts = __mp.thousands_sep();
3146 __grp = __mp.grouping();
3147 __sym = __mp.curr_symbol();
3148 __fd = __mp.frac_digits();
3152 const moneypunct<char_type, false>& __mp =
3153 use_facet<moneypunct<char_type, false> >(__loc);
3156 __pat = __mp.neg_format();
3157 __sn = __mp.negative_sign();
3161 __pat = __mp.pos_format();
3162 __sn = __mp.positive_sign();
3164 __dp = __mp.decimal_point();
3165 __ts = __mp.thousands_sep();
3166 __grp = __mp.grouping();
3167 __sym = __mp.curr_symbol();
3168 __fd = __mp.frac_digits();
3172 template <class _CharT>
3174 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3175 ios_base::fmtflags __flags,
3176 const char_type* __db, const char_type* __de,
3177 const ctype<char_type>& __ct, bool __neg,
3178 const money_base::pattern& __pat, char_type __dp,
3179 char_type __ts, const string& __grp,
3180 const string_type& __sym, const string_type& __sn,
3184 for (unsigned __p = 0; __p < 4; ++__p)
3186 switch (__pat.field[__p])
3188 case money_base::none:
3191 case money_base::space:
3193 *__me++ = __ct.widen(' ');
3195 case money_base::sign:
3199 case money_base::symbol:
3200 if (!__sym.empty() && (__flags & ios_base::showbase))
3201 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3203 case money_base::value:
3205 // remember start of value so we can reverse it
3206 char_type* __t = __me;
3207 // find beginning of digits
3210 // find end of digits
3211 const char_type* __d;
3212 for (__d = __db; __d < __de; ++__d)
3213 if (!__ct.is(ctype_base::digit, *__d))
3215 // print fractional part
3219 for (__f = __fd; __d > __db && __f > 0; --__f)
3221 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3222 for (; __f > 0; --__f)
3229 *__me++ = __ct.widen('0');
3235 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3236 : static_cast<unsigned>(__grp[__ig]);
3243 if (++__ig < __grp.size())
3244 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3245 numeric_limits<unsigned>::max() :
3246 static_cast<unsigned>(__grp[__ig]);
3258 // print rest of sign, if any
3259 if (__sn.size() > 1)
3260 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3262 if ((__flags & ios_base::adjustfield) == ios_base::left)
3264 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3268 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>)
3269 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>)
3271 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3272 class _LIBCPP_TEMPLATE_VIS money_put
3273 : public locale::facet,
3274 private __money_put<_CharT>
3277 typedef _CharT char_type;
3278 typedef _OutputIterator iter_type;
3279 typedef basic_string<char_type> string_type;
3281 _LIBCPP_ALWAYS_INLINE
3282 explicit money_put(size_t __refs = 0)
3283 : locale::facet(__refs) {}
3285 _LIBCPP_ALWAYS_INLINE
3286 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3287 long double __units) const
3289 return do_put(__s, __intl, __iob, __fl, __units);
3292 _LIBCPP_ALWAYS_INLINE
3293 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3294 const string_type& __digits) const
3296 return do_put(__s, __intl, __iob, __fl, __digits);
3299 static locale::id id;
3302 _LIBCPP_ALWAYS_INLINE
3305 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3306 char_type __fl, long double __units) const;
3307 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3308 char_type __fl, const string_type& __digits) const;
3311 template <class _CharT, class _OutputIterator>
3313 money_put<_CharT, _OutputIterator>::id;
3315 template <class _CharT, class _OutputIterator>
3317 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3318 ios_base& __iob, char_type __fl,
3319 long double __units) const
3322 const size_t __bs = 100;
3325 char_type __digits[__bs];
3326 char_type* __db = __digits;
3327 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3328 unique_ptr<char, void(*)(void*)> __hn(0, free);
3329 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3330 // secure memory for digit storage
3333 __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3335 __throw_bad_alloc();
3337 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3338 if (__hd == nullptr)
3339 __throw_bad_alloc();
3343 locale __loc = __iob.getloc();
3344 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3345 __ct.widen(__bb, __bb + __n, __db);
3346 bool __neg = __n > 0 && __bb[0] == '-';
3347 money_base::pattern __pat;
3354 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3355 // secure memory for formatting
3356 char_type __mbuf[__bs];
3357 char_type* __mb = __mbuf;
3358 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3359 size_t __exn = static_cast<int>(__n) > __fd ?
3360 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3361 __sym.size() + static_cast<size_t>(__fd) + 1
3362 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3365 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3368 __throw_bad_alloc();
3373 this->__format(__mb, __mi, __me, __iob.flags(),
3374 __db, __db + __n, __ct,
3375 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3376 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3379 template <class _CharT, class _OutputIterator>
3381 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3382 ios_base& __iob, char_type __fl,
3383 const string_type& __digits) const
3386 locale __loc = __iob.getloc();
3387 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3388 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3389 money_base::pattern __pat;
3396 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3397 // secure memory for formatting
3398 char_type __mbuf[100];
3399 char_type* __mb = __mbuf;
3400 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3401 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3402 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3403 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3404 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3407 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3410 __throw_bad_alloc();
3415 this->__format(__mb, __mi, __me, __iob.flags(),
3416 __digits.data(), __digits.data() + __digits.size(), __ct,
3417 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3418 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3421 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>)
3422 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>)
3426 class _LIBCPP_TYPE_VIS messages_base
3429 typedef ptrdiff_t catalog;
3431 _LIBCPP_ALWAYS_INLINE messages_base() {}
3434 template <class _CharT>
3435 class _LIBCPP_TEMPLATE_VIS messages
3436 : public locale::facet,
3437 public messages_base
3440 typedef _CharT char_type;
3441 typedef basic_string<_CharT> string_type;
3443 _LIBCPP_ALWAYS_INLINE
3444 explicit messages(size_t __refs = 0)
3445 : locale::facet(__refs) {}
3447 _LIBCPP_ALWAYS_INLINE
3448 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3450 return do_open(__nm, __loc);
3453 _LIBCPP_ALWAYS_INLINE
3454 string_type get(catalog __c, int __set, int __msgid,
3455 const string_type& __dflt) const
3457 return do_get(__c, __set, __msgid, __dflt);
3460 _LIBCPP_ALWAYS_INLINE
3461 void close(catalog __c) const
3466 static locale::id id;
3469 _LIBCPP_ALWAYS_INLINE
3472 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3473 virtual string_type do_get(catalog, int __set, int __msgid,
3474 const string_type& __dflt) const;
3475 virtual void do_close(catalog) const;
3478 template <class _CharT>
3480 messages<_CharT>::id;
3482 template <class _CharT>
3483 typename messages<_CharT>::catalog
3484 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3486 #ifdef _LIBCPP_HAS_CATOPEN
3487 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3489 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3491 #else // !_LIBCPP_HAS_CATOPEN
3493 #endif // _LIBCPP_HAS_CATOPEN
3496 template <class _CharT>
3497 typename messages<_CharT>::string_type
3498 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3499 const string_type& __dflt) const
3501 #ifdef _LIBCPP_HAS_CATOPEN
3503 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3505 __dflt.c_str() + __dflt.size());
3508 nl_catd __cat = (nl_catd)__c;
3509 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3511 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3512 __n, __n + strlen(__n));
3514 #else // !_LIBCPP_HAS_CATOPEN
3516 #endif // _LIBCPP_HAS_CATOPEN
3519 template <class _CharT>
3521 messages<_CharT>::do_close(catalog __c) const
3523 #ifdef _LIBCPP_HAS_CATOPEN
3526 nl_catd __cat = (nl_catd)__c;
3528 #endif // _LIBCPP_HAS_CATOPEN
3531 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>)
3532 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>)
3534 template <class _CharT>
3535 class _LIBCPP_TEMPLATE_VIS messages_byname
3536 : public messages<_CharT>
3539 typedef messages_base::catalog catalog;
3540 typedef basic_string<_CharT> string_type;
3542 _LIBCPP_ALWAYS_INLINE
3543 explicit messages_byname(const char*, size_t __refs = 0)
3544 : messages<_CharT>(__refs) {}
3546 _LIBCPP_ALWAYS_INLINE
3547 explicit messages_byname(const string&, size_t __refs = 0)
3548 : messages<_CharT>(__refs) {}
3551 _LIBCPP_ALWAYS_INLINE
3552 ~messages_byname() {}
3555 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>)
3556 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>)
3558 template<class _Codecvt, class _Elem = wchar_t,
3559 class _Wide_alloc = allocator<_Elem>,
3560 class _Byte_alloc = allocator<char> >
3561 class _LIBCPP_TEMPLATE_VIS wstring_convert
3564 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3565 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3566 typedef typename _Codecvt::state_type state_type;
3567 typedef typename wide_string::traits_type::int_type int_type;
3570 byte_string __byte_err_string_;
3571 wide_string __wide_err_string_;
3572 _Codecvt* __cvtptr_;
3573 state_type __cvtstate_;
3576 wstring_convert(const wstring_convert& __wc);
3577 wstring_convert& operator=(const wstring_convert& __wc);
3579 _LIBCPP_ALWAYS_INLINE
3580 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3581 _LIBCPP_ALWAYS_INLINE
3582 wstring_convert(_Codecvt* __pcvt, state_type __state);
3583 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
3584 const wide_string& __wide_err = wide_string());
3585 #ifndef _LIBCPP_CXX03_LANG
3586 _LIBCPP_ALWAYS_INLINE
3587 wstring_convert(wstring_convert&& __wc);
3591 _LIBCPP_ALWAYS_INLINE
3592 wide_string from_bytes(char __byte)
3593 {return from_bytes(&__byte, &__byte+1);}
3594 _LIBCPP_ALWAYS_INLINE
3595 wide_string from_bytes(const char* __ptr)
3596 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3597 _LIBCPP_ALWAYS_INLINE
3598 wide_string from_bytes(const byte_string& __str)
3599 {return from_bytes(__str.data(), __str.data() + __str.size());}
3600 wide_string from_bytes(const char* __first, const char* __last);
3602 _LIBCPP_ALWAYS_INLINE
3603 byte_string to_bytes(_Elem __wchar)
3604 {return to_bytes(&__wchar, &__wchar+1);}
3605 _LIBCPP_ALWAYS_INLINE
3606 byte_string to_bytes(const _Elem* __wptr)
3607 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3608 _LIBCPP_ALWAYS_INLINE
3609 byte_string to_bytes(const wide_string& __wstr)
3610 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3611 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3613 _LIBCPP_ALWAYS_INLINE
3614 size_t converted() const _NOEXCEPT {return __cvtcount_;}
3615 _LIBCPP_ALWAYS_INLINE
3616 state_type state() const {return __cvtstate_;}
3619 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3621 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3622 wstring_convert(_Codecvt* __pcvt)
3623 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3627 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3629 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3630 wstring_convert(_Codecvt* __pcvt, state_type __state)
3631 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3635 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3636 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3637 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3638 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3639 __cvtstate_(), __cvtcount_(0)
3641 __cvtptr_ = new _Codecvt;
3644 #ifndef _LIBCPP_CXX03_LANG
3646 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3648 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3649 wstring_convert(wstring_convert&& __wc)
3650 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3651 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3652 __cvtptr_(__wc.__cvtptr_),
3653 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_)
3655 __wc.__cvtptr_ = nullptr;
3658 #endif // _LIBCPP_CXX03_LANG
3660 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3661 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3666 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3667 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3668 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3669 from_bytes(const char* __frm, const char* __frm_end)
3672 if (__cvtptr_ != nullptr)
3674 wide_string __ws(2*(__frm_end - __frm), _Elem());
3675 if (__frm != __frm_end)
3676 __ws.resize(__ws.capacity());
3677 codecvt_base::result __r = codecvt_base::ok;
3678 state_type __st = __cvtstate_;
3679 if (__frm != __frm_end)
3681 _Elem* __to = &__ws[0];
3682 _Elem* __to_end = __to + __ws.size();
3683 const char* __frm_nxt;
3687 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3688 __to, __to_end, __to_nxt);
3689 __cvtcount_ += __frm_nxt - __frm;
3690 if (__frm_nxt == __frm)
3692 __r = codecvt_base::error;
3694 else if (__r == codecvt_base::noconv)
3696 __ws.resize(__to - &__ws[0]);
3697 // This only gets executed if _Elem is char
3698 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3700 __r = codecvt_base::ok;
3702 else if (__r == codecvt_base::ok)
3704 __ws.resize(__to_nxt - &__ws[0]);
3707 else if (__r == codecvt_base::partial)
3709 ptrdiff_t __s = __to_nxt - &__ws[0];
3710 __ws.resize(2 * __s);
3711 __to = &__ws[0] + __s;
3712 __to_end = &__ws[0] + __ws.size();
3715 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3717 if (__r == codecvt_base::ok)
3721 if (__wide_err_string_.empty())
3722 __throw_range_error("wstring_convert: from_bytes error");
3724 return __wide_err_string_;
3727 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3728 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3729 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3730 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3733 if (__cvtptr_ != nullptr)
3735 byte_string __bs(2*(__frm_end - __frm), char());
3736 if (__frm != __frm_end)
3737 __bs.resize(__bs.capacity());
3738 codecvt_base::result __r = codecvt_base::ok;
3739 state_type __st = __cvtstate_;
3740 if (__frm != __frm_end)
3742 char* __to = &__bs[0];
3743 char* __to_end = __to + __bs.size();
3744 const _Elem* __frm_nxt;
3748 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3749 __to, __to_end, __to_nxt);
3750 __cvtcount_ += __frm_nxt - __frm;
3751 if (__frm_nxt == __frm)
3753 __r = codecvt_base::error;
3755 else if (__r == codecvt_base::noconv)
3757 __bs.resize(__to - &__bs[0]);
3758 // This only gets executed if _Elem is char
3759 __bs.append((const char*)__frm, (const char*)__frm_end);
3761 __r = codecvt_base::ok;
3763 else if (__r == codecvt_base::ok)
3765 __bs.resize(__to_nxt - &__bs[0]);
3768 else if (__r == codecvt_base::partial)
3770 ptrdiff_t __s = __to_nxt - &__bs[0];
3771 __bs.resize(2 * __s);
3772 __to = &__bs[0] + __s;
3773 __to_end = &__bs[0] + __bs.size();
3776 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3778 if (__r == codecvt_base::ok)
3780 size_t __s = __bs.size();
3781 __bs.resize(__bs.capacity());
3782 char* __to = &__bs[0] + __s;
3783 char* __to_end = __to + __bs.size();
3787 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3788 if (__r == codecvt_base::noconv)
3790 __bs.resize(__to - &__bs[0]);
3791 __r = codecvt_base::ok;
3793 else if (__r == codecvt_base::ok)
3795 __bs.resize(__to_nxt - &__bs[0]);
3797 else if (__r == codecvt_base::partial)
3799 ptrdiff_t __sp = __to_nxt - &__bs[0];
3800 __bs.resize(2 * __sp);
3801 __to = &__bs[0] + __sp;
3802 __to_end = &__bs[0] + __bs.size();
3804 } while (__r == codecvt_base::partial);
3805 if (__r == codecvt_base::ok)
3810 if (__byte_err_string_.empty())
3811 __throw_range_error("wstring_convert: to_bytes error");
3813 return __byte_err_string_;
3816 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
3817 class _LIBCPP_TEMPLATE_VIS wbuffer_convert
3818 : public basic_streambuf<_Elem, _Tr>
3822 typedef _Elem char_type;
3823 typedef _Tr traits_type;
3824 typedef typename traits_type::int_type int_type;
3825 typedef typename traits_type::pos_type pos_type;
3826 typedef typename traits_type::off_type off_type;
3827 typedef typename _Codecvt::state_type state_type;
3831 const char* __extbufnext_;
3832 const char* __extbufend_;
3833 char __extbuf_min_[8];
3835 char_type* __intbuf_;
3837 streambuf* __bufptr_;
3840 ios_base::openmode __cm_;
3843 bool __always_noconv_;
3845 wbuffer_convert(const wbuffer_convert&);
3846 wbuffer_convert& operator=(const wbuffer_convert&);
3848 _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0,
3849 _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
3852 _LIBCPP_INLINE_VISIBILITY
3853 streambuf* rdbuf() const {return __bufptr_;}
3854 _LIBCPP_INLINE_VISIBILITY
3855 streambuf* rdbuf(streambuf* __bytebuf)
3857 streambuf* __r = __bufptr_;
3858 __bufptr_ = __bytebuf;
3862 _LIBCPP_INLINE_VISIBILITY
3863 state_type state() const {return __st_;}
3866 virtual int_type underflow();
3867 virtual int_type pbackfail(int_type __c = traits_type::eof());
3868 virtual int_type overflow (int_type __c = traits_type::eof());
3869 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
3871 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
3872 ios_base::openmode __wch = ios_base::in | ios_base::out);
3873 virtual pos_type seekpos(pos_type __sp,
3874 ios_base::openmode __wch = ios_base::in | ios_base::out);
3879 void __write_mode();
3880 wbuffer_convert* __close();
3883 template <class _Codecvt, class _Elem, class _Tr>
3884 wbuffer_convert<_Codecvt, _Elem, _Tr>::
3885 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
3892 __bufptr_(__bytebuf),
3898 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
3903 template <class _Codecvt, class _Elem, class _Tr>
3904 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
3909 delete [] __extbuf_;
3911 delete [] __intbuf_;
3914 template <class _Codecvt, class _Elem, class _Tr>
3915 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3916 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
3918 if (__cv_ == 0 || __bufptr_ == 0)
3919 return traits_type::eof();
3920 bool __initial = __read_mode();
3922 if (this->gptr() == 0)
3923 this->setg(&__1buf, &__1buf+1, &__1buf+1);
3924 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
3925 int_type __c = traits_type::eof();
3926 if (this->gptr() == this->egptr())
3928 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
3929 if (__always_noconv_)
3931 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
3932 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
3935 this->setg(this->eback(),
3936 this->eback() + __unget_sz,
3937 this->eback() + __unget_sz + __nmemb);
3938 __c = *this->gptr();
3943 _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
3944 if (__extbufend_ != __extbufnext_)
3945 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
3946 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
3947 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
3948 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
3949 static_cast<streamsize>(__extbufend_ - __extbufnext_));
3950 codecvt_base::result __r;
3951 // FIXME: Do we ever need to restore the state here?
3952 //state_type __svs = __st_;
3953 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
3956 __extbufend_ = __extbufnext_ + __nr;
3958 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
3959 this->eback() + __unget_sz,
3960 this->egptr(), __inext);
3961 if (__r == codecvt_base::noconv)
3963 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
3964 __c = *this->gptr();
3966 else if (__inext != this->eback() + __unget_sz)
3968 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
3969 __c = *this->gptr();
3975 __c = *this->gptr();
3976 if (this->eback() == &__1buf)
3977 this->setg(0, 0, 0);
3981 template <class _Codecvt, class _Elem, class _Tr>
3982 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3983 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
3985 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
3987 if (traits_type::eq_int_type(__c, traits_type::eof()))
3990 return traits_type::not_eof(__c);
3992 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
3995 *this->gptr() = traits_type::to_char_type(__c);
3999 return traits_type::eof();
4002 template <class _Codecvt, class _Elem, class _Tr>
4003 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4004 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4006 if (__cv_ == 0 || __bufptr_ == 0)
4007 return traits_type::eof();
4010 char_type* __pb_save = this->pbase();
4011 char_type* __epb_save = this->epptr();
4012 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4014 if (this->pptr() == 0)
4015 this->setp(&__1buf, &__1buf+1);
4016 *this->pptr() = traits_type::to_char_type(__c);
4019 if (this->pptr() != this->pbase())
4021 if (__always_noconv_)
4023 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4024 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4025 return traits_type::eof();
4029 char* __extbe = __extbuf_;
4030 codecvt_base::result __r;
4033 const char_type* __e;
4034 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4035 __extbuf_, __extbuf_ + __ebs_, __extbe);
4036 if (__e == this->pbase())
4037 return traits_type::eof();
4038 if (__r == codecvt_base::noconv)
4040 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4041 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4042 return traits_type::eof();
4044 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4046 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4047 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4048 return traits_type::eof();
4049 if (__r == codecvt_base::partial)
4051 this->setp((char_type*)__e, this->pptr());
4052 this->pbump(this->epptr() - this->pbase());
4056 return traits_type::eof();
4057 } while (__r == codecvt_base::partial);
4059 this->setp(__pb_save, __epb_save);
4061 return traits_type::not_eof(__c);
4064 template <class _Codecvt, class _Elem, class _Tr>
4065 basic_streambuf<_Elem, _Tr>*
4066 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4068 this->setg(0, 0, 0);
4071 delete [] __extbuf_;
4073 delete [] __intbuf_;
4075 if (__ebs_ > sizeof(__extbuf_min_))
4077 if (__always_noconv_ && __s)
4079 __extbuf_ = (char*)__s;
4084 __extbuf_ = new char[__ebs_];
4090 __extbuf_ = __extbuf_min_;
4091 __ebs_ = sizeof(__extbuf_min_);
4094 if (!__always_noconv_)
4096 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4097 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4104 __intbuf_ = new char_type[__ibs_];
4117 template <class _Codecvt, class _Elem, class _Tr>
4118 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4119 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4120 ios_base::openmode __om)
4122 int __width = __cv_->encoding();
4123 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4124 return pos_type(off_type(-1));
4125 // __width > 0 || __off == 0, now check __way
4126 if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end)
4127 return pos_type(off_type(-1));
4128 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4133 template <class _Codecvt, class _Elem, class _Tr>
4134 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4135 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4137 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4138 return pos_type(off_type(-1));
4139 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4140 return pos_type(off_type(-1));
4144 template <class _Codecvt, class _Elem, class _Tr>
4146 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4148 if (__cv_ == 0 || __bufptr_ == 0)
4150 if (__cm_ & ios_base::out)
4152 if (this->pptr() != this->pbase())
4153 if (overflow() == traits_type::eof())
4155 codecvt_base::result __r;
4159 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4160 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4161 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4163 } while (__r == codecvt_base::partial);
4164 if (__r == codecvt_base::error)
4166 if (__bufptr_->pubsync())
4169 else if (__cm_ & ios_base::in)
4172 if (__always_noconv_)
4173 __c = this->egptr() - this->gptr();
4176 int __width = __cv_->encoding();
4177 __c = __extbufend_ - __extbufnext_;
4179 __c += __width * (this->egptr() - this->gptr());
4182 if (this->gptr() != this->egptr())
4184 reverse(this->gptr(), this->egptr());
4185 codecvt_base::result __r;
4186 const char_type* __e = this->gptr();
4190 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4191 __extbuf_, __extbuf_ + __ebs_, __extbe);
4194 case codecvt_base::noconv:
4195 __c += this->egptr() - this->gptr();
4197 case codecvt_base::ok:
4198 case codecvt_base::partial:
4199 __c += __extbe - __extbuf_;
4204 } while (__r == codecvt_base::partial);
4208 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4210 this->setg(0, 0, 0);
4216 template <class _Codecvt, class _Elem, class _Tr>
4218 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4220 if (!(__cm_ & ios_base::in))
4223 if (__always_noconv_)
4224 this->setg((char_type*)__extbuf_,
4225 (char_type*)__extbuf_ + __ebs_,
4226 (char_type*)__extbuf_ + __ebs_);
4228 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4229 __cm_ = ios_base::in;
4235 template <class _Codecvt, class _Elem, class _Tr>
4237 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4239 if (!(__cm_ & ios_base::out))
4241 this->setg(0, 0, 0);
4242 if (__ebs_ > sizeof(__extbuf_min_))
4244 if (__always_noconv_)
4245 this->setp((char_type*)__extbuf_,
4246 (char_type*)__extbuf_ + (__ebs_ - 1));
4248 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4252 __cm_ = ios_base::out;
4256 template <class _Codecvt, class _Elem, class _Tr>
4257 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4258 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4260 wbuffer_convert* __rt = 0;
4261 if (__cv_ != 0 && __bufptr_ != 0)
4264 if ((__cm_ & ios_base::out) && sync())
4270 _LIBCPP_END_NAMESPACE_STD
4274 #endif // _LIBCPP_LOCALE