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