Files
allhaileris afb81b8278
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
init
2026-02-16 15:50:16 +03:00

269 lines
8.6 KiB
C++

// Range v3 library
//
// Copyright Eric Niebler 2014-present
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <array>
#include <memory>
#include <algorithm>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/swap_ranges.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
#include "../test_iterators.hpp"
template<class Iter1, class Iter2>
void test_iter_3()
{
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
ranges::swap_ranges_result<Iter1, Iter2> r =
ranges::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j));
CHECK(base(r.in1) == i+3);
CHECK(base(r.in2) == j+3);
CHECK(i[0] == 4);
CHECK(i[1] == 5);
CHECK(i[2] == 6);
CHECK(j[0] == 1);
CHECK(j[1] == 2);
CHECK(j[2] == 3);
using Sent1 = typename sentinel_type<Iter1>::type;
r = ranges::swap_ranges(Iter1(j), Sent1(j+3), Iter2(i));
CHECK(base(r.in1) == j+3);
CHECK(base(r.in2) == i+3);
CHECK(i[0] == 1);
CHECK(i[1] == 2);
CHECK(i[2] == 3);
CHECK(j[0] == 4);
CHECK(j[1] == 5);
CHECK(j[2] == 6);
}
template<class Iter1, class Iter2>
void test_iter_4()
{
int i[3] = {1, 2, 3};
int j[4] = {4, 5, 6, 7};
ranges::swap_ranges_result<Iter1, Iter2> r =
ranges::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j), Iter2(j+4));
CHECK(base(r.in1) == i+3);
CHECK(base(r.in2) == j+3);
CHECK(i[0] == 4);
CHECK(i[1] == 5);
CHECK(i[2] == 6);
CHECK(j[0] == 1);
CHECK(j[1] == 2);
CHECK(j[2] == 3);
CHECK(j[3] == 7);
using Sent1 = typename sentinel_type<Iter1>::type;
using Sent2 = typename sentinel_type<Iter2>::type;
r = ranges::swap_ranges(Iter1(j), Sent1(j+4), Iter2(i), Sent2(i+3));
CHECK(base(r.in1) == j+3);
CHECK(base(r.in2) == i+3);
CHECK(i[0] == 1);
CHECK(i[1] == 2);
CHECK(i[2] == 3);
CHECK(j[0] == 4);
CHECK(j[1] == 5);
CHECK(j[2] == 6);
CHECK(j[3] == 7);
}
template<class Iter1, class Iter2>
void test_rng_3()
{
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
ranges::swap_ranges_result<Iter1, Iter2> r =
ranges::swap_ranges(as_lvalue(ranges::make_subrange(Iter1(i), Iter1(i+3))), Iter2(j));
CHECK(base(r.in1) == i+3);
CHECK(base(r.in2) == j+3);
CHECK(i[0] == 4);
CHECK(i[1] == 5);
CHECK(i[2] == 6);
CHECK(j[0] == 1);
CHECK(j[1] == 2);
CHECK(j[2] == 3);
using Sent1 = typename sentinel_type<Iter1>::type;
r = ranges::swap_ranges(as_lvalue(ranges::make_subrange(Iter1(j), Sent1(j+3))), Iter2(i));
CHECK(base(r.in1) == j+3);
CHECK(base(r.in2) == i+3);
CHECK(i[0] == 1);
CHECK(i[1] == 2);
CHECK(i[2] == 3);
CHECK(j[0] == 4);
CHECK(j[1] == 5);
CHECK(j[2] == 6);
}
template<class Iter1, class Iter2>
void test_rng_4()
{
int i[3] = {1, 2, 3};
int j[4] = {4, 5, 6, 7};
ranges::swap_ranges_result<Iter1, Iter2> r = ranges::swap_ranges(
as_lvalue(ranges::make_subrange(Iter1(i), Iter1(i+3))),
as_lvalue(ranges::make_subrange(Iter2(j), Iter2(j+4))));
CHECK(base(r.in1) == i+3);
CHECK(base(r.in2) == j+3);
CHECK(i[0] == 4);
CHECK(i[1] == 5);
CHECK(i[2] == 6);
CHECK(j[0] == 1);
CHECK(j[1] == 2);
CHECK(j[2] == 3);
CHECK(j[3] == 7);
using Sent1 = typename sentinel_type<Iter1>::type;
using Sent2 = typename sentinel_type<Iter2>::type;
r = ranges::swap_ranges(
as_lvalue(ranges::make_subrange(Iter1(j), Sent1(j+4))),
as_lvalue(ranges::make_subrange(Iter2(i), Sent2(i+3))));
CHECK(base(r.in1) == j+3);
CHECK(base(r.in2) == i+3);
CHECK(i[0] == 1);
CHECK(i[1] == 2);
CHECK(i[2] == 3);
CHECK(j[0] == 4);
CHECK(j[1] == 5);
CHECK(j[2] == 6);
CHECK(j[3] == 7);
auto r2 = ranges::swap_ranges(
ranges::make_subrange(Iter1(j), Sent1(j+4)),
ranges::make_subrange(Iter2(i), Sent2(i+3)));
CHECK(base(r2.in1) == j+3);
CHECK(base(r2.in2) == i+3);
CHECK(i[0] == 4);
CHECK(i[1] == 5);
CHECK(i[2] == 6);
CHECK(j[0] == 1);
CHECK(j[1] == 2);
CHECK(j[2] == 3);
CHECK(j[3] == 7);
}
template<class Iter1, class Iter2>
void test_move_only()
{
std::unique_ptr<int> i[3];
for (int k = 0; k < 3; ++k)
i[k].reset(new int(k+1));
std::unique_ptr<int> j[3];
for (int k = 0; k < 3; ++k)
j[k].reset(new int(k+4));
ranges::swap_ranges_result<Iter1, Iter2> r =
ranges::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j));
CHECK(base(r.in1) == i+3);
CHECK(base(r.in2) == j+3);
CHECK(*i[0] == 4);
CHECK(*i[1] == 5);
CHECK(*i[2] == 6);
CHECK(*j[0] == 1);
CHECK(*j[1] == 2);
CHECK(*j[2] == 3);
}
template<class Iter1, class Iter2>
void test()
{
test_iter_3<Iter1, Iter2>();
test_iter_4<Iter1, Iter2>();
test_rng_3<Iter1, Iter2>();
test_rng_4<Iter1, Iter2>();
}
constexpr bool test_constexpr()
{
using namespace ranges;
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
const auto r = ranges::swap_ranges(i, j);
STATIC_CHECK_RETURN(r.in1 == i + 3);
STATIC_CHECK_RETURN(r.in2 == j + 3);
STATIC_CHECK_RETURN(i[0] == 4);
STATIC_CHECK_RETURN(i[1] == 5);
STATIC_CHECK_RETURN(i[2] == 6);
STATIC_CHECK_RETURN(j[0] == 1);
STATIC_CHECK_RETURN(j[1] == 2);
STATIC_CHECK_RETURN(j[2] == 3);
return true;
}
int main()
{
test<ForwardIterator<int*>, ForwardIterator<int*> >();
test<ForwardIterator<int*>, BidirectionalIterator<int*> >();
test<ForwardIterator<int*>, RandomAccessIterator<int*> >();
test<ForwardIterator<int*>, int*>();
test<BidirectionalIterator<int*>, ForwardIterator<int*> >();
test<BidirectionalIterator<int*>, BidirectionalIterator<int*> >();
test<BidirectionalIterator<int*>, RandomAccessIterator<int*> >();
test<BidirectionalIterator<int*>, int*>();
test<RandomAccessIterator<int*>, ForwardIterator<int*> >();
test<RandomAccessIterator<int*>, BidirectionalIterator<int*> >();
test<RandomAccessIterator<int*>, RandomAccessIterator<int*> >();
test<RandomAccessIterator<int*>, int*>();
test<int*, ForwardIterator<int*> >();
test<int*, BidirectionalIterator<int*> >();
test<int*, RandomAccessIterator<int*> >();
test<int*, int*>();
test_move_only<ForwardIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test_move_only<ForwardIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test_move_only<ForwardIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test_move_only<ForwardIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test_move_only<BidirectionalIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test_move_only<BidirectionalIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test_move_only<BidirectionalIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test_move_only<BidirectionalIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test_move_only<RandomAccessIterator<std::unique_ptr<int>*>, ForwardIterator<std::unique_ptr<int>*> >();
test_move_only<RandomAccessIterator<std::unique_ptr<int>*>, BidirectionalIterator<std::unique_ptr<int>*> >();
test_move_only<RandomAccessIterator<std::unique_ptr<int>*>, RandomAccessIterator<std::unique_ptr<int>*> >();
test_move_only<RandomAccessIterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
test_move_only<std::unique_ptr<int>*, ForwardIterator<std::unique_ptr<int>*> >();
test_move_only<std::unique_ptr<int>*, BidirectionalIterator<std::unique_ptr<int>*> >();
test_move_only<std::unique_ptr<int>*, RandomAccessIterator<std::unique_ptr<int>*> >();
test_move_only<std::unique_ptr<int>*, std::unique_ptr<int>*>();
{
int a[4] = {1, 2, 3, 4};
int b[4] = {5, 6, 7, 8};
ranges::swap_ranges(a, a + 4, b);
::check_equal(a, {5, 6, 7, 8});
::check_equal(b, {1, 2, 3, 4});
ranges::swap_ranges(std::array<int, 2>{{3,4}}, a+2);
::check_equal(a, {5, 6, 3, 4});
}
{
STATIC_CHECK(test_constexpr());
}
return ::test_result();
}