rcp/test/tests.cpp

263 lines
5.6 KiB
C++

#include <rcp.h>
#include <cassert>
#include <vector>
static int mybase_construct;
static int mybase_destruct;
static int myderived_construct;
static int myderived_destruct;
class MyBase
{
rcp_managed_root(MyBase);
protected:
MyBase(int x, int y)
{
this->x = x;
this->y = y;
mybase_construct++;
}
virtual ~MyBase()
{
mybase_destruct++;
}
public:
int x;
int y;
};
typedef rcp<MyBase> MyB;
class MyDerived : public MyBase
{
rcp_managed(MyDerived);
protected:
MyDerived(double v) : MyBase(1, 2)
{
this->v = v;
myderived_construct++;
}
virtual ~MyDerived()
{
myderived_destruct++;
}
public:
double v;
};
void test_class_hierarchy()
{
{
rcp<MyBase> mybase = MyBase::create(4, 5);
rcp<MyDerived> myderived = MyDerived::create(42.5);
}
assert(mybase_construct == 2);
assert(mybase_destruct == 2);
assert(myderived_construct == 1);
assert(myderived_destruct == 1);
}
void test_dereference()
{
rcp<MyBase> mybase = MyBase::create(2, 3);
assert(mybase->x == 2);
assert(mybase->y == 3);
assert((*mybase).x == 2);
assert((*mybase).y == 3);
rcp<MyBase> mybase2 = mybase;
assert(mybase == mybase2);
assert(!(mybase != mybase2));
}
void test_booleans()
{
rcp<MyBase> mybase = MyBase::create(2, 3);
assert(mybase);
assert(mybase != nullptr);
rcp<MyDerived> myderived;
assert(!myderived);
assert(myderived == nullptr);
}
void test_create()
{
MyB myb = MyB::create(8, 9);
assert(myb->x == 8);
}
struct MyObj
{
rcp_managed_root(MyObj);
public:
int v = {42};
template <typename R>
void add_to(R & receiver)
{
receiver.add(this);
}
};
struct Receiver
{
std::vector<rcp<MyObj>> objects;
void add(MyObj * o)
{
objects.push_back(rcp<MyObj>(o));
}
};
void test_multi_construct_from_raw_pointers()
{
Receiver r;
auto myo = MyObj::create();
for (size_t i = 0u; i < 5u; i++)
{
myo->add_to(r);
}
for (size_t i = 0u; i < 5u; i++)
{
assert(r.objects[i]->v == 42);
}
}
void test_copy_assignment_decrements_previous_reference()
{
MyB myb = MyB::create(12, 13);
MyB myb2 = MyB::create(14, 15);
myb = myb2;
assert(myb->x == 14);
}
void test_move_constructor()
{
int constructed_before = mybase_construct;
int destructed_before = mybase_destruct;
{
MyB a = MyB::create(1, 2);
MyB b = std::move(a);
assert(!a);
assert(b);
assert(b->x == 1);
assert(mybase_destruct == destructed_before);
}
assert(mybase_construct == constructed_before + 1);
assert(mybase_destruct == destructed_before + 1);
}
void test_move_assignment()
{
int constructed_before = mybase_construct;
int destructed_before = mybase_destruct;
{
MyB a = MyB::create(1, 2);
MyB b;
b = std::move(a);
assert(!a);
assert(b);
assert(b->x == 1);
assert(mybase_destruct == destructed_before);
}
assert(mybase_construct == constructed_before + 1);
assert(mybase_destruct == destructed_before + 1);
}
void test_move_assignment_releases_existing()
{
int constructed_before = mybase_construct;
int destructed_before = mybase_destruct;
{
MyB a = MyB::create(1, 2);
MyB b = MyB::create(3, 4);
b = std::move(a);
assert(!a);
assert(b->x == 1);
assert(mybase_destruct == destructed_before + 1);
}
assert(mybase_construct == constructed_before + 2);
assert(mybase_destruct == destructed_before + 2);
}
void test_cross_type_comparison()
{
rcp<MyDerived> derived = MyDerived::create(1.5);
rcp<MyBase> base = derived;
assert(base == derived);
assert(!(base != derived));
rcp<MyBase> other = MyBase::create(1, 2);
assert(base != other);
assert(!(base == other));
}
void test_reset()
{
int destructed_before = mybase_destruct;
MyB p = MyB::create(1, 2);
p.reset();
assert(!p);
assert(mybase_destruct == destructed_before + 1);
}
void test_upcast()
{
rcp<MyDerived> derived = MyDerived::create(1.5);
rcp<MyBase> base = derived;
assert(base);
assert(base->x == 1);
}
void test_move_upcast()
{
int constructed_before = mybase_construct;
int destructed_before = mybase_destruct;
{
rcp<MyDerived> derived = MyDerived::create(1.5);
rcp<MyBase> base = std::move(derived);
assert(!derived);
assert(base);
assert(base->x == 1);
assert(mybase_destruct == destructed_before);
}
assert(mybase_construct == constructed_before + 1);
assert(mybase_destruct == destructed_before + 1);
}
void test_dynamic_cast_success()
{
rcp<MyDerived> derived = MyDerived::create(1.5);
rcp<MyBase> base = derived;
rcp<MyDerived> back = rcp_dynamic_cast<MyDerived>(base);
assert(back);
assert(back->v == 1.5);
}
void test_dynamic_cast_failure()
{
rcp<MyBase> base = MyBase::create(1, 2);
rcp<MyDerived> derived = rcp_dynamic_cast<MyDerived>(base);
assert(!derived);
}
int main(int argc, char * argv[])
{
test_class_hierarchy();
test_dereference();
test_booleans();
test_create();
test_multi_construct_from_raw_pointers();
test_copy_assignment_decrements_previous_reference();
test_cross_type_comparison();
test_reset();
test_move_constructor();
test_move_assignment();
test_move_assignment_releases_existing();
test_upcast();
test_move_upcast();
test_dynamic_cast_success();
test_dynamic_cast_failure();
return 0;
}