Fix gcc werrors

This commit is contained in:
Maya Warrier 2023-12-11 04:40:08 -05:00
parent c9527c2e4f
commit 3d446f1eba
4 changed files with 30 additions and 15 deletions

View File

@ -445,11 +445,11 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value, int base)
{
from_chars_result_t<UC> answer;
answer.ec = std::errc::invalid_argument;
answer.ptr = p;
bool negative = (*p == UC('-'));
if (!std::is_signed<T>::value && negative) {
answer.ec = std::errc::invalid_argument;
answer.ptr = p;
return answer;
}
#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
@ -473,14 +473,16 @@ from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value,
if (digit > base) {
break;
}
i = base * i + digit; // might overflow, check this later
i = uint64_t(base) * i + digit; // might overflow, check this later
p++;
}
size_t digit_count = size_t(p - start_digits);
answer.ec = std::errc::result_out_of_range;
answer.ptr = p;
// check u64 overflow
constexpr int max_digits = max_digits_u64(base);
size_t max_digits = max_digits_u64(base);
if (digit_count == 0 || digit_count > max_digits) {
return answer;
}
@ -495,8 +497,19 @@ from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value,
return answer;
}
}
return negative ? (~i + 1) : i;
if (negative) {
// this weird workaround is required because:
// - converting unsigned to signed when its value is greater than signed max is UB pre-C++23.
// - reinterpret_cast<T>(~i + 1) would have worked, but it is not constexpr
// this should be optimized away.
value = -std::numeric_limits<T>::max() -
static_cast<T>(i - std::numeric_limits<T>::max());
}
else value = T(i);
answer.ec = std::errc();
return answer;
}
} // namespace fast_float

View File

@ -40,6 +40,7 @@ from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
* from_chars for integer types.
*/
template <typename T, typename UC = char, typename = FASTFLOAT_ENABLE_IF(!is_supported_float_type<T>())>
FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> from_chars(UC const * first, UC const * last, T& value, int base = 10) noexcept;
} // namespace fast_float

View File

@ -711,7 +711,7 @@ struct int_luts {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
};
static constexpr int maxdigits_u64[] = {
static constexpr size_t maxdigits_u64[] = {
64, 41, 32, 28, 25, 23, 22, 21,
20, 19, 18, 18, 17, 17, 16, 16,
16, 16, 15, 15, 15, 15, 14, 14,
@ -720,12 +720,12 @@ struct int_luts {
};
static constexpr uint64_t min_safe_u64[] = {
9223372036854775808, 12157665459056928801, 4611686018427387904, 7450580596923828125, 4738381338321616896,
3909821048582988049, 9223372036854775808, 12157665459056928801, 10000000000000000000, 5559917313492231481,
9223372036854775808ull, 12157665459056928801ull, 4611686018427387904, 7450580596923828125, 4738381338321616896,
3909821048582988049, 9223372036854775808ull, 12157665459056928801ull, 10000000000000000000ull, 5559917313492231481,
2218611106740436992, 8650415919381337933, 2177953337809371136, 6568408355712890625, 1152921504606846976,
2862423051509815793, 6746640616477458432, 15181127029874798299, 1638400000000000000, 3243919932521508681,
6221821273427820544, 11592836324538749809, 876488338465357824, 1490116119384765625, 2481152873203736576,
4052555153018976267, 6502111422497947648, 10260628712958602189, 15943230000000000000, 787662783788549761,
2862423051509815793, 6746640616477458432, 15181127029874798299ull, 1638400000000000000, 3243919932521508681,
6221821273427820544, 11592836324538749809ull, 876488338465357824, 1490116119384765625, 2481152873203736576,
4052555153018976267, 6502111422497947648, 10260628712958602189ull, 15943230000000000000ull, 787662783788549761,
1152921504606846976, 1667889514952984961, 2386420683693101056, 3379220508056640625, 4738381338321616896
};
};
@ -734,7 +734,7 @@ template <typename T>
constexpr uint8_t int_luts<T>::chdigit[];
template <typename T>
constexpr int int_luts<T>::maxdigits_u64[];
constexpr size_t int_luts<T>::maxdigits_u64[];
template <typename T>
constexpr uint64_t int_luts<T>::min_safe_u64[];
@ -744,7 +744,7 @@ fastfloat_really_inline
constexpr uint8_t ch_to_digit(UC c) { return int_luts<>::chdigit[c]; }
fastfloat_really_inline
constexpr int max_digits_u64(int base) { return int_luts<>::maxdigits_u64[base - 2]; }
constexpr size_t max_digits_u64(int base) { return int_luts<>::maxdigits_u64[base - 2]; }
// If a u64 is exactly max_digits_u64() in length, this is
// the value below which it has definitely overflowed.

View File

@ -231,6 +231,7 @@ from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
template <typename T, typename UC, typename>
FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> from_chars(UC const* first, UC const* last, T& value, int base) noexcept
{
static_assert (is_supported_char_type<UC>(), "only char, wchar_t, char16_t and char32_t are supported");
@ -246,7 +247,7 @@ from_chars_result_t<UC> from_chars(UC const* first, UC const* last, T& value, in
answer.ptr = first;
return answer;
}
return parse_int_string(first, last, base);
return parse_int_string(first, last, value, base);
}
} // namespace fast_float