Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions libcxx/include/__algorithm/ranges_inplace_merge.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
struct __inplace_merge {
template <class _Iter, class _Sent, class _Comp, class _Proj>
_LIBCPP_HIDE_FROM_ABI static constexpr auto
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX26 auto
__inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
auto __last_iter = ranges::next(__middle, __last);
std::__inplace_merge<_RangeAlgPolicy>(
Expand All @@ -51,15 +51,15 @@ struct __inplace_merge {

template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity>
requires sortable<_Iter, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI _Iter
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Iter
operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
return __inplace_merge_impl(
std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
}

template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity>
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 borrowed_iterator_t<_Range>
operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
return __inplace_merge_impl(
ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
Expand Down
7 changes: 4 additions & 3 deletions libcxx/include/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -1031,13 +1031,14 @@ namespace ranges {
template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
class Proj = identity>
requires sortable<I, Comp, Proj>
I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // since C++20
constexpr I // constexpr since C++26
inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // since C++20

template<bidirectional_range R, class Comp = ranges::less, class Proj = identity>
requires sortable<iterator_t<R>, Comp, Proj>
borrowed_iterator_t<R>
constexpr borrowed_iterator_t<R> // constexpr since C++26
inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {},
Proj proj = {}); // since C++20
Proj proj = {}); // since C++20

template<permutable I, sentinel_for<I> S, class Proj = identity,
indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,15 @@ constexpr bool all_the_algorithms()
(void)std::ranges::is_sorted(a, Less(&copies)); assert(copies == 0);
(void)std::ranges::is_sorted_until(first, last, Less(&copies)); assert(copies == 0);
(void)std::ranges::is_sorted_until(a, Less(&copies)); assert(copies == 0);
if (!std::is_constant_evaluated()) { (void)std::ranges::inplace_merge(first, mid, last, Less(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::inplace_merge(a, mid, Less(&copies)); assert(copies == 0); }
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
(void)std::ranges::inplace_merge(first, mid, last, Less(&copies));
assert(copies == 0);
(void)std::ranges::inplace_merge(a, mid, Less(&copies));
assert(copies == 0);
}
(void)std::ranges::lexicographical_compare(first, last, first2, last2, Less(&copies)); assert(copies == 0);
(void)std::ranges::lexicographical_compare(a, b, Less(&copies)); assert(copies == 0);
(void)std::ranges::lower_bound(first, last, value, Less(&copies)); assert(copies == 0);
Expand Down Expand Up @@ -223,10 +230,19 @@ constexpr bool all_the_algorithms()
(void)std::ranges::sort(a, Less(&copies)); assert(copies == 0);
(void)std::ranges::sort_heap(first, last, Less(&copies)); assert(copies == 0);
(void)std::ranges::sort_heap(a, Less(&copies)); assert(copies == 0);
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_partition(first, last, UnaryTrue(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_partition(a, UnaryTrue(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(first, last, Less(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(a, Less(&copies)); assert(copies == 0); }
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
(void)std::ranges::stable_partition(first, last, UnaryTrue(&copies));
assert(copies == 0);
(void)std::ranges::stable_partition(a, UnaryTrue(&copies));
assert(copies == 0);
(void)std::ranges::stable_sort(first, last, Less(&copies));
assert(copies == 0);
(void)std::ranges::stable_sort(a, Less(&copies));
assert(copies == 0);
}
#if TEST_STD_VER > 20
(void)std::ranges::starts_with(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
(void)std::ranges::starts_with(a, b, Equal(&copies)); assert(copies == 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,15 @@ constexpr bool all_the_algorithms()
(void)std::ranges::is_sorted(a, Less(), Proj(&copies)); assert(copies == 0);
(void)std::ranges::is_sorted_until(first, last, Less(), Proj(&copies)); assert(copies == 0);
(void)std::ranges::is_sorted_until(a, Less(), Proj(&copies)); assert(copies == 0);
if (!std::is_constant_evaluated()) { (void)std::ranges::inplace_merge(first, mid, last, Less(), Proj(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::inplace_merge(a, mid, Less(), Proj(&copies)); assert(copies == 0); }
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
(void)std::ranges::inplace_merge(first, mid, last, Less(), Proj(&copies));
assert(copies == 0);
(void)std::ranges::inplace_merge(a, mid, Less(), Proj(&copies));
assert(copies == 0);
}
(void)std::ranges::lexicographical_compare(first, last, first2, last2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
(void)std::ranges::lexicographical_compare(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
(void)std::ranges::lower_bound(first, last, value, Less(), Proj(&copies)); assert(copies == 0);
Expand Down Expand Up @@ -228,10 +235,19 @@ constexpr bool all_the_algorithms()
(void)std::ranges::sort(a, Less(), Proj(&copies)); assert(copies == 0);
(void)std::ranges::sort_heap(first, last, Less(), Proj(&copies)); assert(copies == 0);
(void)std::ranges::sort_heap(a, Less(), Proj(&copies)); assert(copies == 0);
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_partition(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_partition(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(first, last, Less(), Proj(&copies)); assert(copies == 0); }
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(a, Less(), Proj(&copies)); assert(copies == 0); }
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
(void)std::ranges::stable_partition(first, last, UnaryTrue(), Proj(&copies));
assert(copies == 0);
(void)std::ranges::stable_partition(a, UnaryTrue(), Proj(&copies));
assert(copies == 0);
(void)std::ranges::stable_sort(first, last, Less(), Proj(&copies));
assert(copies == 0);
(void)std::ranges::stable_sort(a, Less(), Proj(&copies));
assert(copies == 0);
}
#if TEST_STD_VER > 20
(void)std::ranges::starts_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
(void)std::ranges::starts_with(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
// template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less,
// class Proj = identity>
// requires sortable<I, Comp, Proj>
// I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // Since C++20
// constexpr I // constexpr since C++26
// inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // Since C++20
//
// template<bidirectional_range R, class Comp = ranges::less, class Proj = identity>
// requires sortable<iterator_t<R>, Comp, Proj>
// borrowed_iterator_t<R>
// constexpr borrowed_iterator_t<R> // constexpr since C++26
// inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {},
// Proj proj = {}); // Since C++20
// Proj proj = {}); // Since C++20

#include <algorithm>
#include <array>
Expand Down Expand Up @@ -86,7 +87,7 @@ static_assert(!HasInplaceMergeRange<R<int*>, int*, ComparatorNotCopyable<int*>>)
static_assert(!HasInplaceMergeIter<R<const int*>, const int*>);

template <class In, template <class> class SentWrapper, std::size_t N1, std::size_t N2>
void testInplaceMergeImpl(std::array<int, N1> input, int midIdx, std::array<int, N2> expected) {
TEST_CONSTEXPR_CXX26 void testInplaceMergeImpl(std::array<int, N1> input, int midIdx, std::array<int, N2> expected) {
assert(std::is_sorted(input.begin(), input.begin() + midIdx));
assert(std::is_sorted(input.begin() + midIdx, input.end()));
assert(std::is_sorted(expected.begin(), expected.end()));
Expand All @@ -113,7 +114,7 @@ void testInplaceMergeImpl(std::array<int, N1> input, int midIdx, std::array<int,
}

template <class In, template <class> class SentWrapper>
void testImpl() {
TEST_CONSTEXPR_CXX26 void testImpl() {
// sorted range
{
std::array in{0, 1, 5, 6, 9, 10};
Expand Down Expand Up @@ -193,14 +194,14 @@ void testImpl() {
}

template < template <class> class SentWrapper>
void withAllPermutationsOfIter() {
TEST_CONSTEXPR_CXX26 void withAllPermutationsOfIter() {
testImpl<bidirectional_iterator<int*>, SentWrapper>();
testImpl<random_access_iterator<int*>, SentWrapper>();
testImpl<contiguous_iterator<int*>, SentWrapper>();
testImpl<int*, SentWrapper>();
}

bool test() {
TEST_CONSTEXPR_CXX26 bool test() {
withAllPermutationsOfIter<std::type_identity_t>();
withAllPermutationsOfIter<sentinel_wrapper>();

Expand Down Expand Up @@ -334,7 +335,9 @@ bool test() {

int main(int, char**) {
test();
// inplace_merge is not constexpr in the latest finished Standard (C++20)
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,12 @@ constexpr bool test_all() {
}
dangling_1st(std::ranges::partial_sort, in, mid);
dangling_1st(std::ranges::nth_element, in, mid);
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
dangling_1st(std::ranges::inplace_merge, in, mid);
}
dangling_1st(std::ranges::make_heap, in);
dangling_1st(std::ranges::push_heap, in);
dangling_1st(std::ranges::pop_heap, in);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,12 @@ constexpr bool test_all() {
}
test_mid(std::ranges::partial_sort, in, mid, &Foo::binary_pred, &Bar::val);
test_mid(std::ranges::nth_element, in, mid, &Foo::binary_pred, &Bar::val);
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
test_mid(std::ranges::inplace_merge, in, mid, &Foo::binary_pred, &Bar::val);
}
test(std::ranges::make_heap, in, &Foo::binary_pred, &Bar::val);
test(std::ranges::push_heap, in, &Foo::binary_pred, &Bar::val);
test(std::ranges::pop_heap, in, &Foo::binary_pred, &Bar::val);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,12 @@ constexpr void run_tests() {
}
test_mid(std::ranges::partial_sort, in, mid);
test_mid(std::ranges::nth_element, in, mid);
#if TEST_STD_VER < 26
if (!std::is_constant_evaluated())
#endif
{
test_mid(std::ranges::inplace_merge, in, mid);
}
test(std::ranges::make_heap, in);
test(std::ranges::push_heap, in);
test(std::ranges::pop_heap, in);
Expand Down
43 changes: 28 additions & 15 deletions libcxx/test/std/algorithms/robust_against_adl_on_new.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,36 @@

struct A {
int i = 0;
bool operator<(const A& rhs) const { return i < rhs.i; }
static bool isEven(const A& a) { return a.i % 2 == 0; }
TEST_CONSTEXPR bool operator<(const A& rhs) const { return i < rhs.i; }
static TEST_CONSTEXPR bool isEven(const A& a) { return a.i % 2 == 0; }
};

void *operator new(std::size_t, A*) = delete;

int main(int, char**)
{
A a[4] = {};
std::sort(a, a+4);
std::sort(a, a+4, std::less<A>());
std::partition(a, a+4, A::isEven);
std::stable_sort(a, a+4);
std::stable_sort(a, a+4, std::less<A>());
std::stable_partition(a, a+4, A::isEven);
std::inplace_merge(a, a+2, a+4);
std::inplace_merge(a, a+2, a+4, std::less<A>());

return 0;
TEST_CONSTEXPR_CXX20 bool test() {
A a[4] = {};
std::sort(a, a + 4);
std::sort(a, a + 4, std::less<A>());
std::partition(a, a + 4, A::isEven);
#if TEST_STD_VER < 26
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
{
std::stable_sort(a, a + 4);
std::stable_sort(a, a + 4, std::less<A>());
std::stable_partition(a, a + 4, A::isEven);
std::inplace_merge(a, a + 2, a + 4);
std::inplace_merge(a, a + 2, a + 4, std::less<A>());
}

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif

return 0;
}