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