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