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