From e597a4d366844db62a57cc385aedb1e8dff266b5 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 3 Nov 2004 01:05:08 +0000 Subject: [PATCH] locale_facets.tcc (num_get<>::_M_extract_int): Evaluate *__beg the exact strict minimum number of times... 2004-11-02 Paolo Carlini * include/bits/locale_facets.tcc (num_get<>::_M_extract_int): Evaluate *__beg the exact strict minimum number of times; likewise for __beg != __end; slightly simplify main parsing loop. From-SVN: r90012 --- libstdc++-v3/ChangeLog | 12 +- libstdc++-v3/include/bits/locale_facets.tcc | 155 +++++++++++--------- 2 files changed, 91 insertions(+), 76 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index dbbbea99113..9063603c0a2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2004-11-02 Paolo Carlini + + * include/bits/locale_facets.tcc (num_get<>::_M_extract_int): + Evaluate *__beg the exact strict minimum number of times; likewise + for __beg != __end; slightly simplify main parsing loop. + 2004-11-02 Benjamin Kosnik Lothar Werzinger @@ -34,9 +40,9 @@ 2004-11-01 Chris Jefferson - PR libstdc++/18159 - * include/tr1/tuple (get(pair)): Change occurrences of _I to _Int. - (get(const pair)): Likewise. + PR libstdc++/18159 + * include/tr1/tuple (get(pair)): Change occurrences of _I to _Int. + (get(const pair)): Likewise. 2004-11-01 Paolo Carlini diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 0f92db205a1..c32a65da765 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -301,10 +301,8 @@ namespace std } } - // True if a mantissa is found. - bool __found_mantissa = false; - // Next, look for leading zeros. + bool __found_mantissa = false; while (!__testeof) { if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep @@ -452,6 +450,7 @@ namespace std const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __lit = __lc->_M_atoms_in; + char_type __c = char_type(); // NB: Iff __basefield == 0, __base can change based on contents. const ios_base::fmtflags __basefield = __io.flags() @@ -459,37 +458,39 @@ namespace std 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; + // True if __beg becomes equal to __end. + bool __testeof = __beg == __end; // First check for sign. bool __negative = false; - if (__beg != __end) + if (!__testeof) { - const char_type __c = *__beg; + __c = *__beg; if (numeric_limits<_ValueT>::is_signed) __negative = __c == __lit[__num_base::_S_iminus]; if ((__negative || __c == __lit[__num_base::_S_iplus]) && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) && !(__c == __lc->_M_decimal_point)) - ++__beg; + { + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; + } } // Next, look for leading zeros and check required digits // for base formats. - while (__beg != __end) + bool __found_zero = false; + while (!__testeof) { - const char_type __c = *__beg; if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep || __c == __lc->_M_decimal_point) break; else if (__c == __lit[__num_base::_S_izero] - && (!__found_num || __base == 10)) - { - __found_num = true; - ++__beg; - } - else if (__found_num) + && (!__found_zero || __base == 10)) + __found_zero = true; + else if (__found_zero) { if (__c == __lit[__num_base::_S_ix] || __c == __lit[__num_base::_S_iX]) @@ -497,19 +498,30 @@ namespace std if (__basefield == 0) __base = 16; if (__base == 16) - { - __found_num = false; - ++__beg; - } + __found_zero = false; + else + break; + } + else + { + if (__basefield == 0) + __base = 8; + break; } - else if (__basefield == 0) - __base = 8; - break; } else break; - } + if (++__beg != __end) + { + __c = *__beg; + if (!__found_zero) + break; + } + else + __testeof = true; + } + // At this point, base is determined. If not hex, only allow // base digits as valid input. const size_t __len = (__base == 16 ? __num_base::_S_iend @@ -522,15 +534,15 @@ namespace std int __sep_pos = 0; bool __overflow = false; _ValueT __result = 0; + const char_type* __q; const char_type* __lit_zero = __lit + __num_base::_S_izero; if (__negative) { const _ValueT __min = numeric_limits<_ValueT>::min() / __base; - for (; __beg != __end; ++__beg) + while (!__testeof) { // 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 && __c == __lc->_M_thousands_sep) { // NB: Thousands separator at the beginning of a string @@ -548,39 +560,37 @@ namespace std } else if (__c == __lc->_M_decimal_point) break; - else + else if ((__q = __traits_type::find(__lit_zero, __len, __c))) { - const char_type* __q = __traits_type::find(__lit_zero, - __len, __c); - if (__q) - { - 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; - } - } + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result < __min) + __overflow = true; else - // Not a valid input item. - break; + { + const _ValueT __new_result = (__result * __base + - __digit); + __overflow |= __new_result > __result; + __result = __new_result; + ++__sep_pos; + } } + else + // Not a valid input item. + break; + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; } } else { const _ValueT __max = numeric_limits<_ValueT>::max() / __base; - for (; __beg != __end; ++__beg) + while (!__testeof) { - const char_type __c = *__beg; if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) { if (__sep_pos) @@ -596,30 +606,29 @@ namespace std } else if (__c == __lc->_M_decimal_point) break; - else + else if ((__q = __traits_type::find(__lit_zero, __len, __c))) { - const char_type* __q = __traits_type::find(__lit_zero, - __len, __c); - if (__q) - { - 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; - } - } + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __max) + __overflow = true; else - break; + { + const _ValueT __new_result = (__result * __base + + __digit); + __overflow |= __new_result < __result; + __result = __new_result; + ++__sep_pos; + } } + else + break; + + if (++__beg != __end) + __c = *__beg; + else + __testeof = true; } } @@ -637,12 +646,12 @@ namespace std } if (!(__err & ios_base::failbit) && !__overflow - && __found_num) + && (__sep_pos || __found_zero || __found_grouping.size())) __v = __result; else __err |= ios_base::failbit; - if (__beg == __end) + if (__testeof) __err |= ios_base::eofbit; return __beg; }