Add casting move constructor

This commit is contained in:
Josh Holtrop 2026-02-24 16:00:14 -05:00
parent 7880adef89
commit ddaae32525
2 changed files with 27 additions and 1 deletions

View File

@ -31,6 +31,8 @@
template <typename T>
class rcp
{
template <typename U> friend class rcp;
private:
T * ptr = nullptr;
@ -100,7 +102,7 @@ public:
/* Upcasting constructor: allows rcp<Derived> -> rcp<Base> */
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");
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
{
return ptr;

View File

@ -189,6 +189,22 @@ void test_upcast()
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);
@ -217,6 +233,7 @@ int main(int argc, char * argv[])
test_move_assignment();
test_move_assignment_releases_existing();
test_upcast();
test_move_upcast();
test_dynamic_cast_success();
test_dynamic_cast_failure();
return 0;