1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // <memory>
10
11 // unique_ptr
12
13 //=============================================================================
14 // TESTING std::unique_ptr::unique_ptr(pointer)
15 //
16 // Concerns:
17 // 1 The pointer constructor works for any default constructible deleter types.
18 // 2 The pointer constructor accepts pointers to derived types.
19 // 2 The stored type 'T' is allowed to be incomplete.
20 //
21 // Plan
22 // 1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
23 // types (C-1)
24 // 2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
25 // types where 'D' is derived from 'T'. (C-1,2)
26 // 3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
27 // types where 'T' is an incomplete type (C-1,3)
28
29 // Test unique_ptr(pointer) ctor
30
31 #include <memory>
32 #include <cassert>
33
34 #include "test_macros.h"
35 #include "unique_ptr_test_helper.h"
36
37 // unique_ptr(pointer) ctor should only require default Deleter ctor
38
39 template <bool IsArray>
test_pointer()40 TEST_CONSTEXPR_CXX23 void test_pointer() {
41 typedef typename std::conditional<!IsArray, A, A[]>::type ValueT;
42 const int expect_alive = IsArray ? 5 : 1;
43 #if TEST_STD_VER >= 11
44 {
45 using U1 = std::unique_ptr<ValueT>;
46 using U2 = std::unique_ptr<ValueT, Deleter<ValueT> >;
47
48 // Test for noexcept
49 static_assert(std::is_nothrow_constructible<U1, A*>::value, "");
50 static_assert(std::is_nothrow_constructible<U2, A*>::value, "");
51
52 // Test for explicit
53 static_assert(!std::is_convertible<A*, U1>::value, "");
54 static_assert(!std::is_convertible<A*, U2>::value, "");
55 }
56 #endif
57 {
58 A* p = newValue<ValueT>(expect_alive);
59 if (!TEST_IS_CONSTANT_EVALUATED)
60 assert(A::count == expect_alive);
61
62 std::unique_ptr<ValueT> s(p);
63 assert(s.get() == p);
64 }
65 if (!TEST_IS_CONSTANT_EVALUATED)
66 assert(A::count == 0);
67 {
68 A* p = newValue<ValueT>(expect_alive);
69 if (!TEST_IS_CONSTANT_EVALUATED)
70 assert(A::count == expect_alive);
71
72 std::unique_ptr<ValueT, NCDeleter<ValueT> > s(p);
73 assert(s.get() == p);
74 assert(s.get_deleter().state() == 0);
75 }
76 if (!TEST_IS_CONSTANT_EVALUATED)
77 assert(A::count == 0);
78 {
79 A* p = newValue<ValueT>(expect_alive);
80 if (!TEST_IS_CONSTANT_EVALUATED)
81 assert(A::count == expect_alive);
82
83 std::unique_ptr<ValueT, DefaultCtorDeleter<ValueT> > s(p);
84 assert(s.get() == p);
85 assert(s.get_deleter().state() == 0);
86 }
87 if (!TEST_IS_CONSTANT_EVALUATED)
88 assert(A::count == 0);
89 }
90
test_derived()91 TEST_CONSTEXPR_CXX23 void test_derived() {
92 {
93 B* p = new B;
94 if (!TEST_IS_CONSTANT_EVALUATED) {
95 assert(A::count == 1);
96 assert(B::count == 1);
97 }
98 std::unique_ptr<A> s(p);
99 assert(s.get() == p);
100 }
101 if (!TEST_IS_CONSTANT_EVALUATED) {
102 assert(A::count == 0);
103 assert(B::count == 0);
104 }
105 {
106 B* p = new B;
107 if (!TEST_IS_CONSTANT_EVALUATED) {
108 assert(A::count == 1);
109 assert(B::count == 1);
110 }
111 std::unique_ptr<A, NCDeleter<A> > s(p);
112 assert(s.get() == p);
113 assert(s.get_deleter().state() == 0);
114 }
115 if (!TEST_IS_CONSTANT_EVALUATED) {
116 assert(A::count == 0);
117 assert(B::count == 0);
118 }
119 }
120
121 #if TEST_STD_VER >= 11
122 struct NonDefaultDeleter {
123 NonDefaultDeleter() = delete;
operator ()NonDefaultDeleter124 void operator()(void*) const {}
125 };
126
127 struct GenericDeleter {
128 void operator()(void*) const;
129 };
130 #endif
131
132 template <class T>
test_sfinae()133 void TEST_CONSTEXPR_CXX23 test_sfinae() {
134 #if TEST_STD_VER >= 11
135 { // the constructor does not participate in overload resolution when
136 // the deleter is a pointer type
137 using U = std::unique_ptr<T, void (*)(void*)>;
138 static_assert(!std::is_constructible<U, T*>::value, "");
139 }
140 { // the constructor does not participate in overload resolution when
141 // the deleter is not default constructible
142 using Del = CDeleter<T>;
143 using U1 = std::unique_ptr<T, NonDefaultDeleter>;
144 using U2 = std::unique_ptr<T, Del&>;
145 using U3 = std::unique_ptr<T, Del const&>;
146 static_assert(!std::is_constructible<U1, T*>::value, "");
147 static_assert(!std::is_constructible<U2, T*>::value, "");
148 static_assert(!std::is_constructible<U3, T*>::value, "");
149 }
150 #endif
151 }
152
test_sfinae_runtime()153 static TEST_CONSTEXPR_CXX23 void test_sfinae_runtime() {
154 #if TEST_STD_VER >= 11
155 { // the constructor does not participate in overload resolution when
156 // a base <-> derived conversion would occur.
157 using UA = std::unique_ptr<A[]>;
158 using UAD = std::unique_ptr<A[], GenericDeleter>;
159 using UAC = std::unique_ptr<const A[]>;
160 using UB = std::unique_ptr<B[]>;
161 using UBD = std::unique_ptr<B[], GenericDeleter>;
162 using UBC = std::unique_ptr<const B[]>;
163
164 static_assert(!std::is_constructible<UA, B*>::value, "");
165 static_assert(!std::is_constructible<UB, A*>::value, "");
166 static_assert(!std::is_constructible<UAD, B*>::value, "");
167 static_assert(!std::is_constructible<UBD, A*>::value, "");
168 static_assert(!std::is_constructible<UAC, const B*>::value, "");
169 static_assert(!std::is_constructible<UBC, const A*>::value, "");
170 }
171 #endif
172 }
173
174 DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
175 { doIncompleteTypeTest(1, getNewIncomplete()); }
176 checkNumIncompleteTypeAlive(0);
177 {
178 doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(
179 1, getNewIncomplete());
180 }
181 checkNumIncompleteTypeAlive(0);
182 })
183
test()184 TEST_CONSTEXPR_CXX23 bool test() {
185 {
186 test_pointer</*IsArray*/ false>();
187 test_derived();
188 test_sfinae<int>();
189 }
190 {
191 test_pointer</*IsArray*/ true>();
192 test_sfinae<int[]>();
193 test_sfinae_runtime();
194 }
195
196 return true;
197 }
198
main(int,char **)199 int main(int, char**) {
200 test();
201 #if TEST_STD_VER >= 23
202 static_assert(test());
203 #endif
204
205 return 0;
206 }
207