Commit e597a4d3 by Paolo Carlini

locale_facets.tcc (num_get<>::_M_extract_int): Evaluate *__beg the exact strict…

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
parent 36f4d144
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> 2004-11-02 Benjamin Kosnik <bkoz@redhat.com>
Lothar Werzinger <lothar@xcerla.com> Lothar Werzinger <lothar@xcerla.com>
......
...@@ -301,10 +301,8 @@ namespace std ...@@ -301,10 +301,8 @@ namespace std
} }
} }
// True if a mantissa is found.
bool __found_mantissa = false;
// Next, look for leading zeros. // Next, look for leading zeros.
bool __found_mantissa = false;
while (!__testeof) while (!__testeof)
{ {
if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
...@@ -452,6 +450,7 @@ namespace std ...@@ -452,6 +450,7 @@ namespace std
const locale& __loc = __io._M_getloc(); const locale& __loc = __io._M_getloc();
const __cache_type* __lc = __uc(__loc); const __cache_type* __lc = __uc(__loc);
const _CharT* __lit = __lc->_M_atoms_in; const _CharT* __lit = __lc->_M_atoms_in;
char_type __c = char_type();
// NB: Iff __basefield == 0, __base can change based on contents. // NB: Iff __basefield == 0, __base can change based on contents.
const ios_base::fmtflags __basefield = __io.flags() const ios_base::fmtflags __basefield = __io.flags()
...@@ -459,37 +458,39 @@ namespace std ...@@ -459,37 +458,39 @@ namespace std
const bool __oct = __basefield == ios_base::oct; const bool __oct = __basefield == ios_base::oct;
int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
// True if numeric digits are found. // True if __beg becomes equal to __end.
bool __found_num = false; bool __testeof = __beg == __end;
// First check for sign. // First check for sign.
bool __negative = false; bool __negative = false;
if (__beg != __end) if (!__testeof)
{ {
const char_type __c = *__beg; __c = *__beg;
if (numeric_limits<_ValueT>::is_signed) if (numeric_limits<_ValueT>::is_signed)
__negative = __c == __lit[__num_base::_S_iminus]; __negative = __c == __lit[__num_base::_S_iminus];
if ((__negative || __c == __lit[__num_base::_S_iplus]) if ((__negative || __c == __lit[__num_base::_S_iplus])
&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
&& !(__c == __lc->_M_decimal_point)) && !(__c == __lc->_M_decimal_point))
++__beg; {
if (++__beg != __end)
__c = *__beg;
else
__testeof = true;
}
} }
// Next, look for leading zeros and check required digits // Next, look for leading zeros and check required digits
// for base formats. // 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 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
|| __c == __lc->_M_decimal_point) || __c == __lc->_M_decimal_point)
break; break;
else if (__c == __lit[__num_base::_S_izero] else if (__c == __lit[__num_base::_S_izero]
&& (!__found_num || __base == 10)) && (!__found_zero || __base == 10))
{ __found_zero = true;
__found_num = true; else if (__found_zero)
++__beg;
}
else if (__found_num)
{ {
if (__c == __lit[__num_base::_S_ix] if (__c == __lit[__num_base::_S_ix]
|| __c == __lit[__num_base::_S_iX]) || __c == __lit[__num_base::_S_iX])
...@@ -497,17 +498,28 @@ namespace std ...@@ -497,17 +498,28 @@ namespace std
if (__basefield == 0) if (__basefield == 0)
__base = 16; __base = 16;
if (__base == 16) if (__base == 16)
{ __found_zero = false;
__found_num = false; else
++__beg; break;
}
} }
else if (__basefield == 0) else
{
if (__basefield == 0)
__base = 8; __base = 8;
break; break;
} }
}
else else
break; break;
if (++__beg != __end)
{
__c = *__beg;
if (!__found_zero)
break;
}
else
__testeof = true;
} }
// At this point, base is determined. If not hex, only allow // At this point, base is determined. If not hex, only allow
...@@ -522,15 +534,15 @@ namespace std ...@@ -522,15 +534,15 @@ namespace std
int __sep_pos = 0; int __sep_pos = 0;
bool __overflow = false; bool __overflow = false;
_ValueT __result = 0; _ValueT __result = 0;
const char_type* __q;
const char_type* __lit_zero = __lit + __num_base::_S_izero; const char_type* __lit_zero = __lit + __num_base::_S_izero;
if (__negative) if (__negative)
{ {
const _ValueT __min = numeric_limits<_ValueT>::min() / __base; 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 // According to 22.2.2.1.2, p8-9, first look for thousands_sep
// and decimal_point. // and decimal_point.
const char_type __c = *__beg;
if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
{ {
// NB: Thousands separator at the beginning of a string // NB: Thousands separator at the beginning of a string
...@@ -548,11 +560,7 @@ namespace std ...@@ -548,11 +560,7 @@ namespace std
} }
else if (__c == __lc->_M_decimal_point) else if (__c == __lc->_M_decimal_point)
break; 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; int __digit = __q - __lit_zero;
if (__digit > 15) if (__digit > 15)
...@@ -566,21 +574,23 @@ namespace std ...@@ -566,21 +574,23 @@ namespace std
__overflow |= __new_result > __result; __overflow |= __new_result > __result;
__result = __new_result; __result = __new_result;
++__sep_pos; ++__sep_pos;
__found_num = true;
} }
} }
else else
// Not a valid input item. // Not a valid input item.
break; break;
}
if (++__beg != __end)
__c = *__beg;
else
__testeof = true;
} }
} }
else else
{ {
const _ValueT __max = numeric_limits<_ValueT>::max() / __base; 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 (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
{ {
if (__sep_pos) if (__sep_pos)
...@@ -596,11 +606,7 @@ namespace std ...@@ -596,11 +606,7 @@ namespace std
} }
else if (__c == __lc->_M_decimal_point) else if (__c == __lc->_M_decimal_point)
break; 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; int __digit = __q - __lit_zero;
if (__digit > 15) if (__digit > 15)
...@@ -614,12 +620,15 @@ namespace std ...@@ -614,12 +620,15 @@ namespace std
__overflow |= __new_result < __result; __overflow |= __new_result < __result;
__result = __new_result; __result = __new_result;
++__sep_pos; ++__sep_pos;
__found_num = true;
} }
} }
else else
break; break;
}
if (++__beg != __end)
__c = *__beg;
else
__testeof = true;
} }
} }
...@@ -637,12 +646,12 @@ namespace std ...@@ -637,12 +646,12 @@ namespace std
} }
if (!(__err & ios_base::failbit) && !__overflow if (!(__err & ios_base::failbit) && !__overflow
&& __found_num) && (__sep_pos || __found_zero || __found_grouping.size()))
__v = __result; __v = __result;
else else
__err |= ios_base::failbit; __err |= ios_base::failbit;
if (__beg == __end) if (__testeof)
__err |= ios_base::eofbit; __err |= ios_base::eofbit;
return __beg; return __beg;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment