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