added template overload for integer_times_pow10()

This commit is contained in:
Pavel Novikov 2025-09-18 21:28:20 +03:00
parent 88b1e5321c
commit 13345cab65
No known key found for this signature in database
GPG Key ID: F2C305CAE4167D14
2 changed files with 60 additions and 11 deletions

View File

@ -63,6 +63,20 @@ integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
FASTFLOAT_CONSTEXPR20 inline double FASTFLOAT_CONSTEXPR20 inline double
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept; integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
/**
* This function is a template overload of `integer_times_pow10()`
* that returns a floating-point value of type `T` that is one of
* supported floating-point types (e.g. `double`, `float`).
*/
template <typename T>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value, T>::type
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
template <typename T>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value, T>::type
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
/** /**
* from_chars for integer types. * from_chars for integer types.
*/ */

View File

@ -344,44 +344,79 @@ from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
return from_chars_advanced(first, last, value, options); return from_chars_advanced(first, last, value, options);
} }
FASTFLOAT_CONSTEXPR20 inline double template <typename T>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value, T>::type
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept { integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
double value; T value;
if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value)) if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value))
return value; return value;
adjusted_mantissa am = adjusted_mantissa am =
compute_float<binary_format<double>>(decimal_exponent, mantissa); compute_float<binary_format<T>>(decimal_exponent, mantissa);
to_float(false, am, value); to_float(false, am, value);
return value; return value;
} }
FASTFLOAT_CONSTEXPR20 inline double template <typename T>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value, T>::type
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept { integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
const bool is_negative = mantissa < 0; const bool is_negative = mantissa < 0;
const uint64_t m = static_cast<uint64_t>(is_negative ? -mantissa : mantissa); const uint64_t m = static_cast<uint64_t>(is_negative ? -mantissa : mantissa);
double value; T value;
if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value)) if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value))
return value; return value;
adjusted_mantissa am = adjusted_mantissa am = compute_float<binary_format<T>>(decimal_exponent, m);
compute_float<binary_format<double>>(decimal_exponent, m);
to_float(is_negative, am, value); to_float(is_negative, am, value);
return value; return value;
} }
FASTFLOAT_CONSTEXPR20 inline double
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
return integer_times_pow10<double>(mantissa, decimal_exponent);
}
FASTFLOAT_CONSTEXPR20 inline double
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
return integer_times_pow10<double>(mantissa, decimal_exponent);
}
// the following overloads are here to avoid surprising ambiguity for int, // the following overloads are here to avoid surprising ambiguity for int,
// unsigned, etc. // unsigned, etc.
template <typename T, typename Int>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value &&
std::is_integral<Int>::value &&
!std::is_signed<Int>::value,
T>::type
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
return integer_times_pow10<T>(static_cast<uint64_t>(mantissa),
decimal_exponent);
}
template <typename T, typename Int>
FASTFLOAT_CONSTEXPR20
typename std::enable_if<is_supported_float_type<T>::value &&
std::is_integral<Int>::value &&
std::is_signed<Int>::value,
T>::type
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
return integer_times_pow10<T>(static_cast<int64_t>(mantissa),
decimal_exponent);
}
template <typename Int> template <typename Int>
FASTFLOAT_CONSTEXPR20 inline typename std::enable_if< FASTFLOAT_CONSTEXPR20 typename std::enable_if<
std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept { integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent); return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent);
} }
template <typename Int> template <typename Int>
FASTFLOAT_CONSTEXPR20 inline typename std::enable_if< FASTFLOAT_CONSTEXPR20 typename std::enable_if<
std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept { integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent); return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);