[libcxx-commits] [libcxx] [libc++][C++26] P2562R1: `constexpr` Stable Sorting (PR #110320)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Nov 9 04:05:29 PST 2024
https://github.com/PaulXiCao updated https://github.com/llvm/llvm-project/pull/110320
>From 477f2f38a97cd0075869857b7ef956bf04c059bf Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 27 Sep 2024 21:36:37 +0200
Subject: [PATCH 01/20] constexpr stable_sort
---
libcxx/include/__algorithm/sort.h | 2 +-
libcxx/include/__algorithm/stable_sort.h | 48 +++++++++++++-----------
libcxx/include/__memory/destruct_n.h | 20 +++++-----
3 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h
index 0b2137dee2f77e..2e858fd15022d8 100644
--- a/libcxx/include/__algorithm/sort.h
+++ b/libcxx/include/__algorithm/sort.h
@@ -283,7 +283,7 @@ __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last,
// Sort the iterator range [__first, __last) using the comparator __comp using
// the insertion sort algorithm.
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
using _Ops = _IterOps<_AlgPolicy>;
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index ec556aad82e8d8..4f7f8b7615781c 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -68,7 +68,7 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
}
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2>
-_LIBCPP_HIDE_FROM_ABI void __merge_move_construct(
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
_InputIterator1 __first1,
_InputIterator1 __last1,
_InputIterator2 __first2,
@@ -106,7 +106,7 @@ _LIBCPP_HIDE_FROM_ABI void __merge_move_construct(
}
template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI void __merge_move_assign(
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_assign(
_InputIterator1 __first1,
_InputIterator1 __last1,
_InputIterator2 __first2,
@@ -134,19 +134,21 @@ _LIBCPP_HIDE_FROM_ABI void __merge_move_assign(
}
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
-void __stable_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Compare __comp,
- typename iterator_traits<_RandomAccessIterator>::difference_type __len,
- typename iterator_traits<_RandomAccessIterator>::value_type* __buff,
- ptrdiff_t __buff_size);
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
+ _RandomAccessIterator __first,
+ _RandomAccessIterator __last,
+ _Compare __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+ typename iterator_traits<_RandomAccessIterator>::value_type* __buff,
+ ptrdiff_t __buff_size);
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
-void __stable_sort_move(_RandomAccessIterator __first1,
- _RandomAccessIterator __last1,
- _Compare __comp,
- typename iterator_traits<_RandomAccessIterator>::difference_type __len,
- typename iterator_traits<_RandomAccessIterator>::value_type* __first2) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort_move(
+ _RandomAccessIterator __first1,
+ _RandomAccessIterator __last1,
+ _Compare __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+ typename iterator_traits<_RandomAccessIterator>::value_type* __first2) {
using _Ops = _IterOps<_AlgPolicy>;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
@@ -190,12 +192,13 @@ struct __stable_sort_switch {
};
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
-void __stable_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Compare __comp,
- typename iterator_traits<_RandomAccessIterator>::difference_type __len,
- typename iterator_traits<_RandomAccessIterator>::value_type* __buff,
- ptrdiff_t __buff_size) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
+ _RandomAccessIterator __first,
+ _RandomAccessIterator __last,
+ _Compare __comp,
+ typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+ typename iterator_traits<_RandomAccessIterator>::value_type* __buff,
+ ptrdiff_t __buff_size) {
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
switch (__len) {
@@ -235,7 +238,7 @@ void __stable_sort(_RandomAccessIterator __first,
}
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
__stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
@@ -254,13 +257,14 @@ __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last,
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
}
template <class _RandomAccessIterator>
-inline _LIBCPP_HIDE_FROM_ABI void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::stable_sort(__first, __last, __less<>());
}
diff --git a/libcxx/include/__memory/destruct_n.h b/libcxx/include/__memory/destruct_n.h
index 78635ad0af04bd..1445a909162d32 100644
--- a/libcxx/include/__memory/destruct_n.h
+++ b/libcxx/include/__memory/destruct_n.h
@@ -25,35 +25,35 @@ struct __destruct_n {
size_t __size_;
template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI void __process(_Tp* __p, false_type) _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __process(_Tp* __p, false_type) _NOEXCEPT {
for (size_t __i = 0; __i < __size_; ++__i, ++__p)
__p->~_Tp();
}
template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI void __process(_Tp*, true_type) _NOEXCEPT {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __process(_Tp*, true_type) _NOEXCEPT {}
- _LIBCPP_HIDE_FROM_ABI void __incr(false_type) _NOEXCEPT { ++__size_; }
- _LIBCPP_HIDE_FROM_ABI void __incr(true_type) _NOEXCEPT {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __incr(false_type) _NOEXCEPT { ++__size_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __incr(true_type) _NOEXCEPT {}
- _LIBCPP_HIDE_FROM_ABI void __set(size_t __s, false_type) _NOEXCEPT { __size_ = __s; }
- _LIBCPP_HIDE_FROM_ABI void __set(size_t, true_type) _NOEXCEPT {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __set(size_t __s, false_type) _NOEXCEPT { __size_ = __s; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __set(size_t, true_type) _NOEXCEPT {}
public:
- _LIBCPP_HIDE_FROM_ABI explicit __destruct_n(size_t __s) _NOEXCEPT : __size_(__s) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __destruct_n(size_t __s) _NOEXCEPT : __size_(__s) {}
template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI void __incr() _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __incr() _NOEXCEPT {
__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());
}
template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI void __set(size_t __s, _Tp*) _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __set(size_t __s, _Tp*) _NOEXCEPT {
__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());
}
template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void operator()(_Tp* __p) _NOEXCEPT {
__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());
}
};
>From 5dbcf56fa84f73fcab779edd480d7d7de5b4acee Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 27 Sep 2024 21:36:54 +0200
Subject: [PATCH 02/20] tests
---
.../alg.sort/stable.sort/stable_sort.pass.cpp | 233 ++++++++++++------
1 file changed, 163 insertions(+), 70 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index 4301d22027de85..92803c89dbcb7c 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -14,7 +14,9 @@
// void
// stable_sort(Iter first, Iter last);
+#include <__config>
#include <algorithm>
+#include <array>
#include <cassert>
#include <iterator>
#include <random>
@@ -23,8 +25,6 @@
#include "count_new.h"
#include "test_macros.h"
-std::mt19937 randomness;
-
template <class RI>
void
test_sort_helper(RI f, RI l)
@@ -80,66 +80,149 @@ test_sort_()
}
}
-void
-test_larger_sorts(int N, int M)
-{
- assert(N != 0);
- assert(M != 0);
- // create array length N filled with M different numbers
- int* array = new int[N];
- int x = 0;
- for (int i = 0; i < N; ++i)
- {
- array[i] = x;
- if (++x == M)
- x = 0;
+template <int N, int M>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> init_saw_tooth_pattern() {
+ std::array<int, N> array;
+ for (int i = 0, x = 0; i < N; ++i) {
+ array[i] = x;
+ if (++x == M)
+ x = 0;
+ }
+ return array;
+}
+
+template <int N, int M>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> sort_saw_tooth_pattern() {
+ std::array<int, N> array = init_saw_tooth_pattern<N, M>();
+ std::stable_sort(array.begin(), array.end());
+ return array;
+}
+
+template <int N, int M>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> sort_already_sorted() {
+ std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ std::stable_sort(array.begin(), array.end());
+ return array;
+}
+
+template <int N, int M>
+std::array<int, N> sort_reversely_sorted() {
+ std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ std::reverse(array.begin(), array.end());
+ std::stable_sort(array.begin(), array.end());
+ return array;
+}
+
+template <int N, int M>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> sort_swapped_sorted_ranges() {
+ std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ std::swap_ranges(array.begin(), array.begin() + N / 2, array.begin() + N / 2);
+ std::stable_sort(array.begin(), array.end());
+ return array;
+}
+
+template <int N, int M>
+std::array<int, N> sort_reversely_swapped_sorted_ranges() {
+ std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ std::reverse(array.begin(), array.end());
+ std::swap_ranges(array.begin(), array.begin() + N / 2, array.begin() + N / 2);
+ std::stable_sort(array.begin(), array.end());
+ return array;
+}
+
+#if _LIBCPP_STD_VER >= 26
+# define COMPILE_OR_RUNTIME_ASSERT(func) \
+ if consteval { \
+ static_assert(func); \
+ } else { \
+ assert(func); \
}
- // test saw tooth pattern
- std::stable_sort(array, array+N);
- assert(std::is_sorted(array, array+N));
- // test random pattern
- std::shuffle(array, array+N, randomness);
- std::stable_sort(array, array+N);
- assert(std::is_sorted(array, array+N));
- // test sorted pattern
- std::stable_sort(array, array+N);
- assert(std::is_sorted(array, array+N));
- // test reverse sorted pattern
- std::reverse(array, array+N);
- std::stable_sort(array, array+N);
- assert(std::is_sorted(array, array+N));
- // test swap ranges 2 pattern
- std::swap_ranges(array, array+N/2, array+N/2);
- std::stable_sort(array, array+N);
- assert(std::is_sorted(array, array+N));
- // test reverse swap ranges 2 pattern
- std::reverse(array, array+N);
- std::swap_ranges(array, array+N/2, array+N/2);
- std::stable_sort(array, array+N);
- assert(std::is_sorted(array, array+N));
- delete [] array;
+#else
+# define COMPILE_OR_RUNTIME_ASSERT(func) assert(func);
+#endif
+
+template <int N, int M>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
+ static_assert(N > 0, "");
+ static_assert(M > 0, "");
+
+ { // test saw tooth pattern
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
+ }
+
+#if _LIBCPP_STD_VER >= 26
+ if !consteval
+#endif
+ { // test random pattern
+ // random-number generators not constexpr-friendly
+ static std::mt19937 randomness;
+ std::array<int, N> array = init_saw_tooth_pattern<N, M>();
+ std::shuffle(array.begin(), array.end(), randomness);
+ std::stable_sort(array.begin(), array.end());
+ assert(std::is_sorted(array.begin(), array.end()));
+ }
+
+ { // test sorted pattern
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> array = sort_already_sorted<N, M>();
+ COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
+ }
+
+#if _LIBCPP_STD_VER >= 26
+ if !consteval
+#endif
+ { // test reverse sorted pattern
+ // consteval error: "constexpr evaluation hit maximum step limit"
+ std::array<int, N> array = sort_reversely_sorted<N, M>();
+ assert(std::is_sorted(array.begin(), array.end()));
+ }
+
+ { // test swap ranges 2 pattern
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> array = sort_swapped_sorted_ranges<N, M>();
+ COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
+ }
+
+#if _LIBCPP_STD_VER >= 26
+ if !consteval
+#endif
+ { // test reverse swap ranges 2 pattern
+ // consteval error: "constexpr evaluation hit maximum step limit"
+ std::array<int, N> array = sort_reversely_swapped_sorted_ranges<N, M>();
+ assert(std::is_sorted(array.begin(), array.end()));
+ }
}
-void
-test_larger_sorts(int N)
-{
- test_larger_sorts(N, 1);
- test_larger_sorts(N, 2);
- test_larger_sorts(N, 3);
- test_larger_sorts(N, N/2-1);
- test_larger_sorts(N, N/2);
- test_larger_sorts(N, N/2+1);
- test_larger_sorts(N, N-2);
- test_larger_sorts(N, N-1);
- test_larger_sorts(N, N);
+template <int N>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
+ test_larger_sorts<N, 1>();
+ test_larger_sorts<N, 2>();
+ test_larger_sorts<N, 3>();
+ test_larger_sorts<N, N / 2 - 1>();
+ test_larger_sorts<N, N / 2>();
+ test_larger_sorts<N, N / 2 + 1>();
+ test_larger_sorts<N, N - 2>();
+ test_larger_sorts<N, N - 1>();
+ test_larger_sorts<N, N>();
}
-int main(int, char**)
-{
- // test null range
+#if _LIBCPP_STD_VER >= 26
+# define COMPILE_AND_RUNTIME_CALL(func) \
+ func; \
+ static_assert((func, true));
+#else
+# define COMPILE_AND_RUNTIME_CALL(func) func;
+#endif
+
+int main(int, char**) {
+ { // test null range
int d = 0;
std::stable_sort(&d, &d);
- // exhaustively test all possibilities up to length 8
+#if _LIBCPP_STD_VER >= 26
+ static_assert((std::stable_sort(&d, &d), true));
+#endif
+ }
+
+ { // exhaustively test all possibilities up to length 8
test_sort_<1>();
test_sort_<2>();
test_sort_<3>();
@@ -148,22 +231,32 @@ int main(int, char**)
test_sort_<6>();
test_sort_<7>();
test_sort_<8>();
+ }
- test_larger_sorts(256);
- test_larger_sorts(257);
- test_larger_sorts(499);
- test_larger_sorts(500);
- test_larger_sorts(997);
- test_larger_sorts(1000);
- test_larger_sorts(1009);
-
-#if !defined(TEST_HAS_NO_EXCEPTIONS)
- { // check that the algorithm works without memory
- std::vector<int> vec(150, 3);
- getGlobalMemCounter()->throw_after = 0;
- std::stable_sort(vec.begin(), vec.end());
- }
-#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+ { // larger sorts
+ // run- and conditionally compile-time tests
+ test_larger_sorts<256>();
+ test_larger_sorts<257>();
+#if _LIBCPP_STD_VER >= 26
+ static_assert((test_larger_sorts<256>(), true));
+ static_assert((test_larger_sorts<257>(), true));
+#endif
+
+ // only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
+ test_larger_sorts<499>();
+ test_larger_sorts<500>();
+ test_larger_sorts<997>();
+ test_larger_sorts<1000>();
+ test_larger_sorts<1009>();
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // check that the algorithm works without memory
+ std::vector<int> vec(150, 3);
+ getGlobalMemCounter()->throw_after = 0;
+ std::stable_sort(vec.begin(), vec.end());
+ }
+#endif
return 0;
}
>From 0733a85daccad052dac87920045b3ad2459fa60b Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 27 Sep 2024 21:48:37 +0200
Subject: [PATCH 03/20] update algorithm synopsis
---
libcxx/include/algorithm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 17d63ce0cf1c0f..fd80bd7150829d 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -1530,11 +1530,11 @@ template <class RandomAccessIterator, class Compare>
sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
template <class RandomAccessIterator>
- void
+ constexpr void // constexpr in C++26
stable_sort(RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
- void
+ constexpr void // constexpr in C++26
stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
template <class RandomAccessIterator>
>From db314e2b7ce99b93ce4a19c75e022d8c5f91ecab Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 27 Sep 2024 21:50:51 +0200
Subject: [PATCH 04/20] update docs
---
libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 8864b1ebe28891..a780c721f63d96 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -2,7 +2,7 @@
"`P2497R0 <https://wg21.link/P2497R0>`__","Testing for success or failure of ``<charconv>`` functions","2023-06 (Varna)","|Complete|","18.0",""
"`P2592R3 <https://wg21.link/P2592R3>`__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","","",""
"`P2587R3 <https://wg21.link/P2587R3>`__","``to_string`` or not ``to_string``","2023-06 (Varna)","","",""
-"`P2562R1 <https://wg21.link/P2562R1>`__","``constexpr`` Stable Sorting","2023-06 (Varna)","","",""
+"`P2562R1 <https://wg21.link/P2562R1>`__","``constexpr`` Stable Sorting","2023-06 (Varna)","|Complete|","20.0",""
"`P2545R4 <https://wg21.link/P2545R4>`__","Read-Copy Update (RCU)","2023-06 (Varna)","","",""
"`P2530R3 <https://wg21.link/P2530R3>`__","Hazard Pointers for C++26","2023-06 (Varna)","","",""
"`P2538R1 <https://wg21.link/P2538R1>`__","ADL-proof ``std::projected``","2023-06 (Varna)","|Complete|","18.0",""
>From 8221f443f8a5eedbbadfcf55502db4aae1af4942 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Wed, 2 Oct 2024 22:39:53 +0200
Subject: [PATCH 05/20] paper status: partial
---
libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index a780c721f63d96..8bdf7464e22e40 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -2,7 +2,7 @@
"`P2497R0 <https://wg21.link/P2497R0>`__","Testing for success or failure of ``<charconv>`` functions","2023-06 (Varna)","|Complete|","18.0",""
"`P2592R3 <https://wg21.link/P2592R3>`__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","","",""
"`P2587R3 <https://wg21.link/P2587R3>`__","``to_string`` or not ``to_string``","2023-06 (Varna)","","",""
-"`P2562R1 <https://wg21.link/P2562R1>`__","``constexpr`` Stable Sorting","2023-06 (Varna)","|Complete|","20.0",""
+"`P2562R1 <https://wg21.link/P2562R1>`__","``constexpr`` Stable Sorting","2023-06 (Varna)","|Partial|","20.0",""
"`P2545R4 <https://wg21.link/P2545R4>`__","Read-Copy Update (RCU)","2023-06 (Varna)","","",""
"`P2530R3 <https://wg21.link/P2530R3>`__","Hazard Pointers for C++26","2023-06 (Varna)","","",""
"`P2538R1 <https://wg21.link/P2538R1>`__","ADL-proof ``std::projected``","2023-06 (Varna)","|Complete|","18.0",""
>From 7abb0b8a40979bf24b1ef0e3eb30561d7f0ddaa8 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 4 Oct 2024 19:13:04 +0200
Subject: [PATCH 06/20] remove include of internal header
---
.../alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index 92803c89dbcb7c..14560a98fff727 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -14,7 +14,6 @@
// void
// stable_sort(Iter first, Iter last);
-#include <__config>
#include <algorithm>
#include <array>
#include <cassert>
>From da3173c7f23fce94b0e17873c3a8f397b340c378 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 4 Oct 2024 19:15:42 +0200
Subject: [PATCH 07/20] replace _LIBCPP_CONSTEXPR_SINCE_CXX26 by
TEST_CONSTEXPR_CXX26
---
.../alg.sort/stable.sort/stable_sort.pass.cpp | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index 14560a98fff727..89cf06bad3046a 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -80,7 +80,7 @@ test_sort_()
}
template <int N, int M>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> init_saw_tooth_pattern() {
+TEST_CONSTEXPR_CXX26 std::array<int, N> init_saw_tooth_pattern() {
std::array<int, N> array;
for (int i = 0, x = 0; i < N; ++i) {
array[i] = x;
@@ -91,14 +91,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> init_saw_tooth_pattern() {
}
template <int N, int M>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> sort_saw_tooth_pattern() {
+TEST_CONSTEXPR_CXX26 std::array<int, N> sort_saw_tooth_pattern() {
std::array<int, N> array = init_saw_tooth_pattern<N, M>();
std::stable_sort(array.begin(), array.end());
return array;
}
template <int N, int M>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> sort_already_sorted() {
+TEST_CONSTEXPR_CXX26 std::array<int, N> sort_already_sorted() {
std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
std::stable_sort(array.begin(), array.end());
return array;
@@ -113,7 +113,7 @@ std::array<int, N> sort_reversely_sorted() {
}
template <int N, int M>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> sort_swapped_sorted_ranges() {
+TEST_CONSTEXPR_CXX26 std::array<int, N> sort_swapped_sorted_ranges() {
std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
std::swap_ranges(array.begin(), array.begin() + N / 2, array.begin() + N / 2);
std::stable_sort(array.begin(), array.end());
@@ -141,12 +141,12 @@ std::array<int, N> sort_reversely_swapped_sorted_ranges() {
#endif
template <int N, int M>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
+TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
static_assert(N > 0, "");
static_assert(M > 0, "");
{ // test saw tooth pattern
- _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ TEST_CONSTEXPR_CXX26 std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
}
@@ -163,7 +163,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
}
{ // test sorted pattern
- _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> array = sort_already_sorted<N, M>();
+ TEST_CONSTEXPR_CXX26 std::array<int, N> array = sort_already_sorted<N, M>();
COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
}
@@ -177,7 +177,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
}
{ // test swap ranges 2 pattern
- _LIBCPP_CONSTEXPR_SINCE_CXX26 std::array<int, N> array = sort_swapped_sorted_ranges<N, M>();
+ TEST_CONSTEXPR_CXX26 std::array<int, N> array = sort_swapped_sorted_ranges<N, M>();
COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
}
@@ -192,7 +192,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
}
template <int N>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 void test_larger_sorts() {
+TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
test_larger_sorts<N, 1>();
test_larger_sorts<N, 2>();
test_larger_sorts<N, 3>();
>From 5f518d27f7a363b6ca468669899eae26174cfa83 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 4 Oct 2024 19:14:05 +0200
Subject: [PATCH 08/20] documentation: use proper function declaration
---
.../alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index 89cf06bad3046a..cb32174a2ca0c5 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -8,11 +8,9 @@
// <algorithm>
-// template<RandomAccessIterator Iter>
-// requires ShuffleIterator<Iter>
-// && LessThanComparable<Iter::value_type>
-// void
-// stable_sort(Iter first, Iter last);
+// template <class RandomAccessIterator>
+// constexpr void // constexpr in C++26
+// stable_sort(RandomAccessIterator first, RandomAccessIterator last);
#include <algorithm>
#include <array>
>From 693c338552ca78a69163b8428230fe6305d1b13f Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sat, 5 Oct 2024 22:13:23 +0200
Subject: [PATCH 09/20] workaround for gcc bug with placement new
---
libcxx/include/__algorithm/stable_sort.h | 38 ++++++++++++++++--------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 4f7f8b7615781c..feb28c69a8175b 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -34,6 +34,18 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
+# define __STABLE_SORT_NEW(__placement_args, __type, __new_initializer) \
+ do { \
+ [__placement_args] { ::new (__placement_args) __type(__new_initializer); }(); \
+ } while (0)
+#else
+# define __STABLE_SORT_NEW(__placement_args, __type, __new_initializer) \
+ do { \
+ ::new (__placement_args) __type(__new_initializer); \
+ } while (0)
+#endif
+
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
_BidirectionalIterator __first1,
@@ -47,19 +59,19 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
value_type* __last2 = __first2;
- ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__last2, value_type, _Ops::__iter_move(__first1));
__d.template __incr<value_type>();
for (++__last2; ++__first1 != __last1; ++__last2) {
value_type* __j2 = __last2;
value_type* __i2 = __j2;
if (__comp(*__first1, *--__i2)) {
- ::new ((void*)__j2) value_type(std::move(*__i2));
+ __STABLE_SORT_NEW((void*)__j2, value_type, std::move(*__i2));
__d.template __incr<value_type>();
for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
*__j2 = std::move(*__i2);
*__j2 = _Ops::__iter_move(__first1);
} else {
- ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__j2, value_type, _Ops::__iter_move(__first1));
__d.template __incr<value_type>();
}
}
@@ -83,22 +95,22 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
for (; true; ++__result) {
if (__first1 == __last1) {
for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr<value_type>())
- ::new ((void*)__result) value_type(_Ops::__iter_move(__first2));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first2));
__h.release();
return;
}
if (__first2 == __last2) {
for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr<value_type>())
- ::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first1));
__h.release();
return;
}
if (__comp(*__first2, *__first1)) {
- ::new ((void*)__result) value_type(_Ops::__iter_move(__first2));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first2));
__d.template __incr<value_type>();
++__first2;
} else {
- ::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first1));
__d.template __incr<value_type>();
++__first1;
}
@@ -156,21 +168,21 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort_move(
case 0:
return;
case 1:
- ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__first1));
return;
case 2:
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
if (__comp(*--__last1, *__first1)) {
- ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__last1));
__d.template __incr<value_type>();
++__first2;
- ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__first1));
} else {
- ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__first1));
__d.template __incr<value_type>();
++__first2;
- ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__last1));
}
__h2.release();
return;
@@ -268,8 +280,8 @@ stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::stable_sort(__first, __last, __less<>());
}
+#undef __STABLE_SORT_NEW
_LIBCPP_END_NAMESPACE_STD
-
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_STABLE_SORT_H
>From e401b3c438cdec9f5ff99f9a7986ac9f9bd9c0bb Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 6 Oct 2024 15:00:48 +0200
Subject: [PATCH 10/20] workaround for gcc bug with placement new: fix lambda
capturing
---
libcxx/include/__algorithm/stable_sort.h | 40 ++++++++++++++----------
1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index feb28c69a8175b..7ad8c36b19e077 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -34,15 +34,22 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+#define __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
+ do { \
+ ::new (__placement_arg) __type(__new_initializer_func(__new_initializer_arg)); \
+ } while (0)
+
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
-# define __STABLE_SORT_NEW(__placement_args, __type, __new_initializer) \
+# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
do { \
- [__placement_args] { ::new (__placement_args) __type(__new_initializer); }(); \
+ [__placement_arg, &__new_initializer_arg] { \
+ __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg); \
+ }(); \
} while (0)
#else
-# define __STABLE_SORT_NEW(__placement_args, __type, __new_initializer) \
+# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
do { \
- ::new (__placement_args) __type(__new_initializer); \
+ __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg); \
} while (0)
#endif
@@ -59,19 +66,19 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
value_type* __last2 = __first2;
- __STABLE_SORT_NEW((void*)__last2, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__last2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
for (++__last2; ++__first1 != __last1; ++__last2) {
value_type* __j2 = __last2;
value_type* __i2 = __j2;
if (__comp(*__first1, *--__i2)) {
- __STABLE_SORT_NEW((void*)__j2, value_type, std::move(*__i2));
+ __STABLE_SORT_NEW((void*)__j2, value_type, std::move, *__i2);
__d.template __incr<value_type>();
for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
*__j2 = std::move(*__i2);
*__j2 = _Ops::__iter_move(__first1);
} else {
- __STABLE_SORT_NEW((void*)__j2, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__j2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
}
}
@@ -95,22 +102,22 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
for (; true; ++__result) {
if (__first1 == __last1) {
for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr<value_type>())
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first2));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first2);
__h.release();
return;
}
if (__first2 == __last2) {
for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr<value_type>())
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first1);
__h.release();
return;
}
if (__comp(*__first2, *__first1)) {
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first2));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first2);
__d.template __incr<value_type>();
++__first2;
} else {
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
++__first1;
}
@@ -168,21 +175,21 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort_move(
case 0:
return;
case 1:
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __first1);
return;
case 2:
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
if (__comp(*--__last1, *__first1)) {
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__last1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __last1);
__d.template __incr<value_type>();
++__first2;
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __first1);
} else {
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__first1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
++__first2;
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move(__last1));
+ __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __last1);
}
__h2.release();
return;
@@ -281,6 +288,7 @@ stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
}
#undef __STABLE_SORT_NEW
+#undef __STABLE_SORT_NEW_IMPL
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
>From 514ecdb5b65a564085f6addb7901ce8b26ca0fe2 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 6 Oct 2024 21:16:33 +0200
Subject: [PATCH 11/20] workaround for gcc bug with placement new: v3
---
libcxx/include/__algorithm/stable_sort.h | 33 ++++++++++++------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 7ad8c36b19e077..2fe78c0346a9c7 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -34,20 +34,21 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+// Workaround for "constexpr placement new" bug in gcc (fixed in 14.2).
+// See https://github.com/llvm/llvm-project/pull/110320#discussion_r1788557715.
#define __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
do { \
- ::new (__placement_arg) __type(__new_initializer_func(__new_initializer_arg)); \
+ ::new ((void*)__placement_arg) __type(__new_initializer_func(__new_initializer_arg)); \
} while (0)
-
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
do { \
- [__placement_arg, &__new_initializer_arg] { \
+ [__placement_arg, &__new_initializer_arg] { \
__STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg); \
}(); \
} while (0)
#else
-# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
+# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
do { \
__STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg); \
} while (0)
@@ -66,19 +67,19 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
value_type* __last2 = __first2;
- __STABLE_SORT_NEW((void*)__last2, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__last2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
for (++__last2; ++__first1 != __last1; ++__last2) {
value_type* __j2 = __last2;
value_type* __i2 = __j2;
if (__comp(*__first1, *--__i2)) {
- __STABLE_SORT_NEW((void*)__j2, value_type, std::move, *__i2);
+ __STABLE_SORT_NEW(__j2, value_type, std::move, *__i2);
__d.template __incr<value_type>();
for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
*__j2 = std::move(*__i2);
*__j2 = _Ops::__iter_move(__first1);
} else {
- __STABLE_SORT_NEW((void*)__j2, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__j2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
}
}
@@ -102,22 +103,22 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
for (; true; ++__result) {
if (__first1 == __last1) {
for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr<value_type>())
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first2);
+ __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first2);
__h.release();
return;
}
if (__first2 == __last2) {
for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr<value_type>())
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
__h.release();
return;
}
if (__comp(*__first2, *__first1)) {
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first2);
+ __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first2);
__d.template __incr<value_type>();
++__first2;
} else {
- __STABLE_SORT_NEW((void*)__result, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
++__first1;
}
@@ -175,21 +176,21 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort_move(
case 0:
return;
case 1:
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
return;
case 2:
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
if (__comp(*--__last1, *__first1)) {
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __last1);
+ __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __last1);
__d.template __incr<value_type>();
++__first2;
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
} else {
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __first1);
+ __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
++__first2;
- __STABLE_SORT_NEW((void*)__first2, value_type, _Ops::__iter_move, __last1);
+ __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __last1);
}
__h2.release();
return;
>From 39f2aff5d884d1a7c935a36cf5b893d56305229c Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 6 Oct 2024 21:26:55 +0200
Subject: [PATCH 12/20] workaround for gcc bug with placement new: v4
---
libcxx/include/__algorithm/stable_sort.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 2fe78c0346a9c7..66378042acda72 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -73,7 +73,10 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
value_type* __j2 = __last2;
value_type* __i2 = __j2;
if (__comp(*__first1, *--__i2)) {
- __STABLE_SORT_NEW(__j2, value_type, std::move, *__i2);
+ {
+ value_type& __tmp = *__i2;
+ __STABLE_SORT_NEW(__j2, value_type, std::move, __tmp);
+ }
__d.template __incr<value_type>();
for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
*__j2 = std::move(*__i2);
>From 1fe36c2ccc2de90485a950337903b9e20a025faf Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 11 Oct 2024 21:53:13 +0200
Subject: [PATCH 13/20] workaround for gcc bug with placement new: v5 (test)
---
libcxx/include/__algorithm/stable_sort.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 66378042acda72..73b9da9cfd8a32 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -121,7 +121,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
__d.template __incr<value_type>();
++__first2;
} else {
- __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
+// __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
+#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
+ [__result, &__first1] { ::new (__result) value_type(_Ops::__iter_move(__first1)); }();
+#else
+ ::new (__result) value_type(_Ops::__iter_move(__first1));
+#endif
__d.template __incr<value_type>();
++__first1;
}
>From f6cc51bfdb663ef5e1704d8bf3fd11846ba3a944 Mon Sep 17 00:00:00 2001
From: PaulXiCao <paul.luckner at rwth-aachen.de>
Date: Sat, 12 Oct 2024 09:14:30 +0000
Subject: [PATCH 14/20] workaround for gcc bug with placement new: v6
Co-authored-by: A. Jiang <de34 at live.cn>
---
libcxx/include/__algorithm/stable_sort.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 73b9da9cfd8a32..fb95fcc9ea6fbd 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -123,9 +123,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
} else {
// __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
- [__result, &__first1] { ::new (__result) value_type(_Ops::__iter_move(__first1)); }();
+ [__result, &__first1] { ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); }();
#else
- ::new (__result) value_type(_Ops::__iter_move(__first1));
+ ::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
#endif
__d.template __incr<value_type>();
++__first1;
>From d7c4fa921a8319a42087bf0abd902ddeb20b3997 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 13 Oct 2024 18:57:43 +0200
Subject: [PATCH 15/20] workaround for gcc bug with placement new: v7
---
libcxx/include/__algorithm/stable_sort.h | 50 ++++++++----------------
1 file changed, 17 insertions(+), 33 deletions(-)
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index fb95fcc9ea6fbd..d9428d6672b086 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -36,22 +36,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Workaround for "constexpr placement new" bug in gcc (fixed in 14.2).
// See https://github.com/llvm/llvm-project/pull/110320#discussion_r1788557715.
-#define __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
- do { \
- ::new ((void*)__placement_arg) __type(__new_initializer_func(__new_initializer_arg)); \
- } while (0)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
-# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
- do { \
- [__placement_arg, &__new_initializer_arg] { \
- __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg); \
- }(); \
- } while (0)
+# define _LIBCPP_MOVING_PLACEMENT_NEW(__ptr, __type, __move_func, __iter) \
+ [__ptr, &__iter] { ::new ((void*)__ptr) __type(__move_func(__iter)); }()
#else
-# define __STABLE_SORT_NEW(__placement_arg, __type, __new_initializer_func, __new_initializer_arg) \
- do { \
- __STABLE_SORT_NEW_IMPL(__placement_arg, __type, __new_initializer_func, __new_initializer_arg); \
- } while (0)
+# define _LIBCPP_MOVING_PLACEMENT_NEW(__ptr, __type, __move_func, __iter) \
+ ::new ((void*)__ptr) __type(__move_func(__iter))
#endif
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
@@ -67,7 +57,7 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
value_type* __last2 = __first2;
- __STABLE_SORT_NEW(__last2, value_type, _Ops::__iter_move, __first1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__last2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
for (++__last2; ++__first1 != __last1; ++__last2) {
value_type* __j2 = __last2;
@@ -75,14 +65,14 @@ _LIBCPP_HIDE_FROM_ABI void __insertion_sort_move(
if (__comp(*__first1, *--__i2)) {
{
value_type& __tmp = *__i2;
- __STABLE_SORT_NEW(__j2, value_type, std::move, __tmp);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__j2, value_type, std::move, __tmp);
}
__d.template __incr<value_type>();
for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2)
*__j2 = std::move(*__i2);
*__j2 = _Ops::__iter_move(__first1);
} else {
- __STABLE_SORT_NEW(__j2, value_type, _Ops::__iter_move, __first1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__j2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
}
}
@@ -106,27 +96,22 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __merge_move_construct(
for (; true; ++__result) {
if (__first1 == __last1) {
for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr<value_type>())
- __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first2);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__result, value_type, _Ops::__iter_move, __first2);
__h.release();
return;
}
if (__first2 == __last2) {
for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr<value_type>())
- __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__result, value_type, _Ops::__iter_move, __first1);
__h.release();
return;
}
if (__comp(*__first2, *__first1)) {
- __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first2);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__result, value_type, _Ops::__iter_move, __first2);
__d.template __incr<value_type>();
++__first2;
} else {
-// __STABLE_SORT_NEW(__result, value_type, _Ops::__iter_move, __first1);
-#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 <= 140100)
- [__result, &__first1] { ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); }();
-#else
- ::new ((void*)__result) value_type(_Ops::__iter_move(__first1));
-#endif
+ _LIBCPP_MOVING_PLACEMENT_NEW(__result, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
++__first1;
}
@@ -184,21 +169,21 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort_move(
case 0:
return;
case 1:
- __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
return;
case 2:
__destruct_n __d(0);
unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
if (__comp(*--__last1, *__first1)) {
- __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __last1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__first2, value_type, _Ops::__iter_move, __last1);
__d.template __incr<value_type>();
++__first2;
- __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
} else {
- __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__first2, value_type, _Ops::__iter_move, __first1);
__d.template __incr<value_type>();
++__first2;
- __STABLE_SORT_NEW(__first2, value_type, _Ops::__iter_move, __last1);
+ _LIBCPP_MOVING_PLACEMENT_NEW(__first2, value_type, _Ops::__iter_move, __last1);
}
__h2.release();
return;
@@ -296,8 +281,7 @@ stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::stable_sort(__first, __last, __less<>());
}
-#undef __STABLE_SORT_NEW
-#undef __STABLE_SORT_NEW_IMPL
+#undef _LIBCPP_MOVING_PLACEMENT_NEW
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
>From c3470a27beb71efc855ed8bdc9fe343ce0918ef4 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 13 Oct 2024 19:00:27 +0200
Subject: [PATCH 16/20] test: use TEST_STD_VER
---
.../alg.sort/stable.sort/stable_sort.pass.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index cb32174a2ca0c5..720b93e5d1779c 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -127,7 +127,7 @@ std::array<int, N> sort_reversely_swapped_sorted_ranges() {
return array;
}
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
# define COMPILE_OR_RUNTIME_ASSERT(func) \
if consteval { \
static_assert(func); \
@@ -148,7 +148,7 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
}
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
if !consteval
#endif
{ // test random pattern
@@ -165,7 +165,7 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
}
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
if !consteval
#endif
{ // test reverse sorted pattern
@@ -179,7 +179,7 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
}
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
if !consteval
#endif
{ // test reverse swap ranges 2 pattern
@@ -202,7 +202,7 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
test_larger_sorts<N, N>();
}
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
# define COMPILE_AND_RUNTIME_CALL(func) \
func; \
static_assert((func, true));
@@ -214,7 +214,7 @@ int main(int, char**) {
{ // test null range
int d = 0;
std::stable_sort(&d, &d);
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
static_assert((std::stable_sort(&d, &d), true));
#endif
}
@@ -234,7 +234,7 @@ int main(int, char**) {
// run- and conditionally compile-time tests
test_larger_sorts<256>();
test_larger_sorts<257>();
-#if _LIBCPP_STD_VER >= 26
+#if TEST_STD_VER >= 26
static_assert((test_larger_sorts<256>(), true));
static_assert((test_larger_sorts<257>(), true));
#endif
>From 6bd6297886133ccf22ff68ea927ec87fe3994a63 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 18 Oct 2024 21:19:47 +0200
Subject: [PATCH 17/20] increase constexpr-steps as unstable abi tests cause
more evaluation steps
---
.../alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index 720b93e5d1779c..bcd5155138a169 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -12,6 +12,8 @@
// constexpr void // constexpr in C++26
// stable_sort(RandomAccessIterator first, RandomAccessIterator last);
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000
+
#include <algorithm>
#include <array>
#include <cassert>
@@ -234,14 +236,16 @@ int main(int, char**) {
// run- and conditionally compile-time tests
test_larger_sorts<256>();
test_larger_sorts<257>();
+ test_larger_sorts<499>();
+ test_larger_sorts<500>();
#if TEST_STD_VER >= 26
static_assert((test_larger_sorts<256>(), true));
static_assert((test_larger_sorts<257>(), true));
+ static_assert((test_larger_sorts<499>(), true));
+ static_assert((test_larger_sorts<500>(), true));
#endif
// only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
- test_larger_sorts<499>();
- test_larger_sorts<500>();
test_larger_sorts<997>();
test_larger_sorts<1000>();
test_larger_sorts<1009>();
>From e93a63069067e3779d44f5a2c11d74b16eaac6a3 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Fri, 18 Oct 2024 22:06:51 +0200
Subject: [PATCH 18/20] simplify testing (possible b.c. increase of
constexpr-steps)
---
.../alg.sort/stable.sort/stable_sort.pass.cpp | 53 +++++--------------
1 file changed, 12 insertions(+), 41 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index bcd5155138a169..8302c59ef0ef54 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -12,7 +12,7 @@
// constexpr void // constexpr in C++26
// stable_sort(RandomAccessIterator first, RandomAccessIterator last);
-// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=20000000
#include <algorithm>
#include <array>
@@ -105,7 +105,7 @@ TEST_CONSTEXPR_CXX26 std::array<int, N> sort_already_sorted() {
}
template <int N, int M>
-std::array<int, N> sort_reversely_sorted() {
+TEST_CONSTEXPR_CXX26 std::array<int, N> sort_reversely_sorted() {
std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
std::reverse(array.begin(), array.end());
std::stable_sort(array.begin(), array.end());
@@ -121,7 +121,7 @@ TEST_CONSTEXPR_CXX26 std::array<int, N> sort_swapped_sorted_ranges() {
}
template <int N, int M>
-std::array<int, N> sort_reversely_swapped_sorted_ranges() {
+TEST_CONSTEXPR_CXX26 std::array<int, N> sort_reversely_swapped_sorted_ranges() {
std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
std::reverse(array.begin(), array.end());
std::swap_ranges(array.begin(), array.begin() + N / 2, array.begin() + N / 2);
@@ -129,25 +129,14 @@ std::array<int, N> sort_reversely_swapped_sorted_ranges() {
return array;
}
-#if TEST_STD_VER >= 26
-# define COMPILE_OR_RUNTIME_ASSERT(func) \
- if consteval { \
- static_assert(func); \
- } else { \
- assert(func); \
- }
-#else
-# define COMPILE_OR_RUNTIME_ASSERT(func) assert(func);
-#endif
-
template <int N, int M>
TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
static_assert(N > 0, "");
static_assert(M > 0, "");
{ // test saw tooth pattern
- TEST_CONSTEXPR_CXX26 std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
- COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
+ std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
+ assert(std::is_sorted(array.begin(), array.end()));
}
#if TEST_STD_VER >= 26
@@ -163,29 +152,21 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
}
{ // test sorted pattern
- TEST_CONSTEXPR_CXX26 std::array<int, N> array = sort_already_sorted<N, M>();
- COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
+ std::array<int, N> array = sort_already_sorted<N, M>();
+ assert(std::is_sorted(array.begin(), array.end()));
}
-#if TEST_STD_VER >= 26
- if !consteval
-#endif
{ // test reverse sorted pattern
- // consteval error: "constexpr evaluation hit maximum step limit"
std::array<int, N> array = sort_reversely_sorted<N, M>();
assert(std::is_sorted(array.begin(), array.end()));
}
{ // test swap ranges 2 pattern
- TEST_CONSTEXPR_CXX26 std::array<int, N> array = sort_swapped_sorted_ranges<N, M>();
- COMPILE_OR_RUNTIME_ASSERT(std::is_sorted(array.begin(), array.end()))
+ std::array<int, N> array = sort_swapped_sorted_ranges<N, M>();
+ assert(std::is_sorted(array.begin(), array.end()));
}
-#if TEST_STD_VER >= 26
- if !consteval
-#endif
{ // test reverse swap ranges 2 pattern
- // consteval error: "constexpr evaluation hit maximum step limit"
std::array<int, N> array = sort_reversely_swapped_sorted_ranges<N, M>();
assert(std::is_sorted(array.begin(), array.end()));
}
@@ -204,14 +185,6 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
test_larger_sorts<N, N>();
}
-#if TEST_STD_VER >= 26
-# define COMPILE_AND_RUNTIME_CALL(func) \
- func; \
- static_assert((func, true));
-#else
-# define COMPILE_AND_RUNTIME_CALL(func) func;
-#endif
-
int main(int, char**) {
{ // test null range
int d = 0;
@@ -233,19 +206,17 @@ int main(int, char**) {
}
{ // larger sorts
- // run- and conditionally compile-time tests
+ // run- and compile-time tests
test_larger_sorts<256>();
test_larger_sorts<257>();
- test_larger_sorts<499>();
- test_larger_sorts<500>();
#if TEST_STD_VER >= 26
static_assert((test_larger_sorts<256>(), true));
static_assert((test_larger_sorts<257>(), true));
- static_assert((test_larger_sorts<499>(), true));
- static_assert((test_larger_sorts<500>(), true));
#endif
// only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
+ test_larger_sorts<499>();
+ test_larger_sorts<500>();
test_larger_sorts<997>();
test_larger_sorts<1000>();
test_larger_sorts<1009>();
>From 0e4559e6ec101356213063fe6cc8b9aa8c740def Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sat, 9 Nov 2024 12:56:13 +0100
Subject: [PATCH 19/20] refactor tests: do not extract tests into separate
functions
---
.../alg.sort/stable.sort/stable_sort.pass.cpp | 163 +++++++-----------
1 file changed, 60 insertions(+), 103 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index 8302c59ef0ef54..e924d3562c9246 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -80,96 +80,48 @@ test_sort_()
}
template <int N, int M>
-TEST_CONSTEXPR_CXX26 std::array<int, N> init_saw_tooth_pattern() {
- std::array<int, N> array;
- for (int i = 0, x = 0; i < N; ++i) {
+TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
+ static_assert(N != 0);
+ static_assert(M != 0);
+
+ // create array length N filled with M different numbers
+ std::array<int, N> array_;
+ int* const array = array_.data();
+ int x = 0;
+ for (int i = 0; i < N; ++i) {
array[i] = x;
if (++x == M)
x = 0;
}
- return array;
-}
-
-template <int N, int M>
-TEST_CONSTEXPR_CXX26 std::array<int, N> sort_saw_tooth_pattern() {
- std::array<int, N> array = init_saw_tooth_pattern<N, M>();
- std::stable_sort(array.begin(), array.end());
- return array;
-}
-
-template <int N, int M>
-TEST_CONSTEXPR_CXX26 std::array<int, N> sort_already_sorted() {
- std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
- std::stable_sort(array.begin(), array.end());
- return array;
-}
-
-template <int N, int M>
-TEST_CONSTEXPR_CXX26 std::array<int, N> sort_reversely_sorted() {
- std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
- std::reverse(array.begin(), array.end());
- std::stable_sort(array.begin(), array.end());
- return array;
-}
-
-template <int N, int M>
-TEST_CONSTEXPR_CXX26 std::array<int, N> sort_swapped_sorted_ranges() {
- std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
- std::swap_ranges(array.begin(), array.begin() + N / 2, array.begin() + N / 2);
- std::stable_sort(array.begin(), array.end());
- return array;
-}
-
-template <int N, int M>
-TEST_CONSTEXPR_CXX26 std::array<int, N> sort_reversely_swapped_sorted_ranges() {
- std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
- std::reverse(array.begin(), array.end());
- std::swap_ranges(array.begin(), array.begin() + N / 2, array.begin() + N / 2);
- std::stable_sort(array.begin(), array.end());
- return array;
-}
-
-template <int N, int M>
-TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
- static_assert(N > 0, "");
- static_assert(M > 0, "");
-
- { // test saw tooth pattern
- std::array<int, N> array = sort_saw_tooth_pattern<N, M>();
- assert(std::is_sorted(array.begin(), array.end()));
- }
-
+ // test saw tooth pattern
+ std::stable_sort(array, array + N);
+ assert(std::is_sorted(array, array + N));
+ // test random pattern
#if TEST_STD_VER >= 26
- if !consteval
+ if !consteval // random-number generators not constexpr-friendly
#endif
- { // test random pattern
- // random-number generators not constexpr-friendly
+ {
static std::mt19937 randomness;
- std::array<int, N> array = init_saw_tooth_pattern<N, M>();
- std::shuffle(array.begin(), array.end(), randomness);
- std::stable_sort(array.begin(), array.end());
- assert(std::is_sorted(array.begin(), array.end()));
- }
-
- { // test sorted pattern
- std::array<int, N> array = sort_already_sorted<N, M>();
- assert(std::is_sorted(array.begin(), array.end()));
- }
-
- { // test reverse sorted pattern
- std::array<int, N> array = sort_reversely_sorted<N, M>();
- assert(std::is_sorted(array.begin(), array.end()));
- }
-
- { // test swap ranges 2 pattern
- std::array<int, N> array = sort_swapped_sorted_ranges<N, M>();
- assert(std::is_sorted(array.begin(), array.end()));
- }
-
- { // test reverse swap ranges 2 pattern
- std::array<int, N> array = sort_reversely_swapped_sorted_ranges<N, M>();
- assert(std::is_sorted(array.begin(), array.end()));
+ std::shuffle(array, array + N, randomness);
+ std::stable_sort(array, array + N);
+ assert(std::is_sorted(array, array + N));
}
+ // test sorted pattern
+ std::stable_sort(array, array + N);
+ assert(std::is_sorted(array, array + N));
+ // test reverse sorted pattern
+ std::reverse(array, array + N);
+ std::stable_sort(array, array + N);
+ assert(std::is_sorted(array, array + N));
+ // test swap ranges 2 pattern
+ std::swap_ranges(array, array + N / 2, array + N / 2);
+ std::stable_sort(array, array + N);
+ assert(std::is_sorted(array, array + N));
+ // test reverse swap ranges 2 pattern
+ std::reverse(array, array + N);
+ std::swap_ranges(array, array + N / 2, array + N / 2);
+ std::stable_sort(array, array + N);
+ assert(std::is_sorted(array, array + N));
}
template <int N>
@@ -185,16 +137,16 @@ TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
test_larger_sorts<N, N>();
}
-int main(int, char**) {
- { // test null range
- int d = 0;
- std::stable_sort(&d, &d);
+TEST_CONSTEXPR_CXX26 void test() {
+ // test null range
+ int d = 0;
+ std::stable_sort(&d, &d);
+
+ // exhaustively test all possibilities up to length 8
#if TEST_STD_VER >= 26
- static_assert((std::stable_sort(&d, &d), true));
+ if !consteval
#endif
- }
-
- { // exhaustively test all possibilities up to length 8
+ {
test_sort_<1>();
test_sort_<2>();
test_sort_<3>();
@@ -205,30 +157,35 @@ int main(int, char**) {
test_sort_<8>();
}
- { // larger sorts
- // run- and compile-time tests
- test_larger_sorts<256>();
- test_larger_sorts<257>();
+ test_larger_sorts<256>();
+ test_larger_sorts<257>();
+ test_larger_sorts<499>();
+ test_larger_sorts<500>();
+ test_larger_sorts<997>();
#if TEST_STD_VER >= 26
- static_assert((test_larger_sorts<256>(), true));
- static_assert((test_larger_sorts<257>(), true));
+ if !consteval // only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
#endif
-
- // only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
- test_larger_sorts<499>();
- test_larger_sorts<500>();
- test_larger_sorts<997>();
+ {
test_larger_sorts<1000>();
test_larger_sorts<1009>();
}
-#ifndef TEST_HAS_NO_EXCEPTIONS
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+# if TEST_STD_VER >= 26
+ if !consteval
+# endif
{ // check that the algorithm works without memory
std::vector<int> vec(150, 3);
getGlobalMemCounter()->throw_after = 0;
std::stable_sort(vec.begin(), vec.end());
}
-#endif
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert((test(), true));
+#endif
return 0;
}
>From 6709efc01a033b4b7b3c4ffba3312b911ae0724f Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sat, 9 Nov 2024 13:04:48 +0100
Subject: [PATCH 20/20] tests: match previous formatting
---
.../alg.sort/stable.sort/stable_sort.pass.cpp | 185 +++++++++---------
1 file changed, 96 insertions(+), 89 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
index e924d3562c9246..bcc4505b4c0f3c 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
@@ -80,112 +80,119 @@ test_sort_()
}
template <int N, int M>
-TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
- static_assert(N != 0);
- static_assert(M != 0);
-
- // create array length N filled with M different numbers
- std::array<int, N> array_;
- int* const array = array_.data();
- int x = 0;
- for (int i = 0; i < N; ++i) {
- array[i] = x;
- if (++x == M)
- x = 0;
- }
- // test saw tooth pattern
- std::stable_sort(array, array + N);
- assert(std::is_sorted(array, array + N));
- // test random pattern
+TEST_CONSTEXPR_CXX26
+void
+test_larger_sorts()
+{
+ static_assert(N != 0);
+ static_assert(M != 0);
+ // create array length N filled with M different numbers
+ std::array<int, N> array_;
+ int* array = array_.data();
+ int x = 0;
+ for (int i = 0; i < N; ++i)
+ {
+ array[i] = x;
+ if (++x == M)
+ x = 0;
+ }
+ // test saw tooth pattern
+ std::stable_sort(array, array+N);
+ assert(std::is_sorted(array, array+N));
+ // test random pattern
#if TEST_STD_VER >= 26
- if !consteval // random-number generators not constexpr-friendly
+ if !consteval // random-number generators not constexpr-friendly
#endif
- {
- static std::mt19937 randomness;
- std::shuffle(array, array + N, randomness);
- std::stable_sort(array, array + N);
- assert(std::is_sorted(array, array + N));
- }
- // test sorted pattern
- std::stable_sort(array, array + N);
- assert(std::is_sorted(array, array + N));
- // test reverse sorted pattern
- std::reverse(array, array + N);
- std::stable_sort(array, array + N);
- assert(std::is_sorted(array, array + N));
- // test swap ranges 2 pattern
- std::swap_ranges(array, array + N / 2, array + N / 2);
- std::stable_sort(array, array + N);
- assert(std::is_sorted(array, array + N));
- // test reverse swap ranges 2 pattern
- std::reverse(array, array + N);
- std::swap_ranges(array, array + N / 2, array + N / 2);
- std::stable_sort(array, array + N);
- assert(std::is_sorted(array, array + N));
+ {
+ static std::mt19937 randomness;
+ std::shuffle(array, array+N, randomness);
+ std::stable_sort(array, array+N);
+ assert(std::is_sorted(array, array+N));
+ }
+ // test sorted pattern
+ std::stable_sort(array, array+N);
+ assert(std::is_sorted(array, array+N));
+ // test reverse sorted pattern
+ std::reverse(array, array+N);
+ std::stable_sort(array, array+N);
+ assert(std::is_sorted(array, array+N));
+ // test swap ranges 2 pattern
+ std::swap_ranges(array, array+N/2, array+N/2);
+ std::stable_sort(array, array+N);
+ assert(std::is_sorted(array, array+N));
+ // test reverse swap ranges 2 pattern
+ std::reverse(array, array+N);
+ std::swap_ranges(array, array+N/2, array+N/2);
+ std::stable_sort(array, array+N);
+ assert(std::is_sorted(array, array+N));
}
template <int N>
-TEST_CONSTEXPR_CXX26 void test_larger_sorts() {
- test_larger_sorts<N, 1>();
- test_larger_sorts<N, 2>();
- test_larger_sorts<N, 3>();
- test_larger_sorts<N, N / 2 - 1>();
- test_larger_sorts<N, N / 2>();
- test_larger_sorts<N, N / 2 + 1>();
- test_larger_sorts<N, N - 2>();
- test_larger_sorts<N, N - 1>();
- test_larger_sorts<N, N>();
+TEST_CONSTEXPR_CXX26
+void
+test_larger_sorts()
+{
+ test_larger_sorts<N, 1>();
+ test_larger_sorts<N, 2>();
+ test_larger_sorts<N, 3>();
+ test_larger_sorts<N, N/2-1>();
+ test_larger_sorts<N, N/2>();
+ test_larger_sorts<N, N/2+1>();
+ test_larger_sorts<N, N-2>();
+ test_larger_sorts<N, N-1>();
+ test_larger_sorts<N, N>();
}
-TEST_CONSTEXPR_CXX26 void test() {
- // test null range
- int d = 0;
- std::stable_sort(&d, &d);
-
- // exhaustively test all possibilities up to length 8
+TEST_CONSTEXPR_CXX26 void test()
+{
+ // test null range
+ int d = 0;
+ std::stable_sort(&d, &d);
+
+ // exhaustively test all possibilities up to length 8
#if TEST_STD_VER >= 26
- if !consteval
+ if !consteval
#endif
- {
- test_sort_<1>();
- test_sort_<2>();
- test_sort_<3>();
- test_sort_<4>();
- test_sort_<5>();
- test_sort_<6>();
- test_sort_<7>();
- test_sort_<8>();
- }
-
- test_larger_sorts<256>();
- test_larger_sorts<257>();
- test_larger_sorts<499>();
- test_larger_sorts<500>();
- test_larger_sorts<997>();
+ {
+ test_sort_<1>();
+ test_sort_<2>();
+ test_sort_<3>();
+ test_sort_<4>();
+ test_sort_<5>();
+ test_sort_<6>();
+ test_sort_<7>();
+ test_sort_<8>();
+ }
+
+ test_larger_sorts<256>();
+ test_larger_sorts<257>();
+ test_larger_sorts<499>();
+ test_larger_sorts<500>();
+ test_larger_sorts<997>();
#if TEST_STD_VER >= 26
- if !consteval // only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
+ if !consteval // only runtime tests bc. error: "constexpr evaluation hit maximum step limit"
#endif
- {
- test_larger_sorts<1000>();
- test_larger_sorts<1009>();
- }
+ {
+ test_larger_sorts<1000>();
+ test_larger_sorts<1009>();
+ }
#if !defined(TEST_HAS_NO_EXCEPTIONS)
-# if TEST_STD_VER >= 26
- if !consteval
-# endif
- { // check that the algorithm works without memory
- std::vector<int> vec(150, 3);
- getGlobalMemCounter()->throw_after = 0;
- std::stable_sort(vec.begin(), vec.end());
- }
+#if TEST_STD_VER >= 26
+ if !consteval
+#endif
+ { // check that the algorithm works without memory
+ std::vector<int> vec(150, 3);
+ getGlobalMemCounter()->throw_after = 0;
+ std::stable_sort(vec.begin(), vec.end());
+ }
#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
}
int main(int, char**) {
- test();
+ test();
#if TEST_STD_VER >= 26
- static_assert((test(), true));
+ static_assert((test(), true));
#endif
- return 0;
+ return 0;
}
More information about the libcxx-commits
mailing list