-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][numeric] P0543R3: Saturation arithmetic #77967
[libc++][numeric] P0543R3: Saturation arithmetic #77967
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
Implements: https://wg21.link/P0543R3 - https://eel.is/c++draft/numeric.sat Additional notes: - Division: https://eel.is/c++draft/expr.mul#4 - Arithmetic conversions: https://eel.is/c++draft/expr.arith.conv#1.5 - Clang builtins: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-functions
cecbc2e
to
db3e72e
Compare
@llvm/pr-subscribers-libcxx Author: Hristo Hristov (H-G-Hristov) ChangesImplements: https://wg21.link/P0543R3 Additional references:
Patch is 39.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/77967.diff 23 Files Affected:
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 893a3b13ca06e0..9dd9c0c023bc8a 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -432,7 +432,7 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_rcu`` *unimplemented*
--------------------------------------------------- -----------------
- ``__cpp_lib_saturation_arithmetic`` *unimplemented*
+ ``__cpp_lib_saturation_arithmetic`` ``202311L``
--------------------------------------------------- -----------------
``__cpp_lib_smart_ptr_owner_equality`` *unimplemented*
--------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index 6de7d07e454d34..877e387d9280fd 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -54,12 +54,13 @@ Implemented Papers
- P2905R2 - Runtime format strings
- P2918R2 - Runtime format strings II
- P2871R3 - Remove Deprecated Unicode Conversion Facets from C++26
-- P2870R3 - Remove basic_string::reserve()
+- P2870R3 - Remove ``basic_string::reserve()``
- P2909R4 - Fix formatting of code units as integers (Dude, where’s my ``char``?)
-- P2821R5 - span.at()
-- P0521R0 - Proposed Resolution for CA 14 (shared_ptr use_count/unique)
+- P2821R5 - ``span.at()``
+- P0521R0 - Proposed Resolution for CA 14 (``shared_ptr`` ``use_count/unique``)
- P1759R6 - Native handles and file streams
- P2517R1 - Add a conditional ``noexcept`` specification to ``std::apply``
+- P0543R3 - Saturation arithmetic
Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 5701717f39766c..b38b3028863fee 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -27,7 +27,7 @@
"`P2714R1 <https://wg21.link/P2714R1>`__","LWG","Bind front and back to NTTP callables","Varna June 2023","","",""
"`P2630R4 <https://wg21.link/P2630R4>`__","LWG","``submdspan``","Varna June 2023","","",""
"","","","","","",""
-"`P0543R3 <https://wg21.link/P0543R3>`__","LWG","Saturation arithmetic","Kona November 2023","","",""
+"`P0543R3 <https://wg21.link/P0543R3>`__","LWG","Saturation arithmetic","Kona November 2023","|Complete|","18.0",""
"`P2407R5 <https://wg21.link/P2407R5>`__","LWG","Freestanding Library: Partial Classes","Kona November 2023","","",""
"`P2546R5 <https://wg21.link/P2546R5>`__","LWG","Debugging Support","Kona November 2023","","",""
"`P2905R2 <https://wg21.link/P2905R2>`__","LWG","Runtime format strings","Kona November 2023","|Complete|","18.0","|format| |DR|"
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 0fe3ab44d2466e..c4d8a9f092de14 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -569,6 +569,7 @@ set(files
__numeric/pstl_reduce.h
__numeric/pstl_transform_reduce.h
__numeric/reduce.h
+ __numeric/saturation_arithmetic.h
__numeric/transform_exclusive_scan.h
__numeric/transform_inclusive_scan.h
__numeric/transform_reduce.h
diff --git a/libcxx/include/__numeric/saturation_arithmetic.h b/libcxx/include/__numeric/saturation_arithmetic.h
new file mode 100644
index 00000000000000..6d13ec5b3fd5bc
--- /dev/null
+++ b/libcxx/include/__numeric/saturation_arithmetic.h
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H
+#define _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H
+
+#include <__concepts/arithmetic.h>
+#include <__config>
+#include <__type_traits/decay.h>
+#include <__utility/cmp.h>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26
+
+template <typename _Tp>
+concept __libcpp_standard_integer = __libcpp_unsigned_integer<decay_t<_Tp>> || __libcpp_signed_integer<decay_t<_Tp>>;
+
+template <__libcpp_standard_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp add_sat(_Tp __x, _Tp __y) noexcept {
+ if (_Tp __sum; !__builtin_add_overflow(__x, __y, &__sum))
+ return __sum;
+ // Handle overflow
+ if constexpr (__libcpp_unsigned_integer<_Tp>) {
+ return std::numeric_limits<_Tp>::max();
+ } else {
+ // Signed addition overflow
+ if (__x > 0)
+ // Overflows if (x > 0 && y > 0)
+ return std::numeric_limits<_Tp>::max();
+ else
+ // Overflows if (x < 0 && y < 0)
+ return std::numeric_limits<_Tp>::min();
+ }
+}
+
+template <__libcpp_standard_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp sub_sat(_Tp __x, _Tp __y) noexcept {
+ if (_Tp __sub; !__builtin_sub_overflow(__x, __y, &__sub))
+ return __sub;
+ // Handle overflow
+ if constexpr (__libcpp_unsigned_integer<_Tp>) {
+ // Overflows if (x < y)
+ return std::numeric_limits<_Tp>::min();
+ } else {
+ // Signed subtration overflow
+ if (__x > 0)
+ // Overflows if (x > 0 && y < 0)
+ return std::numeric_limits<_Tp>::max();
+ else
+ // Overflows if (x < 0 && y > 0)
+ return std::numeric_limits<_Tp>::min();
+ }
+}
+
+template <__libcpp_standard_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp mul_sat(_Tp __x, _Tp __y) noexcept {
+ if (_Tp __mul; !__builtin_mul_overflow(__x, __y, &__mul))
+ return __mul;
+ // Handle overflow
+ if constexpr (__libcpp_unsigned_integer<_Tp>) {
+ return std::numeric_limits<_Tp>::max();
+ } else {
+ // Signed multiplication overflow
+ if (__x > 0) {
+ if (__y > 0)
+ // Overflows if (x > 0 && y > 0)
+ return std::numeric_limits<_Tp>::max();
+ // Overflows if (x > 0 && y < 0)
+ return std::numeric_limits<_Tp>::min();
+ }
+ if (__y > 0)
+ // Overflows if (x < 0 && y > 0)
+ return std::numeric_limits<_Tp>::min();
+ // Overflows if (x < 0 && y < 0)
+ return std::numeric_limits<_Tp>::max();
+ }
+}
+
+template <__libcpp_standard_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp div_sat(_Tp __x, _Tp __y) noexcept {
+ _LIBCPP_ASSERT_UNCATEGORIZED(__y != 0, "Division by 0 is undefined");
+ if constexpr (__libcpp_unsigned_integer<_Tp>) {
+ return __x / __y;
+ } else {
+ // Handle signed division overflow
+ if (__x == std::numeric_limits<_Tp>::min() && __y == _Tp{-1})
+ return std::numeric_limits<_Tp>::max();
+ return __x / __y;
+ }
+}
+
+template <__libcpp_standard_integer _Rp, __libcpp_standard_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Rp saturate_cast(_Tp __x) noexcept {
+ // Handle overflow
+ if (std::cmp_less_equal(__x, std::numeric_limits<_Rp>::min()))
+ return std::numeric_limits<_Rp>::min();
+ if (std::cmp_greater_equal(__x, std::numeric_limits<_Rp>::max()))
+ return std::numeric_limits<_Rp>::max();
+ // No overflow
+ return static_cast<_Rp>(__x);
+}
+
+#endif // _LIBCPP_STD_VER >= 26
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index d10670d4faaffc..194a74a1e07b14 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1580,6 +1580,7 @@ module std_private_numeric_pstl_transform_reduce [system] {
export *
}
module std_private_numeric_reduce [system] { header "__numeric/reduce.h" }
+module std_private_numeric_saturation_arithmetic [system] { header "__numeric/saturation_arithmetic.h" }
module std_private_numeric_transform_exclusive_scan [system] { header "__numeric/transform_exclusive_scan.h" }
module std_private_numeric_transform_inclusive_scan [system] { header "__numeric/transform_inclusive_scan.h" }
module std_private_numeric_transform_reduce [system] { header "__numeric/transform_reduce.h" }
diff --git a/libcxx/include/numeric b/libcxx/include/numeric
index d09d0a81fcc03a..0fe7115f1c666e 100644
--- a/libcxx/include/numeric
+++ b/libcxx/include/numeric
@@ -140,6 +140,18 @@ template<class T>
template<class T>
constexpr T* midpoint(T* a, T* b); // C++20
+// [numeric.sat], saturation arithmetic
+template<class T>
+constexpr T add_sat(T x, T y) noexcept; // freestanding, Since C++26
+template<class T>
+constexpr T sub_sat(T x, T y) noexcept; // freestanding, Since C++26
+template<class T>
+constexpr T mul_sat(T x, T y) noexcept; // freestanding, Since C++26
+template<class T>
+constexpr T div_sat(T x, T y) noexcept; // freestanding, Since C++26
+template<class T, class U>
+constexpr T saturate_cast(U x) noexcept; // freestanding, Since C++26
+
} // std
*/
@@ -160,6 +172,7 @@ template<class T>
#include <__numeric/pstl_reduce.h>
#include <__numeric/pstl_transform_reduce.h>
#include <__numeric/reduce.h>
+#include <__numeric/saturation_arithmetic.h>
#include <__numeric/transform_exclusive_scan.h>
#include <__numeric/transform_inclusive_scan.h>
#include <__numeric/transform_reduce.h>
diff --git a/libcxx/include/version b/libcxx/include/version
index c96647894dce63..b8d0c4e6f3c898 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -504,7 +504,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_out_ptr 202311L
# define __cpp_lib_ratio 202306L
// # define __cpp_lib_rcu 202306L
-// # define __cpp_lib_saturation_arithmetic 202311L
+# define __cpp_lib_saturation_arithmetic 202311L
// # define __cpp_lib_smart_ptr_owner_equality 202306L
# define __cpp_lib_span_at 202311L
// # define __cpp_lib_span_initializer_list 202311L
diff --git a/libcxx/modules/std/numeric.inc b/libcxx/modules/std/numeric.inc
index d2b7688d4e5f10..3bc7b231681584 100644
--- a/libcxx/modules/std/numeric.inc
+++ b/libcxx/modules/std/numeric.inc
@@ -54,4 +54,14 @@ export namespace std {
// [numeric.ops.midpoint], midpoint
using std::midpoint;
+
+#if _LIBCPP_STD_VER >= 26
+ // [numeric.sat], saturation arithmetic
+ using std::add_sat;
+ using std::div_sat;
+ using std::mul_sat;
+ using std::saturate_cast;
+ using std::sub_sat;
+#endif
+
} // namespace std
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.compile.pass.cpp
index b510eefc69a5d3..d132b7c7b9c4f5 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.compile.pass.cpp
@@ -263,17 +263,11 @@
# endif
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_saturation_arithmetic
-# error "__cpp_lib_saturation_arithmetic should be defined in c++26"
-# endif
-# if __cpp_lib_saturation_arithmetic != 202311L
-# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_saturation_arithmetic
-# error "__cpp_lib_saturation_arithmetic should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_saturation_arithmetic
+# error "__cpp_lib_saturation_arithmetic should be defined in c++26"
+# endif
+# if __cpp_lib_saturation_arithmetic != 202311L
+# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26"
# endif
#endif // TEST_STD_VER > 23
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index d5a0839b30f824..edb36da28bbe15 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -7167,17 +7167,11 @@
# error "__cpp_lib_sample should have the value 201603L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_saturation_arithmetic
-# error "__cpp_lib_saturation_arithmetic should be defined in c++26"
-# endif
-# if __cpp_lib_saturation_arithmetic != 202311L
-# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_saturation_arithmetic
-# error "__cpp_lib_saturation_arithmetic should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_saturation_arithmetic
+# error "__cpp_lib_saturation_arithmetic should be defined in c++26"
+# endif
+# if __cpp_lib_saturation_arithmetic != 202311L
+# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26"
# endif
# ifndef __cpp_lib_scoped_lock
diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.pass.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.pass.cpp
new file mode 100644
index 00000000000000..ccd3594fd3a652
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.pass.cpp
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <numeric>
+
+// template<class T>
+// constexpr T add_sat(T x, T y) noexcept; // freestanding
+
+#include <cassert>
+#include <concepts>
+#include <limits>
+#include <numeric>
+
+template <typename IntegerT>
+constexpr bool test_signed() {
+ constexpr auto minVal = std::numeric_limits<IntegerT>::min();
+ constexpr auto maxVal = std::numeric_limits<IntegerT>::max();
+
+ static_assert(noexcept(std::div_sat(minVal, maxVal)));
+
+ // No saturation
+ {
+ std::same_as<IntegerT> decltype(auto) sum = std::add_sat(IntegerT{3}, IntegerT{4});
+ assert(sum == IntegerT{7});
+ }
+
+ {
+ std::same_as<IntegerT> decltype(auto) sum = std::add_sat(IntegerT{-3}, IntegerT{4});
+ assert(sum == IntegerT{1});
+ }
+
+ // Saturation - max - both arguments positive
+ {
+ std::same_as<IntegerT> decltype(auto) sum = std::add_sat(maxVal, IntegerT{4});
+ assert(sum == maxVal);
+ }
+
+ // Saturation - min - both arguments negative
+ {
+ std::same_as<IntegerT> decltype(auto) sum = std::add_sat(minVal, IntegerT{-4});
+ assert(sum == minVal);
+ }
+
+ return true;
+}
+
+template <typename IntegerT>
+constexpr bool test_unsigned() {
+ constexpr auto minVal = std::numeric_limits<IntegerT>::min();
+ constexpr auto maxVal = std::numeric_limits<IntegerT>::max();
+
+ static_assert(noexcept(std::div_sat(minVal, maxVal)));
+
+ // No Saturation
+ {
+ std::same_as<IntegerT> decltype(auto) sum = std::add_sat(IntegerT{3}, IntegerT{4});
+ assert(sum == IntegerT{7});
+ }
+
+ // Saturation - max only
+ {
+ std::same_as<IntegerT> decltype(auto) sum = std::add_sat(maxVal, IntegerT{4});
+ assert(sum == maxVal);
+ }
+
+ return true;
+}
+
+constexpr bool test() {
+ // Signed
+ test_signed<signed char>();
+ test_signed<short int>();
+ test_signed<int>();
+ test_signed<long int>();
+ test_signed<long long int>();
+ // Unsigned
+ test_unsigned<unsigned char>();
+ test_unsigned<unsigned short int>();
+ test_unsigned<unsigned int>();
+ test_unsigned<unsigned long int>();
+ test_unsigned<unsigned long long int>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.verify.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.verify.cpp
new file mode 100644
index 00000000000000..b05b30abea6fdb
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.verify.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <numeric>
+
+// template<class T>
+// constexpr T add_sat(T x, T y) noexcept; // freestanding
+
+#include <cstdint>
+#include <numeric>
+
+#include "test_macros.h"
+
+template <typename IntegerT>
+constexpr void test_constraint() {
+ // expected-error-re@*:* 0-2 {{constant expression evaluates to {{.*}} which cannot be narrowed to type {{.*}}}}
+ // expected-error@*:* 0-3 {{no matching function for call to 'add_sat'}}
+ // expected-error@*:* 0-2 {{expected unqualified-id}}
+ [[maybe_unused]] auto sum = std::add_sat(IntegerT{3}, IntegerT{4});
+}
+
+constexpr bool test() {
+ test_constraint<bool>();
+ test_constraint<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_constraint<wchar_t>();
+#endif
+ test_constraint<std::char16_t>();
+ test_constraint<std::char32_t>();
+
+ return true;
+}
diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.assert.pass.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.assert.pass.cpp
new file mode 100644
index 00000000000000..98616d2c1c427c
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.assert.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: availability-verbose_abort-missing
+
+// <numeric>
+
+// template<class T>
+// constexpr T div_sat(T x, T y) noexcept; // freestanding
+
+#include <cassert>
+#include <concepts>
+#include <limits>
+#include <numeric>
+
+#include "check_assertion.h"
+
+template <typename IntegerT>
+constexpr void test() {
+ TEST_LIBCPP_ASSERT_FAILURE((void)std::div_sat(IntegerT{3}, IntegerT{0}), "Division by 0 is undefined");
+}
+
+constexpr bool test() {
+ // signed
+ test<signed char>();
+ test<short int>();
+ test<int>();
+ test<long int>();
+ test<long long int>();
+ // unsigned
+ test<unsigned char>();
+ test<unsigned short int>();
+ test<unsigned int>();
+ test<unsigned long int>();
+ test<unsigned long long int>();
+
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.pass.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.pass.cpp
new file mode 100644
index 00000000000000..d2891f77c564fa
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.pass.cpp
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--------------------------------------------------...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this. I'm happy to accept the patch without 128-bit integral support and add that later.
I have not looked closely at the tests, I'd like a bit more test cases before looking at all of them.
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.verify.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.assert.pass.cpp
Show resolved
Hide resolved
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/mul_sat.verify.cpp
Outdated
Show resolved
Hide resolved
Thank you for the review! |
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/div_sat.pass.cpp
Outdated
Show resolved
Hide resolved
I did some re-imagining of the tests, there is a some redundancy but it is cleared that nothing was missed. If the above is unacceptable, it can be fixed easily. For now it makes it easier to read and review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did some re-imagining of the tests, there is a some redundancy but it is cleared that nothing was missed. The tests are formatted in tabular form manually to make them easier to read.
Redundant code in tests when if improves readability is not too bad. I really like how the new testing code looks. It was a lot easier to follow. Thanks a lot!
I also used the Clang 18's "Placeholder variables with no name" to make the test a bit cleaner, so I disabled the unsupported compilers.
If the above is unacceptable, it can be fixed easily. For now it makes it easier to read and review.
IMO we should not disable tests for compilers, only for the reason to be able to use newer language features in the test. Note if the header requires language features I'm fine to disable that for a compiler. In this case we can easily allow clang-17 with a minor change as pointed out in the review.
The patch is getting close to be ready.
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/add_sat.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/saturate_cast.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/saturate_cast.pass.cpp
Outdated
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo one typo.
libcxx/test/std/numerics/numeric.ops/numeric.ops.sat/saturate_cast.pass.cpp
Outdated
Show resolved
Hide resolved
…cast.pass.cpp Co-authored-by: Mark de Wever <zar-rpg@xs4all.nl>
@Zingam ,
|
@H-G-Hristov, @Zingam any updates? |
Looks like I see the problem. The test configuration must be updated on the builder. |
Implements: https://wg21.link/P0543R3
Additional references:
Depends on: #78086