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> 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 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; 100 void operator()(void*) const {} 101 }; 102 103 struct GenericDeleter { 104 void operator()(void*) const; 105 }; 106 #endif 107 108 template <class T> 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 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 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