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() 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 "../../deleter.h" 36 37 // unique_ptr(pointer) ctor should only require default Deleter ctor 38 39 struct A 40 { 41 static int count; 42 A() {++count;} 43 A(const A&) {++count;} 44 virtual ~A() {--count;} 45 }; 46 47 int A::count = 0; 48 49 50 struct B 51 : public A 52 { 53 static int count; 54 B() {++count;} 55 B(const B&) {++count;} 56 virtual ~B() {--count;} 57 }; 58 59 int B::count = 0; 60 61 62 struct IncompleteT; 63 64 IncompleteT* getIncomplete(); 65 void checkNumIncompleteTypeAlive(int i); 66 67 template <class Del = std::default_delete<IncompleteT> > 68 struct StoresIncomplete { 69 std::unique_ptr<IncompleteT, Del> m_ptr; 70 StoresIncomplete() {} 71 explicit StoresIncomplete(IncompleteT* ptr) : m_ptr(ptr) {} 72 ~StoresIncomplete(); 73 74 IncompleteT* get() const { return m_ptr.get(); } 75 Del& get_deleter() { return m_ptr.get_deleter(); } 76 }; 77 78 void test_pointer() 79 { 80 { 81 A* p = new A; 82 assert(A::count == 1); 83 std::unique_ptr<A> s(p); 84 assert(s.get() == p); 85 } 86 assert(A::count == 0); 87 { 88 A* p = new A; 89 assert(A::count == 1); 90 std::unique_ptr<A, NCDeleter<A> > s(p); 91 assert(s.get() == p); 92 assert(s.get_deleter().state() == 0); 93 } 94 assert(A::count == 0); 95 } 96 97 void test_derived() 98 { 99 { 100 B* p = new B; 101 assert(A::count == 1); 102 assert(B::count == 1); 103 std::unique_ptr<A> s(p); 104 assert(s.get() == p); 105 } 106 assert(A::count == 0); 107 assert(B::count == 0); 108 { 109 B* p = new B; 110 assert(A::count == 1); 111 assert(B::count == 1); 112 std::unique_ptr<A, NCDeleter<A> > s(p); 113 assert(s.get() == p); 114 assert(s.get_deleter().state() == 0); 115 } 116 assert(A::count == 0); 117 assert(B::count == 0); 118 } 119 120 void test_incomplete() 121 { 122 { 123 IncompleteT* p = getIncomplete(); 124 checkNumIncompleteTypeAlive(1); 125 StoresIncomplete<> s(p); 126 assert(s.get() == p); 127 } 128 checkNumIncompleteTypeAlive(0); 129 { 130 IncompleteT* p = getIncomplete(); 131 checkNumIncompleteTypeAlive(1); 132 StoresIncomplete< NCDeleter<IncompleteT> > s(p); 133 assert(s.get() == p); 134 assert(s.get_deleter().state() == 0); 135 } 136 checkNumIncompleteTypeAlive(0); 137 } 138 139 struct IncompleteT { 140 static int count; 141 IncompleteT() { ++count; } 142 ~IncompleteT() {--count; } 143 }; 144 145 int IncompleteT::count = 0; 146 147 IncompleteT* getIncomplete() { 148 return new IncompleteT; 149 } 150 151 void checkNumIncompleteTypeAlive(int i) { 152 assert(IncompleteT::count == i); 153 } 154 155 template <class Del> 156 StoresIncomplete<Del>::~StoresIncomplete() { } 157 158 int main() 159 { 160 test_pointer(); 161 test_derived(); 162 test_incomplete(); 163 } 164