mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-11-09 22:59:51 +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
|
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
|
## 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,
|
// the following overloads are here to avoid surprising ambiguity for int,
|
||||||
// unsigned, etc.
|
// unsigned, etc.
|
||||||
template <typename T, typename Int>
|
template <typename T, typename Int>
|
||||||
FASTFLOAT_CONSTEXPR20
|
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
||||||
typename std::enable_if<is_supported_float_type<T>::value &&
|
is_supported_float_type<T>::value && std::is_integral<Int>::value &&
|
||||||
std::is_integral<Int>::value &&
|
sizeof(Int) <= sizeof(uint64_t) && !std::is_signed<Int>::value,
|
||||||
!std::is_signed<Int>::value,
|
T>::type
|
||||||
T>::type
|
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
|
||||||
return integer_times_pow10<T>(static_cast<uint64_t>(mantissa),
|
return integer_times_pow10<T>(static_cast<uint64_t>(mantissa),
|
||||||
decimal_exponent);
|
decimal_exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Int>
|
template <typename T, typename Int>
|
||||||
FASTFLOAT_CONSTEXPR20
|
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
||||||
typename std::enable_if<is_supported_float_type<T>::value &&
|
is_supported_float_type<T>::value && std::is_integral<Int>::value &&
|
||||||
std::is_integral<Int>::value &&
|
sizeof(Int) <= sizeof(int64_t) && std::is_signed<Int>::value,
|
||||||
std::is_signed<Int>::value,
|
T>::type
|
||||||
T>::type
|
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
|
||||||
return integer_times_pow10<T>(static_cast<int64_t>(mantissa),
|
return integer_times_pow10<T>(static_cast<int64_t>(mantissa),
|
||||||
decimal_exponent);
|
decimal_exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Int>
|
template <typename Int>
|
||||||
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
FASTFLOAT_CONSTEXPR20
|
||||||
std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
|
typename std::enable_if<std::is_integral<Int>::value &&
|
||||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
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);
|
return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Int>
|
template <typename Int>
|
||||||
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
|
FASTFLOAT_CONSTEXPR20
|
||||||
std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
|
typename std::enable_if<std::is_integral<Int>::value &&
|
||||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
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);
|
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
|
} // 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") {
|
TEST_CASE("integer_times_pow10") {
|
||||||
/* explicitly verifying API with different types of integers */
|
/* explicitly verifying API with different types of integers */
|
||||||
// double (the "default" overload)
|
// double (the "default" overload)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user