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