}
}
- // 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
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()
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])
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
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
}
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)
}
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;
}
}
}
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;
}