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