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