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