Synchronize libstdc++ PSTL with upstream LLVM PSTL
[gcc.git] / libstdc++-v3 / testsuite / 20_util / specialized_algorithms / pstl / uninitialized_copy_move.cc
1 // -*- C++ -*-
2 // { dg-options "-std=gnu++17 -ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-require-effective-target tbb-backend }
5
6 //===-- uninitialized_copy_move.pass.cpp ----------------------------------===//
7 //
8 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9 // See https://llvm.org/LICENSE.txt for license information.
10 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //
12 //===----------------------------------------------------------------------===//
13
14 // Tests for uninitialized_copy, uninitialized_copy_n, uninitialized_move, uninitialized_move_n
15
16 #include "pstl/pstl_test_config.h"
17
18 #ifdef PSTL_STANDALONE_TESTS
19 #include "pstl/execution"
20 #include "pstl/memory"
21 #else
22 #include <execution>
23 #include <memory>
24 #endif // PSTL_STANDALONE_TESTS
25
26 #include "pstl/test_utils.h"
27
28 using namespace TestUtils;
29
30 // function of checking correctness for uninitialized.construct.value
31 template <typename InputIterator, typename OutputIterator, typename Size>
32 bool
33 IsCheckValueCorrectness(InputIterator first1, OutputIterator first2, Size n)
34 {
35 for (Size i = 0; i < n; ++i, ++first1, ++first2)
36 {
37 if (*first1 != *first2)
38 {
39 return false;
40 }
41 }
42 return true;
43 }
44
45 struct test_uninitialized_copy_move
46 {
47 template <typename Policy, typename InputIterator, typename OutputIterator>
48 void
49 operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first, size_t n,
50 /*is_trivial<T>=*/std::false_type)
51 {
52 typedef typename std::iterator_traits<InputIterator>::value_type T;
53 // it needs for cleaning memory that was filled by default constructors in unique_ptr<T[]> p(new T[n])
54 // and for cleaning memory after last calling of uninitialized_value_construct_n.
55 // It is important for non-trivial types
56 std::destroy_n(exec, out_first, n);
57
58 // reset counter of constructors
59 T::SetCount(0);
60 // run algorithm
61 std::uninitialized_copy(exec, first, last, out_first);
62 // compare counter of constructors to length of container
63 EXPECT_TRUE(T::Count() == n, "wrong uninitialized_copy");
64 // destroy objects for testing new algorithms on same memory
65 std::destroy_n(exec, out_first, n);
66
67 std::uninitialized_copy_n(exec, first, n, out_first);
68 EXPECT_TRUE(T::Count() == n, "wrong uninitialized_copy_n");
69 std::destroy_n(exec, out_first, n);
70
71 // For move
72 std::uninitialized_move(exec, first, last, out_first);
73 // compare counter of constructors to length of container
74 EXPECT_TRUE(T::MoveCount() == n, "wrong uninitialized_move");
75 // destroy objects for testing new algorithms on same memory
76 std::destroy_n(exec, out_first, n);
77
78 std::uninitialized_move_n(exec, first, n, out_first);
79 EXPECT_TRUE(T::MoveCount() == n, "wrong uninitialized_move_n");
80 std::destroy_n(exec, out_first, n);
81 }
82
83 #if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
84 template <typename InputIterator, typename OutputIterator>
85 void
86 operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
87 size_t n, /*is_trivial<T>=*/std::true_type)
88 {
89 }
90 template <typename InputIterator, typename OutputIterator>
91 void
92 operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
93 OutputIterator out_first, size_t n, /*is_trivial<T>=*/std::true_type)
94 {
95 }
96 #endif
97
98 template <typename Policy, typename InputIterator, typename OutputIterator>
99 void
100 operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first, size_t n,
101 /*is_trivial<T>=*/std::true_type)
102 {
103 typedef typename std::iterator_traits<InputIterator>::value_type T;
104
105 std::uninitialized_copy(exec, first, last, out_first);
106 EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_copy");
107 std::destroy_n(exec, out_first, n);
108
109 std::uninitialized_copy_n(exec, first, n, out_first);
110 EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_copy_n");
111 std::destroy_n(exec, out_first, n);
112
113 std::uninitialized_move(exec, first, last, out_first);
114 EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_move");
115 std::destroy_n(exec, out_first, n);
116
117 std::uninitialized_move_n(exec, first, n, out_first);
118 EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_move_n");
119 std::destroy_n(exec, out_first, n);
120 }
121 };
122
123 template <typename T>
124 void
125 test_uninitialized_copy_move_by_type()
126 {
127 std::size_t N = 100000;
128 for (size_t n = 0; n <= N; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
129 {
130 Sequence<T> in(n, [=](size_t k) -> T { return T(k); });
131 std::unique_ptr<T[]> p(new T[n]);
132 invoke_on_all_policies(test_uninitialized_copy_move(), in.begin(), in.end(), p.get(), n, std::is_trivial<T>());
133 }
134 }
135
136 int32_t
137 main()
138 {
139
140 // for trivial types
141 test_uninitialized_copy_move_by_type<int16_t>();
142 test_uninitialized_copy_move_by_type<float64_t>();
143
144 // for user-defined types
145 #if !_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN && !_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN && \
146 !_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN
147 test_uninitialized_copy_move_by_type<Wrapper<int8_t>>();
148 #endif
149
150 std::cout << done() << std::endl;
151 return 0;
152 }