introduce equiv_uint_t

This commit is contained in:
Anders Dalvander 2024-12-01 16:36:17 +01:00
parent 82865ad475
commit 3146e686d0
3 changed files with 30 additions and 10 deletions

View File

@ -62,7 +62,7 @@ scientific_exponent(parsed_number_string_t<UC> &num) noexcept {
template <typename T>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
to_extended(T value) noexcept {
using equiv_uint = typename binary_format<T>::equiv_uint;
using equiv_uint = equiv_uint_t<T>;
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
constexpr equiv_uint hidden_bit_mask = binary_format<T>::hidden_bit_mask();

View File

@ -230,6 +230,14 @@ struct is_supported_float_type
> {
};
template <typename T>
using equiv_uint_t = typename std::conditional<
sizeof(T) == 1, uint8_t,
typename std::conditional<
sizeof(T) == 2, uint16_t,
typename std::conditional<sizeof(T) == 4, uint32_t,
uint64_t>::type>::type>::type;
template <typename T> struct is_supported_integer_type : std::is_integral<T> {};
template <typename UC>
@ -413,8 +421,7 @@ constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
template <typename T, typename U = void> struct binary_format_lookup_tables;
template <typename T> struct binary_format : binary_format_lookup_tables<T> {
using equiv_uint =
typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
using equiv_uint = equiv_uint_t<T>;
static inline constexpr int mantissa_explicit_bits();
static inline constexpr int minimum_exponent();
@ -694,11 +701,10 @@ binary_format<double>::hidden_bit_mask() {
template <typename T>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
to_float(bool negative, adjusted_mantissa am, T &value) {
using fastfloat_uint = typename binary_format<T>::equiv_uint;
fastfloat_uint word = (fastfloat_uint)am.mantissa;
word |= fastfloat_uint(am.power2)
<< binary_format<T>::mantissa_explicit_bits();
word |= fastfloat_uint(negative) << binary_format<T>::sign_index();
using equiv_uint = equiv_uint_t<T>;
equiv_uint word = equiv_uint(am.mantissa);
word |= equiv_uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
word |= equiv_uint(negative) << binary_format<T>::sign_index();
#if FASTFLOAT_HAS_BIT_CAST
value = std::bit_cast<T>(word);
#else
@ -841,6 +847,21 @@ fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) {
return int_luts<>::min_safe_u64[base - 2];
}
static_assert(std::is_same<equiv_uint_t<double>, uint64_t>::value,
"equiv_uint should be uint64_t for double");
static_assert(std::is_same<equiv_uint_t<float>, uint32_t>::value,
"equiv_uint should be uint32_t for float");
#ifdef __STDCPP_FLOAT64_T__
static_assert(std::is_same<equiv_uint_t<std::float64_t>, uint64_t>::value,
"equiv_uint should be uint64_t for std::float64_t");
#endif
#ifdef __STDCPP_FLOAT32_T__
static_assert(std::is_same<equiv_uint_t<std::float32_t>, uint32_t>::value,
"equiv_uint should be uint32_t for std::float32_t");
#endif
constexpr chars_format operator~(chars_format rhs) noexcept {
using int_type = std::underlying_type<chars_format>::type;
return static_cast<chars_format>(~static_cast<int_type>(rhs));

View File

@ -729,8 +729,7 @@ constexpr void check_basic_test_result(stringtype str, result_type result,
auto copysign = [](double x, double y) -> double {
#if FASTFLOAT_HAS_BIT_CAST
if (fast_float::cpp20_and_in_constexpr()) {
using equiv_int = std::make_signed_t<
typename fast_float::binary_format<double>::equiv_uint>;
using equiv_int = std::make_signed_t<fast_float::equiv_uint_t<double>>;
auto const i = std::bit_cast<equiv_int>(y);
if (i < 0) {
return -x;