diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index 3dc8b43..5c82c6c 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "float_common.h" @@ -462,11 +463,6 @@ from_chars_result_t parse_int_string(UC const* p, UC const* pend, T& value, ++p; } - // skip leading zeros - while (p != pend && *p == UC('0')) { - ++p; - } - UC const* const start_digits = p; uint64_t i = 0; @@ -512,10 +508,9 @@ from_chars_result_t parse_int_string(UC const* p, UC const* pend, T& value, 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(~i + 1) would have worked, but it is not constexpr - // this should be optimized away. - value = -std::numeric_limits::max() - - static_cast(i - std::numeric_limits::max()); + // - reinterpret_casting (~i + 1) would work, but it is not constexpr + // this is always optimized into a neg instruction. + value = T(-std::numeric_limits::max() - T(i - std::numeric_limits::max())); } else value = T(i); diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 0721d12..3595491 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -741,7 +741,7 @@ constexpr uint64_t int_luts::min_safe_u64[]; template fastfloat_really_inline -constexpr uint8_t ch_to_digit(UC c) { return int_luts<>::chdigit[c]; } +constexpr uint8_t ch_to_digit(UC c) { return int_luts<>::chdigit[static_cast(c)]; } fastfloat_really_inline constexpr size_t max_digits_u64(int base) { return int_luts<>::maxdigits_u64[base - 2]; }