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