mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-10-31 03:16:25 +08:00
Reject integer_times_pow10 arguments wider than 64 bits
This commit is contained in:
parent
0de7a21da5
commit
4b37bda237
@ -482,7 +482,7 @@ float: 12345678 * 10^23 = 1.23456782e+30 (==expected)
|
||||
```
|
||||
|
||||
Overloads of `fast_float::integer_times_pow10()` are provided for
|
||||
signed and unsigned integer types: `int64_t`, `uint64_t`, etc.
|
||||
signed and unsigned integer types up to 64 bits: `int64_t`, `uint64_t`, etc.
|
||||
|
||||
|
||||
## Users and Related Work
|
||||
|
||||
@ -535,38 +535,42 @@ integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
|
||||
// the following overloads are here to avoid surprising ambiguity for int,
|
||||
// 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 {
|
||||
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
||||
is_supported_float_type<T>::value && std::is_integral<Int>::value &&
|
||||
sizeof(Int) <= sizeof(uint64_t) && !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 {
|
||||
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
||||
is_supported_float_type<T>::value && std::is_integral<Int>::value &&
|
||||
sizeof(Int) <= sizeof(int64_t) && 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>
|
||||
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
||||
std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
|
||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
typename std::enable_if<std::is_integral<Int>::value &&
|
||||
sizeof(Int) <= sizeof(uint64_t) &&
|
||||
!std::is_signed<Int>::value,
|
||||
double>::type
|
||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||
return integer_times_pow10(static_cast<uint64_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 decimal_exponent) noexcept {
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
typename std::enable_if<std::is_integral<Int>::value &&
|
||||
sizeof(Int) <= sizeof(int64_t) &&
|
||||
std::is_signed<Int>::value,
|
||||
double>::type
|
||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||
return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);
|
||||
}
|
||||
|
||||
|
||||
@ -2283,6 +2283,38 @@ void verify_integer_times_pow10(Int mantissa, int decimal_exponent) {
|
||||
}
|
||||
} // namespace all_supported_types
|
||||
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
template <typename Int, typename = void>
|
||||
struct has_integer_times_pow10 : std::false_type {};
|
||||
|
||||
template <typename Int>
|
||||
struct has_integer_times_pow10<
|
||||
Int, std::void_t<decltype(fast_float::integer_times_pow10(Int{}, 0))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename Float, typename Int, typename = void>
|
||||
struct has_typed_integer_times_pow10 : std::false_type {};
|
||||
|
||||
template <typename Float, typename Int>
|
||||
struct has_typed_integer_times_pow10<
|
||||
Float, Int,
|
||||
std::void_t<decltype(fast_float::integer_times_pow10<Float>(Int{}, 0))>>
|
||||
: std::true_type {};
|
||||
|
||||
TEST_CASE("integer_times_pow10 rejects integers wider than 64 bits") {
|
||||
CHECK(has_integer_times_pow10<int64_t>::value);
|
||||
CHECK(has_integer_times_pow10<uint64_t>::value);
|
||||
CHECK(has_typed_integer_times_pow10<float, int64_t>::value);
|
||||
CHECK(has_typed_integer_times_pow10<double, uint64_t>::value);
|
||||
CHECK_FALSE(has_integer_times_pow10<__int128_t>::value);
|
||||
CHECK_FALSE(has_integer_times_pow10<__uint128_t>::value);
|
||||
CHECK_FALSE(has_typed_integer_times_pow10<float, __int128_t>::value);
|
||||
CHECK_FALSE(has_typed_integer_times_pow10<float, __uint128_t>::value);
|
||||
CHECK_FALSE(has_typed_integer_times_pow10<double, __int128_t>::value);
|
||||
CHECK_FALSE(has_typed_integer_times_pow10<double, __uint128_t>::value);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("integer_times_pow10") {
|
||||
/* explicitly verifying API with different types of integers */
|
||||
// double (the "default" overload)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user