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> 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 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; 107 void operator()(void*) const {} 108 }; 109 110 struct GenericDeleter { 111 void operator()(void*) const; 112 }; 113 #endif 114 115 template <class T> 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 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 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