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