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