[libcxx-commits] [libcxx] dc129d6 - [libc++] Add std::fpclassify overloads for floating-point. (#67913)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Oct 5 12:18:07 PDT 2023


Author: Anatolii Malibroda
Date: 2023-10-05T21:18:02+02:00
New Revision: dc129d6f715cf83a2072fc8de8b4e4c70bca6935

URL: https://github.com/llvm/llvm-project/commit/dc129d6f715cf83a2072fc8de8b4e4c70bca6935
DIFF: https://github.com/llvm/llvm-project/commit/dc129d6f715cf83a2072fc8de8b4e4c70bca6935.diff

LOG: [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".

Added: 
    

Modified: 
    libcxx/include/math.h
    libcxx/test/std/numerics/c.math/cmath.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/math.h b/libcxx/include/math.h
index fdf3231c2978cee..b068ea388f095b5 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -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);
 }
 

diff  --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
index e2062cc7ecfd911..11a3de748cb7a69 100644
--- a/libcxx/test/std/numerics/c.math/cmath.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
@@ -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()


        


More information about the libcxx-commits mailing list