1*d2a46e64SNikolas Klauser //===----------------------------------------------------------------------===//
2*d2a46e64SNikolas Klauser //
3*d2a46e64SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d2a46e64SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5*d2a46e64SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d2a46e64SNikolas Klauser //
7*d2a46e64SNikolas Klauser //===----------------------------------------------------------------------===//
8*d2a46e64SNikolas Klauser
9*d2a46e64SNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14
10*d2a46e64SNikolas Klauser
11*d2a46e64SNikolas Klauser // UNSUPPORTED: libcpp-has-no-incomplete-pstl
12*d2a46e64SNikolas Klauser
13*d2a46e64SNikolas Klauser // <algorithm>
14*d2a46e64SNikolas Klauser
15*d2a46e64SNikolas Klauser // template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
16*d2a46e64SNikolas Klauser // ForwardIterator2 move(ExecutionPolicy&& policy,
17*d2a46e64SNikolas Klauser // ForwardIterator1 first, ForwardIterator1 last,
18*d2a46e64SNikolas Klauser // ForwardIterator2 result);
19*d2a46e64SNikolas Klauser
20*d2a46e64SNikolas Klauser #include <algorithm>
21*d2a46e64SNikolas Klauser #include <vector>
22*d2a46e64SNikolas Klauser
23*d2a46e64SNikolas Klauser #include "test_macros.h"
24*d2a46e64SNikolas Klauser #include "test_execution_policies.h"
25*d2a46e64SNikolas Klauser #include "test_iterators.h"
26*d2a46e64SNikolas Klauser
27*d2a46e64SNikolas Klauser EXECUTION_POLICY_SFINAE_TEST(move);
28*d2a46e64SNikolas Klauser
29*d2a46e64SNikolas Klauser static_assert(sfinae_test_move<int, int*, int*, int*>);
30*d2a46e64SNikolas Klauser static_assert(!sfinae_test_move<std::execution::parallel_policy, int*, int*, int*>);
31*d2a46e64SNikolas Klauser
32*d2a46e64SNikolas Klauser template <class Iter1, class Iter2>
33*d2a46e64SNikolas Klauser struct TestInt {
34*d2a46e64SNikolas Klauser template <class Policy>
operator ()TestInt35*d2a46e64SNikolas Klauser void operator()(Policy&& policy) {
36*d2a46e64SNikolas Klauser // simple test
37*d2a46e64SNikolas Klauser for (const int size : {0, 1, 2, 100, 350}) {
38*d2a46e64SNikolas Klauser std::vector<int> a(size);
39*d2a46e64SNikolas Klauser for (int i = 0; i != size; ++i)
40*d2a46e64SNikolas Klauser a[i] = i + 1;
41*d2a46e64SNikolas Klauser
42*d2a46e64SNikolas Klauser std::vector<int> out(std::size(a));
43*d2a46e64SNikolas Klauser decltype(auto) ret =
44*d2a46e64SNikolas Klauser std::move(policy, Iter1(std::data(a)), Iter1(std::data(a) + std::size(a)), Iter2(std::data(out)));
45*d2a46e64SNikolas Klauser static_assert(std::is_same_v<decltype(ret), Iter2>);
46*d2a46e64SNikolas Klauser assert(base(ret) == std::data(out) + std::size(out));
47*d2a46e64SNikolas Klauser for (int i = 0; i != size; ++i)
48*d2a46e64SNikolas Klauser assert(out[i] == i + 1);
49*d2a46e64SNikolas Klauser }
50*d2a46e64SNikolas Klauser }
51*d2a46e64SNikolas Klauser };
52*d2a46e64SNikolas Klauser
53*d2a46e64SNikolas Klauser struct MovedToTester {
54*d2a46e64SNikolas Klauser bool moved_to = false;
55*d2a46e64SNikolas Klauser MovedToTester() = default;
MovedToTesterMovedToTester56*d2a46e64SNikolas Klauser MovedToTester(MovedToTester&&) {}
operator =MovedToTester57*d2a46e64SNikolas Klauser MovedToTester& operator=(MovedToTester&&) {
58*d2a46e64SNikolas Klauser assert(!moved_to);
59*d2a46e64SNikolas Klauser moved_to = true;
60*d2a46e64SNikolas Klauser return *this;
61*d2a46e64SNikolas Klauser }
62*d2a46e64SNikolas Klauser ~MovedToTester() = default;
63*d2a46e64SNikolas Klauser };
64*d2a46e64SNikolas Klauser
65*d2a46e64SNikolas Klauser template <class Iter1, class Iter2>
66*d2a46e64SNikolas Klauser struct TestNonTrivial {
67*d2a46e64SNikolas Klauser template <class Policy>
operator ()TestNonTrivial68*d2a46e64SNikolas Klauser void operator()(Policy&& policy) {
69*d2a46e64SNikolas Klauser // simple test
70*d2a46e64SNikolas Klauser for (const int size : {0, 1, 2, 100, 350}) {
71*d2a46e64SNikolas Klauser std::vector<MovedToTester> a(size);
72*d2a46e64SNikolas Klauser
73*d2a46e64SNikolas Klauser std::vector<MovedToTester> out(std::size(a));
74*d2a46e64SNikolas Klauser auto ret = std::move(policy, Iter1(std::data(a)), Iter1(std::data(a) + std::size(a)), Iter2(std::data(out)));
75*d2a46e64SNikolas Klauser assert(base(ret) == std::data(out) + std::size(out));
76*d2a46e64SNikolas Klauser assert(std::all_of(std::begin(out), std::end(out), [](MovedToTester& t) { return t.moved_to; }));
77*d2a46e64SNikolas Klauser assert(std::none_of(std::begin(a), std::end(a), [](MovedToTester& t) { return t.moved_to; }));
78*d2a46e64SNikolas Klauser }
79*d2a46e64SNikolas Klauser }
80*d2a46e64SNikolas Klauser };
81*d2a46e64SNikolas Klauser
main(int,char **)82*d2a46e64SNikolas Klauser int main(int, char**) {
83*d2a46e64SNikolas Klauser types::for_each(types::forward_iterator_list<int*>{}, types::apply_type_identity{[](auto v) {
84*d2a46e64SNikolas Klauser using Iter = typename decltype(v)::type;
85*d2a46e64SNikolas Klauser types::for_each(
86*d2a46e64SNikolas Klauser types::forward_iterator_list<int*>{},
87*d2a46e64SNikolas Klauser TestIteratorWithPolicies< types::partial_instantiation<TestInt, Iter>::template apply>{});
88*d2a46e64SNikolas Klauser }});
89*d2a46e64SNikolas Klauser
90*d2a46e64SNikolas Klauser types::for_each(
91*d2a46e64SNikolas Klauser types::forward_iterator_list<MovedToTester*>{}, types::apply_type_identity{[](auto v) {
92*d2a46e64SNikolas Klauser using Iter = typename decltype(v)::type;
93*d2a46e64SNikolas Klauser types::for_each(
94*d2a46e64SNikolas Klauser types::forward_iterator_list<MovedToTester*>{},
95*d2a46e64SNikolas Klauser TestIteratorWithPolicies< types::partial_instantiation<TestNonTrivial, Iter>::template apply>{});
96*d2a46e64SNikolas Klauser }});
97*d2a46e64SNikolas Klauser
98*d2a46e64SNikolas Klauser return 0;
99*d2a46e64SNikolas Klauser }
100