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