Skip to content

Commit

Permalink
Implement constexpr isfinite to avoid producing NaN
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed May 11, 2022
1 parent 358f5a7 commit ae963e4
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
10 changes: 7 additions & 3 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -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&&
has_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);
}
template <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>
constexpr bool isfinite(T value) {
return value - value == 0; // std::isfinite doesn't support __float128.
FMT_CONSTEXPR bool isfinite(T value) {
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)>
Expand Down
2 changes: 2 additions & 0 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ template <typename Float> void check_isfinite() {
EXPECT_TRUE(isfinite(Float(fmt::detail::max_value<double>())));
// Use double because std::numeric_limits is broken for __float128.
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::quiet_NaN())));
Expand Down

0 comments on commit ae963e4

Please sign in to comment.