[libcxx-commits] [libcxx] [libc++][math] Add constexpr for std::abs() (PR #146633)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 1 21:40:16 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Arjun Patel (arjunUpatel)
<details>
<summary>Changes</summary>
Implement `constexpr` for `std::abs()` as defined by [P0533R9](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf) (new C++23 feature). Progress tracked by #<!-- -->105174
---
Full diff: https://github.com/llvm/llvm-project/pull/146633.diff
3 Files Affected:
- (modified) libcxx/include/__math/abs.h (+6-6)
- (modified) libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp (+6-6)
- (modified) libcxx/test/std/numerics/c.math/abs.pass.cpp (+19-11)
``````````diff
diff --git a/libcxx/include/__math/abs.h b/libcxx/include/__math/abs.h
index b780159f11ebf..a1d5854ac8878 100644
--- a/libcxx/include/__math/abs.h
+++ b/libcxx/include/__math/abs.h
@@ -41,25 +41,25 @@ template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
// abs
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); }
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); }
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); }
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); }
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT {
return __builtin_fabsl(__x);
}
template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT {
return __builtin_abs(__x);
}
template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT {
return __builtin_labs(__x);
}
template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT {
return __builtin_llabs(__x);
}
diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
index 3f17f21e8c108..64164240c8564 100644
--- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
+++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
@@ -40,12 +40,12 @@ int main(int, char**) {
double DummyDouble;
long double DummyLongDouble;
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1) == 1);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
- ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
ASSERT_NOT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
ASSERT_NOT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
diff --git a/libcxx/test/std/numerics/c.math/abs.pass.cpp b/libcxx/test/std/numerics/c.math/abs.pass.cpp
index 51aee6e986836..908620b2a3290 100644
--- a/libcxx/test/std/numerics/c.math/abs.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/abs.pass.cpp
@@ -20,21 +20,29 @@ struct correct_size_int {
};
template <class Source, class Result>
-void test_abs() {
- Source neg_val = -5;
- Source pos_val = 5;
- Result res = 5;
+TEST_CONSTEXPR_CXX23 void test_abs() {
+ TEST_CONSTEXPR_CXX23 Source neg_val = -5;
+ TEST_CONSTEXPR_CXX23 Source pos_val = 5;
+ TEST_CONSTEXPR_CXX23 Result res = 5;
ASSERT_SAME_TYPE(decltype(std::abs(neg_val)), Result);
-
- assert(std::abs(neg_val) == res);
- assert(std::abs(pos_val) == res);
+ #if TEST_STD_VER >= 23
+ static_assert(std::abs(neg_val) == res);
+ static_assert(std::abs(pos_val) == res);
+ #else
+ assert(std::abs(neg_val) == res);
+ assert(std::abs(pos_val) == res);
+ #endif
}
-void test_big() {
- long long int big_value = std::numeric_limits<long long int>::max(); // a value too big for ints to store
- long long int negative_big_value = -big_value;
- assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+TEST_CONSTEXPR_CXX23 void test_big() {
+ TEST_CONSTEXPR_CXX23 long long int big_value = std::numeric_limits<long long int>::max(); // a value too big for ints to store
+ TEST_CONSTEXPR_CXX23 long long int negative_big_value = -big_value;
+ #if TEST_STD_VER >= 23
+ static_assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+ #else
+ assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+ #endif
}
// The following is helpful to keep in mind:
``````````
</details>
https://github.com/llvm/llvm-project/pull/146633
More information about the libcxx-commits
mailing list