Add static_assert to upcasting constructor; add rcp_dynamic_cast()
This commit is contained in:
parent
ce921e31be
commit
7880adef89
@ -23,6 +23,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
|
||||
/**
|
||||
* Reference-counting pointer.
|
||||
@ -97,10 +98,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/* Casting constructor: allows rcp<Base> -> rcp<Derived> */
|
||||
/* Upcasting constructor: allows rcp<Derived> -> rcp<Base> */
|
||||
template <typename U>
|
||||
rcp(const rcp<U> & other) : ptr(static_cast<T *>(other.get_raw()))
|
||||
{
|
||||
static_assert(std::is_base_of<T, U>::value, "rcp: implicit cast must be an upcast");
|
||||
if (ptr)
|
||||
{
|
||||
ptr->rcp_inc();
|
||||
@ -154,6 +156,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
rcp<T> rcp_dynamic_cast(const rcp<U> & other)
|
||||
{
|
||||
return rcp<T>(dynamic_cast<T *>(other.get_raw()));
|
||||
}
|
||||
|
||||
#define rcp_managed_root(classname) \
|
||||
public: \
|
||||
void rcp_inc() const \
|
||||
|
||||
@ -181,6 +181,30 @@ void test_move_assignment_releases_existing()
|
||||
assert(mybase_destruct == destructed_before + 2);
|
||||
}
|
||||
|
||||
void test_upcast()
|
||||
{
|
||||
rcp<MyDerived> derived = MyDerived::create(1.5);
|
||||
rcp<MyBase> base = derived;
|
||||
assert(base);
|
||||
assert(base->x == 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();
|
||||
@ -192,5 +216,8 @@ int main(int argc, char * argv[])
|
||||
test_move_constructor();
|
||||
test_move_assignment();
|
||||
test_move_assignment_releases_existing();
|
||||
test_upcast();
|
||||
test_dynamic_cast_success();
|
||||
test_dynamic_cast_failure();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user