From 8126ad04516fc479b95409e8b49d4e88ee8813f2 Mon Sep 17 00:00:00 2001 From: Anatolii Malibroda Date: Sun, 1 Oct 2023 14:54:42 +0200 Subject: [PATCH 1/7] [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 fdf3231c2978c..59787fb8408b1 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -387,8 +387,16 @@ namespace __math { // fpclassify -template ::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 +_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 Date: Mon, 2 Oct 2023 22:05:03 +0200 Subject: [PATCH 2/7] 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 e2062cc7ecfd9..fe5e5aa0360c8 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::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); + static_assert((std::is_same())), int>::value), ""); + static_assert((std::is_same())), int>::value), ""); + static_assert((std::is_same())), 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::max()) == FP_NORMAL); assert(std::fpclassify(std::numeric_limits::min()) == FP_NORMAL); + assert(std::fpclassify(Value()) == FP_NORMAL); } void test_isfinite() From ab0a048f3d2aa922462c2f608f460e81478bb7b1 Mon Sep 17 00:00:00 2001 From: Anatolii Malibroda Date: Tue, 3 Oct 2023 20:55:06 +0200 Subject: [PATCH 3/7] 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 fe5e5aa0360c8..11a3de748cb7a 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())), int>::value), ""); static_assert((std::is_same())), int>::value), ""); static_assert((std::is_same())), 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 Date: Tue, 3 Oct 2023 22:04:59 +0200 Subject: [PATCH 4/7] 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 59787fb8408b1..78ffb54246622 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; From 69dd1bbe267db5204cfa7f2d889a02665f6c5a8e Mon Sep 17 00:00:00 2001 From: Anatolii Malibroda Date: Wed, 4 Oct 2023 10:48:26 +0200 Subject: [PATCH 5/7] MSVC runtime don't have `fpclassify` overload for integers. So we should provide weaker floating-point overloads. --- libcxx/include/math.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libcxx/include/math.h b/libcxx/include/math.h index 78ffb54246622..b484e61076c83 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -387,6 +387,7 @@ namespace __math { // fpclassify +template _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); } @@ -396,6 +397,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI int fpclassify(double __x) _N return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } +template _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); } @@ -409,11 +411,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; From dba2e242400c46868fca5e6b26b59b7a59101398 Mon Sep 17 00:00:00 2001 From: Anatolii Malibroda Date: Thu, 5 Oct 2023 11:39:49 +0200 Subject: [PATCH 6/7] Added comment to inform that float/long double overloads of fpclassify are templates to be weaker than overloads provided by MSVC runtime. --- libcxx/include/math.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/math.h b/libcxx/include/math.h index b484e61076c83..fa23c42e4561e 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -387,6 +387,7 @@ namespace __math { // fpclassify +// template on float/long double overloads to make them weaker than same overloads from MSVC runtime template _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); From ec8a135d60ab516b320f571b87abc65bd24a6145 Mon Sep 17 00:00:00 2001 From: Anatolii Malibroda Date: Thu, 5 Oct 2023 13:18:41 +0200 Subject: [PATCH 7/7] Fixed comment with trailing whitespace. --- 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 fa23c42e4561e..b068ea388f095 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -387,7 +387,7 @@ namespace __math { // fpclassify -// template on float/long double overloads to make them weaker than same overloads from MSVC runtime +// template on non-double overloads to make them weaker than same overloads from MSVC runtime template _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);