2 //===-------------------------- locale ------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_LOCALE
12 #define _LIBCPP_LOCALE
28 static const category // values assigned here are for exposition only
36 all = collate | ctype | monetary | numeric | time | messages;
38 // construct/copy/destroy:
40 locale(const locale& other) noexcept;
41 explicit locale(const char* std_name);
42 explicit locale(const string& std_name);
43 locale(const locale& other, const char* std_name, category);
44 locale(const locale& other, const string& std_name, category);
45 template <class Facet> locale(const locale& other, Facet* f);
46 locale(const locale& other, const locale& one, category);
48 ~locale(); // not virtual
50 const locale& operator=(const locale& other) noexcept;
52 template <class Facet> locale combine(const locale& other) const;
55 basic_string<char> name() const;
56 bool operator==(const locale& other) const;
57 bool operator!=(const locale& other) const;
58 template <class charT, class Traits, class Allocator>
59 bool operator()(const basic_string<charT,Traits,Allocator>& s1,
60 const basic_string<charT,Traits,Allocator>& s2) const;
62 // global locale objects:
63 static locale global(const locale&);
64 static const locale& classic();
67 template <class Facet> const Facet& use_facet(const locale&);
68 template <class Facet> bool has_facet(const locale&) noexcept;
70 // 22.3.3, convenience interfaces:
71 template <class charT> bool isspace (charT c, const locale& loc);
72 template <class charT> bool isprint (charT c, const locale& loc);
73 template <class charT> bool iscntrl (charT c, const locale& loc);
74 template <class charT> bool isupper (charT c, const locale& loc);
75 template <class charT> bool islower (charT c, const locale& loc);
76 template <class charT> bool isalpha (charT c, const locale& loc);
77 template <class charT> bool isdigit (charT c, const locale& loc);
78 template <class charT> bool ispunct (charT c, const locale& loc);
79 template <class charT> bool isxdigit(charT c, const locale& loc);
80 template <class charT> bool isalnum (charT c, const locale& loc);
81 template <class charT> bool isgraph (charT c, const locale& loc);
82 template <class charT> charT toupper(charT c, const locale& loc);
83 template <class charT> charT tolower(charT c, const locale& loc);
85 template<class Codecvt, class Elem = wchar_t,
86 class Wide_alloc = allocator<Elem>,
87 class Byte_alloc = allocator<char>>
91 typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
92 typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
93 typedef typename Codecvt::state_type state_type;
94 typedef typename wide_string::traits_type::int_type int_type;
96 wstring_convert(Codecvt* pcvt = new Codecvt);
97 wstring_convert(Codecvt* pcvt, state_type state);
98 wstring_convert(const byte_string& byte_err,
99 const wide_string& wide_err = wide_string());
102 wide_string from_bytes(char byte);
103 wide_string from_bytes(const char* ptr);
104 wide_string from_bytes(const byte_string& str);
105 wide_string from_bytes(const char* first, const char* last);
107 byte_string to_bytes(Elem wchar);
108 byte_string to_bytes(const Elem* wptr);
109 byte_string to_bytes(const wide_string& wstr);
110 byte_string to_bytes(const Elem* first, const Elem* last);
112 size_t converted() const;
113 state_type state() const;
116 template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
117 class wbuffer_convert
118 : public basic_streambuf<Elem, Tr>
121 typedef typename Tr::state_type state_type;
123 wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
124 state_type state = state_type());
126 streambuf* rdbuf() const;
127 streambuf* rdbuf(streambuf* bytebuf);
129 state_type state() const;
132 // 22.4.1 and 22.4.1.3, ctype:
134 template <class charT> class ctype;
135 template <> class ctype<char>; // specialization
136 template <class charT> class ctype_byname;
137 template <> class ctype_byname<char>; // specialization
140 template <class internT, class externT, class stateT> class codecvt;
141 template <class internT, class externT, class stateT> class codecvt_byname;
143 // 22.4.2 and 22.4.3, numeric:
144 template <class charT, class InputIterator> class num_get;
145 template <class charT, class OutputIterator> class num_put;
146 template <class charT> class numpunct;
147 template <class charT> class numpunct_byname;
149 // 22.4.4, col lation:
150 template <class charT> class collate;
151 template <class charT> class collate_byname;
153 // 22.4.5, date and time:
155 template <class charT, class InputIterator> class time_get;
156 template <class charT, class InputIterator> class time_get_byname;
157 template <class charT, class OutputIterator> class time_put;
158 template <class charT, class OutputIterator> class time_put_byname;
162 template <class charT, class InputIterator> class money_get;
163 template <class charT, class OutputIterator> class money_put;
164 template <class charT, bool Intl> class moneypunct;
165 template <class charT, bool Intl> class moneypunct_byname;
167 // 22.4.7, message retrieval:
169 template <class charT> class messages;
170 template <class charT> class messages_byname;
190 #include <support/win32/locale_win32.h>
192 #include <nl_types.h>
196 #include <Availability.h>
199 #include <__undef_min_max>
201 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
202 #pragma GCC system_header
205 _LIBCPP_BEGIN_NAMESPACE_STD
207 #if defined(__APPLE__) || defined(__FreeBSD__)
208 # define _LIBCPP_GET_C_LOCALE 0
209 #elif defined(__NetBSD__)
210 # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
212 # define _LIBCPP_GET_C_LOCALE __cloc()
213 // Get the C locale object
215 #define __cloc_defined
218 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
219 typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
220 #ifndef _LIBCPP_LOCALE__L_EXTENSIONS
221 typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
224 // OSX has nice foo_l() functions that let you turn off use of the global
225 // locale. Linux, not so much. The following functions avoid the locale when
226 // that's possible and otherwise do the wrong thing. FIXME.
227 #if defined(__linux__) || defined(EMSCRIPTEN)
229 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
230 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
231 inline _LIBCPP_INLINE_VISIBILITY
232 __mb_cur_max_l(locale_t __l)
234 return MB_CUR_MAX_L(__l);
236 #else // _LIBCPP_LOCALE__L_EXTENSIONS
237 _LIBCPP_ALWAYS_INLINE inline
238 decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
240 __locale_raii __current(uselocale(__l), uselocale);
243 #endif // _LIBCPP_LOCALE__L_EXTENSIONS
245 _LIBCPP_ALWAYS_INLINE inline
246 wint_t __btowc_l(int __c, locale_t __l)
248 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
249 return btowc_l(__c, __l);
251 __locale_raii __current(uselocale(__l), uselocale);
256 _LIBCPP_ALWAYS_INLINE inline
257 int __wctob_l(wint_t __c, locale_t __l)
259 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
260 return wctob_l(__c, __l);
262 __locale_raii __current(uselocale(__l), uselocale);
267 _LIBCPP_ALWAYS_INLINE inline
268 size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
269 size_t __len, mbstate_t *__ps, locale_t __l)
271 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
272 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
274 __locale_raii __current(uselocale(__l), uselocale);
275 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
279 _LIBCPP_ALWAYS_INLINE inline
280 size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
282 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
283 return wcrtomb_l(__s, __wc, __ps, __l);
285 __locale_raii __current(uselocale(__l), uselocale);
286 return wcrtomb(__s, __wc, __ps);
290 _LIBCPP_ALWAYS_INLINE inline
291 size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
292 size_t __len, mbstate_t *__ps, locale_t __l)
294 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
295 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
297 __locale_raii __current(uselocale(__l), uselocale);
298 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
302 _LIBCPP_ALWAYS_INLINE inline
303 size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
304 mbstate_t *__ps, locale_t __l)
306 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
307 return mbrtowc_l(__pwc, __s, __n, __ps, __l);
309 __locale_raii __current(uselocale(__l), uselocale);
310 return mbrtowc(__pwc, __s, __n, __ps);
314 _LIBCPP_ALWAYS_INLINE inline
315 int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
317 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
318 return mbtowc_l(__pwc, __pmb, __max, __l);
320 __locale_raii __current(uselocale(__l), uselocale);
321 return mbtowc(__pwc, __pmb, __max);
325 _LIBCPP_ALWAYS_INLINE inline
326 size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
328 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
329 return mbrlen_l(__s, __n, __ps, __l);
331 __locale_raii __current(uselocale(__l), uselocale);
332 return mbrlen(__s, __n, __ps);
336 _LIBCPP_ALWAYS_INLINE inline
337 lconv *__localeconv_l(locale_t __l)
339 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
340 return localeconv_l(__l);
342 __locale_raii __current(uselocale(__l), uselocale);
347 _LIBCPP_ALWAYS_INLINE inline
348 size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
349 mbstate_t *__ps, locale_t __l)
351 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
352 return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
354 __locale_raii __current(uselocale(__l), uselocale);
355 return mbsrtowcs(__dest, __src, __len, __ps);
360 int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
362 va_start(__va, __format);
363 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
364 int __res = vsnprintf_l(__s, __n, __l, __format, __va);
366 __locale_raii __current(uselocale(__l), uselocale);
367 int __res = vsnprintf(__s, __n, __format, __va);
374 int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
376 va_start(__va, __format);
377 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
378 int __res = vasprintf_l(__s, __l, __format, __va);
380 __locale_raii __current(uselocale(__l), uselocale);
381 int __res = vasprintf(__s, __format, __va);
388 int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
390 va_start(__va, __format);
391 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
392 int __res = vsscanf_l(__s, __l, __format, __va);
394 __locale_raii __current(uselocale(__l), uselocale);
395 int __res = vsscanf(__s, __format, __va);
404 // Scans [__b, __e) until a match is found in the basic_strings range
405 // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
406 // __b will be incremented (visibly), consuming CharT until a match is found
407 // or proved to not exist. A keyword may be "", in which will match anything.
408 // If one keyword is a prefix of another, and the next CharT in the input
409 // might match another keyword, the algorithm will attempt to find the longest
410 // matching keyword. If the longer matching keyword ends up not matching, then
411 // no keyword match is found. If no keyword match is found, __ke is returned
412 // and failbit is set in __err.
413 // Else an iterator pointing to the matching keyword is found. If more than
414 // one keyword matches, an iterator to the first matching keyword is returned.
415 // If on exit __b == __e, eofbit is set in __err. If __case_senstive is false,
416 // __ct is used to force to lower case before comparing characters.
418 // Keywords: "a", "abb"
419 // If the input is "a", the first keyword matches and eofbit is set.
420 // If the input is "abc", no match is found and "ab" are consumed.
421 template <class _InputIterator, class _ForwardIterator, class _Ctype>
424 __scan_keyword(_InputIterator& __b, _InputIterator __e,
425 _ForwardIterator __kb, _ForwardIterator __ke,
426 const _Ctype& __ct, ios_base::iostate& __err,
427 bool __case_sensitive = true)
429 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
430 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
431 const unsigned char __doesnt_match = '\0';
432 const unsigned char __might_match = '\1';
433 const unsigned char __does_match = '\2';
434 unsigned char __statbuf[100];
435 unsigned char* __status = __statbuf;
436 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
437 if (__nkw > sizeof(__statbuf))
439 __status = (unsigned char*)malloc(__nkw);
442 __stat_hold.reset(__status);
444 size_t __n_might_match = __nkw; // At this point, any keyword might match
445 size_t __n_does_match = 0; // but none of them definitely do
446 // Initialize all statuses to __might_match, except for "" keywords are __does_match
447 unsigned char* __st = __status;
448 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
451 *__st = __might_match;
454 *__st = __does_match;
459 // While there might be a match, test keywords against the next CharT
460 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
462 // Peek at the next CharT but don't consume it
464 if (!__case_sensitive)
465 __c = __ct.toupper(__c);
466 bool __consume = false;
467 // For each keyword which might match, see if the __indx character is __c
468 // If a match if found, consume __c
469 // If a match is found, and that is the last character in the keyword,
470 // then that keyword matches.
471 // If the keyword doesn't match this character, then change the keyword
474 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
476 if (*__st == __might_match)
478 _CharT __kc = (*__ky)[__indx];
479 if (!__case_sensitive)
480 __kc = __ct.toupper(__kc);
484 if (__ky->size() == __indx+1)
486 *__st = __does_match;
493 *__st = __doesnt_match;
498 // consume if we matched a character
502 // If we consumed a character and there might be a matched keyword that
503 // was marked matched on a previous iteration, then such keywords
504 // which are now marked as not matching.
505 if (__n_might_match + __n_does_match > 1)
508 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
510 if (*__st == __does_match && __ky->size() != __indx+1)
512 *__st = __doesnt_match;
519 // We've exited the loop because we hit eof and/or we have no more "might matches".
521 __err |= ios_base::eofbit;
522 // Return the first matching result
523 for (__st = __status; __kb != __ke; ++__kb, ++__st)
524 if (*__st == __does_match)
527 __err |= ios_base::failbit;
531 struct __num_get_base
533 static const int __num_get_buf_sz = 40;
535 static int __get_base(ios_base&);
536 static const char __src[33];
539 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
540 ios_base::iostate& __err);
542 template <class _CharT>
544 : protected __num_get_base
546 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
547 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
548 _CharT& __thousands_sep);
549 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
550 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
551 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
552 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
553 char* __a, char*& __a_end,
554 _CharT __decimal_point, _CharT __thousands_sep,
555 const string& __grouping, unsigned* __g,
556 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
559 template <class _CharT>
561 __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
563 locale __loc = __iob.getloc();
564 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
565 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
566 __thousands_sep = __np.thousands_sep();
567 return __np.grouping();
570 template <class _CharT>
572 __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
573 _CharT& __thousands_sep)
575 locale __loc = __iob.getloc();
576 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
577 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
578 __decimal_point = __np.decimal_point();
579 __thousands_sep = __np.thousands_sep();
580 return __np.grouping();
583 template <class _CharT>
585 __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
586 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
587 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
589 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
591 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
595 if (__grouping.size() != 0 && __ct == __thousands_sep)
597 if (__g_end-__g < __num_get_buf_sz)
604 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
617 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
620 *__a_end++ = __src[__f];
625 *__a_end++ = __src[__f];
630 template <class _CharT>
632 __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
633 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
634 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
636 if (__ct == __decimal_point)
642 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
646 if (__ct == __thousands_sep && __grouping.size() != 0)
650 if (__g_end-__g < __num_get_buf_sz)
657 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
660 char __x = __src[__f];
661 if (__x == '-' || __x == '+')
663 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
670 if (__x == 'x' || __x == 'X')
672 else if ((__x & 0x5F) == __exp)
678 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
689 _LIBCPP_EXTERN_TEMPLATE(struct __num_get<char>)
690 _LIBCPP_EXTERN_TEMPLATE(struct __num_get<wchar_t>)
692 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
693 class _LIBCPP_TYPE_VIS num_get
694 : public locale::facet,
695 private __num_get<_CharT>
698 typedef _CharT char_type;
699 typedef _InputIterator iter_type;
701 _LIBCPP_ALWAYS_INLINE
702 explicit num_get(size_t __refs = 0)
703 : locale::facet(__refs) {}
705 _LIBCPP_ALWAYS_INLINE
706 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
707 ios_base::iostate& __err, bool& __v) const
709 return do_get(__b, __e, __iob, __err, __v);
712 _LIBCPP_ALWAYS_INLINE
713 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
714 ios_base::iostate& __err, long& __v) const
716 return do_get(__b, __e, __iob, __err, __v);
719 _LIBCPP_ALWAYS_INLINE
720 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
721 ios_base::iostate& __err, long long& __v) const
723 return do_get(__b, __e, __iob, __err, __v);
726 _LIBCPP_ALWAYS_INLINE
727 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
728 ios_base::iostate& __err, unsigned short& __v) const
730 return do_get(__b, __e, __iob, __err, __v);
733 _LIBCPP_ALWAYS_INLINE
734 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
735 ios_base::iostate& __err, unsigned int& __v) const
737 return do_get(__b, __e, __iob, __err, __v);
740 _LIBCPP_ALWAYS_INLINE
741 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
742 ios_base::iostate& __err, unsigned long& __v) const
744 return do_get(__b, __e, __iob, __err, __v);
747 _LIBCPP_ALWAYS_INLINE
748 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
749 ios_base::iostate& __err, unsigned long long& __v) const
751 return do_get(__b, __e, __iob, __err, __v);
754 _LIBCPP_ALWAYS_INLINE
755 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
756 ios_base::iostate& __err, float& __v) const
758 return do_get(__b, __e, __iob, __err, __v);
761 _LIBCPP_ALWAYS_INLINE
762 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
763 ios_base::iostate& __err, double& __v) const
765 return do_get(__b, __e, __iob, __err, __v);
768 _LIBCPP_ALWAYS_INLINE
769 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
770 ios_base::iostate& __err, long double& __v) const
772 return do_get(__b, __e, __iob, __err, __v);
775 _LIBCPP_ALWAYS_INLINE
776 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
777 ios_base::iostate& __err, void*& __v) const
779 return do_get(__b, __e, __iob, __err, __v);
782 static locale::id id;
785 _LIBCPP_ALWAYS_INLINE
788 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
789 ios_base::iostate& __err, bool& __v) const;
790 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
791 ios_base::iostate& __err, long& __v) const;
792 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
793 ios_base::iostate& __err, long long& __v) const;
794 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
795 ios_base::iostate& __err, unsigned short& __v) const;
796 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
797 ios_base::iostate& __err, unsigned int& __v) const;
798 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
799 ios_base::iostate& __err, unsigned long& __v) const;
800 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
801 ios_base::iostate& __err, unsigned long long& __v) const;
802 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
803 ios_base::iostate& __err, float& __v) const;
804 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
805 ios_base::iostate& __err, double& __v) const;
806 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
807 ios_base::iostate& __err, long double& __v) const;
808 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
809 ios_base::iostate& __err, void*& __v) const;
812 template <class _CharT, class _InputIterator>
814 num_get<_CharT, _InputIterator>::id;
818 __num_get_signed_integral(const char* __a, const char* __a_end,
819 ios_base::iostate& __err, int __base)
823 typename remove_reference<decltype(errno)>::type __save_errno = errno;
826 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
827 typename remove_reference<decltype(errno)>::type __current_errno = errno;
828 if (__current_errno == 0)
829 errno = __save_errno;
832 __err = ios_base::failbit;
835 else if (__current_errno == ERANGE ||
836 __ll < numeric_limits<_Tp>::min() ||
837 numeric_limits<_Tp>::max() < __ll)
839 __err = ios_base::failbit;
841 return numeric_limits<_Tp>::max();
843 return numeric_limits<_Tp>::min();
845 return static_cast<_Tp>(__ll);
847 __err = ios_base::failbit;
853 __num_get_unsigned_integral(const char* __a, const char* __a_end,
854 ios_base::iostate& __err, int __base)
860 __err = ios_base::failbit;
863 typename remove_reference<decltype(errno)>::type __save_errno = errno;
866 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
867 typename remove_reference<decltype(errno)>::type __current_errno = errno;
868 if (__current_errno == 0)
869 errno = __save_errno;
872 __err = ios_base::failbit;
875 else if (__current_errno == ERANGE ||
876 numeric_limits<_Tp>::max() < __ll)
878 __err = ios_base::failbit;
879 return numeric_limits<_Tp>::max();
881 return static_cast<_Tp>(__ll);
883 __err = ios_base::failbit;
889 __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
893 typename remove_reference<decltype(errno)>::type __save_errno = errno;
896 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
897 typename remove_reference<decltype(errno)>::type __current_errno = errno;
898 if (__current_errno == 0)
899 errno = __save_errno;
902 __err = ios_base::failbit;
905 else if (__current_errno == ERANGE)
906 __err = ios_base::failbit;
907 return static_cast<_Tp>(__ld);
909 __err = ios_base::failbit;
913 template <class _CharT, class _InputIterator>
915 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
917 ios_base::iostate& __err,
920 if ((__iob.flags() & ios_base::boolalpha) == 0)
923 __b = do_get(__b, __e, __iob, __err, __lv);
934 __err = ios_base::failbit;
939 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
940 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
941 typedef typename numpunct<_CharT>::string_type string_type;
942 const string_type __names[2] = {__np.truename(), __np.falsename()};
943 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
945 __v = __i == __names;
949 template <class _CharT, class _InputIterator>
951 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
953 ios_base::iostate& __err,
957 int __base = this->__get_base(__iob);
959 char_type __atoms[26];
960 char_type __thousands_sep;
961 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
963 __buf.resize(__buf.capacity());
964 char* __a = &__buf[0];
966 unsigned __g[__num_get_base::__num_get_buf_sz];
967 unsigned* __g_end = __g;
969 for (; __b != __e; ++__b)
971 if (__a_end - __a == __buf.size())
973 size_t __tmp = __buf.size();
974 __buf.resize(2*__buf.size());
975 __buf.resize(__buf.capacity());
977 __a_end = __a + __tmp;
979 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
980 __thousands_sep, __grouping, __g, __g_end,
984 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
987 __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base);
988 // Digit grouping checked
989 __check_grouping(__grouping, __g, __g_end, __err);
992 __err |= ios_base::eofbit;
996 template <class _CharT, class _InputIterator>
998 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1000 ios_base::iostate& __err,
1001 long long& __v) const
1004 int __base = this->__get_base(__iob);
1006 char_type __atoms[26];
1007 char_type __thousands_sep;
1008 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1010 __buf.resize(__buf.capacity());
1011 char* __a = &__buf[0];
1012 char* __a_end = __a;
1013 unsigned __g[__num_get_base::__num_get_buf_sz];
1014 unsigned* __g_end = __g;
1016 for (; __b != __e; ++__b)
1018 if (__a_end - __a == __buf.size())
1020 size_t __tmp = __buf.size();
1021 __buf.resize(2*__buf.size());
1022 __buf.resize(__buf.capacity());
1024 __a_end = __a + __tmp;
1026 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1027 __thousands_sep, __grouping, __g, __g_end,
1031 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1034 __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base);
1035 // Digit grouping checked
1036 __check_grouping(__grouping, __g, __g_end, __err);
1039 __err |= ios_base::eofbit;
1043 template <class _CharT, class _InputIterator>
1045 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1047 ios_base::iostate& __err,
1048 unsigned short& __v) const
1051 int __base = this->__get_base(__iob);
1053 char_type __atoms[26];
1054 char_type __thousands_sep;
1055 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1057 __buf.resize(__buf.capacity());
1058 char* __a = &__buf[0];
1059 char* __a_end = __a;
1060 unsigned __g[__num_get_base::__num_get_buf_sz];
1061 unsigned* __g_end = __g;
1063 for (; __b != __e; ++__b)
1065 if (__a_end - __a == __buf.size())
1067 size_t __tmp = __buf.size();
1068 __buf.resize(2*__buf.size());
1069 __buf.resize(__buf.capacity());
1071 __a_end = __a + __tmp;
1073 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1074 __thousands_sep, __grouping, __g, __g_end,
1078 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1081 __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base);
1082 // Digit grouping checked
1083 __check_grouping(__grouping, __g, __g_end, __err);
1086 __err |= ios_base::eofbit;
1090 template <class _CharT, class _InputIterator>
1092 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1094 ios_base::iostate& __err,
1095 unsigned int& __v) const
1098 int __base = this->__get_base(__iob);
1100 char_type __atoms[26];
1101 char_type __thousands_sep;
1102 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1104 __buf.resize(__buf.capacity());
1105 char* __a = &__buf[0];
1106 char* __a_end = __a;
1107 unsigned __g[__num_get_base::__num_get_buf_sz];
1108 unsigned* __g_end = __g;
1110 for (; __b != __e; ++__b)
1112 if (__a_end - __a == __buf.size())
1114 size_t __tmp = __buf.size();
1115 __buf.resize(2*__buf.size());
1116 __buf.resize(__buf.capacity());
1118 __a_end = __a + __tmp;
1120 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1121 __thousands_sep, __grouping, __g, __g_end,
1125 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1128 __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base);
1129 // Digit grouping checked
1130 __check_grouping(__grouping, __g, __g_end, __err);
1133 __err |= ios_base::eofbit;
1137 template <class _CharT, class _InputIterator>
1139 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1141 ios_base::iostate& __err,
1142 unsigned long& __v) const
1145 int __base = this->__get_base(__iob);
1147 char_type __atoms[26];
1148 char_type __thousands_sep;
1149 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1151 __buf.resize(__buf.capacity());
1152 char* __a = &__buf[0];
1153 char* __a_end = __a;
1154 unsigned __g[__num_get_base::__num_get_buf_sz];
1155 unsigned* __g_end = __g;
1157 for (; __b != __e; ++__b)
1159 if (__a_end - __a == __buf.size())
1161 size_t __tmp = __buf.size();
1162 __buf.resize(2*__buf.size());
1163 __buf.resize(__buf.capacity());
1165 __a_end = __a + __tmp;
1167 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1168 __thousands_sep, __grouping, __g, __g_end,
1172 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1175 __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base);
1176 // Digit grouping checked
1177 __check_grouping(__grouping, __g, __g_end, __err);
1180 __err |= ios_base::eofbit;
1184 template <class _CharT, class _InputIterator>
1186 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1188 ios_base::iostate& __err,
1189 unsigned long long& __v) const
1192 int __base = this->__get_base(__iob);
1194 char_type __atoms[26];
1195 char_type __thousands_sep;
1196 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1198 __buf.resize(__buf.capacity());
1199 char* __a = &__buf[0];
1200 char* __a_end = __a;
1201 unsigned __g[__num_get_base::__num_get_buf_sz];
1202 unsigned* __g_end = __g;
1204 for (; __b != __e; ++__b)
1206 if (__a_end - __a == __buf.size())
1208 size_t __tmp = __buf.size();
1209 __buf.resize(2*__buf.size());
1210 __buf.resize(__buf.capacity());
1212 __a_end = __a + __tmp;
1214 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1215 __thousands_sep, __grouping, __g, __g_end,
1219 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1222 __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base);
1223 // Digit grouping checked
1224 __check_grouping(__grouping, __g, __g_end, __err);
1227 __err |= ios_base::eofbit;
1231 template <class _CharT, class _InputIterator>
1233 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1235 ios_base::iostate& __err,
1238 // Stage 1, nothing to do
1240 char_type __atoms[32];
1241 char_type __decimal_point;
1242 char_type __thousands_sep;
1243 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1247 __buf.resize(__buf.capacity());
1248 char* __a = &__buf[0];
1249 char* __a_end = __a;
1250 unsigned __g[__num_get_base::__num_get_buf_sz];
1251 unsigned* __g_end = __g;
1253 bool __in_units = true;
1255 for (; __b != __e; ++__b)
1257 if (__a_end - __a == __buf.size())
1259 size_t __tmp = __buf.size();
1260 __buf.resize(2*__buf.size());
1261 __buf.resize(__buf.capacity());
1263 __a_end = __a + __tmp;
1265 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1266 __decimal_point, __thousands_sep,
1267 __grouping, __g, __g_end,
1271 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1274 __v = __num_get_float<float>(__a, __a_end, __err);
1275 // Digit grouping checked
1276 __check_grouping(__grouping, __g, __g_end, __err);
1279 __err |= ios_base::eofbit;
1283 template <class _CharT, class _InputIterator>
1285 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1287 ios_base::iostate& __err,
1290 // Stage 1, nothing to do
1292 char_type __atoms[32];
1293 char_type __decimal_point;
1294 char_type __thousands_sep;
1295 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1299 __buf.resize(__buf.capacity());
1300 char* __a = &__buf[0];
1301 char* __a_end = __a;
1302 unsigned __g[__num_get_base::__num_get_buf_sz];
1303 unsigned* __g_end = __g;
1305 bool __in_units = true;
1307 for (; __b != __e; ++__b)
1309 if (__a_end - __a == __buf.size())
1311 size_t __tmp = __buf.size();
1312 __buf.resize(2*__buf.size());
1313 __buf.resize(__buf.capacity());
1315 __a_end = __a + __tmp;
1317 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1318 __decimal_point, __thousands_sep,
1319 __grouping, __g, __g_end,
1323 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1326 __v = __num_get_float<double>(__a, __a_end, __err);
1327 // Digit grouping checked
1328 __check_grouping(__grouping, __g, __g_end, __err);
1331 __err |= ios_base::eofbit;
1335 template <class _CharT, class _InputIterator>
1337 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1339 ios_base::iostate& __err,
1340 long double& __v) const
1342 // Stage 1, nothing to do
1344 char_type __atoms[32];
1345 char_type __decimal_point;
1346 char_type __thousands_sep;
1347 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1351 __buf.resize(__buf.capacity());
1352 char* __a = &__buf[0];
1353 char* __a_end = __a;
1354 unsigned __g[__num_get_base::__num_get_buf_sz];
1355 unsigned* __g_end = __g;
1357 bool __in_units = true;
1359 for (; __b != __e; ++__b)
1361 if (__a_end - __a == __buf.size())
1363 size_t __tmp = __buf.size();
1364 __buf.resize(2*__buf.size());
1365 __buf.resize(__buf.capacity());
1367 __a_end = __a + __tmp;
1369 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1370 __decimal_point, __thousands_sep,
1371 __grouping, __g, __g_end,
1375 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1378 __v = __num_get_float<long double>(__a, __a_end, __err);
1379 // Digit grouping checked
1380 __check_grouping(__grouping, __g, __g_end, __err);
1383 __err |= ios_base::eofbit;
1387 template <class _CharT, class _InputIterator>
1389 num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1391 ios_base::iostate& __err,
1397 char_type __atoms[26];
1398 char_type __thousands_sep = 0;
1400 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1401 __num_get_base::__src + 26, __atoms);
1403 __buf.resize(__buf.capacity());
1404 char* __a = &__buf[0];
1405 char* __a_end = __a;
1406 unsigned __g[__num_get_base::__num_get_buf_sz];
1407 unsigned* __g_end = __g;
1409 for (; __b != __e; ++__b)
1411 if (__a_end - __a == __buf.size())
1413 size_t __tmp = __buf.size();
1414 __buf.resize(2*__buf.size());
1415 __buf.resize(__buf.capacity());
1417 __a_end = __a + __tmp;
1419 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1420 __thousands_sep, __grouping,
1421 __g, __g_end, __atoms))
1425 __a[sizeof(__a)-1] = 0;
1426 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1427 if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1429 if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1)
1431 __err = ios_base::failbit;
1434 __err |= ios_base::eofbit;
1438 _LIBCPP_EXTERN_TEMPLATE(class num_get<char>)
1439 _LIBCPP_EXTERN_TEMPLATE(class num_get<wchar_t>)
1441 struct __num_put_base
1444 static void __format_int(char* __fmt, const char* __len, bool __signd,
1445 ios_base::fmtflags __flags);
1446 static bool __format_float(char* __fmt, const char* __len,
1447 ios_base::fmtflags __flags);
1448 static char* __identify_padding(char* __nb, char* __ne,
1449 const ios_base& __iob);
1452 template <class _CharT>
1454 : protected __num_put_base
1456 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1457 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1458 const locale& __loc);
1459 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1460 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1461 const locale& __loc);
1464 template <class _CharT>
1466 __num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1467 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1468 const locale& __loc)
1470 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1471 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1472 string __grouping = __npt.grouping();
1473 if (__grouping.empty())
1475 __ct.widen(__nb, __ne, __ob);
1476 __oe = __ob + (__ne - __nb);
1482 if (*__nf == '-' || *__nf == '+')
1483 *__oe++ = __ct.widen(*__nf++);
1484 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1487 *__oe++ = __ct.widen(*__nf++);
1488 *__oe++ = __ct.widen(*__nf++);
1490 reverse(__nf, __ne);
1491 _CharT __thousands_sep = __npt.thousands_sep();
1494 for (char* __p = __nf; __p < __ne; ++__p)
1496 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1497 __dc == static_cast<unsigned>(__grouping[__dg]))
1499 *__oe++ = __thousands_sep;
1501 if (__dg < __grouping.size()-1)
1504 *__oe++ = __ct.widen(*__p);
1507 reverse(__ob + (__nf - __nb), __oe);
1512 __op = __ob + (__np - __nb);
1515 template <class _CharT>
1517 __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1518 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1519 const locale& __loc)
1521 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1522 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1523 string __grouping = __npt.grouping();
1526 if (*__nf == '-' || *__nf == '+')
1527 *__oe++ = __ct.widen(*__nf++);
1529 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1532 *__oe++ = __ct.widen(*__nf++);
1533 *__oe++ = __ct.widen(*__nf++);
1534 for (__ns = __nf; __ns < __ne; ++__ns)
1535 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1540 for (__ns = __nf; __ns < __ne; ++__ns)
1541 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1544 if (__grouping.empty())
1546 __ct.widen(__nf, __ns, __oe);
1547 __oe += __ns - __nf;
1551 reverse(__nf, __ns);
1552 _CharT __thousands_sep = __npt.thousands_sep();
1555 for (char* __p = __nf; __p < __ns; ++__p)
1557 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1559 *__oe++ = __thousands_sep;
1561 if (__dg < __grouping.size()-1)
1564 *__oe++ = __ct.widen(*__p);
1567 reverse(__ob + (__nf - __nb), __oe);
1569 for (__nf = __ns; __nf < __ne; ++__nf)
1573 *__oe++ = __npt.decimal_point();
1578 *__oe++ = __ct.widen(*__nf);
1580 __ct.widen(__nf, __ne, __oe);
1581 __oe += __ne - __nf;
1585 __op = __ob + (__np - __nb);
1588 _LIBCPP_EXTERN_TEMPLATE(struct __num_put<char>)
1589 _LIBCPP_EXTERN_TEMPLATE(struct __num_put<wchar_t>)
1591 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1592 class _LIBCPP_TYPE_VIS num_put
1593 : public locale::facet,
1594 private __num_put<_CharT>
1597 typedef _CharT char_type;
1598 typedef _OutputIterator iter_type;
1600 _LIBCPP_ALWAYS_INLINE
1601 explicit num_put(size_t __refs = 0)
1602 : locale::facet(__refs) {}
1604 _LIBCPP_ALWAYS_INLINE
1605 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1608 return do_put(__s, __iob, __fl, __v);
1611 _LIBCPP_ALWAYS_INLINE
1612 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1615 return do_put(__s, __iob, __fl, __v);
1618 _LIBCPP_ALWAYS_INLINE
1619 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1620 long long __v) const
1622 return do_put(__s, __iob, __fl, __v);
1625 _LIBCPP_ALWAYS_INLINE
1626 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1627 unsigned long __v) const
1629 return do_put(__s, __iob, __fl, __v);
1632 _LIBCPP_ALWAYS_INLINE
1633 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1634 unsigned long long __v) const
1636 return do_put(__s, __iob, __fl, __v);
1639 _LIBCPP_ALWAYS_INLINE
1640 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1643 return do_put(__s, __iob, __fl, __v);
1646 _LIBCPP_ALWAYS_INLINE
1647 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1648 long double __v) const
1650 return do_put(__s, __iob, __fl, __v);
1653 _LIBCPP_ALWAYS_INLINE
1654 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1655 const void* __v) const
1657 return do_put(__s, __iob, __fl, __v);
1660 static locale::id id;
1663 _LIBCPP_ALWAYS_INLINE
1666 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1668 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1670 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1671 long long __v) const;
1672 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1673 unsigned long) const;
1674 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1675 unsigned long long) const;
1676 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1678 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1679 long double __v) const;
1680 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1681 const void* __v) const;
1684 template <class _CharT, class _OutputIterator>
1686 num_put<_CharT, _OutputIterator>::id;
1688 template <class _CharT, class _OutputIterator>
1691 __pad_and_output(_OutputIterator __s,
1692 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1693 ios_base& __iob, _CharT __fl)
1695 streamsize __sz = __oe - __ob;
1696 streamsize __ns = __iob.width();
1701 for (;__ob < __op; ++__ob, ++__s)
1703 for (; __ns; --__ns, ++__s)
1705 for (; __ob < __oe; ++__ob, ++__s)
1711 #if !defined(__APPLE__) || \
1712 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1713 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1715 template <class _CharT, class _Traits>
1717 ostreambuf_iterator<_CharT, _Traits>
1718 __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1719 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1720 ios_base& __iob, _CharT __fl)
1722 if (__s.__sbuf_ == nullptr)
1724 streamsize __sz = __oe - __ob;
1725 streamsize __ns = __iob.width();
1730 streamsize __np = __op - __ob;
1733 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1735 __s.__sbuf_ = nullptr;
1741 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1742 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1744 __s.__sbuf_ = nullptr;
1751 if (__s.__sbuf_->sputn(__op, __np) != __np)
1753 __s.__sbuf_ = nullptr;
1763 template <class _CharT, class _OutputIterator>
1765 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1766 char_type __fl, bool __v) const
1768 if ((__iob.flags() & ios_base::boolalpha) == 0)
1769 return do_put(__s, __iob, __fl, (unsigned long)__v);
1770 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1771 typedef typename numpunct<char_type>::string_type string_type;
1772 string_type __nm = __v ? __np.truename() : __np.falsename();
1773 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1778 template <class _CharT, class _OutputIterator>
1780 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1781 char_type __fl, long __v) const
1783 // Stage 1 - Get number in narrow char
1784 char __fmt[6] = {'%', 0};
1785 const char* __len = "l";
1786 this->__format_int(__fmt+1, __len, true, __iob.flags());
1787 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1788 + ((numeric_limits<long>::digits % 3) != 0)
1791 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1792 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1794 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1796 char* __ne = __nar + __nc;
1797 char* __np = this->__identify_padding(__nar, __ne, __iob);
1798 // Stage 2 - Widen __nar while adding thousands separators
1799 char_type __o[2*(__nbuf-1) - 1];
1800 char_type* __op; // pad here
1801 char_type* __oe; // end of output
1802 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1803 // [__o, __oe) contains thousands_sep'd wide number
1805 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1808 template <class _CharT, class _OutputIterator>
1810 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1811 char_type __fl, long long __v) const
1813 // Stage 1 - Get number in narrow char
1814 char __fmt[8] = {'%', 0};
1815 const char* __len = "ll";
1816 this->__format_int(__fmt+1, __len, true, __iob.flags());
1817 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1818 + ((numeric_limits<long long>::digits % 3) != 0)
1821 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1822 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1824 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1826 char* __ne = __nar + __nc;
1827 char* __np = this->__identify_padding(__nar, __ne, __iob);
1828 // Stage 2 - Widen __nar while adding thousands separators
1829 char_type __o[2*(__nbuf-1) - 1];
1830 char_type* __op; // pad here
1831 char_type* __oe; // end of output
1832 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1833 // [__o, __oe) contains thousands_sep'd wide number
1835 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1838 template <class _CharT, class _OutputIterator>
1840 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1841 char_type __fl, unsigned long __v) const
1843 // Stage 1 - Get number in narrow char
1844 char __fmt[6] = {'%', 0};
1845 const char* __len = "l";
1846 this->__format_int(__fmt+1, __len, false, __iob.flags());
1847 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1848 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1851 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1852 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1854 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1856 char* __ne = __nar + __nc;
1857 char* __np = this->__identify_padding(__nar, __ne, __iob);
1858 // Stage 2 - Widen __nar while adding thousands separators
1859 char_type __o[2*(__nbuf-1) - 1];
1860 char_type* __op; // pad here
1861 char_type* __oe; // end of output
1862 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1863 // [__o, __oe) contains thousands_sep'd wide number
1865 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1868 template <class _CharT, class _OutputIterator>
1870 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1871 char_type __fl, unsigned long long __v) const
1873 // Stage 1 - Get number in narrow char
1874 char __fmt[8] = {'%', 0};
1875 const char* __len = "ll";
1876 this->__format_int(__fmt+1, __len, false, __iob.flags());
1877 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1878 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1881 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1882 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1884 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1886 char* __ne = __nar + __nc;
1887 char* __np = this->__identify_padding(__nar, __ne, __iob);
1888 // Stage 2 - Widen __nar while adding thousands separators
1889 char_type __o[2*(__nbuf-1) - 1];
1890 char_type* __op; // pad here
1891 char_type* __oe; // end of output
1892 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1893 // [__o, __oe) contains thousands_sep'd wide number
1895 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1898 template <class _CharT, class _OutputIterator>
1900 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1901 char_type __fl, double __v) const
1903 // Stage 1 - Get number in narrow char
1904 char __fmt[8] = {'%', 0};
1905 const char* __len = "";
1906 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1907 const unsigned __nbuf = 30;
1911 if (__specify_precision)
1912 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1913 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1914 (int)__iob.precision(), __v);
1916 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1917 (int)__iob.precision(), __v);
1920 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1921 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1923 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1925 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1926 if (__nc > static_cast<int>(__nbuf-1))
1928 if (__specify_precision)
1929 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1930 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1932 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1933 (int)__iob.precision(), __v);
1936 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1937 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1939 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
1942 __throw_bad_alloc();
1945 char* __ne = __nb + __nc;
1946 char* __np = this->__identify_padding(__nb, __ne, __iob);
1947 // Stage 2 - Widen __nar while adding thousands separators
1948 char_type __o[2*(__nbuf-1) - 1];
1949 char_type* __ob = __o;
1950 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1953 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1955 __throw_bad_alloc();
1958 char_type* __op; // pad here
1959 char_type* __oe; // end of output
1960 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1961 // [__o, __oe) contains thousands_sep'd wide number
1963 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1967 template <class _CharT, class _OutputIterator>
1969 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1970 char_type __fl, long double __v) const
1972 // Stage 1 - Get number in narrow char
1973 char __fmt[8] = {'%', 0};
1974 const char* __len = "L";
1975 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1976 const unsigned __nbuf = 30;
1980 if (__specify_precision)
1981 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1982 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1983 (int)__iob.precision(), __v);
1985 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1986 (int)__iob.precision(), __v);
1989 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1990 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1992 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1994 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1995 if (__nc > static_cast<int>(__nbuf-1))
1997 if (__specify_precision)
1998 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1999 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
2001 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
2002 (int)__iob.precision(), __v);
2005 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
2006 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
2008 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
2011 __throw_bad_alloc();
2014 char* __ne = __nb + __nc;
2015 char* __np = this->__identify_padding(__nb, __ne, __iob);
2016 // Stage 2 - Widen __nar while adding thousands separators
2017 char_type __o[2*(__nbuf-1) - 1];
2018 char_type* __ob = __o;
2019 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
2022 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
2024 __throw_bad_alloc();
2027 char_type* __op; // pad here
2028 char_type* __oe; // end of output
2029 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
2030 // [__o, __oe) contains thousands_sep'd wide number
2032 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
2036 template <class _CharT, class _OutputIterator>
2038 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
2039 char_type __fl, const void* __v) const
2041 // Stage 1 - Get pointer in narrow char
2042 char __fmt[6] = "%p";
2043 const unsigned __nbuf = 20;
2045 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
2046 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
2048 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
2050 char* __ne = __nar + __nc;
2051 char* __np = this->__identify_padding(__nar, __ne, __iob);
2052 // Stage 2 - Widen __nar
2053 char_type __o[2*(__nbuf-1) - 1];
2054 char_type* __op; // pad here
2055 char_type* __oe; // end of output
2056 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2057 __ct.widen(__nar, __ne, __o);
2058 __oe = __o + (__ne - __nar);
2062 __op = __o + (__np - __nar);
2063 // [__o, __oe) contains wide number
2065 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
2068 _LIBCPP_EXTERN_TEMPLATE(class num_put<char>)
2069 _LIBCPP_EXTERN_TEMPLATE(class num_put<wchar_t>)
2071 template <class _CharT, class _InputIterator>
2074 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
2075 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
2077 // Precondition: __n >= 1
2080 __err |= ios_base::eofbit | ios_base::failbit;
2085 if (!__ct.is(ctype_base::digit, __c))
2087 __err |= ios_base::failbit;
2090 int __r = __ct.narrow(__c, 0) - '0';
2091 for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
2095 if (!__ct.is(ctype_base::digit, __c))
2097 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
2100 __err |= ios_base::eofbit;
2104 class _LIBCPP_TYPE_VIS time_base
2107 enum dateorder {no_order, dmy, mdy, ymd, ydm};
2110 template <class _CharT>
2111 class __time_get_c_storage // purposefully not decorated
2114 typedef basic_string<_CharT> string_type;
2116 virtual const string_type* __weeks() const;
2117 virtual const string_type* __months() const;
2118 virtual const string_type* __am_pm() const;
2119 virtual const string_type& __c() const;
2120 virtual const string_type& __r() const;
2121 virtual const string_type& __x() const;
2122 virtual const string_type& __X() const;
2125 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2126 class _LIBCPP_TYPE_VIS time_get
2127 : public locale::facet,
2129 private __time_get_c_storage<_CharT>
2132 typedef _CharT char_type;
2133 typedef _InputIterator iter_type;
2134 typedef time_base::dateorder dateorder;
2135 typedef basic_string<char_type> string_type;
2137 _LIBCPP_ALWAYS_INLINE
2138 explicit time_get(size_t __refs = 0)
2139 : locale::facet(__refs) {}
2141 _LIBCPP_ALWAYS_INLINE
2142 dateorder date_order() const
2144 return this->do_date_order();
2147 _LIBCPP_ALWAYS_INLINE
2148 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
2149 ios_base::iostate& __err, tm* __tm) const
2151 return do_get_time(__b, __e, __iob, __err, __tm);
2154 _LIBCPP_ALWAYS_INLINE
2155 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
2156 ios_base::iostate& __err, tm* __tm) const
2158 return do_get_date(__b, __e, __iob, __err, __tm);
2161 _LIBCPP_ALWAYS_INLINE
2162 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2163 ios_base::iostate& __err, tm* __tm) const
2165 return do_get_weekday(__b, __e, __iob, __err, __tm);
2168 _LIBCPP_ALWAYS_INLINE
2169 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2170 ios_base::iostate& __err, tm* __tm) const
2172 return do_get_monthname(__b, __e, __iob, __err, __tm);
2175 _LIBCPP_ALWAYS_INLINE
2176 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
2177 ios_base::iostate& __err, tm* __tm) const
2179 return do_get_year(__b, __e, __iob, __err, __tm);
2182 _LIBCPP_ALWAYS_INLINE
2183 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2184 ios_base::iostate& __err, tm *__tm,
2185 char __fmt, char __mod = 0) const
2187 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
2190 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2191 ios_base::iostate& __err, tm* __tm,
2192 const char_type* __fmtb, const char_type* __fmte) const;
2194 static locale::id id;
2197 _LIBCPP_ALWAYS_INLINE
2200 virtual dateorder do_date_order() const;
2201 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
2202 ios_base::iostate& __err, tm* __tm) const;
2203 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
2204 ios_base::iostate& __err, tm* __tm) const;
2205 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2206 ios_base::iostate& __err, tm* __tm) const;
2207 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2208 ios_base::iostate& __err, tm* __tm) const;
2209 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
2210 ios_base::iostate& __err, tm* __tm) const;
2211 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
2212 ios_base::iostate& __err, tm* __tm,
2213 char __fmt, char __mod) const;
2215 void __get_white_space(iter_type& __b, iter_type __e,
2216 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
2217 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
2218 const ctype<char_type>& __ct) const;
2220 void __get_weekdayname(int& __m,
2221 iter_type& __b, iter_type __e,
2222 ios_base::iostate& __err,
2223 const ctype<char_type>& __ct) const;
2224 void __get_monthname(int& __m,
2225 iter_type& __b, iter_type __e,
2226 ios_base::iostate& __err,
2227 const ctype<char_type>& __ct) const;
2228 void __get_day(int& __d,
2229 iter_type& __b, iter_type __e,
2230 ios_base::iostate& __err,
2231 const ctype<char_type>& __ct) const;
2232 void __get_month(int& __m,
2233 iter_type& __b, iter_type __e,
2234 ios_base::iostate& __err,
2235 const ctype<char_type>& __ct) const;
2236 void __get_year(int& __y,
2237 iter_type& __b, iter_type __e,
2238 ios_base::iostate& __err,
2239 const ctype<char_type>& __ct) const;
2240 void __get_year4(int& __y,
2241 iter_type& __b, iter_type __e,
2242 ios_base::iostate& __err,
2243 const ctype<char_type>& __ct) const;
2244 void __get_hour(int& __d,
2245 iter_type& __b, iter_type __e,
2246 ios_base::iostate& __err,
2247 const ctype<char_type>& __ct) const;
2248 void __get_12_hour(int& __h,
2249 iter_type& __b, iter_type __e,
2250 ios_base::iostate& __err,
2251 const ctype<char_type>& __ct) const;
2252 void __get_am_pm(int& __h,
2253 iter_type& __b, iter_type __e,
2254 ios_base::iostate& __err,
2255 const ctype<char_type>& __ct) const;
2256 void __get_minute(int& __m,
2257 iter_type& __b, iter_type __e,
2258 ios_base::iostate& __err,
2259 const ctype<char_type>& __ct) const;
2260 void __get_second(int& __s,
2261 iter_type& __b, iter_type __e,
2262 ios_base::iostate& __err,
2263 const ctype<char_type>& __ct) const;
2264 void __get_weekday(int& __w,
2265 iter_type& __b, iter_type __e,
2266 ios_base::iostate& __err,
2267 const ctype<char_type>& __ct) const;
2268 void __get_day_year_num(int& __w,
2269 iter_type& __b, iter_type __e,
2270 ios_base::iostate& __err,
2271 const ctype<char_type>& __ct) const;
2274 template <class _CharT, class _InputIterator>
2276 time_get<_CharT, _InputIterator>::id;
2278 // time_get primatives
2280 template <class _CharT, class _InputIterator>
2282 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2283 iter_type& __b, iter_type __e,
2284 ios_base::iostate& __err,
2285 const ctype<char_type>& __ct) const
2287 // Note: ignoring case comes from the POSIX strptime spec
2288 const string_type* __wk = this->__weeks();
2289 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
2294 template <class _CharT, class _InputIterator>
2296 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2297 iter_type& __b, iter_type __e,
2298 ios_base::iostate& __err,
2299 const ctype<char_type>& __ct) const
2301 // Note: ignoring case comes from the POSIX strptime spec
2302 const string_type* __month = this->__months();
2303 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
2308 template <class _CharT, class _InputIterator>
2310 time_get<_CharT, _InputIterator>::__get_day(int& __d,
2311 iter_type& __b, iter_type __e,
2312 ios_base::iostate& __err,
2313 const ctype<char_type>& __ct) const
2315 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2316 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
2319 __err |= ios_base::failbit;
2322 template <class _CharT, class _InputIterator>
2324 time_get<_CharT, _InputIterator>::__get_month(int& __m,
2325 iter_type& __b, iter_type __e,
2326 ios_base::iostate& __err,
2327 const ctype<char_type>& __ct) const
2329 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
2330 if (!(__err & ios_base::failbit) && __t <= 11)
2333 __err |= ios_base::failbit;
2336 template <class _CharT, class _InputIterator>
2338 time_get<_CharT, _InputIterator>::__get_year(int& __y,
2339 iter_type& __b, iter_type __e,
2340 ios_base::iostate& __err,
2341 const ctype<char_type>& __ct) const
2343 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2344 if (!(__err & ios_base::failbit))
2348 else if (69 <= __t && __t <= 99)
2354 template <class _CharT, class _InputIterator>
2356 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2357 iter_type& __b, iter_type __e,
2358 ios_base::iostate& __err,
2359 const ctype<char_type>& __ct) const
2361 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2362 if (!(__err & ios_base::failbit))
2366 template <class _CharT, class _InputIterator>
2368 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2369 iter_type& __b, iter_type __e,
2370 ios_base::iostate& __err,
2371 const ctype<char_type>& __ct) const
2373 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2374 if (!(__err & ios_base::failbit) && __t <= 23)
2377 __err |= ios_base::failbit;
2380 template <class _CharT, class _InputIterator>
2382 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2383 iter_type& __b, iter_type __e,
2384 ios_base::iostate& __err,
2385 const ctype<char_type>& __ct) const
2387 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2388 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2391 __err |= ios_base::failbit;
2394 template <class _CharT, class _InputIterator>
2396 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2397 iter_type& __b, iter_type __e,
2398 ios_base::iostate& __err,
2399 const ctype<char_type>& __ct) const
2401 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2402 if (!(__err & ios_base::failbit) && __t <= 59)
2405 __err |= ios_base::failbit;
2408 template <class _CharT, class _InputIterator>
2410 time_get<_CharT, _InputIterator>::__get_second(int& __s,
2411 iter_type& __b, iter_type __e,
2412 ios_base::iostate& __err,
2413 const ctype<char_type>& __ct) const
2415 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2416 if (!(__err & ios_base::failbit) && __t <= 60)
2419 __err |= ios_base::failbit;
2422 template <class _CharT, class _InputIterator>
2424 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2425 iter_type& __b, iter_type __e,
2426 ios_base::iostate& __err,
2427 const ctype<char_type>& __ct) const
2429 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2430 if (!(__err & ios_base::failbit) && __t <= 6)
2433 __err |= ios_base::failbit;
2436 template <class _CharT, class _InputIterator>
2438 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2439 iter_type& __b, iter_type __e,
2440 ios_base::iostate& __err,
2441 const ctype<char_type>& __ct) const
2443 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2444 if (!(__err & ios_base::failbit) && __t <= 365)
2447 __err |= ios_base::failbit;
2450 template <class _CharT, class _InputIterator>
2452 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2453 ios_base::iostate& __err,
2454 const ctype<char_type>& __ct) const
2456 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2459 __err |= ios_base::eofbit;
2462 template <class _CharT, class _InputIterator>
2464 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2465 iter_type& __b, iter_type __e,
2466 ios_base::iostate& __err,
2467 const ctype<char_type>& __ct) const
2469 const string_type* __ap = this->__am_pm();
2470 if (__ap[0].size() + __ap[1].size() == 0)
2472 __err |= ios_base::failbit;
2475 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2476 if (__i == 0 && __h == 12)
2478 else if (__i == 1 && __h < 12)
2482 template <class _CharT, class _InputIterator>
2484 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2485 ios_base::iostate& __err,
2486 const ctype<char_type>& __ct) const
2490 __err |= ios_base::eofbit | ios_base::failbit;
2493 if (__ct.narrow(*__b, 0) != '%')
2494 __err |= ios_base::failbit;
2495 else if(++__b == __e)
2496 __err |= ios_base::eofbit;
2499 // time_get end primatives
2501 template <class _CharT, class _InputIterator>
2503 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2505 ios_base::iostate& __err, tm* __tm,
2506 const char_type* __fmtb, const char_type* __fmte) const
2508 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2509 __err = ios_base::goodbit;
2510 while (__fmtb != __fmte && __err == ios_base::goodbit)
2514 __err = ios_base::failbit;
2517 if (__ct.narrow(*__fmtb, 0) == '%')
2519 if (++__fmtb == __fmte)
2521 __err = ios_base::failbit;
2524 char __cmd = __ct.narrow(*__fmtb, 0);
2526 if (__cmd == 'E' || __cmd == '0')
2528 if (++__fmtb == __fmte)
2530 __err = ios_base::failbit;
2534 __cmd = __ct.narrow(*__fmtb, 0);
2536 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2539 else if (__ct.is(ctype_base::space, *__fmtb))
2541 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2543 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2546 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2552 __err = ios_base::failbit;
2555 __err |= ios_base::eofbit;
2559 template <class _CharT, class _InputIterator>
2560 typename time_get<_CharT, _InputIterator>::dateorder
2561 time_get<_CharT, _InputIterator>::do_date_order() const
2566 template <class _CharT, class _InputIterator>
2568 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2570 ios_base::iostate& __err,
2573 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2574 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2577 template <class _CharT, class _InputIterator>
2579 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2581 ios_base::iostate& __err,
2584 const string_type& __fmt = this->__x();
2585 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2588 template <class _CharT, class _InputIterator>
2590 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2592 ios_base::iostate& __err,
2595 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2596 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2600 template <class _CharT, class _InputIterator>
2602 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2604 ios_base::iostate& __err,
2607 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2608 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2612 template <class _CharT, class _InputIterator>
2614 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2616 ios_base::iostate& __err,
2619 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2620 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2624 template <class _CharT, class _InputIterator>
2626 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2628 ios_base::iostate& __err, tm* __tm,
2629 char __fmt, char) const
2631 __err = ios_base::goodbit;
2632 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2637 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2642 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2646 const string_type& __fm = this->__c();
2647 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2652 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2656 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2657 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2662 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2663 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2667 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2670 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2673 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2676 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2679 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2683 __get_white_space(__b, __e, __err, __ct);
2686 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2690 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2691 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2696 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2697 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2701 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2705 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2706 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2710 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2713 return do_get_date(__b, __e, __iob, __err, __tm);
2716 const string_type& __fm = this->__X();
2717 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2721 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2724 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2727 __get_percent(__b, __e, __err, __ct);
2730 __err |= ios_base::failbit;
2735 _LIBCPP_EXTERN_TEMPLATE(class time_get<char>)
2736 _LIBCPP_EXTERN_TEMPLATE(class time_get<wchar_t>)
2743 __time_get(const char* __nm);
2744 __time_get(const string& __nm);
2748 template <class _CharT>
2749 class __time_get_storage
2753 typedef basic_string<_CharT> string_type;
2755 string_type __weeks_[14];
2756 string_type __months_[24];
2757 string_type __am_pm_[2];
2763 explicit __time_get_storage(const char* __nm);
2764 explicit __time_get_storage(const string& __nm);
2766 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2768 time_base::dateorder __do_date_order() const;
2771 void init(const ctype<_CharT>&);
2772 string_type __analyze(char __fmt, const ctype<_CharT>&);
2775 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2776 class _LIBCPP_TYPE_VIS time_get_byname
2777 : public time_get<_CharT, _InputIterator>,
2778 private __time_get_storage<_CharT>
2781 typedef time_base::dateorder dateorder;
2782 typedef _InputIterator iter_type;
2783 typedef _CharT char_type;
2784 typedef basic_string<char_type> string_type;
2786 _LIBCPP_INLINE_VISIBILITY
2787 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2788 : time_get<_CharT, _InputIterator>(__refs),
2789 __time_get_storage<_CharT>(__nm) {}
2790 _LIBCPP_INLINE_VISIBILITY
2791 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2792 : time_get<_CharT, _InputIterator>(__refs),
2793 __time_get_storage<_CharT>(__nm) {}
2796 _LIBCPP_INLINE_VISIBILITY
2797 ~time_get_byname() {}
2799 _LIBCPP_INLINE_VISIBILITY
2800 virtual dateorder do_date_order() const {return this->__do_date_order();}
2802 _LIBCPP_INLINE_VISIBILITY
2803 virtual const string_type* __weeks() const {return this->__weeks_;}
2804 _LIBCPP_INLINE_VISIBILITY
2805 virtual const string_type* __months() const {return this->__months_;}
2806 _LIBCPP_INLINE_VISIBILITY
2807 virtual const string_type* __am_pm() const {return this->__am_pm_;}
2808 _LIBCPP_INLINE_VISIBILITY
2809 virtual const string_type& __c() const {return this->__c_;}
2810 _LIBCPP_INLINE_VISIBILITY
2811 virtual const string_type& __r() const {return this->__r_;}
2812 _LIBCPP_INLINE_VISIBILITY
2813 virtual const string_type& __x() const {return this->__x_;}
2814 _LIBCPP_INLINE_VISIBILITY
2815 virtual const string_type& __X() const {return this->__X_;}
2818 _LIBCPP_EXTERN_TEMPLATE(class time_get_byname<char>)
2819 _LIBCPP_EXTERN_TEMPLATE(class time_get_byname<wchar_t>)
2825 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2826 __time_put(const char* __nm);
2827 __time_put(const string& __nm);
2829 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2830 char __fmt, char __mod) const;
2831 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2832 char __fmt, char __mod) const;
2835 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2836 class _LIBCPP_TYPE_VIS time_put
2837 : public locale::facet,
2841 typedef _CharT char_type;
2842 typedef _OutputIterator iter_type;
2844 _LIBCPP_ALWAYS_INLINE
2845 explicit time_put(size_t __refs = 0)
2846 : locale::facet(__refs) {}
2848 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2849 const char_type* __pb, const char_type* __pe) const;
2851 _LIBCPP_ALWAYS_INLINE
2852 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2853 const tm* __tm, char __fmt, char __mod = 0) const
2855 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2858 static locale::id id;
2861 _LIBCPP_ALWAYS_INLINE
2863 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2864 char __fmt, char __mod) const;
2866 _LIBCPP_ALWAYS_INLINE
2867 explicit time_put(const char* __nm, size_t __refs)
2868 : locale::facet(__refs),
2870 _LIBCPP_ALWAYS_INLINE
2871 explicit time_put(const string& __nm, size_t __refs)
2872 : locale::facet(__refs),
2876 template <class _CharT, class _OutputIterator>
2878 time_put<_CharT, _OutputIterator>::id;
2880 template <class _CharT, class _OutputIterator>
2882 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2883 char_type __fl, const tm* __tm,
2884 const char_type* __pb,
2885 const char_type* __pe) const
2887 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2888 for (; __pb != __pe; ++__pb)
2890 if (__ct.narrow(*__pb, 0) == '%')
2898 char __fmt = __ct.narrow(*__pb, 0);
2899 if (__fmt == 'E' || __fmt == 'O')
2908 __fmt = __ct.narrow(*__pb, 0);
2910 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2918 template <class _CharT, class _OutputIterator>
2920 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2921 char_type, const tm* __tm,
2922 char __fmt, char __mod) const
2924 char_type __nar[100];
2925 char_type* __nb = __nar;
2926 char_type* __ne = __nb + 100;
2927 __do_put(__nb, __ne, __tm, __fmt, __mod);
2928 return _VSTD::copy(__nb, __ne, __s);
2931 _LIBCPP_EXTERN_TEMPLATE(class time_put<char>)
2932 _LIBCPP_EXTERN_TEMPLATE(class time_put<wchar_t>)
2934 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2935 class _LIBCPP_TYPE_VIS time_put_byname
2936 : public time_put<_CharT, _OutputIterator>
2939 _LIBCPP_ALWAYS_INLINE
2940 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2941 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2943 _LIBCPP_ALWAYS_INLINE
2944 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2945 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2948 _LIBCPP_ALWAYS_INLINE
2949 ~time_put_byname() {}
2952 _LIBCPP_EXTERN_TEMPLATE(class time_put_byname<char>)
2953 _LIBCPP_EXTERN_TEMPLATE(class time_put_byname<wchar_t>)
2957 class _LIBCPP_TYPE_VIS money_base
2960 enum part {none, space, symbol, sign, value};
2961 struct pattern {char field[4];};
2963 _LIBCPP_ALWAYS_INLINE money_base() {}
2968 template <class _CharT, bool _International = false>
2969 class _LIBCPP_TYPE_VIS moneypunct
2970 : public locale::facet,
2974 typedef _CharT char_type;
2975 typedef basic_string<char_type> string_type;
2977 _LIBCPP_ALWAYS_INLINE
2978 explicit moneypunct(size_t __refs = 0)
2979 : locale::facet(__refs) {}
2981 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2982 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2983 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2984 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2985 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2986 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2987 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2988 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2989 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2991 static locale::id id;
2992 static const bool intl = _International;
2995 _LIBCPP_ALWAYS_INLINE
2998 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2999 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
3000 virtual string do_grouping() const {return string();}
3001 virtual string_type do_curr_symbol() const {return string_type();}
3002 virtual string_type do_positive_sign() const {return string_type();}
3003 virtual string_type do_negative_sign() const {return string_type(1, '-');}
3004 virtual int do_frac_digits() const {return 0;}
3005 virtual pattern do_pos_format() const
3006 {pattern __p = {{symbol, sign, none, value}}; return __p;}
3007 virtual pattern do_neg_format() const
3008 {pattern __p = {{symbol, sign, none, value}}; return __p;}
3011 template <class _CharT, bool _International>
3013 moneypunct<_CharT, _International>::id;
3015 template <class _CharT, bool _International>
3017 moneypunct<_CharT, _International>::intl;
3019 _LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, false>)
3020 _LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, true>)
3021 _LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, false>)
3022 _LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, true>)
3024 // moneypunct_byname
3026 template <class _CharT, bool _International = false>
3027 class _LIBCPP_TYPE_VIS moneypunct_byname
3028 : public moneypunct<_CharT, _International>
3031 typedef money_base::pattern pattern;
3032 typedef _CharT char_type;
3033 typedef basic_string<char_type> string_type;
3035 _LIBCPP_ALWAYS_INLINE
3036 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
3037 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
3039 _LIBCPP_ALWAYS_INLINE
3040 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
3041 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
3044 _LIBCPP_ALWAYS_INLINE
3045 ~moneypunct_byname() {}
3047 virtual char_type do_decimal_point() const {return __decimal_point_;}
3048 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
3049 virtual string do_grouping() const {return __grouping_;}
3050 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
3051 virtual string_type do_positive_sign() const {return __positive_sign_;}
3052 virtual string_type do_negative_sign() const {return __negative_sign_;}
3053 virtual int do_frac_digits() const {return __frac_digits_;}
3054 virtual pattern do_pos_format() const {return __pos_format_;}
3055 virtual pattern do_neg_format() const {return __neg_format_;}
3058 char_type __decimal_point_;
3059 char_type __thousands_sep_;
3061 string_type __curr_symbol_;
3062 string_type __positive_sign_;
3063 string_type __negative_sign_;
3065 pattern __pos_format_;
3066 pattern __neg_format_;
3068 void init(const char*);
3071 template<> void moneypunct_byname<char, false>::init(const char*);
3072 template<> void moneypunct_byname<char, true>::init(const char*);
3073 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
3074 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
3076 _LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, false>)
3077 _LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, true>)
3078 _LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, false>)
3079 _LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, true>)
3083 template <class _CharT>
3087 typedef _CharT char_type;
3088 typedef basic_string<char_type> string_type;
3090 _LIBCPP_ALWAYS_INLINE __money_get() {}
3092 static void __gather_info(bool __intl, const locale& __loc,
3093 money_base::pattern& __pat, char_type& __dp,
3094 char_type& __ts, string& __grp,
3095 string_type& __sym, string_type& __psn,
3096 string_type& __nsn, int& __fd);
3099 template <class _CharT>
3101 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
3102 money_base::pattern& __pat, char_type& __dp,
3103 char_type& __ts, string& __grp,
3104 string_type& __sym, string_type& __psn,
3105 string_type& __nsn, int& __fd)
3109 const moneypunct<char_type, true>& __mp =
3110 use_facet<moneypunct<char_type, true> >(__loc);
3111 __pat = __mp.neg_format();
3112 __nsn = __mp.negative_sign();
3113 __psn = __mp.positive_sign();
3114 __dp = __mp.decimal_point();
3115 __ts = __mp.thousands_sep();
3116 __grp = __mp.grouping();
3117 __sym = __mp.curr_symbol();
3118 __fd = __mp.frac_digits();
3122 const moneypunct<char_type, false>& __mp =
3123 use_facet<moneypunct<char_type, false> >(__loc);
3124 __pat = __mp.neg_format();
3125 __nsn = __mp.negative_sign();
3126 __psn = __mp.positive_sign();
3127 __dp = __mp.decimal_point();
3128 __ts = __mp.thousands_sep();
3129 __grp = __mp.grouping();
3130 __sym = __mp.curr_symbol();
3131 __fd = __mp.frac_digits();
3135 _LIBCPP_EXTERN_TEMPLATE(class __money_get<char>)
3136 _LIBCPP_EXTERN_TEMPLATE(class __money_get<wchar_t>)
3138 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
3139 class _LIBCPP_TYPE_VIS money_get
3140 : public locale::facet,
3141 private __money_get<_CharT>
3144 typedef _CharT char_type;
3145 typedef _InputIterator iter_type;
3146 typedef basic_string<char_type> string_type;
3148 _LIBCPP_ALWAYS_INLINE
3149 explicit money_get(size_t __refs = 0)
3150 : locale::facet(__refs) {}
3152 _LIBCPP_ALWAYS_INLINE
3153 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
3154 ios_base::iostate& __err, long double& __v) const
3156 return do_get(__b, __e, __intl, __iob, __err, __v);
3159 _LIBCPP_ALWAYS_INLINE
3160 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
3161 ios_base::iostate& __err, string_type& __v) const
3163 return do_get(__b, __e, __intl, __iob, __err, __v);
3166 static locale::id id;
3170 _LIBCPP_ALWAYS_INLINE
3173 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3174 ios_base& __iob, ios_base::iostate& __err,
3175 long double& __v) const;
3176 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3177 ios_base& __iob, ios_base::iostate& __err,
3178 string_type& __v) const;
3181 static bool __do_get(iter_type& __b, iter_type __e,
3182 bool __intl, const locale& __loc,
3183 ios_base::fmtflags __flags, ios_base::iostate& __err,
3184 bool& __neg, const ctype<char_type>& __ct,
3185 unique_ptr<char_type, void(*)(void*)>& __wb,
3186 char_type*& __wn, char_type* __we);
3189 template <class _CharT, class _InputIterator>
3191 money_get<_CharT, _InputIterator>::id;
3193 void __do_nothing(void*);
3195 template <class _Tp>
3198 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
3200 bool __owns = __b.get_deleter() != __do_nothing;
3201 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
3202 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
3203 2 * __cur_cap : numeric_limits<size_t>::max();
3204 size_t __n_off = static_cast<size_t>(__n - __b.get());
3205 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
3207 __throw_bad_alloc();
3210 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
3211 __new_cap /= sizeof(_Tp);
3212 __n = __b.get() + __n_off;
3213 __e = __b.get() + __new_cap;
3217 template <class _CharT, class _InputIterator>
3219 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
3220 bool __intl, const locale& __loc,
3221 ios_base::fmtflags __flags,
3222 ios_base::iostate& __err,
3224 const ctype<char_type>& __ct,
3225 unique_ptr<char_type, void(*)(void*)>& __wb,
3226 char_type*& __wn, char_type* __we)
3228 const unsigned __bz = 100;
3229 unsigned __gbuf[__bz];
3230 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3231 unsigned* __gn = __gb.get();
3232 unsigned* __ge = __gn + __bz;
3233 money_base::pattern __pat;
3240 // Capture the spaces read into money_base::{space,none} so they
3241 // can be compared to initial spaces in __sym.
3242 string_type __spaces;
3244 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3245 __sym, __psn, __nsn, __fd);
3246 const string_type* __trailing_sign = 0;
3248 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3250 switch (__pat.field[__p])
3252 case money_base::space:
3255 if (__ct.is(ctype_base::space, *__b))
3256 __spaces.push_back(*__b++);
3259 __err |= ios_base::failbit;
3264 case money_base::none:
3267 while (__b != __e && __ct.is(ctype_base::space, *__b))
3268 __spaces.push_back(*__b++);
3271 case money_base::sign:
3272 if (__psn.size() + __nsn.size() > 0)
3274 if (__psn.size() == 0 || __nsn.size() == 0)
3275 { // sign is optional
3276 if (__psn.size() > 0)
3277 { // __nsn.size() == 0
3278 if (*__b == __psn[0])
3281 if (__psn.size() > 1)
3282 __trailing_sign = &__psn;
3287 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
3291 if (__nsn.size() > 1)
3292 __trailing_sign = &__nsn;
3295 else // sign is required
3297 if (*__b == __psn[0])
3300 if (__psn.size() > 1)
3301 __trailing_sign = &__psn;
3303 else if (*__b == __nsn[0])
3307 if (__nsn.size() > 1)
3308 __trailing_sign = &__nsn;
3312 __err |= ios_base::failbit;
3318 case money_base::symbol:
3320 bool __more_needed = __trailing_sign ||
3322 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
3323 bool __sb = __flags & ios_base::showbase;
3324 if (__sb || __more_needed)
3326 typename string_type::const_iterator __sym_space_end = __sym.begin();
3327 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3328 __pat.field[__p - 1] == money_base::space)) {
3329 // Match spaces we've already read against spaces at
3330 // the beginning of __sym.
3331 while (__sym_space_end != __sym.end() &&
3332 __ct.is(ctype_base::space, *__sym_space_end))
3334 const size_t __num_spaces = __sym_space_end - __sym.begin();
3335 if (__num_spaces > __spaces.size() ||
3336 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3338 // No match. Put __sym_space_end back at the
3339 // beginning of __sym, which will prevent a
3340 // match in the next loop.
3341 __sym_space_end = __sym.begin();
3344 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3345 while (__sym_curr_char != __sym.end() && __b != __e &&
3346 *__b == *__sym_curr_char) {
3350 if (__sb && __sym_curr_char != __sym.end())
3352 __err |= ios_base::failbit;
3358 case money_base::value:
3361 for (; __b != __e; ++__b)
3363 char_type __c = *__b;
3364 if (__ct.is(ctype_base::digit, __c))
3367 __double_or_nothing(__wb, __wn, __we);
3371 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3374 __double_or_nothing(__gb, __gn, __ge);
3381 if (__gb.get() != __gn && __ng > 0)
3384 __double_or_nothing(__gb, __gn, __ge);
3389 if (__b == __e || *__b != __dp)
3391 __err |= ios_base::failbit;
3394 for (++__b; __fd > 0; --__fd, ++__b)
3396 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3398 __err |= ios_base::failbit;
3402 __double_or_nothing(__wb, __wn, __we);
3406 if (__wn == __wb.get())
3408 __err |= ios_base::failbit;
3415 if (__trailing_sign)
3417 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3419 if (__b == __e || *__b != (*__trailing_sign)[__i])
3421 __err |= ios_base::failbit;
3426 if (__gb.get() != __gn)
3428 ios_base::iostate __et = ios_base::goodbit;
3429 __check_grouping(__grp, __gb.get(), __gn, __et);
3432 __err |= ios_base::failbit;
3439 template <class _CharT, class _InputIterator>
3441 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3442 bool __intl, ios_base& __iob,
3443 ios_base::iostate& __err,
3444 long double& __v) const
3446 const int __bz = 100;
3447 char_type __wbuf[__bz];
3448 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3450 char_type* __we = __wbuf + __bz;
3451 locale __loc = __iob.getloc();
3452 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3454 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3457 const char __src[] = "0123456789";
3458 char_type __atoms[sizeof(__src)-1];
3459 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3461 char* __nc = __nbuf;
3462 unique_ptr<char, void(*)(void*)> __h(0, free);
3463 if (__wn - __wb.get() > __bz-2)
3465 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3467 __throw_bad_alloc();
3472 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3473 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3475 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3476 __throw_runtime_error("money_get error");
3479 __err |= ios_base::eofbit;
3483 template <class _CharT, class _InputIterator>
3485 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3486 bool __intl, ios_base& __iob,
3487 ios_base::iostate& __err,
3488 string_type& __v) const
3490 const int __bz = 100;
3491 char_type __wbuf[__bz];
3492 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3494 char_type* __we = __wbuf + __bz;
3495 locale __loc = __iob.getloc();
3496 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3498 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3503 __v.push_back(__ct.widen('-'));
3504 char_type __z = __ct.widen('0');
3506 for (__w = __wb.get(); __w < __wn-1; ++__w)
3509 __v.append(__w, __wn);
3512 __err |= ios_base::eofbit;
3516 _LIBCPP_EXTERN_TEMPLATE(class money_get<char>)
3517 _LIBCPP_EXTERN_TEMPLATE(class money_get<wchar_t>)
3521 template <class _CharT>
3525 typedef _CharT char_type;
3526 typedef basic_string<char_type> string_type;
3528 _LIBCPP_ALWAYS_INLINE __money_put() {}
3530 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3531 money_base::pattern& __pat, char_type& __dp,
3532 char_type& __ts, string& __grp,
3533 string_type& __sym, string_type& __sn,
3535 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3536 ios_base::fmtflags __flags,
3537 const char_type* __db, const char_type* __de,
3538 const ctype<char_type>& __ct, bool __neg,
3539 const money_base::pattern& __pat, char_type __dp,
3540 char_type __ts, const string& __grp,
3541 const string_type& __sym, const string_type& __sn,
3545 template <class _CharT>
3547 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3548 money_base::pattern& __pat, char_type& __dp,
3549 char_type& __ts, string& __grp,
3550 string_type& __sym, string_type& __sn,
3555 const moneypunct<char_type, true>& __mp =
3556 use_facet<moneypunct<char_type, true> >(__loc);
3559 __pat = __mp.neg_format();
3560 __sn = __mp.negative_sign();
3564 __pat = __mp.pos_format();
3565 __sn = __mp.positive_sign();
3567 __dp = __mp.decimal_point();
3568 __ts = __mp.thousands_sep();
3569 __grp = __mp.grouping();
3570 __sym = __mp.curr_symbol();
3571 __fd = __mp.frac_digits();
3575 const moneypunct<char_type, false>& __mp =
3576 use_facet<moneypunct<char_type, false> >(__loc);
3579 __pat = __mp.neg_format();
3580 __sn = __mp.negative_sign();
3584 __pat = __mp.pos_format();
3585 __sn = __mp.positive_sign();
3587 __dp = __mp.decimal_point();
3588 __ts = __mp.thousands_sep();
3589 __grp = __mp.grouping();
3590 __sym = __mp.curr_symbol();
3591 __fd = __mp.frac_digits();
3595 template <class _CharT>
3597 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3598 ios_base::fmtflags __flags,
3599 const char_type* __db, const char_type* __de,
3600 const ctype<char_type>& __ct, bool __neg,
3601 const money_base::pattern& __pat, char_type __dp,
3602 char_type __ts, const string& __grp,
3603 const string_type& __sym, const string_type& __sn,
3607 for (unsigned __p = 0; __p < 4; ++__p)
3609 switch (__pat.field[__p])
3611 case money_base::none:
3614 case money_base::space:
3616 *__me++ = __ct.widen(' ');
3618 case money_base::sign:
3622 case money_base::symbol:
3623 if (!__sym.empty() && (__flags & ios_base::showbase))
3624 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3626 case money_base::value:
3628 // remember start of value so we can reverse it
3629 char_type* __t = __me;
3630 // find beginning of digits
3633 // find end of digits
3634 const char_type* __d;
3635 for (__d = __db; __d < __de; ++__d)
3636 if (!__ct.is(ctype_base::digit, *__d))
3638 // print fractional part
3642 for (__f = __fd; __d > __db && __f > 0; --__f)
3644 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3645 for (; __f > 0; --__f)
3652 *__me++ = __ct.widen('0');
3658 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3659 : static_cast<unsigned>(__grp[__ig]);
3666 if (++__ig < __grp.size())
3667 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3668 numeric_limits<unsigned>::max() :
3669 static_cast<unsigned>(__grp[__ig]);
3681 // print rest of sign, if any
3682 if (__sn.size() > 1)
3683 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3685 if ((__flags & ios_base::adjustfield) == ios_base::left)
3687 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3691 _LIBCPP_EXTERN_TEMPLATE(class __money_put<char>)
3692 _LIBCPP_EXTERN_TEMPLATE(class __money_put<wchar_t>)
3694 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3695 class _LIBCPP_TYPE_VIS money_put
3696 : public locale::facet,
3697 private __money_put<_CharT>
3700 typedef _CharT char_type;
3701 typedef _OutputIterator iter_type;
3702 typedef basic_string<char_type> string_type;
3704 _LIBCPP_ALWAYS_INLINE
3705 explicit money_put(size_t __refs = 0)
3706 : locale::facet(__refs) {}
3708 _LIBCPP_ALWAYS_INLINE
3709 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3710 long double __units) const
3712 return do_put(__s, __intl, __iob, __fl, __units);
3715 _LIBCPP_ALWAYS_INLINE
3716 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3717 const string_type& __digits) const
3719 return do_put(__s, __intl, __iob, __fl, __digits);
3722 static locale::id id;
3725 _LIBCPP_ALWAYS_INLINE
3728 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3729 char_type __fl, long double __units) const;
3730 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3731 char_type __fl, const string_type& __digits) const;
3734 template <class _CharT, class _OutputIterator>
3736 money_put<_CharT, _OutputIterator>::id;
3738 template <class _CharT, class _OutputIterator>
3740 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3741 ios_base& __iob, char_type __fl,
3742 long double __units) const
3745 const size_t __bs = 100;
3748 char_type __digits[__bs];
3749 char_type* __db = __digits;
3750 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3751 unique_ptr<char, void(*)(void*)> __hn(0, free);
3752 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3753 // secure memory for digit storage
3756 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
3757 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3759 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
3762 __throw_bad_alloc();
3764 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3765 if (__hd == nullptr)
3766 __throw_bad_alloc();
3770 locale __loc = __iob.getloc();
3771 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3772 __ct.widen(__bb, __bb + __n, __db);
3773 bool __neg = __n > 0 && __bb[0] == '-';
3774 money_base::pattern __pat;
3781 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3782 // secure memory for formatting
3783 char_type __mbuf[__bs];
3784 char_type* __mb = __mbuf;
3785 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3786 size_t __exn = static_cast<int>(__n) > __fd ?
3787 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3788 __sym.size() + static_cast<size_t>(__fd) + 1
3789 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3792 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3795 __throw_bad_alloc();
3800 this->__format(__mb, __mi, __me, __iob.flags(),
3801 __db, __db + __n, __ct,
3802 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3803 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3806 template <class _CharT, class _OutputIterator>
3808 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3809 ios_base& __iob, char_type __fl,
3810 const string_type& __digits) const
3813 locale __loc = __iob.getloc();
3814 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3815 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3816 money_base::pattern __pat;
3823 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3824 // secure memory for formatting
3825 char_type __mbuf[100];
3826 char_type* __mb = __mbuf;
3827 unique_ptr<char_type, void(*)(void*)> __h(0, free);
3828 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3829 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3830 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3831 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3834 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3837 __throw_bad_alloc();
3842 this->__format(__mb, __mi, __me, __iob.flags(),
3843 __digits.data(), __digits.data() + __digits.size(), __ct,
3844 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3845 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3848 _LIBCPP_EXTERN_TEMPLATE(class money_put<char>)
3849 _LIBCPP_EXTERN_TEMPLATE(class money_put<wchar_t>)
3853 class _LIBCPP_TYPE_VIS messages_base
3856 typedef ptrdiff_t catalog;
3858 _LIBCPP_ALWAYS_INLINE messages_base() {}
3861 template <class _CharT>
3862 class _LIBCPP_TYPE_VIS messages
3863 : public locale::facet,
3864 public messages_base
3867 typedef _CharT char_type;
3868 typedef basic_string<_CharT> string_type;
3870 _LIBCPP_ALWAYS_INLINE
3871 explicit messages(size_t __refs = 0)
3872 : locale::facet(__refs) {}
3874 _LIBCPP_ALWAYS_INLINE
3875 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3877 return do_open(__nm, __loc);
3880 _LIBCPP_ALWAYS_INLINE
3881 string_type get(catalog __c, int __set, int __msgid,
3882 const string_type& __dflt) const
3884 return do_get(__c, __set, __msgid, __dflt);
3887 _LIBCPP_ALWAYS_INLINE
3888 void close(catalog __c) const
3893 static locale::id id;
3896 _LIBCPP_ALWAYS_INLINE
3899 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3900 virtual string_type do_get(catalog, int __set, int __msgid,
3901 const string_type& __dflt) const;
3902 virtual void do_close(catalog) const;
3905 template <class _CharT>
3907 messages<_CharT>::id;
3909 template <class _CharT>
3910 typename messages<_CharT>::catalog
3911 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3916 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3918 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3923 template <class _CharT>
3924 typename messages<_CharT>::string_type
3925 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3926 const string_type& __dflt) const
3932 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3934 __dflt.c_str() + __dflt.size());
3937 nl_catd __cat = (nl_catd)__c;
3938 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3940 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3941 __n, __n + strlen(__n));
3946 template <class _CharT>
3948 messages<_CharT>::do_close(catalog __c) const
3950 #if !defined(_WIN32)
3953 nl_catd __cat = (nl_catd)__c;
3958 _LIBCPP_EXTERN_TEMPLATE(class messages<char>)
3959 _LIBCPP_EXTERN_TEMPLATE(class messages<wchar_t>)
3961 template <class _CharT>
3962 class _LIBCPP_TYPE_VIS messages_byname
3963 : public messages<_CharT>
3966 typedef messages_base::catalog catalog;
3967 typedef basic_string<_CharT> string_type;
3969 _LIBCPP_ALWAYS_INLINE
3970 explicit messages_byname(const char*, size_t __refs = 0)
3971 : messages<_CharT>(__refs) {}
3973 _LIBCPP_ALWAYS_INLINE
3974 explicit messages_byname(const string&, size_t __refs = 0)
3975 : messages<_CharT>(__refs) {}
3978 _LIBCPP_ALWAYS_INLINE
3979 ~messages_byname() {}
3982 _LIBCPP_EXTERN_TEMPLATE(class messages_byname<char>)
3983 _LIBCPP_EXTERN_TEMPLATE(class messages_byname<wchar_t>)
3985 template<class _Codecvt, class _Elem = wchar_t,
3986 class _Wide_alloc = allocator<_Elem>,
3987 class _Byte_alloc = allocator<char> >
3988 class _LIBCPP_TYPE_VIS wstring_convert
3991 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3992 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3993 typedef typename _Codecvt::state_type state_type;
3994 typedef typename wide_string::traits_type::int_type int_type;
3997 byte_string __byte_err_string_;
3998 wide_string __wide_err_string_;
3999 _Codecvt* __cvtptr_;
4000 state_type __cvtstate_;
4003 wstring_convert(const wstring_convert& __wc);
4004 wstring_convert& operator=(const wstring_convert& __wc);
4006 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
4007 wstring_convert(_Codecvt* __pcvt, state_type __state);
4008 wstring_convert(const byte_string& __byte_err,
4009 const wide_string& __wide_err = wide_string());
4010 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4011 wstring_convert(wstring_convert&& __wc);
4015 _LIBCPP_ALWAYS_INLINE
4016 wide_string from_bytes(char __byte)
4017 {return from_bytes(&__byte, &__byte+1);}
4018 _LIBCPP_ALWAYS_INLINE
4019 wide_string from_bytes(const char* __ptr)
4020 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
4021 _LIBCPP_ALWAYS_INLINE
4022 wide_string from_bytes(const byte_string& __str)
4023 {return from_bytes(__str.data(), __str.data() + __str.size());}
4024 wide_string from_bytes(const char* __first, const char* __last);
4026 _LIBCPP_ALWAYS_INLINE
4027 byte_string to_bytes(_Elem __wchar)
4028 {return to_bytes(&__wchar, &__wchar+1);}
4029 _LIBCPP_ALWAYS_INLINE
4030 byte_string to_bytes(const _Elem* __wptr)
4031 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
4032 _LIBCPP_ALWAYS_INLINE
4033 byte_string to_bytes(const wide_string& __wstr)
4034 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
4035 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
4037 _LIBCPP_ALWAYS_INLINE
4038 size_t converted() const {return __cvtcount_;}
4039 _LIBCPP_ALWAYS_INLINE
4040 state_type state() const {return __cvtstate_;}
4043 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4044 inline _LIBCPP_ALWAYS_INLINE
4045 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4046 wstring_convert(_Codecvt* __pcvt)
4047 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
4051 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4052 inline _LIBCPP_ALWAYS_INLINE
4053 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4054 wstring_convert(_Codecvt* __pcvt, state_type __state)
4055 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
4059 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4060 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4061 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
4062 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
4063 __cvtstate_(), __cvtcount_(0)
4065 __cvtptr_ = new _Codecvt;
4068 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4070 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4071 inline _LIBCPP_ALWAYS_INLINE
4072 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4073 wstring_convert(wstring_convert&& __wc)
4074 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
4075 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
4076 __cvtptr_(__wc.__cvtptr_),
4077 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
4079 __wc.__cvtptr_ = nullptr;
4082 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4084 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4085 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
4090 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4091 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
4092 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4093 from_bytes(const char* __frm, const char* __frm_end)
4096 if (__cvtptr_ != nullptr)
4098 wide_string __ws(2*(__frm_end - __frm), _Elem());
4099 if (__frm != __frm_end)
4100 __ws.resize(__ws.capacity());
4101 codecvt_base::result __r = codecvt_base::ok;
4102 state_type __st = __cvtstate_;
4103 if (__frm != __frm_end)
4105 _Elem* __to = &__ws[0];
4106 _Elem* __to_end = __to + __ws.size();
4107 const char* __frm_nxt;
4111 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
4112 __to, __to_end, __to_nxt);
4113 __cvtcount_ += __frm_nxt - __frm;
4114 if (__frm_nxt == __frm)
4116 __r = codecvt_base::error;
4118 else if (__r == codecvt_base::noconv)
4120 __ws.resize(__to - &__ws[0]);
4121 // This only gets executed if _Elem is char
4122 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
4124 __r = codecvt_base::ok;
4126 else if (__r == codecvt_base::ok)
4128 __ws.resize(__to_nxt - &__ws[0]);
4131 else if (__r == codecvt_base::partial)
4133 ptrdiff_t __s = __to_nxt - &__ws[0];
4134 __ws.resize(2 * __s);
4135 __to = &__ws[0] + __s;
4136 __to_end = &__ws[0] + __ws.size();
4139 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4141 if (__r == codecvt_base::ok)
4144 #ifndef _LIBCPP_NO_EXCEPTIONS
4145 if (__wide_err_string_.empty())
4146 throw range_error("wstring_convert: from_bytes error");
4147 #endif // _LIBCPP_NO_EXCEPTIONS
4148 return __wide_err_string_;
4151 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4152 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
4153 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4154 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
4157 if (__cvtptr_ != nullptr)
4159 byte_string __bs(2*(__frm_end - __frm), char());
4160 if (__frm != __frm_end)
4161 __bs.resize(__bs.capacity());
4162 codecvt_base::result __r = codecvt_base::ok;
4163 state_type __st = __cvtstate_;
4164 if (__frm != __frm_end)
4166 char* __to = &__bs[0];
4167 char* __to_end = __to + __bs.size();
4168 const _Elem* __frm_nxt;
4172 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
4173 __to, __to_end, __to_nxt);
4174 __cvtcount_ += __frm_nxt - __frm;
4175 if (__frm_nxt == __frm)
4177 __r = codecvt_base::error;
4179 else if (__r == codecvt_base::noconv)
4181 __bs.resize(__to - &__bs[0]);
4182 // This only gets executed if _Elem is char
4183 __bs.append((const char*)__frm, (const char*)__frm_end);
4185 __r = codecvt_base::ok;
4187 else if (__r == codecvt_base::ok)
4189 __bs.resize(__to_nxt - &__bs[0]);
4192 else if (__r == codecvt_base::partial)
4194 ptrdiff_t __s = __to_nxt - &__bs[0];
4195 __bs.resize(2 * __s);
4196 __to = &__bs[0] + __s;
4197 __to_end = &__bs[0] + __bs.size();
4200 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4202 if (__r == codecvt_base::ok)
4204 size_t __s = __bs.size();
4205 __bs.resize(__bs.capacity());
4206 char* __to = &__bs[0] + __s;
4207 char* __to_end = __to + __bs.size();
4211 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
4212 if (__r == codecvt_base::noconv)
4214 __bs.resize(__to - &__bs[0]);
4215 __r = codecvt_base::ok;
4217 else if (__r == codecvt_base::ok)
4219 __bs.resize(__to_nxt - &__bs[0]);
4221 else if (__r == codecvt_base::partial)
4223 ptrdiff_t __sp = __to_nxt - &__bs[0];
4224 __bs.resize(2 * __sp);
4225 __to = &__bs[0] + __sp;
4226 __to_end = &__bs[0] + __bs.size();
4228 } while (__r == codecvt_base::partial);
4229 if (__r == codecvt_base::ok)
4233 #ifndef _LIBCPP_NO_EXCEPTIONS
4234 if (__byte_err_string_.empty())
4235 throw range_error("wstring_convert: to_bytes error");
4236 #endif // _LIBCPP_NO_EXCEPTIONS
4237 return __byte_err_string_;
4240 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
4241 class _LIBCPP_TYPE_VIS wbuffer_convert
4242 : public basic_streambuf<_Elem, _Tr>
4246 typedef _Elem char_type;
4247 typedef _Tr traits_type;
4248 typedef typename traits_type::int_type int_type;
4249 typedef typename traits_type::pos_type pos_type;
4250 typedef typename traits_type::off_type off_type;
4251 typedef typename _Codecvt::state_type state_type;
4255 const char* __extbufnext_;
4256 const char* __extbufend_;
4257 char __extbuf_min_[8];
4259 char_type* __intbuf_;
4261 streambuf* __bufptr_;
4264 ios_base::openmode __cm_;
4267 bool __always_noconv_;
4269 wbuffer_convert(const wbuffer_convert&);
4270 wbuffer_convert& operator=(const wbuffer_convert&);
4272 wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
4273 state_type __state = state_type());
4276 _LIBCPP_INLINE_VISIBILITY
4277 streambuf* rdbuf() const {return __bufptr_;}
4278 _LIBCPP_INLINE_VISIBILITY
4279 streambuf* rdbuf(streambuf* __bytebuf)
4281 streambuf* __r = __bufptr_;
4282 __bufptr_ = __bytebuf;
4286 _LIBCPP_INLINE_VISIBILITY
4287 state_type state() const {return __st_;}
4290 virtual int_type underflow();
4291 virtual int_type pbackfail(int_type __c = traits_type::eof());
4292 virtual int_type overflow (int_type __c = traits_type::eof());
4293 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4295 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4296 ios_base::openmode __wch = ios_base::in | ios_base::out);
4297 virtual pos_type seekpos(pos_type __sp,
4298 ios_base::openmode __wch = ios_base::in | ios_base::out);
4303 void __write_mode();
4304 wbuffer_convert* __close();
4307 template <class _Codecvt, class _Elem, class _Tr>
4308 wbuffer_convert<_Codecvt, _Elem, _Tr>::
4309 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4316 __bufptr_(__bytebuf),
4322 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4327 template <class _Codecvt, class _Elem, class _Tr>
4328 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4333 delete [] __extbuf_;
4335 delete [] __intbuf_;
4338 template <class _Codecvt, class _Elem, class _Tr>
4339 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4340 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4342 if (__cv_ == 0 || __bufptr_ == 0)
4343 return traits_type::eof();
4344 bool __initial = __read_mode();
4346 if (this->gptr() == 0)
4347 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4348 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4349 int_type __c = traits_type::eof();
4350 if (this->gptr() == this->egptr())
4352 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4353 if (__always_noconv_)
4355 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4356 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4359 this->setg(this->eback(),
4360 this->eback() + __unget_sz,
4361 this->eback() + __unget_sz + __nmemb);
4362 __c = *this->gptr();
4367 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4368 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4369 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
4370 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
4371 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4372 codecvt_base::result __r;
4373 state_type __svs = __st_;
4374 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4377 __extbufend_ = __extbufnext_ + __nr;
4379 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4380 this->eback() + __unget_sz,
4381 this->egptr(), __inext);
4382 if (__r == codecvt_base::noconv)
4384 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4385 __c = *this->gptr();
4387 else if (__inext != this->eback() + __unget_sz)
4389 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4390 __c = *this->gptr();
4396 __c = *this->gptr();
4397 if (this->eback() == &__1buf)
4398 this->setg(0, 0, 0);
4402 template <class _Codecvt, class _Elem, class _Tr>
4403 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4404 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4406 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4408 if (traits_type::eq_int_type(__c, traits_type::eof()))
4411 return traits_type::not_eof(__c);
4413 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4416 *this->gptr() = traits_type::to_char_type(__c);
4420 return traits_type::eof();
4423 template <class _Codecvt, class _Elem, class _Tr>
4424 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4425 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4427 if (__cv_ == 0 || __bufptr_ == 0)
4428 return traits_type::eof();
4431 char_type* __pb_save = this->pbase();
4432 char_type* __epb_save = this->epptr();
4433 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4435 if (this->pptr() == 0)
4436 this->setp(&__1buf, &__1buf+1);
4437 *this->pptr() = traits_type::to_char_type(__c);
4440 if (this->pptr() != this->pbase())
4442 if (__always_noconv_)
4444 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4445 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4446 return traits_type::eof();
4450 char* __extbe = __extbuf_;
4451 codecvt_base::result __r;
4454 const char_type* __e;
4455 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4456 __extbuf_, __extbuf_ + __ebs_, __extbe);
4457 if (__e == this->pbase())
4458 return traits_type::eof();
4459 if (__r == codecvt_base::noconv)
4461 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4462 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4463 return traits_type::eof();
4465 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4467 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4468 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4469 return traits_type::eof();
4470 if (__r == codecvt_base::partial)
4472 this->setp((char_type*)__e, this->pptr());
4473 this->pbump(this->epptr() - this->pbase());
4477 return traits_type::eof();
4478 } while (__r == codecvt_base::partial);
4480 this->setp(__pb_save, __epb_save);
4482 return traits_type::not_eof(__c);
4485 template <class _Codecvt, class _Elem, class _Tr>
4486 basic_streambuf<_Elem, _Tr>*
4487 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4489 this->setg(0, 0, 0);
4492 delete [] __extbuf_;
4494 delete [] __intbuf_;
4496 if (__ebs_ > sizeof(__extbuf_min_))
4498 if (__always_noconv_ && __s)
4500 __extbuf_ = (char*)__s;
4505 __extbuf_ = new char[__ebs_];
4511 __extbuf_ = __extbuf_min_;
4512 __ebs_ = sizeof(__extbuf_min_);
4515 if (!__always_noconv_)
4517 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4518 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4525 __intbuf_ = new char_type[__ibs_];
4538 template <class _Codecvt, class _Elem, class _Tr>
4539 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4540 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4541 ios_base::openmode __om)
4543 int __width = __cv_->encoding();
4544 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4545 return pos_type(off_type(-1));
4546 // __width > 0 || __off == 0
4556 return pos_type(off_type(-1));
4558 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4563 template <class _Codecvt, class _Elem, class _Tr>
4564 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4565 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4567 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4568 return pos_type(off_type(-1));
4569 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4570 return pos_type(off_type(-1));
4574 template <class _Codecvt, class _Elem, class _Tr>
4576 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4578 if (__cv_ == 0 || __bufptr_ == 0)
4580 if (__cm_ & ios_base::out)
4582 if (this->pptr() != this->pbase())
4583 if (overflow() == traits_type::eof())
4585 codecvt_base::result __r;
4589 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4590 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4591 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4593 } while (__r == codecvt_base::partial);
4594 if (__r == codecvt_base::error)
4596 if (__bufptr_->pubsync())
4599 else if (__cm_ & ios_base::in)
4602 if (__always_noconv_)
4603 __c = this->egptr() - this->gptr();
4606 int __width = __cv_->encoding();
4607 __c = __extbufend_ - __extbufnext_;
4609 __c += __width * (this->egptr() - this->gptr());
4612 if (this->gptr() != this->egptr())
4614 reverse(this->gptr(), this->egptr());
4615 codecvt_base::result __r;
4616 const char_type* __e = this->gptr();
4620 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4621 __extbuf_, __extbuf_ + __ebs_, __extbe);
4624 case codecvt_base::noconv:
4625 __c += this->egptr() - this->gptr();
4627 case codecvt_base::ok:
4628 case codecvt_base::partial:
4629 __c += __extbe - __extbuf_;
4634 } while (__r == codecvt_base::partial);
4638 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4640 this->setg(0, 0, 0);
4646 template <class _Codecvt, class _Elem, class _Tr>
4648 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4650 if (!(__cm_ & ios_base::in))
4653 if (__always_noconv_)
4654 this->setg((char_type*)__extbuf_,
4655 (char_type*)__extbuf_ + __ebs_,
4656 (char_type*)__extbuf_ + __ebs_);
4658 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4659 __cm_ = ios_base::in;
4665 template <class _Codecvt, class _Elem, class _Tr>
4667 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4669 if (!(__cm_ & ios_base::out))
4671 this->setg(0, 0, 0);
4672 if (__ebs_ > sizeof(__extbuf_min_))
4674 if (__always_noconv_)
4675 this->setp((char_type*)__extbuf_,
4676 (char_type*)__extbuf_ + (__ebs_ - 1));
4678 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4682 __cm_ = ios_base::out;
4686 template <class _Codecvt, class _Elem, class _Tr>
4687 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4688 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4690 wbuffer_convert* __rt = 0;
4691 if (__cv_ != 0 && __bufptr_ != 0)
4694 if ((__cm_ & ios_base::out) && sync())
4700 _LIBCPP_END_NAMESPACE_STD
4702 #endif // _LIBCPP_LOCALE