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

Anatolii Malibroda via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 3 13:09:38 PDT 2023


https://github.com/antl-m updated https://github.com/llvm/llvm-project/pull/67913

>From 8126ad04516fc479b95409e8b49d4e88ee8813f2 Mon Sep 17 00:00:00 2001
From: Anatolii Malibroda <tolikmalibroda at gmail.com>
Date: Sun, 1 Oct 2023 14:54:42 +0200
Subject: [PATCH 1/4] [libc++] Add std::fpclassify overloads for
 floating-point.

Standard says that implementation of math functions that have floating-point-type parameter should provide an "overload for each cv-unqualified floating-point type".
---
 libcxx/include/math.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/math.h b/libcxx/include/math.h
index fdf3231c2978cee..59787fb8408b167 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -387,8 +387,16 @@ 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 {
+_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);
+}
+
+_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);
 }
 

>From d31a906b3c6e5768b3b1da588b7c261839af270d Mon Sep 17 00:00:00 2001
From: Anatolii Malibroda <tolikmalibroda at gmail.com>
Date: Mon, 2 Oct 2023 22:05:03 +0200
Subject: [PATCH 2/4] Code review adjustments: added required tests.

---
 libcxx/test/std/numerics/c.math/cmath.pass.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
index e2062cc7ecfd911..fe5e5aa0360c85e 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), "");
+    static_assert(noexcept(std::fpclassify((float)0)), "");
+    static_assert(noexcept(std::fpclassify((double)0)), "");
+    static_assert(noexcept(std::fpclassify((long double)0)), "");
+    static_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()

>From ab0a048f3d2aa922462c2f608f460e81478bb7b1 Mon Sep 17 00:00:00 2001
From: Anatolii Malibroda <tolikmalibroda at gmail.com>
Date: Tue, 3 Oct 2023 20:55:06 +0200
Subject: [PATCH 3/4] Fixed failing noexcept tests on C++03.

---
 libcxx/test/std/numerics/c.math/cmath.pass.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
index fe5e5aa0360c85e..11a3de748cb7a69 100644
--- a/libcxx/test/std/numerics/c.math/cmath.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
@@ -606,10 +606,10 @@ void test_fpclassify()
     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), "");
-    static_assert(noexcept(std::fpclassify((float)0)), "");
-    static_assert(noexcept(std::fpclassify((double)0)), "");
-    static_assert(noexcept(std::fpclassify((long double)0)), "");
-    static_assert(noexcept(std::fpclassify(0)), "");
+    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);

>From a9955dcd08d00d0f40b6f96dd3db7b51aedaa5fb Mon Sep 17 00:00:00 2001
From: Anatolii Malibroda <tolikmalibroda at gmail.com>
Date: Tue, 3 Oct 2023 22:04:59 +0200
Subject: [PATCH 4/4] Not define name `fpclassify` if it is defined by Windows
 CRT.

---
 libcxx/include/math.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/math.h b/libcxx/include/math.h
index 59787fb8408b167..78ffb54246622a2 100644
--- a/libcxx/include/math.h
+++ b/libcxx/include/math.h
@@ -409,11 +409,11 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(_A1 __x) _NOEX
 
 _LIBCPP_END_NAMESPACE_STD
 
-using std::__math::fpclassify;
 using std::__math::signbit;
 
 // The MSVC runtime already provides these functions as templates
 #ifndef _LIBCPP_MSVCRT
+using std::__math::fpclassify;
 using std::__math::isfinite;
 using std::__math::isgreater;
 using std::__math::isgreaterequal;



More information about the libcxx-commits mailing list