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