| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- // 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();
- }
|