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