diff options
Diffstat (limited to 'libstdc++-v3/include/bits/locale_facets.tcc')
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.tcc | 233 |
1 files changed, 120 insertions, 113 deletions
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 8bcb035a97e..ee5ea7d1def 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -325,7 +325,6 @@ namespace std __found_grouping.reserve(32); int __sep_pos = 0; const char_type* __lit_zero = __lit + __num_base::_S_izero; - const char_type* __q; while (__beg != __end) { // According to 22.2.2.1.2, p8-9, first look for thousands_sep @@ -368,40 +367,44 @@ namespace std else break; } - else if (__q = __traits_type::find(__lit_zero, 10, __c)) + else { - __xtrc += __num_base::_S_atoms_in[__q - __lit]; - __found_mantissa = true; - ++__sep_pos; - ++__beg; - } - else if ((__c == __lit[__num_base::_S_ie] - || __c == __lit[__num_base::_S_iE]) - && __found_mantissa && !__found_sci) - { - // Scientific notation. - if (__found_grouping.size() && !__found_dec) - __found_grouping += static_cast<char>(__sep_pos); - __xtrc += 'e'; - __found_sci = true; - - // Remove optional plus or minus sign, if they exist. - if (++__beg != __end) + const char_type* __q = __traits_type::find(__lit_zero, 10, __c); + if (__q) + { + __xtrc += __num_base::_S_atoms_in[__q - __lit]; + __found_mantissa = true; + ++__sep_pos; + ++__beg; + } + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && __found_mantissa && !__found_sci) { - const bool __plus = *__beg == __lit[__num_base::_S_iplus]; - if ((__plus || *__beg == __lit[__num_base::_S_iminus]) - && !(__lc->_M_use_grouping - && *__beg == __lc->_M_thousands_sep) - && !(*__beg == __lc->_M_decimal_point)) + // Scientific notation. + if (__found_grouping.size() && !__found_dec) + __found_grouping += static_cast<char>(__sep_pos); + __xtrc += 'e'; + __found_sci = true; + + // Remove optional plus or minus sign, if they exist. + if (++__beg != __end) { - __xtrc += __plus ? '+' : '-'; - ++__beg; + const bool __plus = *__beg == __lit[__num_base::_S_iplus]; + if ((__plus || *__beg == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep) + && !(*__beg == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } } } + else + // Not a valid input item. + break; } - else - // Not a valid input item. - break; } // Digit grouping is checked. If grouping and found_grouping don't @@ -508,7 +511,6 @@ namespace std bool __overflow = false; _ValueT __result = 0; const char_type* __lit_zero = __lit + __num_base::_S_izero; - const char_type* __q; if (__negative) { const _ValueT __min = numeric_limits<_ValueT>::min() / __base; @@ -534,26 +536,31 @@ namespace std } else if (__c == __lc->_M_decimal_point) break; - else if (__q = __traits_type::find(__lit_zero, __len, __c)) + else { - int __digit = __q - __lit_zero; - if (__digit > 15) - __digit -= 6; - if (__result < __min) - __overflow = true; - else + const char_type* __q = __traits_type::find(__lit_zero, + __len, __c); + if (__q) { - const _ValueT __new_result = __result * __base - - __digit; - __overflow |= __new_result > __result; - __result = __new_result; - ++__sep_pos; - __found_num = true; + int __digit = __q - __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 - // Not a valid input item. - break; } } else @@ -577,25 +584,30 @@ namespace std } else if (__c == __lc->_M_decimal_point) break; - else if (__q = __traits_type::find(__lit_zero, __len, __c)) + else { - int __digit = __q - __lit_zero; - if (__digit > 15) - __digit -= 6; - if (__result > __max) - __overflow = true; - else + const char_type* __q = __traits_type::find(__lit_zero, + __len, __c); + if (__q) { - const _ValueT __new_result = __result * __base - + __digit; - __overflow |= __new_result < __result; - __result = __new_result; - ++__sep_pos; - __found_num = true; + int __digit = __q - __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; } - else - break; } } @@ -1049,29 +1061,20 @@ namespace std 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 - // chosen inside _S_format_float, the precision field is "the - // maximum number of significant digits", *not* the "number of - // digits to appear after the decimal point", as happens for - // %{e,E,f,F} (C99, 7.19.6.1,4). - const int __max_digits = numeric_limits<_ValueT>::digits10 + 2; - // Use default precision if out of range. streamsize __prec = __io.precision(); - if (__prec > static_cast<streamsize>(__max_digits)) - __prec = static_cast<streamsize>(__max_digits); - else if (__prec < static_cast<streamsize>(0)) + if (__prec < static_cast<streamsize>(0)) __prec = static_cast<streamsize>(6); + const int __max_digits = numeric_limits<_ValueT>::digits10; + // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; // Long enough for the max format spec. char __fbuf[16]; #ifdef _GLIBCXX_USE_C99 - // First try a buffer perhaps big enough (for sure sufficient + // First try a buffer perhaps big enough (most probably sufficient // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); @@ -1094,13 +1097,13 @@ namespace std 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 - // the other hand, for non-fixed outputs __max_digits*3 chars - // are largely sufficient. - const int __cs_size = __fixed ? __max_exp + __max_digits + 4 - : __max_digits * 3; + // ios_base::fixed outputs may need up to __max_exp + 1 chars + // for the integer part + __prec chars for the fractional part + // + 3 chars for sign, decimal point, '\0'. On the other hand, + // for non-fixed outputs __max_digits * 2 + __prec chars are + // largely sufficient. + const int __cs_size = __fixed ? __max_exp + __prec + 4 + : __max_digits * 2 + __prec; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); __num_base::_S_format_float(__io, __fbuf, __mod); @@ -1119,8 +1122,8 @@ namespace std // Replace decimal point. const _CharT __cdec = __ctype.widen('.'); const _CharT __dec = __lc->_M_decimal_point; - const _CharT* __p; - if (__p = char_traits<_CharT>::find(__ws, __len, __cdec)) + const _CharT* __p = char_traits<_CharT>::find(__ws, __len, __cdec); + if (__p) __ws[__p - __ws] = __dec; // Add grouping, if necessary. @@ -1294,7 +1297,6 @@ namespace std __res.reserve(32); const char_type* __lit_zero = __lit + money_base::_S_zero; - const char_type* __q; const money_base::pattern __p = __lc->_M_neg_format; for (int __i = 0; __i < 4 && __testvalid; ++__i) { @@ -1356,35 +1358,40 @@ namespace std // Extract digits, remove and stash away the // grouping of found thousands separators. for (; __beg != __end; ++__beg) - if (__q = __traits_type::find(__lit_zero, 10, *__beg)) - { - __res += money_base::_S_atoms[__q - __lit]; - ++__n; - } - else if (*__beg == __lc->_M_decimal_point && !__testdecfound) - { - __last_pos = __n; - __n = 0; - __testdecfound = true; - } - else if (__lc->_M_use_grouping - && *__beg == __lc->_M_thousands_sep - && !__testdecfound) - { - if (__n) - { - // Mark position for later analysis. - __grouping_tmp += static_cast<char>(__n); - __n = 0; - } - else - { - __testvalid = false; - break; - } - } - else - break; + { + const char_type* __q = __traits_type::find(__lit_zero, + 10, *__beg); + if (__q != 0) + { + __res += money_base::_S_atoms[__q - __lit]; + ++__n; + } + else if (*__beg == __lc->_M_decimal_point + && !__testdecfound) + { + __last_pos = __n; + __n = 0; + __testdecfound = true; + } + else if (__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep + && !__testdecfound) + { + if (__n) + { + // Mark position for later analysis. + __grouping_tmp += static_cast<char>(__n); + __n = 0; + } + else + { + __testvalid = false; + break; + } + } + else + break; + } if (__res.empty()) __testvalid = false; break; |