Add move version of rcp_dynamic_cast()

This commit is contained in:
Josh Holtrop 2026-02-24 17:17:34 -05:00
parent 69ecab39f2
commit 627661158e
2 changed files with 43 additions and 0 deletions

View File

@ -174,6 +174,9 @@ public:
{ {
return T::create(std::forward<Args>(args)...); return T::create(std::forward<Args>(args)...);
} }
template <typename V, typename W>
friend rcp<V> rcp_dynamic_cast(rcp<W> && other);
}; };
template <typename T, typename U> template <typename T, typename U>
@ -182,6 +185,20 @@ rcp<T> rcp_dynamic_cast(const rcp<U> & other)
return rcp<T>(dynamic_cast<T *>(other.get_raw())); return rcp<T>(dynamic_cast<T *>(other.get_raw()));
} }
template <typename T, typename U>
rcp<T> rcp_dynamic_cast(rcp<U> && other)
{
T * p = dynamic_cast<T *>(other.ptr);
if (p)
{
other.ptr = nullptr;
rcp<T> result;
result.ptr = p;
return result;
}
return rcp<T>();
}
#define rcp_managed_root(classname) \ #define rcp_managed_root(classname) \
public: \ public: \
void rcp_inc() const \ void rcp_inc() const \

View File

@ -234,6 +234,30 @@ void test_dynamic_cast_success()
assert(back->v == 1.5); assert(back->v == 1.5);
} }
void test_dynamic_cast_move_success()
{
int constructed_before = mybase_construct;
int destructed_before = mybase_destruct;
{
rcp<MyBase> base = MyDerived::create(1.5);
rcp<MyDerived> derived = rcp_dynamic_cast<MyDerived>(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<MyBase> base = MyBase::create(1, 2);
rcp<MyDerived> derived = rcp_dynamic_cast<MyDerived>(std::move(base));
assert(!derived);
assert(base);
}
void test_dynamic_cast_failure() void test_dynamic_cast_failure()
{ {
rcp<MyBase> base = MyBase::create(1, 2); rcp<MyBase> base = MyBase::create(1, 2);
@ -258,5 +282,7 @@ int main(int argc, char * argv[])
test_move_upcast(); test_move_upcast();
test_dynamic_cast_success(); test_dynamic_cast_success();
test_dynamic_cast_failure(); test_dynamic_cast_failure();
test_dynamic_cast_move_success();
test_dynamic_cast_move_failure();
return 0; return 0;
} }