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