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