xref: /llvm-project/pstl/test/std/utilities/memory/specialized.algorithms/uninitialized_construct.pass.cpp (revision 4d88b17b3f282b1023400837c3249c9f27774eca)
1 // -*- C++ -*-
2 //===-- uninitialized_construct.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 // Tests for uninitialized_default_construct, uninitialized_default_construct_n,
11 //           uninitialized_value_construct,   uninitialized_value_construct_n
12 
13 #include "support/pstl_test_config.h"
14 
15 #include <execution>
16 #include <memory>
17 
18 #include "support/utils.h"
19 
20 using namespace TestUtils;
21 
22 // function of checking correctness for uninitialized.construct.value
23 template <typename T, typename Iterator>
24 bool
25 IsCheckValueCorrectness(Iterator begin, Iterator end)
26 {
27     for (; begin != end; ++begin)
28     {
29         if (*begin != T())
30         {
31             return false;
32         }
33     }
34     return true;
35 }
36 
37 struct test_uninit_construct
38 {
39     template <typename Policy, typename Iterator>
40     void
41     operator()(Policy&& exec, Iterator begin, Iterator end, size_t n, /*is_trivial<T>=*/std::false_type)
42     {
43         typedef typename std::iterator_traits<Iterator>::value_type T;
44         // it needs for cleaning memory that was filled by default constructors in unique_ptr<T[]> p(new T[n])
45         // and for cleaning memory after last calling of uninitialized_value_construct_n.
46         // It is important for non-trivial types
47         std::destroy_n(exec, begin, n);
48 
49         // reset counter of constructors
50         T::SetCount(0);
51         // run algorithm
52         std::uninitialized_default_construct(exec, begin, end);
53         // compare counter of constructors to length of container
54         EXPECT_TRUE(T::Count() == n, "wrong uninitialized_default_construct");
55         // destroy objects for testing new algorithms on same memory
56         std::destroy(exec, begin, end);
57 
58         std::uninitialized_default_construct_n(exec, begin, n);
59         EXPECT_TRUE(T::Count() == n, "wrong uninitialized_default_construct_n");
60         std::destroy_n(exec, begin, n);
61 
62         std::uninitialized_value_construct(exec, begin, end);
63         EXPECT_TRUE(T::Count() == n, "wrong uninitialized_value_construct");
64         std::destroy(exec, begin, end);
65 
66         std::uninitialized_value_construct_n(exec, begin, n);
67         EXPECT_TRUE(T::Count() == n, "wrong uninitialized_value_construct_n");
68     }
69 
70     template <typename Policy, typename Iterator>
71     void
72     operator()(Policy&& exec, Iterator begin, Iterator end, size_t n, /*is_trivial<T>=*/std::true_type)
73     {
74         typedef typename std::iterator_traits<Iterator>::value_type T;
75 
76         std::uninitialized_default_construct(exec, begin, end);
77         std::destroy(exec, begin, end);
78 
79         std::uninitialized_default_construct_n(exec, begin, n);
80         std::destroy_n(exec, begin, n);
81 
82         std::uninitialized_value_construct(exec, begin, end);
83         // check correctness for uninitialized.construct.value
84         EXPECT_TRUE(IsCheckValueCorrectness<T>(begin, end), "wrong uninitialized_value_construct");
85         std::destroy(exec, begin, end);
86 
87         std::uninitialized_value_construct_n(exec, begin, n);
88         EXPECT_TRUE(IsCheckValueCorrectness<T>(begin, end), "wrong uninitialized_value_construct_n");
89         std::destroy_n(exec, begin, n);
90     }
91 };
92 
93 template <typename T>
94 void
95 test_uninit_construct_by_type()
96 {
97     std::size_t N = 100000;
98     for (size_t n = 0; n <= N; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
99     {
100         std::unique_ptr<T[]> p(new T[n]);
101         invoke_on_all_policies(test_uninit_construct(), p.get(), std::next(p.get(), n), n, std::is_trivial<T>());
102     }
103 }
104 
105 int32_t
106 main()
107 {
108 
109     // for user-defined types
110 #if !_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN
111     test_uninit_construct_by_type<Wrapper<int32_t>>();
112     test_uninit_construct_by_type<Wrapper<std::vector<std::string>>>();
113 #endif
114 
115     // for trivial types
116     test_uninit_construct_by_type<int8_t>();
117     test_uninit_construct_by_type<float64_t>();
118 
119     std::cout << done() << std::endl;
120     return 0;
121 }
122