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