code cleanup and type usage fixes.

This commit is contained in:
IRainman 2025-12-27 15:42:58 +03:00
parent 22605807b8
commit fb1e92c0e2
6 changed files with 92 additions and 81 deletions

View File

@ -602,9 +602,9 @@ parse_int_string(UC const *p, UC const *pend, T &value,
((digits.as_int + 0x46464646u) | (digits.as_int - 0x30303030u)) &
0x80808080u;
const auto tz =
static_cast<uint32_t>(countr_zero_32(magic)); // 7, 15, 23, 31, or 32
uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
nd = std::min(static_cast<uint32_t>(nd), len);
static_cast<am_digits>(countr_zero_32(magic)); // 7, 15, 23, 31, or 32
am_digits nd = (tz == 32) ? 4 : (tz >> 3);
nd = std::min(nd, len);
if (nd == 0) {
if (has_leading_zeros) {
value = 0;
@ -618,7 +618,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
}
if (nd > 3) {
const UC *q = p + nd;
uint_fast8_t rem = len - nd;
am_digits rem = len - nd;
while (rem) {
if (*q < UC('0') || *q > UC('9'))
break;

View File

@ -41,7 +41,7 @@ constexpr limb_t bigint_limbs = bigint_bits / limb_bits;
template <limb_t size> struct stackvec {
limb data[size];
// we never need more than 150 limbs
uint_fast8_t length{0};
limb_t length{0};
FASTFLOAT_CONSTEXPR20 stackvec() noexcept = default;
stackvec(stackvec const &) = delete;
@ -100,7 +100,7 @@ template <limb_t size> struct stackvec {
FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept {
limb *ptr = data + length;
std::copy_n(s.ptr, s.len(), ptr);
set_len(limb_t(len() + s.len()));
set_len(static_cast<limb_t>(len() + s.len()));
}
// try to add items to the vector, returning if items were added
@ -123,17 +123,20 @@ template <limb_t size> struct stackvec {
limb *first = data + len();
limb *last = first + count;
::std::fill(first, last, value);
set_len(new_len);
} else {
set_len(new_len);
}
set_len(new_len);
}
// try to resize the vector, returning if the vector was resized.
FASTFLOAT_CONSTEXPR20 bool try_resize(limb_t new_len, limb value) noexcept {
if (new_len > capacity()) {
return false;
} else {
resize_unchecked(new_len, value);
return true;
}
resize_unchecked(new_len, value);
return true;
}
// check if any limbs are non-zero after the given index.
@ -259,9 +262,10 @@ inline FASTFLOAT_CONSTEXPR20 bool small_add_from(stackvec<size> &vec, limb y,
limb_t start) noexcept {
limb carry = y;
bool overflow;
while (carry != 0 && start++ != vec.len()) {
while (carry != 0 && start < vec.len()) {
vec[start] = scalar_add(vec[start], carry, overflow);
carry = limb(overflow);
++start;
}
if (carry != 0) {
FASTFLOAT_TRY(vec.try_push(carry));
@ -297,8 +301,8 @@ FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec<size> &x, limb_span y,
limb_t start) noexcept {
// the effective x buffer is from `xstart..x.len()`, so exit early
// if we can't get that current range.
if (x.len() < start || y.len() > limb_t(x.len() - start)) {
FASTFLOAT_TRY(x.try_resize(limb_t(y.len() + start), 0));
if (x.len() < start || y.len() > static_cast<limb_t>(x.len() - start)) {
FASTFLOAT_TRY(x.try_resize(static_cast<limb_t>(y.len() + start), 0));
}
bool carry = false;
@ -317,7 +321,7 @@ FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec<size> &x, limb_span y,
// handle overflow
if (carry) {
FASTFLOAT_TRY(small_add_from(x, 1, limb_t(y.len() + start)));
FASTFLOAT_TRY(small_add_from(x, 1, static_cast<limb_t>(y.len() + start)));
}
return true;
}
@ -369,7 +373,7 @@ FASTFLOAT_CONSTEXPR20 bool large_mul(stackvec<size> &x, limb_span y) noexcept {
}
template <typename = void> struct pow5_tables {
static constexpr uint_fast8_t large_step = 135;
static constexpr limb_t large_step = 135;
static constexpr uint64_t small_power_of_5[] = {
1UL,
5UL,
@ -413,7 +417,7 @@ template <typename = void> struct pow5_tables {
#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
template <typename T> constexpr uint_fast8_t pow5_tables<T>::large_step;
template <typename T> constexpr limb_t pow5_tables<T>::large_step;
template <typename T> constexpr uint64_t pow5_tables<T>::small_power_of_5[];
@ -487,7 +491,7 @@ struct bigint : pow5_tables<> {
} else if (vec.len() < other.vec.len()) {
return -1;
} else {
for (limb_t index = vec.len(); index != 0; --index) {
for (limb_t index = vec.len(); index > 0; --index) {
limb xi = vec[index - 1];
limb yi = other.vec[index - 1];
if (xi > yi) {
@ -502,7 +506,7 @@ struct bigint : pow5_tables<> {
// shift left each limb n bits, carrying over to the new limb
// returns true if we were able to shift all the digits.
FASTFLOAT_CONSTEXPR20 bool shl_bits(bigint_bits_t n) noexcept {
FASTFLOAT_CONSTEXPR20 bool shl_bits(limb_t n) noexcept {
// Internally, for each item, we shift left by n, and add the previous
// right shifted limb-bits.
// For example, we transform (for u8) shifted left 2, to:
@ -511,10 +515,10 @@ struct bigint : pow5_tables<> {
FASTFLOAT_DEBUG_ASSERT(n != 0);
FASTFLOAT_DEBUG_ASSERT(n < sizeof(limb) * 8);
bigint_bits_t const shl = n;
bigint_bits_t const shr = limb_bits - shl;
limb_t const shl = n;
limb_t const shr = limb_bits - shl;
limb prev = 0;
for (limb_t index = 0; index != vec.len(); ++index) {
for (limb_t index = 0; index < vec.len(); ++index) {
limb xi = vec[index];
vec[index] = (xi << shl) | (prev >> shr);
prev = xi;
@ -528,13 +532,12 @@ struct bigint : pow5_tables<> {
}
// move the limbs left by `n` limbs.
FASTFLOAT_CONSTEXPR20 bool shl_limbs(bigint_bits_t n) noexcept {
FASTFLOAT_CONSTEXPR20 bool shl_limbs(limb_t n) noexcept {
FASTFLOAT_DEBUG_ASSERT(n != 0);
if (n + vec.len() > vec.capacity()) {
// we can't shift more than the capacity of the vector.
return false;
}
if (!vec.is_empty()) {
} else if (!vec.is_empty()) {
// move limbs
limb *dst = vec.data + n;
limb const *src = vec.data;
@ -543,15 +546,17 @@ struct bigint : pow5_tables<> {
limb *first = vec.data;
limb *last = first + n;
::std::fill(first, last, 0);
vec.set_len(limb_t(n + vec.len()));
vec.set_len(n + vec.len());
return true;
} else {
return true;
}
return true;
}
// move the limbs left by `n` bits.
FASTFLOAT_CONSTEXPR20 bool shl(bigint_bits_t n) noexcept {
bigint_bits_t const rem = n % limb_bits;
bigint_bits_t const div = n / limb_bits;
auto const rem = static_cast<limb_t>(n % limb_bits);
auto const div = static_cast<limb_t>(n / limb_bits);
if (rem != 0) {
FASTFLOAT_TRY(shl_bits(rem));
}
@ -566,14 +571,15 @@ struct bigint : pow5_tables<> {
if (vec.is_empty()) {
// empty vector, no bits, no zeros.
return 0;
}
} else {
#ifdef FASTFLOAT_64BIT_LIMB
return leading_zeroes(vec.rindex(0));
return leading_zeroes(vec.rindex(0));
#else
// no use defining a specialized leading_zeroes for a 32-bit type.
uint64_t r0 = vec.rindex(0);
return leading_zeroes(r0 << 32);
// no use defining a specialized leading_zeroes for a 32-bit type.
uint64_t r0 = vec.rindex(0);
return leading_zeroes(r0 << 32);
#endif
}
}
// get the number of bits in the bigint.

View File

@ -72,7 +72,7 @@ constexpr fastfloat_really_inline am_pow_t power(am_pow_t q) noexcept {
template <typename binary>
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 adjusted_mantissa
compute_error_scaled(int64_t q, uint64_t w, limb_t lz) noexcept {
limb_t const hilz = static_cast<limb_t>((w >> 63) ^ 1);
auto const hilz = static_cast<limb_t>((w >> 63) ^ 1);
adjusted_mantissa answer;
answer.mantissa = w << hilz;
constexpr am_pow_t bias =
@ -139,9 +139,8 @@ compute_float(int64_t q, uint64_t w) noexcept {
// branchless approach: value128 product = compute_product(q, w); but in
// practice, we can win big with the compute_product_approximation if its
// additional branch is easily predicted. Which is best is data specific.
auto const upperbit = limb_t(product.high >> 63);
auto const shift =
limb_t(upperbit + 64 - binary::mantissa_explicit_bits() - 3);
limb_t const upperbit = static_cast<limb_t>(product.high >> 63);
limb_t const shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3;
answer.mantissa = product.high >> shift;

View File

@ -139,7 +139,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void
round_nearest_tie_even(adjusted_mantissa &am, am_pow_t shift,
callback cb) noexcept {
am_mant_t const mask =
(shift == 64) ? UINT64_MAX : (am_mant_t(1) << shift) - 1;
(shift == 64) ? std::numeric_limits<am_mant_t>::max() : (am_mant_t(1) << shift) - 1;
am_mant_t const halfway = (shift == 0) ? 0 : am_mant_t(1) << (shift - 1);
am_mant_t truncated_bits = am.mantissa & mask;
bool is_above = truncated_bits > halfway;

View File

@ -41,6 +41,8 @@ typedef uint_fast8_t limb_t;
typedef uint_fast8_t chars_format_t;
typedef uint_fast8_t base_t;
enum class chars_format : chars_format_t;
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
@ -82,7 +84,7 @@ using from_chars_result = from_chars_result_t<char>;
template <typename UC> struct parse_options_t {
constexpr explicit parse_options_t(
chars_format const fmt = chars_format::general, UC const dot = UC('.'),
uint_fast8_t const b = 10) noexcept
base_t const b = 10) noexcept
: format(fmt), decimal_point(dot), base(b) {}
/** Which number formats are accepted */
@ -90,7 +92,7 @@ template <typename UC> struct parse_options_t {
/** The character used as decimal point */
UC decimal_point;
/** The base used for integers */
uint_fast8_t base; /* only allowed from 2 to 36 */
base_t base; /* only allowed from 2 to 36 */
};
using parse_options = parse_options_t<char>;
@ -298,6 +300,10 @@ struct is_supported_char_type
};
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
// TODO use SSE4.2 there when SSE2 compiler switch in MSVC
// or in other compiler SSE4.2 available.
// Compares two ASCII strings in a case insensitive manner.
template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
@ -320,16 +326,17 @@ fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
// a pointer and a length to a contiguous block of memory
template <typename T> struct span {
T const *ptr;
am_digits length;
uint_fast16_t length;
constexpr span(T const *_ptr, am_digits _length) noexcept
constexpr span(T const *_ptr, uint_fast16_t _length) noexcept
: ptr(_ptr), length(_length) {}
constexpr span() noexcept : ptr(nullptr), length(0) {}
constexpr am_digits len() const noexcept { return length; }
constexpr uint_fast16_t len() const noexcept { return length; }
FASTFLOAT_CONSTEXPR14 const T &operator[](am_digits index) const noexcept {
FASTFLOAT_CONSTEXPR14 const T &
operator[](uint_fast16_t index) const noexcept {
FASTFLOAT_DEBUG_ASSERT(index < length);
return ptr[index];
}
@ -345,7 +352,7 @@ struct alignas(16) value128 {
constexpr value128() noexcept : low(0), high(0) {}
};
/* Helper C++14 constexpr generic implementation of leading_zeroes */
/* Helper C++14 constexpr generic implementation of leading_zeroes for 64-bit */
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 limb_t
leading_zeroes_generic(uint64_t input_num, uint32_t last_bit = 0) noexcept {
if (input_num & uint64_t(0xffffffff00000000)) {
@ -371,7 +378,7 @@ leading_zeroes_generic(uint64_t input_num, uint32_t last_bit = 0) noexcept {
if (input_num & uint64_t(0x2)) { /* input_num >>= 1; */
last_bit |= 1;
}
return 63 - (limb_t)last_bit;
return 63 - static_cast<limb_t>(last_bit);
}
/* result might be undefined when input_num is zero */
@ -388,22 +395,22 @@ leading_zeroes(uint64_t input_num) noexcept {
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
_BitScanReverse64(&leading_zero, input_num);
return (limb_t)(63 - leading_zero);
return static_cast<limb_t>(63 - leading_zero);
#else
return (limb_t)leading_zeroes_generic(input_num);
return static_cast<limb_t>(leading_zeroes_generic(input_num));
#endif
#else
return (limb_t)__builtin_clzll(input_num);
return static_cast<limb_t>(__builtin_clzll(input_num));
#endif
}
/* Helper C++14 constexpr generic implementation of countr_zero for 32-bit */
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t
countr_zero_generic_32(uint32_t input_num) {
if (input_num == 0) {
return 32;
}
int last_bit = 0;
uint32_t last_bit = 0;
if (!(input_num & 0x0000FFFF)) {
input_num >>= 16;
last_bit |= 16;
@ -1099,7 +1106,6 @@ binary_format<double>::hidden_bit_mask() {
return 0x0010000000000000;
}
// Fix for C2672: Ensure bit_cast is called with explicit template arguments
template <typename T>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float(
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
@ -1120,7 +1126,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float(
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
template <typename = void> struct space_lut {
static constexpr uint_fast8_t value[] = {
static constexpr uint8_t value[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -1136,12 +1142,12 @@ template <typename = void> struct space_lut {
#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
template <typename T> constexpr uint_fast8_t space_lut<T>::value[];
template <typename T> constexpr uint8_t space_lut<T>::value[];
#endif
template <typename UC> constexpr bool is_space(UC c) {
return c < 256 && space_lut<>::value[uint_fast8_t(c)];
return c < 256 && space_lut<>::value[uint8_t(c)];
}
#endif
@ -1227,7 +1233,7 @@ template <typename = void> struct int_luts {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255};
static constexpr uint_fast8_t maxdigits_u64[] = {
static constexpr limb_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, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13};
@ -1248,16 +1254,16 @@ template <typename = void> struct int_luts {
#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
template <typename T> constexpr uint_fast8_t int_luts<T>::chdigit[];
template <typename T> constexpr uint8_t int_luts<T>::chdigit[];
template <typename T> constexpr uint_fast8_t int_luts<T>::maxdigits_u64[];
template <typename T> constexpr limb_t int_luts<T>::maxdigits_u64[];
template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[];
#endif
template <typename UC>
fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) noexcept {
// wchar_t and char can be signed, so we need to be careful.
using UnsignedUC = typename std::make_unsigned<UC>::type;
return int_luts<>::chdigit[static_cast<unsigned char>(
@ -1266,15 +1272,13 @@ fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
-((static_cast<UnsignedUC>(c) & ~0xFFull) == 0)))];
}
fastfloat_really_inline constexpr uint_fast8_t
max_digits_u64(uint_fast8_t base) noexcept {
fastfloat_really_inline constexpr limb_t max_digits_u64(base_t base) noexcept {
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.
fastfloat_really_inline constexpr uint64_t
min_safe_u64(uint_fast8_t base) noexcept {
fastfloat_really_inline constexpr uint64_t min_safe_u64(base_t base) noexcept {
return int_luts<>::min_safe_u64[base - 2];
}

View File

@ -27,12 +27,13 @@ from_chars_result_t<UC>
const chars_format fmt) noexcept {
from_chars_result_t<UC> answer{};
answer.ptr = first;
answer.ec = std::errc(); // be optimistic
answer.ec = std::errc(); // be optimistic
FASTFLOAT_ASSUME(first < last); // so dereference without checks
bool const minusSign = (*first == UC('-'));
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
if ((*first == UC('-')) ||
if (minusSign ||
((chars_format_t(fmt & chars_format::allow_leading_plus)) &&
(*first == UC('+')))) {
++first;
@ -375,7 +376,7 @@ from_chars_float_advanced(UC const *first, UC const *last, T &value,
template <typename T, typename UC, typename>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars(UC const *first, UC const *last, T &value,
uint_fast8_t const base) noexcept {
base_t const base) noexcept {
static_assert(is_supported_integer_type<T>::value,
"only integer types are supported");
@ -389,8 +390,8 @@ from_chars(UC const *first, UC const *last, T &value,
template <typename T>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value, T>::type
integer_times_pow10(uint64_t const mantissa,
int_fast16_t const decimal_exponent) noexcept {
integer_times_pow10(am_mant_t const mantissa,
am_pow_t const decimal_exponent) noexcept {
T value;
if (clinger_fast_path_impl(mantissa, decimal_exponent,
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
@ -412,8 +413,8 @@ FASTFLOAT_CONSTEXPR20
template <typename T>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value, T>::type
integer_times_pow10(int64_t const mantissa,
int_fast16_t const decimal_exponent) noexcept {
integer_times_pow10(am_sign_mant_t const mantissa,
am_pow_t const decimal_exponent) noexcept {
#ifdef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
FASTFLOAT_ASSUME(mantissa >= 0);
const am_mant_t m = static_cast<am_mant_t>(mantissa);
@ -441,14 +442,14 @@ FASTFLOAT_CONSTEXPR20
}
FASTFLOAT_CONSTEXPR20 inline double
integer_times_pow10(uint64_t const mantissa,
int_fast16_t const decimal_exponent) noexcept {
integer_times_pow10(am_mant_t const mantissa,
am_pow_t const decimal_exponent) noexcept {
return integer_times_pow10<double>(mantissa, decimal_exponent);
}
FASTFLOAT_CONSTEXPR20 inline double
integer_times_pow10(int64_t const mantissa,
int_fast16_t const decimal_exponent) noexcept {
integer_times_pow10(am_sign_mant_t const mantissa,
am_pow_t const decimal_exponent) noexcept {
return integer_times_pow10<double>(mantissa, decimal_exponent);
}
@ -460,8 +461,8 @@ FASTFLOAT_CONSTEXPR20
std::is_integral<Int>::value &&
!std::is_signed<Int>::value,
T>::type
integer_times_pow10(Int mantissa, int_fast16_t decimal_exponent) noexcept {
return integer_times_pow10<T>(static_cast<uint64_t>(mantissa),
integer_times_pow10(Int mantissa, am_pow_t decimal_exponent) noexcept {
return integer_times_pow10<T>(static_cast<am_mant_t>(mantissa),
decimal_exponent);
}
@ -471,23 +472,24 @@ FASTFLOAT_CONSTEXPR20
std::is_integral<Int>::value &&
std::is_signed<Int>::value,
T>::type
integer_times_pow10(Int mantissa, int_fast16_t decimal_exponent) noexcept {
return integer_times_pow10<T>(static_cast<int64_t>(mantissa),
integer_times_pow10(Int mantissa, am_pow_t decimal_exponent) noexcept {
return integer_times_pow10<T>(static_cast<am_sign_mant_t>(mantissa),
decimal_exponent);
}
template <typename Int>
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
integer_times_pow10(Int mantissa, int_fast16_t decimal_exponent) noexcept {
return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent);
integer_times_pow10(Int mantissa, am_pow_t decimal_exponent) noexcept {
return integer_times_pow10(static_cast<am_mant_t>(mantissa), decimal_exponent);
}
template <typename Int>
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
integer_times_pow10(Int mantissa, int_fast16_t decimal_exponent) noexcept {
return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);
integer_times_pow10(Int mantissa, am_pow_t decimal_exponent) noexcept {
return integer_times_pow10(static_cast<am_sign_mant_t>(mantissa),
decimal_exponent);
}
template <typename T, typename UC>