//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // UNSUPPORTED: c++03, c++11, c++14, c++17 // template S, weakly_incrementable O> // requires indirectly_movable // constexpr ranges::move_result // ranges::move(I first, S last, O result); // template // requires indirectly_movable, O> // constexpr ranges::move_result, O> // ranges::move(R&& r, O result); #include #include #include #include #include #include #include "almost_satisfies_types.h" #include "MoveOnly.h" #include "test_iterators.h" template > concept HasMoveIt = requires(In in, Sent sent, Out out) { std::ranges::move(in, sent, out); }; static_assert(HasMoveIt); static_assert(!HasMoveIt); static_assert(!HasMoveIt); static_assert(!HasMoveIt); static_assert(!HasMoveIt); struct NotIndirectlyMovable {}; static_assert(!HasMoveIt); static_assert(!HasMoveIt); static_assert(!HasMoveIt); template concept HasMoveR = requires(Range range, Out out) { std::ranges::move(range, out); }; static_assert(HasMoveR, int*>); static_assert(!HasMoveR); static_assert(!HasMoveR); static_assert(!HasMoveR); static_assert(!HasMoveR); static_assert(!HasMoveR, int*>); static_assert(!HasMoveR); static_assert(!HasMoveR); static_assert(!HasMoveR, WeaklyIncrementableNotMovable>); static_assert(std::is_same_v, std::ranges::in_out_result>); template constexpr void test(std::array in) { { std::array out; std::same_as> decltype(auto) ret = std::ranges::move(In(in.data()), Sent(In(in.data() + in.size())), Out(out.data())); assert(in == out); assert(base(ret.in) == in.data() + in.size()); assert(base(ret.out) == out.data() + out.size()); } { std::array out; auto range = std::ranges::subrange(In(in.data()), Sent(In(in.data() + in.size()))); std::same_as> decltype(auto) ret = std::ranges::move(range, Out(out.data())); assert(in == out); assert(base(ret.in) == in.data() + in.size()); assert(base(ret.out) == out.data() + out.size()); } } template constexpr void test_containers() { { InContainer in {1, 2, 3, 4}; OutContainer out(4); std::same_as> auto ret = std::ranges::move(In(in.begin()), Sent(In(in.end())), Out(out.begin())); assert(std::ranges::equal(in, out)); assert(base(ret.in) == in.end()); assert(base(ret.out) == out.end()); } { InContainer in {1, 2, 3, 4}; OutContainer out(4); auto range = std::ranges::subrange(In(in.begin()), Sent(In(in.end()))); std::same_as> auto ret = std::ranges::move(range, Out(out.begin())); assert(std::ranges::equal(in, out)); assert(base(ret.in) == in.end()); assert(base(ret.out) == out.end()); } } template constexpr void test_iterators() { // simple test test({1, 2, 3, 4}); // check that an empty range works test({}); } template