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