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