xref: /llvm-project/pstl/test/std/utilities/memory/specialized.algorithms/uninitialized_copy_move.pass.cpp (revision 3b9a1bb1af90db9472340ef2122d3855eb9ba3fc)
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 
21 using namespace TestUtils;
22 
23 // function of checking correctness for uninitialized.construct.value
24 template <typename InputIterator, typename OutputIterator, typename Size>
25 bool
IsCheckValueCorrectness(InputIterator first1,OutputIterator first2,Size n)26 IsCheckValueCorrectness(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 
38 struct test_uninitialized_copy_move
39 {
40     template <typename Policy, typename InputIterator, typename OutputIterator>
41     void
operator ()test_uninitialized_copy_move42     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
operator ()test_uninitialized_copy_move79     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
operator ()test_uninitialized_copy_move85     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
operator ()test_uninitialized_copy_move93     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 
114 template <typename T>
115 void
test_uninitialized_copy_move_by_type()116 test_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 
127 int
main()128 main()
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