aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo@gcc.gnu.org>2004-11-03 01:05:08 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2004-11-03 01:05:08 +0000
commite597a4d366844db62a57cc385aedb1e8dff266b5 (patch)
tree8278f7b33c552baf8aba4a1ea1e9deecbd183969
parent36f4d1449ca5c83321e28cdffaf0182373b1e8d7 (diff)
downloadgcc-e597a4d366844db62a57cc385aedb1e8dff266b5.zip
gcc-e597a4d366844db62a57cc385aedb1e8dff266b5.tar.gz
gcc-e597a4d366844db62a57cc385aedb1e8dff266b5.tar.bz2
locale_facets.tcc (num_get<>::_M_extract_int): Evaluate *__beg the exact strict minimum number of times...
2004-11-02 Paolo Carlini <pcarlini@suse.de> * 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
-rw-r--r--libstdc++-v3/ChangeLog12
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc151
2 files changed, 89 insertions, 74 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index dbbbea9..9063603 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2004-11-02 Paolo Carlini <pcarlini@suse.de>
+
+ * 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 <bkoz@redhat.com>
Lothar Werzinger <lothar@xcerla.com>
@@ -34,9 +40,9 @@
2004-11-01 Chris Jefferson <chris@bubblescope.net>
- 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 <pcarlini@suse.de>
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 0f92db2..c32a65d 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
{
- 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;
- }
+ const _ValueT __new_result = (__result * __base
+ - __digit);
+ __overflow |= __new_result > __result;
+ __result = __new_result;
+ ++__sep_pos;
}
- else
- // Not a valid input item.
- break;
}
+ 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
{
- 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;
- }
+ const _ValueT __new_result = (__result * __base
+ + __digit);
+ __overflow |= __new_result < __result;
+ __result = __new_result;
+ ++__sep_pos;
}
- else
- break;
}
+ 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;
}