X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Finclude%2Fbits%2Flocale_facets.tcc;h=d781503c3cf9a93ce3012e3f9d1c7091dea59191;hb=c6b83c3c04b42670c276707842d23bc8b7a0cd98;hp=518f41ad0566983898b03fe568abcee4ee8fdc24;hpb=5a64d8cf37253f8227d179a52a0c022a927db8b6;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 518f41ad056..d781503c3cf 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -35,11 +35,6 @@ #pragma GCC system_header -#include -#include // For localeconv -#include // For strof, strtold -#include // For ceil -#include // For isspace #include // For numeric_limits #include // For bad_cast. #include @@ -51,7 +46,15 @@ namespace std locale::combine(const locale& __other) const { _Impl* __tmp = new _Impl(*_M_impl, 1); - __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + try + { + __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + } + catch(...) + { + __tmp->_M_remove_reference(); + __throw_exception_again; + } return locale(__tmp); } @@ -66,20 +69,45 @@ namespace std __s2.data(), __s2.data() + __s2.length()) < 0); } + /** + * @brief Test for the presence of a facet. + * + * has_facet tests the locale argument for the presence of the facet type + * provided as the template parameter. Facets derived from the facet + * parameter will also return true. + * + * @param Facet The facet type to test the presence of. + * @param locale The locale to test. + * @return true if locale contains a facet of type Facet, else false. + * @throw std::bad_cast if locale doesn't contain the facet. + */ template inline bool has_facet(const locale& __loc) throw() { - size_t __i = _Facet::id._M_id(); + const size_t __i = _Facet::id._M_id(); const locale::facet** __facets = __loc._M_impl->_M_facets; return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); } + /** + * @brief Return a facet. + * + * use_facet looks for and returns a reference to a facet of type Facet + * where Facet is the template parameter. If has_facet(locale) is true, + * there is a suitable facet to return. It throws std::bad_cast if the + * locale doesn't contain a facet of type Facet. + * + * @param Facet The facet type to access. + * @param locale The locale to use. + * @return Reference to facet of type Facet. + * @throw std::bad_cast if locale doesn't contain a facet of type Facet. + */ template inline const _Facet& use_facet(const locale& __loc) { - size_t __i = _Facet::id._M_id(); + const size_t __i = _Facet::id._M_id(); const locale::facet** __facets = __loc._M_impl->_M_facets; if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) __throw_bad_cast(); @@ -89,133 +117,168 @@ namespace std // Routine to access a cache for the facet. If the cache didn't // exist before, it gets constructed on the fly. template - const _Facet& - __use_cache(const locale& __loc); - - template<> - const __numpunct_cache& - __use_cache(const locale& __loc); + struct __use_cache + { + const _Facet* + operator() (const locale& __loc) const; + }; -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - const __numpunct_cache& - __use_cache(const locale& __loc); -#endif + template + struct __use_cache<__numpunct_cache<_CharT> > + { + const __numpunct_cache<_CharT>* + operator() (const locale& __loc) const + { + const size_t __i = numpunct<_CharT>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __numpunct_cache<_CharT>* __tmp = NULL; + try + { + __tmp = new __numpunct_cache<_CharT>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast*>(__caches[__i]); + } + }; - // Stage 1: Determine a conversion specifier. template _InIter num_get<_CharT, _InIter>:: _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, string& __xtrc) const { - typedef char_traits<_CharT> __traits_type; - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - const numpunct<_CharT>& __np = use_facet >(__loc); + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; - // First check for sign. - const char_type __plus = __ctype.widen('+'); - const char_type __minus = __ctype.widen('-'); - int __pos = 0; - char_type __c = *__beg; - if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); - } + // True if a mantissa is found. + bool __found_mantissa = false; - // Next, strip leading zeros. - const char_type __zero = __ctype.widen(_S_atoms_in[_S_izero]); - bool __found_zero = false; - while (__traits_type::eq(__c, __zero) && __beg != __end) + // First check for sign. + if (__beg != __end) { - __c = *(++__beg); - __found_zero = true; + const char_type __c = *__beg; + const bool __plus = __traits_type::eq(__c, __lit[_S_iplus]); + if ((__plus || __traits_type::eq(__c, __lit[_S_iminus])) + && !__traits_type::eq(__c, __lc->_M_decimal_point) + && (!__lc->_M_use_grouping + || !__traits_type::eq(__c, __lc->_M_thousands_sep))) + { + __xtrc += __plus ? _S_atoms_in[_S_iplus] + : _S_atoms_in[_S_iminus]; + ++__beg; + } } - if (__found_zero) + + // Next, look for leading zeros. + while (__beg != __end) { - __xtrc += _S_atoms_in[_S_izero]; - ++__pos; + const char_type __c = *__beg; + if (__traits_type::eq(__c, __lc->_M_decimal_point) + || (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep))) + break; + else if (__traits_type::eq(__c, __lit[_S_izero])) + { + if (!__found_mantissa) + { + __xtrc += _S_atoms_in[_S_izero]; + __found_mantissa = true; + } + ++__beg; + } + else + break; } // Only need acceptable digits for floating point numbers. - const size_t __len = _S_iE - _S_izero + 1; - char_type __watoms[__len]; - __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms); bool __found_dec = false; bool __found_sci = false; - const char_type __dec = __np.decimal_point(); - string __found_grouping; - const string __grouping = __np.grouping(); - bool __check_grouping = __grouping.size(); int __sep_pos = 0; - const char_type __sep = __np.thousands_sep(); - + bool __e; + const char_type* __p; while (__beg != __end) { - // Only look in digits. - const char_type* __p = __traits_type::find(__watoms, 10, __c); - - // NB: strchr returns true for __c == 0x0 - if (__p && !__traits_type::eq(__c, char_type())) + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep)) { - // Try first for acceptable digit; record it if found. - ++__pos; - __xtrc += _S_atoms_in[__p - __watoms]; - ++__sep_pos; - __c = *(++__beg); - } - else if (__traits_type::eq(__c, __sep) - && __check_grouping && !__found_dec) - { - // NB: Thousands separator at the beginning of a string - // is a no-no, as is two consecutive thousands separators. - if (__sep_pos) - { - __found_grouping += static_cast(__sep_pos); - __sep_pos = 0; - __c = *(++__beg); - } - else + if (!__found_dec && !__found_sci) { - __err |= ios_base::failbit; - break; + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + ++__beg; + } + else + { + __err |= ios_base::failbit; + break; + } } + else + break; } - else if (__traits_type::eq(__c, __dec) && !__found_dec) + else if (__traits_type::eq(__c, __lc->_M_decimal_point)) { - // According to the standard, if no grouping chars are seen, - // no grouping check is applied. Therefore __found_grouping - // must be adjusted only if __dec comes after some __sep. - if (__found_grouping.size()) - __found_grouping += static_cast(__sep_pos); - ++__pos; - __xtrc += '.'; - __c = *(++__beg); - __found_dec = true; + if (!__found_dec && !__found_sci) + { + // If no grouping chars are seen, no grouping check + // is applied. Therefore __found_grouping is adjusted + // only if decimal_point comes after some thousands_sep. + if (__found_grouping.size()) + __found_grouping += static_cast(__sep_pos); + __xtrc += '.'; + __found_dec = true; + ++__beg; + } + else + break; } - else if ((__traits_type::eq(__c, __watoms[_S_ie]) - || __traits_type::eq(__c, __watoms[_S_iE])) - && !__found_sci && __pos) + else if (__p = __traits_type::find(__lit + _S_izero, 10, __c)) + { + __xtrc += _S_atoms_in[__p - __lit]; + __found_mantissa = true; + ++__sep_pos; + ++__beg; + } + else if ((__e = __traits_type::eq(__c, __lit[_S_ie]) + || __traits_type::eq(__c, __lit[_S_iE])) + && __found_mantissa && !__found_sci) { // Scientific notation. - ++__pos; - __xtrc += __ctype.narrow(__c, char()); - __c = *(++__beg); + __xtrc += __e ? _S_atoms_in[_S_ie] : _S_atoms_in[_S_iE]; + __found_sci = true; // Remove optional plus or minus sign, if they exist. - if (__traits_type::eq(__c, __plus) - || __traits_type::eq(__c, __minus)) + if (++__beg != __end) { - ++__pos; - __xtrc += __ctype.narrow(__c, char()); - __c = *(++__beg); + const bool __plus = __traits_type::eq(*__beg, __lit[_S_iplus]); + if (__plus || __traits_type::eq(*__beg, __lit[_S_iminus])) + { + __xtrc += __plus ? _S_atoms_in[_S_iplus] + : _S_atoms_in[_S_iminus]; + ++__beg; + } } - __found_sci = true; } else // Not a valid input item. @@ -224,306 +287,309 @@ namespace std // Digit grouping is checked. If grouping and found_grouping don't // match, then get very very upset, and set failbit. - if (__check_grouping && __found_grouping.size()) + if (__lc->_M_use_grouping && __found_grouping.size()) { // Add the ending grouping if a decimal wasn't found. if (!__found_dec) __found_grouping += static_cast(__sep_pos); - if (!__verify_grouping(__grouping, __found_grouping)) + + const string __grouping = __lc->_M_grouping; + if (!std::__verify_grouping(__grouping, __found_grouping)) __err |= ios_base::failbit; } - // Finish up + // Finish up. __xtrc += char(); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } - // Stage 1: Determine a conversion specifier. template - _InIter - num_get<_CharT, _InIter>:: - _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, - ios_base::iostate& __err, string& __xtrc, int& __base) const - { - typedef char_traits<_CharT> __traits_type; - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - const numpunct<_CharT>& __np = use_facet >(__loc); - - // NB: Iff __basefield == 0, this can change based on contents. - ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; - if (__basefield == ios_base::oct) - __base = 8; - else if (__basefield == ios_base::hex) - __base = 16; - else - __base = 10; - - // First check for sign. - int __pos = 0; - char_type __c = *__beg; - const char_type __plus = __ctype.widen('+'); - const char_type __minus = __ctype.widen('-'); - - if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); - } + template + _InIter + num_get<_CharT, _InIter>:: + _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, _ValueT& __v) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // NB: Iff __basefield == 0, __base can change based on contents. + const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; + const bool __oct = __basefield == ios_base::oct; + int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); + + // True if numeric digits are found. + bool __found_num = false; + + // First check for sign. + bool __negative = false; + if (__beg != __end) + { + const char_type __c = *__beg; + if (numeric_limits<_ValueT>::is_signed) + __negative = __traits_type::eq(__c, __lit[_S_iminus]); + if ((__negative || __traits_type::eq(__c, __lit[_S_iplus])) + && !__traits_type::eq(__c, __lc->_M_decimal_point) + && (!__lc->_M_use_grouping + || !__traits_type::eq(__c, __lc->_M_thousands_sep))) + ++__beg; + } - // Next, strip leading zeros and check required digits for base formats. - const char_type __zero = __ctype.widen(_S_atoms_in[_S_izero]); - const char_type __x = __ctype.widen('x'); - const char_type __X = __ctype.widen('X'); - if (__base == 10) - { - bool __found_zero = false; - while (__traits_type::eq(__c, __zero) && __beg != __end) - { - __c = *(++__beg); - __found_zero = true; - } - if (__found_zero) - { - __xtrc += _S_atoms_in[_S_izero]; - ++__pos; - if (__basefield == 0) - { - if ((__traits_type::eq(__c, __x) - || __traits_type::eq(__c, __X)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); + // Next, look for leading zeros and check required digits + // for base formats. + while (__beg != __end) + { + const char_type __c = *__beg; + if (__traits_type::eq(__c, __lc->_M_decimal_point) + || (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep))) + break; + else if (__traits_type::eq(__c, __lit[_S_izero]) + && (!__found_num || __base == 10)) + { + __found_num = true; + ++__beg; + } + else if (__found_num) + { + if (__traits_type::eq(__c, __lit[_S_ix]) + || __traits_type::eq(__c, __lit[_S_iX])) + { + if (__basefield == 0) __base = 16; - } - else - __base = 8; - } - } - } - else if (__base == 16) - { - if (__traits_type::eq(__c, __zero) && __beg != __end) - { - __xtrc += _S_atoms_in[_S_izero]; - ++__pos; - __c = *(++__beg); - if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); - } - } - } - - // At this point, base is determined. If not hex, only allow - // base digits as valid input. - size_t __len; - if (__base == 16) - __len = _S_iend; - else - __len = __base; - - // Extract. - char_type __watoms[_S_iend]; - __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms); - string __found_grouping; - const string __grouping = __np.grouping(); - bool __check_grouping = __grouping.size(); - int __sep_pos = 0; - const char_type __sep = __np.thousands_sep(); - while (__beg != __end) - { - const char_type* __p = __traits_type::find(__watoms, __len, __c); + if (__base == 16) + { + __found_num = false; + ++__beg; + } + } + else if (__basefield == 0) + __base = 8; + break; + } + else + break; + } - // NB: strchr returns true for __c == 0x0 - if (__p && !__traits_type::eq(__c, char_type())) - { - // Try first for acceptable digit; record it if found. - __xtrc += _S_atoms_in[__p - __watoms]; - ++__pos; - ++__sep_pos; - __c = *(++__beg); - } - else if (__traits_type::eq(__c, __sep) && __check_grouping) - { - // NB: Thousands separator at the beginning of a string - // is a no-no, as is two consecutive thousands separators. - if (__sep_pos) - { - __found_grouping += static_cast(__sep_pos); - __sep_pos = 0; - __c = *(++__beg); - } - else - { - __err |= ios_base::failbit; + // At this point, base is determined. If not hex, only allow + // base digits as valid input. + const size_t __len = __base == 16 ? _S_iend : __base; + + // Extract. + string __found_grouping; + int __sep_pos = 0; + bool __overflow = false; + _ValueT __result = 0; + const char_type* __lit_zero = __lit + _S_izero; + const char_type* __p; + if (__negative) + { + const _ValueT __min = numeric_limits<_ValueT>::min() / __base; + for (; __beg != __end; ++__beg) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep)) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__traits_type::eq(__c, __lc->_M_decimal_point)) break; - } - } - else - // Not a valid input item. - break; - } + else if (__p = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __p - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result < __min) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base - __digit; + __overflow |= __new_result > __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + // Not a valid input item. + break; + } + } + else + { + const _ValueT __max = numeric_limits<_ValueT>::max() / __base; + for (; __beg != __end; ++__beg) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping + && __traits_type::eq(__c, __lc->_M_thousands_sep)) + { + if (__sep_pos) + { + __found_grouping += static_cast(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__traits_type::eq(__c, __lc->_M_decimal_point)) + break; + else if (__p = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __p - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __max) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + __digit; + __overflow |= __new_result < __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + break; + } + } - // Digit grouping is checked. If grouping and found_grouping don't - // match, then get very very upset, and set failbit. - if (__check_grouping && __found_grouping.size()) - { - // Add the ending grouping. - __found_grouping += static_cast(__sep_pos); - if (!__verify_grouping(__grouping, __found_grouping)) - __err |= ios_base::failbit; - } + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__lc->_M_use_grouping && __found_grouping.size()) + { + // Add the ending grouping. + __found_grouping += static_cast(__sep_pos); + + const string __grouping = __lc->_M_grouping; + if (!std::__verify_grouping(__grouping, __found_grouping)) + __err |= ios_base::failbit; + } - // Finish up. - __xtrc += char(); - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } + if (!(__err & ios_base::failbit) && !__overflow + && __found_num) + __v = __result; + else + __err |= ios_base::failbit; -#ifdef _GLIBCXX_RESOLVE_LIB_DEFECTS - //17. Bad bool parsing + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 17. Bad bool parsing template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { - // Parse bool values as unsigned long if (!(__io.flags() & ios_base::boolalpha)) { + // Parse bool values as long. // NB: We can't just call do_get(long) here, as it might // refer to a derived class. - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); - if (!(__err & ios_base::failbit) && __ul <= 1) - __v = __ul; - else + long __l = -1; + __beg = _M_extract_int(__beg, __end, __io, __err, __l); + if (__l == 0 || __l == 1) + __v = __l; + else __err |= ios_base::failbit; } - - // Parse bool values as alphanumeric else { - typedef char_traits<_CharT> __traits_type; - typedef basic_string<_CharT> __string_type; - - locale __loc = __io.getloc(); - const numpunct<_CharT>& __np = use_facet >(__loc); - const __string_type __true = __np.truename(); - const __string_type __false = __np.falsename(); - const char_type* __trues = __true.c_str(); - const char_type* __falses = __false.c_str(); - const size_t __truen = __true.size() - 1; - const size_t __falsen = __false.size() - 1; - - for (size_t __n = 0; __beg != __end; ++__n) + // Parse bool values as alphanumeric. + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + bool __testf = true; + bool __testt = true; + size_t __n; + for (__n = 0; __beg != __end; ++__n, ++__beg) { - char_type __c = *__beg++; - bool __testf = __n <= __falsen - ? __traits_type::eq(__c, __falses[__n]) : false; - bool __testt = __n <= __truen - ? __traits_type::eq(__c, __trues[__n]) : false; - if (!(__testf || __testt)) - { - __err |= ios_base::failbit; - break; - } - else if (__testf && __n == __falsen) - { - __v = 0; - break; - } - else if (__testt && __n == __truen) - { - __v = 1; - break; - } + if (__testf) + if (__n < __lc->_M_falsename_len) + __testf = __traits_type::eq(*__beg, __lc->_M_falsename[__n]); + else + break; + + if (__testt) + if (__n < __lc->_M_truename_len) + __testt = __traits_type::eq(*__beg, __lc->_M_truename[__n]); + else + break; + + if (!__testf && !__testt) + break; } + if (__testf && __n == __lc->_M_falsename_len) + __v = 0; + else if (__testt && __n == __lc->_M_truename_len) + __v = 1; + else + __err |= ios_base::failbit; + if (__beg == __end) __err |= ios_base::eofbit; } return __beg; } -#endif template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); - if (!(__err & ios_base::failbit) - && __ul <= numeric_limits::max()) - __v = static_cast(__ul); - else - __err |= ios_base::failbit; - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); - if (!(__err & ios_base::failbit) - && __ul <= numeric_limits::max()) - __v = static_cast(__ul); - else - __err |= ios_base::failbit; - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } #ifdef _GLIBCXX_USE_LONG_LONG template @@ -531,26 +597,14 @@ namespace std num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } #endif template @@ -562,7 +616,7 @@ namespace std string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); return __beg; } @@ -575,7 +629,7 @@ namespace std string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); return __beg; } @@ -588,7 +642,7 @@ namespace std string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); return __beg; } @@ -598,22 +652,17 @@ namespace std do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const { - // Prepare for hex formatted input + // Prepare for hex formatted input. typedef ios_base::fmtflags fmtflags; - fmtflags __fmt = __io.flags(); - fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield - | ios_base::uppercase | ios_base::internal); - __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); + const fmtflags __fmt = __io.flags(); + __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); + unsigned long __ul; + __beg = _M_extract_int(__beg, __end, __io, __err, __ul); - // Reset from hex formatted input + // Reset from hex formatted input. __io.flags(__fmt); - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); if (!(__err & ios_base::failbit)) __v = reinterpret_cast(__ul); else @@ -639,8 +688,8 @@ namespace std // Forwarding functions to peel signed from unsigned integer types. template inline int - __int_to_char(_CharT* __out, const int __size, long __v, - const _CharT* __lit, ios_base::fmtflags __flags) + __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit, + ios_base::fmtflags __flags) { unsigned long __ul = static_cast(__v); bool __neg = false; @@ -649,20 +698,20 @@ namespace std __ul = -__ul; __neg = true; } - return __int_to_char(__out, __size, __ul, __lit, __flags, __neg); + return __int_to_char(__bufend, __ul, __lit, __flags, __neg); } template inline int - __int_to_char(_CharT* __out, const int __size, unsigned long __v, - const _CharT* __lit, ios_base::fmtflags __flags) - { return __int_to_char(__out, __size, __v, __lit, __flags, false); } + __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { return __int_to_char(__bufend, __v, __lit, __flags, false); } #ifdef _GLIBCXX_USE_LONG_LONG template inline int - __int_to_char(_CharT* __out, const int __size, long long __v, - const _CharT* __lit, ios_base::fmtflags __flags) + __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit, + ios_base::fmtflags __flags) { unsigned long long __ull = static_cast(__v); bool __neg = false; @@ -671,26 +720,25 @@ namespace std __ull = -__ull; __neg = true; } - return __int_to_char(__out, __size, __ull, __lit, __flags, __neg); + return __int_to_char(__bufend, __ull, __lit, __flags, __neg); } template inline int - __int_to_char(_CharT* __out, const int __size, unsigned long long __v, - const _CharT* __lit, ios_base::fmtflags __flags) - { return __int_to_char(__out, __size, __v, __lit, __flags, false); } + __int_to_char(_CharT* __bufend, unsigned long long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { return __int_to_char(__bufend, __v, __lit, __flags, false); } #endif template int - __int_to_char(_CharT* __out, const int __size, _ValueT __v, - const _CharT* __lit, ios_base::fmtflags __flags, bool __neg) + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __neg) { // Don't write base if already 0. const bool __showbase = (__flags & ios_base::showbase) && __v; const ios_base::fmtflags __basefield = __flags & ios_base::basefield; - _CharT* __buf = __out + __size - 1; - _CharT* __bufend = __out + __size; + _CharT* __buf = __bufend - 1; if (__builtin_expect(__basefield != ios_base::oct && __basefield != ios_base::hex, true)) @@ -707,7 +755,7 @@ namespace std else if (__flags & ios_base::showpos) *__buf-- = __lit[__num_base::_S_oplus]; } - else if (__basefield == ios_base::oct) + else if (__basefield == ios_base::oct) { // Octal. do @@ -723,8 +771,8 @@ namespace std { // Hex. const bool __uppercase = __flags & ios_base::uppercase; - int __case_offset = __uppercase ? __num_base::_S_oudigits - : __num_base::_S_odigits; + const int __case_offset = __uppercase ? __num_base::_S_oudigits + : __num_base::_S_odigits; do { *__buf-- = __lit[(__v & 0xf) + __case_offset]; @@ -739,8 +787,7 @@ namespace std *__buf-- = __lit[__num_base::_S_odigits]; } } - int __ret = __bufend - __buf - 1; - return __ret; + return __bufend - __buf - 1; } template @@ -749,7 +796,7 @@ namespace std _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const { - // By itself __add_grouping cannot deal correctly with __ws when + // By itself __add_grouping cannot deal correctly with __cs when // ios::showbase is set and ios_base::oct || ios_base::hex. // Therefore we take care "by hand" of the initial 0, 0x or 0X. // However, remember that the latter do not occur if the number @@ -761,19 +808,18 @@ namespace std if (__basefield == ios_base::oct) { __off = 1; - *__new = *__cs; + __new[0] = __cs[0]; } else if (__basefield == ios_base::hex) { __off = 2; - *__new = *__cs; - *(__new + 1) = *(__cs + 1); + __new[0] = __cs[0]; + __new[1] = __cs[1]; } _CharT* __p; - __p = __add_grouping(__new + __off, __sep, - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __cs + __off, __cs + __len); + __p = std::__add_grouping(__new + __off, __sep, __grouping.data(), + __grouping.data() + __grouping.size(), + __cs + __off, __cs + __len); __len = __p - __new; } @@ -781,44 +827,44 @@ namespace std template _OutIter num_put<_CharT, _OutIter>:: - _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, - _ValueT __v) const + _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const { - typedef typename numpunct<_CharT>::__cache_type __cache_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); - const __cache_type& __lc = __use_cache<__cache_type>(__loc); - const _CharT* __lit = __lc._M_atoms_out; + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_out; // Long enough to hold hex, dec, and octal representations. - int __ilen = 4 * sizeof(_ValueT); + const int __ilen = 4 * sizeof(_ValueT); _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __ilen)); + // [22.2.2.2.2] Stage 1, numeric conversion to character. // Result is returned right-justified in the buffer. int __len; - __len = __int_to_char(&__cs[0], __ilen, __v, __lit, __io.flags()); - __cs = __cs + __ilen - __len; + __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags()); + __cs += __ilen - __len; // Add grouping, if necessary. - _CharT* __cs2; - if (__lc._M_use_grouping) + if (__lc->_M_use_grouping) { // Grouping can add (almost) as many separators as the // number of digits, but no more. - __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - _M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io, + _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_int(__lc->_M_grouping, __lc->_M_thousands_sep, __io, __cs2, __cs, __len); __cs = __cs2; } // Pad. - _CharT* __cs3; - streamsize __w = __io.width(); + const streamsize __w = __io.width(); if (__w > static_cast(__len)) { - __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __w)); + _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); _M_pad(__fill, __w, __io, __cs3, __cs, __len); __cs = __cs3; } @@ -826,7 +872,7 @@ namespace std // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. - return __write(__s, __cs, __len); + return std::__write(__s, __cs, __len); } template @@ -835,15 +881,14 @@ namespace std _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p, _CharT* __new, _CharT* __cs, int& __len) const { -#ifdef _GLIBCXX_RESOLVE_LIB_DEFECTS - //282. What types does numpunct grouping refer to? + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 282. What types does numpunct grouping refer to? // Add grouping, if necessary. _CharT* __p2; - int __declen = __p ? __p - __cs : __len; - __p2 = __add_grouping(__new, __sep, - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __cs, __cs + __declen); + const int __declen = __p ? __p - __cs : __len; + __p2 = std::__add_grouping(__new, __sep, __grouping.data(), + __grouping.data() + __grouping.size(), + __cs, __cs + __declen); // Tack on decimal part. int __newlen = __p2 - __new; @@ -853,7 +898,6 @@ namespace std __newlen += __len - __declen; } __len = __newlen; -#endif } // The following code uses snprintf (or sprintf(), when @@ -870,9 +914,14 @@ namespace std template _OutIter num_put<_CharT, _OutIter>:: - _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, + _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + // Note: digits10 is rounded down: add 1 to ensure the maximum // available precision. Then, in general, one more 1 needs to // be added since, when the %{g,G} conversion specifiers are @@ -889,10 +938,6 @@ namespace std else if (__prec < static_cast(0)) __prec = static_cast(6); - typedef typename numpunct<_CharT>::__cache_type __cache_type; - const locale& __loc = __io._M_getloc(); - const __cache_type& __lc = __use_cache<__cache_type>(__loc); - // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; // Long enough for the max format spec. @@ -905,22 +950,23 @@ namespace std char* __cs = static_cast(__builtin_alloca(__cs_size)); _S_format_float(__io, __fbuf, __mod); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale, __prec); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale, __prec); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); } #else // Consider the possibility of long ios_base::fixed outputs const bool __fixed = __io.flags() & ios_base::fixed; const int __max_exp = numeric_limits<_ValueT>::max_exponent10; + // The size of the output string is computed as follows. // ios_base::fixed outputs may need up to __max_exp+1 chars // for the integer part + up to __max_digits chars for the // fractional part + 3 chars for sign, decimal point, '\0'. On @@ -931,7 +977,8 @@ namespace std char* __cs = static_cast(__builtin_alloca(__cs_size)); _S_format_float(__io, __fbuf, __mod); - __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec); + __len = std::__convert_from_v(__cs, 0, __fbuf, __v, + _S_get_c_locale(), __prec); #endif // [22.2.2.2.2] Stage 2, convert to char_type, using correct @@ -944,30 +991,29 @@ namespace std // Replace decimal point. const _CharT __cdec = __ctype.widen('.'); - const _CharT __dec = __lc._M_decimal_point; + const _CharT __dec = __lc->_M_decimal_point; const _CharT* __p; if (__p = char_traits<_CharT>::find(__ws, __len, __cdec)) __ws[__p - __ws] = __dec; // Add grouping, if necessary. - _CharT* __ws2; - if (__lc._M_use_grouping) + if (__lc->_M_use_grouping) { - // Grouping can add (almost) as many separators as the - // number of digits, but no more. - __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - _M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p, - __ws2, __ws, __len); - __ws = __ws2; + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_float(__lc->_M_grouping, __lc->_M_thousands_sep, __p, + __ws2, __ws, __len); + __ws = __ws2; } // Pad. - _CharT* __ws3; - streamsize __w = __io.width(); + const streamsize __w = __io.width(); if (__w > static_cast(__len)) { - __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); + _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); _M_pad(__fill, __w, __io, __ws3, __ws, __len); __ws = __ws3; } @@ -975,7 +1021,7 @@ namespace std // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. - return __write(__s, __ws, __len); + return std::__write(__s, __ws, __len); } template @@ -983,38 +1029,34 @@ namespace std num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const { - ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __flags = __io.flags(); if ((__flags & ios_base::boolalpha) == 0) { unsigned long __uv = __v; - __s = _M_convert_int(__s, __io, __fill, __uv); + __s = _M_insert_int(__s, __io, __fill, __uv); } else { - typedef typename numpunct<_CharT>::__cache_type __cache_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); - const __cache_type& __lc = __use_cache<__cache_type>(__loc); - - typedef basic_string<_CharT> __string_type; - __string_type __name; - if (__v) - __name = __lc._M_truename; - else - __name = __lc._M_falsename; - - const _CharT* __cs = __name.c_str(); - int __len = __name.size(); - _CharT* __cs3; - streamsize __w = __io.width(); + const __cache_type* __lc = __uc(__loc); + + const _CharT* __name = __v ? __lc->_M_truename + : __lc->_M_falsename; + int __len = __v ? __lc->_M_truename_len + : __lc->_M_falsename_len; + + const streamsize __w = __io.width(); if (__w > static_cast(__len)) { - __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __w)); - _M_pad(__fill, __w, __io, __cs3, __cs, __len); - __cs = __cs3; + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs, __name, __len); + __name = __cs; } __io.width(0); - __s = __write(__s, __cs, __len); + __s = std::__write(__s, __name, __len); } return __s; } @@ -1023,42 +1065,42 @@ namespace std _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const - { return _M_convert_int(__s, __io, __fill, __v); } + { return _M_insert_int(__s, __io, __fill, __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const - { return _M_convert_int(__s, __io, __fill, __v); } + { return _M_insert_int(__s, __io, __fill, __v); } #ifdef _GLIBCXX_USE_LONG_LONG template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const - { return _M_convert_int(__s, __b, __fill, __v); } + { return _M_insert_int(__s, __b, __fill, __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long long __v) const - { return _M_convert_int(__s, __io, __fill, __v); } + { return _M_insert_int(__s, __io, __fill, __v); } #endif template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const - { return _M_convert_float(__s, __io, __fill, char(), __v); } + { return _M_insert_float(__s, __io, __fill, char(), __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long double __v) const - { return _M_convert_float(__s, __io, __fill, 'L', __v); } + { return _M_insert_float(__s, __io, __fill, 'L', __v); } template _OutIter @@ -1066,21 +1108,14 @@ namespace std do_put(iter_type __s, ios_base& __io, char_type __fill, const void* __v) const { - ios_base::fmtflags __flags = __io.flags(); - ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield - | ios_base::uppercase | ios_base::internal); + const ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield + | ios_base::uppercase | ios_base::internal); __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); - try - { - __s = _M_convert_int(__s, __io, __fill, - reinterpret_cast(__v)); - __io.flags(__flags); - } - catch (...) - { - __io.flags(__flags); - __throw_exception_again; - } + + __s = _M_insert_int(__s, __io, __fill, + reinterpret_cast(__v)); + __io.flags(__flags); return __s; } @@ -1094,13 +1129,13 @@ namespace std string_type __str; __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); - const int __n = numeric_limits::digits10; - char* __cs = static_cast(__builtin_alloca(__n)); + const int __cs_size = __str.size() + 1; + char* __cs = static_cast(__builtin_alloca(__cs_size)); const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); const _CharT* __wcs = __str.c_str(); - __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs); - __convert_to_v(__cs, __units, __err, _S_c_locale); + __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs); + std::__convert_to_v(__cs, __units, __err, _S_get_c_locale()); return __beg; } @@ -1124,10 +1159,10 @@ namespace std const money_base::pattern __p = __intl ? __mpt.neg_format() : __mpf.neg_format(); - const string_type __pos_sign =__intl ? __mpt.positive_sign() - : __mpf.positive_sign(); - const string_type __neg_sign =__intl ? __mpt.negative_sign() - : __mpf.negative_sign(); + const string_type __pos_sign = __intl ? __mpt.positive_sign() + : __mpf.positive_sign(); + const string_type __neg_sign = __intl ? __mpt.negative_sign() + : __mpf.negative_sign(); const char_type __d = __intl ? __mpt.decimal_point() : __mpf.decimal_point(); const char_type __sep = __intl ? __mpt.thousands_sep() @@ -1149,161 +1184,152 @@ namespace std // The tentative returned string is stored here. string_type __tmp_units; - char_type __c = *__beg; - char_type __eof = static_cast(char_traits::eof()); for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i) { - part __which = static_cast(__p.field[__i]); + char_type __c; + const part __which = static_cast(__p.field[__i]); switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase + || __i < 2 || __sign.size() > 1 + || ((static_cast(__p.field[3]) != money_base::none) + && __i == 2)) { - case money_base::symbol: - if (__io.flags() & ios_base::showbase - || __i < 2 || __sign.size() > 1 - || ((static_cast(__p.field[3]) != money_base::none) - && __i == 2)) - { - // According to 22.2.6.1.2.2, symbol is required - // if (__io.flags() & ios_base::showbase), - // otherwise is optional and consumed only if - // other characters are needed to complete the - // format. - const string_type __symbol = __intl ? __mpt.curr_symbol() - : __mpf.curr_symbol(); - size_type __len = __symbol.size(); - size_type __j = 0; - while (__beg != __end - && __j < __len && __symbol[__j] == __c) - { - __c = *(++__beg); - ++__j; - } - // When (__io.flags() & ios_base::showbase) - // symbol is required. - if (__j != __len && (__io.flags() & ios_base::showbase)) - __testvalid = false; - } - break; - case money_base::sign: - // Sign might not exist, or be more than one character long. - if (__pos_sign.size() && __neg_sign.size()) + // According to 22.2.6.1.2.2, symbol is required + // if (__io.flags() & ios_base::showbase), + // otherwise is optional and consumed only if + // other characters are needed to complete the + // format. + const string_type __symbol = __intl ? __mpt.curr_symbol() + : __mpf.curr_symbol(); + const size_type __len = __symbol.size(); + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __symbol[__j]; ++__beg, ++__j); + // When (__io.flags() & ios_base::showbase) + // symbol is required. + if (__j != __len && (__io.flags() & ios_base::showbase)) + __testvalid = false; + } + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__pos_sign.size() && *__beg == __pos_sign[0]) + { + __sign = __pos_sign; + ++__beg; + } + else if (__neg_sign.size() && *__beg == __neg_sign[0]) + { + __sign = __neg_sign; + ++__beg; + } + else if (__pos_sign.size() && __neg_sign.size()) + { + // Sign is mandatory. + __testvalid = false; + } + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + if (__ctype.is(ctype_base::digit, __c = *__beg)) + { + __tmp_units += __c; + ++__sep_pos; + } + else if (__c == __d && !__testdecfound) + { + __grouping_tmp += static_cast(__sep_pos); + __sep_pos = 0; + __testdecfound = true; + } + else if (__c == __sep) { - // Sign is mandatory. - if (__c == __pos_sign[0]) + if (__grouping.size()) { - __sign = __pos_sign; - __c = *(++__beg); + // Mark position for later analysis. + __grouping_tmp += static_cast(__sep_pos); + __sep_pos = 0; } - else if (__c == __neg_sign[0]) + else { - __sign = __neg_sign; - __c = *(++__beg); + __testvalid = false; + break; } - else - __testvalid = false; } - else if (__pos_sign.size() && __c == __pos_sign[0]) - { - __sign = __pos_sign; - __c = *(++__beg); - } - else if (__neg_sign.size() && __c == __neg_sign[0]) - { - __sign = __neg_sign; - __c = *(++__beg); - } - break; - case money_base::value: - // Extract digits, remove and stash away the - // grouping of found thousands separators. - while (__beg != __end - && (__ctype.is(ctype_base::digit, __c) - || (__c == __d && !__testdecfound) - || __c == __sep)) - { - if (__c == __d) - { - __grouping_tmp += static_cast(__sep_pos); - __sep_pos = 0; - __testdecfound = true; - } - else if (__c == __sep) - { - if (__grouping.size()) - { - // Mark position for later analysis. - __grouping_tmp += static_cast(__sep_pos); - __sep_pos = 0; - } - else - { - __testvalid = false; - break; - } - } - else - { - __tmp_units += __c; - ++__sep_pos; - } - __c = *(++__beg); - } - break; - case money_base::space: - case money_base::none: - // Only if not at the end of the pattern. - if (__i != 3) - while (__beg != __end - && __ctype.is(ctype_base::space, __c)) - __c = *(++__beg); + else break; - } + break; + case money_base::space: + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } } - + // Need to get the rest of the sign characters, if they exist. if (__sign.size() > 1) { - size_type __len = __sign.size(); + const size_type __len = __sign.size(); size_type __i = 1; - for (; __c != __eof && __i < __len; ++__i) - while (__beg != __end && __c != __sign[__i]) - __c = *(++__beg); + for (; __beg != __end && __i < __len; ++__i) + for (; __beg != __end + && *__beg != __sign[__i]; ++__beg); if (__i != __len) __testvalid = false; } - // Strip leading zeros. - while (!__tmp_units.empty() && __tmp_units[0] == __ctype.widen('0')) - __tmp_units.erase(__tmp_units.begin()); - - if (__sign.size() && __sign == __neg_sign) - __tmp_units.insert(__tmp_units.begin(), __ctype.widen('-')); - - // Test for grouping fidelity. - if (__grouping.size() && __grouping_tmp.size()) + if (__testvalid && __tmp_units.size()) { - if (!__verify_grouping(__grouping, __grouping_tmp)) - __testvalid = false; - } + const char_type __zero = __ctype.widen('0'); - // Iff no more characters are available. - if (__c == __eof) - __err |= ios_base::eofbit; + // Strip leading zeros. + if (__tmp_units.size() > 1) + { + const size_type __first = __tmp_units.find_first_not_of(__zero); + const bool __only_zeros = __first == string_type::npos; + if (__first) + __tmp_units.erase(0, __only_zeros ? __tmp_units.size() - 1 + : __first); + } + + // 22.2.6.1.2, p4 + if (__sign.size() && __sign == __neg_sign + && __tmp_units[0] != __zero) + __tmp_units.insert(__tmp_units.begin(), __ctype.widen('-')); - // Iff not enough digits were supplied after the decimal-point. - if (__testdecfound) - { - const int __frac = __intl ? __mpt.frac_digits() - : __mpf.frac_digits(); - if (__frac > 0) + // Test for grouping fidelity. + if (__grouping.size() && __grouping_tmp.size()) + { + if (!std::__verify_grouping(__grouping, __grouping_tmp)) + __testvalid = false; + } + + // Iff not enough digits were supplied after the decimal-point. + if (__testdecfound) { - if (__sep_pos != __frac) + const int __frac = __intl ? __mpt.frac_digits() + : __mpf.frac_digits(); + if (__frac > 0 && __sep_pos != __frac) __testvalid = false; } } + else + __testvalid = false; + + // Iff no more characters are available. + if (__beg == __end) + __err |= ios_base::eofbit; // Iff valid sequence is not recognized. - if (!__testvalid || !__tmp_units.size()) + if (!__testvalid) __err |= ios_base::failbit; else // Use the "swap trick" to copy __tmp_units into __units. @@ -1324,22 +1350,24 @@ namespace std // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, - _S_c_locale); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 328. Bad sprintf format modifier in money_put<>::do_put() + int __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units, + _S_get_c_locale()); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, - _S_c_locale); + __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units, + _S_get_c_locale()); } #else - // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point, - // decimal digit, '\0'. - const int __cs_size = numeric_limits::max_exponent10 + 5; + // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. + const int __cs_size = numeric_limits::max_exponent10 + 3; char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale); + int __len = std::__convert_from_v(__cs, 0, "%.0Lf", __units, + _S_get_c_locale()); #endif _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size)); @@ -1376,12 +1404,12 @@ namespace std if (*__beg != __ctype.widen('-')) { __p = __intl ? __mpt.pos_format() : __mpf.pos_format(); - __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign(); + __sign = __intl ? __mpt.positive_sign() : __mpf.positive_sign(); } else { __p = __intl ? __mpt.neg_format() : __mpf.neg_format(); - __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign(); + __sign = __intl ? __mpt.negative_sign() : __mpf.negative_sign(); ++__beg; } @@ -1414,8 +1442,8 @@ namespace std { // Have to pad zeros in the decimal position. __value = string_type(__beg, __end); - int __paddec = __frac - (__end - __beg); - char_type __zero = __ctype.widen('0'); + const int __paddec = __frac - (__end - __beg); + const char_type __zero = __ctype.widen('0'); __value.insert(__value.begin(), __paddec, __zero); __value.insert(__value.begin(), __d); __beg = __end; @@ -1432,13 +1460,13 @@ namespace std { const char_type __sep = __intl ? __mpt.thousands_sep() : __mpf.thousands_sep(); - const char* __gbeg = __grouping.c_str(); + const char* __gbeg = __grouping.data(); const char* __gend = __gbeg + __grouping.size(); const int __n = (__end - __beg) * 2; _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); - _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, - __gend, __beg, __end); + _CharT* __ws_end = std::__add_grouping(__ws2, __sep, __gbeg, + __gend, __beg, __end); __value.insert(0, __ws2, __ws_end - __ws2); } else @@ -1446,15 +1474,15 @@ namespace std } // Calculate length of resulting string. - ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield; + const ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield; size_type __len = __value.size() + __sign.size(); __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0; - bool __testipad = __f == ios_base::internal && __len < __width; + const bool __testipad = __f == ios_base::internal && __len < __width; // Fit formatted digits into the required pattern. for (int __i = 0; __i < 4; ++__i) { - part __which = static_cast(__p.field[__i]); + const part __which = static_cast(__p.field[__i]); switch (__which) { case money_base::symbol: @@ -1505,7 +1533,7 @@ namespace std } // Write resulting, fully-formatted string to output iterator. - __s = __write(__s, __res.c_str(), __len); + __s = std::__write(__s, __res.data(), __len); } __io.width(0); return __s; @@ -1520,6 +1548,10 @@ namespace std time_get<_CharT, _InIter>::do_date_order() const { return time_base::no_order; } + // Recursively expand a strftime format string and parse it. Starts w/ %x + // and %X from do_get_time() and do_get_date(), which translate to a more + // specific string, which may contain yet more strings. I.e. %x => %r => + // %H:%M:%S => extracted characters. template void time_get<_CharT, _InIter>:: @@ -1527,25 +1559,20 @@ namespace std ios_base::iostate& __err, tm* __tm, const _CharT* __format) const { - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + const locale __loc = __io.getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const ctype<_CharT>& __ctype = use_facet >(__loc); - size_t __len = char_traits<_CharT>::length(__format); + const size_t __len = char_traits<_CharT>::length(__format); for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i) { - char __c = __format[__i]; - if (__c == '%') + if (__ctype.narrow(__format[__i], 0) == '%') { // Verify valid formatting code, attempt to extract. - __c = __format[++__i]; - char __mod = 0; + char __c = __ctype.narrow(__format[++__i], 0); int __mem = 0; if (__c == 'E' || __c == 'O') - { - __mod = __c; - __c = __format[++__i]; - } + __c = __ctype.narrow(__format[++__i], 0); switch (__c) { const char* __cs; @@ -1555,14 +1582,14 @@ namespace std const char_type* __days1[7]; __tp._M_days_abbreviated(__days1); _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, - __err); + __ctype, __err); break; case 'A': // Weekday name [tm_wday]. const char_type* __days2[7]; __tp._M_days(__days2); _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, - __err); + __ctype, __err); break; case 'h': case 'b': @@ -1570,14 +1597,14 @@ namespace std const char_type* __months1[12]; __tp._M_months_abbreviated(__months1); _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, - __err); + __ctype, __err); break; case 'B': // Month name [tm_mon]. const char_type* __months2[12]; __tp._M_months(__months2); _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, - __err); + __ctype, __err); break; case 'c': // Default time and date representation. @@ -1591,6 +1618,16 @@ namespace std _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, __ctype, __err); break; + case 'e': + // Day [1, 31], with single digits preceded by + // space. [tm_mday] + if (__ctype.is(ctype_base::space, *__beg)) + _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 1, + __ctype, __err); + else + _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 2, + __ctype, __err); + break; case 'D': // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] __cs = "%m/%d/%y"; @@ -1642,7 +1679,7 @@ namespace std if (__ctype.narrow(*__beg, 0) == '\t') ++__beg; else - __err |= ios_base::failbit; + __err |= ios_base::failbit; break; case 'T': // Equivalent to (%H:%M:%S). @@ -1666,14 +1703,14 @@ namespace std __times[0]); break; case 'y': + case 'C': // C99 // Two digit year. [tm_year] _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, __ctype, __err); break; case 'Y': // Year [1900). [tm_year] - _M_extract_num(__beg, __end, __mem, 0, - numeric_limits::max(), 4, + _M_extract_num(__beg, __end, __mem, 0, 9999, 4, __ctype, __err); if (!__err) __tm->tm_year = __mem - 1900; @@ -1684,37 +1721,36 @@ namespace std { int __tmp; _M_extract_name(__beg, __end, __tmp, - __timepunct<_CharT>::_S_timezones, - 14, __err); + __timepunct_cache<_CharT>::_S_timezones, + 14, __ctype, __err); // GMT requires special effort. - char_type __c = *__beg; - if (!__err && __tmp == 0 - && (__c == __ctype.widen('-') - || __c == __ctype.widen('+'))) + if (__beg != __end && !__err && __tmp == 0 + && (*__beg == __ctype.widen('-') + || *__beg == __ctype.widen('+'))) { _M_extract_num(__beg, __end, __tmp, 0, 23, 2, __ctype, __err); _M_extract_num(__beg, __end, __tmp, 0, 59, 2, __ctype, __err); } - } - else - __err |= ios_base::failbit; - break; - default: - // Not recognized. - __err |= ios_base::failbit; } - } - else - { - // Verify format and input match, extract and discard. - if (__c == __ctype.narrow(*__beg, 0)) - ++__beg; else __err |= ios_base::failbit; + break; + default: + // Not recognized. + __err |= ios_base::failbit; } + } + else + { + // Verify format and input match, extract and discard. + if (__format[__i] == *__beg) + ++__beg; + else + __err |= ios_base::failbit; + } } } @@ -1726,28 +1762,29 @@ namespace std const ctype<_CharT>& __ctype, ios_base::iostate& __err) const { + // As-is works for __len = 1, 2, 4, the values actually used. + int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); + + ++__min; size_t __i = 0; - string __digits; - bool __testvalid = true; - char_type __c = *__beg; - while (__beg != __end && __i < __len - && __ctype.is(ctype_base::digit, __c)) + int __value = 0; + for (; __beg != __end && __i < __len; ++__beg, ++__i) { - __digits += __ctype.narrow(__c, 0); - __c = *(++__beg); - ++__i; - } - if (__i == __len) - { - int __value = atoi(__digits.c_str()); - if (__min <= __value && __value <= __max) - __member = __value; + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + __value = __value * 10 + (__c - '0'); + const int __valuec = __value * __mult; + if (__valuec > __max || __valuec + __mult < __min) + break; + __mult /= 10; + } else - __testvalid = false; + break; } + if (__i == __len) + __member = __value; else - __testvalid = false; - if (!__testvalid) __err |= ios_base::failbit; } @@ -1758,6 +1795,7 @@ namespace std time_get<_CharT, _InIter>:: _M_extract_name(iter_type& __beg, iter_type& __end, int& __member, const _CharT** __names, size_t __indexlen, + const ctype<_CharT>& __ctype, ios_base::iostate& __err) const { typedef char_traits<_CharT> __traits_type; @@ -1768,28 +1806,34 @@ namespace std bool __testvalid = true; const char_type* __name; - char_type __c = *__beg; - // Look for initial matches. - for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) - if (__c == __names[__i1][0]) - __matches[__nmatches++] = __i1; + // Look for initial matches. + // NB: Some of the locale data is in the form of all lowercase + // names, and some is in the form of initially-capitalized + // names. Look for both. + if (__beg != __end) + { + const char_type __c = *__beg; + for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) + if (__c == __names[__i1][0] + || __c == __ctype.toupper(__names[__i1][0])) + __matches[__nmatches++] = __i1; + } while (__nmatches > 1) { // Find smallest matching string. size_t __minlen = 10; for (size_t __i2 = 0; __i2 < __nmatches; ++__i2) - __minlen = min(__minlen, - __traits_type::length(__names[__matches[__i2]])); - + __minlen = std::min(__minlen, + __traits_type::length(__names[__matches[__i2]])); + ++__beg; if (__pos < __minlen && __beg != __end) { ++__pos; - __c = *(++__beg); for (size_t __i3 = 0; __i3 < __nmatches; ++__i3) { __name = __names[__matches[__i3]]; - if (__name[__pos] != __c) + if (__name[__pos] != *__beg) __matches[__i3] = __matches[--__nmatches]; } } @@ -1799,6 +1843,13 @@ namespace std if (__nmatches == 1) { + // If there was only one match, the first compare is redundant. + if (__pos == 0) + { + ++__pos; + ++__beg; + } + // Make sure found name is completely extracted. __name = __names[__matches[0]]; const size_t __len = __traits_type::length(__name); @@ -1824,7 +1875,7 @@ namespace std { _CharT __wcs[3]; const char* __cs = "%X"; - locale __loc = __io.getloc(); + const locale __loc = __io.getloc(); ctype<_CharT> const& __ctype = use_facet >(__loc); __ctype.widen(__cs, __cs + 3, __wcs); _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs); @@ -1841,7 +1892,7 @@ namespace std { _CharT __wcs[3]; const char* __cs = "%x"; - locale __loc = __io.getloc(); + const locale __loc = __io.getloc(); ctype<_CharT> const& __ctype = use_facet >(__loc); __ctype.widen(__cs, __cs + 3, __wcs); _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs); @@ -1857,12 +1908,13 @@ namespace std ios_base::iostate& __err, tm* __tm) const { typedef char_traits<_CharT> __traits_type; - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + const locale __loc = __io.getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); const char_type* __days[7]; __tp._M_days_abbreviated(__days); int __tmpwday; - _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err); + _M_extract_name(__beg, __end, __tmpwday, __days, 7, __ctype, __err); // Check to see if non-abbreviated name exists, and extract. // NB: Assumes both _M_days and _M_days_abbreviated organized in @@ -1900,12 +1952,13 @@ namespace std ios_base& __io, ios_base::iostate& __err, tm* __tm) const { typedef char_traits<_CharT> __traits_type; - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + const locale __loc = __io.getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); const char_type* __months[12]; __tp._M_months_abbreviated(__months); int __tmpmon; - _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err); + _M_extract_name(__beg, __end, __tmpmon, __months, 12, __ctype, __err); // Check to see if non-abbreviated name exists, and extract. // NB: Assumes both _M_months and _M_months_abbreviated organized in @@ -1943,28 +1996,21 @@ namespace std do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - locale __loc = __io.getloc(); + const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); - char_type __c = *__beg; size_t __i = 0; - string __digits; - while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c)) + int __value = 0; + for (; __beg != __end && __i < 4; ++__beg, ++__i) { - __digits += __ctype.narrow(__c, 0); - __c = *(++__beg); - ++__i; + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + __value = __value * 10 + (__c - '0'); + else + break; } if (__i == 2 || __i == 4) - { - long __l; - __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale); - if (!(__err & ios_base::failbit) && __l <= INT_MAX) - { - __l = __i == 2 ? __l : __l - 1900; - __tm->tm_year = static_cast(__l); - } - } + __tm->tm_year = __i == 2 ? __value : __value - 1900; else __err |= ios_base::failbit; if (__beg == __end) @@ -1975,38 +2021,36 @@ namespace std template _OutIter time_put<_CharT, _OutIter>:: - put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, const _CharT* __beg, const _CharT* __end) const { - locale __loc = __io.getloc(); + const locale __loc = __io.getloc(); ctype<_CharT> const& __ctype = use_facet >(__loc); - while (__beg != __end) - { - char __c = __ctype.narrow(*__beg, 0); - ++__beg; - if (__c == '%') - { - char __format; - char __mod = 0; - size_t __len = 1; - __c = __ctype.narrow(*__beg, 0); - ++__beg; - if (__c == 'E' || __c == 'O') - { - __mod = __c; - __format = __ctype.narrow(*__beg, 0); - ++__beg; - } - else - __format = __c; - __s = this->do_put(__s, __io, _CharT(), __tm, __format, __mod); - } - else - { - *__s = __c; - ++__s; - } - } + for (; __beg != __end; ++__beg) + if (__ctype.narrow(*__beg, 0) != '%') + { + *__s = *__beg; + ++__s; + } + else if (++__beg != __end) + { + char __format; + char __mod = 0; + const char __c = __ctype.narrow(*__beg, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__beg != __end) + { + __mod = __c; + __format = __ctype.narrow(*__beg, 0); + } + else + break; + __s = this->do_put(__s, __io, __fill, __tm, + __format, __mod); + } + else + break; return __s; } @@ -2016,14 +2060,15 @@ namespace std do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, char __format, char __mod) const { - locale __loc = __io.getloc(); + const locale __loc = __io.getloc(); ctype<_CharT> const& __ctype = use_facet >(__loc); __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); // NB: This size is arbitrary. Should this be a data member, // initialized at construction? const size_t __maxlen = 64; - char_type* __res = static_cast(__builtin_alloca(sizeof(char_type) * __maxlen)); + char_type* __res = static_cast(__builtin_alloca(sizeof(char_type) + * __maxlen)); // NB: In IEE 1003.1-200x, and perhaps other locale models, it // is possible that the format character will be longer than one @@ -2047,7 +2092,7 @@ namespace std __tp._M_put(__res, __maxlen, __fmt, __tm); // Write resulting, fully-formatted string to output iterator. - return __write(__s, __res, char_traits::length(__res)); + return std::__write(__s, __res, char_traits::length(__res)); } @@ -2075,16 +2120,16 @@ namespace std const string_type __two(__lo2, __hi2); const _CharT* __p = __one.c_str(); - const _CharT* __pend = __one.c_str() + __one.length(); + const _CharT* __pend = __one.data() + __one.length(); const _CharT* __q = __two.c_str(); - const _CharT* __qend = __two.c_str() + __two.length(); + const _CharT* __qend = __two.data() + __two.length(); // strcoll stops when it sees a nul character so we break // the strings into zero-terminated substrings and pass those // to strcoll. for (;;) { - int __res = _M_compare(__p, __q); + const int __res = _M_compare(__p, __q); if (__res) return __res; @@ -2102,7 +2147,7 @@ namespace std } } - template + template typename collate<_CharT>::string_type collate<_CharT>:: do_transform(const _CharT* __lo, const _CharT* __hi) const @@ -2111,7 +2156,7 @@ namespace std string_type __str(__lo, __hi); const _CharT* __p = __str.c_str(); - const _CharT* __pend = __str.c_str() + __str.length(); + const _CharT* __pend = __str.data() + __str.length(); size_t __len = (__hi - __lo) * 2; @@ -2146,7 +2191,7 @@ namespace std } } - template + template long collate<_CharT>:: do_hash(const _CharT* __lo, const _CharT* __hi) const @@ -2176,99 +2221,73 @@ namespace std const streamsize __newlen, const streamsize __oldlen, const bool __num) { - size_t __plen = static_cast(__newlen - __oldlen); - _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __plen)); - _Traits::assign(__pads, __plen, __fill); - - _CharT* __beg; - _CharT* __end; - size_t __mod = 0; - size_t __beglen; //either __plen or __oldlen - ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + const size_t __plen = static_cast(__newlen - __oldlen); + const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + // Padding last. if (__adjust == ios_base::left) { - // Padding last. - __beg = const_cast<_CharT*>(__olds); - __beglen = __oldlen; - __end = __pads; + _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); + _Traits::assign(__news + __oldlen, __plen, __fill); + return; } - else if (__adjust == ios_base::internal && __num) + + size_t __mod = 0; + if (__adjust == ios_base::internal && __num) { // Pad after the sign, if there is one. // Pad after 0[xX], if there is one. // Who came up with these rules, anyway? Jeeze. - locale __loc = __io.getloc(); + const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); const _CharT __minus = __ctype.widen('-'); const _CharT __plus = __ctype.widen('+'); - bool __testsign = _Traits::eq(__olds[0], __minus) - || _Traits::eq(__olds[0], __plus); + const bool __testsign = _Traits::eq(__olds[0], __minus) + || _Traits::eq(__olds[0], __plus); - bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0]) - && (_Traits::eq(__ctype.widen('x'), __olds[1]) - || _Traits::eq(__ctype.widen('X'), __olds[1])); + const bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0]) + && (_Traits::eq(__ctype.widen('x'), __olds[1]) + || _Traits::eq(__ctype.widen('X'), __olds[1])); if (__testhex) { __news[0] = __olds[0]; __news[1] = __olds[1]; - __mod += 2; + __mod = 2; __news += 2; - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds + __mod); } else if (__testsign) { - _Traits::eq((__news[0] = __olds[0]), __plus) ? __plus : __minus; - ++__mod; + __news[0] = __olds[0]; + __mod = 1; ++__news; - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds + __mod); } - else - { - // Padding first. - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds); - } - } - else - { - // Padding first. - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds); + // else Padding first. } - _Traits::copy(__news, __beg, __beglen); - _Traits::copy(__news + __beglen, __end, - __newlen - __beglen - __mod); + _Traits::assign(__news, __plen, __fill); + _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), + __oldlen - __mod); } template bool __verify_grouping(const basic_string<_CharT>& __grouping, - basic_string<_CharT>& __grouping_tmp) - { - int __i = 0; - int __j = 0; - const int __len = __grouping.size(); - const int __n = __grouping_tmp.size(); + const basic_string<_CharT>& __grouping_tmp) + { + const size_t __n = __grouping_tmp.size() - 1; + const size_t __min = std::min(__n, __grouping.size() - 1); + size_t __i = __n; bool __test = true; - + // Parsed number groupings have to match the // numpunct::grouping string exactly, starting at the // right-most point of the parsed sequence of elements ... - while (__test && __i < __n - 1) - for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i) - __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1]; + for (size_t __j = 0; __j < __min && __test; --__i, ++__j) + __test = __grouping_tmp[__i] == __grouping[__j]; + for (; __i && __test; --__i) + __test = __grouping_tmp[__i] == __grouping[__min]; // ... but the last parsed grouping can be <= numpunct // grouping. - __j == __len ? __j = 0 : __j; - __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1]; + __test &= __grouping_tmp[0] <= __grouping[__min]; return __test; } @@ -2279,13 +2298,13 @@ namespace std const _CharT* __first, const _CharT* __last) { if (__last - __first > *__gbeg) - { - __s = __add_grouping(__s, __sep, - (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1), - __gend, __first, __last - *__gbeg); - __first = __last - *__gbeg; - *__s++ = __sep; - } + { + const bool __bump = __gbeg + 1 != __gend; + __s = std::__add_grouping(__s, __sep, __gbeg + __bump, + __gend, __first, __last - *__gbeg); + __first = __last - *__gbeg; + *__s++ = __sep; + } do *__s++ = *__first++; while (__first != __last);