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