Skip to content

Commit

Permalink
[libc++] Add std::fpclassify overloads for floating-point. (#67913)
Browse files Browse the repository at this point in the history
Standard says that implementation of math functions that have
floating-point-type parameter should provide an "overload for each
cv-unqualified floating-point type".
  • Loading branch information
tolikmalibroda authored Oct 5, 2023
1 parent bffbe9a commit dc129d6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
15 changes: 13 additions & 2 deletions libcxx/include/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,19 @@ namespace __math {

// fpclassify

template <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::value, int> = 0>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
// template on non-double overloads to make them weaker than same overloads from MSVC runtime
template <class = int>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(float __x) _NOEXCEPT {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
}

template <class = int>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(double __x) _NOEXCEPT {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
}

template <class = int>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(long double __x) _NOEXCEPT {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
}

Expand Down
8 changes: 8 additions & 0 deletions libcxx/test/std/numerics/c.math/cmath.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,20 @@ void test_fpclassify()
static_assert((std::is_same<decltype(std::fpclassify(0)), int>::value), "");
static_assert((std::is_same<decltype(std::fpclassify((long double)0)), int>::value), "");
static_assert((std::is_same<decltype(fpclassify(Ambiguous())), Ambiguous>::value), "");
static_assert((std::is_same<decltype(fpclassify(Value<float>())), int>::value), "");
static_assert((std::is_same<decltype(fpclassify(Value<double>())), int>::value), "");
static_assert((std::is_same<decltype(fpclassify(Value<long double>())), int>::value), "");
ASSERT_NOEXCEPT(std::fpclassify((float)0));
ASSERT_NOEXCEPT(std::fpclassify((double)0));
ASSERT_NOEXCEPT(std::fpclassify((long double)0));
ASSERT_NOEXCEPT(std::fpclassify(0));
assert(std::fpclassify(-1.0) == FP_NORMAL);
assert(std::fpclassify(0) == FP_ZERO);
assert(std::fpclassify(1) == FP_NORMAL);
assert(std::fpclassify(-1) == FP_NORMAL);
assert(std::fpclassify(std::numeric_limits<int>::max()) == FP_NORMAL);
assert(std::fpclassify(std::numeric_limits<int>::min()) == FP_NORMAL);
assert(std::fpclassify(Value<double, 1>()) == FP_NORMAL);
}

void test_isfinite()
Expand Down

0 comments on commit dc129d6

Please sign in to comment.