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