diff --git a/include/fast_float/constexpr_feature_detect.h b/include/fast_float/constexpr_feature_detect.h index bbe8dcc..6c97f14 100644 --- a/include/fast_float/constexpr_feature_detect.h +++ b/include/fast_float/constexpr_feature_detect.h @@ -32,7 +32,6 @@ // C++20 std::bit_cast #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L -#include #define FASTFLOAT_HAS_BIT_CAST 1 #else #define FASTFLOAT_HAS_BIT_CAST 0 diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index fa39efd..43934da 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -64,19 +64,12 @@ to_extended(T const &value) noexcept { constexpr equiv_uint mantissa_mask = binary_format::mantissa_mask(); constexpr equiv_uint hidden_bit_mask = binary_format::hidden_bit_mask(); - adjusted_mantissa am; constexpr am_pow_t bias = binary_format::mantissa_explicit_bits() - binary_format::minimum_exponent(); - equiv_uint bits; -#if FASTFLOAT_HAS_BIT_CAST - bits = -#if FASTFLOAT_HAS_BIT_CAST == 1 - std:: -#endif - bit_cast(value); -#else - ::memcpy(&bits, &value, sizeof(T)); -#endif + + equiv_uint const bits = bit_cast(value); + + adjusted_mantissa am; if ((bits & exponent_mask) == 0) { // denormal am.power2 = 1 - bias; diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 0474ba3..507da39 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -101,6 +101,23 @@ using parse_options = parse_options_t; #include #endif +namespace fast_float { +template +FASTFLOAT_CONSTEXPR20 To bit_cast(const From &from) { +#if FASTFLOAT_HAS_BIT_CAST + return std::bit_cast(from); +#else + // Implementation of std::bit_cast for pre-C++20. + static_assert(sizeof(To) == sizeof(From), + "bit_cast requires source and destination to be the same size"); + auto to = To(); + // The cast suppresses a bogus -Wclass-memaccess on GCC. + std::memcpy(static_cast(&to), &from, sizeof(to)); + return to; +#endif +} +} // namespace fast_float + #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) || \ defined(__MINGW64__) || defined(__s390x__) || \ @@ -1029,6 +1046,7 @@ binary_format::hidden_bit_mask() { return 0x0010000000000000; } +// Fix for C2672: Ensure bit_cast is called with explicit template arguments template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float( #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN @@ -1043,15 +1061,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float( word = equiv_uint(word | equiv_uint(negative) << binary_format::sign_index()); #endif -#if FASTFLOAT_HAS_BIT_CAST - value = -#if FASTFLOAT_HAS_BIT_CAST == 1 - std:: -#endif - bit_cast(word); -#else - ::memcpy(&value, &word, sizeof(T)); -#endif + value = bit_cast(word); } #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN