This commit is contained in:
HedgehogInTheCPP 2026-08-16 18:41:32 +03:00
parent 6d6442ae54
commit 39b6b8393e
5 changed files with 33 additions and 37 deletions

View File

@ -50,7 +50,7 @@ fastfloat_really_inline constexpr uint32_t byteswap(uint32_t val) noexcept {
template <typename T, typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 T
read_chars_to_unsigned(UC const *chars) noexcept {
if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
if (is_constant_evaluated() || !std::is_same<UC, char>::value) {
T val = 0;
for (uint_fast8_t i = 0; i != sizeof(T); ++i) {
val |= T(uint8_t(*chars)) << (i * 8);
@ -133,7 +133,7 @@ parse_eight_digits_unrolled(uint64_t val) noexcept {
template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t
parse_eight_digits_unrolled(UC const *chars) noexcept {
if (cpp20_and_in_constexpr() || !has_simd_opt<UC>()) {
if (is_constant_evaluated() || !has_simd_opt<UC>()) {
return parse_eight_digits_unrolled(
read_chars_to_unsigned<uint64_t>(chars)); // truncation okay
}
@ -405,7 +405,7 @@ x86_parse_digits_unchecked_until_19(char const *&p, char const *end,
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
simd_parse_if_eight_digits_unrolled(char16_t const *chars,
uint64_t &i) noexcept {
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
return false;
}
#ifdef FASTFLOAT_X86_SIMD

View File

@ -214,7 +214,7 @@ scalar_add(limb x, limb y, bool &overflow) noexcept {
// gcc and clang
#if defined(__has_builtin)
#if __has_builtin(__builtin_add_overflow)
if (!cpp20_and_in_constexpr()) {
if (!is_constant_evaluated()) {
overflow = __builtin_add_overflow(x, y, &z);
return z;
}

View File

@ -169,14 +169,15 @@ round_down(adjusted_mantissa &am, am_pow_t shift) noexcept {
template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
skip_zeros(UC const *&first, UC const *last) noexcept {
while (!cpp20_and_in_constexpr() &&
std::distance(first, last) >= int_cmp_len<UC>()) {
uint64_t val;
::memcpy(&val, first, sizeof(uint64_t));
if (val != int_cmp_zeros<UC>()) {
break;
if (!is_constant_evaluated()) {
while (std::distance(first, last) >= int_cmp_len<UC>()) {
uint64_t val;
::memcpy(&val, first, sizeof(uint64_t));
if (val != int_cmp_zeros<UC>()) {
break;
}
first += int_cmp_len<UC>();
}
first += int_cmp_len<UC>();
}
while (first != last) {
if (*first != UC('0')) {
@ -192,14 +193,15 @@ template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
is_truncated(UC const *first, UC const *last) noexcept {
// do 8-bit optimizations, can just compare to 8 literal 0s.
while (!cpp20_and_in_constexpr() &&
std::distance(first, last) >= int_cmp_len<UC>()) {
uint64_t val;
::memcpy(&val, first, sizeof(uint64_t));
if (val != int_cmp_zeros<UC>()) {
return true;
if (!is_constant_evaluated()) {
while (std::distance(first, last) >= int_cmp_len<UC>()) {
uint64_t val;
::memcpy(&val, first, sizeof(uint64_t));
if (val != int_cmp_zeros<UC>()) {
return true;
}
first += int_cmp_len<UC>();
}
first += int_cmp_len<UC>();
}
while (first != last) {
if (*first != UC('0')) {

View File

@ -193,9 +193,8 @@ using parse_options = parse_options_t<char>;
#endif
#ifdef FASTFLOAT_X86_SIMD // user defined level
static_assert(FASTFLOAT_X86_SIMD >= 20 && FASTFLOAT_X86_SIMD <= 52,
"FASTFLOAT_X86_SIMD should be between 20(SSE2) and 42(SSE4.2) "
"and optionally up to 52(AVX2)");
static_assert(FASTFLOAT_X86_SIMD == 20 || FASTFLOAT_X86_SIMD == 42 || FASTFLOAT_X86_SIMD == 52,
"FASTFLOAT_X86_SIMD should be 20(SSE2), 42(SSE4.2) and 52(AVX2)");
#else // auto detect
#if defined(__AVX2__)
#define FASTFLOAT_X86_SIMD 52
@ -298,10 +297,7 @@ static_assert(FASTFLOAT_X86_SIMD >= 20 && FASTFLOAT_X86_SIMD <= 52,
namespace fast_float {
#if FASTFLOAT_HAS_BIT_CAST
template <typename To, typename From>
fastfloat_really_inline constexpr To bit_cast(const From &from) noexcept {
return std::bit_cast<To>(from);
}
using std::bit_cast;
#else
template <typename To, typename From>
fastfloat_really_inline To bit_cast(const From &from) noexcept {
@ -315,13 +311,13 @@ fastfloat_really_inline To bit_cast(const From &from) noexcept {
}
#endif
fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() noexcept {
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED
return std::is_constant_evaluated();
using std::is_constant_evaluated;
#else
fastfloat_really_inline constexpr bool is_constant_evaluated() noexcept {
return false;
#endif
}
#endif
template <typename T>
struct is_supported_float_type
@ -372,7 +368,7 @@ template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
fastfloat_strncasecmp3(UC const *actual_mixedcase,
UC const *expected_lowercase) {
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
for (uint_fast8_t i = 0; i != 3; ++i) {
if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
return false;
@ -415,7 +411,7 @@ template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
fastfloat_strncasecmp5(UC const *actual_mixedcase,
UC const *expected_lowercase) {
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
for (uint_fast8_t i = 0; i != 5; ++i) {
if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
return false;
@ -459,8 +455,6 @@ fastfloat_strncasecmp5(UC const *actual_mixedcase,
return (actual_mixedcase[4] | 32) == (expected_lowercase[4]);
}
}
// crutch for older GCC and MinGW probably.
return false;
}
// Compares two ASCII strings in a case insensitive manner.
@ -468,7 +462,7 @@ template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
uint_fast8_t const length) noexcept {
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
for (uint_fast8_t i = 0; i != length; ++i) {
if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
return false;
@ -571,7 +565,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb_t
leading_zeroes(uint64_t input_num) noexcept {
assert(input_num > 0);
FASTFLOAT_ASSUME(input_num > 0);
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
return leading_zeroes_generic(input_num);
}
#ifdef FASTFLOAT_VISUAL_STUDIO
@ -632,7 +626,7 @@ countr_zero_generic_32(uint32_t input_num) noexcept {
/* count trailing zeroes for 32-bit integers */
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb_t
countr_zero_32(uint32_t input_num) noexcept {
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
return countr_zero_generic_32(input_num);
}
#ifdef FASTFLOAT_VISUAL_STUDIO
@ -680,7 +674,7 @@ _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) noexcept {
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128
full_multiplication(uint64_t a, uint64_t b) noexcept {
value128 answer;
if (cpp20_and_in_constexpr()) {
if (is_constant_evaluated()) {
answer.low = umul128_generic(a, b, &answer.high);
} else {
#if defined(_M_ARM64) && !defined(__MINGW32__)

View File

@ -219,7 +219,7 @@ clinger_fast_path_impl(am_mant_t const mantissa, am_pow_t const exponent,
// there might be performance advantages at having the check
// be last.
#ifndef FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED
if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
if (!is_constant_evaluated() && detail::rounds_to_nearest()) {
#endif
// We have that fegetround() == FE_TONEAREST.
// Next is Clinger's fast path.