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)...);
}
template <typename V, typename W>
friend rcp<V> rcp_dynamic_cast(rcp<W> && other);
};
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()));
}
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) \
public: \
void rcp_inc() const \

View File

@ -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<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()
{
rcp<MyBase> 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;
}