1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
11 // REQUIRES: with-pstl
15 // template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
16 // ForwardIterator2 copy(ExecutionPolicy&& policy,
17 // ForwardIterator1 first, ForwardIterator1 last,
18 // ForwardIterator2 result);
23 #include "test_macros.h"
24 #include "test_execution_policies.h"
25 #include "test_iterators.h"
27 EXECUTION_POLICY_SFINAE_TEST(copy
);
29 static_assert(sfinae_test_copy
<int, int*, int*, bool (*)(int)>);
30 static_assert(!sfinae_test_copy
<std::execution::parallel_policy
, int*, int*, int>);
32 template <class Iter1
, class Iter2
>
34 template <class Policy
>
35 void operator()(Policy
&& policy
) {
37 for (const int size
: {0, 1, 2, 100, 350}) {
38 std::vector
<int> a(size
);
39 for (int i
= 0; i
!= size
; ++i
)
42 std::vector
<int> out(std::size(a
));
44 std::copy(policy
, Iter1(std::data(a
)), Iter1(std::data(a
) + std::size(a
)), Iter2(std::data(out
)));
45 static_assert(std::is_same_v
<decltype(ret
), Iter2
>);
46 assert(base(ret
) == std::data(out
) + std::size(out
));
47 for (int i
= 0; i
!= size
; ++i
)
48 assert(out
[i
] == i
+ 1);
53 struct CopiedToTester
{
54 bool copied_to
= false;
55 CopiedToTester() = default;
56 CopiedToTester(const CopiedToTester
&) {}
57 CopiedToTester
& operator=(const CopiedToTester
&) {
62 ~CopiedToTester() = default;
65 template <class Iter1
, class Iter2
>
66 struct TestNonTrivial
{
67 template <class Policy
>
68 void operator()(Policy
&& policy
) {
70 for (const int size
: {0, 1, 2, 100, 350}) {
71 std::vector
<CopiedToTester
> a(size
);
73 std::vector
<CopiedToTester
> out(std::size(a
));
74 auto ret
= std::copy(policy
, Iter1(std::data(a
)), Iter1(std::data(a
) + std::size(a
)), Iter2(std::data(out
)));
75 assert(base(ret
) == std::data(out
) + std::size(out
));
76 assert(std::all_of(std::begin(out
), std::end(out
), [](CopiedToTester
& t
) { return t
.copied_to
; }));
77 assert(std::none_of(std::begin(a
), std::end(a
), [](CopiedToTester
& t
) { return t
.copied_to
; }));
82 struct TestIteratorsNonTrivial
{
83 template <class Iter2
>
87 int main(int, char**) {
88 types::for_each(types::forward_iterator_list
<int*>{}, types::apply_type_identity
{[](auto v
) {
89 using Iter
= typename
decltype(v
)::type
;
91 types::forward_iterator_list
<int*>{},
92 TestIteratorWithPolicies
< types::partial_instantiation
<TestInt
, Iter
>::template apply
>{});
96 types::forward_iterator_list
<CopiedToTester
*>{}, types::apply_type_identity
{[](auto v
) {
97 using Iter
= typename
decltype(v
)::type
;
99 types::forward_iterator_list
<CopiedToTester
*>{},
100 TestIteratorWithPolicies
< types::partial_instantiation
<TestNonTrivial
, Iter
>::template apply
>{});