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

source code of pstl/test/std/utilities/memory/specialized.algorithms/uninitialized_copy_move.pass.cpp