locale revision 256281
1// -*- C++ -*-
2//===-------------------------- locale ------------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
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:
39    locale() noexcept;
40    locale(const locale& other) noexcept;
41    explicit locale(const char* std_name);
42    explicit locale(const string& std_name);
43    locale(const locale& other, const char* std_name, category);
44    locale(const locale& other, const string& std_name, category);
45    template <class Facet> locale(const locale& other, Facet* f);
46    locale(const locale& other, const locale& one, category);
47
48    ~locale(); // not virtual
49
50    const locale& operator=(const locale& other) noexcept;
51
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&);
68template <class Facet> bool has_facet(const locale&) noexcept;
69
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);
84
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
96    wstring_convert(Codecvt* pcvt = new Codecvt);
97    wstring_convert(Codecvt* pcvt, state_type state);
98    wstring_convert(const byte_string& byte_err,
99                    const wide_string& wide_err = wide_string());
100    ~wstring_convert();
101
102    wide_string from_bytes(char byte);
103    wide_string from_bytes(const char* ptr);
104    wide_string from_bytes(const byte_string& str);
105    wide_string from_bytes(const char* first, const char* last);
106
107    byte_string to_bytes(Elem wchar);
108    byte_string to_bytes(const Elem* wptr);
109    byte_string to_bytes(const wide_string& wstr);
110    byte_string to_bytes(const Elem* first, const Elem* last);
111
112    size_t converted() const;
113    state_type state() const;
114};
115
116template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
117class wbuffer_convert
118    : public basic_streambuf<Elem, Tr>
119{
120public:
121    typedef typename Tr::state_type state_type;
122
123    wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
124                    state_type state = state_type());
125
126    streambuf* rdbuf() const;
127    streambuf* rdbuf(streambuf* bytebuf);
128
129    state_type state() const;
130};
131
132// 22.4.1 and 22.4.1.3, ctype:
133class ctype_base;
134template <class charT> class ctype;
135template <> class ctype<char>; // specialization
136template <class charT> class ctype_byname;
137template <> class ctype_byname<char>; // specialization
138
139class codecvt_base;
140template <class internT, class externT, class stateT> class codecvt;
141template <class internT, class externT, class stateT> class codecvt_byname;
142
143// 22.4.2 and 22.4.3, numeric:
144template <class charT, class InputIterator> class num_get;
145template <class charT, class OutputIterator> class num_put;
146template <class charT> class numpunct;
147template <class charT> class numpunct_byname;
148
149// 22.4.4, col lation:
150template <class charT> class collate;
151template <class charT> class collate_byname;
152
153// 22.4.5, date and time:
154class time_base;
155template <class charT, class InputIterator> class time_get;
156template <class charT, class InputIterator> class time_get_byname;
157template <class charT, class OutputIterator> class time_put;
158template <class charT, class OutputIterator> class time_put_byname;
159
160// 22.4.6, money:
161class money_base;
162template <class charT, class InputIterator> class money_get;
163template <class charT, class OutputIterator> class money_put;
164template <class charT, bool Intl> class moneypunct;
165template <class charT, bool Intl> class moneypunct_byname;
166
167// 22.4.7, message retrieval:
168class messages_base;
169template <class charT> class messages;
170template <class charT> class messages_byname;
171
172}  // std
173
174*/
175
176#include <__config>
177#include <__locale>
178#include <algorithm>
179#include <memory>
180#include <ios>
181#include <streambuf>
182#include <iterator>
183#include <limits>
184#ifndef __APPLE__
185#include <cstdarg>
186#endif
187#include <cstdlib>
188#include <ctime>
189#ifdef _WIN32
190#include <support/win32/locale_win32.h>
191#else // _WIN32
192#include <nl_types.h>
193#endif  // !_WIN32
194
195#ifdef __APPLE__
196#include <Availability.h>
197#endif
198
199#include <__undef_min_max>
200
201#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
202#pragma GCC system_header
203#endif
204
205_LIBCPP_BEGIN_NAMESPACE_STD
206
207#if defined(__APPLE__) || defined(__FreeBSD__)
208#  define _LIBCPP_GET_C_LOCALE 0
209#elif defined(__NetBSD__)
210#  define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
211#else
212#  define _LIBCPP_GET_C_LOCALE __cloc()
213   // Get the C locale object
214   locale_t __cloc();
215#define __cloc_defined
216#endif
217
218typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
219typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
220#ifndef _LIBCPP_LOCALE__L_EXTENSIONS
221typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
222#endif
223
224// OSX has nice foo_l() functions that let you turn off use of the global
225// locale.  Linux, not so much.  The following functions avoid the locale when
226// that's possible and otherwise do the wrong thing.  FIXME.
227#if defined(__linux__) || defined(EMSCRIPTEN)
228
229#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
230decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
231inline _LIBCPP_INLINE_VISIBILITY
232__mb_cur_max_l(locale_t __l)
233{
234  return MB_CUR_MAX_L(__l);
235}
236#else  // _LIBCPP_LOCALE__L_EXTENSIONS
237_LIBCPP_ALWAYS_INLINE inline
238decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
239{
240  __locale_raii __current(uselocale(__l), uselocale);
241  return MB_CUR_MAX;
242}
243#endif // _LIBCPP_LOCALE__L_EXTENSIONS
244
245_LIBCPP_ALWAYS_INLINE inline
246wint_t __btowc_l(int __c, locale_t __l)
247{
248#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
249  return btowc_l(__c, __l);
250#else
251  __locale_raii __current(uselocale(__l), uselocale);
252  return btowc(__c);
253#endif
254}
255
256_LIBCPP_ALWAYS_INLINE inline
257int __wctob_l(wint_t __c, locale_t __l)
258{
259#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
260  return wctob_l(__c, __l);
261#else
262  __locale_raii __current(uselocale(__l), uselocale);
263  return wctob(__c);
264#endif
265}
266
267_LIBCPP_ALWAYS_INLINE inline
268size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
269                      size_t __len, mbstate_t *__ps, locale_t __l)
270{
271#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
272  return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
273#else
274  __locale_raii __current(uselocale(__l), uselocale);
275  return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
276#endif
277}
278
279_LIBCPP_ALWAYS_INLINE inline
280size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
281{
282#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
283  return wcrtomb_l(__s, __wc, __ps, __l);
284#else
285  __locale_raii __current(uselocale(__l), uselocale);
286  return wcrtomb(__s, __wc, __ps);
287#endif
288}
289
290_LIBCPP_ALWAYS_INLINE inline
291size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
292                      size_t __len, mbstate_t *__ps, locale_t __l)
293{
294#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
295  return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
296#else
297  __locale_raii __current(uselocale(__l), uselocale);
298  return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
299#endif
300}
301
302_LIBCPP_ALWAYS_INLINE inline
303size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
304                   mbstate_t *__ps, locale_t __l)
305{
306#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
307  return mbrtowc_l(__pwc, __s, __n, __ps, __l);
308#else
309  __locale_raii __current(uselocale(__l), uselocale);
310  return mbrtowc(__pwc, __s, __n, __ps);
311#endif
312}
313
314_LIBCPP_ALWAYS_INLINE inline
315int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
316{
317#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
318  return mbtowc_l(__pwc, __pmb, __max, __l);
319#else
320  __locale_raii __current(uselocale(__l), uselocale);
321  return mbtowc(__pwc, __pmb, __max);
322#endif
323}
324
325_LIBCPP_ALWAYS_INLINE inline
326size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
327{
328#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
329  return mbrlen_l(__s, __n, __ps, __l);
330#else
331  __locale_raii __current(uselocale(__l), uselocale);
332  return mbrlen(__s, __n, __ps);
333#endif
334}
335
336_LIBCPP_ALWAYS_INLINE inline
337lconv *__localeconv_l(locale_t __l)
338{
339#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
340  return localeconv_l(__l);
341#else
342  __locale_raii __current(uselocale(__l), uselocale);
343  return localeconv();
344#endif
345}
346
347_LIBCPP_ALWAYS_INLINE inline
348size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
349                     mbstate_t *__ps, locale_t __l)
350{
351#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
352  return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
353#else
354  __locale_raii __current(uselocale(__l), uselocale);
355  return mbsrtowcs(__dest, __src, __len, __ps);
356#endif
357}
358
359inline
360int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
361  va_list __va;
362  va_start(__va, __format);
363#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
364  int __res = vsnprintf_l(__s, __n, __l, __format, __va);
365#else
366  __locale_raii __current(uselocale(__l), uselocale);
367  int __res = vsnprintf(__s, __n, __format, __va);
368#endif
369  va_end(__va);
370  return __res;
371}
372
373inline
374int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
375  va_list __va;
376  va_start(__va, __format);
377#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
378  int __res = vasprintf_l(__s, __l, __format, __va);
379#else
380  __locale_raii __current(uselocale(__l), uselocale);
381  int __res = vasprintf(__s, __format, __va);
382#endif
383  va_end(__va);
384  return __res;
385}
386
387inline
388int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
389  va_list __va;
390  va_start(__va, __format);
391#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
392  int __res = vsscanf_l(__s, __l, __format, __va);
393#else
394  __locale_raii __current(uselocale(__l), uselocale);
395  int __res = vsscanf(__s, __format, __va);
396#endif
397  va_end(__va);
398  return __res;
399}
400
401#endif  // __linux__
402
403// __scan_keyword
404// Scans [__b, __e) until a match is found in the basic_strings range
405//  [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
406//  __b will be incremented (visibly), consuming CharT until a match is found
407//  or proved to not exist.  A keyword may be "", in which will match anything.
408//  If one keyword is a prefix of another, and the next CharT in the input
409//  might match another keyword, the algorithm will attempt to find the longest
410//  matching keyword.  If the longer matching keyword ends up not matching, then
411//  no keyword match is found.  If no keyword match is found, __ke is returned
412//  and failbit is set in __err.
413//  Else an iterator pointing to the matching keyword is found.  If more than
414//  one keyword matches, an iterator to the first matching keyword is returned.
415//  If on exit __b == __e, eofbit is set in __err.  If __case_senstive is false,
416//  __ct is used to force to lower case before comparing characters.
417//  Examples:
418//  Keywords:  "a", "abb"
419//  If the input is "a", the first keyword matches and eofbit is set.
420//  If the input is "abc", no match is found and "ab" are consumed.
421template <class _InputIterator, class _ForwardIterator, class _Ctype>
422_LIBCPP_HIDDEN
423_ForwardIterator
424__scan_keyword(_InputIterator& __b, _InputIterator __e,
425               _ForwardIterator __kb, _ForwardIterator __ke,
426               const _Ctype& __ct, ios_base::iostate& __err,
427               bool __case_sensitive = true)
428{
429    typedef typename iterator_traits<_InputIterator>::value_type _CharT;
430    size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
431    const unsigned char __doesnt_match = '\0';
432    const unsigned char __might_match = '\1';
433    const unsigned char __does_match = '\2';
434    unsigned char __statbuf[100];
435    unsigned char* __status = __statbuf;
436    unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
437    if (__nkw > sizeof(__statbuf))
438    {
439        __status = (unsigned char*)malloc(__nkw);
440        if (__status == 0)
441            __throw_bad_alloc();
442        __stat_hold.reset(__status);
443    }
444    size_t __n_might_match = __nkw;  // At this point, any keyword might match
445    size_t __n_does_match = 0;       // but none of them definitely do
446    // Initialize all statuses to __might_match, except for "" keywords are __does_match
447    unsigned char* __st = __status;
448    for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
449    {
450        if (!__ky->empty())
451            *__st = __might_match;
452        else
453        {
454            *__st = __does_match;
455            --__n_might_match;
456            ++__n_does_match;
457        }
458    }
459    // While there might be a match, test keywords against the next CharT
460    for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
461    {
462        // Peek at the next CharT but don't consume it
463        _CharT __c = *__b;
464        if (!__case_sensitive)
465            __c = __ct.toupper(__c);
466        bool __consume = false;
467        // For each keyword which might match, see if the __indx character is __c
468        // If a match if found, consume __c
469        // If a match is found, and that is the last character in the keyword,
470        //    then that keyword matches.
471        // If the keyword doesn't match this character, then change the keyword
472        //    to doesn't match
473        __st = __status;
474        for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
475        {
476            if (*__st == __might_match)
477            {
478                _CharT __kc = (*__ky)[__indx];
479                if (!__case_sensitive)
480                    __kc = __ct.toupper(__kc);
481                if (__c == __kc)
482                {
483                    __consume = true;
484                    if (__ky->size() == __indx+1)
485                    {
486                        *__st = __does_match;
487                        --__n_might_match;
488                        ++__n_does_match;
489                    }
490                }
491                else
492                {
493                    *__st = __doesnt_match;
494                    --__n_might_match;
495                }
496            }
497        }
498        // consume if we matched a character
499        if (__consume)
500        {
501            ++__b;
502            // If we consumed a character and there might be a matched keyword that
503            //   was marked matched on a previous iteration, then such keywords
504            //   which are now marked as not matching.
505            if (__n_might_match + __n_does_match > 1)
506            {
507                __st = __status;
508                for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
509                {
510                    if (*__st == __does_match && __ky->size() != __indx+1)
511                    {
512                        *__st = __doesnt_match;
513                        --__n_does_match;
514                    }
515                }
516            }
517        }
518    }
519    // We've exited the loop because we hit eof and/or we have no more "might matches".
520    if (__b == __e)
521        __err |= ios_base::eofbit;
522    // Return the first matching result
523    for (__st = __status; __kb != __ke; ++__kb, ++__st)
524        if (*__st == __does_match)
525            break;
526    if (__kb == __ke)
527        __err |= ios_base::failbit;
528    return __kb;
529}
530
531struct __num_get_base
532{
533    static const int __num_get_buf_sz = 40;
534
535    static int __get_base(ios_base&);
536    static const char __src[33];
537};
538
539void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
540                      ios_base::iostate& __err);
541
542template <class _CharT>
543struct __num_get
544    : protected __num_get_base
545{
546    static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
547    static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
548                                      _CharT& __thousands_sep);
549    static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
550                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
551                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
552    static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
553                                   char* __a, char*& __a_end,
554                                   _CharT __decimal_point, _CharT __thousands_sep,
555                                   const string& __grouping, unsigned* __g,
556                                   unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
557};
558
559template <class _CharT>
560string
561__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
562{
563    locale __loc = __iob.getloc();
564    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
565    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
566    __thousands_sep = __np.thousands_sep();
567    return __np.grouping();
568}
569
570template <class _CharT>
571string
572__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
573                    _CharT& __thousands_sep)
574{
575    locale __loc = __iob.getloc();
576    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
577    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
578    __decimal_point = __np.decimal_point();
579    __thousands_sep = __np.thousands_sep();
580    return __np.grouping();
581}
582
583template <class _CharT>
584int
585__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
586                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
587                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
588{
589    if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
590    {
591        *__a_end++ = __ct == __atoms[24] ? '+' : '-';
592        __dc = 0;
593        return 0;
594    }
595    if (__grouping.size() != 0 && __ct == __thousands_sep)
596    {
597        if (__g_end-__g < __num_get_buf_sz)
598        {
599            *__g_end++ = __dc;
600            __dc = 0;
601        }
602        return 0;
603    }
604    ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
605    if (__f >= 24)
606        return -1;
607    switch (__base)
608    {
609    case 8:
610    case 10:
611        if (__f >= __base)
612            return -1;
613        break;
614    case 16:
615        if (__f < 22)
616            break;
617        if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
618        {
619            __dc = 0;
620            *__a_end++ = __src[__f];
621            return 0;
622        }
623        return -1;
624    }
625    *__a_end++ = __src[__f];
626    ++__dc;
627    return 0;
628}
629
630template <class _CharT>
631int
632__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
633                    _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
634                    unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
635{
636    if (__ct == __decimal_point)
637    {
638        if (!__in_units)
639            return -1;
640        __in_units = false;
641        *__a_end++ = '.';
642        if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
643            *__g_end++ = __dc;
644        return 0;
645    }
646    if (__ct == __thousands_sep && __grouping.size() != 0)
647    {
648        if (!__in_units)
649            return -1;
650        if (__g_end-__g < __num_get_buf_sz)
651        {
652            *__g_end++ = __dc;
653            __dc = 0;
654        }
655        return 0;
656    }
657    ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
658    if (__f >= 32)
659        return -1;
660    char __x = __src[__f];
661    if (__x == '-' || __x == '+')
662    {
663        if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
664        {
665            *__a_end++ = __x;
666            return 0;
667        }
668        return -1;
669    }
670    if (__x == 'x' || __x == 'X')
671        __exp = 'P';
672    else if ((__x & 0x5F) == __exp)
673    {
674        __exp |= 0x80;
675        if (__in_units)
676        {
677            __in_units = false;
678            if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
679                *__g_end++ = __dc;
680        }
681    }
682    *__a_end++ = __x;
683    if (__f >= 22)
684        return 0;
685    ++__dc;
686    return 0;
687}
688
689_LIBCPP_EXTERN_TEMPLATE(struct __num_get<char>)
690_LIBCPP_EXTERN_TEMPLATE(struct __num_get<wchar_t>)
691
692template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
693class _LIBCPP_TYPE_VIS num_get
694    : public locale::facet,
695      private __num_get<_CharT>
696{
697public:
698    typedef _CharT char_type;
699    typedef _InputIterator iter_type;
700
701    _LIBCPP_ALWAYS_INLINE
702    explicit num_get(size_t __refs = 0)
703        : locale::facet(__refs) {}
704
705    _LIBCPP_ALWAYS_INLINE
706    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
707                  ios_base::iostate& __err, bool& __v) const
708    {
709        return do_get(__b, __e, __iob, __err, __v);
710    }
711
712    _LIBCPP_ALWAYS_INLINE
713    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
714                  ios_base::iostate& __err, long& __v) const
715    {
716        return do_get(__b, __e, __iob, __err, __v);
717    }
718
719    _LIBCPP_ALWAYS_INLINE
720    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
721                  ios_base::iostate& __err, long long& __v) const
722    {
723        return do_get(__b, __e, __iob, __err, __v);
724    }
725
726    _LIBCPP_ALWAYS_INLINE
727    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
728                  ios_base::iostate& __err, unsigned short& __v) const
729    {
730        return do_get(__b, __e, __iob, __err, __v);
731    }
732
733    _LIBCPP_ALWAYS_INLINE
734    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
735                  ios_base::iostate& __err, unsigned int& __v) const
736    {
737        return do_get(__b, __e, __iob, __err, __v);
738    }
739
740    _LIBCPP_ALWAYS_INLINE
741    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
742                  ios_base::iostate& __err, unsigned long& __v) const
743    {
744        return do_get(__b, __e, __iob, __err, __v);
745    }
746
747    _LIBCPP_ALWAYS_INLINE
748    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
749                  ios_base::iostate& __err, unsigned long long& __v) const
750    {
751        return do_get(__b, __e, __iob, __err, __v);
752    }
753
754    _LIBCPP_ALWAYS_INLINE
755    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
756                  ios_base::iostate& __err, float& __v) const
757    {
758        return do_get(__b, __e, __iob, __err, __v);
759    }
760
761    _LIBCPP_ALWAYS_INLINE
762    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
763                  ios_base::iostate& __err, double& __v) const
764    {
765        return do_get(__b, __e, __iob, __err, __v);
766    }
767
768    _LIBCPP_ALWAYS_INLINE
769    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
770                  ios_base::iostate& __err, long double& __v) const
771    {
772        return do_get(__b, __e, __iob, __err, __v);
773    }
774
775    _LIBCPP_ALWAYS_INLINE
776    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
777                  ios_base::iostate& __err, void*& __v) const
778    {
779        return do_get(__b, __e, __iob, __err, __v);
780    }
781
782    static locale::id id;
783
784protected:
785    _LIBCPP_ALWAYS_INLINE
786    ~num_get() {}
787
788    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
789                             ios_base::iostate& __err, bool& __v) const;
790    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
791                             ios_base::iostate& __err, long& __v) const;
792    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
793                             ios_base::iostate& __err, long long& __v) const;
794    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
795                             ios_base::iostate& __err, unsigned short& __v) const;
796    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
797                             ios_base::iostate& __err, unsigned int& __v) const;
798    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
799                             ios_base::iostate& __err, unsigned long& __v) const;
800    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
801                             ios_base::iostate& __err, unsigned long long& __v) const;
802    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
803                             ios_base::iostate& __err, float& __v) const;
804    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
805                             ios_base::iostate& __err, double& __v) const;
806    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
807                             ios_base::iostate& __err, long double& __v) const;
808    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
809                             ios_base::iostate& __err, void*& __v) const;
810};
811
812template <class _CharT, class _InputIterator>
813locale::id
814num_get<_CharT, _InputIterator>::id;
815
816template <class _Tp>
817_Tp
818__num_get_signed_integral(const char* __a, const char* __a_end,
819                          ios_base::iostate& __err, int __base)
820{
821    if (__a != __a_end)
822    {
823        typename remove_reference<decltype(errno)>::type __save_errno = errno;
824        errno = 0;
825        char *__p2;
826        long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
827        typename remove_reference<decltype(errno)>::type __current_errno = errno;
828        if (__current_errno == 0)
829            errno = __save_errno;
830        if (__p2 != __a_end)
831        {
832            __err = ios_base::failbit;
833            return 0;
834        }
835        else if (__current_errno == ERANGE         ||
836                 __ll < numeric_limits<_Tp>::min() ||
837                 numeric_limits<_Tp>::max() < __ll)
838        {
839            __err = ios_base::failbit;
840            if (__ll > 0)
841                return numeric_limits<_Tp>::max();
842            else
843                return numeric_limits<_Tp>::min();
844        }
845        return static_cast<_Tp>(__ll);
846    }
847    __err = ios_base::failbit;
848    return 0;
849}
850
851template <class _Tp>
852_Tp
853__num_get_unsigned_integral(const char* __a, const char* __a_end,
854                            ios_base::iostate& __err, int __base)
855{
856    if (__a != __a_end)
857    {
858        if (*__a == '-')
859        {
860            __err = ios_base::failbit;
861            return 0;
862        }
863        typename remove_reference<decltype(errno)>::type __save_errno = errno;
864        errno = 0;
865        char *__p2;
866        unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
867        typename remove_reference<decltype(errno)>::type __current_errno = errno;
868        if (__current_errno == 0)
869            errno = __save_errno;
870        if (__p2 != __a_end)
871        {
872            __err = ios_base::failbit;
873            return 0;
874        }
875        else if (__current_errno == ERANGE ||
876                 numeric_limits<_Tp>::max() < __ll)
877        {
878            __err = ios_base::failbit;
879            return numeric_limits<_Tp>::max();
880        }
881        return static_cast<_Tp>(__ll);
882    }
883    __err = ios_base::failbit;
884    return 0;
885}
886
887template <class _Tp>
888_Tp
889__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
890{
891    if (__a != __a_end)
892    {
893        typename remove_reference<decltype(errno)>::type __save_errno = errno;
894        errno = 0;
895        char *__p2;
896        long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
897        typename remove_reference<decltype(errno)>::type __current_errno = errno;
898        if (__current_errno == 0)
899            errno = __save_errno;
900        if (__p2 != __a_end)
901        {
902            __err = ios_base::failbit;
903            return 0;
904        }
905        else if (__current_errno == ERANGE)
906            __err = ios_base::failbit;
907        return static_cast<_Tp>(__ld);
908    }
909    __err = ios_base::failbit;
910    return 0;
911}
912
913template <class _CharT, class _InputIterator>
914_InputIterator
915num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
916                                        ios_base& __iob,
917                                        ios_base::iostate& __err,
918                                        bool& __v) const
919{
920    if ((__iob.flags() & ios_base::boolalpha) == 0)
921    {
922        long __lv = -1;
923        __b = do_get(__b, __e, __iob, __err, __lv);
924        switch (__lv)
925        {
926        case 0:
927            __v = false;
928            break;
929        case 1:
930            __v = true;
931            break;
932        default:
933            __v = true;
934            __err = ios_base::failbit;
935            break;
936        }
937        return __b;
938    }
939    const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
940    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
941    typedef typename numpunct<_CharT>::string_type string_type;
942    const string_type __names[2] = {__np.truename(), __np.falsename()};
943    const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
944                                            __ct, __err);
945    __v = __i == __names;
946    return __b;
947}
948
949template <class _CharT, class _InputIterator>
950_InputIterator
951num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
952                                        ios_base& __iob,
953                                        ios_base::iostate& __err,
954                                        long& __v) const
955{
956    // Stage 1
957    int __base = this->__get_base(__iob);
958    // Stage 2
959    char_type __atoms[26];
960    char_type __thousands_sep;
961    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
962    string __buf;
963    __buf.resize(__buf.capacity());
964    char* __a = &__buf[0];
965    char* __a_end = __a;
966    unsigned __g[__num_get_base::__num_get_buf_sz];
967    unsigned* __g_end = __g;
968    unsigned __dc = 0;
969    for (; __b != __e; ++__b)
970    {
971        if (__a_end - __a == __buf.size())
972        {
973            size_t __tmp = __buf.size();
974            __buf.resize(2*__buf.size());
975            __buf.resize(__buf.capacity());
976            __a = &__buf[0];
977            __a_end = __a + __tmp;
978        }
979        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
980                                    __thousands_sep, __grouping, __g, __g_end,
981                                    __atoms))
982            break;
983    }
984    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
985        *__g_end++ = __dc;
986    // Stage 3
987    __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base);
988    // Digit grouping checked
989    __check_grouping(__grouping, __g, __g_end, __err);
990    // EOF checked
991    if (__b == __e)
992        __err |= ios_base::eofbit;
993    return __b;
994}
995
996template <class _CharT, class _InputIterator>
997_InputIterator
998num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
999                                        ios_base& __iob,
1000                                        ios_base::iostate& __err,
1001                                        long long& __v) const
1002{
1003    // Stage 1
1004    int __base = this->__get_base(__iob);
1005    // Stage 2
1006    char_type __atoms[26];
1007    char_type __thousands_sep;
1008    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1009    string __buf;
1010    __buf.resize(__buf.capacity());
1011    char* __a = &__buf[0];
1012    char* __a_end = __a;
1013    unsigned __g[__num_get_base::__num_get_buf_sz];
1014    unsigned* __g_end = __g;
1015    unsigned __dc = 0;
1016    for (; __b != __e; ++__b)
1017    {
1018        if (__a_end - __a == __buf.size())
1019        {
1020            size_t __tmp = __buf.size();
1021            __buf.resize(2*__buf.size());
1022            __buf.resize(__buf.capacity());
1023            __a = &__buf[0];
1024            __a_end = __a + __tmp;
1025        }
1026        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1027                                    __thousands_sep, __grouping, __g, __g_end,
1028                                    __atoms))
1029            break;
1030    }
1031    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1032        *__g_end++ = __dc;
1033    // Stage 3
1034    __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base);
1035    // Digit grouping checked
1036    __check_grouping(__grouping, __g, __g_end, __err);
1037    // EOF checked
1038    if (__b == __e)
1039        __err |= ios_base::eofbit;
1040    return __b;
1041}
1042
1043template <class _CharT, class _InputIterator>
1044_InputIterator
1045num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1046                                        ios_base& __iob,
1047                                        ios_base::iostate& __err,
1048                                        unsigned short& __v) const
1049{
1050    // Stage 1
1051    int __base = this->__get_base(__iob);
1052    // Stage 2
1053    char_type __atoms[26];
1054    char_type __thousands_sep;
1055    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1056    string __buf;
1057    __buf.resize(__buf.capacity());
1058    char* __a = &__buf[0];
1059    char* __a_end = __a;
1060    unsigned __g[__num_get_base::__num_get_buf_sz];
1061    unsigned* __g_end = __g;
1062    unsigned __dc = 0;
1063    for (; __b != __e; ++__b)
1064    {
1065        if (__a_end - __a == __buf.size())
1066        {
1067            size_t __tmp = __buf.size();
1068            __buf.resize(2*__buf.size());
1069            __buf.resize(__buf.capacity());
1070            __a = &__buf[0];
1071            __a_end = __a + __tmp;
1072        }
1073        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1074                                    __thousands_sep, __grouping, __g, __g_end,
1075                                    __atoms))
1076            break;
1077    }
1078    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1079        *__g_end++ = __dc;
1080    // Stage 3
1081    __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base);
1082    // Digit grouping checked
1083    __check_grouping(__grouping, __g, __g_end, __err);
1084    // EOF checked
1085    if (__b == __e)
1086        __err |= ios_base::eofbit;
1087    return __b;
1088}
1089
1090template <class _CharT, class _InputIterator>
1091_InputIterator
1092num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1093                                        ios_base& __iob,
1094                                        ios_base::iostate& __err,
1095                                        unsigned int& __v) const
1096{
1097    // Stage 1
1098    int __base = this->__get_base(__iob);
1099    // Stage 2
1100    char_type __atoms[26];
1101    char_type __thousands_sep;
1102    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1103    string __buf;
1104    __buf.resize(__buf.capacity());
1105    char* __a = &__buf[0];
1106    char* __a_end = __a;
1107    unsigned __g[__num_get_base::__num_get_buf_sz];
1108    unsigned* __g_end = __g;
1109    unsigned __dc = 0;
1110    for (; __b != __e; ++__b)
1111    {
1112        if (__a_end - __a == __buf.size())
1113        {
1114            size_t __tmp = __buf.size();
1115            __buf.resize(2*__buf.size());
1116            __buf.resize(__buf.capacity());
1117            __a = &__buf[0];
1118            __a_end = __a + __tmp;
1119        }
1120        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1121                                    __thousands_sep, __grouping, __g, __g_end,
1122                                    __atoms))
1123            break;
1124    }
1125    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1126        *__g_end++ = __dc;
1127    // Stage 3
1128    __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base);
1129    // Digit grouping checked
1130    __check_grouping(__grouping, __g, __g_end, __err);
1131    // EOF checked
1132    if (__b == __e)
1133        __err |= ios_base::eofbit;
1134    return __b;
1135}
1136
1137template <class _CharT, class _InputIterator>
1138_InputIterator
1139num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1140                                        ios_base& __iob,
1141                                        ios_base::iostate& __err,
1142                                        unsigned long& __v) const
1143{
1144    // Stage 1
1145    int __base = this->__get_base(__iob);
1146    // Stage 2
1147    char_type __atoms[26];
1148    char_type __thousands_sep;
1149    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1150    string __buf;
1151    __buf.resize(__buf.capacity());
1152    char* __a = &__buf[0];
1153    char* __a_end = __a;
1154    unsigned __g[__num_get_base::__num_get_buf_sz];
1155    unsigned* __g_end = __g;
1156    unsigned __dc = 0;
1157    for (; __b != __e; ++__b)
1158    {
1159        if (__a_end - __a == __buf.size())
1160        {
1161            size_t __tmp = __buf.size();
1162            __buf.resize(2*__buf.size());
1163            __buf.resize(__buf.capacity());
1164            __a = &__buf[0];
1165            __a_end = __a + __tmp;
1166        }
1167        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1168                                    __thousands_sep, __grouping, __g, __g_end,
1169                                    __atoms))
1170            break;
1171    }
1172    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1173        *__g_end++ = __dc;
1174    // Stage 3
1175    __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base);
1176    // Digit grouping checked
1177    __check_grouping(__grouping, __g, __g_end, __err);
1178    // EOF checked
1179    if (__b == __e)
1180        __err |= ios_base::eofbit;
1181    return __b;
1182}
1183
1184template <class _CharT, class _InputIterator>
1185_InputIterator
1186num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1187                                        ios_base& __iob,
1188                                        ios_base::iostate& __err,
1189                                        unsigned long long& __v) const
1190{
1191    // Stage 1
1192    int __base = this->__get_base(__iob);
1193    // Stage 2
1194    char_type __atoms[26];
1195    char_type __thousands_sep;
1196    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
1197    string __buf;
1198    __buf.resize(__buf.capacity());
1199    char* __a = &__buf[0];
1200    char* __a_end = __a;
1201    unsigned __g[__num_get_base::__num_get_buf_sz];
1202    unsigned* __g_end = __g;
1203    unsigned __dc = 0;
1204    for (; __b != __e; ++__b)
1205    {
1206        if (__a_end - __a == __buf.size())
1207        {
1208            size_t __tmp = __buf.size();
1209            __buf.resize(2*__buf.size());
1210            __buf.resize(__buf.capacity());
1211            __a = &__buf[0];
1212            __a_end = __a + __tmp;
1213        }
1214        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1215                                    __thousands_sep, __grouping, __g, __g_end,
1216                                    __atoms))
1217            break;
1218    }
1219    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
1220        *__g_end++ = __dc;
1221    // Stage 3
1222    __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base);
1223    // Digit grouping checked
1224    __check_grouping(__grouping, __g, __g_end, __err);
1225    // EOF checked
1226    if (__b == __e)
1227        __err |= ios_base::eofbit;
1228    return __b;
1229}
1230
1231template <class _CharT, class _InputIterator>
1232_InputIterator
1233num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1234                                        ios_base& __iob,
1235                                        ios_base::iostate& __err,
1236                                        float& __v) const
1237{
1238    // Stage 1, nothing to do
1239    // Stage 2
1240    char_type __atoms[32];
1241    char_type __decimal_point;
1242    char_type __thousands_sep;
1243    string __grouping = this->__stage2_float_prep(__iob, __atoms,
1244                                                  __decimal_point,
1245                                                  __thousands_sep);
1246    string __buf;
1247    __buf.resize(__buf.capacity());
1248    char* __a = &__buf[0];
1249    char* __a_end = __a;
1250    unsigned __g[__num_get_base::__num_get_buf_sz];
1251    unsigned* __g_end = __g;
1252    unsigned __dc = 0;
1253    bool __in_units = true;
1254    char __exp = 'E';
1255    for (; __b != __e; ++__b)
1256    {
1257        if (__a_end - __a == __buf.size())
1258        {
1259            size_t __tmp = __buf.size();
1260            __buf.resize(2*__buf.size());
1261            __buf.resize(__buf.capacity());
1262            __a = &__buf[0];
1263            __a_end = __a + __tmp;
1264        }
1265        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1266                                      __decimal_point, __thousands_sep,
1267                                      __grouping, __g, __g_end,
1268                                      __dc, __atoms))
1269            break;
1270    }
1271    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1272        *__g_end++ = __dc;
1273    // Stage 3
1274    __v = __num_get_float<float>(__a, __a_end, __err);
1275    // Digit grouping checked
1276    __check_grouping(__grouping, __g, __g_end, __err);
1277    // EOF checked
1278    if (__b == __e)
1279        __err |= ios_base::eofbit;
1280    return __b;
1281}
1282
1283template <class _CharT, class _InputIterator>
1284_InputIterator
1285num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1286                                        ios_base& __iob,
1287                                        ios_base::iostate& __err,
1288                                        double& __v) const
1289{
1290    // Stage 1, nothing to do
1291    // Stage 2
1292    char_type __atoms[32];
1293    char_type __decimal_point;
1294    char_type __thousands_sep;
1295    string __grouping = this->__stage2_float_prep(__iob, __atoms,
1296                                                  __decimal_point,
1297                                                  __thousands_sep);
1298    string __buf;
1299    __buf.resize(__buf.capacity());
1300    char* __a = &__buf[0];
1301    char* __a_end = __a;
1302    unsigned __g[__num_get_base::__num_get_buf_sz];
1303    unsigned* __g_end = __g;
1304    unsigned __dc = 0;
1305    bool __in_units = true;
1306    char __exp = 'E';
1307    for (; __b != __e; ++__b)
1308    {
1309        if (__a_end - __a == __buf.size())
1310        {
1311            size_t __tmp = __buf.size();
1312            __buf.resize(2*__buf.size());
1313            __buf.resize(__buf.capacity());
1314            __a = &__buf[0];
1315            __a_end = __a + __tmp;
1316        }
1317        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1318                                      __decimal_point, __thousands_sep,
1319                                      __grouping, __g, __g_end,
1320                                      __dc, __atoms))
1321            break;
1322    }
1323    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1324        *__g_end++ = __dc;
1325    // Stage 3
1326    __v = __num_get_float<double>(__a, __a_end, __err);
1327    // Digit grouping checked
1328    __check_grouping(__grouping, __g, __g_end, __err);
1329    // EOF checked
1330    if (__b == __e)
1331        __err |= ios_base::eofbit;
1332    return __b;
1333}
1334
1335template <class _CharT, class _InputIterator>
1336_InputIterator
1337num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1338                                        ios_base& __iob,
1339                                        ios_base::iostate& __err,
1340                                        long double& __v) const
1341{
1342    // Stage 1, nothing to do
1343    // Stage 2
1344    char_type __atoms[32];
1345    char_type __decimal_point;
1346    char_type __thousands_sep;
1347    string __grouping = this->__stage2_float_prep(__iob, __atoms,
1348                                                  __decimal_point,
1349                                                  __thousands_sep);
1350    string __buf;
1351    __buf.resize(__buf.capacity());
1352    char* __a = &__buf[0];
1353    char* __a_end = __a;
1354    unsigned __g[__num_get_base::__num_get_buf_sz];
1355    unsigned* __g_end = __g;
1356    unsigned __dc = 0;
1357    bool __in_units = true;
1358    char __exp = 'E';
1359    for (; __b != __e; ++__b)
1360    {
1361        if (__a_end - __a == __buf.size())
1362        {
1363            size_t __tmp = __buf.size();
1364            __buf.resize(2*__buf.size());
1365            __buf.resize(__buf.capacity());
1366            __a = &__buf[0];
1367            __a_end = __a + __tmp;
1368        }
1369        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
1370                                      __decimal_point, __thousands_sep,
1371                                      __grouping, __g, __g_end,
1372                                      __dc, __atoms))
1373            break;
1374    }
1375    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
1376        *__g_end++ = __dc;
1377    // Stage 3
1378    __v = __num_get_float<long double>(__a, __a_end, __err);
1379    // Digit grouping checked
1380    __check_grouping(__grouping, __g, __g_end, __err);
1381    // EOF checked
1382    if (__b == __e)
1383        __err |= ios_base::eofbit;
1384    return __b;
1385}
1386
1387template <class _CharT, class _InputIterator>
1388_InputIterator
1389num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
1390                                        ios_base& __iob,
1391                                        ios_base::iostate& __err,
1392                                        void*& __v) const
1393{
1394    // Stage 1
1395    int __base = 16;
1396    // Stage 2
1397    char_type __atoms[26];
1398    char_type __thousands_sep = 0;
1399    string __grouping;
1400    use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
1401                                                    __num_get_base::__src + 26, __atoms);
1402    string __buf;
1403    __buf.resize(__buf.capacity());
1404    char* __a = &__buf[0];
1405    char* __a_end = __a;
1406    unsigned __g[__num_get_base::__num_get_buf_sz];
1407    unsigned* __g_end = __g;
1408    unsigned __dc = 0;
1409    for (; __b != __e; ++__b)
1410    {
1411        if (__a_end - __a == __buf.size())
1412        {
1413            size_t __tmp = __buf.size();
1414            __buf.resize(2*__buf.size());
1415            __buf.resize(__buf.capacity());
1416            __a = &__buf[0];
1417            __a_end = __a + __tmp;
1418        }
1419        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
1420                                    __thousands_sep, __grouping,
1421                                    __g, __g_end, __atoms))
1422            break;
1423    }
1424    // Stage 3
1425    __a[sizeof(__a)-1] = 0;
1426#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1427    if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
1428#else
1429    if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1)
1430#endif
1431        __err = ios_base::failbit;
1432    // EOF checked
1433    if (__b == __e)
1434        __err |= ios_base::eofbit;
1435    return __b;
1436}
1437
1438_LIBCPP_EXTERN_TEMPLATE(class num_get<char>)
1439_LIBCPP_EXTERN_TEMPLATE(class num_get<wchar_t>)
1440
1441struct __num_put_base
1442{
1443protected:
1444    static void __format_int(char* __fmt, const char* __len, bool __signd,
1445                             ios_base::fmtflags __flags);
1446    static bool __format_float(char* __fmt, const char* __len,
1447                               ios_base::fmtflags __flags);
1448    static char* __identify_padding(char* __nb, char* __ne,
1449                                    const ios_base& __iob);
1450};
1451
1452template <class _CharT>
1453struct __num_put
1454    : protected __num_put_base
1455{
1456    static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
1457                                      _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1458                                      const locale& __loc);
1459    static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
1460                                        _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1461                                        const locale& __loc);
1462};
1463
1464template <class _CharT>
1465void
1466__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
1467                                         _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1468                                         const locale& __loc)
1469{
1470    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);
1471    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1472    string __grouping = __npt.grouping();
1473    if (__grouping.empty())
1474    {
1475        __ct.widen(__nb, __ne, __ob);
1476        __oe = __ob + (__ne - __nb);
1477    }
1478    else
1479    {
1480        __oe = __ob;
1481        char* __nf = __nb;
1482        if (*__nf == '-' || *__nf == '+')
1483            *__oe++ = __ct.widen(*__nf++);
1484        if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1485                                                   __nf[1] == 'X'))
1486        {
1487            *__oe++ = __ct.widen(*__nf++);
1488            *__oe++ = __ct.widen(*__nf++);
1489        }
1490        reverse(__nf, __ne);
1491        _CharT __thousands_sep = __npt.thousands_sep();
1492        unsigned __dc = 0;
1493        unsigned __dg = 0;
1494        for (char* __p = __nf; __p < __ne; ++__p)
1495        {
1496            if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
1497                __dc == static_cast<unsigned>(__grouping[__dg]))
1498            {
1499                *__oe++ = __thousands_sep;
1500                __dc = 0;
1501                if (__dg < __grouping.size()-1)
1502                    ++__dg;
1503            }
1504            *__oe++ = __ct.widen(*__p);
1505            ++__dc;
1506        }
1507        reverse(__ob + (__nf - __nb), __oe);
1508    }
1509    if (__np == __ne)
1510        __op = __oe;
1511    else
1512        __op = __ob + (__np - __nb);
1513}
1514
1515template <class _CharT>
1516void
1517__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
1518                                           _CharT* __ob, _CharT*& __op, _CharT*& __oe,
1519                                           const locale& __loc)
1520{
1521    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);
1522    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
1523    string __grouping = __npt.grouping();
1524    __oe = __ob;
1525    char* __nf = __nb;
1526    if (*__nf == '-' || *__nf == '+')
1527        *__oe++ = __ct.widen(*__nf++);
1528    char* __ns;
1529    if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
1530                                               __nf[1] == 'X'))
1531    {
1532        *__oe++ = __ct.widen(*__nf++);
1533        *__oe++ = __ct.widen(*__nf++);
1534        for (__ns = __nf; __ns < __ne; ++__ns)
1535            if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1536                break;
1537    }
1538    else
1539    {
1540        for (__ns = __nf; __ns < __ne; ++__ns)
1541            if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
1542                break;
1543    }
1544    if (__grouping.empty())
1545    {
1546        __ct.widen(__nf, __ns, __oe);
1547        __oe += __ns - __nf;
1548    }
1549    else
1550    {
1551        reverse(__nf, __ns);
1552        _CharT __thousands_sep = __npt.thousands_sep();
1553        unsigned __dc = 0;
1554        unsigned __dg = 0;
1555        for (char* __p = __nf; __p < __ns; ++__p)
1556        {
1557            if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
1558            {
1559                *__oe++ = __thousands_sep;
1560                __dc = 0;
1561                if (__dg < __grouping.size()-1)
1562                    ++__dg;
1563            }
1564            *__oe++ = __ct.widen(*__p);
1565            ++__dc;
1566        }
1567        reverse(__ob + (__nf - __nb), __oe);
1568    }
1569    for (__nf = __ns; __nf < __ne; ++__nf)
1570    {
1571        if (*__nf == '.')
1572        {
1573            *__oe++ = __npt.decimal_point();
1574            ++__nf;
1575            break;
1576        }
1577        else
1578            *__oe++ = __ct.widen(*__nf);
1579    }
1580    __ct.widen(__nf, __ne, __oe);
1581    __oe += __ne - __nf;
1582    if (__np == __ne)
1583        __op = __oe;
1584    else
1585        __op = __ob + (__np - __nb);
1586}
1587
1588_LIBCPP_EXTERN_TEMPLATE(struct __num_put<char>)
1589_LIBCPP_EXTERN_TEMPLATE(struct __num_put<wchar_t>)
1590
1591template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
1592class _LIBCPP_TYPE_VIS num_put
1593    : public locale::facet,
1594      private __num_put<_CharT>
1595{
1596public:
1597    typedef _CharT char_type;
1598    typedef _OutputIterator iter_type;
1599
1600    _LIBCPP_ALWAYS_INLINE
1601    explicit num_put(size_t __refs = 0)
1602        : locale::facet(__refs) {}
1603
1604    _LIBCPP_ALWAYS_INLINE
1605    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1606                  bool __v) const
1607    {
1608        return do_put(__s, __iob, __fl, __v);
1609    }
1610
1611    _LIBCPP_ALWAYS_INLINE
1612    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1613                  long __v) const
1614    {
1615        return do_put(__s, __iob, __fl, __v);
1616    }
1617
1618    _LIBCPP_ALWAYS_INLINE
1619    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1620                  long long __v) const
1621    {
1622        return do_put(__s, __iob, __fl, __v);
1623    }
1624
1625    _LIBCPP_ALWAYS_INLINE
1626    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1627                  unsigned long __v) const
1628    {
1629        return do_put(__s, __iob, __fl, __v);
1630    }
1631
1632    _LIBCPP_ALWAYS_INLINE
1633    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1634                  unsigned long long __v) const
1635    {
1636        return do_put(__s, __iob, __fl, __v);
1637    }
1638
1639    _LIBCPP_ALWAYS_INLINE
1640    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1641                  double __v) const
1642    {
1643        return do_put(__s, __iob, __fl, __v);
1644    }
1645
1646    _LIBCPP_ALWAYS_INLINE
1647    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1648                  long double __v) const
1649    {
1650        return do_put(__s, __iob, __fl, __v);
1651    }
1652
1653    _LIBCPP_ALWAYS_INLINE
1654    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
1655                  const void* __v) const
1656    {
1657        return do_put(__s, __iob, __fl, __v);
1658    }
1659
1660    static locale::id id;
1661
1662protected:
1663    _LIBCPP_ALWAYS_INLINE
1664    ~num_put() {}
1665
1666    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1667                             bool __v) const;
1668    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1669                             long __v) const;
1670    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1671                             long long __v) const;
1672    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1673                             unsigned long) const;
1674    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1675                             unsigned long long) const;
1676    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1677                             double __v) const;
1678    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1679                             long double __v) const;
1680    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
1681                             const void* __v) const;
1682};
1683
1684template <class _CharT, class _OutputIterator>
1685locale::id
1686num_put<_CharT, _OutputIterator>::id;
1687
1688template <class _CharT, class _OutputIterator>
1689_LIBCPP_HIDDEN
1690_OutputIterator
1691__pad_and_output(_OutputIterator __s,
1692                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1693                 ios_base& __iob, _CharT __fl)
1694{
1695    streamsize __sz = __oe - __ob;
1696    streamsize __ns = __iob.width();
1697    if (__ns > __sz)
1698        __ns -= __sz;
1699    else
1700        __ns = 0;
1701    for (;__ob < __op; ++__ob, ++__s)
1702        *__s = *__ob;
1703    for (; __ns; --__ns, ++__s)
1704        *__s = __fl;
1705    for (; __ob < __oe; ++__ob, ++__s)
1706        *__s = *__ob;
1707    __iob.width(0);
1708    return __s;
1709}
1710
1711#if !defined(__APPLE__) || \
1712    (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
1713    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
1714
1715template <class _CharT, class _Traits>
1716_LIBCPP_HIDDEN
1717ostreambuf_iterator<_CharT, _Traits>
1718__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
1719                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
1720                 ios_base& __iob, _CharT __fl)
1721{
1722    if (__s.__sbuf_ == nullptr)
1723        return __s;
1724    streamsize __sz = __oe - __ob;
1725    streamsize __ns = __iob.width();
1726    if (__ns > __sz)
1727        __ns -= __sz;
1728    else
1729        __ns = 0;
1730    streamsize __np = __op - __ob;
1731    if (__np > 0)
1732    {
1733        if (__s.__sbuf_->sputn(__ob, __np) != __np)
1734        {
1735            __s.__sbuf_ = nullptr;
1736            return __s;
1737        }
1738    }
1739    if (__ns > 0)
1740    {
1741        basic_string<_CharT, _Traits> __sp(__ns, __fl);
1742        if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
1743        {
1744            __s.__sbuf_ = nullptr;
1745            return __s;
1746        }
1747    }
1748    __np = __oe - __op;
1749    if (__np > 0)
1750    {
1751        if (__s.__sbuf_->sputn(__op, __np) != __np)
1752        {
1753            __s.__sbuf_ = nullptr;
1754            return __s;
1755        }
1756    }
1757    __iob.width(0);
1758    return __s;
1759}
1760
1761#endif
1762
1763template <class _CharT, class _OutputIterator>
1764_OutputIterator
1765num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1766                                         char_type __fl, bool __v) const
1767{
1768    if ((__iob.flags() & ios_base::boolalpha) == 0)
1769        return do_put(__s, __iob, __fl, (unsigned long)__v);
1770    const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
1771    typedef typename numpunct<char_type>::string_type string_type;
1772    string_type __nm = __v ? __np.truename() : __np.falsename();
1773    for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
1774        *__s = *__i;
1775    return __s;
1776}
1777
1778template <class _CharT, class _OutputIterator>
1779_OutputIterator
1780num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1781                                         char_type __fl, long __v) const
1782{
1783    // Stage 1 - Get number in narrow char
1784    char __fmt[6] = {'%', 0};
1785    const char* __len = "l";
1786    this->__format_int(__fmt+1, __len, true, __iob.flags());
1787    const unsigned __nbuf = (numeric_limits<long>::digits / 3)
1788                          + ((numeric_limits<long>::digits % 3) != 0)
1789                          + 1;
1790    char __nar[__nbuf];
1791#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1792    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1793#else
1794    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1795#endif
1796    char* __ne = __nar + __nc;
1797    char* __np = this->__identify_padding(__nar, __ne, __iob);
1798    // Stage 2 - Widen __nar while adding thousands separators
1799    char_type __o[2*(__nbuf-1) - 1];
1800    char_type* __op;  // pad here
1801    char_type* __oe;  // end of output
1802    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1803    // [__o, __oe) contains thousands_sep'd wide number
1804    // Stage 3 & 4
1805    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1806}
1807
1808template <class _CharT, class _OutputIterator>
1809_OutputIterator
1810num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1811                                         char_type __fl, long long __v) const
1812{
1813    // Stage 1 - Get number in narrow char
1814    char __fmt[8] = {'%', 0};
1815    const char* __len = "ll";
1816    this->__format_int(__fmt+1, __len, true, __iob.flags());
1817    const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1818                          + ((numeric_limits<long long>::digits % 3) != 0)
1819                          + 1;
1820    char __nar[__nbuf];
1821#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1822    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1823#else
1824    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1825#endif
1826    char* __ne = __nar + __nc;
1827    char* __np = this->__identify_padding(__nar, __ne, __iob);
1828    // Stage 2 - Widen __nar while adding thousands separators
1829    char_type __o[2*(__nbuf-1) - 1];
1830    char_type* __op;  // pad here
1831    char_type* __oe;  // end of output
1832    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1833    // [__o, __oe) contains thousands_sep'd wide number
1834    // Stage 3 & 4
1835    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1836}
1837
1838template <class _CharT, class _OutputIterator>
1839_OutputIterator
1840num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1841                                         char_type __fl, unsigned long __v) const
1842{
1843    // Stage 1 - Get number in narrow char
1844    char __fmt[6] = {'%', 0};
1845    const char* __len = "l";
1846    this->__format_int(__fmt+1, __len, false, __iob.flags());
1847    const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1848                          + ((numeric_limits<unsigned long>::digits % 3) != 0)
1849                          + 1;
1850    char __nar[__nbuf];
1851#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1852    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1853#else
1854    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1855#endif
1856    char* __ne = __nar + __nc;
1857    char* __np = this->__identify_padding(__nar, __ne, __iob);
1858    // Stage 2 - Widen __nar while adding thousands separators
1859    char_type __o[2*(__nbuf-1) - 1];
1860    char_type* __op;  // pad here
1861    char_type* __oe;  // end of output
1862    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1863    // [__o, __oe) contains thousands_sep'd wide number
1864    // Stage 3 & 4
1865    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1866}
1867
1868template <class _CharT, class _OutputIterator>
1869_OutputIterator
1870num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1871                                         char_type __fl, unsigned long long __v) const
1872{
1873    // Stage 1 - Get number in narrow char
1874    char __fmt[8] = {'%', 0};
1875    const char* __len = "ll";
1876    this->__format_int(__fmt+1, __len, false, __iob.flags());
1877    const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1878                          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1879                          + 1;
1880    char __nar[__nbuf];
1881#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1882    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1883#else
1884    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
1885#endif
1886    char* __ne = __nar + __nc;
1887    char* __np = this->__identify_padding(__nar, __ne, __iob);
1888    // Stage 2 - Widen __nar while adding thousands separators
1889    char_type __o[2*(__nbuf-1) - 1];
1890    char_type* __op;  // pad here
1891    char_type* __oe;  // end of output
1892    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1893    // [__o, __oe) contains thousands_sep'd wide number
1894    // Stage 3 & 4
1895    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1896}
1897
1898template <class _CharT, class _OutputIterator>
1899_OutputIterator
1900num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1901                                         char_type __fl, double __v) const
1902{
1903    // Stage 1 - Get number in narrow char
1904    char __fmt[8] = {'%', 0};
1905    const char* __len = "";
1906    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1907    const unsigned __nbuf = 30;
1908    char __nar[__nbuf];
1909    char* __nb = __nar;
1910    int __nc;
1911    if (__specify_precision)
1912#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1913        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1914                                   (int)__iob.precision(), __v);
1915#else
1916        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1917                            (int)__iob.precision(), __v);
1918#endif
1919    else
1920#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1921        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1922#else
1923        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1924#endif
1925    unique_ptr<char, void(*)(void*)> __nbh(0, free);
1926    if (__nc > static_cast<int>(__nbuf-1))
1927    {
1928        if (__specify_precision)
1929#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1930            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1931#else
1932            __nc = __asprintf_l(&__nb, __cloc(), __fmt,
1933                              (int)__iob.precision(), __v);
1934#endif
1935        else
1936#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1937            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1938#else
1939            __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
1940#endif
1941        if (__nb == 0)
1942            __throw_bad_alloc();
1943        __nbh.reset(__nb);
1944    }
1945    char* __ne = __nb + __nc;
1946    char* __np = this->__identify_padding(__nb, __ne, __iob);
1947    // Stage 2 - Widen __nar while adding thousands separators
1948    char_type __o[2*(__nbuf-1) - 1];
1949    char_type* __ob = __o;
1950    unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1951    if (__nb != __nar)
1952    {
1953        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1954        if (__ob == 0)
1955            __throw_bad_alloc();
1956        __obh.reset(__ob);
1957    }
1958    char_type* __op;  // pad here
1959    char_type* __oe;  // end of output
1960    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1961    // [__o, __oe) contains thousands_sep'd wide number
1962    // Stage 3 & 4
1963    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1964    return __s;
1965}
1966
1967template <class _CharT, class _OutputIterator>
1968_OutputIterator
1969num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1970                                         char_type __fl, long double __v) const
1971{
1972    // Stage 1 - Get number in narrow char
1973    char __fmt[8] = {'%', 0};
1974    const char* __len = "L";
1975    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1976    const unsigned __nbuf = 30;
1977    char __nar[__nbuf];
1978    char* __nb = __nar;
1979    int __nc;
1980    if (__specify_precision)
1981#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1982        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1983                                   (int)__iob.precision(), __v);
1984#else
1985        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
1986                            (int)__iob.precision(), __v);
1987#endif
1988    else
1989#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1990        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1991#else
1992        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
1993#endif
1994    unique_ptr<char, void(*)(void*)> __nbh(0, free);
1995    if (__nc > static_cast<int>(__nbuf-1))
1996    {
1997        if (__specify_precision)
1998#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1999            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
2000#else
2001            __nc = __asprintf_l(&__nb, __cloc(), __fmt,
2002                              (int)__iob.precision(), __v);
2003#endif
2004        else
2005#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
2006            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
2007#else
2008            __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
2009#endif
2010        if (__nb == 0)
2011            __throw_bad_alloc();
2012        __nbh.reset(__nb);
2013    }
2014    char* __ne = __nb + __nc;
2015    char* __np = this->__identify_padding(__nb, __ne, __iob);
2016    // Stage 2 - Widen __nar while adding thousands separators
2017    char_type __o[2*(__nbuf-1) - 1];
2018    char_type* __ob = __o;
2019    unique_ptr<char_type, void(*)(void*)> __obh(0, free);
2020    if (__nb != __nar)
2021    {
2022        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
2023        if (__ob == 0)
2024            __throw_bad_alloc();
2025        __obh.reset(__ob);
2026    }
2027    char_type* __op;  // pad here
2028    char_type* __oe;  // end of output
2029    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
2030    // [__o, __oe) contains thousands_sep'd wide number
2031    // Stage 3 & 4
2032    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
2033    return __s;
2034}
2035
2036template <class _CharT, class _OutputIterator>
2037_OutputIterator
2038num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
2039                                         char_type __fl, const void* __v) const
2040{
2041    // Stage 1 - Get pointer in narrow char
2042    char __fmt[6] = "%p";
2043    const unsigned __nbuf = 20;
2044    char __nar[__nbuf];
2045#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
2046    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
2047#else
2048    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
2049#endif
2050    char* __ne = __nar + __nc;
2051    char* __np = this->__identify_padding(__nar, __ne, __iob);
2052    // Stage 2 - Widen __nar
2053    char_type __o[2*(__nbuf-1) - 1];
2054    char_type* __op;  // pad here
2055    char_type* __oe;  // end of output
2056    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2057    __ct.widen(__nar, __ne, __o);
2058    __oe = __o + (__ne - __nar);
2059    if (__np == __ne)
2060        __op = __oe;
2061    else
2062        __op = __o + (__np - __nar);
2063    // [__o, __oe) contains wide number
2064    // Stage 3 & 4
2065    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
2066}
2067
2068_LIBCPP_EXTERN_TEMPLATE(class num_put<char>)
2069_LIBCPP_EXTERN_TEMPLATE(class num_put<wchar_t>)
2070
2071template <class _CharT, class _InputIterator>
2072_LIBCPP_HIDDEN
2073int
2074__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
2075                     ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
2076{
2077    // Precondition:  __n >= 1
2078    if (__b == __e)
2079    {
2080        __err |= ios_base::eofbit | ios_base::failbit;
2081        return 0;
2082    }
2083    // get first digit
2084    _CharT __c = *__b;
2085    if (!__ct.is(ctype_base::digit, __c))
2086    {
2087        __err |= ios_base::failbit;
2088        return 0;
2089    }
2090    int __r = __ct.narrow(__c, 0) - '0';
2091    for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
2092    {
2093        // get next digit
2094        __c = *__b;
2095        if (!__ct.is(ctype_base::digit, __c))
2096            return __r;
2097        __r = __r * 10 + __ct.narrow(__c, 0) - '0';
2098    }
2099    if (__b == __e)
2100        __err |= ios_base::eofbit;
2101    return __r;
2102}
2103
2104class _LIBCPP_TYPE_VIS time_base
2105{
2106public:
2107    enum dateorder {no_order, dmy, mdy, ymd, ydm};
2108};
2109
2110template <class _CharT>
2111class __time_get_c_storage  // purposefully not decorated
2112{
2113protected:
2114    typedef basic_string<_CharT> string_type;
2115
2116    virtual const string_type* __weeks() const;
2117    virtual const string_type* __months() const;
2118    virtual const string_type* __am_pm() const;
2119    virtual const string_type& __c() const;
2120    virtual const string_type& __r() const;
2121    virtual const string_type& __x() const;
2122    virtual const string_type& __X() const;
2123};
2124
2125template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2126class _LIBCPP_TYPE_VIS time_get
2127    : public locale::facet,
2128      public time_base,
2129      private __time_get_c_storage<_CharT>
2130{
2131public:
2132    typedef _CharT                  char_type;
2133    typedef _InputIterator          iter_type;
2134    typedef time_base::dateorder    dateorder;
2135    typedef basic_string<char_type> string_type;
2136
2137    _LIBCPP_ALWAYS_INLINE
2138    explicit time_get(size_t __refs = 0)
2139        : locale::facet(__refs) {}
2140
2141    _LIBCPP_ALWAYS_INLINE
2142    dateorder date_order() const
2143    {
2144        return this->do_date_order();
2145    }
2146
2147    _LIBCPP_ALWAYS_INLINE
2148    iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
2149                       ios_base::iostate& __err, tm* __tm) const
2150    {
2151        return do_get_time(__b, __e, __iob, __err, __tm);
2152    }
2153
2154    _LIBCPP_ALWAYS_INLINE
2155    iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
2156                       ios_base::iostate& __err, tm* __tm) const
2157    {
2158        return do_get_date(__b, __e, __iob, __err, __tm);
2159    }
2160
2161    _LIBCPP_ALWAYS_INLINE
2162    iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2163                          ios_base::iostate& __err, tm* __tm) const
2164    {
2165        return do_get_weekday(__b, __e, __iob, __err, __tm);
2166    }
2167
2168    _LIBCPP_ALWAYS_INLINE
2169    iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2170                            ios_base::iostate& __err, tm* __tm) const
2171    {
2172        return do_get_monthname(__b, __e, __iob, __err, __tm);
2173    }
2174
2175    _LIBCPP_ALWAYS_INLINE
2176    iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
2177                       ios_base::iostate& __err, tm* __tm) const
2178    {
2179        return do_get_year(__b, __e, __iob, __err, __tm);
2180    }
2181
2182    _LIBCPP_ALWAYS_INLINE
2183    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2184                  ios_base::iostate& __err, tm *__tm,
2185                  char __fmt, char __mod = 0) const
2186    {
2187        return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
2188    }
2189
2190    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
2191                  ios_base::iostate& __err, tm* __tm,
2192                  const char_type* __fmtb, const char_type* __fmte) const;
2193
2194    static locale::id id;
2195
2196protected:
2197    _LIBCPP_ALWAYS_INLINE
2198    ~time_get() {}
2199
2200    virtual dateorder do_date_order() const;
2201    virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
2202                                  ios_base::iostate& __err, tm* __tm) const;
2203    virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
2204                                  ios_base::iostate& __err, tm* __tm) const;
2205    virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
2206                                     ios_base::iostate& __err, tm* __tm) const;
2207    virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
2208                                       ios_base::iostate& __err, tm* __tm) const;
2209    virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
2210                                  ios_base::iostate& __err, tm* __tm) const;
2211    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
2212                             ios_base::iostate& __err, tm* __tm,
2213                             char __fmt, char __mod) const;
2214private:
2215    void __get_white_space(iter_type& __b, iter_type __e,
2216                           ios_base::iostate& __err, const ctype<char_type>& __ct) const;
2217    void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
2218                       const ctype<char_type>& __ct) const;
2219
2220    void __get_weekdayname(int& __m,
2221                           iter_type& __b, iter_type __e,
2222                           ios_base::iostate& __err,
2223                           const ctype<char_type>& __ct) const;
2224    void __get_monthname(int& __m,
2225                         iter_type& __b, iter_type __e,
2226                         ios_base::iostate& __err,
2227                         const ctype<char_type>& __ct) const;
2228    void __get_day(int& __d,
2229                   iter_type& __b, iter_type __e,
2230                   ios_base::iostate& __err,
2231                   const ctype<char_type>& __ct) const;
2232    void __get_month(int& __m,
2233                     iter_type& __b, iter_type __e,
2234                     ios_base::iostate& __err,
2235                     const ctype<char_type>& __ct) const;
2236    void __get_year(int& __y,
2237                   iter_type& __b, iter_type __e,
2238                   ios_base::iostate& __err,
2239                   const ctype<char_type>& __ct) const;
2240    void __get_year4(int& __y,
2241                    iter_type& __b, iter_type __e,
2242                    ios_base::iostate& __err,
2243                    const ctype<char_type>& __ct) const;
2244    void __get_hour(int& __d,
2245                    iter_type& __b, iter_type __e,
2246                    ios_base::iostate& __err,
2247                    const ctype<char_type>& __ct) const;
2248    void __get_12_hour(int& __h,
2249                       iter_type& __b, iter_type __e,
2250                       ios_base::iostate& __err,
2251                       const ctype<char_type>& __ct) const;
2252    void __get_am_pm(int& __h,
2253                     iter_type& __b, iter_type __e,
2254                     ios_base::iostate& __err,
2255                     const ctype<char_type>& __ct) const;
2256    void __get_minute(int& __m,
2257                      iter_type& __b, iter_type __e,
2258                      ios_base::iostate& __err,
2259                      const ctype<char_type>& __ct) const;
2260    void __get_second(int& __s,
2261                      iter_type& __b, iter_type __e,
2262                      ios_base::iostate& __err,
2263                      const ctype<char_type>& __ct) const;
2264    void __get_weekday(int& __w,
2265                       iter_type& __b, iter_type __e,
2266                       ios_base::iostate& __err,
2267                       const ctype<char_type>& __ct) const;
2268    void __get_day_year_num(int& __w,
2269                            iter_type& __b, iter_type __e,
2270                            ios_base::iostate& __err,
2271                            const ctype<char_type>& __ct) const;
2272};
2273
2274template <class _CharT, class _InputIterator>
2275locale::id
2276time_get<_CharT, _InputIterator>::id;
2277
2278// time_get primatives
2279
2280template <class _CharT, class _InputIterator>
2281void
2282time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
2283                                                    iter_type& __b, iter_type __e,
2284                                                    ios_base::iostate& __err,
2285                                                    const ctype<char_type>& __ct) const
2286{
2287    // Note:  ignoring case comes from the POSIX strptime spec
2288    const string_type* __wk = this->__weeks();
2289    ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
2290    if (__i < 14)
2291        __w = __i % 7;
2292}
2293
2294template <class _CharT, class _InputIterator>
2295void
2296time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
2297                                                  iter_type& __b, iter_type __e,
2298                                                  ios_base::iostate& __err,
2299                                                  const ctype<char_type>& __ct) const
2300{
2301    // Note:  ignoring case comes from the POSIX strptime spec
2302    const string_type* __month = this->__months();
2303    ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
2304    if (__i < 24)
2305        __m = __i % 12;
2306}
2307
2308template <class _CharT, class _InputIterator>
2309void
2310time_get<_CharT, _InputIterator>::__get_day(int& __d,
2311                                            iter_type& __b, iter_type __e,
2312                                            ios_base::iostate& __err,
2313                                            const ctype<char_type>& __ct) const
2314{
2315    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2316    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
2317        __d = __t;
2318    else
2319        __err |= ios_base::failbit;
2320}
2321
2322template <class _CharT, class _InputIterator>
2323void
2324time_get<_CharT, _InputIterator>::__get_month(int& __m,
2325                                              iter_type& __b, iter_type __e,
2326                                              ios_base::iostate& __err,
2327                                              const ctype<char_type>& __ct) const
2328{
2329    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
2330    if (!(__err & ios_base::failbit) && __t <= 11)
2331        __m = __t;
2332    else
2333        __err |= ios_base::failbit;
2334}
2335
2336template <class _CharT, class _InputIterator>
2337void
2338time_get<_CharT, _InputIterator>::__get_year(int& __y,
2339                                             iter_type& __b, iter_type __e,
2340                                             ios_base::iostate& __err,
2341                                             const ctype<char_type>& __ct) const
2342{
2343    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2344    if (!(__err & ios_base::failbit))
2345    {
2346        if (__t < 69)
2347            __t += 2000;
2348        else if (69 <= __t && __t <= 99)
2349            __t += 1900;
2350        __y = __t - 1900;
2351    }
2352}
2353
2354template <class _CharT, class _InputIterator>
2355void
2356time_get<_CharT, _InputIterator>::__get_year4(int& __y,
2357                                              iter_type& __b, iter_type __e,
2358                                              ios_base::iostate& __err,
2359                                              const ctype<char_type>& __ct) const
2360{
2361    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
2362    if (!(__err & ios_base::failbit))
2363        __y = __t - 1900;
2364}
2365
2366template <class _CharT, class _InputIterator>
2367void
2368time_get<_CharT, _InputIterator>::__get_hour(int& __h,
2369                                             iter_type& __b, iter_type __e,
2370                                             ios_base::iostate& __err,
2371                                             const ctype<char_type>& __ct) const
2372{
2373    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2374    if (!(__err & ios_base::failbit) && __t <= 23)
2375        __h = __t;
2376    else
2377        __err |= ios_base::failbit;
2378}
2379
2380template <class _CharT, class _InputIterator>
2381void
2382time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
2383                                                iter_type& __b, iter_type __e,
2384                                                ios_base::iostate& __err,
2385                                                const ctype<char_type>& __ct) const
2386{
2387    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2388    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
2389        __h = __t;
2390    else
2391        __err |= ios_base::failbit;
2392}
2393
2394template <class _CharT, class _InputIterator>
2395void
2396time_get<_CharT, _InputIterator>::__get_minute(int& __m,
2397                                               iter_type& __b, iter_type __e,
2398                                               ios_base::iostate& __err,
2399                                               const ctype<char_type>& __ct) const
2400{
2401    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2402    if (!(__err & ios_base::failbit) && __t <= 59)
2403        __m = __t;
2404    else
2405        __err |= ios_base::failbit;
2406}
2407
2408template <class _CharT, class _InputIterator>
2409void
2410time_get<_CharT, _InputIterator>::__get_second(int& __s,
2411                                               iter_type& __b, iter_type __e,
2412                                               ios_base::iostate& __err,
2413                                               const ctype<char_type>& __ct) const
2414{
2415    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
2416    if (!(__err & ios_base::failbit) && __t <= 60)
2417        __s = __t;
2418    else
2419        __err |= ios_base::failbit;
2420}
2421
2422template <class _CharT, class _InputIterator>
2423void
2424time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
2425                                                iter_type& __b, iter_type __e,
2426                                                ios_base::iostate& __err,
2427                                                const ctype<char_type>& __ct) const
2428{
2429    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
2430    if (!(__err & ios_base::failbit) && __t <= 6)
2431        __w = __t;
2432    else
2433        __err |= ios_base::failbit;
2434}
2435
2436template <class _CharT, class _InputIterator>
2437void
2438time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
2439                                                     iter_type& __b, iter_type __e,
2440                                                     ios_base::iostate& __err,
2441                                                     const ctype<char_type>& __ct) const
2442{
2443    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2444    if (!(__err & ios_base::failbit) && __t <= 365)
2445        __d = __t;
2446    else
2447        __err |= ios_base::failbit;
2448}
2449
2450template <class _CharT, class _InputIterator>
2451void
2452time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2453                                                    ios_base::iostate& __err,
2454                                                    const ctype<char_type>& __ct) const
2455{
2456    for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2457        ;
2458    if (__b == __e)
2459        __err |= ios_base::eofbit;
2460}
2461
2462template <class _CharT, class _InputIterator>
2463void
2464time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2465                                              iter_type& __b, iter_type __e,
2466                                              ios_base::iostate& __err,
2467                                              const ctype<char_type>& __ct) const
2468{
2469    const string_type* __ap = this->__am_pm();
2470    if (__ap[0].size() + __ap[1].size() == 0)
2471    {
2472        __err |= ios_base::failbit;
2473        return;
2474    }
2475    ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2476    if (__i == 0 && __h == 12)
2477        __h = 0;
2478    else if (__i == 1 && __h < 12)
2479        __h += 12;
2480}
2481
2482template <class _CharT, class _InputIterator>
2483void
2484time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2485                                                ios_base::iostate& __err,
2486                                                const ctype<char_type>& __ct) const
2487{
2488    if (__b == __e)
2489    {
2490        __err |= ios_base::eofbit | ios_base::failbit;
2491        return;
2492    }
2493    if (__ct.narrow(*__b, 0) != '%')
2494        __err |= ios_base::failbit;
2495    else if(++__b == __e)
2496        __err |= ios_base::eofbit;
2497}
2498
2499// time_get end primatives
2500
2501template <class _CharT, class _InputIterator>
2502_InputIterator
2503time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2504                                      ios_base& __iob,
2505                                      ios_base::iostate& __err, tm* __tm,
2506                                      const char_type* __fmtb, const char_type* __fmte) const
2507{
2508    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2509    __err = ios_base::goodbit;
2510    while (__fmtb != __fmte && __err == ios_base::goodbit)
2511    {
2512        if (__b == __e)
2513        {
2514            __err = ios_base::failbit;
2515            break;
2516        }
2517        if (__ct.narrow(*__fmtb, 0) == '%')
2518        {
2519            if (++__fmtb == __fmte)
2520            {
2521                __err = ios_base::failbit;
2522                break;
2523            }
2524            char __cmd = __ct.narrow(*__fmtb, 0);
2525            char __opt = '\0';
2526            if (__cmd == 'E' || __cmd == '0')
2527            {
2528                if (++__fmtb == __fmte)
2529                {
2530                    __err = ios_base::failbit;
2531                    break;
2532                }
2533                __opt = __cmd;
2534                __cmd = __ct.narrow(*__fmtb, 0);
2535            }
2536            __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2537            ++__fmtb;
2538        }
2539        else if (__ct.is(ctype_base::space, *__fmtb))
2540        {
2541            for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2542                ;
2543            for (        ;    __b != __e    && __ct.is(ctype_base::space, *__b);    ++__b)
2544                ;
2545        }
2546        else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2547        {
2548            ++__b;
2549            ++__fmtb;
2550        }
2551        else
2552            __err = ios_base::failbit;
2553    }
2554    if (__b == __e)
2555        __err |= ios_base::eofbit;
2556    return __b;
2557}
2558
2559template <class _CharT, class _InputIterator>
2560typename time_get<_CharT, _InputIterator>::dateorder
2561time_get<_CharT, _InputIterator>::do_date_order() const
2562{
2563    return mdy;
2564}
2565
2566template <class _CharT, class _InputIterator>
2567_InputIterator
2568time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2569                                              ios_base& __iob,
2570                                              ios_base::iostate& __err,
2571                                              tm* __tm) const
2572{
2573    const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2574    return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2575}
2576
2577template <class _CharT, class _InputIterator>
2578_InputIterator
2579time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2580                                              ios_base& __iob,
2581                                              ios_base::iostate& __err,
2582                                              tm* __tm) const
2583{
2584    const string_type& __fmt = this->__x();
2585    return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2586}
2587
2588template <class _CharT, class _InputIterator>
2589_InputIterator
2590time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2591                                                 ios_base& __iob,
2592                                                 ios_base::iostate& __err,
2593                                                 tm* __tm) const
2594{
2595    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2596    __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2597    return __b;
2598}
2599
2600template <class _CharT, class _InputIterator>
2601_InputIterator
2602time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2603                                                   ios_base& __iob,
2604                                                   ios_base::iostate& __err,
2605                                                   tm* __tm) const
2606{
2607    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2608    __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2609    return __b;
2610}
2611
2612template <class _CharT, class _InputIterator>
2613_InputIterator
2614time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2615                                              ios_base& __iob,
2616                                              ios_base::iostate& __err,
2617                                              tm* __tm) const
2618{
2619    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2620    __get_year(__tm->tm_year, __b, __e, __err, __ct);
2621    return __b;
2622}
2623
2624template <class _CharT, class _InputIterator>
2625_InputIterator
2626time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2627                                         ios_base& __iob,
2628                                         ios_base::iostate& __err, tm* __tm,
2629                                         char __fmt, char) const
2630{
2631    __err = ios_base::goodbit;
2632    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2633    switch (__fmt)
2634    {
2635    case 'a':
2636    case 'A':
2637        __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2638        break;
2639    case 'b':
2640    case 'B':
2641    case 'h':
2642        __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2643        break;
2644    case 'c':
2645        {
2646        const string_type& __fm = this->__c();
2647        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2648        }
2649        break;
2650    case 'd':
2651    case 'e':
2652        __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2653        break;
2654    case 'D':
2655        {
2656        const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2657        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2658        }
2659        break;
2660    case 'F':
2661        {
2662        const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2663        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2664        }
2665        break;
2666    case 'H':
2667        __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2668        break;
2669    case 'I':
2670        __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2671        break;
2672    case 'j':
2673        __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2674        break;
2675    case 'm':
2676        __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2677        break;
2678    case 'M':
2679        __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2680        break;
2681    case 'n':
2682    case 't':
2683        __get_white_space(__b, __e, __err, __ct);
2684        break;
2685    case 'p':
2686        __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2687        break;
2688    case 'r':
2689        {
2690        const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2691        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2692        }
2693        break;
2694    case 'R':
2695        {
2696        const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2697        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2698        }
2699        break;
2700    case 'S':
2701        __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2702        break;
2703    case 'T':
2704        {
2705        const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2706        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2707        }
2708        break;
2709    case 'w':
2710        __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2711        break;
2712    case 'x':
2713        return do_get_date(__b, __e, __iob, __err, __tm);
2714    case 'X':
2715        {
2716        const string_type& __fm = this->__X();
2717        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2718        }
2719        break;
2720    case 'y':
2721        __get_year(__tm->tm_year, __b, __e, __err, __ct);
2722        break;
2723    case 'Y':
2724        __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2725        break;
2726    case '%':
2727        __get_percent(__b, __e, __err, __ct);
2728        break;
2729    default:
2730        __err |= ios_base::failbit;
2731    }
2732    return __b;
2733}
2734
2735_LIBCPP_EXTERN_TEMPLATE(class time_get<char>)
2736_LIBCPP_EXTERN_TEMPLATE(class time_get<wchar_t>)
2737
2738class __time_get
2739{
2740protected:
2741    locale_t __loc_;
2742
2743    __time_get(const char* __nm);
2744    __time_get(const string& __nm);
2745    ~__time_get();
2746};
2747
2748template <class _CharT>
2749class __time_get_storage
2750    : public __time_get
2751{
2752protected:
2753    typedef basic_string<_CharT> string_type;
2754
2755    string_type __weeks_[14];
2756    string_type __months_[24];
2757    string_type __am_pm_[2];
2758    string_type __c_;
2759    string_type __r_;
2760    string_type __x_;
2761    string_type __X_;
2762
2763    explicit __time_get_storage(const char* __nm);
2764    explicit __time_get_storage(const string& __nm);
2765
2766    _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2767
2768    time_base::dateorder __do_date_order() const;
2769
2770private:
2771    void init(const ctype<_CharT>&);
2772    string_type __analyze(char __fmt, const ctype<_CharT>&);
2773};
2774
2775template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2776class _LIBCPP_TYPE_VIS time_get_byname
2777    : public time_get<_CharT, _InputIterator>,
2778      private __time_get_storage<_CharT>
2779{
2780public:
2781    typedef time_base::dateorder    dateorder;
2782    typedef _InputIterator          iter_type;
2783    typedef _CharT                  char_type;
2784    typedef basic_string<char_type> string_type;
2785
2786    _LIBCPP_INLINE_VISIBILITY
2787    explicit time_get_byname(const char* __nm, size_t __refs = 0)
2788        : time_get<_CharT, _InputIterator>(__refs),
2789          __time_get_storage<_CharT>(__nm) {}
2790    _LIBCPP_INLINE_VISIBILITY
2791    explicit time_get_byname(const string& __nm, size_t __refs = 0)
2792        : time_get<_CharT, _InputIterator>(__refs),
2793          __time_get_storage<_CharT>(__nm) {}
2794
2795protected:
2796    _LIBCPP_INLINE_VISIBILITY
2797    ~time_get_byname() {}
2798
2799    _LIBCPP_INLINE_VISIBILITY
2800    virtual dateorder do_date_order() const {return this->__do_date_order();}
2801private:
2802    _LIBCPP_INLINE_VISIBILITY
2803    virtual const string_type* __weeks() const  {return this->__weeks_;}
2804    _LIBCPP_INLINE_VISIBILITY
2805    virtual const string_type* __months() const {return this->__months_;}
2806    _LIBCPP_INLINE_VISIBILITY
2807    virtual const string_type* __am_pm() const  {return this->__am_pm_;}
2808    _LIBCPP_INLINE_VISIBILITY
2809    virtual const string_type& __c() const      {return this->__c_;}
2810    _LIBCPP_INLINE_VISIBILITY
2811    virtual const string_type& __r() const      {return this->__r_;}
2812    _LIBCPP_INLINE_VISIBILITY
2813    virtual const string_type& __x() const      {return this->__x_;}
2814    _LIBCPP_INLINE_VISIBILITY
2815    virtual const string_type& __X() const      {return this->__X_;}
2816};
2817
2818_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<char>)
2819_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<wchar_t>)
2820
2821class __time_put
2822{
2823    locale_t __loc_;
2824protected:
2825    _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2826    __time_put(const char* __nm);
2827    __time_put(const string& __nm);
2828    ~__time_put();
2829    void __do_put(char* __nb, char*& __ne, const tm* __tm,
2830                  char __fmt, char __mod) const;
2831    void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2832                  char __fmt, char __mod) const;
2833};
2834
2835template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2836class _LIBCPP_TYPE_VIS time_put
2837    : public locale::facet,
2838      private __time_put
2839{
2840public:
2841    typedef _CharT char_type;
2842    typedef _OutputIterator iter_type;
2843
2844    _LIBCPP_ALWAYS_INLINE
2845    explicit time_put(size_t __refs = 0)
2846        : locale::facet(__refs) {}
2847
2848    iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2849                  const char_type* __pb, const char_type* __pe) const;
2850
2851    _LIBCPP_ALWAYS_INLINE
2852    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2853                  const tm* __tm, char __fmt, char __mod = 0) const
2854    {
2855        return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2856    }
2857
2858    static locale::id id;
2859
2860protected:
2861    _LIBCPP_ALWAYS_INLINE
2862    ~time_put() {}
2863    virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2864                             char __fmt, char __mod) const;
2865
2866    _LIBCPP_ALWAYS_INLINE
2867    explicit time_put(const char* __nm, size_t __refs)
2868        : locale::facet(__refs),
2869          __time_put(__nm) {}
2870    _LIBCPP_ALWAYS_INLINE
2871    explicit time_put(const string& __nm, size_t __refs)
2872        : locale::facet(__refs),
2873          __time_put(__nm) {}
2874};
2875
2876template <class _CharT, class _OutputIterator>
2877locale::id
2878time_put<_CharT, _OutputIterator>::id;
2879
2880template <class _CharT, class _OutputIterator>
2881_OutputIterator
2882time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2883                                       char_type __fl, const tm* __tm,
2884                                       const char_type* __pb,
2885                                       const char_type* __pe) const
2886{
2887    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2888    for (; __pb != __pe; ++__pb)
2889    {
2890        if (__ct.narrow(*__pb, 0) == '%')
2891        {
2892            if (++__pb == __pe)
2893            {
2894                *__s++ = __pb[-1];
2895                break;
2896            }
2897            char __mod = 0;
2898            char __fmt = __ct.narrow(*__pb, 0);
2899            if (__fmt == 'E' || __fmt == 'O')
2900            {
2901                if (++__pb == __pe)
2902                {
2903                    *__s++ = __pb[-2];
2904                    *__s++ = __pb[-1];
2905                    break;
2906                }
2907                __mod = __fmt;
2908                __fmt = __ct.narrow(*__pb, 0);
2909            }
2910            __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2911        }
2912        else
2913            *__s++ = *__pb;
2914    }
2915    return __s;
2916}
2917
2918template <class _CharT, class _OutputIterator>
2919_OutputIterator
2920time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2921                                          char_type, const tm* __tm,
2922                                          char __fmt, char __mod) const
2923{
2924    char_type __nar[100];
2925    char_type* __nb = __nar;
2926    char_type* __ne = __nb + 100;
2927    __do_put(__nb, __ne, __tm, __fmt, __mod);
2928    return _VSTD::copy(__nb, __ne, __s);
2929}
2930
2931_LIBCPP_EXTERN_TEMPLATE(class time_put<char>)
2932_LIBCPP_EXTERN_TEMPLATE(class time_put<wchar_t>)
2933
2934template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2935class _LIBCPP_TYPE_VIS time_put_byname
2936    : public time_put<_CharT, _OutputIterator>
2937{
2938public:
2939    _LIBCPP_ALWAYS_INLINE
2940    explicit time_put_byname(const char* __nm, size_t __refs = 0)
2941        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2942
2943    _LIBCPP_ALWAYS_INLINE
2944    explicit time_put_byname(const string& __nm, size_t __refs = 0)
2945        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2946
2947protected:
2948    _LIBCPP_ALWAYS_INLINE
2949    ~time_put_byname() {}
2950};
2951
2952_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<char>)
2953_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<wchar_t>)
2954
2955// money_base
2956
2957class _LIBCPP_TYPE_VIS money_base
2958{
2959public:
2960    enum part {none, space, symbol, sign, value};
2961    struct pattern {char field[4];};
2962
2963    _LIBCPP_ALWAYS_INLINE money_base() {}
2964};
2965
2966// moneypunct
2967
2968template <class _CharT, bool _International = false>
2969class _LIBCPP_TYPE_VIS moneypunct
2970    : public locale::facet,
2971      public money_base
2972{
2973public:
2974    typedef _CharT                  char_type;
2975    typedef basic_string<char_type> string_type;
2976
2977    _LIBCPP_ALWAYS_INLINE
2978    explicit moneypunct(size_t __refs = 0)
2979        : locale::facet(__refs) {}
2980
2981    _LIBCPP_ALWAYS_INLINE char_type   decimal_point() const {return do_decimal_point();}
2982    _LIBCPP_ALWAYS_INLINE char_type   thousands_sep() const {return do_thousands_sep();}
2983    _LIBCPP_ALWAYS_INLINE string      grouping()      const {return do_grouping();}
2984    _LIBCPP_ALWAYS_INLINE string_type curr_symbol()   const {return do_curr_symbol();}
2985    _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2986    _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2987    _LIBCPP_ALWAYS_INLINE int         frac_digits()   const {return do_frac_digits();}
2988    _LIBCPP_ALWAYS_INLINE pattern     pos_format()    const {return do_pos_format();}
2989    _LIBCPP_ALWAYS_INLINE pattern     neg_format()    const {return do_neg_format();}
2990
2991    static locale::id id;
2992    static const bool intl = _International;
2993
2994protected:
2995    _LIBCPP_ALWAYS_INLINE
2996    ~moneypunct() {}
2997
2998    virtual char_type   do_decimal_point() const {return numeric_limits<char_type>::max();}
2999    virtual char_type   do_thousands_sep() const {return numeric_limits<char_type>::max();}
3000    virtual string      do_grouping()      const {return string();}
3001    virtual string_type do_curr_symbol()   const {return string_type();}
3002    virtual string_type do_positive_sign() const {return string_type();}
3003    virtual string_type do_negative_sign() const {return string_type(1, '-');}
3004    virtual int         do_frac_digits()   const {return 0;}
3005    virtual pattern     do_pos_format()    const
3006        {pattern __p = {{symbol, sign, none, value}}; return __p;}
3007    virtual pattern     do_neg_format()    const
3008        {pattern __p = {{symbol, sign, none, value}}; return __p;}
3009};
3010
3011template <class _CharT, bool _International>
3012locale::id
3013moneypunct<_CharT, _International>::id;
3014
3015template <class _CharT, bool _International>
3016const bool
3017moneypunct<_CharT, _International>::intl;
3018
3019_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, false>)
3020_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, true>)
3021_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, false>)
3022_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, true>)
3023
3024// moneypunct_byname
3025
3026template <class _CharT, bool _International = false>
3027class _LIBCPP_TYPE_VIS moneypunct_byname
3028    : public moneypunct<_CharT, _International>
3029{
3030public:
3031    typedef money_base::pattern  pattern;
3032    typedef _CharT                  char_type;
3033    typedef basic_string<char_type> string_type;
3034
3035    _LIBCPP_ALWAYS_INLINE
3036    explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
3037        : moneypunct<_CharT, _International>(__refs) {init(__nm);}
3038
3039    _LIBCPP_ALWAYS_INLINE
3040    explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
3041        : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
3042
3043protected:
3044    _LIBCPP_ALWAYS_INLINE
3045    ~moneypunct_byname() {}
3046
3047    virtual char_type   do_decimal_point() const {return __decimal_point_;}
3048    virtual char_type   do_thousands_sep() const {return __thousands_sep_;}
3049    virtual string      do_grouping()      const {return __grouping_;}
3050    virtual string_type do_curr_symbol()   const {return __curr_symbol_;}
3051    virtual string_type do_positive_sign() const {return __positive_sign_;}
3052    virtual string_type do_negative_sign() const {return __negative_sign_;}
3053    virtual int         do_frac_digits()   const {return __frac_digits_;}
3054    virtual pattern     do_pos_format()    const {return __pos_format_;}
3055    virtual pattern     do_neg_format()    const {return __neg_format_;}
3056
3057private:
3058    char_type   __decimal_point_;
3059    char_type   __thousands_sep_;
3060    string      __grouping_;
3061    string_type __curr_symbol_;
3062    string_type __positive_sign_;
3063    string_type __negative_sign_;
3064    int         __frac_digits_;
3065    pattern     __pos_format_;
3066    pattern     __neg_format_;
3067
3068    void init(const char*);
3069};
3070
3071template<> void moneypunct_byname<char, false>::init(const char*);
3072template<> void moneypunct_byname<char, true>::init(const char*);
3073template<> void moneypunct_byname<wchar_t, false>::init(const char*);
3074template<> void moneypunct_byname<wchar_t, true>::init(const char*);
3075
3076_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, false>)
3077_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, true>)
3078_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, false>)
3079_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, true>)
3080
3081// money_get
3082
3083template <class _CharT>
3084class __money_get
3085{
3086protected:
3087    typedef _CharT                  char_type;
3088    typedef basic_string<char_type> string_type;
3089
3090    _LIBCPP_ALWAYS_INLINE __money_get() {}
3091
3092    static void __gather_info(bool __intl, const locale& __loc,
3093                              money_base::pattern& __pat, char_type& __dp,
3094                              char_type& __ts, string& __grp,
3095                              string_type& __sym, string_type& __psn,
3096                              string_type& __nsn, int& __fd);
3097};
3098
3099template <class _CharT>
3100void
3101__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
3102                                   money_base::pattern& __pat, char_type& __dp,
3103                                   char_type& __ts, string& __grp,
3104                                   string_type& __sym, string_type& __psn,
3105                                   string_type& __nsn, int& __fd)
3106{
3107    if (__intl)
3108    {
3109        const moneypunct<char_type, true>& __mp =
3110            use_facet<moneypunct<char_type, true> >(__loc);
3111        __pat = __mp.neg_format();
3112        __nsn = __mp.negative_sign();
3113        __psn = __mp.positive_sign();
3114        __dp = __mp.decimal_point();
3115        __ts = __mp.thousands_sep();
3116        __grp = __mp.grouping();
3117        __sym = __mp.curr_symbol();
3118        __fd = __mp.frac_digits();
3119    }
3120    else
3121    {
3122        const moneypunct<char_type, false>& __mp =
3123            use_facet<moneypunct<char_type, false> >(__loc);
3124        __pat = __mp.neg_format();
3125        __nsn = __mp.negative_sign();
3126        __psn = __mp.positive_sign();
3127        __dp = __mp.decimal_point();
3128        __ts = __mp.thousands_sep();
3129        __grp = __mp.grouping();
3130        __sym = __mp.curr_symbol();
3131        __fd = __mp.frac_digits();
3132    }
3133}
3134
3135_LIBCPP_EXTERN_TEMPLATE(class __money_get<char>)
3136_LIBCPP_EXTERN_TEMPLATE(class __money_get<wchar_t>)
3137
3138template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
3139class _LIBCPP_TYPE_VIS money_get
3140    : public locale::facet,
3141      private __money_get<_CharT>
3142{
3143public:
3144    typedef _CharT                  char_type;
3145    typedef _InputIterator          iter_type;
3146    typedef basic_string<char_type> string_type;
3147
3148    _LIBCPP_ALWAYS_INLINE
3149    explicit money_get(size_t __refs = 0)
3150        : locale::facet(__refs) {}
3151
3152    _LIBCPP_ALWAYS_INLINE
3153    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
3154                  ios_base::iostate& __err, long double& __v) const
3155    {
3156        return do_get(__b, __e, __intl, __iob, __err, __v);
3157    }
3158
3159    _LIBCPP_ALWAYS_INLINE
3160    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
3161                  ios_base::iostate& __err, string_type& __v) const
3162    {
3163        return do_get(__b, __e, __intl, __iob, __err, __v);
3164    }
3165
3166    static locale::id id;
3167
3168protected:
3169
3170    _LIBCPP_ALWAYS_INLINE
3171    ~money_get() {}
3172
3173    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3174                             ios_base& __iob, ios_base::iostate& __err,
3175                             long double& __v) const;
3176    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
3177                             ios_base& __iob, ios_base::iostate& __err,
3178                             string_type& __v) const;
3179
3180private:
3181    static bool __do_get(iter_type& __b, iter_type __e,
3182                         bool __intl, const locale& __loc,
3183                         ios_base::fmtflags __flags, ios_base::iostate& __err,
3184                         bool& __neg, const ctype<char_type>& __ct,
3185                         unique_ptr<char_type, void(*)(void*)>& __wb,
3186                         char_type*& __wn, char_type* __we);
3187};
3188
3189template <class _CharT, class _InputIterator>
3190locale::id
3191money_get<_CharT, _InputIterator>::id;
3192
3193void __do_nothing(void*);
3194
3195template <class _Tp>
3196_LIBCPP_HIDDEN
3197void
3198__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
3199{
3200    bool __owns = __b.get_deleter() != __do_nothing;
3201    size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
3202    size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
3203                       2 * __cur_cap : numeric_limits<size_t>::max();
3204    size_t __n_off = static_cast<size_t>(__n - __b.get());
3205    _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
3206    if (__t == 0)
3207        __throw_bad_alloc();
3208    if (__owns)
3209        __b.release();
3210    __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
3211    __new_cap /= sizeof(_Tp);
3212    __n = __b.get() + __n_off;
3213    __e = __b.get() + __new_cap;
3214}
3215
3216// true == success
3217template <class _CharT, class _InputIterator>
3218bool
3219money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
3220                                            bool __intl, const locale& __loc,
3221                                            ios_base::fmtflags __flags,
3222                                            ios_base::iostate& __err,
3223                                            bool& __neg,
3224                                            const ctype<char_type>& __ct,
3225                                            unique_ptr<char_type, void(*)(void*)>& __wb,
3226                                            char_type*& __wn, char_type* __we)
3227{
3228    const unsigned __bz = 100;
3229    unsigned __gbuf[__bz];
3230    unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
3231    unsigned* __gn = __gb.get();
3232    unsigned* __ge = __gn + __bz;
3233    money_base::pattern __pat;
3234    char_type __dp;
3235    char_type __ts;
3236    string __grp;
3237    string_type __sym;
3238    string_type __psn;
3239    string_type __nsn;
3240    // Capture the spaces read into money_base::{space,none} so they
3241    // can be compared to initial spaces in __sym.
3242    string_type __spaces;
3243    int __fd;
3244    __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
3245                                       __sym, __psn, __nsn, __fd);
3246    const string_type* __trailing_sign = 0;
3247    __wn = __wb.get();
3248    for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
3249    {
3250        switch (__pat.field[__p])
3251        {
3252        case money_base::space:
3253            if (__p != 3)
3254            {
3255                if (__ct.is(ctype_base::space, *__b))
3256                    __spaces.push_back(*__b++);
3257                else
3258                {
3259                    __err |= ios_base::failbit;
3260                    return false;
3261                }
3262            }
3263            // drop through
3264        case money_base::none:
3265            if (__p != 3)
3266            {
3267                while (__b != __e && __ct.is(ctype_base::space, *__b))
3268                    __spaces.push_back(*__b++);
3269            }
3270            break;
3271        case money_base::sign:
3272            if (__psn.size() + __nsn.size() > 0)
3273            {
3274                if (__psn.size() == 0 || __nsn.size() == 0)
3275                {   // sign is optional
3276                    if (__psn.size() > 0)
3277                    {   // __nsn.size() == 0
3278                        if (*__b == __psn[0])
3279                        {
3280                            ++__b;
3281                            if (__psn.size() > 1)
3282                                __trailing_sign = &__psn;
3283                        }
3284                        else
3285                            __neg = true;
3286                    }
3287                    else if (*__b == __nsn[0])  // __nsn.size() > 0 &&  __psn.size() == 0
3288                    {
3289                        ++__b;
3290                        __neg = true;
3291                        if (__nsn.size() > 1)
3292                            __trailing_sign = &__nsn;
3293                    }
3294                }
3295                else  // sign is required
3296                {
3297                    if (*__b == __psn[0])
3298                    {
3299                        ++__b;
3300                        if (__psn.size() > 1)
3301                            __trailing_sign = &__psn;
3302                    }
3303                    else if (*__b == __nsn[0])
3304                    {
3305                        ++__b;
3306                        __neg = true;
3307                        if (__nsn.size() > 1)
3308                            __trailing_sign = &__nsn;
3309                    }
3310                    else
3311                    {
3312                        __err |= ios_base::failbit;
3313                        return false;
3314                    }
3315                }
3316            }
3317            break;
3318        case money_base::symbol:
3319            {
3320            bool __more_needed = __trailing_sign ||
3321                                 (__p < 2)       ||
3322                                 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
3323            bool __sb = __flags & ios_base::showbase;
3324            if (__sb || __more_needed)
3325            {
3326                typename string_type::const_iterator __sym_space_end = __sym.begin();
3327                if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
3328                                __pat.field[__p - 1] == money_base::space)) {
3329                    // Match spaces we've already read against spaces at
3330                    // the beginning of __sym.
3331                    while (__sym_space_end != __sym.end() &&
3332                           __ct.is(ctype_base::space, *__sym_space_end))
3333                        ++__sym_space_end;
3334                    const size_t __num_spaces = __sym_space_end - __sym.begin();
3335                    if (__num_spaces > __spaces.size() ||
3336                        !equal(__spaces.end() - __num_spaces, __spaces.end(),
3337                               __sym.begin())) {
3338                        // No match. Put __sym_space_end back at the
3339                        // beginning of __sym, which will prevent a
3340                        // match in the next loop.
3341                        __sym_space_end = __sym.begin();
3342                    }
3343                }
3344                typename string_type::const_iterator __sym_curr_char = __sym_space_end;
3345                while (__sym_curr_char != __sym.end() && __b != __e &&
3346                       *__b == *__sym_curr_char) {
3347                    ++__b;
3348                    ++__sym_curr_char;
3349                }
3350                if (__sb && __sym_curr_char != __sym.end())
3351                {
3352                    __err |= ios_base::failbit;
3353                    return false;
3354                }
3355            }
3356            }
3357            break;
3358        case money_base::value:
3359            {
3360            unsigned __ng = 0;
3361            for (; __b != __e; ++__b)
3362            {
3363                char_type __c = *__b;
3364                if (__ct.is(ctype_base::digit, __c))
3365                {
3366                    if (__wn == __we)
3367                        __double_or_nothing(__wb, __wn, __we);
3368                    *__wn++ = __c;
3369                    ++__ng;
3370                }
3371                else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
3372                {
3373                    if (__gn == __ge)
3374                        __double_or_nothing(__gb, __gn, __ge);
3375                    *__gn++ = __ng;
3376                    __ng = 0;
3377                }
3378                else
3379                    break;
3380            }
3381            if (__gb.get() != __gn && __ng > 0)
3382            {
3383                if (__gn == __ge)
3384                    __double_or_nothing(__gb, __gn, __ge);
3385                *__gn++ = __ng;
3386            }
3387            if (__fd > 0)
3388            {
3389                if (__b == __e || *__b != __dp)
3390                {
3391                    __err |= ios_base::failbit;
3392                    return false;
3393                }
3394                for (++__b; __fd > 0; --__fd, ++__b)
3395                {
3396                    if (__b == __e || !__ct.is(ctype_base::digit, *__b))
3397                    {
3398                        __err |= ios_base::failbit;
3399                        return false;
3400                    }
3401                    if (__wn == __we)
3402                        __double_or_nothing(__wb, __wn, __we);
3403                    *__wn++ = *__b;
3404                }
3405            }
3406            if (__wn == __wb.get())
3407            {
3408                __err |= ios_base::failbit;
3409                return false;
3410            }
3411            }
3412            break;
3413        }
3414    }
3415    if (__trailing_sign)
3416    {
3417        for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
3418        {
3419            if (__b == __e || *__b != (*__trailing_sign)[__i])
3420            {
3421                __err |= ios_base::failbit;
3422                return false;
3423            }
3424        }
3425    }
3426    if (__gb.get() != __gn)
3427    {
3428        ios_base::iostate __et = ios_base::goodbit;
3429        __check_grouping(__grp, __gb.get(), __gn, __et);
3430        if (__et)
3431        {
3432            __err |= ios_base::failbit;
3433            return false;
3434        }
3435    }
3436    return true;
3437}
3438
3439template <class _CharT, class _InputIterator>
3440_InputIterator
3441money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3442                                          bool __intl, ios_base& __iob,
3443                                          ios_base::iostate& __err,
3444                                          long double& __v) const
3445{
3446    const int __bz = 100;
3447    char_type __wbuf[__bz];
3448    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3449    char_type* __wn;
3450    char_type* __we = __wbuf + __bz;
3451    locale __loc = __iob.getloc();
3452    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3453    bool __neg = false;
3454    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3455                 __wb, __wn, __we))
3456    {
3457        const char __src[] = "0123456789";
3458        char_type __atoms[sizeof(__src)-1];
3459        __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3460        char __nbuf[__bz];
3461        char* __nc = __nbuf;
3462        unique_ptr<char, void(*)(void*)> __h(0, free);
3463        if (__wn - __wb.get() > __bz-2)
3464        {
3465            __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3466            if (__h.get() == 0)
3467                __throw_bad_alloc();
3468            __nc = __h.get();
3469        }
3470        if (__neg)
3471            *__nc++ = '-';
3472        for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3473            *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3474        *__nc = char();
3475        if (sscanf(__nbuf, "%Lf", &__v) != 1)
3476            __throw_runtime_error("money_get error");
3477    }
3478    if (__b == __e)
3479        __err |= ios_base::eofbit;
3480    return __b;
3481}
3482
3483template <class _CharT, class _InputIterator>
3484_InputIterator
3485money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3486                                          bool __intl, ios_base& __iob,
3487                                          ios_base::iostate& __err,
3488                                          string_type& __v) const
3489{
3490    const int __bz = 100;
3491    char_type __wbuf[__bz];
3492    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3493    char_type* __wn;
3494    char_type* __we = __wbuf + __bz;
3495    locale __loc = __iob.getloc();
3496    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3497    bool __neg = false;
3498    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3499                 __wb, __wn, __we))
3500    {
3501        __v.clear();
3502        if (__neg)
3503            __v.push_back(__ct.widen('-'));
3504        char_type __z = __ct.widen('0');
3505        char_type* __w;
3506        for (__w = __wb.get(); __w < __wn-1; ++__w)
3507            if (*__w != __z)
3508                break;
3509        __v.append(__w, __wn);
3510    }
3511    if (__b == __e)
3512        __err |= ios_base::eofbit;
3513    return __b;
3514}
3515
3516_LIBCPP_EXTERN_TEMPLATE(class money_get<char>)
3517_LIBCPP_EXTERN_TEMPLATE(class money_get<wchar_t>)
3518
3519// money_put
3520
3521template <class _CharT>
3522class __money_put
3523{
3524protected:
3525    typedef _CharT                  char_type;
3526    typedef basic_string<char_type> string_type;
3527
3528    _LIBCPP_ALWAYS_INLINE __money_put() {}
3529
3530    static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3531                              money_base::pattern& __pat, char_type& __dp,
3532                              char_type& __ts, string& __grp,
3533                              string_type& __sym, string_type& __sn,
3534                              int& __fd);
3535    static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3536                         ios_base::fmtflags __flags,
3537                         const char_type* __db, const char_type* __de,
3538                         const ctype<char_type>& __ct, bool __neg,
3539                         const money_base::pattern& __pat, char_type __dp,
3540                         char_type __ts, const string& __grp,
3541                         const string_type& __sym, const string_type& __sn,
3542                         int __fd);
3543};
3544
3545template <class _CharT>
3546void
3547__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3548                                   money_base::pattern& __pat, char_type& __dp,
3549                                   char_type& __ts, string& __grp,
3550                                   string_type& __sym, string_type& __sn,
3551                                   int& __fd)
3552{
3553    if (__intl)
3554    {
3555        const moneypunct<char_type, true>& __mp =
3556            use_facet<moneypunct<char_type, true> >(__loc);
3557        if (__neg)
3558        {
3559            __pat = __mp.neg_format();
3560            __sn = __mp.negative_sign();
3561        }
3562        else
3563        {
3564            __pat = __mp.pos_format();
3565            __sn = __mp.positive_sign();
3566        }
3567        __dp = __mp.decimal_point();
3568        __ts = __mp.thousands_sep();
3569        __grp = __mp.grouping();
3570        __sym = __mp.curr_symbol();
3571        __fd = __mp.frac_digits();
3572    }
3573    else
3574    {
3575        const moneypunct<char_type, false>& __mp =
3576            use_facet<moneypunct<char_type, false> >(__loc);
3577        if (__neg)
3578        {
3579            __pat = __mp.neg_format();
3580            __sn = __mp.negative_sign();
3581        }
3582        else
3583        {
3584            __pat = __mp.pos_format();
3585            __sn = __mp.positive_sign();
3586        }
3587        __dp = __mp.decimal_point();
3588        __ts = __mp.thousands_sep();
3589        __grp = __mp.grouping();
3590        __sym = __mp.curr_symbol();
3591        __fd = __mp.frac_digits();
3592    }
3593}
3594
3595template <class _CharT>
3596void
3597__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3598                              ios_base::fmtflags __flags,
3599                              const char_type* __db, const char_type* __de,
3600                              const ctype<char_type>& __ct, bool __neg,
3601                              const money_base::pattern& __pat, char_type __dp,
3602                              char_type __ts, const string& __grp,
3603                              const string_type& __sym, const string_type& __sn,
3604                              int __fd)
3605{
3606    __me = __mb;
3607    for (unsigned __p = 0; __p < 4; ++__p)
3608    {
3609        switch (__pat.field[__p])
3610        {
3611        case money_base::none:
3612            __mi = __me;
3613            break;
3614        case money_base::space:
3615            __mi = __me;
3616            *__me++ = __ct.widen(' ');
3617            break;
3618        case money_base::sign:
3619            if (!__sn.empty())
3620                *__me++ = __sn[0];
3621            break;
3622        case money_base::symbol:
3623            if (!__sym.empty() && (__flags & ios_base::showbase))
3624                __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3625            break;
3626        case money_base::value:
3627            {
3628            // remember start of value so we can reverse it
3629            char_type* __t = __me;
3630            // find beginning of digits
3631            if (__neg)
3632                ++__db;
3633            // find end of digits
3634            const char_type* __d;
3635            for (__d = __db; __d < __de; ++__d)
3636                if (!__ct.is(ctype_base::digit, *__d))
3637                    break;
3638            // print fractional part
3639            if (__fd > 0)
3640            {
3641                int __f;
3642                for (__f = __fd; __d > __db && __f > 0; --__f)
3643                    *__me++ = *--__d;
3644                char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3645                for (; __f > 0; --__f)
3646                    *__me++ = __z;
3647                *__me++ = __dp;
3648            }
3649            // print units part
3650            if (__d == __db)
3651            {
3652                *__me++ = __ct.widen('0');
3653            }
3654            else
3655            {
3656                unsigned __ng = 0;
3657                unsigned __ig = 0;
3658                unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3659                                              : static_cast<unsigned>(__grp[__ig]);
3660                while (__d != __db)
3661                {
3662                    if (__ng == __gl)
3663                    {
3664                        *__me++ = __ts;
3665                        __ng = 0;
3666                        if (++__ig < __grp.size())
3667                            __gl = __grp[__ig] == numeric_limits<char>::max() ?
3668                                        numeric_limits<unsigned>::max() :
3669                                        static_cast<unsigned>(__grp[__ig]);
3670                    }
3671                    *__me++ = *--__d;
3672                    ++__ng;
3673                }
3674            }
3675            // reverse it
3676            reverse(__t, __me);
3677            }
3678            break;
3679        }
3680    }
3681    // print rest of sign, if any
3682    if (__sn.size() > 1)
3683        __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3684    // set alignment
3685    if ((__flags & ios_base::adjustfield) == ios_base::left)
3686        __mi = __me;
3687    else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3688        __mi = __mb;
3689}
3690
3691_LIBCPP_EXTERN_TEMPLATE(class __money_put<char>)
3692_LIBCPP_EXTERN_TEMPLATE(class __money_put<wchar_t>)
3693
3694template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3695class _LIBCPP_TYPE_VIS money_put
3696    : public locale::facet,
3697      private __money_put<_CharT>
3698{
3699public:
3700    typedef _CharT                  char_type;
3701    typedef _OutputIterator         iter_type;
3702    typedef basic_string<char_type> string_type;
3703
3704    _LIBCPP_ALWAYS_INLINE
3705    explicit money_put(size_t __refs = 0)
3706        : locale::facet(__refs) {}
3707
3708    _LIBCPP_ALWAYS_INLINE
3709    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3710                  long double __units) const
3711    {
3712        return do_put(__s, __intl, __iob, __fl, __units);
3713    }
3714
3715    _LIBCPP_ALWAYS_INLINE
3716    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3717                  const string_type& __digits) const
3718    {
3719        return do_put(__s, __intl, __iob, __fl, __digits);
3720    }
3721
3722    static locale::id id;
3723
3724protected:
3725    _LIBCPP_ALWAYS_INLINE
3726    ~money_put() {}
3727
3728    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3729                             char_type __fl, long double __units) const;
3730    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3731                             char_type __fl, const string_type& __digits) const;
3732};
3733
3734template <class _CharT, class _OutputIterator>
3735locale::id
3736money_put<_CharT, _OutputIterator>::id;
3737
3738template <class _CharT, class _OutputIterator>
3739_OutputIterator
3740money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3741                                           ios_base& __iob, char_type __fl,
3742                                           long double __units) const
3743{
3744    // convert to char
3745    const size_t __bs = 100;
3746    char __buf[__bs];
3747    char* __bb = __buf;
3748    char_type __digits[__bs];
3749    char_type* __db = __digits;
3750    size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3751    unique_ptr<char, void(*)(void*)> __hn(0, free);
3752    unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3753    // secure memory for digit storage
3754    if (__n > __bs-1)
3755    {
3756#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
3757        __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3758#else
3759        __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
3760#endif
3761        if (__bb == 0)
3762            __throw_bad_alloc();
3763        __hn.reset(__bb);
3764        __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3765        if (__hd == nullptr)
3766            __throw_bad_alloc();
3767        __db = __hd.get();
3768    }
3769    // gather info
3770    locale __loc = __iob.getloc();
3771    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3772    __ct.widen(__bb, __bb + __n, __db);
3773    bool __neg = __n > 0 && __bb[0] == '-';
3774    money_base::pattern __pat;
3775    char_type __dp;
3776    char_type __ts;
3777    string __grp;
3778    string_type __sym;
3779    string_type __sn;
3780    int __fd;
3781    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3782    // secure memory for formatting
3783    char_type __mbuf[__bs];
3784    char_type* __mb = __mbuf;
3785    unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3786    size_t __exn = static_cast<int>(__n) > __fd ?
3787                   (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3788                    __sym.size() + static_cast<size_t>(__fd) + 1
3789                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3790    if (__exn > __bs)
3791    {
3792        __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3793        __mb = __hw.get();
3794        if (__mb == 0)
3795            __throw_bad_alloc();
3796    }
3797    // format
3798    char_type* __mi;
3799    char_type* __me;
3800    this->__format(__mb, __mi, __me, __iob.flags(),
3801                   __db, __db + __n, __ct,
3802                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3803    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3804}
3805
3806template <class _CharT, class _OutputIterator>
3807_OutputIterator
3808money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3809                                           ios_base& __iob, char_type __fl,
3810                                           const string_type& __digits) const
3811{
3812    // gather info
3813    locale __loc = __iob.getloc();
3814    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3815    bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3816    money_base::pattern __pat;
3817    char_type __dp;
3818    char_type __ts;
3819    string __grp;
3820    string_type __sym;
3821    string_type __sn;
3822    int __fd;
3823    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3824    // secure memory for formatting
3825    char_type __mbuf[100];
3826    char_type* __mb = __mbuf;
3827    unique_ptr<char_type, void(*)(void*)> __h(0, free);
3828    size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3829                   (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3830                    __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3831                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3832    if (__exn > 100)
3833    {
3834        __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3835        __mb = __h.get();
3836        if (__mb == 0)
3837            __throw_bad_alloc();
3838    }
3839    // format
3840    char_type* __mi;
3841    char_type* __me;
3842    this->__format(__mb, __mi, __me, __iob.flags(),
3843                   __digits.data(), __digits.data() + __digits.size(), __ct,
3844                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3845    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3846}
3847
3848_LIBCPP_EXTERN_TEMPLATE(class money_put<char>)
3849_LIBCPP_EXTERN_TEMPLATE(class money_put<wchar_t>)
3850
3851// messages
3852
3853class _LIBCPP_TYPE_VIS messages_base
3854{
3855public:
3856    typedef ptrdiff_t catalog;
3857
3858    _LIBCPP_ALWAYS_INLINE messages_base() {}
3859};
3860
3861template <class _CharT>
3862class _LIBCPP_TYPE_VIS messages
3863    : public locale::facet,
3864      public messages_base
3865{
3866public:
3867    typedef _CharT               char_type;
3868    typedef basic_string<_CharT> string_type;
3869
3870    _LIBCPP_ALWAYS_INLINE
3871    explicit messages(size_t __refs = 0)
3872        : locale::facet(__refs) {}
3873
3874    _LIBCPP_ALWAYS_INLINE
3875    catalog open(const basic_string<char>& __nm, const locale& __loc) const
3876    {
3877        return do_open(__nm, __loc);
3878    }
3879
3880    _LIBCPP_ALWAYS_INLINE
3881    string_type get(catalog __c, int __set, int __msgid,
3882                    const string_type& __dflt) const
3883    {
3884        return do_get(__c, __set, __msgid, __dflt);
3885    }
3886
3887    _LIBCPP_ALWAYS_INLINE
3888    void close(catalog __c) const
3889    {
3890        do_close(__c);
3891    }
3892
3893    static locale::id id;
3894
3895protected:
3896    _LIBCPP_ALWAYS_INLINE
3897    ~messages() {}
3898
3899    virtual catalog do_open(const basic_string<char>&, const locale&) const;
3900    virtual string_type do_get(catalog, int __set, int __msgid,
3901                               const string_type& __dflt) const;
3902    virtual void do_close(catalog) const;
3903};
3904
3905template <class _CharT>
3906locale::id
3907messages<_CharT>::id;
3908
3909template <class _CharT>
3910typename messages<_CharT>::catalog
3911messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3912{
3913#ifdef _WIN32
3914    return -1;
3915#else // _WIN32
3916    catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3917    if (__cat != -1)
3918        __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3919    return __cat;
3920#endif // _WIN32
3921}
3922
3923template <class _CharT>
3924typename messages<_CharT>::string_type
3925messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3926                         const string_type& __dflt) const
3927{
3928#ifdef _WIN32
3929    return __dflt;
3930#else // _WIN32
3931    string __ndflt;
3932    __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3933                                                       __dflt.c_str(),
3934                                                       __dflt.c_str() + __dflt.size());
3935    if (__c != -1)
3936        __c <<= 1;
3937    nl_catd __cat = (nl_catd)__c;
3938    char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3939    string_type __w;
3940    __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3941                                                        __n, __n + strlen(__n));
3942    return __w;
3943#endif // _WIN32
3944}
3945
3946template <class _CharT>
3947void
3948messages<_CharT>::do_close(catalog __c) const
3949{
3950#if !defined(_WIN32)
3951    if (__c != -1)
3952        __c <<= 1;
3953    nl_catd __cat = (nl_catd)__c;
3954    catclose(__cat);
3955#endif // !_WIN32
3956}
3957
3958_LIBCPP_EXTERN_TEMPLATE(class messages<char>)
3959_LIBCPP_EXTERN_TEMPLATE(class messages<wchar_t>)
3960
3961template <class _CharT>
3962class _LIBCPP_TYPE_VIS messages_byname
3963    : public messages<_CharT>
3964{
3965public:
3966    typedef messages_base::catalog catalog;
3967    typedef basic_string<_CharT> string_type;
3968
3969    _LIBCPP_ALWAYS_INLINE
3970    explicit messages_byname(const char*, size_t __refs = 0)
3971        : messages<_CharT>(__refs) {}
3972
3973    _LIBCPP_ALWAYS_INLINE
3974    explicit messages_byname(const string&, size_t __refs = 0)
3975        : messages<_CharT>(__refs) {}
3976
3977protected:
3978    _LIBCPP_ALWAYS_INLINE
3979    ~messages_byname() {}
3980};
3981
3982_LIBCPP_EXTERN_TEMPLATE(class messages_byname<char>)
3983_LIBCPP_EXTERN_TEMPLATE(class messages_byname<wchar_t>)
3984
3985template<class _Codecvt, class _Elem = wchar_t,
3986         class _Wide_alloc = allocator<_Elem>,
3987         class _Byte_alloc = allocator<char> >
3988class _LIBCPP_TYPE_VIS wstring_convert
3989{
3990public:
3991    typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;
3992    typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3993    typedef typename _Codecvt::state_type                        state_type;
3994    typedef typename wide_string::traits_type::int_type          int_type;
3995
3996private:
3997    byte_string __byte_err_string_;
3998    wide_string __wide_err_string_;
3999    _Codecvt* __cvtptr_;
4000    state_type __cvtstate_;
4001    size_t __cvtcount_;
4002
4003    wstring_convert(const wstring_convert& __wc);
4004    wstring_convert& operator=(const wstring_convert& __wc);
4005public:
4006    wstring_convert(_Codecvt* __pcvt = new _Codecvt);
4007    wstring_convert(_Codecvt* __pcvt, state_type __state);
4008    wstring_convert(const byte_string& __byte_err,
4009                    const wide_string& __wide_err = wide_string());
4010#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4011    wstring_convert(wstring_convert&& __wc);
4012#endif
4013    ~wstring_convert();
4014
4015    _LIBCPP_ALWAYS_INLINE
4016    wide_string from_bytes(char __byte)
4017        {return from_bytes(&__byte, &__byte+1);}
4018    _LIBCPP_ALWAYS_INLINE
4019    wide_string from_bytes(const char* __ptr)
4020        {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
4021    _LIBCPP_ALWAYS_INLINE
4022    wide_string from_bytes(const byte_string& __str)
4023        {return from_bytes(__str.data(), __str.data() + __str.size());}
4024    wide_string from_bytes(const char* __first, const char* __last);
4025
4026    _LIBCPP_ALWAYS_INLINE
4027    byte_string to_bytes(_Elem __wchar)
4028        {return to_bytes(&__wchar, &__wchar+1);}
4029    _LIBCPP_ALWAYS_INLINE
4030    byte_string to_bytes(const _Elem* __wptr)
4031        {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
4032    _LIBCPP_ALWAYS_INLINE
4033    byte_string to_bytes(const wide_string& __wstr)
4034        {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
4035    byte_string to_bytes(const _Elem* __first, const _Elem* __last);
4036
4037    _LIBCPP_ALWAYS_INLINE
4038    size_t converted() const {return __cvtcount_;}
4039    _LIBCPP_ALWAYS_INLINE
4040    state_type state() const {return __cvtstate_;}
4041};
4042
4043template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4044inline _LIBCPP_ALWAYS_INLINE
4045wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4046    wstring_convert(_Codecvt* __pcvt)
4047        : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
4048{
4049}
4050
4051template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4052inline _LIBCPP_ALWAYS_INLINE
4053wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4054    wstring_convert(_Codecvt* __pcvt, state_type __state)
4055        : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
4056{
4057}
4058
4059template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4060wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4061    wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
4062        : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
4063          __cvtstate_(), __cvtcount_(0)
4064{
4065    __cvtptr_ = new _Codecvt;
4066}
4067
4068#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4069
4070template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4071inline _LIBCPP_ALWAYS_INLINE
4072wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4073    wstring_convert(wstring_convert&& __wc)
4074        : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
4075          __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
4076          __cvtptr_(__wc.__cvtptr_),
4077          __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
4078{
4079    __wc.__cvtptr_ = nullptr;
4080}
4081
4082#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4083
4084template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4085wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
4086{
4087    delete __cvtptr_;
4088}
4089
4090template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4091typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
4092wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4093    from_bytes(const char* __frm, const char* __frm_end)
4094{
4095    __cvtcount_ = 0;
4096    if (__cvtptr_ != nullptr)
4097    {
4098        wide_string __ws(2*(__frm_end - __frm), _Elem());
4099        if (__frm != __frm_end)
4100            __ws.resize(__ws.capacity());
4101        codecvt_base::result __r = codecvt_base::ok;
4102        state_type __st = __cvtstate_;
4103        if (__frm != __frm_end)
4104        {
4105            _Elem* __to = &__ws[0];
4106            _Elem* __to_end = __to + __ws.size();
4107            const char* __frm_nxt;
4108            do
4109            {
4110                _Elem* __to_nxt;
4111                __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
4112                                          __to, __to_end, __to_nxt);
4113                __cvtcount_ += __frm_nxt - __frm;
4114                if (__frm_nxt == __frm)
4115                {
4116                    __r = codecvt_base::error;
4117                }
4118                else if (__r == codecvt_base::noconv)
4119                {
4120                    __ws.resize(__to - &__ws[0]);
4121                    // This only gets executed if _Elem is char
4122                    __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
4123                    __frm = __frm_nxt;
4124                    __r = codecvt_base::ok;
4125                }
4126                else if (__r == codecvt_base::ok)
4127                {
4128                    __ws.resize(__to_nxt - &__ws[0]);
4129                    __frm = __frm_nxt;
4130                }
4131                else if (__r == codecvt_base::partial)
4132                {
4133                    ptrdiff_t __s = __to_nxt - &__ws[0];
4134                    __ws.resize(2 * __s);
4135                    __to = &__ws[0] + __s;
4136                    __to_end = &__ws[0] + __ws.size();
4137                    __frm = __frm_nxt;
4138                }
4139            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4140        }
4141        if (__r == codecvt_base::ok)
4142            return __ws;
4143    }
4144#ifndef _LIBCPP_NO_EXCEPTIONS
4145    if (__wide_err_string_.empty())
4146        throw range_error("wstring_convert: from_bytes error");
4147#endif  // _LIBCPP_NO_EXCEPTIONS
4148    return __wide_err_string_;
4149}
4150
4151template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
4152typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
4153wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
4154    to_bytes(const _Elem* __frm, const _Elem* __frm_end)
4155{
4156    __cvtcount_ = 0;
4157    if (__cvtptr_ != nullptr)
4158    {
4159        byte_string __bs(2*(__frm_end - __frm), char());
4160        if (__frm != __frm_end)
4161            __bs.resize(__bs.capacity());
4162        codecvt_base::result __r = codecvt_base::ok;
4163        state_type __st = __cvtstate_;
4164        if (__frm != __frm_end)
4165        {
4166            char* __to = &__bs[0];
4167            char* __to_end = __to + __bs.size();
4168            const _Elem* __frm_nxt;
4169            do
4170            {
4171                char* __to_nxt;
4172                __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
4173                                           __to, __to_end, __to_nxt);
4174                __cvtcount_ += __frm_nxt - __frm;
4175                if (__frm_nxt == __frm)
4176                {
4177                    __r = codecvt_base::error;
4178                }
4179                else if (__r == codecvt_base::noconv)
4180                {
4181                    __bs.resize(__to - &__bs[0]);
4182                    // This only gets executed if _Elem is char
4183                    __bs.append((const char*)__frm, (const char*)__frm_end);
4184                    __frm = __frm_nxt;
4185                    __r = codecvt_base::ok;
4186                }
4187                else if (__r == codecvt_base::ok)
4188                {
4189                    __bs.resize(__to_nxt - &__bs[0]);
4190                    __frm = __frm_nxt;
4191                }
4192                else if (__r == codecvt_base::partial)
4193                {
4194                    ptrdiff_t __s = __to_nxt - &__bs[0];
4195                    __bs.resize(2 * __s);
4196                    __to = &__bs[0] + __s;
4197                    __to_end = &__bs[0] + __bs.size();
4198                    __frm = __frm_nxt;
4199                }
4200            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
4201        }
4202        if (__r == codecvt_base::ok)
4203        {
4204            size_t __s = __bs.size();
4205            __bs.resize(__bs.capacity());
4206            char* __to = &__bs[0] + __s;
4207            char* __to_end = __to + __bs.size();
4208            do
4209            {
4210                char* __to_nxt;
4211                __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
4212                if (__r == codecvt_base::noconv)
4213                {
4214                    __bs.resize(__to - &__bs[0]);
4215                    __r = codecvt_base::ok;
4216                }
4217                else if (__r == codecvt_base::ok)
4218                {
4219                    __bs.resize(__to_nxt - &__bs[0]);
4220                }
4221                else if (__r == codecvt_base::partial)
4222                {
4223                    ptrdiff_t __sp = __to_nxt - &__bs[0];
4224                    __bs.resize(2 * __sp);
4225                    __to = &__bs[0] + __sp;
4226                    __to_end = &__bs[0] + __bs.size();
4227                }
4228            } while (__r == codecvt_base::partial);
4229            if (__r == codecvt_base::ok)
4230                return __bs;
4231        }
4232    }
4233#ifndef _LIBCPP_NO_EXCEPTIONS
4234    if (__byte_err_string_.empty())
4235        throw range_error("wstring_convert: to_bytes error");
4236#endif  // _LIBCPP_NO_EXCEPTIONS
4237    return __byte_err_string_;
4238}
4239
4240template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
4241class _LIBCPP_TYPE_VIS wbuffer_convert
4242    : public basic_streambuf<_Elem, _Tr>
4243{
4244public:
4245    // types:
4246    typedef _Elem                          char_type;
4247    typedef _Tr                            traits_type;
4248    typedef typename traits_type::int_type int_type;
4249    typedef typename traits_type::pos_type pos_type;
4250    typedef typename traits_type::off_type off_type;
4251    typedef typename _Codecvt::state_type  state_type;
4252
4253private:
4254    char*       __extbuf_;
4255    const char* __extbufnext_;
4256    const char* __extbufend_;
4257    char __extbuf_min_[8];
4258    size_t __ebs_;
4259    char_type* __intbuf_;
4260    size_t __ibs_;
4261    streambuf* __bufptr_;
4262    _Codecvt* __cv_;
4263    state_type __st_;
4264    ios_base::openmode __cm_;
4265    bool __owns_eb_;
4266    bool __owns_ib_;
4267    bool __always_noconv_;
4268
4269    wbuffer_convert(const wbuffer_convert&);
4270    wbuffer_convert& operator=(const wbuffer_convert&);
4271public:
4272    wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
4273                    state_type __state = state_type());
4274    ~wbuffer_convert();
4275
4276    _LIBCPP_INLINE_VISIBILITY
4277    streambuf* rdbuf() const {return __bufptr_;}
4278    _LIBCPP_INLINE_VISIBILITY
4279    streambuf* rdbuf(streambuf* __bytebuf)
4280    {
4281        streambuf* __r = __bufptr_;
4282        __bufptr_ = __bytebuf;
4283        return __r;
4284    }
4285
4286    _LIBCPP_INLINE_VISIBILITY
4287    state_type state() const {return __st_;}
4288
4289protected:
4290    virtual int_type underflow();
4291    virtual int_type pbackfail(int_type __c = traits_type::eof());
4292    virtual int_type overflow (int_type __c = traits_type::eof());
4293    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
4294                                                            streamsize __n);
4295    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
4296                             ios_base::openmode __wch = ios_base::in | ios_base::out);
4297    virtual pos_type seekpos(pos_type __sp,
4298                             ios_base::openmode __wch = ios_base::in | ios_base::out);
4299    virtual int sync();
4300
4301private:
4302    bool __read_mode();
4303    void __write_mode();
4304    wbuffer_convert* __close();
4305};
4306
4307template <class _Codecvt, class _Elem, class _Tr>
4308wbuffer_convert<_Codecvt, _Elem, _Tr>::
4309    wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
4310    : __extbuf_(0),
4311      __extbufnext_(0),
4312      __extbufend_(0),
4313      __ebs_(0),
4314      __intbuf_(0),
4315      __ibs_(0),
4316      __bufptr_(__bytebuf),
4317      __cv_(__pcvt),
4318      __st_(__state),
4319      __cm_(0),
4320      __owns_eb_(false),
4321      __owns_ib_(false),
4322      __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
4323{
4324    setbuf(0, 4096);
4325}
4326
4327template <class _Codecvt, class _Elem, class _Tr>
4328wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
4329{
4330    __close();
4331    delete __cv_;
4332    if (__owns_eb_)
4333        delete [] __extbuf_;
4334    if (__owns_ib_)
4335        delete [] __intbuf_;
4336}
4337
4338template <class _Codecvt, class _Elem, class _Tr>
4339typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4340wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
4341{
4342    if (__cv_ == 0 || __bufptr_ == 0)
4343        return traits_type::eof();
4344    bool __initial = __read_mode();
4345    char_type __1buf;
4346    if (this->gptr() == 0)
4347        this->setg(&__1buf, &__1buf+1, &__1buf+1);
4348    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
4349    int_type __c = traits_type::eof();
4350    if (this->gptr() == this->egptr())
4351    {
4352        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
4353        if (__always_noconv_)
4354        {
4355            streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
4356            __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
4357            if (__nmemb != 0)
4358            {
4359                this->setg(this->eback(),
4360                           this->eback() + __unget_sz,
4361                           this->eback() + __unget_sz + __nmemb);
4362                __c = *this->gptr();
4363            }
4364        }
4365        else
4366        {
4367            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
4368            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
4369            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
4370            streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
4371                                 static_cast<streamsize>(__extbufend_ - __extbufnext_));
4372            codecvt_base::result __r;
4373            state_type __svs = __st_;
4374            streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
4375            if (__nr != 0)
4376            {
4377                __extbufend_ = __extbufnext_ + __nr;
4378                char_type*  __inext;
4379                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
4380                                       this->eback() + __unget_sz,
4381                                       this->egptr(), __inext);
4382                if (__r == codecvt_base::noconv)
4383                {
4384                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
4385                    __c = *this->gptr();
4386                }
4387                else if (__inext != this->eback() + __unget_sz)
4388                {
4389                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);
4390                    __c = *this->gptr();
4391                }
4392            }
4393        }
4394    }
4395    else
4396        __c = *this->gptr();
4397    if (this->eback() == &__1buf)
4398        this->setg(0, 0, 0);
4399    return __c;
4400}
4401
4402template <class _Codecvt, class _Elem, class _Tr>
4403typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4404wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
4405{
4406    if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
4407    {
4408        if (traits_type::eq_int_type(__c, traits_type::eof()))
4409        {
4410            this->gbump(-1);
4411            return traits_type::not_eof(__c);
4412        }
4413        if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
4414        {
4415            this->gbump(-1);
4416            *this->gptr() = traits_type::to_char_type(__c);
4417            return __c;
4418        }
4419    }
4420    return traits_type::eof();
4421}
4422
4423template <class _Codecvt, class _Elem, class _Tr>
4424typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
4425wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
4426{
4427    if (__cv_ == 0 || __bufptr_ == 0)
4428        return traits_type::eof();
4429    __write_mode();
4430    char_type __1buf;
4431    char_type* __pb_save = this->pbase();
4432    char_type* __epb_save = this->epptr();
4433    if (!traits_type::eq_int_type(__c, traits_type::eof()))
4434    {
4435        if (this->pptr() == 0)
4436            this->setp(&__1buf, &__1buf+1);
4437        *this->pptr() = traits_type::to_char_type(__c);
4438        this->pbump(1);
4439    }
4440    if (this->pptr() != this->pbase())
4441    {
4442        if (__always_noconv_)
4443        {
4444            streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4445            if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4446                return traits_type::eof();
4447        }
4448        else
4449        {
4450            char* __extbe = __extbuf_;
4451            codecvt_base::result __r;
4452            do
4453            {
4454                const char_type* __e;
4455                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4456                                        __extbuf_, __extbuf_ + __ebs_, __extbe);
4457                if (__e == this->pbase())
4458                    return traits_type::eof();
4459                if (__r == codecvt_base::noconv)
4460                {
4461                    streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4462                    if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4463                        return traits_type::eof();
4464                }
4465                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4466                {
4467                    streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4468                    if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4469                        return traits_type::eof();
4470                    if (__r == codecvt_base::partial)
4471                    {
4472                        this->setp((char_type*)__e, this->pptr());
4473                        this->pbump(this->epptr() - this->pbase());
4474                    }
4475                }
4476                else
4477                    return traits_type::eof();
4478            } while (__r == codecvt_base::partial);
4479        }
4480        this->setp(__pb_save, __epb_save);
4481    }
4482    return traits_type::not_eof(__c);
4483}
4484
4485template <class _Codecvt, class _Elem, class _Tr>
4486basic_streambuf<_Elem, _Tr>*
4487wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4488{
4489    this->setg(0, 0, 0);
4490    this->setp(0, 0);
4491    if (__owns_eb_)
4492        delete [] __extbuf_;
4493    if (__owns_ib_)
4494        delete [] __intbuf_;
4495    __ebs_ = __n;
4496    if (__ebs_ > sizeof(__extbuf_min_))
4497    {
4498        if (__always_noconv_ && __s)
4499        {
4500            __extbuf_ = (char*)__s;
4501            __owns_eb_ = false;
4502        }
4503        else
4504        {
4505            __extbuf_ = new char[__ebs_];
4506            __owns_eb_ = true;
4507        }
4508    }
4509    else
4510    {
4511        __extbuf_ = __extbuf_min_;
4512        __ebs_ = sizeof(__extbuf_min_);
4513        __owns_eb_ = false;
4514    }
4515    if (!__always_noconv_)
4516    {
4517        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4518        if (__s && __ibs_ >= sizeof(__extbuf_min_))
4519        {
4520            __intbuf_ = __s;
4521            __owns_ib_ = false;
4522        }
4523        else
4524        {
4525            __intbuf_ = new char_type[__ibs_];
4526            __owns_ib_ = true;
4527        }
4528    }
4529    else
4530    {
4531        __ibs_ = 0;
4532        __intbuf_ = 0;
4533        __owns_ib_ = false;
4534    }
4535    return this;
4536}
4537
4538template <class _Codecvt, class _Elem, class _Tr>
4539typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4540wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4541                                        ios_base::openmode __om)
4542{
4543    int __width = __cv_->encoding();
4544    if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4545        return pos_type(off_type(-1));
4546    // __width > 0 || __off == 0
4547    switch (__way)
4548    {
4549    case ios_base::beg:
4550        break;
4551    case ios_base::cur:
4552        break;
4553    case ios_base::end:
4554        break;
4555    default:
4556        return pos_type(off_type(-1));
4557    }
4558    pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4559    __r.state(__st_);
4560    return __r;
4561}
4562
4563template <class _Codecvt, class _Elem, class _Tr>
4564typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4565wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4566{
4567    if (__cv_ == 0 || __bufptr_ == 0 || sync())
4568        return pos_type(off_type(-1));
4569    if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4570        return pos_type(off_type(-1));
4571    return __sp;
4572}
4573
4574template <class _Codecvt, class _Elem, class _Tr>
4575int
4576wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4577{
4578    if (__cv_ == 0 || __bufptr_ == 0)
4579        return 0;
4580    if (__cm_ & ios_base::out)
4581    {
4582        if (this->pptr() != this->pbase())
4583            if (overflow() == traits_type::eof())
4584                return -1;
4585        codecvt_base::result __r;
4586        do
4587        {
4588            char* __extbe;
4589            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4590            streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4591            if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4592                return -1;
4593        } while (__r == codecvt_base::partial);
4594        if (__r == codecvt_base::error)
4595            return -1;
4596        if (__bufptr_->pubsync())
4597            return -1;
4598    }
4599    else if (__cm_ & ios_base::in)
4600    {
4601        off_type __c;
4602        if (__always_noconv_)
4603            __c = this->egptr() - this->gptr();
4604        else
4605        {
4606            int __width = __cv_->encoding();
4607            __c = __extbufend_ - __extbufnext_;
4608            if (__width > 0)
4609                __c += __width * (this->egptr() - this->gptr());
4610            else
4611            {
4612                if (this->gptr() != this->egptr())
4613                {
4614                    reverse(this->gptr(), this->egptr());
4615                    codecvt_base::result __r;
4616                    const char_type* __e = this->gptr();
4617                    char* __extbe;
4618                    do
4619                    {
4620                        __r = __cv_->out(__st_, __e, this->egptr(), __e,
4621                                         __extbuf_, __extbuf_ + __ebs_, __extbe);
4622                        switch (__r)
4623                        {
4624                        case codecvt_base::noconv:
4625                            __c += this->egptr() - this->gptr();
4626                            break;
4627                        case codecvt_base::ok:
4628                        case codecvt_base::partial:
4629                            __c += __extbe - __extbuf_;
4630                            break;
4631                        default:
4632                            return -1;
4633                        }
4634                    } while (__r == codecvt_base::partial);
4635                }
4636            }
4637        }
4638        if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4639            return -1;
4640        this->setg(0, 0, 0);
4641        __cm_ = 0;
4642    }
4643    return 0;
4644}
4645
4646template <class _Codecvt, class _Elem, class _Tr>
4647bool
4648wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4649{
4650    if (!(__cm_ & ios_base::in))
4651    {
4652        this->setp(0, 0);
4653        if (__always_noconv_)
4654            this->setg((char_type*)__extbuf_,
4655                       (char_type*)__extbuf_ + __ebs_,
4656                       (char_type*)__extbuf_ + __ebs_);
4657        else
4658            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4659        __cm_ = ios_base::in;
4660        return true;
4661    }
4662    return false;
4663}
4664
4665template <class _Codecvt, class _Elem, class _Tr>
4666void
4667wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4668{
4669    if (!(__cm_ & ios_base::out))
4670    {
4671        this->setg(0, 0, 0);
4672        if (__ebs_ > sizeof(__extbuf_min_))
4673        {
4674            if (__always_noconv_)
4675                this->setp((char_type*)__extbuf_,
4676                           (char_type*)__extbuf_ + (__ebs_ - 1));
4677            else
4678                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4679        }
4680        else
4681            this->setp(0, 0);
4682        __cm_ = ios_base::out;
4683    }
4684}
4685
4686template <class _Codecvt, class _Elem, class _Tr>
4687wbuffer_convert<_Codecvt, _Elem, _Tr>*
4688wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4689{
4690    wbuffer_convert* __rt = 0;
4691    if (__cv_ != 0 && __bufptr_ != 0)
4692    {
4693        __rt = this;
4694        if ((__cm_ & ios_base::out) && sync())
4695            __rt = 0;
4696    }
4697    return __rt;
4698}
4699
4700_LIBCPP_END_NAMESPACE_STD
4701
4702#endif  // _LIBCPP_LOCALE
4703