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
This commit is contained in:
Paolo Carlini 2004-11-03 01:05:08 +00:00
parent 36f4d1449c
commit e597a4d366
2 changed files with 91 additions and 76 deletions

View File

@ -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>

View File

@ -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;
}