mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-31 03:07:36 +02:00
Implement constexpr isfinite to avoid producing NaN
This commit is contained in:
@ -2343,12 +2343,16 @@ struct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>
|
|||||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
|
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value&&
|
||||||
has_isfinite<T>::value)>
|
has_isfinite<T>::value)>
|
||||||
FMT_CONSTEXPR20 bool isfinite(T value) {
|
FMT_CONSTEXPR20 bool isfinite(T value) {
|
||||||
if (is_constant_evaluated()) return !isnan(value - value);
|
constexpr T inf = T(std::numeric_limits<double>::infinity());
|
||||||
|
if (is_constant_evaluated())
|
||||||
|
return !isnan(value) && value != inf && value != -inf;
|
||||||
return std::isfinite(value);
|
return std::isfinite(value);
|
||||||
}
|
}
|
||||||
template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
|
template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
|
||||||
constexpr bool isfinite(T value) {
|
FMT_CONSTEXPR bool isfinite(T value) {
|
||||||
return value - value == 0; // std::isfinite doesn't support __float128.
|
T inf = T(std::numeric_limits<double>::infinity());
|
||||||
|
// std::isfinite doesn't support __float128.
|
||||||
|
return !isnan(value) && value != inf && value != -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
|
template <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>
|
||||||
|
@ -89,6 +89,8 @@ template <typename Float> void check_isfinite() {
|
|||||||
EXPECT_TRUE(isfinite(Float(fmt::detail::max_value<double>())));
|
EXPECT_TRUE(isfinite(Float(fmt::detail::max_value<double>())));
|
||||||
// Use double because std::numeric_limits is broken for __float128.
|
// Use double because std::numeric_limits is broken for __float128.
|
||||||
using limits = std::numeric_limits<double>;
|
using limits = std::numeric_limits<double>;
|
||||||
|
FMT_CONSTEXPR20 auto result = isfinite(Float(limits::infinity()));
|
||||||
|
EXPECT_FALSE(result);
|
||||||
EXPECT_FALSE(isfinite(Float(limits::infinity())));
|
EXPECT_FALSE(isfinite(Float(limits::infinity())));
|
||||||
EXPECT_FALSE(isfinite(Float(-limits::infinity())));
|
EXPECT_FALSE(isfinite(Float(-limits::infinity())));
|
||||||
EXPECT_FALSE(isfinite(Float(limits::quiet_NaN())));
|
EXPECT_FALSE(isfinite(Float(limits::quiet_NaN())));
|
||||||
|
Reference in New Issue
Block a user