Skip to content

Commit dc129d6

Browse files
[libc++] Add std::fpclassify overloads for floating-point. (#67913)
Standard says that implementation of math functions that have floating-point-type parameter should provide an "overload for each cv-unqualified floating-point type".
1 parent bffbe9a commit dc129d6

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

libcxx/include/math.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,19 @@ namespace __math {
387387

388388
// fpclassify
389389

390-
template <class _A1, std::__enable_if_t<std::is_floating_point<_A1>::value, int> = 0>
391-
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEXCEPT {
390+
// template on non-double overloads to make them weaker than same overloads from MSVC runtime
391+
template <class = int>
392+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(float __x) _NOEXCEPT {
393+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
394+
}
395+
396+
template <class = int>
397+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(double __x) _NOEXCEPT {
398+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
399+
}
400+
401+
template <class = int>
402+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(long double __x) _NOEXCEPT {
392403
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
393404
}
394405

libcxx/test/std/numerics/c.math/cmath.pass.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,12 +603,20 @@ void test_fpclassify()
603603
static_assert((std::is_same<decltype(std::fpclassify(0)), int>::value), "");
604604
static_assert((std::is_same<decltype(std::fpclassify((long double)0)), int>::value), "");
605605
static_assert((std::is_same<decltype(fpclassify(Ambiguous())), Ambiguous>::value), "");
606+
static_assert((std::is_same<decltype(fpclassify(Value<float>())), int>::value), "");
607+
static_assert((std::is_same<decltype(fpclassify(Value<double>())), int>::value), "");
608+
static_assert((std::is_same<decltype(fpclassify(Value<long double>())), int>::value), "");
609+
ASSERT_NOEXCEPT(std::fpclassify((float)0));
610+
ASSERT_NOEXCEPT(std::fpclassify((double)0));
611+
ASSERT_NOEXCEPT(std::fpclassify((long double)0));
612+
ASSERT_NOEXCEPT(std::fpclassify(0));
606613
assert(std::fpclassify(-1.0) == FP_NORMAL);
607614
assert(std::fpclassify(0) == FP_ZERO);
608615
assert(std::fpclassify(1) == FP_NORMAL);
609616
assert(std::fpclassify(-1) == FP_NORMAL);
610617
assert(std::fpclassify(std::numeric_limits<int>::max()) == FP_NORMAL);
611618
assert(std::fpclassify(std::numeric_limits<int>::min()) == FP_NORMAL);
619+
assert(std::fpclassify(Value<double, 1>()) == FP_NORMAL);
612620
}
613621

614622
void test_isfinite()

0 commit comments

Comments
 (0)