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 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 assert(A::count == expect_alive);
60 std::unique_ptr<ValueT> s(p);
61 assert(s.get() == p);
62 }
63 assert(A::count == 0);
64 {
65 A* p = newValue<ValueT>(expect_alive);
66 assert(A::count == expect_alive);
67 std::unique_ptr<ValueT, NCDeleter<ValueT> > s(p);
68 assert(s.get() == p);
69 assert(s.get_deleter().state() == 0);
70 }
71 assert(A::count == 0);
72 {
73 A* p = newValue<ValueT>(expect_alive);
74 assert(A::count == expect_alive);
75 std::unique_ptr<ValueT, DefaultCtorDeleter<ValueT> > s(p);
76 assert(s.get() == p);
77 assert(s.get_deleter().state() == 0);
78 }
79 assert(A::count == 0);
80 }
81
test_derived()82 void test_derived() {
83 {
84 B* p = new B;
85 assert(A::count == 1);
86 assert(B::count == 1);
87 std::unique_ptr<A> s(p);
88 assert(s.get() == p);
89 }
90 assert(A::count == 0);
91 assert(B::count == 0);
92 {
93 B* p = new B;
94 assert(A::count == 1);
95 assert(B::count == 1);
96 std::unique_ptr<A, NCDeleter<A> > s(p);
97 assert(s.get() == p);
98 assert(s.get_deleter().state() == 0);
99 }
100 assert(A::count == 0);
101 assert(B::count == 0);
102 }
103
104 #if TEST_STD_VER >= 11
105 struct NonDefaultDeleter {
106 NonDefaultDeleter() = delete;
operator ()NonDefaultDeleter107 void operator()(void*) const {}
108 };
109
110 struct GenericDeleter {
111 void operator()(void*) const;
112 };
113 #endif
114
115 template <class T>
test_sfinae()116 void test_sfinae() {
117 #if TEST_STD_VER >= 11
118 { // the constructor does not participate in overload resolution when
119 // the deleter is a pointer type
120 using U = std::unique_ptr<T, void (*)(void*)>;
121 static_assert(!std::is_constructible<U, T*>::value, "");
122 }
123 { // the constructor does not participate in overload resolution when
124 // the deleter is not default constructible
125 using Del = CDeleter<T>;
126 using U1 = std::unique_ptr<T, NonDefaultDeleter>;
127 using U2 = std::unique_ptr<T, Del&>;
128 using U3 = std::unique_ptr<T, Del const&>;
129 static_assert(!std::is_constructible<U1, T*>::value, "");
130 static_assert(!std::is_constructible<U2, T*>::value, "");
131 static_assert(!std::is_constructible<U3, T*>::value, "");
132 }
133 #endif
134 }
135
test_sfinae_runtime()136 static void test_sfinae_runtime() {
137 #if TEST_STD_VER >= 11
138 { // the constructor does not participate in overload resolution when
139 // a base <-> derived conversion would occur.
140 using UA = std::unique_ptr<A[]>;
141 using UAD = std::unique_ptr<A[], GenericDeleter>;
142 using UAC = std::unique_ptr<const A[]>;
143 using UB = std::unique_ptr<B[]>;
144 using UBD = std::unique_ptr<B[], GenericDeleter>;
145 using UBC = std::unique_ptr<const B[]>;
146
147 static_assert(!std::is_constructible<UA, B*>::value, "");
148 static_assert(!std::is_constructible<UB, A*>::value, "");
149 static_assert(!std::is_constructible<UAD, B*>::value, "");
150 static_assert(!std::is_constructible<UBD, A*>::value, "");
151 static_assert(!std::is_constructible<UAC, const B*>::value, "");
152 static_assert(!std::is_constructible<UBC, const A*>::value, "");
153 }
154 #endif
155 }
156
157 DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
158 { doIncompleteTypeTest(1, getNewIncomplete()); }
159 checkNumIncompleteTypeAlive(0);
160 {
161 doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(
162 1, getNewIncomplete());
163 }
164 checkNumIncompleteTypeAlive(0);
165 })
166
main(int,char **)167 int main(int, char**) {
168 {
169 test_pointer</*IsArray*/ false>();
170 test_derived();
171 test_sfinae<int>();
172 }
173 {
174 test_pointer</*IsArray*/ true>();
175 test_sfinae<int[]>();
176 test_sfinae_runtime();
177 }
178
179 return 0;
180 }
181