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