From ddaae32525258a774335de9214397e420bb4be60 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 24 Feb 2026 16:00:14 -0500 Subject: [PATCH] Add casting move constructor --- include/rcp.h | 11 ++++++++++- test/tests.cpp | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/rcp.h b/include/rcp.h index 50a6d7d..7657bea 100644 --- a/include/rcp.h +++ b/include/rcp.h @@ -31,6 +31,8 @@ template class rcp { + template friend class rcp; + private: T * ptr = nullptr; @@ -100,7 +102,7 @@ public: /* Upcasting constructor: allows rcp -> rcp */ template - rcp(const rcp & other) : ptr(static_cast(other.get_raw())) + rcp(const rcp & other) : ptr(static_cast(other.ptr)) { static_assert(std::is_base_of::value, "rcp: implicit cast must be an upcast"); if (ptr) @@ -109,6 +111,13 @@ public: } } + template + rcp(rcp && other) : ptr(static_cast(other.ptr)) + { + static_assert(std::is_base_of::value, "rcp: implicit cast must be an upcast"); + other.ptr = nullptr; + } + T * get_raw() const { return ptr; diff --git a/test/tests.cpp b/test/tests.cpp index dcca39a..08442fc 100644 --- a/test/tests.cpp +++ b/test/tests.cpp @@ -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 derived = MyDerived::create(1.5); + rcp 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 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;