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;
195 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
196 #include <support/win32/locale_win32.h>
197 #elif defined(_NEWLIB_VERSION)
198 // FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an
199 // include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html
200 // has had a chance to bake for a bit
201 #include <support/newlib/xlocale.h>
203 #ifdef _LIBCPP_HAS_CATOPEN
204 #include <nl_types.h>
208 #include <Availability.h>
211 #include <__undef_min_max>
213 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
214 #pragma GCC system_header
217 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
218 #include <__bsd_locale_defaults.h>
220 #include <__bsd_locale_fallbacks.h>
223 _LIBCPP_BEGIN_NAMESPACE_STD
225 #if defined(__APPLE__) || defined(__FreeBSD__)
226 # define _LIBCPP_GET_C_LOCALE 0
227 #elif defined(__CloudABI__) || defined(__NetBSD__)
228 # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
230 # define _LIBCPP_GET_C_LOCALE __cloc()
231 // Get the C locale object
232 _LIBCPP_FUNC_VIS locale_t __cloc();
233 #define __cloc_defined
236 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
237 typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
240 // Scans [__b, __e) until a match is found in the basic_strings range
241 // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
242 // __b will be incremented (visibly), consuming CharT until a match is found
243 // or proved to not exist. A keyword may be "", in which will match anything.
244 // If one keyword is a prefix of another, and the next CharT in the input
245 // might match another keyword, the algorithm will attempt to find the longest
246 // matching keyword. If the longer matching keyword ends up not matching, then
247 // no keyword match is found. If no keyword match is found, __ke is returned
248 // and failbit is set in __err.
249 // Else an iterator pointing to the matching keyword is found. If more than
250 // one keyword matches, an iterator to the first matching keyword is returned.
251 // If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
252 // __ct is used to force to lower case before comparing characters.
254 // Keywords: "a", "abb"
255 // If the input is "a", the first keyword matches and eofbit is set.
256 // If the input is "abc", no match is found and "ab" are consumed.
257 template <class _InputIterator, class _ForwardIterator, class _Ctype>
260 __scan_keyword(_InputIterator& __b, _InputIterator __e,
261 _ForwardIterator __kb, _ForwardIterator __ke,
262 const _Ctype& __ct, ios_base::iostate& __err,
263 bool __case_sensitive = true)
265 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
266 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
267 const unsigned char __doesnt_match = '\0';
268 const unsigned char __might_match = '\1';
269 const unsigned char __does_match = '\2';
270 unsigned char __statbuf[100];
271 unsigned char* __status = __statbuf;
272 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
273 if (__nkw > sizeof(__statbuf))
275 __status = (unsigned char*)malloc(__nkw);
278 __stat_hold.reset(__status);
280 size_t __n_might_match = __nkw; // At this point, any keyword might match
281 size_t __n_does_match = 0; // but none of them definitely do
282 // Initialize all statuses to __might_match, except for "" keywords are __does_match
283 unsigned char* __st = __status;
284 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
287 *__st = __might_match;
290 *__st = __does_match;
295 // While there might be a match, test keywords against the next CharT
296 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
298 // Peek at the next CharT but don't consume it
300 if (!__case_sensitive)
301 __c = __ct.toupper(__c);
302 bool __consume = false;
303 // For each keyword which might match, see if the __indx character is __c
304 // If a match if found, consume __c
305 // If a match is found, and that is the last character in the keyword,
306 // then that keyword matches.
307 // If the keyword doesn't match this character, then change the keyword
310 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
312 if (*__st == __might_match)
314 _CharT __kc = (*__ky)[__indx];
315 if (!__case_sensitive)
316 __kc = __ct.toupper(__kc);
320 if (__ky->size() == __indx+1)
322 *__st = __does_match;
329 *__st = __doesnt_match;
334 // consume if we matched a character
338 // If we consumed a character and there might be a matched keyword that
339 // was marked matched on a previous iteration, then such keywords
340 // which are now marked as not matching.
341 if (__n_might_match + __n_does_match > 1)
344 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
346 if (*__st == __does_match && __ky->size() != __indx+1)
348 *__st = __doesnt_match;
355 // We've exited the loop because we hit eof and/or we have no more "might matches".
357 __err |= ios_base::eofbit;
358 // Return the first matching result
359 for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
360 if (*__st == __does_match)
363 __err |= ios_base::failbit;
367 struct _LIBCPP_TYPE_VIS __num_get_base
369 static const int __num_get_buf_sz = 40;
371 static int __get_base(ios_base&);
372 static const char __src[33];
376 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
377 ios_base::iostate& __err);
379 template <class _CharT>
381 : protected __num_get_base
383 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
384 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
385 _CharT& __thousands_sep);
386 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
387 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
388 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
389 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
390 char* __a, char*& __a_end,
391 _CharT __decimal_point, _CharT __thousands_sep,
392 const string& __grouping, unsigned* __g,
393 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
396 template <class _CharT>
398 __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
400 locale __loc = __iob.getloc();
401 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
402 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
403 __thousands_sep = __np.thousands_sep();
404 return __np.grouping();
407 template <class _CharT>
409 __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
410 _CharT& __thousands_sep)
412 locale __loc = __iob.getloc();
413 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
414 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
415 __decimal_point = __np.decimal_point();
416 __thousands_sep = __np.thousands_sep();
417 return __np.grouping();
420 template <class _CharT>
422 __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
423 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
424 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
426 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
428 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
432 if (__grouping.size() != 0 && __ct == __thousands_sep)
434 if (__g_end-__g < __num_get_buf_sz)
441 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
454 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
457 *__a_end++ = __src[__f];
462 *__a_end++ = __src[__f];
467 template <class _CharT>
469 __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
470 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
471 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
473 if (__ct == __decimal_point)
479 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
483 if (__ct == __thousands_sep && __grouping.size() != 0)
487 if (__g_end-__g < __num_get_buf_sz)
494 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
497 char __x = __src[__f];
498 if (__x == '-' || __x == '+')
500 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
507 if (__x == 'x' || __x == 'X')
509 else if ((__x & 0x5F) == __exp)
515 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
526 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
527 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
529 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
530 class _LIBCPP_TYPE_VIS_ONLY num_get
531 : public locale::facet,
532 private __num_get<_CharT>
535 typedef _CharT char_type;
536 typedef _InputIterator iter_type;
538 _LIBCPP_ALWAYS_INLINE
539 explicit num_get(size_t __refs = 0)
540 : locale::facet(__refs) {}
542 _LIBCPP_ALWAYS_INLINE
543 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
544 ios_base::iostate& __err, bool& __v) const
546 return do_get(__b, __e, __iob, __err, __v);
549 _LIBCPP_ALWAYS_INLINE
550 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
551 ios_base::iostate& __err, long& __v) const
553 return do_get(__b, __e, __iob, __err, __v);
556 _LIBCPP_ALWAYS_INLINE
557 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
558 ios_base::iostate& __err, long long& __v) const
560 return do_get(__b, __e, __iob, __err, __v);
563 _LIBCPP_ALWAYS_INLINE
564 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
565 ios_base::iostate& __err, unsigned short& __v) const
567 return do_get(__b, __e, __iob, __err, __v);
570 _LIBCPP_ALWAYS_INLINE
571 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
572 ios_base::iostate& __err, unsigned int& __v) const
574 return do_get(__b, __e, __iob, __err, __v);
577 _LIBCPP_ALWAYS_INLINE
578 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
579 ios_base::iostate& __err, unsigned long& __v) const
581 return do_get(__b, __e, __iob, __err, __v);
584 _LIBCPP_ALWAYS_INLINE
585 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
586 ios_base::iostate& __err, unsigned long long& __v) const
588 return do_get(__b, __e, __iob, __err, __v);
591 _LIBCPP_ALWAYS_INLINE
592 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
593 ios_base::iostate& __err, float& __v) const
595 return do_get(__b, __e, __iob, __err, __v);
598 _LIBCPP_ALWAYS_INLINE
599 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
600 ios_base::iostate& __err, double& __v) const
602 return do_get(__b, __e, __iob, __err, __v);
605 _LIBCPP_ALWAYS_INLINE
606 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
607 ios_base::iostate& __err, long double& __v) const
609 return do_get(__b, __e, __iob, __err, __v);
612 _LIBCPP_ALWAYS_INLINE
613 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
614 ios_base::iostate& __err, void*& __v) const
616 return do_get(__b, __e, __iob, __err, __v);
619 static locale::id id;
622 _LIBCPP_ALWAYS_INLINE
626 iter_type __do_get_floating_point
627 (iter_type __b, iter_type __e, ios_base& __iob,
628 ios_base::iostate& __err, _Fp& __v) const;
630 template <class _Signed>
631 iter_type __do_get_signed
632 (iter_type __b, iter_type __e, ios_base& __iob,
633 ios_base::iostate& __err, _Signed& __v) const;
635 template <class _Unsigned>
636 iter_type __do_get_unsigned
637 (iter_type __b, iter_type __e, ios_base& __iob,
638 ios_base::iostate& __err, _Unsigned& __v) const;
641 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
642 ios_base::iostate& __err, bool& __v) const;
644 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
645 ios_base::iostate& __err, long& __v) const
646 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
648 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
649 ios_base::iostate& __err, long long& __v) const
650 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
652 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
653 ios_base::iostate& __err, unsigned short& __v) const
654 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
656 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
657 ios_base::iostate& __err, unsigned int& __v) const
658 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
660 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
661 ios_base::iostate& __err, unsigned long& __v) const
662 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
664 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
665 ios_base::iostate& __err, unsigned long long& __v) const
666 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
668 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
669 ios_base::iostate& __err, float& __v) const
670 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
672 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
673 ios_base::iostate& __err, double& __v) const
674 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
676 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
677 ios_base::iostate& __err, long double& __v) const
678 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
680 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
681 ios_base::iostate& __err, void*& __v) const;
684 template <class _CharT, class _InputIterator>
686 num_get<_CharT, _InputIterator>::id;
690 __num_get_signed_integral(const char* __a, const char* __a_end,
691 ios_base::iostate& __err, int __base)
695 typename remove_reference<decltype(errno)>::type __save_errno = errno;
698 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
699 typename remove_reference<decltype(errno)>::type __current_errno = errno;
700 if (__current_errno == 0)
701 errno = __save_errno;
704 __err = ios_base::failbit;
707 else if (__current_errno == ERANGE ||
708 __ll < numeric_limits<_Tp>::min() ||
709 numeric_limits<_Tp>::max() < __ll)
711 __err = ios_base::failbit;
713 return numeric_limits<_Tp>::max();
715 return numeric_limits<_Tp>::min();
717 return static_cast<_Tp>(__ll);
719 __err = ios_base::failbit;
725 __num_get_unsigned_integral(const char* __a, const char* __a_end,
726 ios_base::iostate& __err, int __base)
732 __err = ios_base::failbit;
735 typename remove_reference<decltype(errno)>::type __save_errno = errno;
738 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
739 typename remove_reference<decltype(errno)>::type __current_errno = errno;
740 if (__current_errno == 0)
741 errno = __save_errno;
744 __err = ios_base::failbit;
747 else if (__current_errno == ERANGE ||
748 numeric_limits<_Tp>::max() < __ll)
750 __err = ios_base::failbit;
751 return numeric_limits<_Tp>::max();
753 return static_cast<_Tp>(__ll);
755 __err = ios_base::failbit;
760 _LIBCPP_INLINE_VISIBILITY
761 _Tp __do_strtod(const char* __a, char** __p2);
764 inline _LIBCPP_INLINE_VISIBILITY
765 float __do_strtod<float>(const char* __a, char** __p2) {
766 return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
770 inline _LIBCPP_INLINE_VISIBILITY
771 double __do_strtod<double>(const char* __a, char** __p2) {
772 return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
776 inline _LIBCPP_INLINE_VISIBILITY
777 long double __do_strtod<long double>(const char* __a, char** __p2) {
778 return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
783 __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
787 typename remove_reference<decltype(errno)>::type __save_errno = errno;
790 _Tp __ld = __do_strtod<_Tp>(__a, &__p2);
791 typename remove_reference<decltype(errno)>::type __current_errno = errno;
792 if (__current_errno == 0)
793 errno = __save_errno;
796 __err = ios_base::failbit;
799 else if (__current_errno == ERANGE)
800 __err = ios_base::failbit;
803 __err = ios_base::failbit;
807 template <class _CharT, class _InputIterator>
809 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
811 ios_base::iostate& __err,
814 if ((__iob.flags() & ios_base::boolalpha) == 0)
817 __b = do_get(__b, __e, __iob, __err, __lv);
828 __err = ios_base::failbit;
833 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
834 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
835 typedef typename numpunct<_CharT>::string_type string_type;
836 const string_type __names[2] = {__np.truename(), __np.falsename()};
837 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
839 __v = __i == __names;
845 template <class _CharT, class _InputIterator>
846 template <class _Signed>
848 num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
850 ios_base::iostate& __err,
854 int __base = this->__get_base(__iob);
856 char_type __atoms[26];
857 char_type __thousands_sep;
858 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
860 __buf.resize(__buf.capacity());
861 char* __a = &__buf[0];
863 unsigned __g[__num_get_base::__num_get_buf_sz];
864 unsigned* __g_end = __g;
866 for (; __b != __e; ++__b)
868 if (__a_end == __a + __buf.size())
870 size_t __tmp = __buf.size();
871 __buf.resize(2*__buf.size());
872 __buf.resize(__buf.capacity());
874 __a_end = __a + __tmp;
876 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
877 __thousands_sep, __grouping, __g, __g_end,
881 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
884 __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
885 // Digit grouping checked
886 __check_grouping(__grouping, __g, __g_end, __err);
889 __err |= ios_base::eofbit;
895 template <class _CharT, class _InputIterator>
896 template <class _Unsigned>
898 num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
900 ios_base::iostate& __err,
901 _Unsigned& __v) const
904 int __base = this->__get_base(__iob);
906 char_type __atoms[26];
907 char_type __thousands_sep;
908 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
910 __buf.resize(__buf.capacity());
911 char* __a = &__buf[0];
913 unsigned __g[__num_get_base::__num_get_buf_sz];
914 unsigned* __g_end = __g;
916 for (; __b != __e; ++__b)
918 if (__a_end == __a + __buf.size())
920 size_t __tmp = __buf.size();
921 __buf.resize(2*__buf.size());
922 __buf.resize(__buf.capacity());
924 __a_end = __a + __tmp;
926 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
927 __thousands_sep, __grouping, __g, __g_end,
931 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
934 __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
935 // Digit grouping checked
936 __check_grouping(__grouping, __g, __g_end, __err);
939 __err |= ios_base::eofbit;
945 template <class _CharT, class _InputIterator>
948 num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
950 ios_base::iostate& __err,
953 // Stage 1, nothing to do
955 char_type __atoms[32];
956 char_type __decimal_point;
957 char_type __thousands_sep;
958 string __grouping = this->__stage2_float_prep(__iob, __atoms,
962 __buf.resize(__buf.capacity());
963 char* __a = &__buf[0];
965 unsigned __g[__num_get_base::__num_get_buf_sz];
966 unsigned* __g_end = __g;
968 bool __in_units = true;
970 for (; __b != __e; ++__b)
972 if (__a_end == __a + __buf.size())
974 size_t __tmp = __buf.size();
975 __buf.resize(2*__buf.size());
976 __buf.resize(__buf.capacity());
978 __a_end = __a + __tmp;
980 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
981 __decimal_point, __thousands_sep,
982 __grouping, __g, __g_end,
986 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
989 __v = __num_get_float<_Fp>(__a, __a_end, __err);
990 // Digit grouping checked
991 __check_grouping(__grouping, __g, __g_end, __err);
994 __err |= ios_base::eofbit;
998 template <class _CharT, class _InputIterator>
1000 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1002 ios_base::iostate& __err,
1008 char_type __atoms[26];
1009 char_type __thousands_sep = 0;
1011 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1012 __num_get_base::__src + 26, __atoms);
1014 __buf.resize(__buf.capacity());
1015 char* __a = &__buf[0];
1016 char* __a_end = __a;
1017 unsigned __g[__num_get_base::__num_get_buf_sz];
1018 unsigned* __g_end = __g;
1020 for (; __b != __e; ++__b)
1022 if (__a_end == __a + __buf.size())
1024 size_t __tmp = __buf.size();
1025 __buf.resize(2*__buf.size());
1026 __buf.resize(__buf.capacity());
1028 __a_end = __a + __tmp;
1030 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1031 __thousands_sep, __grouping,
1032 __g, __g_end, __atoms))
1036 __buf.resize(__a_end - __a);
1037 if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1038 __err = ios_base::failbit;
1041 __err |= ios_base::eofbit;
1045 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
1046 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
1048 struct _LIBCPP_TYPE_VIS __num_put_base
1051 static void __format_int(char* __fmt, const char* __len, bool __signd,
1052 ios_base::fmtflags __flags);
1053 static bool __format_float(char* __fmt, const char* __len,
1054 ios_base::fmtflags __flags);
1055 static char* __identify_padding(char* __nb, char* __ne,
1056 const ios_base& __iob);
1059 template <class _CharT>
1061 : protected __num_put_base
1063 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1064 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1065 const locale& __loc);
1066 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1067 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1068 const locale& __loc);
1071 template <class _CharT>
1073 __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1074 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1075 const locale& __loc)
1077 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1078 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1079 string __grouping = __npt.grouping();
1080 if (__grouping.empty())
1082 __ct.widen(__nb, __ne, __ob);
1083 __oe = __ob + (__ne - __nb);
1089 if (*__nf == '-' || *__nf == '+')
1090 *__oe++ = __ct.widen(*__nf++);
1091 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1094 *__oe++ = __ct.widen(*__nf++);
1095 *__oe++ = __ct.widen(*__nf++);
1097 reverse(__nf, __ne);
1098 _CharT __thousands_sep = __npt.thousands_sep();
1101 for (char* __p = __nf; __p < __ne; ++__p)
1103 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1104 __dc == static_cast<unsigned>(__grouping[__dg]))
1106 *__oe++ = __thousands_sep;
1108 if (__dg < __grouping.size()-1)
1111 *__oe++ = __ct.widen(*__p);
1114 reverse(__ob + (__nf - __nb), __oe);
1119 __op = __ob + (__np - __nb);
1122 template <class _CharT>
1124 __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1125 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1126 const locale& __loc)
1128 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1129 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1130 string __grouping = __npt.grouping();
1133 if (*__nf == '-' || *__nf == '+')
1134 *__oe++ = __ct.widen(*__nf++);
1136 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1139 *__oe++ = __ct.widen(*__nf++);
1140 *__oe++ = __ct.widen(*__nf++);
1141 for (__ns = __nf; __ns < __ne; ++__ns)
1142 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1147 for (__ns = __nf; __ns < __ne; ++__ns)
1148 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1151 if (__grouping.empty())
1153 __ct.widen(__nf, __ns, __oe);
1154 __oe += __ns - __nf;
1158 reverse(__nf, __ns);
1159 _CharT __thousands_sep = __npt.thousands_sep();
1162 for (char* __p = __nf; __p < __ns; ++__p)
1164 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1166 *__oe++ = __thousands_sep;
1168 if (__dg < __grouping.size()-1)
1171 *__oe++ = __ct.widen(*__p);
1174 reverse(__ob + (__nf - __nb), __oe);
1176 for (__nf = __ns; __nf < __ne; ++__nf)
1180 *__oe++ = __npt.decimal_point();
1185 *__oe++ = __ct.widen(*__nf);
1187 __ct.widen(__nf, __ne, __oe);
1188 __oe += __ne - __nf;
1192 __op = __ob + (__np - __nb);
1195 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
1196 _LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
1198 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1199 class _LIBCPP_TYPE_VIS_ONLY num_put
1200 : public locale::facet,
1201 private __num_put<_CharT>
1204 typedef _CharT char_type;
1205 typedef _OutputIterator iter_type;
1207 _LIBCPP_ALWAYS_INLINE
1208 explicit num_put(size_t __refs = 0)
1209 : locale::facet(__refs) {}
1211 _LIBCPP_ALWAYS_INLINE
1212 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1215 return do_put(__s, __iob, __fl, __v);
1218 _LIBCPP_ALWAYS_INLINE
1219 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1222 return do_put(__s, __iob, __fl, __v);
1225 _LIBCPP_ALWAYS_INLINE
1226 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1227 long long __v) const
1229 return do_put(__s, __iob, __fl, __v);
1232 _LIBCPP_ALWAYS_INLINE
1233 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1234 unsigned long __v) const
1236 return do_put(__s, __iob, __fl, __v);
1239 _LIBCPP_ALWAYS_INLINE
1240 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1241 unsigned long long __v) const
1243 return do_put(__s, __iob, __fl, __v);
1246 _LIBCPP_ALWAYS_INLINE
1247 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1250 return do_put(__s, __iob, __fl, __v);
1253 _LIBCPP_ALWAYS_INLINE
1254 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1255 long double __v) const
1257 return do_put(__s, __iob, __fl, __v);
1260 _LIBCPP_ALWAYS_INLINE
1261 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1262 const void* __v) const
1264 return do_put(__s, __iob, __fl, __v);
1267 static locale::id id;
1270 _LIBCPP_ALWAYS_INLINE
1273 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1275 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1277 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1278 long long __v) const;
1279 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1280 unsigned long) const;
1281 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1282 unsigned long long) const;
1283 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1285 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1286 long double __v) const;
1287 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1288 const void* __v) const;
1291 template <class _CharT, class _OutputIterator>
1293 num_put<_CharT, _OutputIterator>::id;
1295 template <class _CharT, class _OutputIterator>
1298 __pad_and_output(_OutputIterator __s,
1299 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1300 ios_base& __iob, _CharT __fl)
1302 streamsize __sz = __oe - __ob;
1303 streamsize __ns = __iob.width();
1308 for (;__ob < __op; ++__ob, ++__s)
1310 for (; __ns; --__ns, ++__s)
1312 for (; __ob < __oe; ++__ob, ++__s)
1318 #if !defined(__APPLE__) || \
1319 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1320 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1322 template <class _CharT, class _Traits>
1324 ostreambuf_iterator<_CharT, _Traits>
1325 __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1326 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1327 ios_base& __iob, _CharT __fl)
1329 if (__s.__sbuf_ == nullptr)
1331 streamsize __sz = __oe - __ob;
1332 streamsize __ns = __iob.width();
1337 streamsize __np = __op - __ob;
1340 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1342 __s.__sbuf_ = nullptr;
1348 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1349 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1351 __s.__sbuf_ = nullptr;
1358 if (__s.__sbuf_->sputn(__op, __np) != __np)
1360 __s.__sbuf_ = nullptr;
1370 template <class _CharT, class _OutputIterator>
1372 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1373 char_type __fl, bool __v) const
1375 if ((__iob.flags() & ios_base::boolalpha) == 0)
1376 return do_put(__s, __iob, __fl, (unsigned long)__v);
1377 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1378 typedef typename numpunct<char_type>::string_type string_type;
1379 #if _LIBCPP_DEBUG_LEVEL >= 2
1380 string_type __tmp(__v ? __np.truename() : __np.falsename());
1381 string_type __nm = _VSTD::move(__tmp);
1383 string_type __nm = __v ? __np.truename() : __np.falsename();
1385 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1390 template <class _CharT, class _OutputIterator>
1392 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1393 char_type __fl, long __v) const
1395 // Stage 1 - Get number in narrow char
1396 char __fmt[6] = {'%', 0};
1397 const char* __len = "l";
1398 this->__format_int(__fmt+1, __len, true, __iob.flags());
1399 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1400 + ((numeric_limits<long>::digits % 3) != 0)
1403 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1404 char* __ne = __nar + __nc;
1405 char* __np = this->__identify_padding(__nar, __ne, __iob);
1406 // Stage 2 - Widen __nar while adding thousands separators
1407 char_type __o[2*(__nbuf-1) - 1];
1408 char_type* __op; // pad here
1409 char_type* __oe; // end of output
1410 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1411 // [__o, __oe) contains thousands_sep'd wide number
1413 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1416 template <class _CharT, class _OutputIterator>
1418 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1419 char_type __fl, long long __v) const
1421 // Stage 1 - Get number in narrow char
1422 char __fmt[8] = {'%', 0};
1423 const char* __len = "ll";
1424 this->__format_int(__fmt+1, __len, true, __iob.flags());
1425 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1426 + ((numeric_limits<long long>::digits % 3) != 0)
1429 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1430 char* __ne = __nar + __nc;
1431 char* __np = this->__identify_padding(__nar, __ne, __iob);
1432 // Stage 2 - Widen __nar while adding thousands separators
1433 char_type __o[2*(__nbuf-1) - 1];
1434 char_type* __op; // pad here
1435 char_type* __oe; // end of output
1436 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1437 // [__o, __oe) contains thousands_sep'd wide number
1439 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1442 template <class _CharT, class _OutputIterator>
1444 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1445 char_type __fl, unsigned long __v) const
1447 // Stage 1 - Get number in narrow char
1448 char __fmt[6] = {'%', 0};
1449 const char* __len = "l";
1450 this->__format_int(__fmt+1, __len, false, __iob.flags());
1451 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1452 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1455 int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1456 char* __ne = __nar + __nc;
1457 char* __np = this->__identify_padding(__nar, __ne, __iob);
1458 // Stage 2 - Widen __nar while adding thousands separators
1459 char_type __o[2*(__nbuf-1) - 1];
1460 char_type* __op; // pad here
1461 char_type* __oe; // end of output
1462 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1463 // [__o, __oe) contains thousands_sep'd wide number
1465 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1468 template <class _CharT, class _OutputIterator>
1470 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1471 char_type __fl, unsigned long long __v) const
1473 // Stage 1 - Get number in narrow char
1474 char __fmt[8] = {'%', 0};
1475 const char* __len = "ll";
1476 this->__format_int(__fmt+1, __len, false, __iob.flags());
1477 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1478 + ((numeric_limits<unsigned long long>::digits % 3) != 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_TYPE_VIS num_put<char>)
1625 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_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_TYPE_VIS_ONLY __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 <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1685 class _LIBCPP_TYPE_VIS_ONLY time_get
1686 : public locale::facet,
1688 private __time_get_c_storage<_CharT>
1691 typedef _CharT char_type;
1692 typedef _InputIterator iter_type;
1693 typedef time_base::dateorder dateorder;
1694 typedef basic_string<char_type> string_type;
1696 _LIBCPP_ALWAYS_INLINE
1697 explicit time_get(size_t __refs = 0)
1698 : locale::facet(__refs) {}
1700 _LIBCPP_ALWAYS_INLINE
1701 dateorder date_order() const
1703 return this->do_date_order();
1706 _LIBCPP_ALWAYS_INLINE
1707 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1708 ios_base::iostate& __err, tm* __tm) const
1710 return do_get_time(__b, __e, __iob, __err, __tm);
1713 _LIBCPP_ALWAYS_INLINE
1714 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1715 ios_base::iostate& __err, tm* __tm) const
1717 return do_get_date(__b, __e, __iob, __err, __tm);
1720 _LIBCPP_ALWAYS_INLINE
1721 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1722 ios_base::iostate& __err, tm* __tm) const
1724 return do_get_weekday(__b, __e, __iob, __err, __tm);
1727 _LIBCPP_ALWAYS_INLINE
1728 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1729 ios_base::iostate& __err, tm* __tm) const
1731 return do_get_monthname(__b, __e, __iob, __err, __tm);
1734 _LIBCPP_ALWAYS_INLINE
1735 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1736 ios_base::iostate& __err, tm* __tm) const
1738 return do_get_year(__b, __e, __iob, __err, __tm);
1741 _LIBCPP_ALWAYS_INLINE
1742 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1743 ios_base::iostate& __err, tm *__tm,
1744 char __fmt, char __mod = 0) const
1746 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1749 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1750 ios_base::iostate& __err, tm* __tm,
1751 const char_type* __fmtb, const char_type* __fmte) const;
1753 static locale::id id;
1756 _LIBCPP_ALWAYS_INLINE
1759 virtual dateorder do_date_order() const;
1760 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1761 ios_base::iostate& __err, tm* __tm) const;
1762 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1763 ios_base::iostate& __err, tm* __tm) const;
1764 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1765 ios_base::iostate& __err, tm* __tm) const;
1766 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1767 ios_base::iostate& __err, tm* __tm) const;
1768 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1769 ios_base::iostate& __err, tm* __tm) const;
1770 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1771 ios_base::iostate& __err, tm* __tm,
1772 char __fmt, char __mod) const;
1774 void __get_white_space(iter_type& __b, iter_type __e,
1775 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1776 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1777 const ctype<char_type>& __ct) const;
1779 void __get_weekdayname(int& __m,
1780 iter_type& __b, iter_type __e,
1781 ios_base::iostate& __err,
1782 const ctype<char_type>& __ct) const;
1783 void __get_monthname(int& __m,
1784 iter_type& __b, iter_type __e,
1785 ios_base::iostate& __err,
1786 const ctype<char_type>& __ct) const;
1787 void __get_day(int& __d,
1788 iter_type& __b, iter_type __e,
1789 ios_base::iostate& __err,
1790 const ctype<char_type>& __ct) const;
1791 void __get_month(int& __m,
1792 iter_type& __b, iter_type __e,
1793 ios_base::iostate& __err,
1794 const ctype<char_type>& __ct) const;
1795 void __get_year(int& __y,
1796 iter_type& __b, iter_type __e,
1797 ios_base::iostate& __err,
1798 const ctype<char_type>& __ct) const;
1799 void __get_year4(int& __y,
1800 iter_type& __b, iter_type __e,
1801 ios_base::iostate& __err,
1802 const ctype<char_type>& __ct) const;
1803 void __get_hour(int& __d,
1804 iter_type& __b, iter_type __e,
1805 ios_base::iostate& __err,
1806 const ctype<char_type>& __ct) const;
1807 void __get_12_hour(int& __h,
1808 iter_type& __b, iter_type __e,
1809 ios_base::iostate& __err,
1810 const ctype<char_type>& __ct) const;
1811 void __get_am_pm(int& __h,
1812 iter_type& __b, iter_type __e,
1813 ios_base::iostate& __err,
1814 const ctype<char_type>& __ct) const;
1815 void __get_minute(int& __m,
1816 iter_type& __b, iter_type __e,
1817 ios_base::iostate& __err,
1818 const ctype<char_type>& __ct) const;
1819 void __get_second(int& __s,
1820 iter_type& __b, iter_type __e,
1821 ios_base::iostate& __err,
1822 const ctype<char_type>& __ct) const;
1823 void __get_weekday(int& __w,
1824 iter_type& __b, iter_type __e,
1825 ios_base::iostate& __err,
1826 const ctype<char_type>& __ct) const;
1827 void __get_day_year_num(int& __w,
1828 iter_type& __b, iter_type __e,
1829 ios_base::iostate& __err,
1830 const ctype<char_type>& __ct) const;
1833 template <class _CharT, class _InputIterator>
1835 time_get<_CharT, _InputIterator>::id;
1837 // time_get primitives
1839 template <class _CharT, class _InputIterator>
1841 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
1842 iter_type& __b, iter_type __e,
1843 ios_base::iostate& __err,
1844 const ctype<char_type>& __ct) const
1846 // Note: ignoring case comes from the POSIX strptime spec
1847 const string_type* __wk = this->__weeks();
1848 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
1853 template <class _CharT, class _InputIterator>
1855 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
1856 iter_type& __b, iter_type __e,
1857 ios_base::iostate& __err,
1858 const ctype<char_type>& __ct) const
1860 // Note: ignoring case comes from the POSIX strptime spec
1861 const string_type* __month = this->__months();
1862 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
1867 template <class _CharT, class _InputIterator>
1869 time_get<_CharT, _InputIterator>::__get_day(int& __d,
1870 iter_type& __b, iter_type __e,
1871 ios_base::iostate& __err,
1872 const ctype<char_type>& __ct) const
1874 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1875 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
1878 __err |= ios_base::failbit;
1881 template <class _CharT, class _InputIterator>
1883 time_get<_CharT, _InputIterator>::__get_month(int& __m,
1884 iter_type& __b, iter_type __e,
1885 ios_base::iostate& __err,
1886 const ctype<char_type>& __ct) const
1888 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
1889 if (!(__err & ios_base::failbit) && __t <= 11)
1892 __err |= ios_base::failbit;
1895 template <class _CharT, class _InputIterator>
1897 time_get<_CharT, _InputIterator>::__get_year(int& __y,
1898 iter_type& __b, iter_type __e,
1899 ios_base::iostate& __err,
1900 const ctype<char_type>& __ct) const
1902 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1903 if (!(__err & ios_base::failbit))
1907 else if (69 <= __t && __t <= 99)
1913 template <class _CharT, class _InputIterator>
1915 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
1916 iter_type& __b, iter_type __e,
1917 ios_base::iostate& __err,
1918 const ctype<char_type>& __ct) const
1920 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1921 if (!(__err & ios_base::failbit))
1925 template <class _CharT, class _InputIterator>
1927 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
1928 iter_type& __b, iter_type __e,
1929 ios_base::iostate& __err,
1930 const ctype<char_type>& __ct) const
1932 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1933 if (!(__err & ios_base::failbit) && __t <= 23)
1936 __err |= ios_base::failbit;
1939 template <class _CharT, class _InputIterator>
1941 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
1942 iter_type& __b, iter_type __e,
1943 ios_base::iostate& __err,
1944 const ctype<char_type>& __ct) const
1946 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1947 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
1950 __err |= ios_base::failbit;
1953 template <class _CharT, class _InputIterator>
1955 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
1956 iter_type& __b, iter_type __e,
1957 ios_base::iostate& __err,
1958 const ctype<char_type>& __ct) const
1960 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1961 if (!(__err & ios_base::failbit) && __t <= 59)
1964 __err |= ios_base::failbit;
1967 template <class _CharT, class _InputIterator>
1969 time_get<_CharT, _InputIterator>::__get_second(int& __s,
1970 iter_type& __b, iter_type __e,
1971 ios_base::iostate& __err,
1972 const ctype<char_type>& __ct) const
1974 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1975 if (!(__err & ios_base::failbit) && __t <= 60)
1978 __err |= ios_base::failbit;
1981 template <class _CharT, class _InputIterator>
1983 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
1984 iter_type& __b, iter_type __e,
1985 ios_base::iostate& __err,
1986 const ctype<char_type>& __ct) const
1988 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
1989 if (!(__err & ios_base::failbit) && __t <= 6)
1992 __err |= ios_base::failbit;
1995 template <class _CharT, class _InputIterator>
1997 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
1998 iter_type& __b, iter_type __e,
1999 ios_base::iostate& __err,
2000 const ctype<char_type>& __ct) const
2002 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2003 if (!(__err & ios_base::failbit) && __t <= 365)
2006 __err |= ios_base::failbit;
2009 template <class _CharT, class _InputIterator>
2011 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2012 ios_base::iostate& __err,
2013 const ctype<char_type>& __ct) const
2015 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2018 __err |= ios_base::eofbit;
2021 template <class _CharT, class _InputIterator>
2023 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2024 iter_type& __b, iter_type __e,
2025 ios_base::iostate& __err,
2026 const ctype<char_type>& __ct) const
2028 const string_type* __ap = this->__am_pm();
2029 if (__ap[0].size() + __ap[1].size() == 0)
2031 __err |= ios_base::failbit;
2034 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2035 if (__i == 0 && __h == 12)
2037 else if (__i == 1 && __h < 12)
2041 template <class _CharT, class _InputIterator>
2043 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2044 ios_base::iostate& __err,
2045 const ctype<char_type>& __ct) const
2049 __err |= ios_base::eofbit | ios_base::failbit;
2052 if (__ct.narrow(*__b, 0) != '%')
2053 __err |= ios_base::failbit;
2054 else if(++__b == __e)
2055 __err |= ios_base::eofbit;
2058 // time_get end primitives
2060 template <class _CharT, class _InputIterator>
2062 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2064 ios_base::iostate& __err, tm* __tm,
2065 const char_type* __fmtb, const char_type* __fmte) const
2067 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2068 __err = ios_base::goodbit;
2069 while (__fmtb != __fmte && __err == ios_base::goodbit)
2073 __err = ios_base::failbit;
2076 if (__ct.narrow(*__fmtb, 0) == '%')
2078 if (++__fmtb == __fmte)
2080 __err = ios_base::failbit;
2083 char __cmd = __ct.narrow(*__fmtb, 0);
2085 if (__cmd == 'E' || __cmd == '0')
2087 if (++__fmtb == __fmte)
2089 __err = ios_base::failbit;
2093 __cmd = __ct.narrow(*__fmtb, 0);
2095 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2098 else if (__ct.is(ctype_base::space, *__fmtb))
2100 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2102 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2105 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2111 __err = ios_base::failbit;
2114 __err |= ios_base::eofbit;
2118 template <class _CharT, class _InputIterator>
2119 typename time_get<_CharT, _InputIterator>::dateorder
2120 time_get<_CharT, _InputIterator>::do_date_order() const
2125 template <class _CharT, class _InputIterator>
2127 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2129 ios_base::iostate& __err,
2132 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2133 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2136 template <class _CharT, class _InputIterator>
2138 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2140 ios_base::iostate& __err,
2143 const string_type& __fmt = this->__x();
2144 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2147 template <class _CharT, class _InputIterator>
2149 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2151 ios_base::iostate& __err,
2154 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2155 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2159 template <class _CharT, class _InputIterator>
2161 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2163 ios_base::iostate& __err,
2166 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2167 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2171 template <class _CharT, class _InputIterator>
2173 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2175 ios_base::iostate& __err,
2178 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2179 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2183 template <class _CharT, class _InputIterator>
2185 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2187 ios_base::iostate& __err, tm* __tm,
2188 char __fmt, char) const
2190 __err = ios_base::goodbit;
2191 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2196 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2201 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2205 const string_type& __fm = this->__c();
2206 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2211 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2215 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2216 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2221 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2222 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2226 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2229 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2232 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2235 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2238 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2242 __get_white_space(__b, __e, __err, __ct);
2245 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2249 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2250 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2255 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2256 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2260 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2264 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2265 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2269 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2272 return do_get_date(__b, __e, __iob, __err, __tm);
2275 const string_type& __fm = this->__X();
2276 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2280 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2283 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2286 __get_percent(__b, __e, __err, __ct);
2289 __err |= ios_base::failbit;
2294 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
2295 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
2297 class _LIBCPP_TYPE_VIS __time_get
2302 __time_get(const char* __nm);
2303 __time_get(const string& __nm);
2307 template <class _CharT>
2308 class _LIBCPP_TYPE_VIS_ONLY __time_get_storage
2312 typedef basic_string<_CharT> string_type;
2314 string_type __weeks_[14];
2315 string_type __months_[24];
2316 string_type __am_pm_[2];
2322 explicit __time_get_storage(const char* __nm);
2323 explicit __time_get_storage(const string& __nm);
2325 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2327 time_base::dateorder __do_date_order() const;
2330 void init(const ctype<_CharT>&);
2331 string_type __analyze(char __fmt, const ctype<_CharT>&);
2334 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2335 class _LIBCPP_TYPE_VIS_ONLY time_get_byname
2336 : public time_get<_CharT, _InputIterator>,
2337 private __time_get_storage<_CharT>
2340 typedef time_base::dateorder dateorder;
2341 typedef _InputIterator iter_type;
2342 typedef _CharT char_type;
2343 typedef basic_string<char_type> string_type;
2345 _LIBCPP_INLINE_VISIBILITY
2346 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2347 : time_get<_CharT, _InputIterator>(__refs),
2348 __time_get_storage<_CharT>(__nm) {}
2349 _LIBCPP_INLINE_VISIBILITY
2350 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2351 : time_get<_CharT, _InputIterator>(__refs),
2352 __time_get_storage<_CharT>(__nm) {}
2355 _LIBCPP_INLINE_VISIBILITY
2356 ~time_get_byname() {}
2358 _LIBCPP_INLINE_VISIBILITY
2359 virtual dateorder do_date_order() const {return this->__do_date_order();}
2361 _LIBCPP_INLINE_VISIBILITY
2362 virtual const string_type* __weeks() const {return this->__weeks_;}
2363 _LIBCPP_INLINE_VISIBILITY
2364 virtual const string_type* __months() const {return this->__months_;}
2365 _LIBCPP_INLINE_VISIBILITY
2366 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2367 _LIBCPP_INLINE_VISIBILITY
2368 virtual const string_type& __c() const {return this->__c_;}
2369 _LIBCPP_INLINE_VISIBILITY
2370 virtual const string_type& __r() const {return this->__r_;}
2371 _LIBCPP_INLINE_VISIBILITY
2372 virtual const string_type& __x() const {return this->__x_;}
2373 _LIBCPP_INLINE_VISIBILITY
2374 virtual const string_type& __X() const {return this->__X_;}
2377 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
2378 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
2380 class _LIBCPP_TYPE_VIS __time_put
2384 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2385 __time_put(const char* __nm);
2386 __time_put(const string& __nm);
2388 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2389 char __fmt, char __mod) const;
2390 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2391 char __fmt, char __mod) const;
2394 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2395 class _LIBCPP_TYPE_VIS_ONLY time_put
2396 : public locale::facet,
2400 typedef _CharT char_type;
2401 typedef _OutputIterator iter_type;
2403 _LIBCPP_ALWAYS_INLINE
2404 explicit time_put(size_t __refs = 0)
2405 : locale::facet(__refs) {}
2407 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2408 const char_type* __pb, const char_type* __pe) const;
2410 _LIBCPP_ALWAYS_INLINE
2411 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2412 const tm* __tm, char __fmt, char __mod = 0) const
2414 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2417 static locale::id id;
2420 _LIBCPP_ALWAYS_INLINE
2422 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2423 char __fmt, char __mod) const;
2425 _LIBCPP_ALWAYS_INLINE
2426 explicit time_put(const char* __nm, size_t __refs)
2427 : locale::facet(__refs),
2429 _LIBCPP_ALWAYS_INLINE
2430 explicit time_put(const string& __nm, size_t __refs)
2431 : locale::facet(__refs),
2435 template <class _CharT, class _OutputIterator>
2437 time_put<_CharT, _OutputIterator>::id;
2439 template <class _CharT, class _OutputIterator>
2441 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2442 char_type __fl, const tm* __tm,
2443 const char_type* __pb,
2444 const char_type* __pe) const
2446 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2447 for (; __pb != __pe; ++__pb)
2449 if (__ct.narrow(*__pb, 0) == '%')
2457 char __fmt = __ct.narrow(*__pb, 0);
2458 if (__fmt == 'E' || __fmt == 'O')
2467 __fmt = __ct.narrow(*__pb, 0);
2469 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2477 template <class _CharT, class _OutputIterator>
2479 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2480 char_type, const tm* __tm,
2481 char __fmt, char __mod) const
2483 char_type __nar[100];
2484 char_type* __nb = __nar;
2485 char_type* __ne = __nb + 100;
2486 __do_put(__nb, __ne, __tm, __fmt, __mod);
2487 return _VSTD::copy(__nb, __ne, __s);
2490 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
2491 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
2493 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2494 class _LIBCPP_TYPE_VIS_ONLY time_put_byname
2495 : public time_put<_CharT, _OutputIterator>
2498 _LIBCPP_ALWAYS_INLINE
2499 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2500 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2502 _LIBCPP_ALWAYS_INLINE
2503 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2504 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2507 _LIBCPP_ALWAYS_INLINE
2508 ~time_put_byname() {}
2511 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
2512 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
2516 class _LIBCPP_TYPE_VIS money_base
2519 enum part {none, space, symbol, sign, value};
2520 struct pattern {char field[4];};
2522 _LIBCPP_ALWAYS_INLINE money_base() {}
2527 template <class _CharT, bool _International = false>
2528 class _LIBCPP_TYPE_VIS_ONLY moneypunct
2529 : public locale::facet,
2533 typedef _CharT char_type;
2534 typedef basic_string<char_type> string_type;
2536 _LIBCPP_ALWAYS_INLINE
2537 explicit moneypunct(size_t __refs = 0)
2538 : locale::facet(__refs) {}
2540 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2541 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2542 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2543 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2544 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2545 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2546 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2547 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2548 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2550 static locale::id id;
2551 static const bool intl = _International;
2554 _LIBCPP_ALWAYS_INLINE
2557 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2558 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2559 virtual string do_grouping() const {return string();}
2560 virtual string_type do_curr_symbol() const {return string_type();}
2561 virtual string_type do_positive_sign() const {return string_type();}
2562 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2563 virtual int do_frac_digits() const {return 0;}
2564 virtual pattern do_pos_format() const
2565 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2566 virtual pattern do_neg_format() const
2567 {pattern __p = {{symbol, sign, none, value}}; return __p;}
2570 template <class _CharT, bool _International>
2572 moneypunct<_CharT, _International>::id;
2574 template <class _CharT, bool _International>
2576 moneypunct<_CharT, _International>::intl;
2578 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
2579 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
2580 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
2581 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
2583 // moneypunct_byname
2585 template <class _CharT, bool _International = false>
2586 class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname
2587 : public moneypunct<_CharT, _International>
2590 typedef money_base::pattern pattern;
2591 typedef _CharT char_type;
2592 typedef basic_string<char_type> string_type;
2594 _LIBCPP_ALWAYS_INLINE
2595 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2596 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2598 _LIBCPP_ALWAYS_INLINE
2599 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2600 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2603 _LIBCPP_ALWAYS_INLINE
2604 ~moneypunct_byname() {}
2606 virtual char_type do_decimal_point() const {return __decimal_point_;}
2607 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2608 virtual string do_grouping() const {return __grouping_;}
2609 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2610 virtual string_type do_positive_sign() const {return __positive_sign_;}
2611 virtual string_type do_negative_sign() const {return __negative_sign_;}
2612 virtual int do_frac_digits() const {return __frac_digits_;}
2613 virtual pattern do_pos_format() const {return __pos_format_;}
2614 virtual pattern do_neg_format() const {return __neg_format_;}
2617 char_type __decimal_point_;
2618 char_type __thousands_sep_;
2620 string_type __curr_symbol_;
2621 string_type __positive_sign_;
2622 string_type __negative_sign_;
2624 pattern __pos_format_;
2625 pattern __neg_format_;
2627 void init(const char*);
2630 template<> void moneypunct_byname<char, false>::init(const char*);
2631 template<> void moneypunct_byname<char, true>::init(const char*);
2632 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2633 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2635 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
2636 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
2637 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
2638 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
2642 template <class _CharT>
2646 typedef _CharT char_type;
2647 typedef basic_string<char_type> string_type;
2649 _LIBCPP_ALWAYS_INLINE __money_get() {}
2651 static void __gather_info(bool __intl, const locale& __loc,
2652 money_base::pattern& __pat, char_type& __dp,
2653 char_type& __ts, string& __grp,
2654 string_type& __sym, string_type& __psn,
2655 string_type& __nsn, int& __fd);
2658 template <class _CharT>
2660 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2661 money_base::pattern& __pat, char_type& __dp,
2662 char_type& __ts, string& __grp,
2663 string_type& __sym, string_type& __psn,
2664 string_type& __nsn, int& __fd)
2668 const moneypunct<char_type, true>& __mp =
2669 use_facet<moneypunct<char_type, true> >(__loc);
2670 __pat = __mp.neg_format();
2671 __nsn = __mp.negative_sign();
2672 __psn = __mp.positive_sign();
2673 __dp = __mp.decimal_point();
2674 __ts = __mp.thousands_sep();
2675 __grp = __mp.grouping();
2676 __sym = __mp.curr_symbol();
2677 __fd = __mp.frac_digits();
2681 const moneypunct<char_type, false>& __mp =
2682 use_facet<moneypunct<char_type, false> >(__loc);
2683 __pat = __mp.neg_format();
2684 __nsn = __mp.negative_sign();
2685 __psn = __mp.positive_sign();
2686 __dp = __mp.decimal_point();
2687 __ts = __mp.thousands_sep();
2688 __grp = __mp.grouping();
2689 __sym = __mp.curr_symbol();
2690 __fd = __mp.frac_digits();
2694 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
2695 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
2697 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2698 class _LIBCPP_TYPE_VIS_ONLY money_get
2699 : public locale::facet,
2700 private __money_get<_CharT>
2703 typedef _CharT char_type;
2704 typedef _InputIterator iter_type;
2705 typedef basic_string<char_type> string_type;
2707 _LIBCPP_ALWAYS_INLINE
2708 explicit money_get(size_t __refs = 0)
2709 : locale::facet(__refs) {}
2711 _LIBCPP_ALWAYS_INLINE
2712 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2713 ios_base::iostate& __err, long double& __v) const
2715 return do_get(__b, __e, __intl, __iob, __err, __v);
2718 _LIBCPP_ALWAYS_INLINE
2719 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2720 ios_base::iostate& __err, string_type& __v) const
2722 return do_get(__b, __e, __intl, __iob, __err, __v);
2725 static locale::id id;
2729 _LIBCPP_ALWAYS_INLINE
2732 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2733 ios_base& __iob, ios_base::iostate& __err,
2734 long double& __v) const;
2735 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2736 ios_base& __iob, ios_base::iostate& __err,
2737 string_type& __v) const;
2740 static bool __do_get(iter_type& __b, iter_type __e,
2741 bool __intl, const locale& __loc,
2742 ios_base::fmtflags __flags, ios_base::iostate& __err,
2743 bool& __neg, const ctype<char_type>& __ct,
2744 unique_ptr<char_type, void(*)(void*)>& __wb,
2745 char_type*& __wn, char_type* __we);
2748 template <class _CharT, class _InputIterator>
2750 money_get<_CharT, _InputIterator>::id;
2752 _LIBCPP_FUNC_VIS void __do_nothing(void*);
2754 template <class _Tp>
2757 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2759 bool __owns = __b.get_deleter() != __do_nothing;
2760 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
2761 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2762 2 * __cur_cap : numeric_limits<size_t>::max();
2764 __new_cap = sizeof(_Tp);
2765 size_t __n_off = static_cast<size_t>(__n - __b.get());
2766 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2768 __throw_bad_alloc();
2771 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2772 __new_cap /= sizeof(_Tp);
2773 __n = __b.get() + __n_off;
2774 __e = __b.get() + __new_cap;
2778 template <class _CharT, class _InputIterator>
2780 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2781 bool __intl, const locale& __loc,
2782 ios_base::fmtflags __flags,
2783 ios_base::iostate& __err,
2785 const ctype<char_type>& __ct,
2786 unique_ptr<char_type, void(*)(void*)>& __wb,
2787 char_type*& __wn, char_type* __we)
2789 const unsigned __bz = 100;
2790 unsigned __gbuf[__bz];
2791 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
2792 unsigned* __gn = __gb.get();
2793 unsigned* __ge = __gn + __bz;
2794 money_base::pattern __pat;
2801 // Capture the spaces read into money_base::{space,none} so they
2802 // can be compared to initial spaces in __sym.
2803 string_type __spaces;
2805 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
2806 __sym, __psn, __nsn, __fd);
2807 const string_type* __trailing_sign = 0;
2809 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
2811 switch (__pat.field[__p])
2813 case money_base::space:
2816 if (__ct.is(ctype_base::space, *__b))
2817 __spaces.push_back(*__b++);
2820 __err |= ios_base::failbit;
2825 case money_base::none:
2828 while (__b != __e && __ct.is(ctype_base::space, *__b))
2829 __spaces.push_back(*__b++);
2832 case money_base::sign:
2833 if (__psn.size() + __nsn.size() > 0)
2835 if (__psn.size() == 0 || __nsn.size() == 0)
2836 { // sign is optional
2837 if (__psn.size() > 0)
2838 { // __nsn.size() == 0
2839 if (*__b == __psn[0])
2842 if (__psn.size() > 1)
2843 __trailing_sign = &__psn;
2848 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
2852 if (__nsn.size() > 1)
2853 __trailing_sign = &__nsn;
2856 else // sign is required
2858 if (*__b == __psn[0])
2861 if (__psn.size() > 1)
2862 __trailing_sign = &__psn;
2864 else if (*__b == __nsn[0])
2868 if (__nsn.size() > 1)
2869 __trailing_sign = &__nsn;
2873 __err |= ios_base::failbit;
2879 case money_base::symbol:
2881 bool __more_needed = __trailing_sign ||
2883 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
2884 bool __sb = (__flags & ios_base::showbase) != 0;
2885 if (__sb || __more_needed)
2887 typename string_type::const_iterator __sym_space_end = __sym.begin();
2888 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
2889 __pat.field[__p - 1] == money_base::space)) {
2890 // Match spaces we've already read against spaces at
2891 // the beginning of __sym.
2892 while (__sym_space_end != __sym.end() &&
2893 __ct.is(ctype_base::space, *__sym_space_end))
2895 const size_t __num_spaces = __sym_space_end - __sym.begin();
2896 if (__num_spaces > __spaces.size() ||
2897 !equal(__spaces.end() - __num_spaces, __spaces.end(),
2899 // No match. Put __sym_space_end back at the
2900 // beginning of __sym, which will prevent a
2901 // match in the next loop.
2902 __sym_space_end = __sym.begin();
2905 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
2906 while (__sym_curr_char != __sym.end() && __b != __e &&
2907 *__b == *__sym_curr_char) {
2911 if (__sb && __sym_curr_char != __sym.end())
2913 __err |= ios_base::failbit;
2919 case money_base::value:
2922 for (; __b != __e; ++__b)
2924 char_type __c = *__b;
2925 if (__ct.is(ctype_base::digit, __c))
2928 __double_or_nothing(__wb, __wn, __we);
2932 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
2935 __double_or_nothing(__gb, __gn, __ge);
2942 if (__gb.get() != __gn && __ng > 0)
2945 __double_or_nothing(__gb, __gn, __ge);
2950 if (__b == __e || *__b != __dp)
2952 __err |= ios_base::failbit;
2955 for (++__b; __fd > 0; --__fd, ++__b)
2957 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
2959 __err |= ios_base::failbit;
2963 __double_or_nothing(__wb, __wn, __we);
2967 if (__wn == __wb.get())
2969 __err |= ios_base::failbit;
2976 if (__trailing_sign)
2978 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
2980 if (__b == __e || *__b != (*__trailing_sign)[__i])
2982 __err |= ios_base::failbit;
2987 if (__gb.get() != __gn)
2989 ios_base::iostate __et = ios_base::goodbit;
2990 __check_grouping(__grp, __gb.get(), __gn, __et);
2993 __err |= ios_base::failbit;
3000 template <class _CharT, class _InputIterator>
3002 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3003 bool __intl, ios_base& __iob,
3004 ios_base::iostate& __err,
3005 long double& __v) const
3007 const int __bz = 100;
3008 char_type __wbuf[__bz];
3009 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3011 char_type* __we = __wbuf + __bz;
3012 locale __loc = __iob.getloc();
3013 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3015 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3018 const char __src[] = "0123456789";
3019 char_type __atoms[sizeof(__src)-1];
3020 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3022 char* __nc = __nbuf;
3023 unique_ptr<char, void(*)(void*)> __h(0, free);
3024 if (__wn - __wb.get() > __bz-2)
3026 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3028 __throw_bad_alloc();
3033 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3034 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3036 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3037 __throw_runtime_error("money_get error");
3040 __err |= ios_base::eofbit;
3044 template <class _CharT, class _InputIterator>
3046 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3047 bool __intl, ios_base& __iob,
3048 ios_base::iostate& __err,
3049 string_type& __v) const
3051 const int __bz = 100;
3052 char_type __wbuf[__bz];
3053 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3055 char_type* __we = __wbuf + __bz;
3056 locale __loc = __iob.getloc();
3057 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3059 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3064 __v.push_back(__ct.widen('-'));
3065 char_type __z = __ct.widen('0');
3067 for (__w = __wb.get(); __w < __wn-1; ++__w)
3070 __v.append(__w, __wn);
3073 __err |= ios_base::eofbit;
3077 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
3078 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
3082 template <class _CharT>
3086 typedef _CharT char_type;
3087 typedef basic_string<char_type> string_type;
3089 _LIBCPP_ALWAYS_INLINE __money_put() {}
3091 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3092 money_base::pattern& __pat, char_type& __dp,
3093 char_type& __ts, string& __grp,
3094 string_type& __sym, string_type& __sn,
3096 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3097 ios_base::fmtflags __flags,
3098 const char_type* __db, const char_type* __de,
3099 const ctype<char_type>& __ct, bool __neg,
3100 const money_base::pattern& __pat, char_type __dp,
3101 char_type __ts, const string& __grp,
3102 const string_type& __sym, const string_type& __sn,
3106 template <class _CharT>
3108 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3109 money_base::pattern& __pat, char_type& __dp,
3110 char_type& __ts, string& __grp,
3111 string_type& __sym, string_type& __sn,
3116 const moneypunct<char_type, true>& __mp =
3117 use_facet<moneypunct<char_type, true> >(__loc);
3120 __pat = __mp.neg_format();
3121 __sn = __mp.negative_sign();
3125 __pat = __mp.pos_format();
3126 __sn = __mp.positive_sign();
3128 __dp = __mp.decimal_point();
3129 __ts = __mp.thousands_sep();
3130 __grp = __mp.grouping();
3131 __sym = __mp.curr_symbol();
3132 __fd = __mp.frac_digits();
3136 const moneypunct<char_type, false>& __mp =
3137 use_facet<moneypunct<char_type, false> >(__loc);
3140 __pat = __mp.neg_format();
3141 __sn = __mp.negative_sign();
3145 __pat = __mp.pos_format();
3146 __sn = __mp.positive_sign();
3148 __dp = __mp.decimal_point();
3149 __ts = __mp.thousands_sep();
3150 __grp = __mp.grouping();
3151 __sym = __mp.curr_symbol();
3152 __fd = __mp.frac_digits();
3156 template <class _CharT>
3158 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3159 ios_base::fmtflags __flags,
3160 const char_type* __db, const char_type* __de,
3161 const ctype<char_type>& __ct, bool __neg,
3162 const money_base::pattern& __pat, char_type __dp,
3163 char_type __ts, const string& __grp,
3164 const string_type& __sym, const string_type& __sn,
3168 for (unsigned __p = 0; __p < 4; ++__p)
3170 switch (__pat.field[__p])
3172 case money_base::none:
3175 case money_base::space:
3177 *__me++ = __ct.widen(' ');
3179 case money_base::sign:
3183 case money_base::symbol:
3184 if (!__sym.empty() && (__flags & ios_base::showbase))
3185 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3187 case money_base::value:
3189 // remember start of value so we can reverse it
3190 char_type* __t = __me;
3191 // find beginning of digits
3194 // find end of digits
3195 const char_type* __d;
3196 for (__d = __db; __d < __de; ++__d)
3197 if (!__ct.is(ctype_base::digit, *__d))
3199 // print fractional part
3203 for (__f = __fd; __d > __db && __f > 0; --__f)
3205 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3206 for (; __f > 0; --__f)
3213 *__me++ = __ct.widen('0');
3219 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3220 : static_cast<unsigned>(__grp[__ig]);
3227 if (++__ig < __grp.size())
3228 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3229 numeric_limits<unsigned>::max() :
3230 static_cast<unsigned>(__grp[__ig]);
3242 // print rest of sign, if any
3243 if (__sn.size() > 1)
3244 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3246 if ((__flags & ios_base::adjustfield) == ios_base::left)
3248 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3252 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
3253 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
3255 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3256 class _LIBCPP_TYPE_VIS_ONLY money_put
3257 : public locale::facet,
3258 private __money_put<_CharT>
3261 typedef _CharT char_type;
3262 typedef _OutputIterator iter_type;
3263 typedef basic_string<char_type> string_type;
3265 _LIBCPP_ALWAYS_INLINE
3266 explicit money_put(size_t __refs = 0)
3267 : locale::facet(__refs) {}
3269 _LIBCPP_ALWAYS_INLINE
3270 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3271 long double __units) const
3273 return do_put(__s, __intl, __iob, __fl, __units);
3276 _LIBCPP_ALWAYS_INLINE
3277 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3278 const string_type& __digits) const
3280 return do_put(__s, __intl, __iob, __fl, __digits);
3283 static locale::id id;
3286 _LIBCPP_ALWAYS_INLINE
3289 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3290 char_type __fl, long double __units) const;
3291 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3292 char_type __fl, const string_type& __digits) const;
3295 template <class _CharT, class _OutputIterator>
3297 money_put<_CharT, _OutputIterator>::id;
3299 template <class _CharT, class _OutputIterator>
3301 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3302 ios_base& __iob, char_type __fl,
3303 long double __units) const
3306 const size_t __bs = 100;
3309 char_type __digits[__bs];
3310 char_type* __db = __digits;
3311 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3312 unique_ptr<char, void(*)(void*)> __hn(0, free);
3313 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3314 // secure memory for digit storage
3317 __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3319 __throw_bad_alloc();
3321 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3322 if (__hd == nullptr)
3323 __throw_bad_alloc();
3327 locale __loc = __iob.getloc();
3328 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3329 __ct.widen(__bb, __bb + __n, __db);
3330 bool __neg = __n > 0 && __bb[0] == '-';
3331 money_base::pattern __pat;
3338 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3339 // secure memory for formatting
3340 char_type __mbuf[__bs];
3341 char_type* __mb = __mbuf;
3342 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3343 size_t __exn = static_cast<int>(__n) > __fd ?
3344 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3345 __sym.size() + static_cast<size_t>(__fd) + 1
3346 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3349 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3352 __throw_bad_alloc();
3357 this->__format(__mb, __mi, __me, __iob.flags(),
3358 __db, __db + __n, __ct,
3359 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3360 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3363 template <class _CharT, class _OutputIterator>
3365 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3366 ios_base& __iob, char_type __fl,
3367 const string_type& __digits) const
3370 locale __loc = __iob.getloc();
3371 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3372 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3373 money_base::pattern __pat;
3380 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3381 // secure memory for formatting
3382 char_type __mbuf[100];
3383 char_type* __mb = __mbuf;
3384 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3385 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3386 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3387 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3388 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3391 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3394 __throw_bad_alloc();
3399 this->__format(__mb, __mi, __me, __iob.flags(),
3400 __digits.data(), __digits.data() + __digits.size(), __ct,
3401 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3402 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3405 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
3406 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
3410 class _LIBCPP_TYPE_VIS messages_base
3413 typedef ptrdiff_t catalog;
3415 _LIBCPP_ALWAYS_INLINE messages_base() {}
3418 template <class _CharT>
3419 class _LIBCPP_TYPE_VIS_ONLY messages
3420 : public locale::facet,
3421 public messages_base
3424 typedef _CharT char_type;
3425 typedef basic_string<_CharT> string_type;
3427 _LIBCPP_ALWAYS_INLINE
3428 explicit messages(size_t __refs = 0)
3429 : locale::facet(__refs) {}
3431 _LIBCPP_ALWAYS_INLINE
3432 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3434 return do_open(__nm, __loc);
3437 _LIBCPP_ALWAYS_INLINE
3438 string_type get(catalog __c, int __set, int __msgid,
3439 const string_type& __dflt) const
3441 return do_get(__c, __set, __msgid, __dflt);
3444 _LIBCPP_ALWAYS_INLINE
3445 void close(catalog __c) const
3450 static locale::id id;
3453 _LIBCPP_ALWAYS_INLINE
3456 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3457 virtual string_type do_get(catalog, int __set, int __msgid,
3458 const string_type& __dflt) const;
3459 virtual void do_close(catalog) const;
3462 template <class _CharT>
3464 messages<_CharT>::id;
3466 template <class _CharT>
3467 typename messages<_CharT>::catalog
3468 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3470 #ifdef _LIBCPP_HAS_CATOPEN
3471 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3473 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3475 #else // !_LIBCPP_HAS_CATOPEN
3477 #endif // _LIBCPP_HAS_CATOPEN
3480 template <class _CharT>
3481 typename messages<_CharT>::string_type
3482 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3483 const string_type& __dflt) const
3485 #ifdef _LIBCPP_HAS_CATOPEN
3487 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3489 __dflt.c_str() + __dflt.size());
3492 nl_catd __cat = (nl_catd)__c;
3493 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3495 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3496 __n, __n + strlen(__n));
3498 #else // !_LIBCPP_HAS_CATOPEN
3500 #endif // _LIBCPP_HAS_CATOPEN
3503 template <class _CharT>
3505 messages<_CharT>::do_close(catalog __c) const
3507 #ifdef _LIBCPP_HAS_CATOPEN
3510 nl_catd __cat = (nl_catd)__c;
3512 #endif // _LIBCPP_HAS_CATOPEN
3515 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
3516 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
3518 template <class _CharT>
3519 class _LIBCPP_TYPE_VIS_ONLY messages_byname
3520 : public messages<_CharT>
3523 typedef messages_base::catalog catalog;
3524 typedef basic_string<_CharT> string_type;
3526 _LIBCPP_ALWAYS_INLINE
3527 explicit messages_byname(const char*, size_t __refs = 0)
3528 : messages<_CharT>(__refs) {}
3530 _LIBCPP_ALWAYS_INLINE
3531 explicit messages_byname(const string&, size_t __refs = 0)
3532 : messages<_CharT>(__refs) {}
3535 _LIBCPP_ALWAYS_INLINE
3536 ~messages_byname() {}
3539 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
3540 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
3542 template<class _Codecvt, class _Elem = wchar_t,
3543 class _Wide_alloc = allocator<_Elem>,
3544 class _Byte_alloc = allocator<char> >
3545 class _LIBCPP_TYPE_VIS_ONLY wstring_convert
3548 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3549 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3550 typedef typename _Codecvt::state_type state_type;
3551 typedef typename wide_string::traits_type::int_type int_type;
3554 byte_string __byte_err_string_;
3555 wide_string __wide_err_string_;
3556 _Codecvt* __cvtptr_;
3557 state_type __cvtstate_;
3560 wstring_convert(const wstring_convert& __wc);
3561 wstring_convert& operator=(const wstring_convert& __wc);
3563 _LIBCPP_ALWAYS_INLINE
3564 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3565 _LIBCPP_ALWAYS_INLINE
3566 wstring_convert(_Codecvt* __pcvt, state_type __state);
3567 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
3568 const wide_string& __wide_err = wide_string());
3569 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3570 _LIBCPP_ALWAYS_INLINE
3571 wstring_convert(wstring_convert&& __wc);
3575 _LIBCPP_ALWAYS_INLINE
3576 wide_string from_bytes(char __byte)
3577 {return from_bytes(&__byte, &__byte+1);}
3578 _LIBCPP_ALWAYS_INLINE
3579 wide_string from_bytes(const char* __ptr)
3580 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3581 _LIBCPP_ALWAYS_INLINE
3582 wide_string from_bytes(const byte_string& __str)
3583 {return from_bytes(__str.data(), __str.data() + __str.size());}
3584 wide_string from_bytes(const char* __first, const char* __last);
3586 _LIBCPP_ALWAYS_INLINE
3587 byte_string to_bytes(_Elem __wchar)
3588 {return to_bytes(&__wchar, &__wchar+1);}
3589 _LIBCPP_ALWAYS_INLINE
3590 byte_string to_bytes(const _Elem* __wptr)
3591 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3592 _LIBCPP_ALWAYS_INLINE
3593 byte_string to_bytes(const wide_string& __wstr)
3594 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3595 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3597 _LIBCPP_ALWAYS_INLINE
3598 size_t converted() const _NOEXCEPT {return __cvtcount_;}
3599 _LIBCPP_ALWAYS_INLINE
3600 state_type state() const {return __cvtstate_;}
3603 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3605 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3606 wstring_convert(_Codecvt* __pcvt)
3607 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3611 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3613 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3614 wstring_convert(_Codecvt* __pcvt, state_type __state)
3615 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3619 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3620 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3621 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3622 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3623 __cvtstate_(), __cvtcount_(0)
3625 __cvtptr_ = new _Codecvt;
3628 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3630 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3632 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3633 wstring_convert(wstring_convert&& __wc)
3634 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3635 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3636 __cvtptr_(__wc.__cvtptr_),
3637 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_)
3639 __wc.__cvtptr_ = nullptr;
3642 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3644 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3645 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3650 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3651 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3652 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3653 from_bytes(const char* __frm, const char* __frm_end)
3656 if (__cvtptr_ != nullptr)
3658 wide_string __ws(2*(__frm_end - __frm), _Elem());
3659 if (__frm != __frm_end)
3660 __ws.resize(__ws.capacity());
3661 codecvt_base::result __r = codecvt_base::ok;
3662 state_type __st = __cvtstate_;
3663 if (__frm != __frm_end)
3665 _Elem* __to = &__ws[0];
3666 _Elem* __to_end = __to + __ws.size();
3667 const char* __frm_nxt;
3671 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3672 __to, __to_end, __to_nxt);
3673 __cvtcount_ += __frm_nxt - __frm;
3674 if (__frm_nxt == __frm)
3676 __r = codecvt_base::error;
3678 else if (__r == codecvt_base::noconv)
3680 __ws.resize(__to - &__ws[0]);
3681 // This only gets executed if _Elem is char
3682 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3684 __r = codecvt_base::ok;
3686 else if (__r == codecvt_base::ok)
3688 __ws.resize(__to_nxt - &__ws[0]);
3691 else if (__r == codecvt_base::partial)
3693 ptrdiff_t __s = __to_nxt - &__ws[0];
3694 __ws.resize(2 * __s);
3695 __to = &__ws[0] + __s;
3696 __to_end = &__ws[0] + __ws.size();
3699 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3701 if (__r == codecvt_base::ok)
3704 #ifndef _LIBCPP_NO_EXCEPTIONS
3705 if (__wide_err_string_.empty())
3706 throw range_error("wstring_convert: from_bytes error");
3707 #endif // _LIBCPP_NO_EXCEPTIONS
3708 return __wide_err_string_;
3711 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3712 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3713 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3714 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3717 if (__cvtptr_ != nullptr)
3719 byte_string __bs(2*(__frm_end - __frm), char());
3720 if (__frm != __frm_end)
3721 __bs.resize(__bs.capacity());
3722 codecvt_base::result __r = codecvt_base::ok;
3723 state_type __st = __cvtstate_;
3724 if (__frm != __frm_end)
3726 char* __to = &__bs[0];
3727 char* __to_end = __to + __bs.size();
3728 const _Elem* __frm_nxt;
3732 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3733 __to, __to_end, __to_nxt);
3734 __cvtcount_ += __frm_nxt - __frm;
3735 if (__frm_nxt == __frm)
3737 __r = codecvt_base::error;
3739 else if (__r == codecvt_base::noconv)
3741 __bs.resize(__to - &__bs[0]);
3742 // This only gets executed if _Elem is char
3743 __bs.append((const char*)__frm, (const char*)__frm_end);
3745 __r = codecvt_base::ok;
3747 else if (__r == codecvt_base::ok)
3749 __bs.resize(__to_nxt - &__bs[0]);
3752 else if (__r == codecvt_base::partial)
3754 ptrdiff_t __s = __to_nxt - &__bs[0];
3755 __bs.resize(2 * __s);
3756 __to = &__bs[0] + __s;
3757 __to_end = &__bs[0] + __bs.size();
3760 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3762 if (__r == codecvt_base::ok)
3764 size_t __s = __bs.size();
3765 __bs.resize(__bs.capacity());
3766 char* __to = &__bs[0] + __s;
3767 char* __to_end = __to + __bs.size();
3771 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3772 if (__r == codecvt_base::noconv)
3774 __bs.resize(__to - &__bs[0]);
3775 __r = codecvt_base::ok;
3777 else if (__r == codecvt_base::ok)
3779 __bs.resize(__to_nxt - &__bs[0]);
3781 else if (__r == codecvt_base::partial)
3783 ptrdiff_t __sp = __to_nxt - &__bs[0];
3784 __bs.resize(2 * __sp);
3785 __to = &__bs[0] + __sp;
3786 __to_end = &__bs[0] + __bs.size();
3788 } while (__r == codecvt_base::partial);
3789 if (__r == codecvt_base::ok)
3793 #ifndef _LIBCPP_NO_EXCEPTIONS
3794 if (__byte_err_string_.empty())
3795 throw range_error("wstring_convert: to_bytes error");
3796 #endif // _LIBCPP_NO_EXCEPTIONS
3797 return __byte_err_string_;
3800 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
3801 class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert
3802 : public basic_streambuf<_Elem, _Tr>
3806 typedef _Elem char_type;
3807 typedef _Tr traits_type;
3808 typedef typename traits_type::int_type int_type;
3809 typedef typename traits_type::pos_type pos_type;
3810 typedef typename traits_type::off_type off_type;
3811 typedef typename _Codecvt::state_type state_type;
3815 const char* __extbufnext_;
3816 const char* __extbufend_;
3817 char __extbuf_min_[8];
3819 char_type* __intbuf_;
3821 streambuf* __bufptr_;
3824 ios_base::openmode __cm_;
3827 bool __always_noconv_;
3829 wbuffer_convert(const wbuffer_convert&);
3830 wbuffer_convert& operator=(const wbuffer_convert&);
3832 _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0,
3833 _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
3836 _LIBCPP_INLINE_VISIBILITY
3837 streambuf* rdbuf() const {return __bufptr_;}
3838 _LIBCPP_INLINE_VISIBILITY
3839 streambuf* rdbuf(streambuf* __bytebuf)
3841 streambuf* __r = __bufptr_;
3842 __bufptr_ = __bytebuf;
3846 _LIBCPP_INLINE_VISIBILITY
3847 state_type state() const {return __st_;}
3850 virtual int_type underflow();
3851 virtual int_type pbackfail(int_type __c = traits_type::eof());
3852 virtual int_type overflow (int_type __c = traits_type::eof());
3853 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
3855 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
3856 ios_base::openmode __wch = ios_base::in | ios_base::out);
3857 virtual pos_type seekpos(pos_type __sp,
3858 ios_base::openmode __wch = ios_base::in | ios_base::out);
3863 void __write_mode();
3864 wbuffer_convert* __close();
3867 template <class _Codecvt, class _Elem, class _Tr>
3868 wbuffer_convert<_Codecvt, _Elem, _Tr>::
3869 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
3876 __bufptr_(__bytebuf),
3882 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
3887 template <class _Codecvt, class _Elem, class _Tr>
3888 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
3893 delete [] __extbuf_;
3895 delete [] __intbuf_;
3898 template <class _Codecvt, class _Elem, class _Tr>
3899 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3900 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
3902 if (__cv_ == 0 || __bufptr_ == 0)
3903 return traits_type::eof();
3904 bool __initial = __read_mode();
3906 if (this->gptr() == 0)
3907 this->setg(&__1buf, &__1buf+1, &__1buf+1);
3908 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
3909 int_type __c = traits_type::eof();
3910 if (this->gptr() == this->egptr())
3912 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
3913 if (__always_noconv_)
3915 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
3916 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
3919 this->setg(this->eback(),
3920 this->eback() + __unget_sz,
3921 this->eback() + __unget_sz + __nmemb);
3922 __c = *this->gptr();
3927 _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
3928 if (__extbufend_ != __extbufnext_)
3929 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
3930 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
3931 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
3932 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
3933 static_cast<streamsize>(__extbufend_ - __extbufnext_));
3934 codecvt_base::result __r;
3935 state_type __svs = __st_;
3936 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
3939 __extbufend_ = __extbufnext_ + __nr;
3941 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
3942 this->eback() + __unget_sz,
3943 this->egptr(), __inext);
3944 if (__r == codecvt_base::noconv)
3946 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
3947 __c = *this->gptr();
3949 else if (__inext != this->eback() + __unget_sz)
3951 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
3952 __c = *this->gptr();
3958 __c = *this->gptr();
3959 if (this->eback() == &__1buf)
3960 this->setg(0, 0, 0);
3964 template <class _Codecvt, class _Elem, class _Tr>
3965 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3966 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
3968 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
3970 if (traits_type::eq_int_type(__c, traits_type::eof()))
3973 return traits_type::not_eof(__c);
3975 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
3978 *this->gptr() = traits_type::to_char_type(__c);
3982 return traits_type::eof();
3985 template <class _Codecvt, class _Elem, class _Tr>
3986 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3987 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
3989 if (__cv_ == 0 || __bufptr_ == 0)
3990 return traits_type::eof();
3993 char_type* __pb_save = this->pbase();
3994 char_type* __epb_save = this->epptr();
3995 if (!traits_type::eq_int_type(__c, traits_type::eof()))
3997 if (this->pptr() == 0)
3998 this->setp(&__1buf, &__1buf+1);
3999 *this->pptr() = traits_type::to_char_type(__c);
4002 if (this->pptr() != this->pbase())
4004 if (__always_noconv_)
4006 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4007 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4008 return traits_type::eof();
4012 char* __extbe = __extbuf_;
4013 codecvt_base::result __r;
4016 const char_type* __e;
4017 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4018 __extbuf_, __extbuf_ + __ebs_, __extbe);
4019 if (__e == this->pbase())
4020 return traits_type::eof();
4021 if (__r == codecvt_base::noconv)
4023 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4024 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4025 return traits_type::eof();
4027 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4029 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4030 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4031 return traits_type::eof();
4032 if (__r == codecvt_base::partial)
4034 this->setp((char_type*)__e, this->pptr());
4035 this->pbump(this->epptr() - this->pbase());
4039 return traits_type::eof();
4040 } while (__r == codecvt_base::partial);
4042 this->setp(__pb_save, __epb_save);
4044 return traits_type::not_eof(__c);
4047 template <class _Codecvt, class _Elem, class _Tr>
4048 basic_streambuf<_Elem, _Tr>*
4049 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4051 this->setg(0, 0, 0);
4054 delete [] __extbuf_;
4056 delete [] __intbuf_;
4058 if (__ebs_ > sizeof(__extbuf_min_))
4060 if (__always_noconv_ && __s)
4062 __extbuf_ = (char*)__s;
4067 __extbuf_ = new char[__ebs_];
4073 __extbuf_ = __extbuf_min_;
4074 __ebs_ = sizeof(__extbuf_min_);
4077 if (!__always_noconv_)
4079 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4080 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4087 __intbuf_ = new char_type[__ibs_];
4100 template <class _Codecvt, class _Elem, class _Tr>
4101 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4102 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4103 ios_base::openmode __om)
4105 int __width = __cv_->encoding();
4106 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4107 return pos_type(off_type(-1));
4108 // __width > 0 || __off == 0, now check __way
4109 if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end)
4110 return pos_type(off_type(-1));
4111 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4116 template <class _Codecvt, class _Elem, class _Tr>
4117 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4118 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4120 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4121 return pos_type(off_type(-1));
4122 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4123 return pos_type(off_type(-1));
4127 template <class _Codecvt, class _Elem, class _Tr>
4129 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4131 if (__cv_ == 0 || __bufptr_ == 0)
4133 if (__cm_ & ios_base::out)
4135 if (this->pptr() != this->pbase())
4136 if (overflow() == traits_type::eof())
4138 codecvt_base::result __r;
4142 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4143 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4144 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4146 } while (__r == codecvt_base::partial);
4147 if (__r == codecvt_base::error)
4149 if (__bufptr_->pubsync())
4152 else if (__cm_ & ios_base::in)
4155 if (__always_noconv_)
4156 __c = this->egptr() - this->gptr();
4159 int __width = __cv_->encoding();
4160 __c = __extbufend_ - __extbufnext_;
4162 __c += __width * (this->egptr() - this->gptr());
4165 if (this->gptr() != this->egptr())
4167 reverse(this->gptr(), this->egptr());
4168 codecvt_base::result __r;
4169 const char_type* __e = this->gptr();
4173 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4174 __extbuf_, __extbuf_ + __ebs_, __extbe);
4177 case codecvt_base::noconv:
4178 __c += this->egptr() - this->gptr();
4180 case codecvt_base::ok:
4181 case codecvt_base::partial:
4182 __c += __extbe - __extbuf_;
4187 } while (__r == codecvt_base::partial);
4191 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4193 this->setg(0, 0, 0);
4199 template <class _Codecvt, class _Elem, class _Tr>
4201 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4203 if (!(__cm_ & ios_base::in))
4206 if (__always_noconv_)
4207 this->setg((char_type*)__extbuf_,
4208 (char_type*)__extbuf_ + __ebs_,
4209 (char_type*)__extbuf_ + __ebs_);
4211 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4212 __cm_ = ios_base::in;
4218 template <class _Codecvt, class _Elem, class _Tr>
4220 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4222 if (!(__cm_ & ios_base::out))
4224 this->setg(0, 0, 0);
4225 if (__ebs_ > sizeof(__extbuf_min_))
4227 if (__always_noconv_)
4228 this->setp((char_type*)__extbuf_,
4229 (char_type*)__extbuf_ + (__ebs_ - 1));
4231 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4235 __cm_ = ios_base::out;
4239 template <class _Codecvt, class _Elem, class _Tr>
4240 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4241 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4243 wbuffer_convert* __rt = 0;
4244 if (__cv_ != 0 && __bufptr_ != 0)
4247 if ((__cm_ & ios_base::out) && sync())
4253 _LIBCPP_END_NAMESPACE_STD
4255 #endif // _LIBCPP_LOCALE