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