From 627661158e107ad959b4dbcfd3b9264ebb14ca22 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 24 Feb 2026 17:17:34 -0500 Subject: [PATCH] Add move version of rcp_dynamic_cast() --- include/rcp.h | 17 +++++++++++++++++ test/tests.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/rcp.h b/include/rcp.h index fbcd38c..3d5a4df 100644 --- a/include/rcp.h +++ b/include/rcp.h @@ -174,6 +174,9 @@ public: { return T::create(std::forward(args)...); } + + template + friend rcp rcp_dynamic_cast(rcp && other); }; template @@ -182,6 +185,20 @@ rcp rcp_dynamic_cast(const rcp & other) return rcp(dynamic_cast(other.get_raw())); } +template +rcp rcp_dynamic_cast(rcp && other) +{ + T * p = dynamic_cast(other.ptr); + if (p) + { + other.ptr = nullptr; + rcp result; + result.ptr = p; + return result; + } + return rcp(); +} + #define rcp_managed_root(classname) \ public: \ void rcp_inc() const \ diff --git a/test/tests.cpp b/test/tests.cpp index d4dac69..ef3d6f1 100644 --- a/test/tests.cpp +++ b/test/tests.cpp @@ -234,6 +234,30 @@ void test_dynamic_cast_success() assert(back->v == 1.5); } +void test_dynamic_cast_move_success() +{ + int constructed_before = mybase_construct; + int destructed_before = mybase_destruct; + { + rcp base = MyDerived::create(1.5); + rcp derived = rcp_dynamic_cast(std::move(base)); + assert(!base); + assert(derived); + assert(derived->v == 1.5); + assert(mybase_destruct == destructed_before); + } + assert(mybase_construct == constructed_before + 1); + assert(mybase_destruct == destructed_before + 1); +} + +void test_dynamic_cast_move_failure() +{ + rcp base = MyBase::create(1, 2); + rcp derived = rcp_dynamic_cast(std::move(base)); + assert(!derived); + assert(base); +} + void test_dynamic_cast_failure() { rcp base = MyBase::create(1, 2); @@ -258,5 +282,7 @@ int main(int argc, char * argv[]) test_move_upcast(); test_dynamic_cast_success(); test_dynamic_cast_failure(); + test_dynamic_cast_move_success(); + test_dynamic_cast_move_failure(); return 0; }