Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,43 @@

// template<Iterator Iter1, Iterator Iter2>
// requires HasSwap<Iter1::reference, Iter2::reference>
// void
// iter_swap(Iter1 a, Iter2 b);
// void iter_swap(Iter1 a, Iter2 b); // constexpr since C++20

#include <algorithm>
#include <cassert>

#include "test_macros.h"

#if TEST_STD_VER > 17
constexpr bool test_swap_constexpr()
{
int i = 1;
int j = 2;
std::iter_swap(&i, &j);
return i == 2 && j == 1;
#include "test_iterators.h"
#include "type_algorithms.h"

struct TestIterators {
template <class Iter>
TEST_CONSTEXPR_CXX20 void operator()() {
types::for_each(types::forward_iterator_list<int*>(), TestImpl<Iter>());
}

template <class Iter1>
struct TestImpl {
template <class Iter2>
TEST_CONSTEXPR_CXX20 void operator()() {
int i = 1;
int j = 2;
std::iter_swap(Iter1(&i), Iter2(&j));
assert(i == 2 && j == 1);
}
};
};

TEST_CONSTEXPR_CXX20 bool test() {
types::for_each(types::forward_iterator_list<int*>(), TestIterators());
return true;
}
#endif // TEST_STD_VER > 17

int main(int, char**)
{
int i = 1;
int j = 2;
std::iter_swap(&i, &j);
assert(i == 2);
assert(j == 1);

#if TEST_STD_VER > 17
static_assert(test_swap_constexpr());
#endif // TEST_STD_VER > 17

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

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,51 +24,45 @@
#include <cassert>
#include <ranges>

#include <cstdio>

#include "test_iterators.h"
#include "type_algorithms.h"

constexpr void test_different_lengths() {
using Expected = std::ranges::swap_ranges_result<int*, int*>;
int i[3] = {1, 2, 3};
int j[1] = {4};
using Expected = std::ranges::swap_ranges_result<int*, int*>;
int i[3] = {1, 2, 3};
int j[1] = {4};
std::same_as<Expected> auto r = std::ranges::swap_ranges(i, i + 3, j, j + 1);
assert(r.in1 == i + 1);
assert(r.in2 == j + 1);
assert(i[0] == 4);
assert(i[1] == 2);
assert(i[2] == 3);
assert(j[0] == 1);
assert(std::ranges::equal(i, std::array{4, 2, 3}));
assert(std::ranges::equal(j, std::array{1}));
std::same_as<Expected> auto r2 = std::ranges::swap_ranges(i, j);
assert(r2.in1 == i + 1);
assert(r2.in2 == j + 1);
assert(i[0] == 1);
assert(i[1] == 2);
assert(i[2] == 3);
assert(j[0] == 4);
assert(std::ranges::equal(i, std::array{1, 2, 3}));
assert(std::ranges::equal(j, std::array{4}));
std::same_as<Expected> auto r3 = std::ranges::swap_ranges(j, j + 1, i, i + 3);
assert(r3.in1 == j + 1);
assert(r3.in2 == i + 1);
assert(i[0] == 4);
assert(i[1] == 2);
assert(i[2] == 3);
assert(j[0] == 1);
assert(std::ranges::equal(i, std::array{4, 2, 3}));
assert(std::ranges::equal(j, std::array{1}));
std::same_as<Expected> auto r4 = std::ranges::swap_ranges(j, i);
assert(r4.in1 == j + 1);
assert(r4.in2 == i + 1);
assert(i[0] == 1);
assert(i[1] == 2);
assert(i[2] == 3);
assert(j[0] == 4);
assert(std::ranges::equal(i, std::array{1, 2, 3}));
assert(std::ranges::equal(j, std::array{4}));
}

constexpr void test_range() {
std::array r1 = {1, 2, 3};
std::array r2 = {4, 5, 6};


std::same_as<std::ranges::in_in_result<std::array<int, 3>::iterator, std::array<int, 3>::iterator>> auto r = std::ranges::swap_ranges(r1, r2);
std::same_as<std::ranges::in_in_result<std::array<int, 3>::iterator, std::array<int, 3>::iterator>> auto r =
std::ranges::swap_ranges(r1, r2);
assert(r.in1 == r1.end());
assert(r.in2 == r2.end());

assert((r1 == std::array{4, 5, 6}));
assert((r2 == std::array{1, 2, 3}));
}
Expand All @@ -78,142 +72,82 @@ constexpr void test_borrowed_input_range() {
int r1[] = {1, 2, 3};
int r2[] = {4, 5, 6};
std::ranges::swap_ranges(std::views::all(r1), r2);
assert(r1[0] == 4);
assert(r1[1] == 5);
assert(r1[2] == 6);
assert(r2[0] == 1);
assert(r2[1] == 2);
assert(r2[2] == 3);
assert(std::ranges::equal(r1, std::array{4, 5, 6}));
assert(std::ranges::equal(r2, std::array{1, 2, 3}));
}
{
int r1[] = {1, 2, 3};
int r2[] = {4, 5, 6};
std::ranges::swap_ranges(r1, std::views::all(r2));
assert(r1[0] == 4);
assert(r1[1] == 5);
assert(r1[2] == 6);
assert(r2[0] == 1);
assert(r2[1] == 2);
assert(r2[2] == 3);
assert(std::ranges::equal(r1, std::array{4, 5, 6}));
assert(std::ranges::equal(r2, std::array{1, 2, 3}));
}
{
int r1[] = {1, 2, 3};
int r2[] = {4, 5, 6};
std::ranges::swap_ranges(std::views::all(r1), std::views::all(r2));
assert(r1[0] == 4);
assert(r1[1] == 5);
assert(r1[2] == 6);
assert(r2[0] == 1);
assert(r2[1] == 2);
assert(r2[2] == 3);
assert(std::ranges::equal(r1, std::array{4, 5, 6}));
assert(std::ranges::equal(r2, std::array{1, 2, 3}));
}
}

constexpr void test_sentinel() {
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
using It = cpp17_input_iterator<int*>;
using Sent = sentinel_wrapper<It>;
using Expected = std::ranges::swap_ranges_result<It, It>;
std::same_as<Expected> auto r =
std::ranges::swap_ranges(It(i), Sent(It(i + 3)), It(j), Sent(It(j + 3)));
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
using It = cpp17_input_iterator<int*>;
using Sent = sentinel_wrapper<It>;
using Expected = std::ranges::swap_ranges_result<It, It>;
std::same_as<Expected> auto r = std::ranges::swap_ranges(It(i), Sent(It(i + 3)), It(j), Sent(It(j + 3)));
assert(base(r.in1) == i + 3);
assert(base(r.in2) == j + 3);
assert(i[0] == 4);
assert(i[1] == 5);
assert(i[2] == 6);
assert(j[0] == 1);
assert(j[1] == 2);
assert(j[2] == 3);
assert(std::ranges::equal(i, std::array{4, 5, 6}));
assert(std::ranges::equal(j, std::array{1, 2, 3}));
}

template <class Iter1, class Iter2>
constexpr void test_iterators() {
TEST_CONSTEXPR_CXX20 void test_iterators() {
using Expected = std::ranges::swap_ranges_result<Iter1, Iter2>;
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
int a[3] = {1, 2, 3};
int b[3] = {4, 5, 6};
std::same_as<Expected> auto r =
std::ranges::swap_ranges(Iter1(i), sentinel_wrapper(Iter1(i + 3)), Iter2(j), sentinel_wrapper(Iter2(j + 3)));
assert(base(r.in1) == i + 3);
assert(base(r.in2) == j + 3);
assert(i[0] == 4);
assert(i[1] == 5);
assert(i[2] == 6);
assert(j[0] == 1);
assert(j[1] == 2);
assert(j[2] == 3);
std::ranges::swap_ranges(Iter1(a), sentinel_wrapper(Iter1(a + 3)), Iter2(b), sentinel_wrapper(Iter2(b + 3)));
assert(base(r.in1) == a + 3);
assert(base(r.in2) == b + 3);
assert(std::ranges::equal(a, std::array{4, 5, 6}));
assert(std::ranges::equal(b, std::array{1, 2, 3}));
}

constexpr void test_rval_range() {
{
using Expected = std::ranges::swap_ranges_result<std::array<int, 3>::iterator, std::ranges::dangling>;
using Expected = std::ranges::swap_ranges_result<std::array<int, 3>::iterator, std::ranges::dangling>;
std::array<int, 3> r = {1, 2, 3};
std::same_as<Expected> auto a = std::ranges::swap_ranges(r, std::array{4, 5, 6});
assert((r == std::array{4, 5, 6}));
assert(a.in1 == r.begin() + 3);
}
{
std::array<int, 3> r = {1, 2, 3};
using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, std::array<int, 3>::iterator>;
using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, std::array<int, 3>::iterator>;
std::same_as<Expected> auto b = std::ranges::swap_ranges(std::array{4, 5, 6}, r);
assert((r == std::array{4, 5, 6}));
assert(b.in2 == r.begin() + 3);
}
}

template <class Out>
constexpr void test_proxy_in_iterators() {
test_iterators<ProxyIterator<cpp20_input_iterator<int*>>, Out>();
test_iterators<ProxyIterator<forward_iterator<int*>>, Out>();
test_iterators<ProxyIterator<bidirectional_iterator<int*>>, Out>();
test_iterators<ProxyIterator<random_access_iterator<int*>>, Out>();
test_iterators<ProxyIterator<contiguous_iterator<int*>>, Out>();
}

constexpr bool test() {
test_range();

test_iterators<cpp20_input_iterator<int*>, cpp20_input_iterator<int*>>();
test_iterators<cpp20_input_iterator<int*>, forward_iterator<int*>>();
test_iterators<cpp20_input_iterator<int*>, bidirectional_iterator<int*>>();
test_iterators<cpp20_input_iterator<int*>, random_access_iterator<int*>>();
test_iterators<cpp20_input_iterator<int*>, int*>();

test_iterators<forward_iterator<int*>, cpp20_input_iterator<int*>>();
test_iterators<forward_iterator<int*>, forward_iterator<int*>>();
test_iterators<forward_iterator<int*>, bidirectional_iterator<int*>>();
test_iterators<forward_iterator<int*>, random_access_iterator<int*>>();
test_iterators<forward_iterator<int*>, int*>();

test_iterators<bidirectional_iterator<int*>, cpp20_input_iterator<int*>>();
test_iterators<bidirectional_iterator<int*>, forward_iterator<int*>>();
test_iterators<bidirectional_iterator<int*>, bidirectional_iterator<int*>>();
test_iterators<bidirectional_iterator<int*>, random_access_iterator<int*>>();
test_iterators<bidirectional_iterator<int*>, int*>();

test_iterators<random_access_iterator<int*>, cpp20_input_iterator<int*>>();
test_iterators<random_access_iterator<int*>, forward_iterator<int*>>();
test_iterators<random_access_iterator<int*>, bidirectional_iterator<int*>>();
test_iterators<random_access_iterator<int*>, random_access_iterator<int*>>();
test_iterators<random_access_iterator<int*>, int*>();

test_iterators<int*, cpp20_input_iterator<int*>>();
test_iterators<int*, forward_iterator<int*>>();
test_iterators<int*, bidirectional_iterator<int*>>();
test_iterators<int*, random_access_iterator<int*>>();
test_iterators<int*, int*>();

test_proxy_in_iterators<ProxyIterator<cpp20_input_iterator<int*>>>();
test_proxy_in_iterators<ProxyIterator<forward_iterator<int*>>>();
test_proxy_in_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
test_proxy_in_iterators<ProxyIterator<random_access_iterator<int*>>>();
test_proxy_in_iterators<ProxyIterator<contiguous_iterator<int*>>>();

test_sentinel();
test_different_lengths();
test_borrowed_input_range();
test_rval_range();

types::for_each(types::cpp20_input_iterator_list<int*>(), []<class Iter1>() {
types::for_each(types::cpp20_input_iterator_list<int*>(), []<class Iter2>() {
test_iterators<Iter1, Iter2>();
test_iterators<ProxyIterator<Iter1>, ProxyIterator<Iter2>>();
});
});

return true;
}

Expand Down
Loading
Loading