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