1 #include <cxxtest/TestSuite.h> 2 3 #include "common/ptr.h" 4 5 class PtrTestSuite : public CxxTest::TestSuite { 6 public: 7 8 struct A { 9 int a; 10 }; 11 12 struct B : public A { 13 int b; 14 }; 15 16 // A simple class which keeps track of all its instances 17 class InstanceCountingClass { 18 public: 19 static int count; InstanceCountingClass()20 InstanceCountingClass() { count++; } InstanceCountingClass(const InstanceCountingClass &)21 InstanceCountingClass(const InstanceCountingClass&) { count++; } ~InstanceCountingClass()22 ~InstanceCountingClass() { count--; } 23 }; 24 test_deletion()25 void test_deletion() { 26 TS_ASSERT_EQUALS(InstanceCountingClass::count, 0); 27 { 28 Common::SharedPtr<InstanceCountingClass> p1(new InstanceCountingClass()); 29 TS_ASSERT_EQUALS(InstanceCountingClass::count, 1); 30 31 Common::ScopedPtr<InstanceCountingClass> p2(new InstanceCountingClass()); 32 TS_ASSERT_EQUALS(InstanceCountingClass::count, 2); 33 } 34 TS_ASSERT_EQUALS(InstanceCountingClass::count, 0); 35 } 36 37 struct CustomDeleter { 38 static bool invoked; operatorCustomDeleter39 void operator()(int *object) { 40 invoked = true; 41 delete object; 42 } 43 }; 44 test_scoped_deleter()45 void test_scoped_deleter() { 46 CustomDeleter::invoked = false; 47 48 { 49 Common::ScopedPtr<int, CustomDeleter> a(new int(0)); 50 TS_ASSERT(!CustomDeleter::invoked); 51 } 52 53 TS_ASSERT(CustomDeleter::invoked); 54 } 55 test_disposable_deleter()56 void test_disposable_deleter() { 57 CustomDeleter::invoked = false; 58 59 { 60 Common::DisposablePtr<int, CustomDeleter> a1(new int, DisposeAfterUse::YES); 61 TS_ASSERT(!CustomDeleter::invoked); 62 } 63 64 TS_ASSERT(CustomDeleter::invoked); 65 CustomDeleter::invoked = false; 66 67 int *a = new int; 68 { 69 Common::DisposablePtr<int, CustomDeleter> a2(a, DisposeAfterUse::NO); 70 } 71 72 TS_ASSERT(!CustomDeleter::invoked); 73 delete a; 74 } 75 test_scoped_deref()76 void test_scoped_deref() { 77 A *raw = new A(); 78 raw->a = 123; 79 Common::ScopedPtr<A> a(raw); 80 TS_ASSERT_EQUALS(&*a, &*raw); 81 TS_ASSERT_EQUALS(a->a, raw->a); 82 } 83 test_disposable_deref()84 void test_disposable_deref() { 85 A *raw = new A(); 86 raw->a = 123; 87 Common::DisposablePtr<A> a(raw, DisposeAfterUse::YES); 88 TS_ASSERT_EQUALS(&*a, &*raw); 89 TS_ASSERT_EQUALS(a->a, raw->a); 90 } 91 test_assign()92 void test_assign() { 93 Common::SharedPtr<int> p1(new int(1)); 94 TS_ASSERT(p1.unique()); 95 TS_ASSERT_EQUALS(*p1, 1); 96 97 { 98 Common::SharedPtr<int> p2 = p1; 99 TS_ASSERT(!p1.unique()); 100 TS_ASSERT_EQUALS(p1.refCount(), p2.refCount()); 101 TS_ASSERT_EQUALS(p1.refCount(), 2); 102 TS_ASSERT_EQUALS(p1, p2); 103 TS_ASSERT_EQUALS(*p2, 1); 104 { 105 Common::SharedPtr<int> p3; 106 p3 = p2; 107 TS_ASSERT_EQUALS(p3, p2); 108 TS_ASSERT_EQUALS(p3, p1); 109 TS_ASSERT_EQUALS(p1.refCount(), 3); 110 TS_ASSERT_EQUALS(*p3, 1); 111 *p3 = 0; 112 TS_ASSERT_EQUALS(*p3, 0); 113 } 114 TS_ASSERT_EQUALS(*p2, 0); 115 TS_ASSERT_EQUALS(p1.refCount(), 2); 116 } 117 118 TS_ASSERT_EQUALS(*p1, 0); 119 TS_ASSERT(p1.unique()); 120 } 121 122 template<class T> 123 struct Deleter { 124 bool *test; operatorDeleter125 void operator()(T *ptr) { *test = true; delete ptr; } 126 }; 127 test_deleter()128 void test_deleter() { 129 Deleter<int> myDeleter; 130 bool test = false; 131 myDeleter.test = &test; 132 133 { 134 Common::SharedPtr<int> p(new int(1), myDeleter); 135 } 136 137 TS_ASSERT_EQUALS(test, true); 138 } 139 test_compare()140 void test_compare() { 141 Common::SharedPtr<int> p1(new int(1)); 142 Common::SharedPtr<int> p2; 143 144 TS_ASSERT(p1); 145 TS_ASSERT(!p2); 146 147 TS_ASSERT(p1 != 0); 148 TS_ASSERT(p2 == 0); 149 150 p1.reset(); 151 TS_ASSERT(!p1); 152 } 153 test_cast()154 void test_cast() { 155 Common::SharedPtr<B> b(new B); 156 Common::SharedPtr<A> a(b); 157 a = b; 158 } 159 }; 160 161 int PtrTestSuite::InstanceCountingClass::count = 0; 162 bool PtrTestSuite::CustomDeleter::invoked = false; 163