blob: 916be806bb0df8d96b51c713a89620ddf72c4bd6 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===-------------------------- locale ------------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_LOCALE
12#define _LIBCPP_LOCALE
13
14/*
15 locale synopsis
16
17namespace std
18{
19
20class locale
21{
22public:
23 // types:
24 class facet;
25 class id;
26
27 typedef int category;
28 static const category // values assigned here are for exposition only
29 none = 0x000,
30 collate = 0x010,
31 ctype = 0x020,
32 monetary = 0x040,
33 numeric = 0x080,
34 time = 0x100,
35 messages = 0x200,
36 all = collate | ctype | monetary | numeric | time | messages;
37
38 // construct/copy/destroy:
Howard Hinnant7c9e5732011-05-31 15:34:58 +000039 locale() noexcept;
40 locale(const locale& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000041 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);
47
Howard Hinnant7c9e5732011-05-31 15:34:58 +000048 ~locale(); // not virtual
Howard Hinnantc51e1022010-05-11 19:42:16 +000049
Howard Hinnant7c9e5732011-05-31 15:34:58 +000050 const locale& operator=(const locale& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000051
52 template <class Facet> locale combine(const locale& other) const;
53
54 // locale operations:
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;
61
62 // global locale objects:
63 static locale global(const locale&);
64 static const locale& classic();
65};
66
67template <class Facet> const Facet& use_facet(const locale&);
Howard Hinnant7c9e5732011-05-31 15:34:58 +000068template <class Facet> bool has_facet(const locale&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000069
70// 22.3.3, convenience interfaces:
71template <class charT> bool isspace (charT c, const locale& loc);
72template <class charT> bool isprint (charT c, const locale& loc);
73template <class charT> bool iscntrl (charT c, const locale& loc);
74template <class charT> bool isupper (charT c, const locale& loc);
75template <class charT> bool islower (charT c, const locale& loc);
76template <class charT> bool isalpha (charT c, const locale& loc);
77template <class charT> bool isdigit (charT c, const locale& loc);
78template <class charT> bool ispunct (charT c, const locale& loc);
79template <class charT> bool isxdigit(charT c, const locale& loc);
80template <class charT> bool isalnum (charT c, const locale& loc);
81template <class charT> bool isgraph (charT c, const locale& loc);
82template <class charT> charT toupper(charT c, const locale& loc);
83template <class charT> charT tolower(charT c, const locale& loc);
Howard Hinnant9dd7e892010-05-31 20:58:54 +000084
85template<class Codecvt, class Elem = wchar_t,
86 class Wide_alloc = allocator<Elem>,
87 class Byte_alloc = allocator<char>>
88class wstring_convert
89{
90public:
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;
95
Marshall Clowccaa0fb2013-08-27 20:18:59 +000096 explicit wstring_convert(Codecvt* pcvt = new Codecvt); // explicit in C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +000097 wstring_convert(Codecvt* pcvt, state_type state);
Marshall Clowccaa0fb2013-08-27 20:18:59 +000098 explicit wstring_convert(const byte_string& byte_err, // explicit in C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +000099 const wide_string& wide_err = wide_string());
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000100 wstring_convert(const wstring_convert&) = delete; // C++14
101 wstring_convert & operator=(const wstring_convert &) = delete; // C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000102 ~wstring_convert();
103
104 wide_string from_bytes(char byte);
105 wide_string from_bytes(const char* ptr);
106 wide_string from_bytes(const byte_string& str);
107 wide_string from_bytes(const char* first, const char* last);
108
109 byte_string to_bytes(Elem wchar);
110 byte_string to_bytes(const Elem* wptr);
111 byte_string to_bytes(const wide_string& wstr);
112 byte_string to_bytes(const Elem* first, const Elem* last);
113
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000114 size_t converted() const; // noexcept in C++14
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000115 state_type state() const;
116};
117
Howard Hinnantc51e1022010-05-11 19:42:16 +0000118template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000119class wbuffer_convert
120 : public basic_streambuf<Elem, Tr>
121{
122public:
123 typedef typename Tr::state_type state_type;
124
Marshall Clowccaa0fb2013-08-27 20:18:59 +0000125 explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
126 state_type state = state_type()); // explicit in C++14
127 wbuffer_convert(const wbuffer_convert&) = delete; // C++14
128 wbuffer_convert & operator=(const wbuffer_convert &) = delete; // C++14
129 ~wbuffer_convert(); // C++14
130
Howard Hinnant9dd7e892010-05-31 20:58:54 +0000131 streambuf* rdbuf() const;
132 streambuf* rdbuf(streambuf* bytebuf);
133
134 state_type state() const;
135};
Howard Hinnantc51e1022010-05-11 19:42:16 +0000136
137// 22.4.1 and 22.4.1.3, ctype:
138class ctype_base;
139template <class charT> class ctype;
140template <> class ctype<char>; // specialization
141template <class charT> class ctype_byname;
142template <> class ctype_byname<char>; // specialization
143
144class codecvt_base;
145template <class internT, class externT, class stateT> class codecvt;
146template <class internT, class externT, class stateT> class codecvt_byname;
147
148// 22.4.2 and 22.4.3, numeric:
149template <class charT, class InputIterator> class num_get;
150template <class charT, class OutputIterator> class num_put;
151template <class charT> class numpunct;
152template <class charT> class numpunct_byname;
153
154// 22.4.4, col lation:
155template <class charT> class collate;
156template <class charT> class collate_byname;
157
158// 22.4.5, date and time:
159class time_base;
160template <class charT, class InputIterator> class time_get;
161template <class charT, class InputIterator> class time_get_byname;
162template <class charT, class OutputIterator> class time_put;
163template <class charT, class OutputIterator> class time_put_byname;
164
165// 22.4.6, money:
166class money_base;
167template <class charT, class InputIterator> class money_get;
168template <class charT, class OutputIterator> class money_put;
169template <class charT, bool Intl> class moneypunct;
170template <class charT, bool Intl> class moneypunct_byname;
171
172// 22.4.7, message retrieval:
173class messages_base;
174template <class charT> class messages;
175template <class charT> class messages_byname;
176
177} // std
178
179*/
180
181#include <__config>
182#include <__locale>
183#include <algorithm>
184#include <memory>
185#include <ios>
186#include <streambuf>
187#include <iterator>
188#include <limits>
Marshall Clowdde4bfe2013-03-18 17:45:34 +0000189#ifndef __APPLE__
Howard Hinnant155c2af2010-05-24 17:49:41 +0000190#include <cstdarg>
191#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000192#include <cstdlib>
193#include <ctime>
Howard Hinnant8ad70912013-09-17 01:34:47 +0000194#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
Howard Hinnantae0f80b2011-09-29 20:33:10 +0000195#include <support/win32/locale_win32.h>
Jonathan Roelofs37058612014-09-19 20:09:12 +0000196#elif defined(_NEWLIB_VERSION)
197// FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an
198// include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html
199// has had a chance to bake for a bit
200#include <support/newlib/xlocale.h>
Ed Schouten118b6032015-03-11 16:39:36 +0000201#endif
202#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +0000203#include <nl_types.h>
Marshall Clow3477ec92014-07-10 15:20:28 +0000204#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000205
Marshall Clowdde4bfe2013-03-18 17:45:34 +0000206#ifdef __APPLE__
Howard Hinnant48fd5d52012-11-14 21:17:15 +0000207#include <Availability.h>
208#endif
209
Howard Hinnantc5a5fbd2011-11-29 16:45:27 +0000210#include <__undef_min_max>
211
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000212#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000213#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000214#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000215
216_LIBCPP_BEGIN_NAMESPACE_STD
217
Marshall Clow82378c02013-03-18 19:34:07 +0000218#if defined(__APPLE__) || defined(__FreeBSD__)
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000219# define _LIBCPP_GET_C_LOCALE 0
Ed Schoutenaa497c82015-03-10 09:35:22 +0000220#elif defined(__CloudABI__) || defined(__NetBSD__)
Joerg Sonnenberger153e4162013-05-17 21:17:34 +0000221# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000222#else
223# define _LIBCPP_GET_C_LOCALE __cloc()
Howard Hinnantf312e3e2011-09-28 23:39:33 +0000224 // Get the C locale object
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000225 _LIBCPP_FUNC_VIS locale_t __cloc();
Howard Hinnantf312e3e2011-09-28 23:39:33 +0000226#define __cloc_defined
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000227#endif
228
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000229typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
230typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
David Chisnall4d958ed2012-02-29 13:00:07 +0000231#ifndef _LIBCPP_LOCALE__L_EXTENSIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000232typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
David Chisnall4d958ed2012-02-29 13:00:07 +0000233#endif
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000234
Howard Hinnant155c2af2010-05-24 17:49:41 +0000235// OSX has nice foo_l() functions that let you turn off use of the global
236// locale. Linux, not so much. The following functions avoid the locale when
237// that's possible and otherwise do the wrong thing. FIXME.
Jonathan Roelofs37058612014-09-19 20:09:12 +0000238#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \
239 defined(_NEWLIB_VERSION)
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000240
241#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
242decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
Howard Hinnant756c69b2010-09-22 16:48:34 +0000243inline _LIBCPP_INLINE_VISIBILITY
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000244__mb_cur_max_l(locale_t __l)
Howard Hinnant155c2af2010-05-24 17:49:41 +0000245{
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000246 return MB_CUR_MAX_L(__l);
247}
248#else // _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000249inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000250decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
251{
252 __locale_raii __current(uselocale(__l), uselocale);
253 return MB_CUR_MAX;
254}
255#endif // _LIBCPP_LOCALE__L_EXTENSIONS
256
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000257inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000258wint_t __btowc_l(int __c, locale_t __l)
259{
Howard Hinnantf312e3e2011-09-28 23:39:33 +0000260#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000261 return btowc_l(__c, __l);
262#else
263 __locale_raii __current(uselocale(__l), uselocale);
264 return btowc(__c);
265#endif
Alexis Huntd4a24912011-07-13 06:40:50 +0000266}
Howard Hinnant2de5c472011-07-13 15:48:16 +0000267
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000268inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000269int __wctob_l(wint_t __c, locale_t __l)
Alexis Huntd4a24912011-07-13 06:40:50 +0000270{
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000271#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
272 return wctob_l(__c, __l);
273#else
274 __locale_raii __current(uselocale(__l), uselocale);
275 return wctob(__c);
276#endif
Alexis Huntd4a24912011-07-13 06:40:50 +0000277}
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000278
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000279inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000280size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
281 size_t __len, mbstate_t *__ps, locale_t __l)
282{
283#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
284 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
285#else
286 __locale_raii __current(uselocale(__l), uselocale);
287 return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
288#endif
289}
290
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000291inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000292size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
293{
294#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
295 return wcrtomb_l(__s, __wc, __ps, __l);
296#else
297 __locale_raii __current(uselocale(__l), uselocale);
298 return wcrtomb(__s, __wc, __ps);
299#endif
300}
301
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000302inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000303size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
304 size_t __len, mbstate_t *__ps, locale_t __l)
305{
306#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
David Chisnall1d581062011-09-21 08:39:44 +0000307 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000308#else
309 __locale_raii __current(uselocale(__l), uselocale);
310 return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
311#endif
312}
313
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000314inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000315size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
316 mbstate_t *__ps, locale_t __l)
317{
318#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
319 return mbrtowc_l(__pwc, __s, __n, __ps, __l);
320#else
321 __locale_raii __current(uselocale(__l), uselocale);
322 return mbrtowc(__pwc, __s, __n, __ps);
323#endif
324}
325
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000326inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000327int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
328{
329#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
David Chisnall1d581062011-09-21 08:39:44 +0000330 return mbtowc_l(__pwc, __pmb, __max, __l);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000331#else
332 __locale_raii __current(uselocale(__l), uselocale);
333 return mbtowc(__pwc, __pmb, __max);
334#endif
335}
336
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000337inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000338size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
339{
340#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
341 return mbrlen_l(__s, __n, __ps, __l);
342#else
343 __locale_raii __current(uselocale(__l), uselocale);
344 return mbrlen(__s, __n, __ps);
345#endif
346}
347
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000348inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000349lconv *__localeconv_l(locale_t __l)
350{
351#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
352 return localeconv_l(__l);
353#else
354 __locale_raii __current(uselocale(__l), uselocale);
355 return localeconv();
356#endif
357}
358
Howard Hinnantb8a8ca22013-10-04 22:09:00 +0000359inline _LIBCPP_ALWAYS_INLINE
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000360size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
361 mbstate_t *__ps, locale_t __l)
362{
363#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
364 return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
365#else
366 __locale_raii __current(uselocale(__l), uselocale);
367 return mbsrtowcs(__dest, __src, __len, __ps);
368#endif
369}
370
Chandler Carruth952bdc82012-12-31 06:09:54 +0000371inline
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000372int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
373 va_list __va;
374 va_start(__va, __format);
375#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
376 int __res = vsnprintf_l(__s, __n, __l, __format, __va);
377#else
378 __locale_raii __current(uselocale(__l), uselocale);
379 int __res = vsnprintf(__s, __n, __format, __va);
380#endif
381 va_end(__va);
382 return __res;
383}
384
Chandler Carruth952bdc82012-12-31 06:09:54 +0000385inline
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000386int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
387 va_list __va;
388 va_start(__va, __format);
389#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
390 int __res = vasprintf_l(__s, __l, __format, __va);
391#else
392 __locale_raii __current(uselocale(__l), uselocale);
393 int __res = vasprintf(__s, __format, __va);
394#endif
395 va_end(__va);
396 return __res;
397}
398
Chandler Carruth952bdc82012-12-31 06:09:54 +0000399inline
Alexis Hunt1adf2aa2011-07-15 05:40:33 +0000400int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
401 va_list __va;
402 va_start(__va, __format);
403#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
404 int __res = vsscanf_l(__s, __l, __format, __va);
405#else
406 __locale_raii __current(uselocale(__l), uselocale);
407 int __res = vsscanf(__s, __format, __va);
408#endif
409 va_end(__va);
410 return __res;
411}
412
Howard Hinnantf312e3e2011-09-28 23:39:33 +0000413#endif // __linux__
Howard Hinnant155c2af2010-05-24 17:49:41 +0000414
Howard Hinnantc51e1022010-05-11 19:42:16 +0000415// __scan_keyword
416// Scans [__b, __e) until a match is found in the basic_strings range
417// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
418// __b will be incremented (visibly), consuming CharT until a match is found
419// or proved to not exist. A keyword may be "", in which will match anything.
420// If one keyword is a prefix of another, and the next CharT in the input
421// might match another keyword, the algorithm will attempt to find the longest
422// matching keyword. If the longer matching keyword ends up not matching, then
423// no keyword match is found. If no keyword match is found, __ke is returned
424// and failbit is set in __err.
425// Else an iterator pointing to the matching keyword is found. If more than
426// one keyword matches, an iterator to the first matching keyword is returned.
Alp Tokerb8a95f52014-05-15 11:27:39 +0000427// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000428// __ct is used to force to lower case before comparing characters.
429// Examples:
430// Keywords: "a", "abb"
431// If the input is "a", the first keyword matches and eofbit is set.
432// If the input is "abc", no match is found and "ab" are consumed.
433template <class _InputIterator, class _ForwardIterator, class _Ctype>
434_LIBCPP_HIDDEN
435_ForwardIterator
436__scan_keyword(_InputIterator& __b, _InputIterator __e,
437 _ForwardIterator __kb, _ForwardIterator __ke,
438 const _Ctype& __ct, ios_base::iostate& __err,
439 bool __case_sensitive = true)
440{
441 typedef typename iterator_traits<_InputIterator>::value_type _CharT;
Howard Hinnant28b24882011-12-01 20:21:04 +0000442 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
Howard Hinnantc51e1022010-05-11 19:42:16 +0000443 const unsigned char __doesnt_match = '\0';
444 const unsigned char __might_match = '\1';
445 const unsigned char __does_match = '\2';
446 unsigned char __statbuf[100];
447 unsigned char* __status = __statbuf;
448 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
449 if (__nkw > sizeof(__statbuf))
450 {
451 __status = (unsigned char*)malloc(__nkw);
452 if (__status == 0)
453 __throw_bad_alloc();
454 __stat_hold.reset(__status);
455 }
456 size_t __n_might_match = __nkw; // At this point, any keyword might match
457 size_t __n_does_match = 0; // but none of them definitely do
458 // Initialize all statuses to __might_match, except for "" keywords are __does_match
459 unsigned char* __st = __status;
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000460 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000461 {
462 if (!__ky->empty())
463 *__st = __might_match;
464 else
465 {
466 *__st = __does_match;
467 --__n_might_match;
468 ++__n_does_match;
469 }
470 }
471 // While there might be a match, test keywords against the next CharT
472 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
473 {
474 // Peek at the next CharT but don't consume it
475 _CharT __c = *__b;
476 if (!__case_sensitive)
477 __c = __ct.toupper(__c);
478 bool __consume = false;
479 // For each keyword which might match, see if the __indx character is __c
480 // If a match if found, consume __c
481 // If a match is found, and that is the last character in the keyword,
482 // then that keyword matches.
483 // If the keyword doesn't match this character, then change the keyword
484 // to doesn't match
485 __st = __status;
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000486 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000487 {
488 if (*__st == __might_match)
489 {
490 _CharT __kc = (*__ky)[__indx];
491 if (!__case_sensitive)
492 __kc = __ct.toupper(__kc);
493 if (__c == __kc)
494 {
495 __consume = true;
496 if (__ky->size() == __indx+1)
497 {
498 *__st = __does_match;
499 --__n_might_match;
500 ++__n_does_match;
501 }
502 }
503 else
504 {
505 *__st = __doesnt_match;
506 --__n_might_match;
507 }
508 }
509 }
510 // consume if we matched a character
511 if (__consume)
512 {
513 ++__b;
514 // If we consumed a character and there might be a matched keyword that
515 // was marked matched on a previous iteration, then such keywords
516 // which are now marked as not matching.
517 if (__n_might_match + __n_does_match > 1)
518 {
519 __st = __status;
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000520 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000521 {
522 if (*__st == __does_match && __ky->size() != __indx+1)
523 {
524 *__st = __doesnt_match;
525 --__n_does_match;
526 }
527 }
528 }
529 }
530 }
531 // We've exited the loop because we hit eof and/or we have no more "might matches".
532 if (__b == __e)
533 __err |= ios_base::eofbit;
534 // Return the first matching result
Eric Fiseliera09a3b42014-10-27 19:28:20 +0000535 for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000536 if (*__st == __does_match)
537 break;
538 if (__kb == __ke)
539 __err |= ios_base::failbit;
540 return __kb;
541}
542
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000543struct _LIBCPP_TYPE_VIS __num_get_base
Howard Hinnantc51e1022010-05-11 19:42:16 +0000544{
545 static const int __num_get_buf_sz = 40;
546
547 static int __get_base(ios_base&);
548 static const char __src[33];
549};
550
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000551_LIBCPP_FUNC_VIS
Howard Hinnantc51e1022010-05-11 19:42:16 +0000552void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
553 ios_base::iostate& __err);
554
Howard Hinnantc51e1022010-05-11 19:42:16 +0000555template <class _CharT>
556struct __num_get
557 : protected __num_get_base
558{
559 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
560 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
561 _CharT& __thousands_sep);
562 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
563 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
564 unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
565 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
566 char* __a, char*& __a_end,
567 _CharT __decimal_point, _CharT __thousands_sep,
568 const string& __grouping, unsigned* __g,
569 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
570};
571
572template <class _CharT>
573string
574__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
575{
576 locale __loc = __iob.getloc();
577 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
578 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
579 __thousands_sep = __np.thousands_sep();
580 return __np.grouping();
581}
582
583template <class _CharT>
584string
585__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
586 _CharT& __thousands_sep)
587{
588 locale __loc = __iob.getloc();
589 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
590 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
591 __decimal_point = __np.decimal_point();
592 __thousands_sep = __np.thousands_sep();
593 return __np.grouping();
594}
595
596template <class _CharT>
597int
598__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
599 unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
600 unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
601{
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000602 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
603 {
604 *__a_end++ = __ct == __atoms[24] ? '+' : '-';
605 __dc = 0;
606 return 0;
607 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000608 if (__grouping.size() != 0 && __ct == __thousands_sep)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000609 {
610 if (__g_end-__g < __num_get_buf_sz)
611 {
612 *__g_end++ = __dc;
613 __dc = 0;
614 }
615 return 0;
616 }
617 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000618 if (__f >= 24)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000619 return -1;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000620 switch (__base)
621 {
622 case 8:
623 case 10:
624 if (__f >= __base)
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000625 return -1;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000626 break;
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000627 case 16:
628 if (__f < 22)
629 break;
630 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
631 {
632 __dc = 0;
633 *__a_end++ = __src[__f];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000634 return 0;
Howard Hinnantf57b3fc2011-03-09 01:03:19 +0000635 }
636 return -1;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000637 }
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000638 *__a_end++ = __src[__f];
Howard Hinnantc51e1022010-05-11 19:42:16 +0000639 ++__dc;
640 return 0;
641}
642
643template <class _CharT>
644int
645__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
646 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
647 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
648{
649 if (__ct == __decimal_point)
650 {
651 if (!__in_units)
652 return -1;
653 __in_units = false;
654 *__a_end++ = '.';
655 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
656 *__g_end++ = __dc;
657 return 0;
658 }
659 if (__ct == __thousands_sep && __grouping.size() != 0)
660 {
661 if (!__in_units)
662 return -1;
663 if (__g_end-__g < __num_get_buf_sz)
664 {
665 *__g_end++ = __dc;
666 __dc = 0;
667 }
668 return 0;
669 }
670 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
671 if (__f >= 32)
672 return -1;
673 char __x = __src[__f];
Howard Hinnant5132e192012-02-15 19:19:37 +0000674 if (__x == '-' || __x == '+')
675 {
Howard Hinnant21413152013-03-08 19:06:24 +0000676 if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
Howard Hinnant5132e192012-02-15 19:19:37 +0000677 {
678 *__a_end++ = __x;
679 return 0;
680 }
681 return -1;
682 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000683 if (__x == 'x' || __x == 'X')
684 __exp = 'P';
Howard Hinnant21413152013-03-08 19:06:24 +0000685 else if ((__x & 0x5F) == __exp)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000686 {
Howard Hinnant21413152013-03-08 19:06:24 +0000687 __exp |= 0x80;
688 if (__in_units)
689 {
690 __in_units = false;
691 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
692 *__g_end++ = __dc;
693 }
Howard Hinnantc51e1022010-05-11 19:42:16 +0000694 }
Howard Hinnant5d4013d2013-04-15 20:40:06 +0000695 *__a_end++ = __x;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000696 if (__f >= 22)
697 return 0;
698 ++__dc;
699 return 0;
700}
701
Howard Hinnant8ea98242013-08-23 17:37:05 +0000702_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
703_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000704
705template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000706class _LIBCPP_TYPE_VIS_ONLY num_get
Howard Hinnantc51e1022010-05-11 19:42:16 +0000707 : public locale::facet,
708 private __num_get<_CharT>
709{
710public:
711 typedef _CharT char_type;
712 typedef _InputIterator iter_type;
713
714 _LIBCPP_ALWAYS_INLINE
715 explicit num_get(size_t __refs = 0)
716 : locale::facet(__refs) {}
717
718 _LIBCPP_ALWAYS_INLINE
719 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
720 ios_base::iostate& __err, bool& __v) const
721 {
722 return do_get(__b, __e, __iob, __err, __v);
723 }
724
725 _LIBCPP_ALWAYS_INLINE
726 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
727 ios_base::iostate& __err, long& __v) const
728 {
729 return do_get(__b, __e, __iob, __err, __v);
730 }
731
732 _LIBCPP_ALWAYS_INLINE
733 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
734 ios_base::iostate& __err, long long& __v) const
735 {
736 return do_get(__b, __e, __iob, __err, __v);
737 }
738
739 _LIBCPP_ALWAYS_INLINE
740 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
741 ios_base::iostate& __err, unsigned short& __v) const
742 {
743 return do_get(__b, __e, __iob, __err, __v);
744 }
745
746 _LIBCPP_ALWAYS_INLINE
747 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
748 ios_base::iostate& __err, unsigned int& __v) const
749 {
750 return do_get(__b, __e, __iob, __err, __v);
751 }
752
753 _LIBCPP_ALWAYS_INLINE
754 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
755 ios_base::iostate& __err, unsigned long& __v) const
756 {
757 return do_get(__b, __e, __iob, __err, __v);
758 }
759
760 _LIBCPP_ALWAYS_INLINE
761 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
762 ios_base::iostate& __err, unsigned long long& __v) const
763 {
764 return do_get(__b, __e, __iob, __err, __v);
765 }
766
767 _LIBCPP_ALWAYS_INLINE
768 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
769 ios_base::iostate& __err, float& __v) const
770 {
771 return do_get(__b, __e, __iob, __err, __v);
772 }
773
774 _LIBCPP_ALWAYS_INLINE
775 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
776 ios_base::iostate& __err, double& __v) const
777 {
778 return do_get(__b, __e, __iob, __err, __v);
779 }
780
781 _LIBCPP_ALWAYS_INLINE
782 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
783 ios_base::iostate& __err, long double& __v) const
784 {
785 return do_get(__b, __e, __iob, __err, __v);
786 }
787
788 _LIBCPP_ALWAYS_INLINE
789 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
790 ios_base::iostate& __err, void*& __v) const
791 {
792 return do_get(__b, __e, __iob, __err, __v);
793 }
794
795 static locale::id id;
796
797protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +0000798 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +0000799 ~num_get() {}
800
Marshall Clowae385382013-11-05 14:28:52 +0000801 template <class _Fp>
802 iter_type __do_get_floating_point
803 (iter_type __b, iter_type __e, ios_base& __iob,
804 ios_base::iostate& __err, _Fp& __v) const;
Marshall Clow96d86d82013-11-07 01:00:50 +0000805
806 template <class _Signed>
807 iter_type __do_get_signed
808 (iter_type __b, iter_type __e, ios_base& __iob,
809 ios_base::iostate& __err, _Signed& __v) const;
810
811 template <class _Unsigned>
812 iter_type __do_get_unsigned
813 (iter_type __b, iter_type __e, ios_base& __iob,
814 ios_base::iostate& __err, _Unsigned& __v) const;
815
816
817 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
818 ios_base::iostate& __err, bool& __v) const;
819
820 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
821 ios_base::iostate& __err, long& __v) const
822 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
823
824 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
825 ios_base::iostate& __err, long long& __v) const
826 { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
827
828 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
829 ios_base::iostate& __err, unsigned short& __v) const
830 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
831
832 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
833 ios_base::iostate& __err, unsigned int& __v) const
834 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
835
836 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
837 ios_base::iostate& __err, unsigned long& __v) const
838 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
839
840 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
841 ios_base::iostate& __err, unsigned long long& __v) const
842 { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
843
844 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
845 ios_base::iostate& __err, float& __v) const
846 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
847
848 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
849 ios_base::iostate& __err, double& __v) const
850 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
851
852 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
853 ios_base::iostate& __err, long double& __v) const
854 { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
855
856 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
857 ios_base::iostate& __err, void*& __v) const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000858};
859
860template <class _CharT, class _InputIterator>
861locale::id
862num_get<_CharT, _InputIterator>::id;
863
864template <class _Tp>
865_Tp
866__num_get_signed_integral(const char* __a, const char* __a_end,
867 ios_base::iostate& __err, int __base)
868{
869 if (__a != __a_end)
870 {
Howard Hinnantca8923c2013-01-22 17:26:08 +0000871 typename remove_reference<decltype(errno)>::type __save_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000872 errno = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000873 char *__p2;
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000874 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
Howard Hinnantca8923c2013-01-22 17:26:08 +0000875 typename remove_reference<decltype(errno)>::type __current_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000876 if (__current_errno == 0)
877 errno = __save_errno;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000878 if (__p2 != __a_end)
879 {
880 __err = ios_base::failbit;
881 return 0;
882 }
Howard Hinnant05c71342011-02-25 19:52:41 +0000883 else if (__current_errno == ERANGE ||
884 __ll < numeric_limits<_Tp>::min() ||
885 numeric_limits<_Tp>::max() < __ll)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000886 {
887 __err = ios_base::failbit;
Howard Hinnant05c71342011-02-25 19:52:41 +0000888 if (__ll > 0)
889 return numeric_limits<_Tp>::max();
890 else
891 return numeric_limits<_Tp>::min();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000892 }
893 return static_cast<_Tp>(__ll);
894 }
895 __err = ios_base::failbit;
896 return 0;
897}
898
899template <class _Tp>
900_Tp
901__num_get_unsigned_integral(const char* __a, const char* __a_end,
902 ios_base::iostate& __err, int __base)
903{
904 if (__a != __a_end)
905 {
Howard Hinnant05c71342011-02-25 19:52:41 +0000906 if (*__a == '-')
907 {
908 __err = ios_base::failbit;
909 return 0;
910 }
Howard Hinnantca8923c2013-01-22 17:26:08 +0000911 typename remove_reference<decltype(errno)>::type __save_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000912 errno = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000913 char *__p2;
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000914 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
Howard Hinnantca8923c2013-01-22 17:26:08 +0000915 typename remove_reference<decltype(errno)>::type __current_errno = errno;
Howard Hinnant05c71342011-02-25 19:52:41 +0000916 if (__current_errno == 0)
917 errno = __save_errno;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000918 if (__p2 != __a_end)
919 {
920 __err = ios_base::failbit;
921 return 0;
922 }
Howard Hinnant05c71342011-02-25 19:52:41 +0000923 else if (__current_errno == ERANGE ||
924 numeric_limits<_Tp>::max() < __ll)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000925 {
926 __err = ios_base::failbit;
927 return numeric_limits<_Tp>::max();
928 }
929 return static_cast<_Tp>(__ll);
930 }
931 __err = ios_base::failbit;
932 return 0;
933}
934
935template <class _Tp>
936_Tp
937__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
938{
939 if (__a != __a_end)
940 {
Howard Hinnantc9567812013-04-13 18:19:25 +0000941 typename remove_reference<decltype(errno)>::type __save_errno = errno;
942 errno = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000943 char *__p2;
Howard Hinnant1ab52da2011-09-28 21:05:01 +0000944 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
Howard Hinnantc9567812013-04-13 18:19:25 +0000945 typename remove_reference<decltype(errno)>::type __current_errno = errno;
946 if (__current_errno == 0)
947 errno = __save_errno;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000948 if (__p2 != __a_end)
949 {
950 __err = ios_base::failbit;
951 return 0;
952 }
Howard Hinnantc9567812013-04-13 18:19:25 +0000953 else if (__current_errno == ERANGE)
954 __err = ios_base::failbit;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000955 return static_cast<_Tp>(__ld);
956 }
957 __err = ios_base::failbit;
958 return 0;
959}
960
961template <class _CharT, class _InputIterator>
962_InputIterator
963num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
964 ios_base& __iob,
965 ios_base::iostate& __err,
966 bool& __v) const
967{
968 if ((__iob.flags() & ios_base::boolalpha) == 0)
969 {
970 long __lv = -1;
971 __b = do_get(__b, __e, __iob, __err, __lv);
972 switch (__lv)
973 {
974 case 0:
975 __v = false;
976 break;
977 case 1:
978 __v = true;
979 break;
980 default:
981 __v = true;
982 __err = ios_base::failbit;
983 break;
984 }
985 return __b;
986 }
987 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
988 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
989 typedef typename numpunct<_CharT>::string_type string_type;
990 const string_type __names[2] = {__np.truename(), __np.falsename()};
991 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
992 __ct, __err);
993 __v = __i == __names;
994 return __b;
995}
996
Marshall Clow96d86d82013-11-07 01:00:50 +0000997// signed
998
Howard Hinnantc51e1022010-05-11 19:42:16 +0000999template <class _CharT, class _InputIterator>
Marshall Clow96d86d82013-11-07 01:00:50 +00001000template <class _Signed>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001001_InputIterator
Marshall Clow96d86d82013-11-07 01:00:50 +00001002num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001003 ios_base& __iob,
1004 ios_base::iostate& __err,
Marshall Clow96d86d82013-11-07 01:00:50 +00001005 _Signed& __v) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001006{
1007 // Stage 1
1008 int __base = this->__get_base(__iob);
1009 // Stage 2
1010 char_type __atoms[26];
1011 char_type __thousands_sep;
1012 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001013 string __buf;
1014 __buf.resize(__buf.capacity());
1015 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +00001016 char* __a_end = __a;
1017 unsigned __g[__num_get_base::__num_get_buf_sz];
1018 unsigned* __g_end = __g;
1019 unsigned __dc = 0;
1020 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001021 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +00001022 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001023 {
1024 size_t __tmp = __buf.size();
1025 __buf.resize(2*__buf.size());
1026 __buf.resize(__buf.capacity());
1027 __a = &__buf[0];
1028 __a_end = __a + __tmp;
1029 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001030 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001031 __thousands_sep, __grouping, __g, __g_end,
1032 __atoms))
1033 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001034 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001035 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1036 *__g_end++ = __dc;
1037 // Stage 3
Marshall Clow96d86d82013-11-07 01:00:50 +00001038 __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001039 // Digit grouping checked
1040 __check_grouping(__grouping, __g, __g_end, __err);
1041 // EOF checked
1042 if (__b == __e)
1043 __err |= ios_base::eofbit;
1044 return __b;
1045}
1046
Marshall Clow96d86d82013-11-07 01:00:50 +00001047// unsigned
Howard Hinnantc51e1022010-05-11 19:42:16 +00001048
1049template <class _CharT, class _InputIterator>
Marshall Clow96d86d82013-11-07 01:00:50 +00001050template <class _Unsigned>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001051_InputIterator
Marshall Clow96d86d82013-11-07 01:00:50 +00001052num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001053 ios_base& __iob,
1054 ios_base::iostate& __err,
Marshall Clow96d86d82013-11-07 01:00:50 +00001055 _Unsigned& __v) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001056{
1057 // Stage 1
1058 int __base = this->__get_base(__iob);
1059 // Stage 2
1060 char_type __atoms[26];
1061 char_type __thousands_sep;
1062 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001063 string __buf;
1064 __buf.resize(__buf.capacity());
1065 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +00001066 char* __a_end = __a;
1067 unsigned __g[__num_get_base::__num_get_buf_sz];
1068 unsigned* __g_end = __g;
1069 unsigned __dc = 0;
1070 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001071 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +00001072 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001073 {
1074 size_t __tmp = __buf.size();
1075 __buf.resize(2*__buf.size());
1076 __buf.resize(__buf.capacity());
1077 __a = &__buf[0];
1078 __a_end = __a + __tmp;
1079 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001080 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001081 __thousands_sep, __grouping, __g, __g_end,
1082 __atoms))
1083 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001084 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001085 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1086 *__g_end++ = __dc;
1087 // Stage 3
Marshall Clow96d86d82013-11-07 01:00:50 +00001088 __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001089 // Digit grouping checked
1090 __check_grouping(__grouping, __g, __g_end, __err);
1091 // EOF checked
1092 if (__b == __e)
1093 __err |= ios_base::eofbit;
1094 return __b;
1095}
1096
Marshall Clowae385382013-11-05 14:28:52 +00001097// floating point
1098
Howard Hinnantc51e1022010-05-11 19:42:16 +00001099template <class _CharT, class _InputIterator>
Marshall Clowae385382013-11-05 14:28:52 +00001100template <class _Fp>
Howard Hinnantc51e1022010-05-11 19:42:16 +00001101_InputIterator
Marshall Clowae385382013-11-05 14:28:52 +00001102num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001103 ios_base& __iob,
1104 ios_base::iostate& __err,
Marshall Clowae385382013-11-05 14:28:52 +00001105 _Fp& __v) const
Howard Hinnantc51e1022010-05-11 19:42:16 +00001106{
1107 // Stage 1, nothing to do
1108 // Stage 2
1109 char_type __atoms[32];
1110 char_type __decimal_point;
1111 char_type __thousands_sep;
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001112 string __grouping = this->__stage2_float_prep(__iob, __atoms,
1113 __decimal_point,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001114 __thousands_sep);
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001115 string __buf;
1116 __buf.resize(__buf.capacity());
1117 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +00001118 char* __a_end = __a;
1119 unsigned __g[__num_get_base::__num_get_buf_sz];
1120 unsigned* __g_end = __g;
1121 unsigned __dc = 0;
1122 bool __in_units = true;
1123 char __exp = 'E';
1124 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001125 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +00001126 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001127 {
1128 size_t __tmp = __buf.size();
1129 __buf.resize(2*__buf.size());
1130 __buf.resize(__buf.capacity());
1131 __a = &__buf[0];
1132 __a_end = __a + __tmp;
1133 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001134 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1135 __decimal_point, __thousands_sep,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001136 __grouping, __g, __g_end,
1137 __dc, __atoms))
1138 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001139 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001140 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1141 *__g_end++ = __dc;
1142 // Stage 3
Marshall Clowae385382013-11-05 14:28:52 +00001143 __v = __num_get_float<_Fp>(__a, __a_end, __err);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001144 // Digit grouping checked
1145 __check_grouping(__grouping, __g, __g_end, __err);
1146 // EOF checked
1147 if (__b == __e)
1148 __err |= ios_base::eofbit;
1149 return __b;
1150}
1151
1152template <class _CharT, class _InputIterator>
1153_InputIterator
1154num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1155 ios_base& __iob,
1156 ios_base::iostate& __err,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001157 void*& __v) const
1158{
1159 // Stage 1
1160 int __base = 16;
1161 // Stage 2
1162 char_type __atoms[26];
Howard Hinnant28b24882011-12-01 20:21:04 +00001163 char_type __thousands_sep = 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001164 string __grouping;
1165 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1166 __num_get_base::__src + 26, __atoms);
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001167 string __buf;
1168 __buf.resize(__buf.capacity());
1169 char* __a = &__buf[0];
Howard Hinnantc51e1022010-05-11 19:42:16 +00001170 char* __a_end = __a;
1171 unsigned __g[__num_get_base::__num_get_buf_sz];
1172 unsigned* __g_end = __g;
1173 unsigned __dc = 0;
1174 for (; __b != __e; ++__b)
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001175 {
Joerg Sonnenberger7a804f62014-02-07 21:14:29 +00001176 if (__a_end == __a + __buf.size())
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001177 {
1178 size_t __tmp = __buf.size();
1179 __buf.resize(2*__buf.size());
1180 __buf.resize(__buf.capacity());
1181 __a = &__buf[0];
1182 __a_end = __a + __tmp;
1183 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00001184 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1185 __thousands_sep, __grouping,
Howard Hinnantc51e1022010-05-11 19:42:16 +00001186 __g, __g_end, __atoms))
1187 break;
Howard Hinnant5d4013d2013-04-15 20:40:06 +00001188 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001189 // Stage 3
Marshall Clow0db963d2014-05-21 16:02:20 +00001190 __buf.resize(__a_end - __a);
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001191#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Marshall Clow0db963d2014-05-21 16:02:20 +00001192 if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001193#else
Marshall Clow0db963d2014-05-21 16:02:20 +00001194 if (__sscanf_l(__buf.c_str(), __cloc(), "%p", &__v) != 1)
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001195#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001196 __err = ios_base::failbit;
1197 // EOF checked
1198 if (__b == __e)
1199 __err |= ios_base::eofbit;
1200 return __b;
1201}
1202
Howard Hinnant8ea98242013-08-23 17:37:05 +00001203_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
1204_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001205
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001206struct _LIBCPP_TYPE_VIS __num_put_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00001207{
1208protected:
1209 static void __format_int(char* __fmt, const char* __len, bool __signd,
1210 ios_base::fmtflags __flags);
1211 static bool __format_float(char* __fmt, const char* __len,
1212 ios_base::fmtflags __flags);
1213 static char* __identify_padding(char* __nb, char* __ne,
1214 const ios_base& __iob);
1215};
1216
1217template <class _CharT>
1218struct __num_put
1219 : protected __num_put_base
1220{
1221 static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1222 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1223 const locale& __loc);
1224 static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1225 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1226 const locale& __loc);
1227};
1228
1229template <class _CharT>
1230void
1231__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1232 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1233 const locale& __loc)
1234{
1235 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1236 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1237 string __grouping = __npt.grouping();
1238 if (__grouping.empty())
1239 {
1240 __ct.widen(__nb, __ne, __ob);
1241 __oe = __ob + (__ne - __nb);
1242 }
1243 else
1244 {
1245 __oe = __ob;
1246 char* __nf = __nb;
1247 if (*__nf == '-' || *__nf == '+')
1248 *__oe++ = __ct.widen(*__nf++);
1249 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1250 __nf[1] == 'X'))
1251 {
1252 *__oe++ = __ct.widen(*__nf++);
1253 *__oe++ = __ct.widen(*__nf++);
1254 }
1255 reverse(__nf, __ne);
1256 _CharT __thousands_sep = __npt.thousands_sep();
1257 unsigned __dc = 0;
1258 unsigned __dg = 0;
1259 for (char* __p = __nf; __p < __ne; ++__p)
1260 {
1261 if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1262 __dc == static_cast<unsigned>(__grouping[__dg]))
1263 {
1264 *__oe++ = __thousands_sep;
1265 __dc = 0;
1266 if (__dg < __grouping.size()-1)
1267 ++__dg;
1268 }
1269 *__oe++ = __ct.widen(*__p);
1270 ++__dc;
1271 }
1272 reverse(__ob + (__nf - __nb), __oe);
1273 }
1274 if (__np == __ne)
1275 __op = __oe;
1276 else
1277 __op = __ob + (__np - __nb);
1278}
1279
1280template <class _CharT>
1281void
1282__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1283 _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1284 const locale& __loc)
1285{
1286 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc);
1287 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1288 string __grouping = __npt.grouping();
1289 __oe = __ob;
1290 char* __nf = __nb;
1291 if (*__nf == '-' || *__nf == '+')
1292 *__oe++ = __ct.widen(*__nf++);
1293 char* __ns;
1294 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1295 __nf[1] == 'X'))
1296 {
1297 *__oe++ = __ct.widen(*__nf++);
1298 *__oe++ = __ct.widen(*__nf++);
1299 for (__ns = __nf; __ns < __ne; ++__ns)
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001300 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001301 break;
1302 }
1303 else
1304 {
1305 for (__ns = __nf; __ns < __ne; ++__ns)
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001306 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001307 break;
1308 }
1309 if (__grouping.empty())
1310 {
1311 __ct.widen(__nf, __ns, __oe);
1312 __oe += __ns - __nf;
1313 }
1314 else
1315 {
1316 reverse(__nf, __ns);
1317 _CharT __thousands_sep = __npt.thousands_sep();
1318 unsigned __dc = 0;
1319 unsigned __dg = 0;
1320 for (char* __p = __nf; __p < __ns; ++__p)
1321 {
1322 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1323 {
1324 *__oe++ = __thousands_sep;
1325 __dc = 0;
1326 if (__dg < __grouping.size()-1)
1327 ++__dg;
1328 }
1329 *__oe++ = __ct.widen(*__p);
1330 ++__dc;
1331 }
1332 reverse(__ob + (__nf - __nb), __oe);
1333 }
1334 for (__nf = __ns; __nf < __ne; ++__nf)
1335 {
1336 if (*__nf == '.')
1337 {
1338 *__oe++ = __npt.decimal_point();
1339 ++__nf;
1340 break;
1341 }
1342 else
1343 *__oe++ = __ct.widen(*__nf);
1344 }
1345 __ct.widen(__nf, __ne, __oe);
1346 __oe += __ne - __nf;
1347 if (__np == __ne)
1348 __op = __oe;
1349 else
1350 __op = __ob + (__np - __nb);
1351}
1352
Howard Hinnant8ea98242013-08-23 17:37:05 +00001353_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
1354_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001355
1356template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001357class _LIBCPP_TYPE_VIS_ONLY num_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00001358 : public locale::facet,
1359 private __num_put<_CharT>
1360{
1361public:
1362 typedef _CharT char_type;
1363 typedef _OutputIterator iter_type;
1364
1365 _LIBCPP_ALWAYS_INLINE
1366 explicit num_put(size_t __refs = 0)
1367 : locale::facet(__refs) {}
1368
1369 _LIBCPP_ALWAYS_INLINE
1370 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1371 bool __v) const
1372 {
1373 return do_put(__s, __iob, __fl, __v);
1374 }
1375
1376 _LIBCPP_ALWAYS_INLINE
1377 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1378 long __v) const
1379 {
1380 return do_put(__s, __iob, __fl, __v);
1381 }
1382
1383 _LIBCPP_ALWAYS_INLINE
1384 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1385 long long __v) const
1386 {
1387 return do_put(__s, __iob, __fl, __v);
1388 }
1389
1390 _LIBCPP_ALWAYS_INLINE
1391 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1392 unsigned long __v) const
1393 {
1394 return do_put(__s, __iob, __fl, __v);
1395 }
1396
1397 _LIBCPP_ALWAYS_INLINE
1398 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1399 unsigned long long __v) const
1400 {
1401 return do_put(__s, __iob, __fl, __v);
1402 }
1403
1404 _LIBCPP_ALWAYS_INLINE
1405 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1406 double __v) const
1407 {
1408 return do_put(__s, __iob, __fl, __v);
1409 }
1410
1411 _LIBCPP_ALWAYS_INLINE
1412 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1413 long double __v) const
1414 {
1415 return do_put(__s, __iob, __fl, __v);
1416 }
1417
1418 _LIBCPP_ALWAYS_INLINE
1419 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1420 const void* __v) const
1421 {
1422 return do_put(__s, __iob, __fl, __v);
1423 }
1424
1425 static locale::id id;
1426
1427protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00001428 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001429 ~num_put() {}
1430
1431 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1432 bool __v) const;
1433 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1434 long __v) const;
1435 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1436 long long __v) const;
1437 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1438 unsigned long) const;
1439 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1440 unsigned long long) const;
1441 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1442 double __v) const;
1443 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1444 long double __v) const;
1445 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1446 const void* __v) const;
1447};
1448
1449template <class _CharT, class _OutputIterator>
1450locale::id
1451num_put<_CharT, _OutputIterator>::id;
1452
1453template <class _CharT, class _OutputIterator>
1454_LIBCPP_HIDDEN
1455_OutputIterator
1456__pad_and_output(_OutputIterator __s,
1457 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1458 ios_base& __iob, _CharT __fl)
1459{
1460 streamsize __sz = __oe - __ob;
1461 streamsize __ns = __iob.width();
1462 if (__ns > __sz)
1463 __ns -= __sz;
1464 else
1465 __ns = 0;
1466 for (;__ob < __op; ++__ob, ++__s)
1467 *__s = *__ob;
1468 for (; __ns; --__ns, ++__s)
1469 *__s = __fl;
1470 for (; __ob < __oe; ++__ob, ++__s)
1471 *__s = *__ob;
1472 __iob.width(0);
1473 return __s;
1474}
1475
Howard Hinnant48fd5d52012-11-14 21:17:15 +00001476#if !defined(__APPLE__) || \
1477 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1478 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1479
Howard Hinnant97955172012-09-19 19:14:15 +00001480template <class _CharT, class _Traits>
1481_LIBCPP_HIDDEN
1482ostreambuf_iterator<_CharT, _Traits>
1483__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1484 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1485 ios_base& __iob, _CharT __fl)
1486{
1487 if (__s.__sbuf_ == nullptr)
1488 return __s;
1489 streamsize __sz = __oe - __ob;
1490 streamsize __ns = __iob.width();
1491 if (__ns > __sz)
1492 __ns -= __sz;
1493 else
1494 __ns = 0;
1495 streamsize __np = __op - __ob;
1496 if (__np > 0)
1497 {
1498 if (__s.__sbuf_->sputn(__ob, __np) != __np)
1499 {
1500 __s.__sbuf_ = nullptr;
1501 return __s;
1502 }
1503 }
1504 if (__ns > 0)
1505 {
1506 basic_string<_CharT, _Traits> __sp(__ns, __fl);
1507 if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1508 {
1509 __s.__sbuf_ = nullptr;
1510 return __s;
1511 }
1512 }
1513 __np = __oe - __op;
1514 if (__np > 0)
1515 {
1516 if (__s.__sbuf_->sputn(__op, __np) != __np)
1517 {
1518 __s.__sbuf_ = nullptr;
1519 return __s;
1520 }
1521 }
1522 __iob.width(0);
1523 return __s;
1524}
1525
Howard Hinnant48fd5d52012-11-14 21:17:15 +00001526#endif
1527
Howard Hinnantc51e1022010-05-11 19:42:16 +00001528template <class _CharT, class _OutputIterator>
1529_OutputIterator
1530num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1531 char_type __fl, bool __v) const
1532{
1533 if ((__iob.flags() & ios_base::boolalpha) == 0)
1534 return do_put(__s, __iob, __fl, (unsigned long)__v);
1535 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1536 typedef typename numpunct<char_type>::string_type string_type;
Howard Hinnant8ea98242013-08-23 17:37:05 +00001537#if _LIBCPP_DEBUG_LEVEL >= 2
1538 string_type __tmp(__v ? __np.truename() : __np.falsename());
1539 string_type __nm = _VSTD::move(__tmp);
1540#else
Howard Hinnantc51e1022010-05-11 19:42:16 +00001541 string_type __nm = __v ? __np.truename() : __np.falsename();
Howard Hinnant8ea98242013-08-23 17:37:05 +00001542#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001543 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1544 *__s = *__i;
1545 return __s;
1546}
1547
1548template <class _CharT, class _OutputIterator>
1549_OutputIterator
1550num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1551 char_type __fl, long __v) const
1552{
1553 // Stage 1 - Get number in narrow char
1554 char __fmt[6] = {'%', 0};
1555 const char* __len = "l";
1556 this->__format_int(__fmt+1, __len, true, __iob.flags());
1557 const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1558 + ((numeric_limits<long>::digits % 3) != 0)
1559 + 1;
1560 char __nar[__nbuf];
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001561#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001562 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001563#else
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001564 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001565#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001566 char* __ne = __nar + __nc;
1567 char* __np = this->__identify_padding(__nar, __ne, __iob);
1568 // Stage 2 - Widen __nar while adding thousands separators
1569 char_type __o[2*(__nbuf-1) - 1];
1570 char_type* __op; // pad here
1571 char_type* __oe; // end of output
1572 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1573 // [__o, __oe) contains thousands_sep'd wide number
1574 // Stage 3 & 4
1575 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1576}
1577
1578template <class _CharT, class _OutputIterator>
1579_OutputIterator
1580num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1581 char_type __fl, long long __v) const
1582{
1583 // Stage 1 - Get number in narrow char
1584 char __fmt[8] = {'%', 0};
1585 const char* __len = "ll";
1586 this->__format_int(__fmt+1, __len, true, __iob.flags());
1587 const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1588 + ((numeric_limits<long long>::digits % 3) != 0)
Marshall Clow7ac088f2015-01-26 17:24:52 +00001589 + 2;
Howard Hinnantc51e1022010-05-11 19:42:16 +00001590 char __nar[__nbuf];
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001591#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001592 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001593#else
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001594 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001595#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001596 char* __ne = __nar + __nc;
1597 char* __np = this->__identify_padding(__nar, __ne, __iob);
1598 // Stage 2 - Widen __nar while adding thousands separators
1599 char_type __o[2*(__nbuf-1) - 1];
1600 char_type* __op; // pad here
1601 char_type* __oe; // end of output
1602 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1603 // [__o, __oe) contains thousands_sep'd wide number
1604 // Stage 3 & 4
1605 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1606}
1607
1608template <class _CharT, class _OutputIterator>
1609_OutputIterator
1610num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1611 char_type __fl, unsigned long __v) const
1612{
1613 // Stage 1 - Get number in narrow char
1614 char __fmt[6] = {'%', 0};
1615 const char* __len = "l";
1616 this->__format_int(__fmt+1, __len, false, __iob.flags());
1617 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1618 + ((numeric_limits<unsigned long>::digits % 3) != 0)
1619 + 1;
1620 char __nar[__nbuf];
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001621#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001622 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001623#else
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001624 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001625#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001626 char* __ne = __nar + __nc;
1627 char* __np = this->__identify_padding(__nar, __ne, __iob);
1628 // Stage 2 - Widen __nar while adding thousands separators
1629 char_type __o[2*(__nbuf-1) - 1];
1630 char_type* __op; // pad here
1631 char_type* __oe; // end of output
1632 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1633 // [__o, __oe) contains thousands_sep'd wide number
1634 // Stage 3 & 4
1635 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1636}
1637
1638template <class _CharT, class _OutputIterator>
1639_OutputIterator
1640num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1641 char_type __fl, unsigned long long __v) const
1642{
1643 // Stage 1 - Get number in narrow char
1644 char __fmt[8] = {'%', 0};
1645 const char* __len = "ll";
1646 this->__format_int(__fmt+1, __len, false, __iob.flags());
1647 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1648 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1649 + 1;
1650 char __nar[__nbuf];
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001651#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001652 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001653#else
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001654 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001655#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001656 char* __ne = __nar + __nc;
1657 char* __np = this->__identify_padding(__nar, __ne, __iob);
1658 // Stage 2 - Widen __nar while adding thousands separators
1659 char_type __o[2*(__nbuf-1) - 1];
1660 char_type* __op; // pad here
1661 char_type* __oe; // end of output
1662 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1663 // [__o, __oe) contains thousands_sep'd wide number
1664 // Stage 3 & 4
1665 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1666}
1667
1668template <class _CharT, class _OutputIterator>
1669_OutputIterator
1670num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1671 char_type __fl, double __v) const
1672{
1673 // Stage 1 - Get number in narrow char
1674 char __fmt[8] = {'%', 0};
1675 const char* __len = "";
1676 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1677 const unsigned __nbuf = 30;
1678 char __nar[__nbuf];
1679 char* __nb = __nar;
1680 int __nc;
1681 if (__specify_precision)
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001682#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001683 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
Howard Hinnant155c2af2010-05-24 17:49:41 +00001684 (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001685#else
1686 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1687 (int)__iob.precision(), __v);
1688#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001689 else
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001690#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001691 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001692#else
1693 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1694#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001695 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1696 if (__nc > static_cast<int>(__nbuf-1))
1697 {
1698 if (__specify_precision)
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001699#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001700 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001701#else
1702 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
David Chisnall1d581062011-09-21 08:39:44 +00001703 (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001704#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001705 else
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001706#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001707 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001708#else
David Chisnall1d581062011-09-21 08:39:44 +00001709 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001710#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001711 if (__nb == 0)
1712 __throw_bad_alloc();
1713 __nbh.reset(__nb);
1714 }
1715 char* __ne = __nb + __nc;
1716 char* __np = this->__identify_padding(__nb, __ne, __iob);
1717 // Stage 2 - Widen __nar while adding thousands separators
1718 char_type __o[2*(__nbuf-1) - 1];
1719 char_type* __ob = __o;
1720 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1721 if (__nb != __nar)
1722 {
Howard Hinnant28b24882011-12-01 20:21:04 +00001723 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001724 if (__ob == 0)
1725 __throw_bad_alloc();
1726 __obh.reset(__ob);
1727 }
1728 char_type* __op; // pad here
1729 char_type* __oe; // end of output
1730 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1731 // [__o, __oe) contains thousands_sep'd wide number
1732 // Stage 3 & 4
1733 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1734 return __s;
1735}
1736
1737template <class _CharT, class _OutputIterator>
1738_OutputIterator
1739num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1740 char_type __fl, long double __v) const
1741{
1742 // Stage 1 - Get number in narrow char
1743 char __fmt[8] = {'%', 0};
1744 const char* __len = "L";
1745 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1746 const unsigned __nbuf = 30;
1747 char __nar[__nbuf];
1748 char* __nb = __nar;
1749 int __nc;
1750 if (__specify_precision)
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001751#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001752 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
Howard Hinnant155c2af2010-05-24 17:49:41 +00001753 (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001754#else
1755 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1756 (int)__iob.precision(), __v);
1757#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001758 else
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001759#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001760 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001761#else
1762 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1763#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001764 unique_ptr<char, void(*)(void*)> __nbh(0, free);
1765 if (__nc > static_cast<int>(__nbuf-1))
1766 {
1767 if (__specify_precision)
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001768#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001769 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001770#else
1771 __nc = __asprintf_l(&__nb, __cloc(), __fmt,
David Chisnall1d581062011-09-21 08:39:44 +00001772 (int)__iob.precision(), __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001773#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001774 else
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001775#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant1ab52da2011-09-28 21:05:01 +00001776 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001777#else
David Chisnall1d581062011-09-21 08:39:44 +00001778 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001779#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001780 if (__nb == 0)
1781 __throw_bad_alloc();
1782 __nbh.reset(__nb);
1783 }
1784 char* __ne = __nb + __nc;
1785 char* __np = this->__identify_padding(__nb, __ne, __iob);
1786 // Stage 2 - Widen __nar while adding thousands separators
1787 char_type __o[2*(__nbuf-1) - 1];
1788 char_type* __ob = __o;
1789 unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1790 if (__nb != __nar)
1791 {
Howard Hinnant28b24882011-12-01 20:21:04 +00001792 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001793 if (__ob == 0)
1794 __throw_bad_alloc();
1795 __obh.reset(__ob);
1796 }
1797 char_type* __op; // pad here
1798 char_type* __oe; // end of output
1799 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1800 // [__o, __oe) contains thousands_sep'd wide number
1801 // Stage 3 & 4
1802 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1803 return __s;
1804}
1805
1806template <class _CharT, class _OutputIterator>
1807_OutputIterator
1808num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1809 char_type __fl, const void* __v) const
1810{
1811 // Stage 1 - Get pointer in narrow char
1812 char __fmt[6] = "%p";
1813 const unsigned __nbuf = 20;
1814 char __nar[__nbuf];
Howard Hinnantf312e3e2011-09-28 23:39:33 +00001815#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001816 int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001817#else
Howard Hinnantb85f2ef2013-07-02 18:42:28 +00001818 int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00001819#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00001820 char* __ne = __nar + __nc;
1821 char* __np = this->__identify_padding(__nar, __ne, __iob);
1822 // Stage 2 - Widen __nar
1823 char_type __o[2*(__nbuf-1) - 1];
1824 char_type* __op; // pad here
1825 char_type* __oe; // end of output
1826 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1827 __ct.widen(__nar, __ne, __o);
1828 __oe = __o + (__ne - __nar);
1829 if (__np == __ne)
1830 __op = __oe;
1831 else
1832 __op = __o + (__np - __nar);
1833 // [__o, __oe) contains wide number
1834 // Stage 3 & 4
1835 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1836}
1837
Howard Hinnant8ea98242013-08-23 17:37:05 +00001838_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)
1839_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001840
1841template <class _CharT, class _InputIterator>
1842_LIBCPP_HIDDEN
1843int
1844__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1845 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1846{
1847 // Precondition: __n >= 1
1848 if (__b == __e)
1849 {
1850 __err |= ios_base::eofbit | ios_base::failbit;
1851 return 0;
1852 }
1853 // get first digit
1854 _CharT __c = *__b;
1855 if (!__ct.is(ctype_base::digit, __c))
1856 {
1857 __err |= ios_base::failbit;
1858 return 0;
1859 }
1860 int __r = __ct.narrow(__c, 0) - '0';
Eric Fiseliera09a3b42014-10-27 19:28:20 +00001861 for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001862 {
1863 // get next digit
1864 __c = *__b;
1865 if (!__ct.is(ctype_base::digit, __c))
1866 return __r;
1867 __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1868 }
1869 if (__b == __e)
1870 __err |= ios_base::eofbit;
1871 return __r;
1872}
1873
Howard Hinnant8331b762013-03-06 23:30:19 +00001874class _LIBCPP_TYPE_VIS time_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00001875{
1876public:
1877 enum dateorder {no_order, dmy, mdy, ymd, ydm};
1878};
1879
1880template <class _CharT>
Saleem Abdulrasoolfb32c5a2014-07-16 01:00:26 +00001881class _LIBCPP_TYPE_VIS_ONLY __time_get_c_storage
Howard Hinnantc51e1022010-05-11 19:42:16 +00001882{
1883protected:
1884 typedef basic_string<_CharT> string_type;
1885
1886 virtual const string_type* __weeks() const;
1887 virtual const string_type* __months() const;
1888 virtual const string_type* __am_pm() const;
1889 virtual const string_type& __c() const;
1890 virtual const string_type& __r() const;
1891 virtual const string_type& __x() const;
1892 virtual const string_type& __X() const;
1893};
1894
1895template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001896class _LIBCPP_TYPE_VIS_ONLY time_get
Howard Hinnantc51e1022010-05-11 19:42:16 +00001897 : public locale::facet,
1898 public time_base,
1899 private __time_get_c_storage<_CharT>
1900{
1901public:
1902 typedef _CharT char_type;
1903 typedef _InputIterator iter_type;
1904 typedef time_base::dateorder dateorder;
1905 typedef basic_string<char_type> string_type;
1906
1907 _LIBCPP_ALWAYS_INLINE
1908 explicit time_get(size_t __refs = 0)
1909 : locale::facet(__refs) {}
1910
1911 _LIBCPP_ALWAYS_INLINE
1912 dateorder date_order() const
1913 {
1914 return this->do_date_order();
1915 }
1916
1917 _LIBCPP_ALWAYS_INLINE
1918 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1919 ios_base::iostate& __err, tm* __tm) const
1920 {
1921 return do_get_time(__b, __e, __iob, __err, __tm);
1922 }
1923
1924 _LIBCPP_ALWAYS_INLINE
1925 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1926 ios_base::iostate& __err, tm* __tm) const
1927 {
1928 return do_get_date(__b, __e, __iob, __err, __tm);
1929 }
1930
1931 _LIBCPP_ALWAYS_INLINE
1932 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1933 ios_base::iostate& __err, tm* __tm) const
1934 {
1935 return do_get_weekday(__b, __e, __iob, __err, __tm);
1936 }
1937
1938 _LIBCPP_ALWAYS_INLINE
1939 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1940 ios_base::iostate& __err, tm* __tm) const
1941 {
1942 return do_get_monthname(__b, __e, __iob, __err, __tm);
1943 }
1944
1945 _LIBCPP_ALWAYS_INLINE
1946 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1947 ios_base::iostate& __err, tm* __tm) const
1948 {
1949 return do_get_year(__b, __e, __iob, __err, __tm);
1950 }
1951
1952 _LIBCPP_ALWAYS_INLINE
1953 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1954 ios_base::iostate& __err, tm *__tm,
1955 char __fmt, char __mod = 0) const
1956 {
1957 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1958 }
1959
1960 iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1961 ios_base::iostate& __err, tm* __tm,
1962 const char_type* __fmtb, const char_type* __fmte) const;
1963
1964 static locale::id id;
1965
1966protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00001967 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00001968 ~time_get() {}
1969
1970 virtual dateorder do_date_order() const;
1971 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1972 ios_base::iostate& __err, tm* __tm) const;
1973 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1974 ios_base::iostate& __err, tm* __tm) const;
1975 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1976 ios_base::iostate& __err, tm* __tm) const;
1977 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1978 ios_base::iostate& __err, tm* __tm) const;
1979 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1980 ios_base::iostate& __err, tm* __tm) const;
1981 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1982 ios_base::iostate& __err, tm* __tm,
1983 char __fmt, char __mod) const;
1984private:
1985 void __get_white_space(iter_type& __b, iter_type __e,
1986 ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1987 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1988 const ctype<char_type>& __ct) const;
1989
1990 void __get_weekdayname(int& __m,
1991 iter_type& __b, iter_type __e,
1992 ios_base::iostate& __err,
1993 const ctype<char_type>& __ct) const;
1994 void __get_monthname(int& __m,
1995 iter_type& __b, iter_type __e,
1996 ios_base::iostate& __err,
1997 const ctype<char_type>& __ct) const;
1998 void __get_day(int& __d,
1999 iter_type& __b, iter_type __e,
2000 ios_base::iostate& __err,
2001 const ctype<char_type>& __ct) const;
2002 void __get_month(int& __m,
2003 iter_type& __b, iter_type __e,
2004 ios_base::iostate& __err,
2005 const ctype<char_type>& __ct) const;
2006 void __get_year(int& __y,
2007 iter_type& __b, iter_type __e,
2008 ios_base::iostate& __err,
2009 const ctype<char_type>& __ct) const;
2010 void __get_year4(int& __y,
2011 iter_type& __b, iter_type __e,
2012 ios_base::iostate& __err,
2013 const ctype<char_type>& __ct) const;
2014 void __get_hour(int& __d,
2015 iter_type& __b, iter_type __e,
2016 ios_base::iostate& __err,
2017 const ctype<char_type>& __ct) const;
2018 void __get_12_hour(int& __h,
2019 iter_type& __b, iter_type __e,
2020 ios_base::iostate& __err,
2021 const ctype<char_type>& __ct) const;
2022 void __get_am_pm(int& __h,
2023 iter_type& __b, iter_type __e,
2024 ios_base::iostate& __err,
2025 const ctype<char_type>& __ct) const;
2026 void __get_minute(int& __m,
2027 iter_type& __b, iter_type __e,
2028 ios_base::iostate& __err,
2029 const ctype<char_type>& __ct) const;
2030 void __get_second(int& __s,
2031 iter_type& __b, iter_type __e,
2032 ios_base::iostate& __err,
2033 const ctype<char_type>& __ct) const;
2034 void __get_weekday(int& __w,
2035 iter_type& __b, iter_type __e,
2036 ios_base::iostate& __err,
2037 const ctype<char_type>& __ct) const;
2038 void __get_day_year_num(int& __w,
2039 iter_type& __b, iter_type __e,
2040 ios_base::iostate& __err,
2041 const ctype<char_type>& __ct) const;
2042};
2043
2044template <class _CharT, class _InputIterator>
2045locale::id
2046time_get<_CharT, _InputIterator>::id;
2047
Alp Tokerb8a95f52014-05-15 11:27:39 +00002048// time_get primitives
Howard Hinnantc51e1022010-05-11 19:42:16 +00002049
2050template <class _CharT, class _InputIterator>
2051void
2052time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2053 iter_type& __b, iter_type __e,
2054 ios_base::iostate& __err,
2055 const ctype<char_type>& __ct) const
2056{
2057 // Note: ignoring case comes from the POSIX strptime spec
2058 const string_type* __wk = this->__weeks();
Howard Hinnant28b24882011-12-01 20:21:04 +00002059 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002060 if (__i < 14)
2061 __w = __i % 7;
2062}
2063
2064template <class _CharT, class _InputIterator>
2065void
2066time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2067 iter_type& __b, iter_type __e,
2068 ios_base::iostate& __err,
2069 const ctype<char_type>& __ct) const
2070{
2071 // Note: ignoring case comes from the POSIX strptime spec
2072 const string_type* __month = this->__months();
Howard Hinnant28b24882011-12-01 20:21:04 +00002073 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002074 if (__i < 24)
2075 __m = __i % 12;
2076}
2077
2078template <class _CharT, class _InputIterator>
2079void
2080time_get<_CharT, _InputIterator>::__get_day(int& __d,
2081 iter_type& __b, iter_type __e,
2082 ios_base::iostate& __err,
2083 const ctype<char_type>& __ct) const
2084{
2085 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2086 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
2087 __d = __t;
2088 else
2089 __err |= ios_base::failbit;
2090}
2091
2092template <class _CharT, class _InputIterator>
2093void
2094time_get<_CharT, _InputIterator>::__get_month(int& __m,
2095 iter_type& __b, iter_type __e,
2096 ios_base::iostate& __err,
2097 const ctype<char_type>& __ct) const
2098{
2099 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
2100 if (!(__err & ios_base::failbit) && __t <= 11)
2101 __m = __t;
2102 else
2103 __err |= ios_base::failbit;
2104}
2105
2106template <class _CharT, class _InputIterator>
2107void
2108time_get<_CharT, _InputIterator>::__get_year(int& __y,
2109 iter_type& __b, iter_type __e,
2110 ios_base::iostate& __err,
2111 const ctype<char_type>& __ct) const
2112{
2113 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2114 if (!(__err & ios_base::failbit))
2115 {
2116 if (__t < 69)
2117 __t += 2000;
2118 else if (69 <= __t && __t <= 99)
2119 __t += 1900;
2120 __y = __t - 1900;
2121 }
2122}
2123
2124template <class _CharT, class _InputIterator>
2125void
2126time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2127 iter_type& __b, iter_type __e,
2128 ios_base::iostate& __err,
2129 const ctype<char_type>& __ct) const
2130{
2131 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2132 if (!(__err & ios_base::failbit))
2133 __y = __t - 1900;
2134}
2135
2136template <class _CharT, class _InputIterator>
2137void
2138time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2139 iter_type& __b, iter_type __e,
2140 ios_base::iostate& __err,
2141 const ctype<char_type>& __ct) const
2142{
2143 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2144 if (!(__err & ios_base::failbit) && __t <= 23)
2145 __h = __t;
2146 else
2147 __err |= ios_base::failbit;
2148}
2149
2150template <class _CharT, class _InputIterator>
2151void
2152time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2153 iter_type& __b, iter_type __e,
2154 ios_base::iostate& __err,
2155 const ctype<char_type>& __ct) const
2156{
2157 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2158 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2159 __h = __t;
2160 else
2161 __err |= ios_base::failbit;
2162}
2163
2164template <class _CharT, class _InputIterator>
2165void
2166time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2167 iter_type& __b, iter_type __e,
2168 ios_base::iostate& __err,
2169 const ctype<char_type>& __ct) const
2170{
2171 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2172 if (!(__err & ios_base::failbit) && __t <= 59)
2173 __m = __t;
2174 else
2175 __err |= ios_base::failbit;
2176}
2177
2178template <class _CharT, class _InputIterator>
2179void
2180time_get<_CharT, _InputIterator>::__get_second(int& __s,
2181 iter_type& __b, iter_type __e,
2182 ios_base::iostate& __err,
2183 const ctype<char_type>& __ct) const
2184{
2185 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2186 if (!(__err & ios_base::failbit) && __t <= 60)
2187 __s = __t;
2188 else
2189 __err |= ios_base::failbit;
2190}
2191
2192template <class _CharT, class _InputIterator>
2193void
2194time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2195 iter_type& __b, iter_type __e,
2196 ios_base::iostate& __err,
2197 const ctype<char_type>& __ct) const
2198{
2199 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2200 if (!(__err & ios_base::failbit) && __t <= 6)
2201 __w = __t;
2202 else
2203 __err |= ios_base::failbit;
2204}
2205
2206template <class _CharT, class _InputIterator>
2207void
2208time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2209 iter_type& __b, iter_type __e,
2210 ios_base::iostate& __err,
2211 const ctype<char_type>& __ct) const
2212{
2213 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2214 if (!(__err & ios_base::failbit) && __t <= 365)
2215 __d = __t;
2216 else
2217 __err |= ios_base::failbit;
2218}
2219
2220template <class _CharT, class _InputIterator>
2221void
2222time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2223 ios_base::iostate& __err,
2224 const ctype<char_type>& __ct) const
2225{
2226 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2227 ;
2228 if (__b == __e)
2229 __err |= ios_base::eofbit;
2230}
2231
2232template <class _CharT, class _InputIterator>
2233void
2234time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2235 iter_type& __b, iter_type __e,
2236 ios_base::iostate& __err,
2237 const ctype<char_type>& __ct) const
2238{
2239 const string_type* __ap = this->__am_pm();
2240 if (__ap[0].size() + __ap[1].size() == 0)
2241 {
2242 __err |= ios_base::failbit;
2243 return;
2244 }
Howard Hinnant28b24882011-12-01 20:21:04 +00002245 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002246 if (__i == 0 && __h == 12)
2247 __h = 0;
2248 else if (__i == 1 && __h < 12)
2249 __h += 12;
2250}
2251
2252template <class _CharT, class _InputIterator>
2253void
2254time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2255 ios_base::iostate& __err,
2256 const ctype<char_type>& __ct) const
2257{
2258 if (__b == __e)
2259 {
2260 __err |= ios_base::eofbit | ios_base::failbit;
2261 return;
2262 }
2263 if (__ct.narrow(*__b, 0) != '%')
2264 __err |= ios_base::failbit;
2265 else if(++__b == __e)
2266 __err |= ios_base::eofbit;
2267}
2268
Alp Tokerb8a95f52014-05-15 11:27:39 +00002269// time_get end primitives
Howard Hinnantc51e1022010-05-11 19:42:16 +00002270
2271template <class _CharT, class _InputIterator>
2272_InputIterator
2273time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2274 ios_base& __iob,
2275 ios_base::iostate& __err, tm* __tm,
2276 const char_type* __fmtb, const char_type* __fmte) const
2277{
2278 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2279 __err = ios_base::goodbit;
2280 while (__fmtb != __fmte && __err == ios_base::goodbit)
2281 {
2282 if (__b == __e)
2283 {
2284 __err = ios_base::failbit;
2285 break;
2286 }
2287 if (__ct.narrow(*__fmtb, 0) == '%')
2288 {
2289 if (++__fmtb == __fmte)
2290 {
2291 __err = ios_base::failbit;
2292 break;
2293 }
2294 char __cmd = __ct.narrow(*__fmtb, 0);
2295 char __opt = '\0';
2296 if (__cmd == 'E' || __cmd == '0')
2297 {
2298 if (++__fmtb == __fmte)
2299 {
2300 __err = ios_base::failbit;
2301 break;
2302 }
2303 __opt = __cmd;
2304 __cmd = __ct.narrow(*__fmtb, 0);
2305 }
2306 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2307 ++__fmtb;
2308 }
2309 else if (__ct.is(ctype_base::space, *__fmtb))
2310 {
2311 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2312 ;
2313 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2314 ;
2315 }
2316 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2317 {
2318 ++__b;
2319 ++__fmtb;
2320 }
2321 else
2322 __err = ios_base::failbit;
2323 }
2324 if (__b == __e)
2325 __err |= ios_base::eofbit;
2326 return __b;
2327}
2328
2329template <class _CharT, class _InputIterator>
2330typename time_get<_CharT, _InputIterator>::dateorder
2331time_get<_CharT, _InputIterator>::do_date_order() const
2332{
2333 return mdy;
2334}
2335
2336template <class _CharT, class _InputIterator>
2337_InputIterator
2338time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2339 ios_base& __iob,
2340 ios_base::iostate& __err,
2341 tm* __tm) const
2342{
2343 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2344 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2345}
2346
2347template <class _CharT, class _InputIterator>
2348_InputIterator
2349time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2350 ios_base& __iob,
2351 ios_base::iostate& __err,
2352 tm* __tm) const
2353{
Howard Hinnantc51e1022010-05-11 19:42:16 +00002354 const string_type& __fmt = this->__x();
2355 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2356}
2357
2358template <class _CharT, class _InputIterator>
2359_InputIterator
2360time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2361 ios_base& __iob,
2362 ios_base::iostate& __err,
2363 tm* __tm) const
2364{
2365 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2366 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2367 return __b;
2368}
2369
2370template <class _CharT, class _InputIterator>
2371_InputIterator
2372time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2373 ios_base& __iob,
2374 ios_base::iostate& __err,
2375 tm* __tm) const
2376{
2377 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2378 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2379 return __b;
2380}
2381
2382template <class _CharT, class _InputIterator>
2383_InputIterator
2384time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2385 ios_base& __iob,
2386 ios_base::iostate& __err,
2387 tm* __tm) const
2388{
2389 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2390 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2391 return __b;
2392}
2393
2394template <class _CharT, class _InputIterator>
2395_InputIterator
2396time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2397 ios_base& __iob,
2398 ios_base::iostate& __err, tm* __tm,
2399 char __fmt, char) const
2400{
2401 __err = ios_base::goodbit;
2402 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2403 switch (__fmt)
2404 {
2405 case 'a':
2406 case 'A':
2407 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2408 break;
2409 case 'b':
2410 case 'B':
2411 case 'h':
2412 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2413 break;
2414 case 'c':
2415 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002416 const string_type& __fm = this->__c();
2417 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002418 }
2419 break;
2420 case 'd':
2421 case 'e':
2422 __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2423 break;
2424 case 'D':
2425 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002426 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2427 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002428 }
2429 break;
Howard Hinnantf60ff4e2011-04-10 17:54:14 +00002430 case 'F':
2431 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002432 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2433 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantf60ff4e2011-04-10 17:54:14 +00002434 }
2435 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +00002436 case 'H':
2437 __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2438 break;
2439 case 'I':
2440 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2441 break;
2442 case 'j':
2443 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2444 break;
2445 case 'm':
2446 __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2447 break;
2448 case 'M':
2449 __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2450 break;
2451 case 'n':
2452 case 't':
2453 __get_white_space(__b, __e, __err, __ct);
2454 break;
2455 case 'p':
2456 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2457 break;
2458 case 'r':
2459 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002460 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2461 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002462 }
2463 break;
2464 case 'R':
2465 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002466 const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2467 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002468 }
2469 break;
2470 case 'S':
2471 __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2472 break;
2473 case 'T':
2474 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002475 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2476 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
Howard Hinnantc51e1022010-05-11 19:42:16 +00002477 }
2478 break;
2479 case 'w':
2480 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2481 break;
2482 case 'x':
2483 return do_get_date(__b, __e, __iob, __err, __tm);
2484 case 'X':
2485 {
Howard Hinnant28b24882011-12-01 20:21:04 +00002486 const string_type& __fm = this->__X();
2487 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002488 }
2489 break;
2490 case 'y':
2491 __get_year(__tm->tm_year, __b, __e, __err, __ct);
2492 break;
2493 case 'Y':
2494 __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2495 break;
2496 case '%':
2497 __get_percent(__b, __e, __err, __ct);
2498 break;
2499 default:
2500 __err |= ios_base::failbit;
2501 }
2502 return __b;
2503}
2504
Howard Hinnant8ea98242013-08-23 17:37:05 +00002505_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
2506_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002507
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002508class _LIBCPP_TYPE_VIS __time_get
Howard Hinnantc51e1022010-05-11 19:42:16 +00002509{
2510protected:
2511 locale_t __loc_;
2512
2513 __time_get(const char* __nm);
2514 __time_get(const string& __nm);
2515 ~__time_get();
2516};
2517
2518template <class _CharT>
Saleem Abdulrasoolfb32c5a2014-07-16 01:00:26 +00002519class _LIBCPP_TYPE_VIS_ONLY __time_get_storage
Howard Hinnantc51e1022010-05-11 19:42:16 +00002520 : public __time_get
2521{
2522protected:
2523 typedef basic_string<_CharT> string_type;
2524
2525 string_type __weeks_[14];
2526 string_type __months_[24];
2527 string_type __am_pm_[2];
2528 string_type __c_;
2529 string_type __r_;
2530 string_type __x_;
2531 string_type __X_;
2532
2533 explicit __time_get_storage(const char* __nm);
2534 explicit __time_get_storage(const string& __nm);
2535
2536 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2537
2538 time_base::dateorder __do_date_order() const;
2539
2540private:
2541 void init(const ctype<_CharT>&);
2542 string_type __analyze(char __fmt, const ctype<_CharT>&);
2543};
2544
2545template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002546class _LIBCPP_TYPE_VIS_ONLY time_get_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00002547 : public time_get<_CharT, _InputIterator>,
2548 private __time_get_storage<_CharT>
2549{
2550public:
2551 typedef time_base::dateorder dateorder;
2552 typedef _InputIterator iter_type;
2553 typedef _CharT char_type;
2554 typedef basic_string<char_type> string_type;
2555
Howard Hinnant756c69b2010-09-22 16:48:34 +00002556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002557 explicit time_get_byname(const char* __nm, size_t __refs = 0)
2558 : time_get<_CharT, _InputIterator>(__refs),
2559 __time_get_storage<_CharT>(__nm) {}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002561 explicit time_get_byname(const string& __nm, size_t __refs = 0)
2562 : time_get<_CharT, _InputIterator>(__refs),
2563 __time_get_storage<_CharT>(__nm) {}
2564
2565protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002567 ~time_get_byname() {}
2568
Howard Hinnant756c69b2010-09-22 16:48:34 +00002569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002570 virtual dateorder do_date_order() const {return this->__do_date_order();}
2571private:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002572 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002573 virtual const string_type* __weeks() const {return this->__weeks_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002575 virtual const string_type* __months() const {return this->__months_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002577 virtual const string_type* __am_pm() const {return this->__am_pm_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002578 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002579 virtual const string_type& __c() const {return this->__c_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002580 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002581 virtual const string_type& __r() const {return this->__r_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002583 virtual const string_type& __x() const {return this->__x_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc51e1022010-05-11 19:42:16 +00002585 virtual const string_type& __X() const {return this->__X_;}
2586};
2587
Howard Hinnant8ea98242013-08-23 17:37:05 +00002588_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
2589_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002590
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002591class _LIBCPP_TYPE_VIS __time_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00002592{
2593 locale_t __loc_;
2594protected:
Howard Hinnant1ab52da2011-09-28 21:05:01 +00002595 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002596 __time_put(const char* __nm);
2597 __time_put(const string& __nm);
2598 ~__time_put();
2599 void __do_put(char* __nb, char*& __ne, const tm* __tm,
2600 char __fmt, char __mod) const;
2601 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2602 char __fmt, char __mod) const;
2603};
2604
2605template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002606class _LIBCPP_TYPE_VIS_ONLY time_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00002607 : public locale::facet,
2608 private __time_put
2609{
2610public:
2611 typedef _CharT char_type;
2612 typedef _OutputIterator iter_type;
2613
2614 _LIBCPP_ALWAYS_INLINE
2615 explicit time_put(size_t __refs = 0)
2616 : locale::facet(__refs) {}
2617
2618 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2619 const char_type* __pb, const char_type* __pe) const;
2620
2621 _LIBCPP_ALWAYS_INLINE
2622 iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2623 const tm* __tm, char __fmt, char __mod = 0) const
2624 {
2625 return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2626 }
2627
2628 static locale::id id;
2629
2630protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002631 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002632 ~time_put() {}
2633 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2634 char __fmt, char __mod) const;
2635
Howard Hinnant756c69b2010-09-22 16:48:34 +00002636 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002637 explicit time_put(const char* __nm, size_t __refs)
2638 : locale::facet(__refs),
2639 __time_put(__nm) {}
Howard Hinnant756c69b2010-09-22 16:48:34 +00002640 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002641 explicit time_put(const string& __nm, size_t __refs)
2642 : locale::facet(__refs),
2643 __time_put(__nm) {}
2644};
2645
2646template <class _CharT, class _OutputIterator>
2647locale::id
2648time_put<_CharT, _OutputIterator>::id;
2649
2650template <class _CharT, class _OutputIterator>
2651_OutputIterator
2652time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2653 char_type __fl, const tm* __tm,
2654 const char_type* __pb,
2655 const char_type* __pe) const
2656{
2657 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2658 for (; __pb != __pe; ++__pb)
2659 {
2660 if (__ct.narrow(*__pb, 0) == '%')
2661 {
2662 if (++__pb == __pe)
2663 {
2664 *__s++ = __pb[-1];
2665 break;
2666 }
2667 char __mod = 0;
2668 char __fmt = __ct.narrow(*__pb, 0);
2669 if (__fmt == 'E' || __fmt == 'O')
2670 {
2671 if (++__pb == __pe)
2672 {
2673 *__s++ = __pb[-2];
2674 *__s++ = __pb[-1];
2675 break;
2676 }
2677 __mod = __fmt;
2678 __fmt = __ct.narrow(*__pb, 0);
2679 }
2680 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2681 }
2682 else
2683 *__s++ = *__pb;
2684 }
2685 return __s;
2686}
2687
2688template <class _CharT, class _OutputIterator>
2689_OutputIterator
Howard Hinnant28b24882011-12-01 20:21:04 +00002690time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
Howard Hinnantc51e1022010-05-11 19:42:16 +00002691 char_type, const tm* __tm,
2692 char __fmt, char __mod) const
2693{
2694 char_type __nar[100];
2695 char_type* __nb = __nar;
2696 char_type* __ne = __nb + 100;
2697 __do_put(__nb, __ne, __tm, __fmt, __mod);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002698 return _VSTD::copy(__nb, __ne, __s);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002699}
2700
Howard Hinnant8ea98242013-08-23 17:37:05 +00002701_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
2702_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002703
2704template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002705class _LIBCPP_TYPE_VIS_ONLY time_put_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00002706 : public time_put<_CharT, _OutputIterator>
2707{
2708public:
2709 _LIBCPP_ALWAYS_INLINE
2710 explicit time_put_byname(const char* __nm, size_t __refs = 0)
2711 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2712
2713 _LIBCPP_ALWAYS_INLINE
2714 explicit time_put_byname(const string& __nm, size_t __refs = 0)
2715 : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2716
2717protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002718 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002719 ~time_put_byname() {}
2720};
2721
Howard Hinnant8ea98242013-08-23 17:37:05 +00002722_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
2723_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002724
2725// money_base
2726
Howard Hinnant8331b762013-03-06 23:30:19 +00002727class _LIBCPP_TYPE_VIS money_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00002728{
2729public:
2730 enum part {none, space, symbol, sign, value};
2731 struct pattern {char field[4];};
2732
2733 _LIBCPP_ALWAYS_INLINE money_base() {}
2734};
2735
2736// moneypunct
2737
2738template <class _CharT, bool _International = false>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002739class _LIBCPP_TYPE_VIS_ONLY moneypunct
Howard Hinnantc51e1022010-05-11 19:42:16 +00002740 : public locale::facet,
2741 public money_base
2742{
2743public:
2744 typedef _CharT char_type;
2745 typedef basic_string<char_type> string_type;
2746
Howard Hinnant756c69b2010-09-22 16:48:34 +00002747 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002748 explicit moneypunct(size_t __refs = 0)
2749 : locale::facet(__refs) {}
2750
2751 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
2752 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
2753 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();}
2754 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();}
2755 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2756 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2757 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();}
2758 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();}
2759 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();}
2760
2761 static locale::id id;
2762 static const bool intl = _International;
2763
2764protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002765 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002766 ~moneypunct() {}
2767
2768 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();}
2769 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();}
2770 virtual string do_grouping() const {return string();}
2771 virtual string_type do_curr_symbol() const {return string_type();}
2772 virtual string_type do_positive_sign() const {return string_type();}
2773 virtual string_type do_negative_sign() const {return string_type(1, '-');}
2774 virtual int do_frac_digits() const {return 0;}
2775 virtual pattern do_pos_format() const
Howard Hinnantb10e6cf2012-11-06 21:48:33 +00002776 {pattern __p = {{symbol, sign, none, value}}; return __p;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002777 virtual pattern do_neg_format() const
Howard Hinnantb10e6cf2012-11-06 21:48:33 +00002778 {pattern __p = {{symbol, sign, none, value}}; return __p;}
Howard Hinnantc51e1022010-05-11 19:42:16 +00002779};
2780
2781template <class _CharT, bool _International>
2782locale::id
2783moneypunct<_CharT, _International>::id;
2784
Howard Hinnant2c45cb42012-12-12 21:14:28 +00002785template <class _CharT, bool _International>
2786const bool
2787moneypunct<_CharT, _International>::intl;
2788
Howard Hinnant8ea98242013-08-23 17:37:05 +00002789_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
2790_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
2791_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
2792_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002793
2794// moneypunct_byname
2795
2796template <class _CharT, bool _International = false>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002797class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname
Howard Hinnant756c69b2010-09-22 16:48:34 +00002798 : public moneypunct<_CharT, _International>
Howard Hinnantc51e1022010-05-11 19:42:16 +00002799{
2800public:
2801 typedef money_base::pattern pattern;
2802 typedef _CharT char_type;
2803 typedef basic_string<char_type> string_type;
2804
2805 _LIBCPP_ALWAYS_INLINE
2806 explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2807 : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2808
2809 _LIBCPP_ALWAYS_INLINE
2810 explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2811 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2812
2813protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00002814 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002815 ~moneypunct_byname() {}
2816
2817 virtual char_type do_decimal_point() const {return __decimal_point_;}
2818 virtual char_type do_thousands_sep() const {return __thousands_sep_;}
2819 virtual string do_grouping() const {return __grouping_;}
2820 virtual string_type do_curr_symbol() const {return __curr_symbol_;}
2821 virtual string_type do_positive_sign() const {return __positive_sign_;}
2822 virtual string_type do_negative_sign() const {return __negative_sign_;}
2823 virtual int do_frac_digits() const {return __frac_digits_;}
2824 virtual pattern do_pos_format() const {return __pos_format_;}
2825 virtual pattern do_neg_format() const {return __neg_format_;}
2826
2827private:
2828 char_type __decimal_point_;
2829 char_type __thousands_sep_;
2830 string __grouping_;
2831 string_type __curr_symbol_;
2832 string_type __positive_sign_;
2833 string_type __negative_sign_;
2834 int __frac_digits_;
2835 pattern __pos_format_;
2836 pattern __neg_format_;
2837
2838 void init(const char*);
2839};
2840
2841template<> void moneypunct_byname<char, false>::init(const char*);
2842template<> void moneypunct_byname<char, true>::init(const char*);
2843template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2844template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2845
Howard Hinnant8ea98242013-08-23 17:37:05 +00002846_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
2847_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
2848_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
2849_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002850
2851// money_get
2852
2853template <class _CharT>
2854class __money_get
2855{
2856protected:
2857 typedef _CharT char_type;
2858 typedef basic_string<char_type> string_type;
2859
2860 _LIBCPP_ALWAYS_INLINE __money_get() {}
2861
2862 static void __gather_info(bool __intl, const locale& __loc,
2863 money_base::pattern& __pat, char_type& __dp,
2864 char_type& __ts, string& __grp,
2865 string_type& __sym, string_type& __psn,
2866 string_type& __nsn, int& __fd);
2867};
2868
2869template <class _CharT>
2870void
2871__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2872 money_base::pattern& __pat, char_type& __dp,
2873 char_type& __ts, string& __grp,
2874 string_type& __sym, string_type& __psn,
2875 string_type& __nsn, int& __fd)
2876{
2877 if (__intl)
2878 {
2879 const moneypunct<char_type, true>& __mp =
2880 use_facet<moneypunct<char_type, true> >(__loc);
2881 __pat = __mp.neg_format();
2882 __nsn = __mp.negative_sign();
2883 __psn = __mp.positive_sign();
2884 __dp = __mp.decimal_point();
2885 __ts = __mp.thousands_sep();
2886 __grp = __mp.grouping();
2887 __sym = __mp.curr_symbol();
2888 __fd = __mp.frac_digits();
2889 }
2890 else
2891 {
2892 const moneypunct<char_type, false>& __mp =
2893 use_facet<moneypunct<char_type, false> >(__loc);
2894 __pat = __mp.neg_format();
2895 __nsn = __mp.negative_sign();
2896 __psn = __mp.positive_sign();
2897 __dp = __mp.decimal_point();
2898 __ts = __mp.thousands_sep();
2899 __grp = __mp.grouping();
2900 __sym = __mp.curr_symbol();
2901 __fd = __mp.frac_digits();
2902 }
2903}
2904
Howard Hinnant8ea98242013-08-23 17:37:05 +00002905_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
2906_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00002907
2908template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002909class _LIBCPP_TYPE_VIS_ONLY money_get
Howard Hinnantc51e1022010-05-11 19:42:16 +00002910 : public locale::facet,
2911 private __money_get<_CharT>
2912{
2913public:
2914 typedef _CharT char_type;
2915 typedef _InputIterator iter_type;
2916 typedef basic_string<char_type> string_type;
2917
2918 _LIBCPP_ALWAYS_INLINE
2919 explicit money_get(size_t __refs = 0)
2920 : locale::facet(__refs) {}
2921
2922 _LIBCPP_ALWAYS_INLINE
2923 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2924 ios_base::iostate& __err, long double& __v) const
2925 {
2926 return do_get(__b, __e, __intl, __iob, __err, __v);
2927 }
2928
2929 _LIBCPP_ALWAYS_INLINE
2930 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2931 ios_base::iostate& __err, string_type& __v) const
2932 {
2933 return do_get(__b, __e, __intl, __iob, __err, __v);
2934 }
2935
2936 static locale::id id;
2937
2938protected:
2939
Howard Hinnant756c69b2010-09-22 16:48:34 +00002940 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00002941 ~money_get() {}
Howard Hinnant3b6579a2010-08-22 00:02:43 +00002942
Howard Hinnantc51e1022010-05-11 19:42:16 +00002943 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2944 ios_base& __iob, ios_base::iostate& __err,
2945 long double& __v) const;
2946 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2947 ios_base& __iob, ios_base::iostate& __err,
2948 string_type& __v) const;
2949
2950private:
2951 static bool __do_get(iter_type& __b, iter_type __e,
2952 bool __intl, const locale& __loc,
2953 ios_base::fmtflags __flags, ios_base::iostate& __err,
2954 bool& __neg, const ctype<char_type>& __ct,
2955 unique_ptr<char_type, void(*)(void*)>& __wb,
2956 char_type*& __wn, char_type* __we);
2957};
2958
2959template <class _CharT, class _InputIterator>
2960locale::id
2961money_get<_CharT, _InputIterator>::id;
2962
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002963_LIBCPP_FUNC_VIS void __do_nothing(void*);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002964
2965template <class _Tp>
2966_LIBCPP_HIDDEN
2967void
2968__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2969{
2970 bool __owns = __b.get_deleter() != __do_nothing;
Howard Hinnant28b24882011-12-01 20:21:04 +00002971 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
Howard Hinnantc51e1022010-05-11 19:42:16 +00002972 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2973 2 * __cur_cap : numeric_limits<size_t>::max();
Marshall Clow6c9ddc22014-10-27 19:08:10 +00002974 if (__new_cap == 0)
2975 __new_cap = sizeof(_Tp);
Howard Hinnant28b24882011-12-01 20:21:04 +00002976 size_t __n_off = static_cast<size_t>(__n - __b.get());
Howard Hinnantc51e1022010-05-11 19:42:16 +00002977 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2978 if (__t == 0)
2979 __throw_bad_alloc();
2980 if (__owns)
2981 __b.release();
2982 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2983 __new_cap /= sizeof(_Tp);
2984 __n = __b.get() + __n_off;
2985 __e = __b.get() + __new_cap;
2986}
2987
2988// true == success
2989template <class _CharT, class _InputIterator>
2990bool
2991money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2992 bool __intl, const locale& __loc,
2993 ios_base::fmtflags __flags,
2994 ios_base::iostate& __err,
2995 bool& __neg,
2996 const ctype<char_type>& __ct,
2997 unique_ptr<char_type, void(*)(void*)>& __wb,
2998 char_type*& __wn, char_type* __we)
2999{
3000 const unsigned __bz = 100;
3001 unsigned __gbuf[__bz];
3002 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3003 unsigned* __gn = __gb.get();
3004 unsigned* __ge = __gn + __bz;
3005 money_base::pattern __pat;
3006 char_type __dp;
3007 char_type __ts;
3008 string __grp;
3009 string_type __sym;
3010 string_type __psn;
3011 string_type __nsn;
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00003012 // Capture the spaces read into money_base::{space,none} so they
3013 // can be compared to initial spaces in __sym.
3014 string_type __spaces;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003015 int __fd;
3016 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3017 __sym, __psn, __nsn, __fd);
3018 const string_type* __trailing_sign = 0;
3019 __wn = __wb.get();
3020 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3021 {
3022 switch (__pat.field[__p])
3023 {
3024 case money_base::space:
3025 if (__p != 3)
3026 {
3027 if (__ct.is(ctype_base::space, *__b))
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00003028 __spaces.push_back(*__b++);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003029 else
3030 {
3031 __err |= ios_base::failbit;
3032 return false;
3033 }
3034 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +00003035 // drop through
Howard Hinnantc51e1022010-05-11 19:42:16 +00003036 case money_base::none:
3037 if (__p != 3)
3038 {
3039 while (__b != __e && __ct.is(ctype_base::space, *__b))
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00003040 __spaces.push_back(*__b++);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003041 }
3042 break;
3043 case money_base::sign:
3044 if (__psn.size() + __nsn.size() > 0)
3045 {
3046 if (__psn.size() == 0 || __nsn.size() == 0)
3047 { // sign is optional
3048 if (__psn.size() > 0)
3049 { // __nsn.size() == 0
3050 if (*__b == __psn[0])
3051 {
3052 ++__b;
3053 if (__psn.size() > 1)
3054 __trailing_sign = &__psn;
3055 }
3056 else
3057 __neg = true;
3058 }
3059 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0
3060 {
3061 ++__b;
3062 __neg = true;
3063 if (__nsn.size() > 1)
3064 __trailing_sign = &__nsn;
3065 }
3066 }
3067 else // sign is required
3068 {
3069 if (*__b == __psn[0])
3070 {
3071 ++__b;
3072 if (__psn.size() > 1)
3073 __trailing_sign = &__psn;
3074 }
3075 else if (*__b == __nsn[0])
3076 {
3077 ++__b;
3078 __neg = true;
3079 if (__nsn.size() > 1)
3080 __trailing_sign = &__nsn;
3081 }
3082 else
3083 {
3084 __err |= ios_base::failbit;
3085 return false;
3086 }
3087 }
3088 }
3089 break;
3090 case money_base::symbol:
3091 {
3092 bool __more_needed = __trailing_sign ||
3093 (__p < 2) ||
3094 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
Marshall Clowdfcbb432013-10-13 01:02:45 +00003095 bool __sb = (__flags & ios_base::showbase) != 0;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003096 if (__sb || __more_needed)
3097 {
Jeffrey Yasskin6b045fb2012-03-10 18:31:43 +00003098 typename string_type::const_iterator __sym_space_end = __sym.begin();
3099 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3100 __pat.field[__p - 1] == money_base::space)) {
3101 // Match spaces we've already read against spaces at
3102 // the beginning of __sym.
3103 while (__sym_space_end != __sym.end() &&
3104 __ct.is(ctype_base::space, *__sym_space_end))
3105 ++__sym_space_end;
3106 const size_t __num_spaces = __sym_space_end - __sym.begin();
3107 if (__num_spaces > __spaces.size() ||
3108 !equal(__spaces.end() - __num_spaces, __spaces.end(),
3109 __sym.begin())) {
3110 // No match. Put __sym_space_end back at the
3111 // beginning of __sym, which will prevent a
3112 // match in the next loop.
3113 __sym_space_end = __sym.begin();
3114 }
3115 }
3116 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3117 while (__sym_curr_char != __sym.end() && __b != __e &&
3118 *__b == *__sym_curr_char) {
3119 ++__b;
3120 ++__sym_curr_char;
3121 }
3122 if (__sb && __sym_curr_char != __sym.end())
Howard Hinnantc51e1022010-05-11 19:42:16 +00003123 {
3124 __err |= ios_base::failbit;
3125 return false;
3126 }
3127 }
3128 }
3129 break;
3130 case money_base::value:
3131 {
3132 unsigned __ng = 0;
3133 for (; __b != __e; ++__b)
3134 {
3135 char_type __c = *__b;
3136 if (__ct.is(ctype_base::digit, __c))
3137 {
3138 if (__wn == __we)
3139 __double_or_nothing(__wb, __wn, __we);
3140 *__wn++ = __c;
3141 ++__ng;
3142 }
3143 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3144 {
3145 if (__gn == __ge)
3146 __double_or_nothing(__gb, __gn, __ge);
3147 *__gn++ = __ng;
3148 __ng = 0;
3149 }
3150 else
3151 break;
3152 }
3153 if (__gb.get() != __gn && __ng > 0)
3154 {
3155 if (__gn == __ge)
3156 __double_or_nothing(__gb, __gn, __ge);
3157 *__gn++ = __ng;
3158 }
3159 if (__fd > 0)
3160 {
3161 if (__b == __e || *__b != __dp)
3162 {
3163 __err |= ios_base::failbit;
3164 return false;
3165 }
3166 for (++__b; __fd > 0; --__fd, ++__b)
3167 {
3168 if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3169 {
3170 __err |= ios_base::failbit;
3171 return false;
3172 }
3173 if (__wn == __we)
3174 __double_or_nothing(__wb, __wn, __we);
3175 *__wn++ = *__b;
3176 }
3177 }
3178 if (__wn == __wb.get())
3179 {
3180 __err |= ios_base::failbit;
3181 return false;
3182 }
3183 }
3184 break;
3185 }
3186 }
3187 if (__trailing_sign)
3188 {
3189 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3190 {
3191 if (__b == __e || *__b != (*__trailing_sign)[__i])
3192 {
3193 __err |= ios_base::failbit;
3194 return false;
3195 }
3196 }
3197 }
3198 if (__gb.get() != __gn)
3199 {
3200 ios_base::iostate __et = ios_base::goodbit;
3201 __check_grouping(__grp, __gb.get(), __gn, __et);
3202 if (__et)
3203 {
3204 __err |= ios_base::failbit;
3205 return false;
3206 }
3207 }
3208 return true;
3209}
3210
3211template <class _CharT, class _InputIterator>
3212_InputIterator
3213money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3214 bool __intl, ios_base& __iob,
3215 ios_base::iostate& __err,
3216 long double& __v) const
3217{
Howard Hinnant28b24882011-12-01 20:21:04 +00003218 const int __bz = 100;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003219 char_type __wbuf[__bz];
3220 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3221 char_type* __wn;
3222 char_type* __we = __wbuf + __bz;
3223 locale __loc = __iob.getloc();
3224 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3225 bool __neg = false;
3226 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3227 __wb, __wn, __we))
3228 {
3229 const char __src[] = "0123456789";
3230 char_type __atoms[sizeof(__src)-1];
3231 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3232 char __nbuf[__bz];
3233 char* __nc = __nbuf;
3234 unique_ptr<char, void(*)(void*)> __h(0, free);
3235 if (__wn - __wb.get() > __bz-2)
3236 {
Howard Hinnant28b24882011-12-01 20:21:04 +00003237 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00003238 if (__h.get() == 0)
3239 __throw_bad_alloc();
3240 __nc = __h.get();
3241 }
3242 if (__neg)
3243 *__nc++ = '-';
3244 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
Marshall Clow1e68fd42013-03-22 02:14:40 +00003245 *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
Howard Hinnantc51e1022010-05-11 19:42:16 +00003246 *__nc = char();
3247 if (sscanf(__nbuf, "%Lf", &__v) != 1)
3248 __throw_runtime_error("money_get error");
3249 }
3250 if (__b == __e)
3251 __err |= ios_base::eofbit;
3252 return __b;
3253}
3254
3255template <class _CharT, class _InputIterator>
3256_InputIterator
3257money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3258 bool __intl, ios_base& __iob,
3259 ios_base::iostate& __err,
3260 string_type& __v) const
3261{
Howard Hinnant28b24882011-12-01 20:21:04 +00003262 const int __bz = 100;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003263 char_type __wbuf[__bz];
3264 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3265 char_type* __wn;
3266 char_type* __we = __wbuf + __bz;
3267 locale __loc = __iob.getloc();
3268 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3269 bool __neg = false;
3270 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3271 __wb, __wn, __we))
3272 {
3273 __v.clear();
3274 if (__neg)
3275 __v.push_back(__ct.widen('-'));
3276 char_type __z = __ct.widen('0');
3277 char_type* __w;
3278 for (__w = __wb.get(); __w < __wn-1; ++__w)
3279 if (*__w != __z)
3280 break;
3281 __v.append(__w, __wn);
3282 }
3283 if (__b == __e)
3284 __err |= ios_base::eofbit;
3285 return __b;
3286}
3287
Howard Hinnant8ea98242013-08-23 17:37:05 +00003288_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
3289_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003290
3291// money_put
3292
3293template <class _CharT>
3294class __money_put
3295{
3296protected:
3297 typedef _CharT char_type;
3298 typedef basic_string<char_type> string_type;
3299
3300 _LIBCPP_ALWAYS_INLINE __money_put() {}
3301
3302 static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3303 money_base::pattern& __pat, char_type& __dp,
3304 char_type& __ts, string& __grp,
3305 string_type& __sym, string_type& __sn,
3306 int& __fd);
3307 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3308 ios_base::fmtflags __flags,
3309 const char_type* __db, const char_type* __de,
3310 const ctype<char_type>& __ct, bool __neg,
3311 const money_base::pattern& __pat, char_type __dp,
3312 char_type __ts, const string& __grp,
3313 const string_type& __sym, const string_type& __sn,
3314 int __fd);
3315};
3316
3317template <class _CharT>
3318void
3319__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3320 money_base::pattern& __pat, char_type& __dp,
3321 char_type& __ts, string& __grp,
3322 string_type& __sym, string_type& __sn,
3323 int& __fd)
3324{
3325 if (__intl)
3326 {
3327 const moneypunct<char_type, true>& __mp =
3328 use_facet<moneypunct<char_type, true> >(__loc);
3329 if (__neg)
3330 {
3331 __pat = __mp.neg_format();
3332 __sn = __mp.negative_sign();
3333 }
3334 else
3335 {
3336 __pat = __mp.pos_format();
3337 __sn = __mp.positive_sign();
3338 }
3339 __dp = __mp.decimal_point();
3340 __ts = __mp.thousands_sep();
3341 __grp = __mp.grouping();
3342 __sym = __mp.curr_symbol();
3343 __fd = __mp.frac_digits();
3344 }
3345 else
3346 {
3347 const moneypunct<char_type, false>& __mp =
3348 use_facet<moneypunct<char_type, false> >(__loc);
3349 if (__neg)
3350 {
3351 __pat = __mp.neg_format();
3352 __sn = __mp.negative_sign();
3353 }
3354 else
3355 {
3356 __pat = __mp.pos_format();
3357 __sn = __mp.positive_sign();
3358 }
3359 __dp = __mp.decimal_point();
3360 __ts = __mp.thousands_sep();
3361 __grp = __mp.grouping();
3362 __sym = __mp.curr_symbol();
3363 __fd = __mp.frac_digits();
3364 }
3365}
3366
3367template <class _CharT>
3368void
3369__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3370 ios_base::fmtflags __flags,
3371 const char_type* __db, const char_type* __de,
3372 const ctype<char_type>& __ct, bool __neg,
3373 const money_base::pattern& __pat, char_type __dp,
3374 char_type __ts, const string& __grp,
3375 const string_type& __sym, const string_type& __sn,
3376 int __fd)
3377{
3378 __me = __mb;
3379 for (unsigned __p = 0; __p < 4; ++__p)
3380 {
3381 switch (__pat.field[__p])
3382 {
3383 case money_base::none:
3384 __mi = __me;
3385 break;
3386 case money_base::space:
3387 __mi = __me;
3388 *__me++ = __ct.widen(' ');
3389 break;
3390 case money_base::sign:
3391 if (!__sn.empty())
3392 *__me++ = __sn[0];
3393 break;
3394 case money_base::symbol:
3395 if (!__sym.empty() && (__flags & ios_base::showbase))
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00003396 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003397 break;
3398 case money_base::value:
3399 {
3400 // remember start of value so we can reverse it
3401 char_type* __t = __me;
3402 // find beginning of digits
3403 if (__neg)
3404 ++__db;
3405 // find end of digits
3406 const char_type* __d;
3407 for (__d = __db; __d < __de; ++__d)
3408 if (!__ct.is(ctype_base::digit, *__d))
3409 break;
3410 // print fractional part
3411 if (__fd > 0)
3412 {
3413 int __f;
3414 for (__f = __fd; __d > __db && __f > 0; --__f)
3415 *__me++ = *--__d;
3416 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3417 for (; __f > 0; --__f)
3418 *__me++ = __z;
3419 *__me++ = __dp;
3420 }
3421 // print units part
3422 if (__d == __db)
3423 {
3424 *__me++ = __ct.widen('0');
3425 }
3426 else
3427 {
3428 unsigned __ng = 0;
3429 unsigned __ig = 0;
3430 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3431 : static_cast<unsigned>(__grp[__ig]);
3432 while (__d != __db)
3433 {
3434 if (__ng == __gl)
3435 {
3436 *__me++ = __ts;
3437 __ng = 0;
3438 if (++__ig < __grp.size())
3439 __gl = __grp[__ig] == numeric_limits<char>::max() ?
3440 numeric_limits<unsigned>::max() :
3441 static_cast<unsigned>(__grp[__ig]);
3442 }
3443 *__me++ = *--__d;
3444 ++__ng;
3445 }
3446 }
3447 // reverse it
3448 reverse(__t, __me);
3449 }
3450 break;
3451 }
3452 }
3453 // print rest of sign, if any
3454 if (__sn.size() > 1)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00003455 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
Howard Hinnantc51e1022010-05-11 19:42:16 +00003456 // set alignment
3457 if ((__flags & ios_base::adjustfield) == ios_base::left)
3458 __mi = __me;
3459 else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3460 __mi = __mb;
3461}
3462
Howard Hinnant8ea98242013-08-23 17:37:05 +00003463_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
3464_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003465
3466template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00003467class _LIBCPP_TYPE_VIS_ONLY money_put
Howard Hinnantc51e1022010-05-11 19:42:16 +00003468 : public locale::facet,
3469 private __money_put<_CharT>
3470{
3471public:
3472 typedef _CharT char_type;
3473 typedef _OutputIterator iter_type;
3474 typedef basic_string<char_type> string_type;
3475
3476 _LIBCPP_ALWAYS_INLINE
3477 explicit money_put(size_t __refs = 0)
3478 : locale::facet(__refs) {}
3479
3480 _LIBCPP_ALWAYS_INLINE
3481 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3482 long double __units) const
3483 {
3484 return do_put(__s, __intl, __iob, __fl, __units);
3485 }
3486
3487 _LIBCPP_ALWAYS_INLINE
3488 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3489 const string_type& __digits) const
3490 {
3491 return do_put(__s, __intl, __iob, __fl, __digits);
3492 }
3493
3494 static locale::id id;
3495
3496protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00003497 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00003498 ~money_put() {}
3499
3500 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3501 char_type __fl, long double __units) const;
3502 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3503 char_type __fl, const string_type& __digits) const;
3504};
3505
3506template <class _CharT, class _OutputIterator>
3507locale::id
3508money_put<_CharT, _OutputIterator>::id;
3509
3510template <class _CharT, class _OutputIterator>
3511_OutputIterator
3512money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3513 ios_base& __iob, char_type __fl,
3514 long double __units) const
3515{
3516 // convert to char
3517 const size_t __bs = 100;
3518 char __buf[__bs];
3519 char* __bb = __buf;
3520 char_type __digits[__bs];
3521 char_type* __db = __digits;
Howard Hinnant28b24882011-12-01 20:21:04 +00003522 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
Howard Hinnantc51e1022010-05-11 19:42:16 +00003523 unique_ptr<char, void(*)(void*)> __hn(0, free);
3524 unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3525 // secure memory for digit storage
3526 if (__n > __bs-1)
3527 {
Howard Hinnantf312e3e2011-09-28 23:39:33 +00003528#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
Howard Hinnant28b24882011-12-01 20:21:04 +00003529 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
Alexis Hunt1adf2aa2011-07-15 05:40:33 +00003530#else
3531 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
3532#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +00003533 if (__bb == 0)
3534 __throw_bad_alloc();
3535 __hn.reset(__bb);
3536 __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
Howard Hinnant03de6f92012-03-07 20:37:43 +00003537 if (__hd == nullptr)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003538 __throw_bad_alloc();
3539 __db = __hd.get();
3540 }
3541 // gather info
3542 locale __loc = __iob.getloc();
3543 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3544 __ct.widen(__bb, __bb + __n, __db);
3545 bool __neg = __n > 0 && __bb[0] == '-';
3546 money_base::pattern __pat;
3547 char_type __dp;
3548 char_type __ts;
3549 string __grp;
3550 string_type __sym;
3551 string_type __sn;
3552 int __fd;
3553 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3554 // secure memory for formatting
3555 char_type __mbuf[__bs];
3556 char_type* __mb = __mbuf;
3557 unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3558 size_t __exn = static_cast<int>(__n) > __fd ?
Howard Hinnant28b24882011-12-01 20:21:04 +00003559 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3560 __sym.size() + static_cast<size_t>(__fd) + 1
3561 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003562 if (__exn > __bs)
3563 {
3564 __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3565 __mb = __hw.get();
3566 if (__mb == 0)
3567 __throw_bad_alloc();
3568 }
3569 // format
3570 char_type* __mi;
3571 char_type* __me;
3572 this->__format(__mb, __mi, __me, __iob.flags(),
3573 __db, __db + __n, __ct,
3574 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3575 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3576}
3577
3578template <class _CharT, class _OutputIterator>
3579_OutputIterator
3580money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3581 ios_base& __iob, char_type __fl,
3582 const string_type& __digits) const
3583{
3584 // gather info
3585 locale __loc = __iob.getloc();
3586 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3587 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3588 money_base::pattern __pat;
3589 char_type __dp;
3590 char_type __ts;
3591 string __grp;
3592 string_type __sym;
3593 string_type __sn;
3594 int __fd;
3595 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3596 // secure memory for formatting
3597 char_type __mbuf[100];
3598 char_type* __mb = __mbuf;
3599 unique_ptr<char_type, void(*)(void*)> __h(0, free);
Howard Hinnant28b24882011-12-01 20:21:04 +00003600 size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3601 (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3602 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3603 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003604 if (__exn > 100)
3605 {
3606 __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3607 __mb = __h.get();
3608 if (__mb == 0)
3609 __throw_bad_alloc();
3610 }
3611 // format
3612 char_type* __mi;
3613 char_type* __me;
3614 this->__format(__mb, __mi, __me, __iob.flags(),
3615 __digits.data(), __digits.data() + __digits.size(), __ct,
3616 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3617 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3618}
3619
Howard Hinnant8ea98242013-08-23 17:37:05 +00003620_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
3621_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003622
3623// messages
3624
Howard Hinnant8331b762013-03-06 23:30:19 +00003625class _LIBCPP_TYPE_VIS messages_base
Howard Hinnantc51e1022010-05-11 19:42:16 +00003626{
3627public:
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003628 typedef ptrdiff_t catalog;
Howard Hinnantc51e1022010-05-11 19:42:16 +00003629
3630 _LIBCPP_ALWAYS_INLINE messages_base() {}
3631};
3632
3633template <class _CharT>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00003634class _LIBCPP_TYPE_VIS_ONLY messages
Howard Hinnantc51e1022010-05-11 19:42:16 +00003635 : public locale::facet,
3636 public messages_base
3637{
3638public:
3639 typedef _CharT char_type;
3640 typedef basic_string<_CharT> string_type;
3641
3642 _LIBCPP_ALWAYS_INLINE
3643 explicit messages(size_t __refs = 0)
3644 : locale::facet(__refs) {}
3645
3646 _LIBCPP_ALWAYS_INLINE
3647 catalog open(const basic_string<char>& __nm, const locale& __loc) const
3648 {
3649 return do_open(__nm, __loc);
3650 }
3651
3652 _LIBCPP_ALWAYS_INLINE
3653 string_type get(catalog __c, int __set, int __msgid,
3654 const string_type& __dflt) const
3655 {
3656 return do_get(__c, __set, __msgid, __dflt);
3657 }
3658
3659 _LIBCPP_ALWAYS_INLINE
3660 void close(catalog __c) const
3661 {
3662 do_close(__c);
3663 }
3664
3665 static locale::id id;
3666
3667protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00003668 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00003669 ~messages() {}
3670
3671 virtual catalog do_open(const basic_string<char>&, const locale&) const;
3672 virtual string_type do_get(catalog, int __set, int __msgid,
3673 const string_type& __dflt) const;
3674 virtual void do_close(catalog) const;
3675};
3676
3677template <class _CharT>
3678locale::id
3679messages<_CharT>::id;
3680
3681template <class _CharT>
3682typename messages<_CharT>::catalog
3683messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3684{
Ed Schouten118b6032015-03-11 16:39:36 +00003685#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +00003686 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003687 if (__cat != -1)
3688 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3689 return __cat;
Ed Schouten118b6032015-03-11 16:39:36 +00003690#else // !_LIBCPP_HAS_CATOPEN
3691 return -1;
3692#endif // _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003693}
3694
3695template <class _CharT>
3696typename messages<_CharT>::string_type
3697messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3698 const string_type& __dflt) const
3699{
Ed Schouten118b6032015-03-11 16:39:36 +00003700#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003701 string __ndflt;
3702 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3703 __dflt.c_str(),
3704 __dflt.c_str() + __dflt.size());
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003705 if (__c != -1)
3706 __c <<= 1;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +00003707 nl_catd __cat = (nl_catd)__c;
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003708 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
Howard Hinnantc51e1022010-05-11 19:42:16 +00003709 string_type __w;
3710 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3711 __n, __n + strlen(__n));
3712 return __w;
Ed Schouten118b6032015-03-11 16:39:36 +00003713#else // !_LIBCPP_HAS_CATOPEN
3714 return __dflt;
3715#endif // _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003716}
3717
3718template <class _CharT>
3719void
3720messages<_CharT>::do_close(catalog __c) const
3721{
Ed Schouten118b6032015-03-11 16:39:36 +00003722#ifdef _LIBCPP_HAS_CATOPEN
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003723 if (__c != -1)
3724 __c <<= 1;
Howard Hinnant8c2bf6b2011-10-11 16:00:46 +00003725 nl_catd __cat = (nl_catd)__c;
Howard Hinnant2862aeb2011-02-25 00:51:08 +00003726 catclose(__cat);
Ed Schouten118b6032015-03-11 16:39:36 +00003727#endif // _LIBCPP_HAS_CATOPEN
Howard Hinnantc51e1022010-05-11 19:42:16 +00003728}
3729
Howard Hinnant8ea98242013-08-23 17:37:05 +00003730_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
3731_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003732
3733template <class _CharT>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00003734class _LIBCPP_TYPE_VIS_ONLY messages_byname
Howard Hinnantc51e1022010-05-11 19:42:16 +00003735 : public messages<_CharT>
3736{
3737public:
3738 typedef messages_base::catalog catalog;
3739 typedef basic_string<_CharT> string_type;
3740
3741 _LIBCPP_ALWAYS_INLINE
3742 explicit messages_byname(const char*, size_t __refs = 0)
3743 : messages<_CharT>(__refs) {}
3744
3745 _LIBCPP_ALWAYS_INLINE
3746 explicit messages_byname(const string&, size_t __refs = 0)
3747 : messages<_CharT>(__refs) {}
3748
3749protected:
Howard Hinnant756c69b2010-09-22 16:48:34 +00003750 _LIBCPP_ALWAYS_INLINE
Howard Hinnantc51e1022010-05-11 19:42:16 +00003751 ~messages_byname() {}
3752};
3753
Howard Hinnant8ea98242013-08-23 17:37:05 +00003754_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
3755_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
Howard Hinnantc51e1022010-05-11 19:42:16 +00003756
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003757template<class _Codecvt, class _Elem = wchar_t,
3758 class _Wide_alloc = allocator<_Elem>,
3759 class _Byte_alloc = allocator<char> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00003760class _LIBCPP_TYPE_VIS_ONLY wstring_convert
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003761{
3762public:
3763 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
3764 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3765 typedef typename _Codecvt::state_type state_type;
3766 typedef typename wide_string::traits_type::int_type int_type;
3767
3768private:
3769 byte_string __byte_err_string_;
3770 wide_string __wide_err_string_;
3771 _Codecvt* __cvtptr_;
3772 state_type __cvtstate_;
3773 size_t __cvtcount_;
3774
3775 wstring_convert(const wstring_convert& __wc);
3776 wstring_convert& operator=(const wstring_convert& __wc);
3777public:
Marshall Clowccaa0fb2013-08-27 20:18:59 +00003778 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003779 wstring_convert(_Codecvt* __pcvt, state_type __state);
Marshall Clowccaa0fb2013-08-27 20:18:59 +00003780 _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003781 const wide_string& __wide_err = wide_string());
Howard Hinnant74279a52010-09-04 23:28:19 +00003782#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003783 wstring_convert(wstring_convert&& __wc);
3784#endif
3785 ~wstring_convert();
3786
Howard Hinnant756c69b2010-09-22 16:48:34 +00003787 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003788 wide_string from_bytes(char __byte)
3789 {return from_bytes(&__byte, &__byte+1);}
Howard Hinnant756c69b2010-09-22 16:48:34 +00003790 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003791 wide_string from_bytes(const char* __ptr)
3792 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
Howard Hinnant756c69b2010-09-22 16:48:34 +00003793 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003794 wide_string from_bytes(const byte_string& __str)
3795 {return from_bytes(__str.data(), __str.data() + __str.size());}
3796 wide_string from_bytes(const char* __first, const char* __last);
3797
Howard Hinnant756c69b2010-09-22 16:48:34 +00003798 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003799 byte_string to_bytes(_Elem __wchar)
3800 {return to_bytes(&__wchar, &__wchar+1);}
Howard Hinnant756c69b2010-09-22 16:48:34 +00003801 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003802 byte_string to_bytes(const _Elem* __wptr)
3803 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
Howard Hinnant756c69b2010-09-22 16:48:34 +00003804 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003805 byte_string to_bytes(const wide_string& __wstr)
3806 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3807 byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3808
Howard Hinnant756c69b2010-09-22 16:48:34 +00003809 _LIBCPP_ALWAYS_INLINE
Marshall Clowccaa0fb2013-08-27 20:18:59 +00003810 size_t converted() const _NOEXCEPT {return __cvtcount_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00003811 _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003812 state_type state() const {return __cvtstate_;}
3813};
3814
3815template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
Howard Hinnant756c69b2010-09-22 16:48:34 +00003816inline _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003817wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3818 wstring_convert(_Codecvt* __pcvt)
3819 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3820{
3821}
3822
3823template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
Howard Hinnant756c69b2010-09-22 16:48:34 +00003824inline _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003825wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3826 wstring_convert(_Codecvt* __pcvt, state_type __state)
3827 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3828{
3829}
3830
3831template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3832wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3833 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3834 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3835 __cvtstate_(), __cvtcount_(0)
3836{
3837 __cvtptr_ = new _Codecvt;
3838}
3839
Howard Hinnant74279a52010-09-04 23:28:19 +00003840#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003841
3842template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
Howard Hinnant756c69b2010-09-22 16:48:34 +00003843inline _LIBCPP_ALWAYS_INLINE
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003844wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3845 wstring_convert(wstring_convert&& __wc)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00003846 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3847 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003848 __cvtptr_(__wc.__cvtptr_),
3849 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
3850{
3851 __wc.__cvtptr_ = nullptr;
3852}
3853
Howard Hinnant5dc89112010-09-04 23:46:48 +00003854#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003855
3856template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3857wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3858{
3859 delete __cvtptr_;
3860}
3861
3862template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3863typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3864wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3865 from_bytes(const char* __frm, const char* __frm_end)
3866{
3867 __cvtcount_ = 0;
3868 if (__cvtptr_ != nullptr)
3869 {
3870 wide_string __ws(2*(__frm_end - __frm), _Elem());
Howard Hinnant16d54f22012-07-12 18:07:41 +00003871 if (__frm != __frm_end)
3872 __ws.resize(__ws.capacity());
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003873 codecvt_base::result __r = codecvt_base::ok;
3874 state_type __st = __cvtstate_;
3875 if (__frm != __frm_end)
3876 {
3877 _Elem* __to = &__ws[0];
3878 _Elem* __to_end = __to + __ws.size();
3879 const char* __frm_nxt;
3880 do
3881 {
3882 _Elem* __to_nxt;
3883 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3884 __to, __to_end, __to_nxt);
3885 __cvtcount_ += __frm_nxt - __frm;
3886 if (__frm_nxt == __frm)
3887 {
3888 __r = codecvt_base::error;
3889 }
3890 else if (__r == codecvt_base::noconv)
3891 {
3892 __ws.resize(__to - &__ws[0]);
3893 // This only gets executed if _Elem is char
3894 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3895 __frm = __frm_nxt;
3896 __r = codecvt_base::ok;
3897 }
3898 else if (__r == codecvt_base::ok)
3899 {
3900 __ws.resize(__to_nxt - &__ws[0]);
3901 __frm = __frm_nxt;
3902 }
3903 else if (__r == codecvt_base::partial)
3904 {
3905 ptrdiff_t __s = __to_nxt - &__ws[0];
3906 __ws.resize(2 * __s);
3907 __to = &__ws[0] + __s;
3908 __to_end = &__ws[0] + __ws.size();
3909 __frm = __frm_nxt;
3910 }
3911 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3912 }
3913 if (__r == codecvt_base::ok)
3914 return __ws;
3915 }
Howard Hinnant72f73582010-08-11 17:04:31 +00003916#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003917 if (__wide_err_string_.empty())
3918 throw range_error("wstring_convert: from_bytes error");
Howard Hinnant3b6579a2010-08-22 00:02:43 +00003919#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003920 return __wide_err_string_;
3921}
3922
3923template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3924typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3925wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3926 to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3927{
3928 __cvtcount_ = 0;
3929 if (__cvtptr_ != nullptr)
3930 {
3931 byte_string __bs(2*(__frm_end - __frm), char());
Howard Hinnant16d54f22012-07-12 18:07:41 +00003932 if (__frm != __frm_end)
3933 __bs.resize(__bs.capacity());
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003934 codecvt_base::result __r = codecvt_base::ok;
3935 state_type __st = __cvtstate_;
3936 if (__frm != __frm_end)
3937 {
3938 char* __to = &__bs[0];
3939 char* __to_end = __to + __bs.size();
3940 const _Elem* __frm_nxt;
3941 do
3942 {
3943 char* __to_nxt;
3944 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3945 __to, __to_end, __to_nxt);
3946 __cvtcount_ += __frm_nxt - __frm;
3947 if (__frm_nxt == __frm)
3948 {
3949 __r = codecvt_base::error;
3950 }
3951 else if (__r == codecvt_base::noconv)
3952 {
3953 __bs.resize(__to - &__bs[0]);
3954 // This only gets executed if _Elem is char
3955 __bs.append((const char*)__frm, (const char*)__frm_end);
3956 __frm = __frm_nxt;
3957 __r = codecvt_base::ok;
3958 }
3959 else if (__r == codecvt_base::ok)
3960 {
3961 __bs.resize(__to_nxt - &__bs[0]);
3962 __frm = __frm_nxt;
3963 }
3964 else if (__r == codecvt_base::partial)
3965 {
3966 ptrdiff_t __s = __to_nxt - &__bs[0];
3967 __bs.resize(2 * __s);
3968 __to = &__bs[0] + __s;
3969 __to_end = &__bs[0] + __bs.size();
3970 __frm = __frm_nxt;
3971 }
3972 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3973 }
3974 if (__r == codecvt_base::ok)
3975 {
3976 size_t __s = __bs.size();
3977 __bs.resize(__bs.capacity());
3978 char* __to = &__bs[0] + __s;
3979 char* __to_end = __to + __bs.size();
3980 do
3981 {
3982 char* __to_nxt;
3983 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3984 if (__r == codecvt_base::noconv)
3985 {
3986 __bs.resize(__to - &__bs[0]);
3987 __r = codecvt_base::ok;
3988 }
3989 else if (__r == codecvt_base::ok)
3990 {
3991 __bs.resize(__to_nxt - &__bs[0]);
3992 }
3993 else if (__r == codecvt_base::partial)
3994 {
Howard Hinnant28b24882011-12-01 20:21:04 +00003995 ptrdiff_t __sp = __to_nxt - &__bs[0];
3996 __bs.resize(2 * __sp);
3997 __to = &__bs[0] + __sp;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00003998 __to_end = &__bs[0] + __bs.size();
3999 }
4000 } while (__r == codecvt_base::partial);
4001 if (__r == codecvt_base::ok)
4002 return __bs;
4003 }
4004 }
Howard Hinnant72f73582010-08-11 17:04:31 +00004005#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004006 if (__byte_err_string_.empty())
4007 throw range_error("wstring_convert: to_bytes error");
Howard Hinnant3b6579a2010-08-22 00:02:43 +00004008#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004009 return __byte_err_string_;
4010}
4011
4012template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00004013class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004014 : public basic_streambuf<_Elem, _Tr>
4015{
4016public:
4017 // types:
4018 typedef _Elem char_type;
4019 typedef _Tr traits_type;
4020 typedef typename traits_type::int_type int_type;
4021 typedef typename traits_type::pos_type pos_type;
4022 typedef typename traits_type::off_type off_type;
4023 typedef typename _Codecvt::state_type state_type;
4024
4025private:
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004026 char* __extbuf_;
4027 const char* __extbufnext_;
4028 const char* __extbufend_;
4029 char __extbuf_min_[8];
4030 size_t __ebs_;
4031 char_type* __intbuf_;
4032 size_t __ibs_;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004033 streambuf* __bufptr_;
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004034 _Codecvt* __cv_;
4035 state_type __st_;
4036 ios_base::openmode __cm_;
4037 bool __owns_eb_;
4038 bool __owns_ib_;
4039 bool __always_noconv_;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004040
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004041 wbuffer_convert(const wbuffer_convert&);
4042 wbuffer_convert& operator=(const wbuffer_convert&);
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004043public:
Marshall Clowccaa0fb2013-08-27 20:18:59 +00004044 _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0,
4045 _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004046 ~wbuffer_convert();
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004047
Howard Hinnant756c69b2010-09-22 16:48:34 +00004048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004049 streambuf* rdbuf() const {return __bufptr_;}
Howard Hinnant756c69b2010-09-22 16:48:34 +00004050 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004051 streambuf* rdbuf(streambuf* __bytebuf)
4052 {
4053 streambuf* __r = __bufptr_;
4054 __bufptr_ = __bytebuf;
4055 return __r;
4056 }
4057
Howard Hinnant756c69b2010-09-22 16:48:34 +00004058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004059 state_type state() const {return __st_;}
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004060
4061protected:
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004062 virtual int_type underflow();
4063 virtual int_type pbackfail(int_type __c = traits_type::eof());
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004064 virtual int_type overflow (int_type __c = traits_type::eof());
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004065 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4066 streamsize __n);
4067 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4068 ios_base::openmode __wch = ios_base::in | ios_base::out);
4069 virtual pos_type seekpos(pos_type __sp,
4070 ios_base::openmode __wch = ios_base::in | ios_base::out);
4071 virtual int sync();
4072
4073private:
4074 bool __read_mode();
4075 void __write_mode();
4076 wbuffer_convert* __close();
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004077};
4078
4079template <class _Codecvt, class _Elem, class _Tr>
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004080wbuffer_convert<_Codecvt, _Elem, _Tr>::
4081 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4082 : __extbuf_(0),
4083 __extbufnext_(0),
4084 __extbufend_(0),
4085 __ebs_(0),
4086 __intbuf_(0),
4087 __ibs_(0),
4088 __bufptr_(__bytebuf),
4089 __cv_(__pcvt),
4090 __st_(__state),
4091 __cm_(0),
4092 __owns_eb_(false),
4093 __owns_ib_(false),
4094 __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4095{
4096 setbuf(0, 4096);
4097}
4098
4099template <class _Codecvt, class _Elem, class _Tr>
4100wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4101{
4102 __close();
4103 delete __cv_;
4104 if (__owns_eb_)
4105 delete [] __extbuf_;
4106 if (__owns_ib_)
4107 delete [] __intbuf_;
4108}
4109
4110template <class _Codecvt, class _Elem, class _Tr>
4111typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4112wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4113{
4114 if (__cv_ == 0 || __bufptr_ == 0)
4115 return traits_type::eof();
4116 bool __initial = __read_mode();
4117 char_type __1buf;
4118 if (this->gptr() == 0)
4119 this->setg(&__1buf, &__1buf+1, &__1buf+1);
4120 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4121 int_type __c = traits_type::eof();
4122 if (this->gptr() == this->egptr())
4123 {
4124 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4125 if (__always_noconv_)
4126 {
4127 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4128 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4129 if (__nmemb != 0)
4130 {
4131 this->setg(this->eback(),
4132 this->eback() + __unget_sz,
4133 this->eback() + __unget_sz + __nmemb);
4134 __c = *this->gptr();
4135 }
4136 }
4137 else
4138 {
4139 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4140 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4141 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00004142 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004143 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4144 codecvt_base::result __r;
4145 state_type __svs = __st_;
4146 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4147 if (__nr != 0)
4148 {
4149 __extbufend_ = __extbufnext_ + __nr;
4150 char_type* __inext;
4151 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4152 this->eback() + __unget_sz,
4153 this->egptr(), __inext);
4154 if (__r == codecvt_base::noconv)
4155 {
4156 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4157 __c = *this->gptr();
4158 }
4159 else if (__inext != this->eback() + __unget_sz)
4160 {
4161 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4162 __c = *this->gptr();
4163 }
4164 }
4165 }
4166 }
4167 else
4168 __c = *this->gptr();
4169 if (this->eback() == &__1buf)
4170 this->setg(0, 0, 0);
4171 return __c;
4172}
4173
4174template <class _Codecvt, class _Elem, class _Tr>
4175typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4176wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4177{
4178 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4179 {
4180 if (traits_type::eq_int_type(__c, traits_type::eof()))
4181 {
4182 this->gbump(-1);
4183 return traits_type::not_eof(__c);
4184 }
4185 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4186 {
4187 this->gbump(-1);
4188 *this->gptr() = traits_type::to_char_type(__c);
4189 return __c;
4190 }
4191 }
4192 return traits_type::eof();
4193}
4194
4195template <class _Codecvt, class _Elem, class _Tr>
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004196typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4197wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4198{
Howard Hinnant0ac182a2010-06-01 20:09:18 +00004199 if (__cv_ == 0 || __bufptr_ == 0)
4200 return traits_type::eof();
4201 __write_mode();
4202 char_type __1buf;
4203 char_type* __pb_save = this->pbase();
4204 char_type* __epb_save = this->epptr();
4205 if (!traits_type::eq_int_type(__c, traits_type::eof()))
4206 {
4207 if (this->pptr() == 0)
4208 this->setp(&__1buf, &__1buf+1);
4209 *this->pptr() = traits_type::to_char_type(__c);
4210 this->pbump(1);
4211 }
4212 if (this->pptr() != this->pbase())
4213 {
4214 if (__always_noconv_)
4215 {
4216 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4217 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4218 return traits_type::eof();
4219 }
4220 else
4221 {
4222 char* __extbe = __extbuf_;
4223 codecvt_base::result __r;
4224 do
4225 {
4226 const char_type* __e;
4227 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4228 __extbuf_, __extbuf_ + __ebs_, __extbe);
4229 if (__e == this->pbase())
4230 return traits_type::eof();
4231 if (__r == codecvt_base::noconv)
4232 {
4233 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4234 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4235 return traits_type::eof();
4236 }
4237 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4238 {
4239 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4240 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4241 return traits_type::eof();
4242 if (__r == codecvt_base::partial)
4243 {
4244 this->setp((char_type*)__e, this->pptr());
4245 this->pbump(this->epptr() - this->pbase());
4246 }
4247 }
4248 else
4249 return traits_type::eof();
4250 } while (__r == codecvt_base::partial);
4251 }
4252 this->setp(__pb_save, __epb_save);
4253 }
4254 return traits_type::not_eof(__c);
4255}
4256
4257template <class _Codecvt, class _Elem, class _Tr>
4258basic_streambuf<_Elem, _Tr>*
4259wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4260{
4261 this->setg(0, 0, 0);
4262 this->setp(0, 0);
4263 if (__owns_eb_)
4264 delete [] __extbuf_;
4265 if (__owns_ib_)
4266 delete [] __intbuf_;
4267 __ebs_ = __n;
4268 if (__ebs_ > sizeof(__extbuf_min_))
4269 {
4270 if (__always_noconv_ && __s)
4271 {
4272 __extbuf_ = (char*)__s;
4273 __owns_eb_ = false;
4274 }
4275 else
4276 {
4277 __extbuf_ = new char[__ebs_];
4278 __owns_eb_ = true;
4279 }
4280 }
4281 else
4282 {
4283 __extbuf_ = __extbuf_min_;
4284 __ebs_ = sizeof(__extbuf_min_);
4285 __owns_eb_ = false;
4286 }
4287 if (!__always_noconv_)
4288 {
4289 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4290 if (__s && __ibs_ >= sizeof(__extbuf_min_))
4291 {
4292 __intbuf_ = __s;
4293 __owns_ib_ = false;
4294 }
4295 else
4296 {
4297 __intbuf_ = new char_type[__ibs_];
4298 __owns_ib_ = true;
4299 }
4300 }
4301 else
4302 {
4303 __ibs_ = 0;
4304 __intbuf_ = 0;
4305 __owns_ib_ = false;
4306 }
4307 return this;
4308}
4309
4310template <class _Codecvt, class _Elem, class _Tr>
4311typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4312wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4313 ios_base::openmode __om)
4314{
4315 int __width = __cv_->encoding();
4316 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4317 return pos_type(off_type(-1));
4318 // __width > 0 || __off == 0
4319 switch (__way)
4320 {
4321 case ios_base::beg:
4322 break;
4323 case ios_base::cur:
4324 break;
4325 case ios_base::end:
4326 break;
4327 default:
4328 return pos_type(off_type(-1));
4329 }
4330 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4331 __r.state(__st_);
4332 return __r;
4333}
4334
4335template <class _Codecvt, class _Elem, class _Tr>
4336typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4337wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4338{
4339 if (__cv_ == 0 || __bufptr_ == 0 || sync())
4340 return pos_type(off_type(-1));
4341 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4342 return pos_type(off_type(-1));
4343 return __sp;
4344}
4345
4346template <class _Codecvt, class _Elem, class _Tr>
4347int
4348wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4349{
4350 if (__cv_ == 0 || __bufptr_ == 0)
4351 return 0;
4352 if (__cm_ & ios_base::out)
4353 {
4354 if (this->pptr() != this->pbase())
4355 if (overflow() == traits_type::eof())
4356 return -1;
4357 codecvt_base::result __r;
4358 do
4359 {
4360 char* __extbe;
4361 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4362 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4363 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4364 return -1;
4365 } while (__r == codecvt_base::partial);
4366 if (__r == codecvt_base::error)
4367 return -1;
4368 if (__bufptr_->pubsync())
4369 return -1;
4370 }
4371 else if (__cm_ & ios_base::in)
4372 {
4373 off_type __c;
4374 if (__always_noconv_)
4375 __c = this->egptr() - this->gptr();
4376 else
4377 {
4378 int __width = __cv_->encoding();
4379 __c = __extbufend_ - __extbufnext_;
4380 if (__width > 0)
4381 __c += __width * (this->egptr() - this->gptr());
4382 else
4383 {
4384 if (this->gptr() != this->egptr())
4385 {
4386 reverse(this->gptr(), this->egptr());
4387 codecvt_base::result __r;
4388 const char_type* __e = this->gptr();
4389 char* __extbe;
4390 do
4391 {
4392 __r = __cv_->out(__st_, __e, this->egptr(), __e,
4393 __extbuf_, __extbuf_ + __ebs_, __extbe);
4394 switch (__r)
4395 {
4396 case codecvt_base::noconv:
4397 __c += this->egptr() - this->gptr();
4398 break;
4399 case codecvt_base::ok:
4400 case codecvt_base::partial:
4401 __c += __extbe - __extbuf_;
4402 break;
4403 default:
4404 return -1;
4405 }
4406 } while (__r == codecvt_base::partial);
4407 }
4408 }
4409 }
4410 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4411 return -1;
4412 this->setg(0, 0, 0);
4413 __cm_ = 0;
4414 }
4415 return 0;
4416}
4417
4418template <class _Codecvt, class _Elem, class _Tr>
4419bool
4420wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4421{
4422 if (!(__cm_ & ios_base::in))
4423 {
4424 this->setp(0, 0);
4425 if (__always_noconv_)
4426 this->setg((char_type*)__extbuf_,
4427 (char_type*)__extbuf_ + __ebs_,
4428 (char_type*)__extbuf_ + __ebs_);
4429 else
4430 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4431 __cm_ = ios_base::in;
4432 return true;
4433 }
4434 return false;
4435}
4436
4437template <class _Codecvt, class _Elem, class _Tr>
4438void
4439wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4440{
4441 if (!(__cm_ & ios_base::out))
4442 {
4443 this->setg(0, 0, 0);
4444 if (__ebs_ > sizeof(__extbuf_min_))
4445 {
4446 if (__always_noconv_)
4447 this->setp((char_type*)__extbuf_,
4448 (char_type*)__extbuf_ + (__ebs_ - 1));
4449 else
4450 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4451 }
4452 else
4453 this->setp(0, 0);
4454 __cm_ = ios_base::out;
4455 }
4456}
4457
4458template <class _Codecvt, class _Elem, class _Tr>
4459wbuffer_convert<_Codecvt, _Elem, _Tr>*
4460wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4461{
4462 wbuffer_convert* __rt = 0;
4463 if (__cv_ != 0 && __bufptr_ != 0)
4464 {
4465 __rt = this;
4466 if ((__cm_ & ios_base::out) && sync())
4467 __rt = 0;
4468 }
4469 return __rt;
Howard Hinnant9dd7e892010-05-31 20:58:54 +00004470}
4471
Howard Hinnantc51e1022010-05-11 19:42:16 +00004472_LIBCPP_END_NAMESPACE_STD
4473
4474#endif // _LIBCPP_LOCALE