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