]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/locale
Merge ^/head r313644 through r313895.
[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                           + 2;
1403     char __nar[__nbuf];
1404     int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1405     char* __ne = __nar + __nc;
1406     char* __np = this->__identify_padding(__nar, __ne, __iob);
1407     // Stage 2 - Widen __nar while adding thousands separators
1408     char_type __o[2*(__nbuf-1) - 1];
1409     char_type* __op;  // pad here
1410     char_type* __oe;  // end of output
1411     this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1412     // [__o, __oe) contains thousands_sep'd wide number
1413     // Stage 3 & 4
1414     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1415 }
1416
1417 template <class _CharT, class _OutputIterator>
1418 _OutputIterator
1419 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1420                                          char_type __fl, long long __v) const
1421 {
1422     // Stage 1 - Get number in narrow char
1423     char __fmt[8] = {'%', 0};
1424     const char* __len = "ll";
1425     this->__format_int(__fmt+1, __len, true, __iob.flags());
1426     const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
1427                           + ((numeric_limits<long long>::digits % 3) != 0)
1428                           + 2;
1429     char __nar[__nbuf];
1430     int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1431     char* __ne = __nar + __nc;
1432     char* __np = this->__identify_padding(__nar, __ne, __iob);
1433     // Stage 2 - Widen __nar while adding thousands separators
1434     char_type __o[2*(__nbuf-1) - 1];
1435     char_type* __op;  // pad here
1436     char_type* __oe;  // end of output
1437     this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1438     // [__o, __oe) contains thousands_sep'd wide number
1439     // Stage 3 & 4
1440     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1441 }
1442
1443 template <class _CharT, class _OutputIterator>
1444 _OutputIterator
1445 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1446                                          char_type __fl, unsigned long __v) const
1447 {
1448     // Stage 1 - Get number in narrow char
1449     char __fmt[6] = {'%', 0};
1450     const char* __len = "l";
1451     this->__format_int(__fmt+1, __len, false, __iob.flags());
1452     const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
1453                           + ((numeric_limits<unsigned long>::digits % 3) != 0)
1454                           + 1;
1455     char __nar[__nbuf];
1456     int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1457     char* __ne = __nar + __nc;
1458     char* __np = this->__identify_padding(__nar, __ne, __iob);
1459     // Stage 2 - Widen __nar while adding thousands separators
1460     char_type __o[2*(__nbuf-1) - 1];
1461     char_type* __op;  // pad here
1462     char_type* __oe;  // end of output
1463     this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1464     // [__o, __oe) contains thousands_sep'd wide number
1465     // Stage 3 & 4
1466     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1467 }
1468
1469 template <class _CharT, class _OutputIterator>
1470 _OutputIterator
1471 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1472                                          char_type __fl, unsigned long long __v) const
1473 {
1474     // Stage 1 - Get number in narrow char
1475     char __fmt[8] = {'%', 0};
1476     const char* __len = "ll";
1477     this->__format_int(__fmt+1, __len, false, __iob.flags());
1478     const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
1479                           + ((numeric_limits<unsigned long long>::digits % 3) != 0)
1480                           + 1;
1481     char __nar[__nbuf];
1482     int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1483     char* __ne = __nar + __nc;
1484     char* __np = this->__identify_padding(__nar, __ne, __iob);
1485     // Stage 2 - Widen __nar while adding thousands separators
1486     char_type __o[2*(__nbuf-1) - 1];
1487     char_type* __op;  // pad here
1488     char_type* __oe;  // end of output
1489     this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
1490     // [__o, __oe) contains thousands_sep'd wide number
1491     // Stage 3 & 4
1492     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1493 }
1494
1495 template <class _CharT, class _OutputIterator>
1496 _OutputIterator
1497 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1498                                          char_type __fl, double __v) const
1499 {
1500     // Stage 1 - Get number in narrow char
1501     char __fmt[8] = {'%', 0};
1502     const char* __len = "";
1503     bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1504     const unsigned __nbuf = 30;
1505     char __nar[__nbuf];
1506     char* __nb = __nar;
1507     int __nc;
1508     if (__specify_precision)
1509         __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1510                                    (int)__iob.precision(), __v);
1511     else
1512         __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1513     unique_ptr<char, void(*)(void*)> __nbh(0, free);
1514     if (__nc > static_cast<int>(__nbuf-1))
1515     {
1516         if (__specify_precision)
1517             __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1518         else
1519             __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1520         if (__nb == 0)
1521             __throw_bad_alloc();
1522         __nbh.reset(__nb);
1523     }
1524     char* __ne = __nb + __nc;
1525     char* __np = this->__identify_padding(__nb, __ne, __iob);
1526     // Stage 2 - Widen __nar while adding thousands separators
1527     char_type __o[2*(__nbuf-1) - 1];
1528     char_type* __ob = __o;
1529     unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1530     if (__nb != __nar)
1531     {
1532         __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1533         if (__ob == 0)
1534             __throw_bad_alloc();
1535         __obh.reset(__ob);
1536     }
1537     char_type* __op;  // pad here
1538     char_type* __oe;  // end of output
1539     this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1540     // [__o, __oe) contains thousands_sep'd wide number
1541     // Stage 3 & 4
1542     __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1543     return __s;
1544 }
1545
1546 template <class _CharT, class _OutputIterator>
1547 _OutputIterator
1548 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1549                                          char_type __fl, long double __v) const
1550 {
1551     // Stage 1 - Get number in narrow char
1552     char __fmt[8] = {'%', 0};
1553     const char* __len = "L";
1554     bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
1555     const unsigned __nbuf = 30;
1556     char __nar[__nbuf];
1557     char* __nb = __nar;
1558     int __nc;
1559     if (__specify_precision)
1560         __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
1561                                    (int)__iob.precision(), __v);
1562     else
1563         __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1564     unique_ptr<char, void(*)(void*)> __nbh(0, free);
1565     if (__nc > static_cast<int>(__nbuf-1))
1566     {
1567         if (__specify_precision)
1568             __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
1569         else
1570             __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
1571         if (__nb == 0)
1572             __throw_bad_alloc();
1573         __nbh.reset(__nb);
1574     }
1575     char* __ne = __nb + __nc;
1576     char* __np = this->__identify_padding(__nb, __ne, __iob);
1577     // Stage 2 - Widen __nar while adding thousands separators
1578     char_type __o[2*(__nbuf-1) - 1];
1579     char_type* __ob = __o;
1580     unique_ptr<char_type, void(*)(void*)> __obh(0, free);
1581     if (__nb != __nar)
1582     {
1583         __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
1584         if (__ob == 0)
1585             __throw_bad_alloc();
1586         __obh.reset(__ob);
1587     }
1588     char_type* __op;  // pad here
1589     char_type* __oe;  // end of output
1590     this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
1591     // [__o, __oe) contains thousands_sep'd wide number
1592     // Stage 3 & 4
1593     __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
1594     return __s;
1595 }
1596
1597 template <class _CharT, class _OutputIterator>
1598 _OutputIterator
1599 num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
1600                                          char_type __fl, const void* __v) const
1601 {
1602     // Stage 1 - Get pointer in narrow char
1603     char __fmt[6] = "%p";
1604     const unsigned __nbuf = 20;
1605     char __nar[__nbuf];
1606     int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
1607     char* __ne = __nar + __nc;
1608     char* __np = this->__identify_padding(__nar, __ne, __iob);
1609     // Stage 2 - Widen __nar
1610     char_type __o[2*(__nbuf-1) - 1];
1611     char_type* __op;  // pad here
1612     char_type* __oe;  // end of output
1613     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
1614     __ct.widen(__nar, __ne, __o);
1615     __oe = __o + (__ne - __nar);
1616     if (__np == __ne)
1617         __op = __oe;
1618     else
1619         __op = __o + (__np - __nar);
1620     // [__o, __oe) contains wide number
1621     // Stage 3 & 4
1622     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
1623 }
1624
1625 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>)
1626 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>)
1627
1628 template <class _CharT, class _InputIterator>
1629 _LIBCPP_HIDDEN
1630 int
1631 __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
1632                      ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
1633 {
1634     // Precondition:  __n >= 1
1635     if (__b == __e)
1636     {
1637         __err |= ios_base::eofbit | ios_base::failbit;
1638         return 0;
1639     }
1640     // get first digit
1641     _CharT __c = *__b;
1642     if (!__ct.is(ctype_base::digit, __c))
1643     {
1644         __err |= ios_base::failbit;
1645         return 0;
1646     }
1647     int __r = __ct.narrow(__c, 0) - '0';
1648     for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
1649     {
1650         // get next digit
1651         __c = *__b;
1652         if (!__ct.is(ctype_base::digit, __c))
1653             return __r;
1654         __r = __r * 10 + __ct.narrow(__c, 0) - '0';
1655     }
1656     if (__b == __e)
1657         __err |= ios_base::eofbit;
1658     return __r;
1659 }
1660
1661 class _LIBCPP_TYPE_VIS time_base
1662 {
1663 public:
1664     enum dateorder {no_order, dmy, mdy, ymd, ydm};
1665 };
1666
1667 template <class _CharT>
1668 class _LIBCPP_TEMPLATE_VIS __time_get_c_storage
1669 {
1670 protected:
1671     typedef basic_string<_CharT> string_type;
1672
1673     virtual const string_type* __weeks() const;
1674     virtual const string_type* __months() const;
1675     virtual const string_type* __am_pm() const;
1676     virtual const string_type& __c() const;
1677     virtual const string_type& __r() const;
1678     virtual const string_type& __x() const;
1679     virtual const string_type& __X() const;
1680
1681     _LIBCPP_ALWAYS_INLINE
1682     ~__time_get_c_storage() {}
1683 };
1684
1685 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
1686 class _LIBCPP_TEMPLATE_VIS time_get
1687     : public locale::facet,
1688       public time_base,
1689       private __time_get_c_storage<_CharT>
1690 {
1691 public:
1692     typedef _CharT                  char_type;
1693     typedef _InputIterator          iter_type;
1694     typedef time_base::dateorder    dateorder;
1695     typedef basic_string<char_type> string_type;
1696
1697     _LIBCPP_ALWAYS_INLINE
1698     explicit time_get(size_t __refs = 0)
1699         : locale::facet(__refs) {}
1700
1701     _LIBCPP_ALWAYS_INLINE
1702     dateorder date_order() const
1703     {
1704         return this->do_date_order();
1705     }
1706
1707     _LIBCPP_ALWAYS_INLINE
1708     iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
1709                        ios_base::iostate& __err, tm* __tm) const
1710     {
1711         return do_get_time(__b, __e, __iob, __err, __tm);
1712     }
1713
1714     _LIBCPP_ALWAYS_INLINE
1715     iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
1716                        ios_base::iostate& __err, tm* __tm) const
1717     {
1718         return do_get_date(__b, __e, __iob, __err, __tm);
1719     }
1720
1721     _LIBCPP_ALWAYS_INLINE
1722     iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1723                           ios_base::iostate& __err, tm* __tm) const
1724     {
1725         return do_get_weekday(__b, __e, __iob, __err, __tm);
1726     }
1727
1728     _LIBCPP_ALWAYS_INLINE
1729     iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1730                             ios_base::iostate& __err, tm* __tm) const
1731     {
1732         return do_get_monthname(__b, __e, __iob, __err, __tm);
1733     }
1734
1735     _LIBCPP_ALWAYS_INLINE
1736     iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
1737                        ios_base::iostate& __err, tm* __tm) const
1738     {
1739         return do_get_year(__b, __e, __iob, __err, __tm);
1740     }
1741
1742     _LIBCPP_ALWAYS_INLINE
1743     iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1744                   ios_base::iostate& __err, tm *__tm,
1745                   char __fmt, char __mod = 0) const
1746     {
1747         return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
1748     }
1749
1750     iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
1751                   ios_base::iostate& __err, tm* __tm,
1752                   const char_type* __fmtb, const char_type* __fmte) const;
1753
1754     static locale::id id;
1755
1756 protected:
1757     _LIBCPP_ALWAYS_INLINE
1758     ~time_get() {}
1759
1760     virtual dateorder do_date_order() const;
1761     virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
1762                                   ios_base::iostate& __err, tm* __tm) const;
1763     virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
1764                                   ios_base::iostate& __err, tm* __tm) const;
1765     virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
1766                                      ios_base::iostate& __err, tm* __tm) const;
1767     virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
1768                                        ios_base::iostate& __err, tm* __tm) const;
1769     virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
1770                                   ios_base::iostate& __err, tm* __tm) const;
1771     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
1772                              ios_base::iostate& __err, tm* __tm,
1773                              char __fmt, char __mod) const;
1774 private:
1775     void __get_white_space(iter_type& __b, iter_type __e,
1776                            ios_base::iostate& __err, const ctype<char_type>& __ct) const;
1777     void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
1778                        const ctype<char_type>& __ct) const;
1779
1780     void __get_weekdayname(int& __m,
1781                            iter_type& __b, iter_type __e,
1782                            ios_base::iostate& __err,
1783                            const ctype<char_type>& __ct) const;
1784     void __get_monthname(int& __m,
1785                          iter_type& __b, iter_type __e,
1786                          ios_base::iostate& __err,
1787                          const ctype<char_type>& __ct) const;
1788     void __get_day(int& __d,
1789                    iter_type& __b, iter_type __e,
1790                    ios_base::iostate& __err,
1791                    const ctype<char_type>& __ct) const;
1792     void __get_month(int& __m,
1793                      iter_type& __b, iter_type __e,
1794                      ios_base::iostate& __err,
1795                      const ctype<char_type>& __ct) const;
1796     void __get_year(int& __y,
1797                    iter_type& __b, iter_type __e,
1798                    ios_base::iostate& __err,
1799                    const ctype<char_type>& __ct) const;
1800     void __get_year4(int& __y,
1801                     iter_type& __b, iter_type __e,
1802                     ios_base::iostate& __err,
1803                     const ctype<char_type>& __ct) const;
1804     void __get_hour(int& __d,
1805                     iter_type& __b, iter_type __e,
1806                     ios_base::iostate& __err,
1807                     const ctype<char_type>& __ct) const;
1808     void __get_12_hour(int& __h,
1809                        iter_type& __b, iter_type __e,
1810                        ios_base::iostate& __err,
1811                        const ctype<char_type>& __ct) const;
1812     void __get_am_pm(int& __h,
1813                      iter_type& __b, iter_type __e,
1814                      ios_base::iostate& __err,
1815                      const ctype<char_type>& __ct) const;
1816     void __get_minute(int& __m,
1817                       iter_type& __b, iter_type __e,
1818                       ios_base::iostate& __err,
1819                       const ctype<char_type>& __ct) const;
1820     void __get_second(int& __s,
1821                       iter_type& __b, iter_type __e,
1822                       ios_base::iostate& __err,
1823                       const ctype<char_type>& __ct) const;
1824     void __get_weekday(int& __w,
1825                        iter_type& __b, iter_type __e,
1826                        ios_base::iostate& __err,
1827                        const ctype<char_type>& __ct) const;
1828     void __get_day_year_num(int& __w,
1829                             iter_type& __b, iter_type __e,
1830                             ios_base::iostate& __err,
1831                             const ctype<char_type>& __ct) const;
1832 };
1833
1834 template <class _CharT, class _InputIterator>
1835 locale::id
1836 time_get<_CharT, _InputIterator>::id;
1837
1838 // time_get primitives
1839
1840 template <class _CharT, class _InputIterator>
1841 void
1842 time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
1843                                                     iter_type& __b, iter_type __e,
1844                                                     ios_base::iostate& __err,
1845                                                     const ctype<char_type>& __ct) const
1846 {
1847     // Note:  ignoring case comes from the POSIX strptime spec
1848     const string_type* __wk = this->__weeks();
1849     ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
1850     if (__i < 14)
1851         __w = __i % 7;
1852 }
1853
1854 template <class _CharT, class _InputIterator>
1855 void
1856 time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
1857                                                   iter_type& __b, iter_type __e,
1858                                                   ios_base::iostate& __err,
1859                                                   const ctype<char_type>& __ct) const
1860 {
1861     // Note:  ignoring case comes from the POSIX strptime spec
1862     const string_type* __month = this->__months();
1863     ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
1864     if (__i < 24)
1865         __m = __i % 12;
1866 }
1867
1868 template <class _CharT, class _InputIterator>
1869 void
1870 time_get<_CharT, _InputIterator>::__get_day(int& __d,
1871                                             iter_type& __b, iter_type __e,
1872                                             ios_base::iostate& __err,
1873                                             const ctype<char_type>& __ct) const
1874 {
1875     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1876     if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
1877         __d = __t;
1878     else
1879         __err |= ios_base::failbit;
1880 }
1881
1882 template <class _CharT, class _InputIterator>
1883 void
1884 time_get<_CharT, _InputIterator>::__get_month(int& __m,
1885                                               iter_type& __b, iter_type __e,
1886                                               ios_base::iostate& __err,
1887                                               const ctype<char_type>& __ct) const
1888 {
1889     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
1890     if (!(__err & ios_base::failbit) && __t <= 11)
1891         __m = __t;
1892     else
1893         __err |= ios_base::failbit;
1894 }
1895
1896 template <class _CharT, class _InputIterator>
1897 void
1898 time_get<_CharT, _InputIterator>::__get_year(int& __y,
1899                                              iter_type& __b, iter_type __e,
1900                                              ios_base::iostate& __err,
1901                                              const ctype<char_type>& __ct) const
1902 {
1903     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1904     if (!(__err & ios_base::failbit))
1905     {
1906         if (__t < 69)
1907             __t += 2000;
1908         else if (69 <= __t && __t <= 99)
1909             __t += 1900;
1910         __y = __t - 1900;
1911     }
1912 }
1913
1914 template <class _CharT, class _InputIterator>
1915 void
1916 time_get<_CharT, _InputIterator>::__get_year4(int& __y,
1917                                               iter_type& __b, iter_type __e,
1918                                               ios_base::iostate& __err,
1919                                               const ctype<char_type>& __ct) const
1920 {
1921     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
1922     if (!(__err & ios_base::failbit))
1923         __y = __t - 1900;
1924 }
1925
1926 template <class _CharT, class _InputIterator>
1927 void
1928 time_get<_CharT, _InputIterator>::__get_hour(int& __h,
1929                                              iter_type& __b, iter_type __e,
1930                                              ios_base::iostate& __err,
1931                                              const ctype<char_type>& __ct) const
1932 {
1933     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1934     if (!(__err & ios_base::failbit) && __t <= 23)
1935         __h = __t;
1936     else
1937         __err |= ios_base::failbit;
1938 }
1939
1940 template <class _CharT, class _InputIterator>
1941 void
1942 time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
1943                                                 iter_type& __b, iter_type __e,
1944                                                 ios_base::iostate& __err,
1945                                                 const ctype<char_type>& __ct) const
1946 {
1947     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1948     if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
1949         __h = __t;
1950     else
1951         __err |= ios_base::failbit;
1952 }
1953
1954 template <class _CharT, class _InputIterator>
1955 void
1956 time_get<_CharT, _InputIterator>::__get_minute(int& __m,
1957                                                iter_type& __b, iter_type __e,
1958                                                ios_base::iostate& __err,
1959                                                const ctype<char_type>& __ct) const
1960 {
1961     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1962     if (!(__err & ios_base::failbit) && __t <= 59)
1963         __m = __t;
1964     else
1965         __err |= ios_base::failbit;
1966 }
1967
1968 template <class _CharT, class _InputIterator>
1969 void
1970 time_get<_CharT, _InputIterator>::__get_second(int& __s,
1971                                                iter_type& __b, iter_type __e,
1972                                                ios_base::iostate& __err,
1973                                                const ctype<char_type>& __ct) const
1974 {
1975     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
1976     if (!(__err & ios_base::failbit) && __t <= 60)
1977         __s = __t;
1978     else
1979         __err |= ios_base::failbit;
1980 }
1981
1982 template <class _CharT, class _InputIterator>
1983 void
1984 time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
1985                                                 iter_type& __b, iter_type __e,
1986                                                 ios_base::iostate& __err,
1987                                                 const ctype<char_type>& __ct) const
1988 {
1989     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
1990     if (!(__err & ios_base::failbit) && __t <= 6)
1991         __w = __t;
1992     else
1993         __err |= ios_base::failbit;
1994 }
1995
1996 template <class _CharT, class _InputIterator>
1997 void
1998 time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
1999                                                      iter_type& __b, iter_type __e,
2000                                                      ios_base::iostate& __err,
2001                                                      const ctype<char_type>& __ct) const
2002 {
2003     int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
2004     if (!(__err & ios_base::failbit) && __t <= 365)
2005         __d = __t;
2006     else
2007         __err |= ios_base::failbit;
2008 }
2009
2010 template <class _CharT, class _InputIterator>
2011 void
2012 time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
2013                                                     ios_base::iostate& __err,
2014                                                     const ctype<char_type>& __ct) const
2015 {
2016     for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
2017         ;
2018     if (__b == __e)
2019         __err |= ios_base::eofbit;
2020 }
2021
2022 template <class _CharT, class _InputIterator>
2023 void
2024 time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
2025                                               iter_type& __b, iter_type __e,
2026                                               ios_base::iostate& __err,
2027                                               const ctype<char_type>& __ct) const
2028 {
2029     const string_type* __ap = this->__am_pm();
2030     if (__ap[0].size() + __ap[1].size() == 0)
2031     {
2032         __err |= ios_base::failbit;
2033         return;
2034     }
2035     ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
2036     if (__i == 0 && __h == 12)
2037         __h = 0;
2038     else if (__i == 1 && __h < 12)
2039         __h += 12;
2040 }
2041
2042 template <class _CharT, class _InputIterator>
2043 void
2044 time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
2045                                                 ios_base::iostate& __err,
2046                                                 const ctype<char_type>& __ct) const
2047 {
2048     if (__b == __e)
2049     {
2050         __err |= ios_base::eofbit | ios_base::failbit;
2051         return;
2052     }
2053     if (__ct.narrow(*__b, 0) != '%')
2054         __err |= ios_base::failbit;
2055     else if(++__b == __e)
2056         __err |= ios_base::eofbit;
2057 }
2058
2059 // time_get end primitives
2060
2061 template <class _CharT, class _InputIterator>
2062 _InputIterator
2063 time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
2064                                       ios_base& __iob,
2065                                       ios_base::iostate& __err, tm* __tm,
2066                                       const char_type* __fmtb, const char_type* __fmte) const
2067 {
2068     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2069     __err = ios_base::goodbit;
2070     while (__fmtb != __fmte && __err == ios_base::goodbit)
2071     {
2072         if (__b == __e)
2073         {
2074             __err = ios_base::failbit;
2075             break;
2076         }
2077         if (__ct.narrow(*__fmtb, 0) == '%')
2078         {
2079             if (++__fmtb == __fmte)
2080             {
2081                 __err = ios_base::failbit;
2082                 break;
2083             }
2084             char __cmd = __ct.narrow(*__fmtb, 0);
2085             char __opt = '\0';
2086             if (__cmd == 'E' || __cmd == '0')
2087             {
2088                 if (++__fmtb == __fmte)
2089                 {
2090                     __err = ios_base::failbit;
2091                     break;
2092                 }
2093                 __opt = __cmd;
2094                 __cmd = __ct.narrow(*__fmtb, 0);
2095             }
2096             __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
2097             ++__fmtb;
2098         }
2099         else if (__ct.is(ctype_base::space, *__fmtb))
2100         {
2101             for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
2102                 ;
2103             for (        ;    __b != __e    && __ct.is(ctype_base::space, *__b);    ++__b)
2104                 ;
2105         }
2106         else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
2107         {
2108             ++__b;
2109             ++__fmtb;
2110         }
2111         else
2112             __err = ios_base::failbit;
2113     }
2114     if (__b == __e)
2115         __err |= ios_base::eofbit;
2116     return __b;
2117 }
2118
2119 template <class _CharT, class _InputIterator>
2120 typename time_get<_CharT, _InputIterator>::dateorder
2121 time_get<_CharT, _InputIterator>::do_date_order() const
2122 {
2123     return mdy;
2124 }
2125
2126 template <class _CharT, class _InputIterator>
2127 _InputIterator
2128 time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
2129                                               ios_base& __iob,
2130                                               ios_base::iostate& __err,
2131                                               tm* __tm) const
2132 {
2133     const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2134     return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
2135 }
2136
2137 template <class _CharT, class _InputIterator>
2138 _InputIterator
2139 time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
2140                                               ios_base& __iob,
2141                                               ios_base::iostate& __err,
2142                                               tm* __tm) const
2143 {
2144     const string_type& __fmt = this->__x();
2145     return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
2146 }
2147
2148 template <class _CharT, class _InputIterator>
2149 _InputIterator
2150 time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
2151                                                  ios_base& __iob,
2152                                                  ios_base::iostate& __err,
2153                                                  tm* __tm) const
2154 {
2155     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2156     __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2157     return __b;
2158 }
2159
2160 template <class _CharT, class _InputIterator>
2161 _InputIterator
2162 time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
2163                                                    ios_base& __iob,
2164                                                    ios_base::iostate& __err,
2165                                                    tm* __tm) const
2166 {
2167     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2168     __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2169     return __b;
2170 }
2171
2172 template <class _CharT, class _InputIterator>
2173 _InputIterator
2174 time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
2175                                               ios_base& __iob,
2176                                               ios_base::iostate& __err,
2177                                               tm* __tm) const
2178 {
2179     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2180     __get_year(__tm->tm_year, __b, __e, __err, __ct);
2181     return __b;
2182 }
2183
2184 template <class _CharT, class _InputIterator>
2185 _InputIterator
2186 time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
2187                                          ios_base& __iob,
2188                                          ios_base::iostate& __err, tm* __tm,
2189                                          char __fmt, char) const
2190 {
2191     __err = ios_base::goodbit;
2192     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2193     switch (__fmt)
2194     {
2195     case 'a':
2196     case 'A':
2197         __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
2198         break;
2199     case 'b':
2200     case 'B':
2201     case 'h':
2202         __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
2203         break;
2204     case 'c':
2205         {
2206         const string_type& __fm = this->__c();
2207         __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2208         }
2209         break;
2210     case 'd':
2211     case 'e':
2212         __get_day(__tm->tm_mday, __b, __e, __err, __ct);
2213         break;
2214     case 'D':
2215         {
2216         const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
2217         __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2218         }
2219         break;
2220     case 'F':
2221         {
2222         const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
2223         __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2224         }
2225         break;
2226     case 'H':
2227         __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
2228         break;
2229     case 'I':
2230         __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
2231         break;
2232     case 'j':
2233         __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
2234         break;
2235     case 'm':
2236         __get_month(__tm->tm_mon, __b, __e, __err, __ct);
2237         break;
2238     case 'M':
2239         __get_minute(__tm->tm_min, __b, __e, __err, __ct);
2240         break;
2241     case 'n':
2242     case 't':
2243         __get_white_space(__b, __e, __err, __ct);
2244         break;
2245     case 'p':
2246         __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
2247         break;
2248     case 'r':
2249         {
2250         const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
2251         __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2252         }
2253         break;
2254     case 'R':
2255         {
2256         const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
2257         __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2258         }
2259         break;
2260     case 'S':
2261         __get_second(__tm->tm_sec, __b, __e, __err, __ct);
2262         break;
2263     case 'T':
2264         {
2265         const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
2266         __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
2267         }
2268         break;
2269     case 'w':
2270         __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
2271         break;
2272     case 'x':
2273         return do_get_date(__b, __e, __iob, __err, __tm);
2274     case 'X':
2275         {
2276         const string_type& __fm = this->__X();
2277         __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
2278         }
2279         break;
2280     case 'y':
2281         __get_year(__tm->tm_year, __b, __e, __err, __ct);
2282         break;
2283     case 'Y':
2284         __get_year4(__tm->tm_year, __b, __e, __err, __ct);
2285         break;
2286     case '%':
2287         __get_percent(__b, __e, __err, __ct);
2288         break;
2289     default:
2290         __err |= ios_base::failbit;
2291     }
2292     return __b;
2293 }
2294
2295 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>)
2296 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>)
2297
2298 class _LIBCPP_TYPE_VIS __time_get
2299 {
2300 protected:
2301     locale_t __loc_;
2302
2303     __time_get(const char* __nm);
2304     __time_get(const string& __nm);
2305     ~__time_get();
2306 };
2307
2308 template <class _CharT>
2309 class _LIBCPP_TEMPLATE_VIS __time_get_storage
2310     : public __time_get
2311 {
2312 protected:
2313     typedef basic_string<_CharT> string_type;
2314
2315     string_type __weeks_[14];
2316     string_type __months_[24];
2317     string_type __am_pm_[2];
2318     string_type __c_;
2319     string_type __r_;
2320     string_type __x_;
2321     string_type __X_;
2322
2323     explicit __time_get_storage(const char* __nm);
2324     explicit __time_get_storage(const string& __nm);
2325
2326     _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
2327
2328     time_base::dateorder __do_date_order() const;
2329
2330 private:
2331     void init(const ctype<_CharT>&);
2332     string_type __analyze(char __fmt, const ctype<_CharT>&);
2333 };
2334
2335 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2336 class _LIBCPP_TEMPLATE_VIS time_get_byname
2337     : public time_get<_CharT, _InputIterator>,
2338       private __time_get_storage<_CharT>
2339 {
2340 public:
2341     typedef time_base::dateorder    dateorder;
2342     typedef _InputIterator          iter_type;
2343     typedef _CharT                  char_type;
2344     typedef basic_string<char_type> string_type;
2345
2346     _LIBCPP_INLINE_VISIBILITY
2347     explicit time_get_byname(const char* __nm, size_t __refs = 0)
2348         : time_get<_CharT, _InputIterator>(__refs),
2349           __time_get_storage<_CharT>(__nm) {}
2350     _LIBCPP_INLINE_VISIBILITY
2351     explicit time_get_byname(const string& __nm, size_t __refs = 0)
2352         : time_get<_CharT, _InputIterator>(__refs),
2353           __time_get_storage<_CharT>(__nm) {}
2354
2355 protected:
2356     _LIBCPP_INLINE_VISIBILITY
2357     ~time_get_byname() {}
2358
2359     _LIBCPP_INLINE_VISIBILITY
2360     virtual dateorder do_date_order() const {return this->__do_date_order();}
2361 private:
2362     _LIBCPP_INLINE_VISIBILITY
2363     virtual const string_type* __weeks() const  {return this->__weeks_;}
2364     _LIBCPP_INLINE_VISIBILITY
2365     virtual const string_type* __months() const {return this->__months_;}
2366     _LIBCPP_INLINE_VISIBILITY
2367     virtual const string_type* __am_pm() const  {return this->__am_pm_;}
2368     _LIBCPP_INLINE_VISIBILITY
2369     virtual const string_type& __c() const      {return this->__c_;}
2370     _LIBCPP_INLINE_VISIBILITY
2371     virtual const string_type& __r() const      {return this->__r_;}
2372     _LIBCPP_INLINE_VISIBILITY
2373     virtual const string_type& __x() const      {return this->__x_;}
2374     _LIBCPP_INLINE_VISIBILITY
2375     virtual const string_type& __X() const      {return this->__X_;}
2376 };
2377
2378 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>)
2379 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>)
2380
2381 class _LIBCPP_TYPE_VIS __time_put
2382 {
2383     locale_t __loc_;
2384 protected:
2385     _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
2386     __time_put(const char* __nm);
2387     __time_put(const string& __nm);
2388     ~__time_put();
2389     void __do_put(char* __nb, char*& __ne, const tm* __tm,
2390                   char __fmt, char __mod) const;
2391     void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
2392                   char __fmt, char __mod) const;
2393 };
2394
2395 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2396 class _LIBCPP_TEMPLATE_VIS time_put
2397     : public locale::facet,
2398       private __time_put
2399 {
2400 public:
2401     typedef _CharT char_type;
2402     typedef _OutputIterator iter_type;
2403
2404     _LIBCPP_ALWAYS_INLINE
2405     explicit time_put(size_t __refs = 0)
2406         : locale::facet(__refs) {}
2407
2408     iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
2409                   const char_type* __pb, const char_type* __pe) const;
2410
2411     _LIBCPP_ALWAYS_INLINE
2412     iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
2413                   const tm* __tm, char __fmt, char __mod = 0) const
2414     {
2415         return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2416     }
2417
2418     static locale::id id;
2419
2420 protected:
2421     _LIBCPP_ALWAYS_INLINE
2422     ~time_put() {}
2423     virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
2424                              char __fmt, char __mod) const;
2425
2426     _LIBCPP_ALWAYS_INLINE
2427     explicit time_put(const char* __nm, size_t __refs)
2428         : locale::facet(__refs),
2429           __time_put(__nm) {}
2430     _LIBCPP_ALWAYS_INLINE
2431     explicit time_put(const string& __nm, size_t __refs)
2432         : locale::facet(__refs),
2433           __time_put(__nm) {}
2434 };
2435
2436 template <class _CharT, class _OutputIterator>
2437 locale::id
2438 time_put<_CharT, _OutputIterator>::id;
2439
2440 template <class _CharT, class _OutputIterator>
2441 _OutputIterator
2442 time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
2443                                        char_type __fl, const tm* __tm,
2444                                        const char_type* __pb,
2445                                        const char_type* __pe) const
2446 {
2447     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
2448     for (; __pb != __pe; ++__pb)
2449     {
2450         if (__ct.narrow(*__pb, 0) == '%')
2451         {
2452             if (++__pb == __pe)
2453             {
2454                 *__s++ = __pb[-1];
2455                 break;
2456             }
2457             char __mod = 0;
2458             char __fmt = __ct.narrow(*__pb, 0);
2459             if (__fmt == 'E' || __fmt == 'O')
2460             {
2461                 if (++__pb == __pe)
2462                 {
2463                     *__s++ = __pb[-2];
2464                     *__s++ = __pb[-1];
2465                     break;
2466                 }
2467                 __mod = __fmt;
2468                 __fmt = __ct.narrow(*__pb, 0);
2469             }
2470             __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
2471         }
2472         else
2473             *__s++ = *__pb;
2474     }
2475     return __s;
2476 }
2477
2478 template <class _CharT, class _OutputIterator>
2479 _OutputIterator
2480 time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
2481                                           char_type, const tm* __tm,
2482                                           char __fmt, char __mod) const
2483 {
2484     char_type __nar[100];
2485     char_type* __nb = __nar;
2486     char_type* __ne = __nb + 100;
2487     __do_put(__nb, __ne, __tm, __fmt, __mod);
2488     return _VSTD::copy(__nb, __ne, __s);
2489 }
2490
2491 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>)
2492 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>)
2493
2494 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
2495 class _LIBCPP_TEMPLATE_VIS time_put_byname
2496     : public time_put<_CharT, _OutputIterator>
2497 {
2498 public:
2499     _LIBCPP_ALWAYS_INLINE
2500     explicit time_put_byname(const char* __nm, size_t __refs = 0)
2501         : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2502
2503     _LIBCPP_ALWAYS_INLINE
2504     explicit time_put_byname(const string& __nm, size_t __refs = 0)
2505         : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
2506
2507 protected:
2508     _LIBCPP_ALWAYS_INLINE
2509     ~time_put_byname() {}
2510 };
2511
2512 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>)
2513 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>)
2514
2515 // money_base
2516
2517 class _LIBCPP_TYPE_VIS money_base
2518 {
2519 public:
2520     enum part {none, space, symbol, sign, value};
2521     struct pattern {char field[4];};
2522
2523     _LIBCPP_ALWAYS_INLINE money_base() {}
2524 };
2525
2526 // moneypunct
2527
2528 template <class _CharT, bool _International = false>
2529 class _LIBCPP_TEMPLATE_VIS moneypunct
2530     : public locale::facet,
2531       public money_base
2532 {
2533 public:
2534     typedef _CharT                  char_type;
2535     typedef basic_string<char_type> string_type;
2536
2537     _LIBCPP_ALWAYS_INLINE
2538     explicit moneypunct(size_t __refs = 0)
2539         : locale::facet(__refs) {}
2540
2541     _LIBCPP_ALWAYS_INLINE char_type   decimal_point() const {return do_decimal_point();}
2542     _LIBCPP_ALWAYS_INLINE char_type   thousands_sep() const {return do_thousands_sep();}
2543     _LIBCPP_ALWAYS_INLINE string      grouping()      const {return do_grouping();}
2544     _LIBCPP_ALWAYS_INLINE string_type curr_symbol()   const {return do_curr_symbol();}
2545     _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
2546     _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
2547     _LIBCPP_ALWAYS_INLINE int         frac_digits()   const {return do_frac_digits();}
2548     _LIBCPP_ALWAYS_INLINE pattern     pos_format()    const {return do_pos_format();}
2549     _LIBCPP_ALWAYS_INLINE pattern     neg_format()    const {return do_neg_format();}
2550
2551     static locale::id id;
2552     static const bool intl = _International;
2553
2554 protected:
2555     _LIBCPP_ALWAYS_INLINE
2556     ~moneypunct() {}
2557
2558     virtual char_type   do_decimal_point() const {return numeric_limits<char_type>::max();}
2559     virtual char_type   do_thousands_sep() const {return numeric_limits<char_type>::max();}
2560     virtual string      do_grouping()      const {return string();}
2561     virtual string_type do_curr_symbol()   const {return string_type();}
2562     virtual string_type do_positive_sign() const {return string_type();}
2563     virtual string_type do_negative_sign() const {return string_type(1, '-');}
2564     virtual int         do_frac_digits()   const {return 0;}
2565     virtual pattern     do_pos_format()    const
2566         {pattern __p = {{symbol, sign, none, value}}; return __p;}
2567     virtual pattern     do_neg_format()    const
2568         {pattern __p = {{symbol, sign, none, value}}; return __p;}
2569 };
2570
2571 template <class _CharT, bool _International>
2572 locale::id
2573 moneypunct<_CharT, _International>::id;
2574
2575 template <class _CharT, bool _International>
2576 const bool
2577 moneypunct<_CharT, _International>::intl;
2578
2579 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>)
2580 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>)
2581 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>)
2582 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>)
2583
2584 // moneypunct_byname
2585
2586 template <class _CharT, bool _International = false>
2587 class _LIBCPP_TEMPLATE_VIS moneypunct_byname
2588     : public moneypunct<_CharT, _International>
2589 {
2590 public:
2591     typedef money_base::pattern  pattern;
2592     typedef _CharT                  char_type;
2593     typedef basic_string<char_type> string_type;
2594
2595     _LIBCPP_ALWAYS_INLINE
2596     explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
2597         : moneypunct<_CharT, _International>(__refs) {init(__nm);}
2598
2599     _LIBCPP_ALWAYS_INLINE
2600     explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
2601         : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
2602
2603 protected:
2604     _LIBCPP_ALWAYS_INLINE
2605     ~moneypunct_byname() {}
2606
2607     virtual char_type   do_decimal_point() const {return __decimal_point_;}
2608     virtual char_type   do_thousands_sep() const {return __thousands_sep_;}
2609     virtual string      do_grouping()      const {return __grouping_;}
2610     virtual string_type do_curr_symbol()   const {return __curr_symbol_;}
2611     virtual string_type do_positive_sign() const {return __positive_sign_;}
2612     virtual string_type do_negative_sign() const {return __negative_sign_;}
2613     virtual int         do_frac_digits()   const {return __frac_digits_;}
2614     virtual pattern     do_pos_format()    const {return __pos_format_;}
2615     virtual pattern     do_neg_format()    const {return __neg_format_;}
2616
2617 private:
2618     char_type   __decimal_point_;
2619     char_type   __thousands_sep_;
2620     string      __grouping_;
2621     string_type __curr_symbol_;
2622     string_type __positive_sign_;
2623     string_type __negative_sign_;
2624     int         __frac_digits_;
2625     pattern     __pos_format_;
2626     pattern     __neg_format_;
2627
2628     void init(const char*);
2629 };
2630
2631 template<> void moneypunct_byname<char, false>::init(const char*);
2632 template<> void moneypunct_byname<char, true>::init(const char*);
2633 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
2634 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
2635
2636 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>)
2637 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>)
2638 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>)
2639 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>)
2640
2641 // money_get
2642
2643 template <class _CharT>
2644 class __money_get
2645 {
2646 protected:
2647     typedef _CharT                  char_type;
2648     typedef basic_string<char_type> string_type;
2649
2650     _LIBCPP_ALWAYS_INLINE __money_get() {}
2651
2652     static void __gather_info(bool __intl, const locale& __loc,
2653                               money_base::pattern& __pat, char_type& __dp,
2654                               char_type& __ts, string& __grp,
2655                               string_type& __sym, string_type& __psn,
2656                               string_type& __nsn, int& __fd);
2657 };
2658
2659 template <class _CharT>
2660 void
2661 __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
2662                                    money_base::pattern& __pat, char_type& __dp,
2663                                    char_type& __ts, string& __grp,
2664                                    string_type& __sym, string_type& __psn,
2665                                    string_type& __nsn, int& __fd)
2666 {
2667     if (__intl)
2668     {
2669         const moneypunct<char_type, true>& __mp =
2670             use_facet<moneypunct<char_type, true> >(__loc);
2671         __pat = __mp.neg_format();
2672         __nsn = __mp.negative_sign();
2673         __psn = __mp.positive_sign();
2674         __dp = __mp.decimal_point();
2675         __ts = __mp.thousands_sep();
2676         __grp = __mp.grouping();
2677         __sym = __mp.curr_symbol();
2678         __fd = __mp.frac_digits();
2679     }
2680     else
2681     {
2682         const moneypunct<char_type, false>& __mp =
2683             use_facet<moneypunct<char_type, false> >(__loc);
2684         __pat = __mp.neg_format();
2685         __nsn = __mp.negative_sign();
2686         __psn = __mp.positive_sign();
2687         __dp = __mp.decimal_point();
2688         __ts = __mp.thousands_sep();
2689         __grp = __mp.grouping();
2690         __sym = __mp.curr_symbol();
2691         __fd = __mp.frac_digits();
2692     }
2693 }
2694
2695 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>)
2696 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>)
2697
2698 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
2699 class _LIBCPP_TEMPLATE_VIS money_get
2700     : public locale::facet,
2701       private __money_get<_CharT>
2702 {
2703 public:
2704     typedef _CharT                  char_type;
2705     typedef _InputIterator          iter_type;
2706     typedef basic_string<char_type> string_type;
2707
2708     _LIBCPP_ALWAYS_INLINE
2709     explicit money_get(size_t __refs = 0)
2710         : locale::facet(__refs) {}
2711
2712     _LIBCPP_ALWAYS_INLINE
2713     iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2714                   ios_base::iostate& __err, long double& __v) const
2715     {
2716         return do_get(__b, __e, __intl, __iob, __err, __v);
2717     }
2718
2719     _LIBCPP_ALWAYS_INLINE
2720     iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
2721                   ios_base::iostate& __err, string_type& __v) const
2722     {
2723         return do_get(__b, __e, __intl, __iob, __err, __v);
2724     }
2725
2726     static locale::id id;
2727
2728 protected:
2729
2730     _LIBCPP_ALWAYS_INLINE
2731     ~money_get() {}
2732
2733     virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2734                              ios_base& __iob, ios_base::iostate& __err,
2735                              long double& __v) const;
2736     virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
2737                              ios_base& __iob, ios_base::iostate& __err,
2738                              string_type& __v) const;
2739
2740 private:
2741     static bool __do_get(iter_type& __b, iter_type __e,
2742                          bool __intl, const locale& __loc,
2743                          ios_base::fmtflags __flags, ios_base::iostate& __err,
2744                          bool& __neg, const ctype<char_type>& __ct,
2745                          unique_ptr<char_type, void(*)(void*)>& __wb,
2746                          char_type*& __wn, char_type* __we);
2747 };
2748
2749 template <class _CharT, class _InputIterator>
2750 locale::id
2751 money_get<_CharT, _InputIterator>::id;
2752
2753 _LIBCPP_FUNC_VIS void __do_nothing(void*);
2754
2755 template <class _Tp>
2756 _LIBCPP_HIDDEN
2757 void
2758 __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
2759 {
2760     bool __owns = __b.get_deleter() != __do_nothing;
2761     size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
2762     size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
2763                        2 * __cur_cap : numeric_limits<size_t>::max();
2764     if (__new_cap == 0)
2765         __new_cap = sizeof(_Tp);
2766     size_t __n_off = static_cast<size_t>(__n - __b.get());
2767     _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
2768     if (__t == 0)
2769         __throw_bad_alloc();
2770     if (__owns)
2771         __b.release();
2772     __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
2773     __new_cap /= sizeof(_Tp);
2774     __n = __b.get() + __n_off;
2775     __e = __b.get() + __new_cap;
2776 }
2777
2778 // true == success
2779 template <class _CharT, class _InputIterator>
2780 bool
2781 money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
2782                                             bool __intl, const locale& __loc,
2783                                             ios_base::fmtflags __flags,
2784                                             ios_base::iostate& __err,
2785                                             bool& __neg,
2786                                             const ctype<char_type>& __ct,
2787                                             unique_ptr<char_type, void(*)(void*)>& __wb,
2788                                             char_type*& __wn, char_type* __we)
2789 {
2790     const unsigned __bz = 100;
2791     unsigned __gbuf[__bz];
2792     unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
2793     unsigned* __gn = __gb.get();
2794     unsigned* __ge = __gn + __bz;
2795     money_base::pattern __pat;
2796     char_type __dp;
2797     char_type __ts;
2798     string __grp;
2799     string_type __sym;
2800     string_type __psn;
2801     string_type __nsn;
2802     // Capture the spaces read into money_base::{space,none} so they
2803     // can be compared to initial spaces in __sym.
2804     string_type __spaces;
2805     int __fd;
2806     __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
2807                                        __sym, __psn, __nsn, __fd);
2808     const string_type* __trailing_sign = 0;
2809     __wn = __wb.get();
2810     for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
2811     {
2812         switch (__pat.field[__p])
2813         {
2814         case money_base::space:
2815             if (__p != 3)
2816             {
2817                 if (__ct.is(ctype_base::space, *__b))
2818                     __spaces.push_back(*__b++);
2819                 else
2820                 {
2821                     __err |= ios_base::failbit;
2822                     return false;
2823                 }
2824             }
2825             // drop through
2826         case money_base::none:
2827             if (__p != 3)
2828             {
2829                 while (__b != __e && __ct.is(ctype_base::space, *__b))
2830                     __spaces.push_back(*__b++);
2831             }
2832             break;
2833         case money_base::sign:
2834             if (__psn.size() + __nsn.size() > 0)
2835             {
2836                 if (__psn.size() == 0 || __nsn.size() == 0)
2837                 {   // sign is optional
2838                     if (__psn.size() > 0)
2839                     {   // __nsn.size() == 0
2840                         if (*__b == __psn[0])
2841                         {
2842                             ++__b;
2843                             if (__psn.size() > 1)
2844                                 __trailing_sign = &__psn;
2845                         }
2846                         else
2847                             __neg = true;
2848                     }
2849                     else if (*__b == __nsn[0])  // __nsn.size() > 0 &&  __psn.size() == 0
2850                     {
2851                         ++__b;
2852                         __neg = true;
2853                         if (__nsn.size() > 1)
2854                             __trailing_sign = &__nsn;
2855                     }
2856                 }
2857                 else  // sign is required
2858                 {
2859                     if (*__b == __psn[0])
2860                     {
2861                         ++__b;
2862                         if (__psn.size() > 1)
2863                             __trailing_sign = &__psn;
2864                     }
2865                     else if (*__b == __nsn[0])
2866                     {
2867                         ++__b;
2868                         __neg = true;
2869                         if (__nsn.size() > 1)
2870                             __trailing_sign = &__nsn;
2871                     }
2872                     else
2873                     {
2874                         __err |= ios_base::failbit;
2875                         return false;
2876                     }
2877                 }
2878             }
2879             break;
2880         case money_base::symbol:
2881             {
2882             bool __more_needed = __trailing_sign ||
2883                                  (__p < 2)       ||
2884                                  (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
2885             bool __sb = (__flags & ios_base::showbase) != 0;
2886             if (__sb || __more_needed)
2887             {
2888                 typename string_type::const_iterator __sym_space_end = __sym.begin();
2889                 if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
2890                                 __pat.field[__p - 1] == money_base::space)) {
2891                     // Match spaces we've already read against spaces at
2892                     // the beginning of __sym.
2893                     while (__sym_space_end != __sym.end() &&
2894                            __ct.is(ctype_base::space, *__sym_space_end))
2895                         ++__sym_space_end;
2896                     const size_t __num_spaces = __sym_space_end - __sym.begin();
2897                     if (__num_spaces > __spaces.size() ||
2898                         !equal(__spaces.end() - __num_spaces, __spaces.end(),
2899                                __sym.begin())) {
2900                         // No match. Put __sym_space_end back at the
2901                         // beginning of __sym, which will prevent a
2902                         // match in the next loop.
2903                         __sym_space_end = __sym.begin();
2904                     }
2905                 }
2906                 typename string_type::const_iterator __sym_curr_char = __sym_space_end;
2907                 while (__sym_curr_char != __sym.end() && __b != __e &&
2908                        *__b == *__sym_curr_char) {
2909                     ++__b;
2910                     ++__sym_curr_char;
2911                 }
2912                 if (__sb && __sym_curr_char != __sym.end())
2913                 {
2914                     __err |= ios_base::failbit;
2915                     return false;
2916                 }
2917             }
2918             }
2919             break;
2920         case money_base::value:
2921             {
2922             unsigned __ng = 0;
2923             for (; __b != __e; ++__b)
2924             {
2925                 char_type __c = *__b;
2926                 if (__ct.is(ctype_base::digit, __c))
2927                 {
2928                     if (__wn == __we)
2929                         __double_or_nothing(__wb, __wn, __we);
2930                     *__wn++ = __c;
2931                     ++__ng;
2932                 }
2933                 else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
2934                 {
2935                     if (__gn == __ge)
2936                         __double_or_nothing(__gb, __gn, __ge);
2937                     *__gn++ = __ng;
2938                     __ng = 0;
2939                 }
2940                 else
2941                     break;
2942             }
2943             if (__gb.get() != __gn && __ng > 0)
2944             {
2945                 if (__gn == __ge)
2946                     __double_or_nothing(__gb, __gn, __ge);
2947                 *__gn++ = __ng;
2948             }
2949             if (__fd > 0)
2950             {
2951                 if (__b == __e || *__b != __dp)
2952                 {
2953                     __err |= ios_base::failbit;
2954                     return false;
2955                 }
2956                 for (++__b; __fd > 0; --__fd, ++__b)
2957                 {
2958                     if (__b == __e || !__ct.is(ctype_base::digit, *__b))
2959                     {
2960                         __err |= ios_base::failbit;
2961                         return false;
2962                     }
2963                     if (__wn == __we)
2964                         __double_or_nothing(__wb, __wn, __we);
2965                     *__wn++ = *__b;
2966                 }
2967             }
2968             if (__wn == __wb.get())
2969             {
2970                 __err |= ios_base::failbit;
2971                 return false;
2972             }
2973             }
2974             break;
2975         }
2976     }
2977     if (__trailing_sign)
2978     {
2979         for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
2980         {
2981             if (__b == __e || *__b != (*__trailing_sign)[__i])
2982             {
2983                 __err |= ios_base::failbit;
2984                 return false;
2985             }
2986         }
2987     }
2988     if (__gb.get() != __gn)
2989     {
2990         ios_base::iostate __et = ios_base::goodbit;
2991         __check_grouping(__grp, __gb.get(), __gn, __et);
2992         if (__et)
2993         {
2994             __err |= ios_base::failbit;
2995             return false;
2996         }
2997     }
2998     return true;
2999 }
3000
3001 template <class _CharT, class _InputIterator>
3002 _InputIterator
3003 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3004                                           bool __intl, ios_base& __iob,
3005                                           ios_base::iostate& __err,
3006                                           long double& __v) const
3007 {
3008     const int __bz = 100;
3009     char_type __wbuf[__bz];
3010     unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3011     char_type* __wn;
3012     char_type* __we = __wbuf + __bz;
3013     locale __loc = __iob.getloc();
3014     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3015     bool __neg = false;
3016     if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3017                  __wb, __wn, __we))
3018     {
3019         const char __src[] = "0123456789";
3020         char_type __atoms[sizeof(__src)-1];
3021         __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
3022         char __nbuf[__bz];
3023         char* __nc = __nbuf;
3024         unique_ptr<char, void(*)(void*)> __h(0, free);
3025         if (__wn - __wb.get() > __bz-2)
3026         {
3027             __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
3028             if (__h.get() == 0)
3029                 __throw_bad_alloc();
3030             __nc = __h.get();
3031         }
3032         if (__neg)
3033             *__nc++ = '-';
3034         for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
3035             *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
3036         *__nc = char();
3037         if (sscanf(__nbuf, "%Lf", &__v) != 1)
3038             __throw_runtime_error("money_get error");
3039     }
3040     if (__b == __e)
3041         __err |= ios_base::eofbit;
3042     return __b;
3043 }
3044
3045 template <class _CharT, class _InputIterator>
3046 _InputIterator
3047 money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
3048                                           bool __intl, ios_base& __iob,
3049                                           ios_base::iostate& __err,
3050                                           string_type& __v) const
3051 {
3052     const int __bz = 100;
3053     char_type __wbuf[__bz];
3054     unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
3055     char_type* __wn;
3056     char_type* __we = __wbuf + __bz;
3057     locale __loc = __iob.getloc();
3058     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3059     bool __neg = false;
3060     if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
3061                  __wb, __wn, __we))
3062     {
3063         __v.clear();
3064         if (__neg)
3065             __v.push_back(__ct.widen('-'));
3066         char_type __z = __ct.widen('0');
3067         char_type* __w;
3068         for (__w = __wb.get(); __w < __wn-1; ++__w)
3069             if (*__w != __z)
3070                 break;
3071         __v.append(__w, __wn);
3072     }
3073     if (__b == __e)
3074         __err |= ios_base::eofbit;
3075     return __b;
3076 }
3077
3078 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>)
3079 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>)
3080
3081 // money_put
3082
3083 template <class _CharT>
3084 class __money_put
3085 {
3086 protected:
3087     typedef _CharT                  char_type;
3088     typedef basic_string<char_type> string_type;
3089
3090     _LIBCPP_ALWAYS_INLINE __money_put() {}
3091
3092     static void __gather_info(bool __intl, bool __neg, const locale& __loc,
3093                               money_base::pattern& __pat, char_type& __dp,
3094                               char_type& __ts, string& __grp,
3095                               string_type& __sym, string_type& __sn,
3096                               int& __fd);
3097     static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
3098                          ios_base::fmtflags __flags,
3099                          const char_type* __db, const char_type* __de,
3100                          const ctype<char_type>& __ct, bool __neg,
3101                          const money_base::pattern& __pat, char_type __dp,
3102                          char_type __ts, const string& __grp,
3103                          const string_type& __sym, const string_type& __sn,
3104                          int __fd);
3105 };
3106
3107 template <class _CharT>
3108 void
3109 __money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
3110                                    money_base::pattern& __pat, char_type& __dp,
3111                                    char_type& __ts, string& __grp,
3112                                    string_type& __sym, string_type& __sn,
3113                                    int& __fd)
3114 {
3115     if (__intl)
3116     {
3117         const moneypunct<char_type, true>& __mp =
3118             use_facet<moneypunct<char_type, true> >(__loc);
3119         if (__neg)
3120         {
3121             __pat = __mp.neg_format();
3122             __sn = __mp.negative_sign();
3123         }
3124         else
3125         {
3126             __pat = __mp.pos_format();
3127             __sn = __mp.positive_sign();
3128         }
3129         __dp = __mp.decimal_point();
3130         __ts = __mp.thousands_sep();
3131         __grp = __mp.grouping();
3132         __sym = __mp.curr_symbol();
3133         __fd = __mp.frac_digits();
3134     }
3135     else
3136     {
3137         const moneypunct<char_type, false>& __mp =
3138             use_facet<moneypunct<char_type, false> >(__loc);
3139         if (__neg)
3140         {
3141             __pat = __mp.neg_format();
3142             __sn = __mp.negative_sign();
3143         }
3144         else
3145         {
3146             __pat = __mp.pos_format();
3147             __sn = __mp.positive_sign();
3148         }
3149         __dp = __mp.decimal_point();
3150         __ts = __mp.thousands_sep();
3151         __grp = __mp.grouping();
3152         __sym = __mp.curr_symbol();
3153         __fd = __mp.frac_digits();
3154     }
3155 }
3156
3157 template <class _CharT>
3158 void
3159 __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
3160                               ios_base::fmtflags __flags,
3161                               const char_type* __db, const char_type* __de,
3162                               const ctype<char_type>& __ct, bool __neg,
3163                               const money_base::pattern& __pat, char_type __dp,
3164                               char_type __ts, const string& __grp,
3165                               const string_type& __sym, const string_type& __sn,
3166                               int __fd)
3167 {
3168     __me = __mb;
3169     for (unsigned __p = 0; __p < 4; ++__p)
3170     {
3171         switch (__pat.field[__p])
3172         {
3173         case money_base::none:
3174             __mi = __me;
3175             break;
3176         case money_base::space:
3177             __mi = __me;
3178             *__me++ = __ct.widen(' ');
3179             break;
3180         case money_base::sign:
3181             if (!__sn.empty())
3182                 *__me++ = __sn[0];
3183             break;
3184         case money_base::symbol:
3185             if (!__sym.empty() && (__flags & ios_base::showbase))
3186                 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
3187             break;
3188         case money_base::value:
3189             {
3190             // remember start of value so we can reverse it
3191             char_type* __t = __me;
3192             // find beginning of digits
3193             if (__neg)
3194                 ++__db;
3195             // find end of digits
3196             const char_type* __d;
3197             for (__d = __db; __d < __de; ++__d)
3198                 if (!__ct.is(ctype_base::digit, *__d))
3199                     break;
3200             // print fractional part
3201             if (__fd > 0)
3202             {
3203                 int __f;
3204                 for (__f = __fd; __d > __db && __f > 0; --__f)
3205                     *__me++ = *--__d;
3206                 char_type __z = __f > 0 ? __ct.widen('0') : char_type();
3207                 for (; __f > 0; --__f)
3208                     *__me++ = __z;
3209                 *__me++ = __dp;
3210             }
3211             // print units part
3212             if (__d == __db)
3213             {
3214                 *__me++ = __ct.widen('0');
3215             }
3216             else
3217             {
3218                 unsigned __ng = 0;
3219                 unsigned __ig = 0;
3220                 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
3221                                               : static_cast<unsigned>(__grp[__ig]);
3222                 while (__d != __db)
3223                 {
3224                     if (__ng == __gl)
3225                     {
3226                         *__me++ = __ts;
3227                         __ng = 0;
3228                         if (++__ig < __grp.size())
3229                             __gl = __grp[__ig] == numeric_limits<char>::max() ?
3230                                         numeric_limits<unsigned>::max() :
3231                                         static_cast<unsigned>(__grp[__ig]);
3232                     }
3233                     *__me++ = *--__d;
3234                     ++__ng;
3235                 }
3236             }
3237             // reverse it
3238             reverse(__t, __me);
3239             }
3240             break;
3241         }
3242     }
3243     // print rest of sign, if any
3244     if (__sn.size() > 1)
3245         __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
3246     // set alignment
3247     if ((__flags & ios_base::adjustfield) == ios_base::left)
3248         __mi = __me;
3249     else if ((__flags & ios_base::adjustfield) != ios_base::internal)
3250         __mi = __mb;
3251 }
3252
3253 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>)
3254 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>)
3255
3256 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
3257 class _LIBCPP_TEMPLATE_VIS money_put
3258     : public locale::facet,
3259       private __money_put<_CharT>
3260 {
3261 public:
3262     typedef _CharT                  char_type;
3263     typedef _OutputIterator         iter_type;
3264     typedef basic_string<char_type> string_type;
3265
3266     _LIBCPP_ALWAYS_INLINE
3267     explicit money_put(size_t __refs = 0)
3268         : locale::facet(__refs) {}
3269
3270     _LIBCPP_ALWAYS_INLINE
3271     iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3272                   long double __units) const
3273     {
3274         return do_put(__s, __intl, __iob, __fl, __units);
3275     }
3276
3277     _LIBCPP_ALWAYS_INLINE
3278     iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
3279                   const string_type& __digits) const
3280     {
3281         return do_put(__s, __intl, __iob, __fl, __digits);
3282     }
3283
3284     static locale::id id;
3285
3286 protected:
3287     _LIBCPP_ALWAYS_INLINE
3288     ~money_put() {}
3289
3290     virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3291                              char_type __fl, long double __units) const;
3292     virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
3293                              char_type __fl, const string_type& __digits) const;
3294 };
3295
3296 template <class _CharT, class _OutputIterator>
3297 locale::id
3298 money_put<_CharT, _OutputIterator>::id;
3299
3300 template <class _CharT, class _OutputIterator>
3301 _OutputIterator
3302 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3303                                            ios_base& __iob, char_type __fl,
3304                                            long double __units) const
3305 {
3306     // convert to char
3307     const size_t __bs = 100;
3308     char __buf[__bs];
3309     char* __bb = __buf;
3310     char_type __digits[__bs];
3311     char_type* __db = __digits;
3312     size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
3313     unique_ptr<char, void(*)(void*)> __hn(0, free);
3314     unique_ptr<char_type, void(*)(void*)> __hd(0, free);
3315     // secure memory for digit storage
3316     if (__n > __bs-1)
3317     {
3318         __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
3319         if (__bb == 0)
3320             __throw_bad_alloc();
3321         __hn.reset(__bb);
3322         __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
3323         if (__hd == nullptr)
3324             __throw_bad_alloc();
3325         __db = __hd.get();
3326     }
3327     // gather info
3328     locale __loc = __iob.getloc();
3329     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3330     __ct.widen(__bb, __bb + __n, __db);
3331     bool __neg = __n > 0 && __bb[0] == '-';
3332     money_base::pattern __pat;
3333     char_type __dp;
3334     char_type __ts;
3335     string __grp;
3336     string_type __sym;
3337     string_type __sn;
3338     int __fd;
3339     this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3340     // secure memory for formatting
3341     char_type __mbuf[__bs];
3342     char_type* __mb = __mbuf;
3343     unique_ptr<char_type, void(*)(void*)> __hw(0, free);
3344     size_t __exn = static_cast<int>(__n) > __fd ?
3345                    (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
3346                     __sym.size() + static_cast<size_t>(__fd) + 1
3347                  : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3348     if (__exn > __bs)
3349     {
3350         __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
3351         __mb = __hw.get();
3352         if (__mb == 0)
3353             __throw_bad_alloc();
3354     }
3355     // format
3356     char_type* __mi;
3357     char_type* __me;
3358     this->__format(__mb, __mi, __me, __iob.flags(),
3359                    __db, __db + __n, __ct,
3360                    __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3361     return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3362 }
3363
3364 template <class _CharT, class _OutputIterator>
3365 _OutputIterator
3366 money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
3367                                            ios_base& __iob, char_type __fl,
3368                                            const string_type& __digits) const
3369 {
3370     // gather info
3371     locale __loc = __iob.getloc();
3372     const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
3373     bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
3374     money_base::pattern __pat;
3375     char_type __dp;
3376     char_type __ts;
3377     string __grp;
3378     string_type __sym;
3379     string_type __sn;
3380     int __fd;
3381     this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3382     // secure memory for formatting
3383     char_type __mbuf[100];
3384     char_type* __mb = __mbuf;
3385     unique_ptr<char_type, void(*)(void*)> __h(0, free);
3386     size_t __exn = static_cast<int>(__digits.size()) > __fd ?
3387                    (__digits.size() - static_cast<size_t>(__fd)) * 2 +
3388                     __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
3389                  : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
3390     if (__exn > 100)
3391     {
3392         __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
3393         __mb = __h.get();
3394         if (__mb == 0)
3395             __throw_bad_alloc();
3396     }
3397     // format
3398     char_type* __mi;
3399     char_type* __me;
3400     this->__format(__mb, __mi, __me, __iob.flags(),
3401                    __digits.data(), __digits.data() + __digits.size(), __ct,
3402                    __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
3403     return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
3404 }
3405
3406 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>)
3407 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>)
3408
3409 // messages
3410
3411 class _LIBCPP_TYPE_VIS messages_base
3412 {
3413 public:
3414     typedef ptrdiff_t catalog;
3415
3416     _LIBCPP_ALWAYS_INLINE messages_base() {}
3417 };
3418
3419 template <class _CharT>
3420 class _LIBCPP_TEMPLATE_VIS messages
3421     : public locale::facet,
3422       public messages_base
3423 {
3424 public:
3425     typedef _CharT               char_type;
3426     typedef basic_string<_CharT> string_type;
3427
3428     _LIBCPP_ALWAYS_INLINE
3429     explicit messages(size_t __refs = 0)
3430         : locale::facet(__refs) {}
3431
3432     _LIBCPP_ALWAYS_INLINE
3433     catalog open(const basic_string<char>& __nm, const locale& __loc) const
3434     {
3435         return do_open(__nm, __loc);
3436     }
3437
3438     _LIBCPP_ALWAYS_INLINE
3439     string_type get(catalog __c, int __set, int __msgid,
3440                     const string_type& __dflt) const
3441     {
3442         return do_get(__c, __set, __msgid, __dflt);
3443     }
3444
3445     _LIBCPP_ALWAYS_INLINE
3446     void close(catalog __c) const
3447     {
3448         do_close(__c);
3449     }
3450
3451     static locale::id id;
3452
3453 protected:
3454     _LIBCPP_ALWAYS_INLINE
3455     ~messages() {}
3456
3457     virtual catalog do_open(const basic_string<char>&, const locale&) const;
3458     virtual string_type do_get(catalog, int __set, int __msgid,
3459                                const string_type& __dflt) const;
3460     virtual void do_close(catalog) const;
3461 };
3462
3463 template <class _CharT>
3464 locale::id
3465 messages<_CharT>::id;
3466
3467 template <class _CharT>
3468 typename messages<_CharT>::catalog
3469 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
3470 {
3471 #ifdef _LIBCPP_HAS_CATOPEN
3472     catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
3473     if (__cat != -1)
3474         __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
3475     return __cat;
3476 #else // !_LIBCPP_HAS_CATOPEN
3477     return -1;
3478 #endif // _LIBCPP_HAS_CATOPEN
3479 }
3480
3481 template <class _CharT>
3482 typename messages<_CharT>::string_type
3483 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
3484                          const string_type& __dflt) const
3485 {
3486 #ifdef _LIBCPP_HAS_CATOPEN
3487     string __ndflt;
3488     __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
3489                                                        __dflt.c_str(),
3490                                                        __dflt.c_str() + __dflt.size());
3491     if (__c != -1)
3492         __c <<= 1;
3493     nl_catd __cat = (nl_catd)__c;
3494     char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
3495     string_type __w;
3496     __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
3497                                                         __n, __n + strlen(__n));
3498     return __w;
3499 #else // !_LIBCPP_HAS_CATOPEN
3500     return __dflt;
3501 #endif // _LIBCPP_HAS_CATOPEN
3502 }
3503
3504 template <class _CharT>
3505 void
3506 messages<_CharT>::do_close(catalog __c) const
3507 {
3508 #ifdef _LIBCPP_HAS_CATOPEN
3509     if (__c != -1)
3510         __c <<= 1;
3511     nl_catd __cat = (nl_catd)__c;
3512     catclose(__cat);
3513 #endif // _LIBCPP_HAS_CATOPEN
3514 }
3515
3516 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>)
3517 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>)
3518
3519 template <class _CharT>
3520 class _LIBCPP_TEMPLATE_VIS messages_byname
3521     : public messages<_CharT>
3522 {
3523 public:
3524     typedef messages_base::catalog catalog;
3525     typedef basic_string<_CharT> string_type;
3526
3527     _LIBCPP_ALWAYS_INLINE
3528     explicit messages_byname(const char*, size_t __refs = 0)
3529         : messages<_CharT>(__refs) {}
3530
3531     _LIBCPP_ALWAYS_INLINE
3532     explicit messages_byname(const string&, size_t __refs = 0)
3533         : messages<_CharT>(__refs) {}
3534
3535 protected:
3536     _LIBCPP_ALWAYS_INLINE
3537     ~messages_byname() {}
3538 };
3539
3540 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>)
3541 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>)
3542
3543 template<class _Codecvt, class _Elem = wchar_t,
3544          class _Wide_alloc = allocator<_Elem>,
3545          class _Byte_alloc = allocator<char> >
3546 class _LIBCPP_TEMPLATE_VIS wstring_convert
3547 {
3548 public:
3549     typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;
3550     typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
3551     typedef typename _Codecvt::state_type                        state_type;
3552     typedef typename wide_string::traits_type::int_type          int_type;
3553
3554 private:
3555     byte_string __byte_err_string_;
3556     wide_string __wide_err_string_;
3557     _Codecvt* __cvtptr_;
3558     state_type __cvtstate_;
3559     size_t __cvtcount_;
3560
3561     wstring_convert(const wstring_convert& __wc);
3562     wstring_convert& operator=(const wstring_convert& __wc);
3563 public:
3564     _LIBCPP_ALWAYS_INLINE
3565     _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
3566     _LIBCPP_ALWAYS_INLINE
3567     wstring_convert(_Codecvt* __pcvt, state_type __state);
3568     _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
3569                     const wide_string& __wide_err = wide_string());
3570 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3571     _LIBCPP_ALWAYS_INLINE
3572     wstring_convert(wstring_convert&& __wc);
3573 #endif
3574     ~wstring_convert();
3575
3576     _LIBCPP_ALWAYS_INLINE
3577     wide_string from_bytes(char __byte)
3578         {return from_bytes(&__byte, &__byte+1);}
3579     _LIBCPP_ALWAYS_INLINE
3580     wide_string from_bytes(const char* __ptr)
3581         {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
3582     _LIBCPP_ALWAYS_INLINE
3583     wide_string from_bytes(const byte_string& __str)
3584         {return from_bytes(__str.data(), __str.data() + __str.size());}
3585     wide_string from_bytes(const char* __first, const char* __last);
3586
3587     _LIBCPP_ALWAYS_INLINE
3588     byte_string to_bytes(_Elem __wchar)
3589         {return to_bytes(&__wchar, &__wchar+1);}
3590     _LIBCPP_ALWAYS_INLINE
3591     byte_string to_bytes(const _Elem* __wptr)
3592         {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
3593     _LIBCPP_ALWAYS_INLINE
3594     byte_string to_bytes(const wide_string& __wstr)
3595         {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
3596     byte_string to_bytes(const _Elem* __first, const _Elem* __last);
3597
3598     _LIBCPP_ALWAYS_INLINE
3599     size_t converted() const _NOEXCEPT {return __cvtcount_;}
3600     _LIBCPP_ALWAYS_INLINE
3601     state_type state() const {return __cvtstate_;}
3602 };
3603
3604 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3605 inline
3606 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3607     wstring_convert(_Codecvt* __pcvt)
3608         : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
3609 {
3610 }
3611
3612 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3613 inline
3614 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3615     wstring_convert(_Codecvt* __pcvt, state_type __state)
3616         : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
3617 {
3618 }
3619
3620 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3621 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3622     wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
3623         : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
3624           __cvtstate_(), __cvtcount_(0)
3625 {
3626     __cvtptr_ = new _Codecvt;
3627 }
3628
3629 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3630
3631 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3632 inline
3633 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3634     wstring_convert(wstring_convert&& __wc)
3635         : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
3636           __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
3637           __cvtptr_(__wc.__cvtptr_),
3638           __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_)
3639 {
3640     __wc.__cvtptr_ = nullptr;
3641 }
3642
3643 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3644
3645 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3646 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
3647 {
3648     delete __cvtptr_;
3649 }
3650
3651 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3652 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
3653 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3654     from_bytes(const char* __frm, const char* __frm_end)
3655 {
3656     __cvtcount_ = 0;
3657     if (__cvtptr_ != nullptr)
3658     {
3659         wide_string __ws(2*(__frm_end - __frm), _Elem());
3660         if (__frm != __frm_end)
3661             __ws.resize(__ws.capacity());
3662         codecvt_base::result __r = codecvt_base::ok;
3663         state_type __st = __cvtstate_;
3664         if (__frm != __frm_end)
3665         {
3666             _Elem* __to = &__ws[0];
3667             _Elem* __to_end = __to + __ws.size();
3668             const char* __frm_nxt;
3669             do
3670             {
3671                 _Elem* __to_nxt;
3672                 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
3673                                           __to, __to_end, __to_nxt);
3674                 __cvtcount_ += __frm_nxt - __frm;
3675                 if (__frm_nxt == __frm)
3676                 {
3677                     __r = codecvt_base::error;
3678                 }
3679                 else if (__r == codecvt_base::noconv)
3680                 {
3681                     __ws.resize(__to - &__ws[0]);
3682                     // This only gets executed if _Elem is char
3683                     __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
3684                     __frm = __frm_nxt;
3685                     __r = codecvt_base::ok;
3686                 }
3687                 else if (__r == codecvt_base::ok)
3688                 {
3689                     __ws.resize(__to_nxt - &__ws[0]);
3690                     __frm = __frm_nxt;
3691                 }
3692                 else if (__r == codecvt_base::partial)
3693                 {
3694                     ptrdiff_t __s = __to_nxt - &__ws[0];
3695                     __ws.resize(2 * __s);
3696                     __to = &__ws[0] + __s;
3697                     __to_end = &__ws[0] + __ws.size();
3698                     __frm = __frm_nxt;
3699                 }
3700             } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3701         }
3702         if (__r == codecvt_base::ok)
3703             return __ws;
3704     }
3705
3706     if (__wide_err_string_.empty())
3707         __throw_range_error("wstring_convert: from_bytes error");
3708
3709     return __wide_err_string_;
3710 }
3711
3712 template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
3713 typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
3714 wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
3715     to_bytes(const _Elem* __frm, const _Elem* __frm_end)
3716 {
3717     __cvtcount_ = 0;
3718     if (__cvtptr_ != nullptr)
3719     {
3720         byte_string __bs(2*(__frm_end - __frm), char());
3721         if (__frm != __frm_end)
3722             __bs.resize(__bs.capacity());
3723         codecvt_base::result __r = codecvt_base::ok;
3724         state_type __st = __cvtstate_;
3725         if (__frm != __frm_end)
3726         {
3727             char* __to = &__bs[0];
3728             char* __to_end = __to + __bs.size();
3729             const _Elem* __frm_nxt;
3730             do
3731             {
3732                 char* __to_nxt;
3733                 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
3734                                            __to, __to_end, __to_nxt);
3735                 __cvtcount_ += __frm_nxt - __frm;
3736                 if (__frm_nxt == __frm)
3737                 {
3738                     __r = codecvt_base::error;
3739                 }
3740                 else if (__r == codecvt_base::noconv)
3741                 {
3742                     __bs.resize(__to - &__bs[0]);
3743                     // This only gets executed if _Elem is char
3744                     __bs.append((const char*)__frm, (const char*)__frm_end);
3745                     __frm = __frm_nxt;
3746                     __r = codecvt_base::ok;
3747                 }
3748                 else if (__r == codecvt_base::ok)
3749                 {
3750                     __bs.resize(__to_nxt - &__bs[0]);
3751                     __frm = __frm_nxt;
3752                 }
3753                 else if (__r == codecvt_base::partial)
3754                 {
3755                     ptrdiff_t __s = __to_nxt - &__bs[0];
3756                     __bs.resize(2 * __s);
3757                     __to = &__bs[0] + __s;
3758                     __to_end = &__bs[0] + __bs.size();
3759                     __frm = __frm_nxt;
3760                 }
3761             } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
3762         }
3763         if (__r == codecvt_base::ok)
3764         {
3765             size_t __s = __bs.size();
3766             __bs.resize(__bs.capacity());
3767             char* __to = &__bs[0] + __s;
3768             char* __to_end = __to + __bs.size();
3769             do
3770             {
3771                 char* __to_nxt;
3772                 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
3773                 if (__r == codecvt_base::noconv)
3774                 {
3775                     __bs.resize(__to - &__bs[0]);
3776                     __r = codecvt_base::ok;
3777                 }
3778                 else if (__r == codecvt_base::ok)
3779                 {
3780                     __bs.resize(__to_nxt - &__bs[0]);
3781                 }
3782                 else if (__r == codecvt_base::partial)
3783                 {
3784                     ptrdiff_t __sp = __to_nxt - &__bs[0];
3785                     __bs.resize(2 * __sp);
3786                     __to = &__bs[0] + __sp;
3787                     __to_end = &__bs[0] + __bs.size();
3788                 }
3789             } while (__r == codecvt_base::partial);
3790             if (__r == codecvt_base::ok)
3791                 return __bs;
3792         }
3793     }
3794
3795     if (__byte_err_string_.empty())
3796         __throw_range_error("wstring_convert: to_bytes error");
3797
3798     return __byte_err_string_;
3799 }
3800
3801 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
3802 class _LIBCPP_TEMPLATE_VIS wbuffer_convert
3803     : public basic_streambuf<_Elem, _Tr>
3804 {
3805 public:
3806     // types:
3807     typedef _Elem                          char_type;
3808     typedef _Tr                            traits_type;
3809     typedef typename traits_type::int_type int_type;
3810     typedef typename traits_type::pos_type pos_type;
3811     typedef typename traits_type::off_type off_type;
3812     typedef typename _Codecvt::state_type  state_type;
3813
3814 private:
3815     char*       __extbuf_;
3816     const char* __extbufnext_;
3817     const char* __extbufend_;
3818     char __extbuf_min_[8];
3819     size_t __ebs_;
3820     char_type* __intbuf_;
3821     size_t __ibs_;
3822     streambuf* __bufptr_;
3823     _Codecvt* __cv_;
3824     state_type __st_;
3825     ios_base::openmode __cm_;
3826     bool __owns_eb_;
3827     bool __owns_ib_;
3828     bool __always_noconv_;
3829
3830     wbuffer_convert(const wbuffer_convert&);
3831     wbuffer_convert& operator=(const wbuffer_convert&);
3832 public:
3833     _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, 
3834             _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
3835     ~wbuffer_convert();
3836
3837     _LIBCPP_INLINE_VISIBILITY
3838     streambuf* rdbuf() const {return __bufptr_;}
3839     _LIBCPP_INLINE_VISIBILITY
3840     streambuf* rdbuf(streambuf* __bytebuf)
3841     {
3842         streambuf* __r = __bufptr_;
3843         __bufptr_ = __bytebuf;
3844         return __r;
3845     }
3846
3847     _LIBCPP_INLINE_VISIBILITY
3848     state_type state() const {return __st_;}
3849
3850 protected:
3851     virtual int_type underflow();
3852     virtual int_type pbackfail(int_type __c = traits_type::eof());
3853     virtual int_type overflow (int_type __c = traits_type::eof());
3854     virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
3855                                                             streamsize __n);
3856     virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
3857                              ios_base::openmode __wch = ios_base::in | ios_base::out);
3858     virtual pos_type seekpos(pos_type __sp,
3859                              ios_base::openmode __wch = ios_base::in | ios_base::out);
3860     virtual int sync();
3861
3862 private:
3863     bool __read_mode();
3864     void __write_mode();
3865     wbuffer_convert* __close();
3866 };
3867
3868 template <class _Codecvt, class _Elem, class _Tr>
3869 wbuffer_convert<_Codecvt, _Elem, _Tr>::
3870     wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
3871     : __extbuf_(0),
3872       __extbufnext_(0),
3873       __extbufend_(0),
3874       __ebs_(0),
3875       __intbuf_(0),
3876       __ibs_(0),
3877       __bufptr_(__bytebuf),
3878       __cv_(__pcvt),
3879       __st_(__state),
3880       __cm_(0),
3881       __owns_eb_(false),
3882       __owns_ib_(false),
3883       __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
3884 {
3885     setbuf(0, 4096);
3886 }
3887
3888 template <class _Codecvt, class _Elem, class _Tr>
3889 wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
3890 {
3891     __close();
3892     delete __cv_;
3893     if (__owns_eb_)
3894         delete [] __extbuf_;
3895     if (__owns_ib_)
3896         delete [] __intbuf_;
3897 }
3898
3899 template <class _Codecvt, class _Elem, class _Tr>
3900 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3901 wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
3902 {
3903     if (__cv_ == 0 || __bufptr_ == 0)
3904         return traits_type::eof();
3905     bool __initial = __read_mode();
3906     char_type __1buf;
3907     if (this->gptr() == 0)
3908         this->setg(&__1buf, &__1buf+1, &__1buf+1);
3909     const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
3910     int_type __c = traits_type::eof();
3911     if (this->gptr() == this->egptr())
3912     {
3913         memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
3914         if (__always_noconv_)
3915         {
3916             streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
3917             __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
3918             if (__nmemb != 0)
3919             {
3920                 this->setg(this->eback(),
3921                            this->eback() + __unget_sz,
3922                            this->eback() + __unget_sz + __nmemb);
3923                 __c = *this->gptr();
3924             }
3925         }
3926         else
3927         {
3928              _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
3929              if (__extbufend_ != __extbufnext_)
3930                 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
3931             __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
3932             __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
3933             streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
3934                                  static_cast<streamsize>(__extbufend_ - __extbufnext_));
3935             codecvt_base::result __r;
3936             // FIXME: Do we ever need to restore the state here?
3937             //state_type __svs = __st_;
3938             streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
3939             if (__nr != 0)
3940             {
3941                 __extbufend_ = __extbufnext_ + __nr;
3942                 char_type*  __inext;
3943                 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
3944                                        this->eback() + __unget_sz,
3945                                        this->egptr(), __inext);
3946                 if (__r == codecvt_base::noconv)
3947                 {
3948                     this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
3949                     __c = *this->gptr();
3950                 }
3951                 else if (__inext != this->eback() + __unget_sz)
3952                 {
3953                     this->setg(this->eback(), this->eback() + __unget_sz, __inext);
3954                     __c = *this->gptr();
3955                 }
3956             }
3957         }
3958     }
3959     else
3960         __c = *this->gptr();
3961     if (this->eback() == &__1buf)
3962         this->setg(0, 0, 0);
3963     return __c;
3964 }
3965
3966 template <class _Codecvt, class _Elem, class _Tr>
3967 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3968 wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
3969 {
3970     if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
3971     {
3972         if (traits_type::eq_int_type(__c, traits_type::eof()))
3973         {
3974             this->gbump(-1);
3975             return traits_type::not_eof(__c);
3976         }
3977         if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
3978         {
3979             this->gbump(-1);
3980             *this->gptr() = traits_type::to_char_type(__c);
3981             return __c;
3982         }
3983     }
3984     return traits_type::eof();
3985 }
3986
3987 template <class _Codecvt, class _Elem, class _Tr>
3988 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
3989 wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
3990 {
3991     if (__cv_ == 0 || __bufptr_ == 0)
3992         return traits_type::eof();
3993     __write_mode();
3994     char_type __1buf;
3995     char_type* __pb_save = this->pbase();
3996     char_type* __epb_save = this->epptr();
3997     if (!traits_type::eq_int_type(__c, traits_type::eof()))
3998     {
3999         if (this->pptr() == 0)
4000             this->setp(&__1buf, &__1buf+1);
4001         *this->pptr() = traits_type::to_char_type(__c);
4002         this->pbump(1);
4003     }
4004     if (this->pptr() != this->pbase())
4005     {
4006         if (__always_noconv_)
4007         {
4008             streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
4009             if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4010                 return traits_type::eof();
4011         }
4012         else
4013         {
4014             char* __extbe = __extbuf_;
4015             codecvt_base::result __r;
4016             do
4017             {
4018                 const char_type* __e;
4019                 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
4020                                         __extbuf_, __extbuf_ + __ebs_, __extbe);
4021                 if (__e == this->pbase())
4022                     return traits_type::eof();
4023                 if (__r == codecvt_base::noconv)
4024                 {
4025                     streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
4026                     if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
4027                         return traits_type::eof();
4028                 }
4029                 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
4030                 {
4031                     streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
4032                     if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4033                         return traits_type::eof();
4034                     if (__r == codecvt_base::partial)
4035                     {
4036                         this->setp((char_type*)__e, this->pptr());
4037                         this->pbump(this->epptr() - this->pbase());
4038                     }
4039                 }
4040                 else
4041                     return traits_type::eof();
4042             } while (__r == codecvt_base::partial);
4043         }
4044         this->setp(__pb_save, __epb_save);
4045     }
4046     return traits_type::not_eof(__c);
4047 }
4048
4049 template <class _Codecvt, class _Elem, class _Tr>
4050 basic_streambuf<_Elem, _Tr>*
4051 wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
4052 {
4053     this->setg(0, 0, 0);
4054     this->setp(0, 0);
4055     if (__owns_eb_)
4056         delete [] __extbuf_;
4057     if (__owns_ib_)
4058         delete [] __intbuf_;
4059     __ebs_ = __n;
4060     if (__ebs_ > sizeof(__extbuf_min_))
4061     {
4062         if (__always_noconv_ && __s)
4063         {
4064             __extbuf_ = (char*)__s;
4065             __owns_eb_ = false;
4066         }
4067         else
4068         {
4069             __extbuf_ = new char[__ebs_];
4070             __owns_eb_ = true;
4071         }
4072     }
4073     else
4074     {
4075         __extbuf_ = __extbuf_min_;
4076         __ebs_ = sizeof(__extbuf_min_);
4077         __owns_eb_ = false;
4078     }
4079     if (!__always_noconv_)
4080     {
4081         __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
4082         if (__s && __ibs_ >= sizeof(__extbuf_min_))
4083         {
4084             __intbuf_ = __s;
4085             __owns_ib_ = false;
4086         }
4087         else
4088         {
4089             __intbuf_ = new char_type[__ibs_];
4090             __owns_ib_ = true;
4091         }
4092     }
4093     else
4094     {
4095         __ibs_ = 0;
4096         __intbuf_ = 0;
4097         __owns_ib_ = false;
4098     }
4099     return this;
4100 }
4101
4102 template <class _Codecvt, class _Elem, class _Tr>
4103 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4104 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
4105                                         ios_base::openmode __om)
4106 {
4107     int __width = __cv_->encoding();
4108     if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
4109         return pos_type(off_type(-1));
4110     // __width > 0 || __off == 0, now check __way
4111     if (__way != ios_base::beg && __way != ios_base::cur && __way != ios_base::end)
4112         return pos_type(off_type(-1));
4113     pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
4114     __r.state(__st_);
4115     return __r;
4116 }
4117
4118 template <class _Codecvt, class _Elem, class _Tr>
4119 typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
4120 wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
4121 {
4122     if (__cv_ == 0 || __bufptr_ == 0 || sync())
4123         return pos_type(off_type(-1));
4124     if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
4125         return pos_type(off_type(-1));
4126     return __sp;
4127 }
4128
4129 template <class _Codecvt, class _Elem, class _Tr>
4130 int
4131 wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
4132 {
4133     if (__cv_ == 0 || __bufptr_ == 0)
4134         return 0;
4135     if (__cm_ & ios_base::out)
4136     {
4137         if (this->pptr() != this->pbase())
4138             if (overflow() == traits_type::eof())
4139                 return -1;
4140         codecvt_base::result __r;
4141         do
4142         {
4143             char* __extbe;
4144             __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
4145             streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
4146             if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
4147                 return -1;
4148         } while (__r == codecvt_base::partial);
4149         if (__r == codecvt_base::error)
4150             return -1;
4151         if (__bufptr_->pubsync())
4152             return -1;
4153     }
4154     else if (__cm_ & ios_base::in)
4155     {
4156         off_type __c;
4157         if (__always_noconv_)
4158             __c = this->egptr() - this->gptr();
4159         else
4160         {
4161             int __width = __cv_->encoding();
4162             __c = __extbufend_ - __extbufnext_;
4163             if (__width > 0)
4164                 __c += __width * (this->egptr() - this->gptr());
4165             else
4166             {
4167                 if (this->gptr() != this->egptr())
4168                 {
4169                     reverse(this->gptr(), this->egptr());
4170                     codecvt_base::result __r;
4171                     const char_type* __e = this->gptr();
4172                     char* __extbe;
4173                     do
4174                     {
4175                         __r = __cv_->out(__st_, __e, this->egptr(), __e,
4176                                          __extbuf_, __extbuf_ + __ebs_, __extbe);
4177                         switch (__r)
4178                         {
4179                         case codecvt_base::noconv:
4180                             __c += this->egptr() - this->gptr();
4181                             break;
4182                         case codecvt_base::ok:
4183                         case codecvt_base::partial:
4184                             __c += __extbe - __extbuf_;
4185                             break;
4186                         default:
4187                             return -1;
4188                         }
4189                     } while (__r == codecvt_base::partial);
4190                 }
4191             }
4192         }
4193         if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
4194             return -1;
4195         this->setg(0, 0, 0);
4196         __cm_ = 0;
4197     }
4198     return 0;
4199 }
4200
4201 template <class _Codecvt, class _Elem, class _Tr>
4202 bool
4203 wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
4204 {
4205     if (!(__cm_ & ios_base::in))
4206     {
4207         this->setp(0, 0);
4208         if (__always_noconv_)
4209             this->setg((char_type*)__extbuf_,
4210                        (char_type*)__extbuf_ + __ebs_,
4211                        (char_type*)__extbuf_ + __ebs_);
4212         else
4213             this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
4214         __cm_ = ios_base::in;
4215         return true;
4216     }
4217     return false;
4218 }
4219
4220 template <class _Codecvt, class _Elem, class _Tr>
4221 void
4222 wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
4223 {
4224     if (!(__cm_ & ios_base::out))
4225     {
4226         this->setg(0, 0, 0);
4227         if (__ebs_ > sizeof(__extbuf_min_))
4228         {
4229             if (__always_noconv_)
4230                 this->setp((char_type*)__extbuf_,
4231                            (char_type*)__extbuf_ + (__ebs_ - 1));
4232             else
4233                 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
4234         }
4235         else
4236             this->setp(0, 0);
4237         __cm_ = ios_base::out;
4238     }
4239 }
4240
4241 template <class _Codecvt, class _Elem, class _Tr>
4242 wbuffer_convert<_Codecvt, _Elem, _Tr>*
4243 wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
4244 {
4245     wbuffer_convert* __rt = 0;
4246     if (__cv_ != 0 && __bufptr_ != 0)
4247     {
4248         __rt = this;
4249         if ((__cm_ & ios_base::out) && sync())
4250             __rt = 0;
4251     }
4252     return __rt;
4253 }
4254
4255 _LIBCPP_END_NAMESPACE_STD
4256
4257 #endif  // _LIBCPP_LOCALE