[libcxx-commits] [libcxx] [libc++] Implement part of P2562R1: constexpr `std::inplace_merge` (PR #129008)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 26 22:10:17 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: A. Jiang (frederick-vs-ja)
<details>
<summary>Changes</summary>
Fixes #<!-- -->119398.
---
Patch is 22.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/129008.diff
6 Files Affected:
- (modified) libcxx/include/__algorithm/inplace_merge.h (+3-3)
- (modified) libcxx/include/algorithm (+2-2)
- (modified) libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp (+121-80)
- (modified) libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp (+174-108)
- (modified) libcxx/test/std/algorithms/robust_re_difference_type.compile.pass.cpp (+7-2)
- (modified) libcxx/test/support/counting_predicates.h (+14-12)
``````````diff
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 1fc31b66f4bd6..ca49196320981 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -203,7 +203,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __inplace_merge(
}
template <class _AlgPolicy, class _BidirectionalIterator, class _Compare>
-_LIBCPP_HIDE_FROM_ABI void __inplace_merge(
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __inplace_merge(
_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) {
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
@@ -223,14 +223,14 @@ _LIBCPP_HIDE_FROM_ABI void __inplace_merge(
}
template <class _BidirectionalIterator, class _Compare>
-inline _LIBCPP_HIDE_FROM_ABI void inplace_merge(
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX26 void inplace_merge(
_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) {
std::__inplace_merge<_ClassicAlgPolicy>(
std::move(__first), std::move(__middle), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp));
}
template <class _BidirectionalIterator>
-inline _LIBCPP_HIDE_FROM_ABI void
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) {
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
}
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 7b4cb8e496196..916d162c9fa86 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -1606,11 +1606,11 @@ template <class InputIterator1, class InputIterator2, class OutputIterator, clas
InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
template <class BidirectionalIterator>
- void
+ constexpr void // constexpr in C++26
inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last);
template <class BidirectionalIterator, class Compare>
- void
+ constexpr void // constexpr in C++26
inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);
template <class InputIterator1, class InputIterator2>
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
index 87bf9dc3854b3..21ade1d9fcfeb 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
@@ -8,11 +8,9 @@
// <algorithm>
-// template<BidirectionalIterator Iter>
-// requires ShuffleIterator<Iter>
-// && LessThanComparable<Iter::value_type>
-// void
-// inplace_merge(Iter first, Iter middle, Iter last);
+// template<class BidirectionalIterator>
+// constexpr void // constexpr since C++26
+// inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last);
#include <algorithm>
#include <cassert>
@@ -25,99 +23,142 @@
#if TEST_STD_VER >= 11
struct S {
- S() : i_(0) {}
- S(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX26 S() : i_(0) {}
+ TEST_CONSTEXPR_CXX26 S(int i) : i_(i) {}
+
+ TEST_CONSTEXPR_CXX26 S(const S& rhs) : i_(rhs.i_) {}
+ TEST_CONSTEXPR_CXX26 S(S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
+
+ TEST_CONSTEXPR_CXX26 S& operator=(const S& rhs) {
+ i_ = rhs.i_;
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX26 S& operator=(S&& rhs) {
+ i_ = rhs.i_;
+ rhs.i_ = -2;
+ assert(this != &rhs);
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX26 S& operator=(int i) {
+ i_ = i;
+ return *this;
+ }
+
+ TEST_CONSTEXPR_CXX26 bool operator<(const S& rhs) const { return i_ < rhs.i_; }
+ TEST_CONSTEXPR_CXX26 bool operator==(const S& rhs) const { return i_ == rhs.i_; }
+ TEST_CONSTEXPR_CXX26 bool operator==(int i) const { return i_ == i; }
+
+ TEST_CONSTEXPR_CXX26 void set(int i) { i_ = i; }
+
+ int i_;
+};
+#endif // TEST_STD_VER >= 11
- S(const S& rhs) : i_(rhs.i_) {}
- S( S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
-
- S& operator =(const S& rhs) { i_ = rhs.i_; return *this; }
- S& operator =( S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; }
- S& operator =(int i) { i_ = i; return *this; }
-
- bool operator <(const S& rhs) const { return i_ < rhs.i_; }
- bool operator ==(const S& rhs) const { return i_ == rhs.i_; }
- bool operator ==(int i) const { return i_ == i; }
-
- void set(int i) { i_ = i; }
+std::mt19937 randomness;
- int i_;
- };
-#endif
+template <class Iter>
+void test_one_randomized(unsigned N, unsigned M) {
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+ value_type* ia = new value_type[N];
+
+ for (unsigned i = 0; i < N; ++i)
+ ia[i] = i;
+ std::shuffle(ia, ia + N, randomness);
+ std::sort(ia, ia + M);
+ std::sort(ia + M, ia + N);
+ std::inplace_merge(Iter(ia), Iter(ia + M), Iter(ia + N));
+ if (N > 0) {
+ assert(ia[0] == 0);
+ assert(ia[N - 1] == static_cast<value_type>(N - 1));
+ assert(std::is_sorted(ia, ia + N));
+ }
+ delete[] ia;
+}
-std::mt19937 randomness;
+template <class Iter>
+TEST_CONSTEXPR_CXX26 void test_one_non_randomized(unsigned N, unsigned M) {
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+ value_type* ia = new value_type[N];
+ const unsigned long small_prime = 19937;
+ const unsigned long large_prime = 212987;
+ unsigned long product_mod = small_prime;
+ for (unsigned i = 0; i < N; ++i) {
+ ia[i] = static_cast<int>(product_mod);
+ product_mod = product_mod * small_prime % large_prime;
+ }
+ std::sort(ia, ia + M);
+ std::sort(ia + M, ia + N);
+ std::inplace_merge(Iter(ia), Iter(ia + M), Iter(ia + N));
+ if (N > 0) {
+ assert(std::is_sorted(ia, ia + N));
+ }
+ delete[] ia;
+}
template <class Iter>
-void
-test_one(unsigned N, unsigned M)
-{
- typedef typename std::iterator_traits<Iter>::value_type value_type;
- assert(M <= N);
- value_type* ia = new value_type[N];
- for (unsigned i = 0; i < N; ++i)
- ia[i] = i;
- std::shuffle(ia, ia+N, randomness);
- std::sort(ia, ia+M);
- std::sort(ia+M, ia+N);
- std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N));
- if(N > 0)
- {
- assert(ia[0] == 0);
- assert(ia[N-1] == static_cast<value_type>(N-1));
- assert(std::is_sorted(ia, ia+N));
- }
- delete [] ia;
+TEST_CONSTEXPR_CXX26 void test_one(unsigned N, unsigned M) {
+ assert(M <= N);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ test_one_randomized<Iter>(N, M);
+ }
+ test_one_non_randomized<Iter>(N, M);
}
template <class Iter>
-void
-test(unsigned N)
-{
- test_one<Iter>(N, 0);
- test_one<Iter>(N, N/4);
- test_one<Iter>(N, N/2);
- test_one<Iter>(N, 3*N/4);
- test_one<Iter>(N, N);
+TEST_CONSTEXPR_CXX26 void test(unsigned N) {
+ test_one<Iter>(N, 0);
+ test_one<Iter>(N, N / 4);
+ test_one<Iter>(N, N / 2);
+ test_one<Iter>(N, 3 * N / 4);
+ test_one<Iter>(N, N);
}
template <class Iter>
-void
-test()
-{
- test_one<Iter>(0, 0);
- test_one<Iter>(1, 0);
- test_one<Iter>(1, 1);
- test_one<Iter>(2, 0);
- test_one<Iter>(2, 1);
- test_one<Iter>(2, 2);
- test_one<Iter>(3, 0);
- test_one<Iter>(3, 1);
- test_one<Iter>(3, 2);
- test_one<Iter>(3, 3);
- test<Iter>(4);
- test<Iter>(100);
+TEST_CONSTEXPR_CXX26 void test() {
+ test_one<Iter>(0, 0);
+ test_one<Iter>(1, 0);
+ test_one<Iter>(1, 1);
+ test_one<Iter>(2, 0);
+ test_one<Iter>(2, 1);
+ test_one<Iter>(2, 2);
+ test_one<Iter>(3, 0);
+ test_one<Iter>(3, 1);
+ test_one<Iter>(3, 2);
+ test_one<Iter>(3, 3);
+ test<Iter>(4);
+ test<Iter>(100);
+ if (!TEST_IS_CONSTANT_EVALUATED) { // avoid blowing past constant evaluation limit
test<Iter>(1000);
+ }
}
-int main(int, char**)
-{
- test<bidirectional_iterator<int*> >();
- test<random_access_iterator<int*> >();
- test<int*>();
+TEST_CONSTEXPR_CXX26 bool test() {
+ test<bidirectional_iterator<int*> >();
+ test<random_access_iterator<int*> >();
+ test<int*>();
#if TEST_STD_VER >= 11
- test<bidirectional_iterator<S*> >();
- test<random_access_iterator<S*> >();
- test<S*>();
-#endif
+ test<bidirectional_iterator<S*> >();
+ test<random_access_iterator<S*> >();
+ test<S*>();
+#endif // TEST_STD_VER >= 11
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif // TEST_STD_VER >= 26
#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
- {
- std::vector<int> vec(150, 3);
- getGlobalMemCounter()->throw_after = 0;
- std::inplace_merge(vec.begin(), vec.begin() + 100, vec.end());
- assert(std::all_of(vec.begin(), vec.end(), [](int i) { return i == 3; }));
- }
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ std::vector<int> vec(150, 3);
+ getGlobalMemCounter()->throw_after = 0;
+ std::inplace_merge(vec.begin(), vec.begin() + 100, vec.end());
+ assert(std::all_of(vec.begin(), vec.end(), [](int i) { return i == 3; }));
+ }
#endif // TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
return 0;
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
index bcde2323ad1de..3c98c8377de21 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
@@ -8,11 +8,9 @@
// <algorithm>
-// template<BidirectionalIterator Iter, StrictWeakOrder<auto, Iter::value_type> Compare>
-// requires ShuffleIterator<Iter>
-// && CopyConstructible<Compare>
-// void
-// inplace_merge(Iter first, Iter middle, Iter last, Compare comp);
+// template<class BidirectionalIterator, class Compare>
+// constexpr void // constexpr since C++26
+// inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);
#include <algorithm>
#include <cassert>
@@ -23,37 +21,46 @@
#include "test_macros.h"
#if TEST_STD_VER >= 11
-#include <memory>
+# include <memory>
struct indirect_less {
template <class P>
- bool operator()(const P& x, const P& y) const {
+ TEST_CONSTEXPR_CXX26 bool operator()(const P& x, const P& y) const {
return *x < *y;
}
};
struct S {
- S() : i_(0) {}
- S(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX26 S() : i_(0) {}
+ TEST_CONSTEXPR_CXX26 S(int i) : i_(i) {}
- S(const S& rhs) : i_(rhs.i_) {}
- S( S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
+ TEST_CONSTEXPR_CXX26 S(const S& rhs) : i_(rhs.i_) {}
+ TEST_CONSTEXPR_CXX26 S(S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
- S& operator =(const S& rhs) { i_ = rhs.i_; return *this; }
- S& operator =( S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; }
- S& operator =(int i) { i_ = i; return *this; }
-
- bool operator <(const S& rhs) const { return i_ < rhs.i_; }
- bool operator >(const S& rhs) const { return i_ > rhs.i_; }
- bool operator ==(const S& rhs) const { return i_ == rhs.i_; }
- bool operator ==(int i) const { return i_ == i; }
-
- void set(int i) { i_ = i; }
+ TEST_CONSTEXPR_CXX26 S& operator=(const S& rhs) {
+ i_ = rhs.i_;
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX26 S& operator=(S&& rhs) {
+ i_ = rhs.i_;
+ rhs.i_ = -2;
+ assert(this != &rhs);
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX26 S& operator=(int i) {
+ i_ = i;
+ return *this;
+ }
- int i_;
- };
+ TEST_CONSTEXPR_CXX26 bool operator<(const S& rhs) const { return i_ < rhs.i_; }
+ TEST_CONSTEXPR_CXX26 bool operator>(const S& rhs) const { return i_ > rhs.i_; }
+ TEST_CONSTEXPR_CXX26 bool operator==(const S& rhs) const { return i_ == rhs.i_; }
+ TEST_CONSTEXPR_CXX26 bool operator==(int i) const { return i_ == i; }
+ TEST_CONSTEXPR_CXX26 void set(int i) { i_ = i; }
+ int i_;
+};
#endif // TEST_STD_VER >= 11
#include "test_iterators.h"
@@ -62,114 +69,173 @@ struct S {
std::mt19937 randomness;
template <class Iter>
-void
-test_one(unsigned N, unsigned M)
-{
- assert(M <= N);
- typedef typename std::iterator_traits<Iter>::value_type value_type;
- value_type* ia = new value_type[N];
- for (unsigned i = 0; i < N; ++i)
- ia[i] = i;
- std::shuffle(ia, ia+N, randomness);
- std::sort(ia, ia+M, std::greater<value_type>());
- std::sort(ia+M, ia+N, std::greater<value_type>());
- binary_counting_predicate<std::greater<value_type>, value_type, value_type> pred((std::greater<value_type>()));
- std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N), std::ref(pred));
- if(N > 0)
- {
- assert(ia[0] == static_cast<int>(N)-1);
- assert(ia[N-1] == 0);
- assert(std::is_sorted(ia, ia+N, std::greater<value_type>()));
+void test_one_randomized(unsigned N, unsigned M) {
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+
+ value_type* ia = new value_type[N];
+ for (unsigned i = 0; i < N; ++i)
+ ia[i] = i;
+ std::shuffle(ia, ia + N, randomness);
+ std::sort(ia, ia + M, std::greater<value_type>());
+ std::sort(ia + M, ia + N, std::greater<value_type>());
+ binary_counting_predicate<std::greater<value_type>, value_type, value_type> pred((std::greater<value_type>()));
+ std::inplace_merge(Iter(ia), Iter(ia + M), Iter(ia + N), std::ref(pred));
+ if (N > 0) {
+ assert(ia[0] == static_cast<int>(N) - 1);
+ assert(ia[N - 1] == 0);
+ assert(std::is_sorted(ia, ia + N, std::greater<value_type>()));
+#if defined(_LIBCPP_HARDENING_MODE) && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
+ assert(pred.count() <= (N - 1));
+#endif
+ }
+ delete[] ia;
+}
+
+template <class Iter>
+TEST_CONSTEXPR_CXX26 void test_one_non_randomized(unsigned N, unsigned M) {
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+
+ value_type* ia = new value_type[N];
+ const unsigned long small_prime = 19937;
+ const unsigned long large_prime = 212987;
+ unsigned long product_mod = small_prime;
+ for (unsigned i = 0; i < N; ++i) {
+ ia[i] = static_cast<int>(product_mod);
+ product_mod = product_mod * small_prime % large_prime;
+ }
+ std::sort(ia, ia + M, std::greater<value_type>());
+ std::sort(ia + M, ia + N, std::greater<value_type>());
+ binary_counting_predicate<std::greater<value_type>, value_type, value_type> pred((std::greater<value_type>()));
+ std::inplace_merge(Iter(ia), Iter(ia + M), Iter(ia + N), std::ref(pred));
+ if (N > 0) {
+ assert(std::is_sorted(ia, ia + N, std::greater<value_type>()));
#if defined(_LIBCPP_HARDENING_MODE) && _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
- assert(pred.count() <= (N-1));
+ assert(pred.count() <= (N - 1));
#endif
- }
- delete [] ia;
+ }
+ delete[] ia;
+}
+
+template <class Iter>
+TEST_CONSTEXPR_CXX26 void test_one(unsigned N, unsigned M) {
+ assert(M <= N);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ test_one_randomized<Iter>(N, M);
+ }
+ test_one_non_randomized<Iter>(N, M);
}
template <class Iter>
-void
-test(unsigned N)
-{
- test_one<Iter>(N, 0);
- test_one<Iter>(N, N/4);
- test_one<Iter>(N, N/2);
- test_one<Iter>(N, 3*N/4);
- test_one<Iter>(N, N);
+TEST_CONSTEXPR_CXX26 void test(unsigned N) {
+ test_one<Iter>(N, 0);
+ test_one<Iter>(N, N / 4);
+ test_one<Iter>(N, N / 2);
+ test_one<Iter>(N, 3 * N / 4);
+ test_one<Iter>(N, N);
}
template <class Iter>
-void
-test()
-{
- test_one<Iter>(0, 0);
- test_one<Iter>(1, 0);
- test_one<Iter>(1, 1);
- test_one<Iter>(2, 0);
- test_one<Iter>(2, 1);
- test_one<Iter>(2, 2);
- test_one<Iter>(3, 0);
- test_one<Iter>(3, 1);
- test_one<Iter>(3, 2);
- test_one<Iter>(3, 3);
- test<Iter>(4);
- test<Iter>(20);
- test<Iter>(100);
+TEST_CONSTEXPR_CXX26 void test() {
+ test_one<Iter>(0, 0);
+ test_one<Iter>(1, 0);
+ test_one<Iter>(1, 1);
+ test_one<Iter>(2, 0);
+ test_one<Iter>(2, 1);
+ test_one<Iter>(2, 2);
+ test_one<Iter>(3, 0);
+ test_one<Iter>(3, 1);
+ test_one<Iter>(3, 2);
+ test_one<Iter>(3, 3);
+ test<Iter>(4);
+ test<Iter>(20);
+ test<Iter>(100);
+ if (!TEST_IS_CONSTANT_EVALUATED) { // avoid blowing past constant evaluation limit
test<Iter>(1000);
+ }
}
struct less_by_first {
template <typename Pair>
- bool operator()(const Pair& lhs, const Pair& rhs) const {
+ TEST_CONSTEXPR_CXX26 bool operator()(const Pair& lhs, const Pair& rhs) const {
return std::less<typename Pair::first_type>()(lhs.first, rhs.first);
}
};
-void test_PR31166 ()
-{
- typedef std::pair<int, int> P;
- typedef std::vector<P> V;
- P vec[5] = {P(1, 0), P(2, 0), P(2, 1), P(2, 2), P(2, 3)};
- for ( int i = 0; i < 5; ++i ) {
- V res(vec, vec + 5);
- std::inplace_merge(res.begin(), res.begin() + i, res.end(), less_by_first());
- assert(res.size() == 5);
- assert(std::equal(res.begin(), res.end(), vec));
- }
+TEST_CONSTEXPR_CXX26 void test_PR31166() {
+ typedef std::pair<int, int> P;
+ typedef std::vector<P> V;
+ P vec[5] = {P(1, 0), P(2, 0), P(2, 1), P(2, 2), P(2, 3)};
+ for (int i = 0; i < 5; ++i) {
+ V res(vec, vec + 5);
+ std::inplace_merge(res.begin(), res.begin() + i, res.end(), less_by_first());
+ assert(res.size() == 5);
+ assert(std::equal(res.begin(), res.end(), vec));
+ }
}
-int main(int, char**)
-{
- test<bidirectional_iterator<int*> >();
- test<random_access_iterator<int*> >();
- test<int*>();
+#if TEST_STD_VER >= 11
+void test_wrapped_randomized(int N, unsigned M) {
+ std::unique_ptr<int>* ia = new std::unique_ptr<int>[N];
+ for (int i = 0; i < N; ++i)
+ ia[i].reset(new int(i));
+ std::shuffle(ia, ia + N, randomness);
+ std::sort(ia, ia + M, indirect_less());
+ std::sort(ia + M, ia + N, indirect_less());
+ std::inplace_merge(ia, ia + M, ia + N, indirect_less());
+ if (N > 0) {
+ assert(*ia[0] == 0);
+ assert(*ia[N - 1] == N - 1);
+ assert(std::is_sorted(ia, ia + N, indirect_less()));
+ }
+ delete[] ia;
+}
+
+TEST_CONSTEXPR_CXX26 void test_wrapped_non_randomized(int N, unsigned M) {
+ std::unique_ptr<int>* ia = new std::unique_ptr<int>[N];
+
+ const unsigned long small_prime = 19937;
+ const unsigned long large_prime = 212987;
+ unsigned long product_mod = small_prime;
+ for (unsigned i = 0; i < N; ++i) {
+ ia[i].reset(new int(static_cast<int>(product_mod)));
+ product_mod = product_mod * small_prime % large_prime;
+ }
+ std::sort(ia, ia + M, indirect_less());
+ std::sort(ia + M, ia + N, indirect_less());
+ std::inplace_merge(ia, ia + M, ia + N, indirect_less());
+ if (N > 0) {
+ assert(std::is_sorted(ia, ia + N, indirect_less()));
+ }
+ delete[] ia;
+}
+#endif // TEST_STD_VER >= 11
+
+TEST_CONSTEXPR_CXX26 bool test() {
+ test<bidirectional_iterator<int*> >();
+ test<random_access_iterator<int*> >();
+ test<int*>();
#if TEST_STD_VER >= 11
- test<bidirectional_iterator<S*> >();
- test<random_access_iterator<S*> >();
- test<S*>();
-
- {
- int N = 100;
- unsigned M = 50;
- std::unique_ptr<int>* ia = new std::unique_ptr<int>[N];
- for (int i = 0; i < N; ++i)
- ia[i].reset(new int(i));
- std::shuffle(ia, ia+N, randomness);
- std::sort(ia, ia+M, indirect_less());
- std::sort(ia+M, ia+N, indirect_less());
- std::inplace_merge(ia, ia+M, ia+N, indirect_less());
- if(N > 0)
- {
- assert(*ia[0] == 0);
- assert(*ia[N-1] == N-1);
- assert(std::is_sorted(ia, ia+N, indirect_less()));
- }
- delete [] ia;
- }
+ test<bidirectional_iterator<S*> >();
+ test<random_access_iterator<S*> >();
+ test<S*>();
+
+ if (!TEST_IS_CONSTANT_EVALUATED)...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/129008
More information about the libcxx-commits
mailing list