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