[libcxx-commits] [libcxx] [libc++][math] Fix testing `constexpr` at compile time (PR #105984)
Robin Caloudis via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Aug 25 05:48:45 PDT 2024
https://github.com/robincaloudis created https://github.com/llvm/llvm-project/pull/105984
None
>From eceb3158c36a5e3f8009aa01257df5dfa6f07260 Mon Sep 17 00:00:00 2001
From: Robin Caloudis <robin.caloudis at gmx.de>
Date: Sun, 25 Aug 2024 14:45:05 +0200
Subject: [PATCH] Test constexpr at compile time
---
.../std/numerics/c.math/isfinite.pass.cpp | 56 +++++++++----------
.../test/std/numerics/c.math/isinf.pass.cpp | 56 +++++++++----------
.../test/std/numerics/c.math/isnan.pass.cpp | 56 +++++++++----------
.../std/numerics/c.math/isnormal.pass.cpp | 48 ++++++++--------
4 files changed, 100 insertions(+), 116 deletions(-)
diff --git a/libcxx/test/std/numerics/c.math/isfinite.pass.cpp b/libcxx/test/std/numerics/c.math/isfinite.pass.cpp
index 3d5be616343343..e6d6af52ed3e94 100644
--- a/libcxx/test/std/numerics/c.math/isfinite.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isfinite.pass.cpp
@@ -18,53 +18,49 @@
#include "test_macros.h"
#include "type_algorithms.h"
+#if TEST_STD_VER >= 23
+# define COMPILE_OR_RUNTIME_ASSERT(expr) static_assert(expr)
+#else
+# define COMPILE_OR_RUNTIME_ASSERT(expr) assert(expr)
+#endif
+
struct TestFloat {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(std::isfinite(std::numeric_limits<T>::max()));
- assert(!std::isfinite(std::numeric_limits<T>::infinity()));
- assert(std::isfinite(std::numeric_limits<T>::min()));
- assert(std::isfinite(std::numeric_limits<T>::denorm_min()));
- assert(std::isfinite(std::numeric_limits<T>::lowest()));
- assert(!std::isfinite(-std::numeric_limits<T>::infinity()));
- assert(std::isfinite(T(0)));
- assert(!std::isfinite(std::numeric_limits<T>::quiet_NaN()));
- assert(!std::isfinite(std::numeric_limits<T>::signaling_NaN()));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isfinite(std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(std::numeric_limits<T>::min()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(std::numeric_limits<T>::denorm_min()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isfinite(-std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(T(0)));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isfinite(std::numeric_limits<T>::quiet_NaN()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isfinite(std::numeric_limits<T>::signaling_NaN()));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
struct TestInt {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(std::isfinite(std::numeric_limits<T>::max()));
- assert(std::isfinite(std::numeric_limits<T>::lowest()));
- assert(std::isfinite(T(0)));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(T(0)));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
template <typename T>
struct ConvertibleTo {
- operator T() const { return T(); }
+ TEST_CONSTEXPR_CXX23 operator T() const { return T(); }
};
int main(int, char**) {
@@ -73,9 +69,9 @@ int main(int, char**) {
// Make sure we can call `std::isfinite` with convertible types
{
- assert(std::isfinite(ConvertibleTo<float>()));
- assert(std::isfinite(ConvertibleTo<double>()));
- assert(std::isfinite(ConvertibleTo<long double>()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(ConvertibleTo<float>()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(ConvertibleTo<double>()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isfinite(ConvertibleTo<long double>()));
}
return 0;
diff --git a/libcxx/test/std/numerics/c.math/isinf.pass.cpp b/libcxx/test/std/numerics/c.math/isinf.pass.cpp
index e5169e8056c2ea..b77162f1b254de 100644
--- a/libcxx/test/std/numerics/c.math/isinf.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isinf.pass.cpp
@@ -18,53 +18,49 @@
#include "test_macros.h"
#include "type_algorithms.h"
+#if TEST_STD_VER >= 23
+# define COMPILE_OR_RUNTIME_ASSERT(expr) static_assert(expr)
+#else
+# define COMPILE_OR_RUNTIME_ASSERT(expr) assert(expr)
+#endif
+
struct TestFloat {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(!std::isinf(std::numeric_limits<T>::max()));
- assert(std::isinf(std::numeric_limits<T>::infinity()));
- assert(!std::isinf(std::numeric_limits<T>::min()));
- assert(!std::isinf(std::numeric_limits<T>::denorm_min()));
- assert(!std::isinf(std::numeric_limits<T>::lowest()));
- assert(std::isinf(-std::numeric_limits<T>::infinity()));
- assert(!std::isinf(T(0)));
- assert(!std::isinf(std::numeric_limits<T>::quiet_NaN()));
- assert(!std::isinf(std::numeric_limits<T>::signaling_NaN()));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isinf(std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::min()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::denorm_min()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isinf(-std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(T(0)));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::quiet_NaN()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::signaling_NaN()));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
struct TestInt {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(!std::isinf(std::numeric_limits<T>::max()));
- assert(!std::isinf(std::numeric_limits<T>::lowest()));
- assert(!std::isinf(T(0)));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(T(0)));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
template <typename T>
struct ConvertibleTo {
- operator T() const { return T(); }
+ TEST_CONSTEXPR_CXX23 operator T() const { return T(); }
};
int main(int, char**) {
@@ -73,9 +69,9 @@ int main(int, char**) {
// Make sure we can call `std::isinf` with convertible types
{
- assert(!std::isinf(ConvertibleTo<float>()));
- assert(!std::isinf(ConvertibleTo<double>()));
- assert(!std::isinf(ConvertibleTo<long double>()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(ConvertibleTo<float>()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(ConvertibleTo<double>()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isinf(ConvertibleTo<long double>()));
}
return 0;
diff --git a/libcxx/test/std/numerics/c.math/isnan.pass.cpp b/libcxx/test/std/numerics/c.math/isnan.pass.cpp
index e4ccab1243e567..1eb8a2d3c50797 100644
--- a/libcxx/test/std/numerics/c.math/isnan.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isnan.pass.cpp
@@ -18,53 +18,49 @@
#include "test_macros.h"
#include "type_algorithms.h"
+#if TEST_STD_VER >= 23
+# define COMPILE_OR_RUNTIME_ASSERT(expr) static_assert(expr)
+#else
+# define COMPILE_OR_RUNTIME_ASSERT(expr) assert(expr)
+#endif
+
struct TestFloat {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(!std::isnan(std::numeric_limits<T>::max()));
- assert(!std::isnan(std::numeric_limits<T>::infinity()));
- assert(!std::isnan(std::numeric_limits<T>::min()));
- assert(!std::isnan(std::numeric_limits<T>::denorm_min()));
- assert(!std::isnan(std::numeric_limits<T>::lowest()));
- assert(!std::isnan(-std::numeric_limits<T>::infinity()));
- assert(!std::isnan(T(0)));
- assert(std::isnan(std::numeric_limits<T>::quiet_NaN()));
- assert(std::isnan(std::numeric_limits<T>::signaling_NaN()));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::min()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::denorm_min()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(-std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(T(0)));
+ COMPILE_OR_RUNTIME_ASSERT(std::isnan(std::numeric_limits<T>::quiet_NaN()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isnan(std::numeric_limits<T>::signaling_NaN()));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
struct TestInt {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(!std::isnan(std::numeric_limits<T>::max()));
- assert(!std::isnan(std::numeric_limits<T>::lowest()));
- assert(!std::isnan(T(0)));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(T(0)));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
template <typename T>
struct ConvertibleTo {
- operator T() const { return T(); }
+ TEST_CONSTEXPR_CXX23 operator T() const { return T(); }
};
int main(int, char**) {
@@ -73,9 +69,9 @@ int main(int, char**) {
// Make sure we can call `std::isnan` with convertible types
{
- assert(!std::isnan(ConvertibleTo<float>()));
- assert(!std::isnan(ConvertibleTo<double>()));
- assert(!std::isnan(ConvertibleTo<long double>()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(ConvertibleTo<float>()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(ConvertibleTo<double>()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnan(ConvertibleTo<long double>()));
}
return 0;
diff --git a/libcxx/test/std/numerics/c.math/isnormal.pass.cpp b/libcxx/test/std/numerics/c.math/isnormal.pass.cpp
index c3b8f31359f988..884e0fd6e09f7b 100644
--- a/libcxx/test/std/numerics/c.math/isnormal.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isnormal.pass.cpp
@@ -18,47 +18,43 @@
#include "test_macros.h"
#include "type_algorithms.h"
+#if TEST_STD_VER >= 23
+# define COMPILE_OR_RUNTIME_ASSERT(expr) static_assert(expr)
+#else
+# define COMPILE_OR_RUNTIME_ASSERT(expr) assert(expr)
+#endif
+
struct TestFloat {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(std::isnormal(std::numeric_limits<T>::max()));
- assert(!std::isnormal(std::numeric_limits<T>::infinity()));
- assert(std::isnormal(std::numeric_limits<T>::min()));
- assert(!std::isnormal(std::numeric_limits<T>::denorm_min()));
- assert(std::isnormal(std::numeric_limits<T>::lowest()));
- assert(!std::isnormal(-std::numeric_limits<T>::infinity()));
- assert(!std::isnormal(T(0)));
- assert(!std::isnormal(std::numeric_limits<T>::quiet_NaN()));
- assert(!std::isnormal(std::numeric_limits<T>::signaling_NaN()));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(std::isnormal(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isnormal(std::numeric_limits<T>::min()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(std::numeric_limits<T>::denorm_min()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isnormal(std::numeric_limits<T>::lowest()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(-std::numeric_limits<T>::infinity()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(T(0)));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(std::numeric_limits<T>::quiet_NaN()));
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(std::numeric_limits<T>::signaling_NaN()));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
struct TestInt {
template <class T>
- static TEST_CONSTEXPR_CXX23 bool test() {
- assert(std::isnormal(std::numeric_limits<T>::max()));
- assert(std::isnormal(std::numeric_limits<T>::lowest()) == std::is_signed<T>::value);
- assert(!std::isnormal(T(0)));
-
- return true;
+ static void test() {
+ COMPILE_OR_RUNTIME_ASSERT(std::isnormal(std::numeric_limits<T>::max()));
+ COMPILE_OR_RUNTIME_ASSERT(std::isnormal(std::numeric_limits<T>::lowest()) == std::is_signed<T>::value);
+ COMPILE_OR_RUNTIME_ASSERT(!std::isnormal(T(0)));
}
template <class T>
- TEST_CONSTEXPR_CXX23 void operator()() {
+ void operator()() {
test<T>();
-#if TEST_STD_VER >= 23
- static_assert(test<T>());
-#endif
}
};
More information about the libcxx-commits
mailing list