Index: libcxx/include/__config =================================================================== --- libcxx/include/__config +++ libcxx/include/__config @@ -59,6 +59,7 @@ // `pointer_safety` and `get_pointer_safety()` will no longer be available // in C++03. #define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE +#define _LIBCPP_ABI_OPTIMIZED_LOCALE #elif _LIBCPP_ABI_VERSION == 1 #if !defined(_WIN32) // Enable compiling copies of now inline methods into the dylib to support Index: libcxx/include/locale =================================================================== --- libcxx/include/locale +++ libcxx/include/locale @@ -380,19 +380,57 @@ struct __num_get : protected __num_get_base { - static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, _CharT& __thousands_sep); - static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, - unsigned& __dc, _CharT __thousands_sep, const string& __grouping, - unsigned* __g, unsigned*& __g_end, _CharT* __atoms); + static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end, _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); +#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE + static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); + static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, + unsigned& __dc, _CharT __thousands_sep, const string& __grouping, + unsigned* __g, unsigned*& __g_end, _CharT* __atoms); + +#else + static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep) + { + locale __loc = __iob.getloc(); + const numpunct<_CharT>& __np = use_facet >(__loc); + __thousands_sep = __np.thousands_sep(); + return __np.grouping(); + } + + const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const + { + return __do_widen_p(__iob, __atoms); + } + + + static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, + unsigned& __dc, _CharT __thousands_sep, const string& __grouping, + unsigned* __g, unsigned*& __g_end, const _CharT* __atoms); +private: + template + const T* __do_widen_p(ios_base& __iob, T* __atoms) const + { + locale __loc = __iob.getloc(); + use_facet >(__loc).widen(__src, __src + 26, __atoms); + return __atoms; + } + + const char* __do_widen_p(ios_base& __iob, char* __atoms) const + { + (void)__iob; + (void)__atoms; + return __src; + } +#endif }; +#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE template string __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) @@ -403,6 +441,7 @@ __thousands_sep = __np.thousands_sep(); return __np.grouping(); } +#endif template string @@ -419,9 +458,17 @@ template int +#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, unsigned& __dc, _CharT __thousands_sep, const string& __grouping, unsigned* __g, unsigned*& __g_end, _CharT* __atoms) +#else +__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, + unsigned& __dc, _CharT __thousands_sep, const string& __grouping, + unsigned* __g, unsigned*& __g_end, const _CharT* __atoms) + +#endif + { if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) { @@ -841,6 +888,7 @@ return __b; } +#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE // signed template @@ -941,6 +989,110 @@ return __b; } +#else +//signed + +template +template +_InputIterator +num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + _Signed& __v) const +{ + // Stage 1 + int __base = this->__get_base(__iob); + // Stage 2 + char_type __atoms1[26]; + char_type __thousands_sep; + const char_type *__atoms = this->__do_widen(__iob, __atoms1); + string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); + string __buf; + __buf.resize(__buf.capacity()); + char* __a = &__buf[0]; + char* __a_end = __a; + unsigned __g[__num_get_base::__num_get_buf_sz]; + unsigned* __g_end = __g; + unsigned __dc = 0; + for (; __b != __e; ++__b) + { + if (__a_end == __a + __buf.size()) + { + size_t __tmp = __buf.size(); + __buf.resize(2*__buf.size()); + __buf.resize(__buf.capacity()); + __a = &__buf[0]; + __a_end = __a + __tmp; + } + if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, + __thousands_sep, __grouping, __g, __g_end, + __atoms)) + break; + } + if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) + *__g_end++ = __dc; + // Stage 3 + __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base); + // Digit grouping checked + __check_grouping(__grouping, __g, __g_end, __err); + // EOF checked + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} + +// unsigned + +template +template +_InputIterator +num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e, + ios_base& __iob, + ios_base::iostate& __err, + _Unsigned& __v) const +{ + // Stage 1 + int __base = this->__get_base(__iob); + // Stage 2 + char_type __atoms1[26]; + char_type __thousands_sep; + const char_type *__atoms = this->__do_widen(__iob, __atoms1); + string __grouping = this->__stage2_int_prep(__iob, __thousands_sep); + string __buf; + __buf.resize(__buf.capacity()); + char* __a = &__buf[0]; + char* __a_end = __a; + unsigned __g[__num_get_base::__num_get_buf_sz]; + unsigned* __g_end = __g; + unsigned __dc = 0; + for (; __b != __e; ++__b) + { + if (__a_end == __a + __buf.size()) + { + size_t __tmp = __buf.size(); + __buf.resize(2*__buf.size()); + __buf.resize(__buf.capacity()); + __a = &__buf[0]; + __a_end = __a + __tmp; + } + if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, + __thousands_sep, __grouping, __g, __g_end, + __atoms)) + break; + } + if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) + *__g_end++ = __dc; + // Stage 3 + __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base); + // Digit grouping checked + __check_grouping(__grouping, __g, __g_end, __err); + // EOF checked + if (__b == __e) + __err |= ios_base::eofbit; + return __b; +} +#endif + // floating point template