Add casting move constructor
This commit is contained in:
parent
7880adef89
commit
ddaae32525
@ -31,6 +31,8 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class rcp
|
class rcp
|
||||||
{
|
{
|
||||||
|
template <typename U> friend class rcp;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T * ptr = nullptr;
|
T * ptr = nullptr;
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ public:
|
|||||||
|
|
||||||
/* Upcasting constructor: allows rcp<Derived> -> rcp<Base> */
|
/* Upcasting constructor: allows rcp<Derived> -> rcp<Base> */
|
||||||
template <typename U>
|
template <typename U>
|
||||||
rcp(const rcp<U> & other) : ptr(static_cast<T *>(other.get_raw()))
|
rcp(const rcp<U> & other) : ptr(static_cast<T *>(other.ptr))
|
||||||
{
|
{
|
||||||
static_assert(std::is_base_of<T, U>::value, "rcp: implicit cast must be an upcast");
|
static_assert(std::is_base_of<T, U>::value, "rcp: implicit cast must be an upcast");
|
||||||
if (ptr)
|
if (ptr)
|
||||||
@ -109,6 +111,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
rcp(rcp<U> && other) : ptr(static_cast<T *>(other.ptr))
|
||||||
|
{
|
||||||
|
static_assert(std::is_base_of<T, U>::value, "rcp: implicit cast must be an upcast");
|
||||||
|
other.ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
T * get_raw() const
|
T * get_raw() const
|
||||||
{
|
{
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|||||||
@ -189,6 +189,22 @@ void test_upcast()
|
|||||||
assert(base->x == 1);
|
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()
|
void test_dynamic_cast_success()
|
||||||
{
|
{
|
||||||
rcp<MyDerived> derived = MyDerived::create(1.5);
|
rcp<MyDerived> derived = MyDerived::create(1.5);
|
||||||
@ -217,6 +233,7 @@ int main(int argc, char * argv[])
|
|||||||
test_move_assignment();
|
test_move_assignment();
|
||||||
test_move_assignment_releases_existing();
|
test_move_assignment_releases_existing();
|
||||||
test_upcast();
|
test_upcast();
|
||||||
|
test_move_upcast();
|
||||||
test_dynamic_cast_success();
|
test_dynamic_cast_success();
|
||||||
test_dynamic_cast_failure();
|
test_dynamic_cast_failure();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user