Add polymorphism support to Ref

This commit is contained in:
2025-09-11 14:15:52 -04:00
parent 9a8d4feedd
commit 5d932bf36c
6 changed files with 331 additions and 6 deletions

View File

@@ -135,6 +135,18 @@ template <typename T> struct Ref {
}
}
/**
* @brief Converting copy constructor for polymorphism (Derived -> Base)
*/
template <typename U>
Ref(const Ref<U> &other) noexcept
requires std::is_convertible_v<U *, T *>
: ptr(other.ptr), control_block(other.control_block) {
if (control_block) {
control_block->increment_strong();
}
}
/**
* @brief Copy assignment operator
*/
@@ -150,6 +162,22 @@ template <typename T> struct Ref {
return *this;
}
/**
* @brief Converting assignment operator for polymorphism (Derived -> Base)
*/
template <typename U>
Ref &operator=(const Ref<U> &other) noexcept
requires std::is_convertible_v<U *, T *>
{
release();
ptr = other.ptr;
control_block = other.control_block;
if (control_block) {
control_block->increment_strong();
}
return *this;
}
/**
* @brief Move constructor - transfers ownership
*/
@@ -159,6 +187,17 @@ template <typename T> struct Ref {
other.control_block = nullptr;
}
/**
* @brief Converting move constructor for polymorphism (Derived -> Base)
*/
template <typename U>
Ref(Ref<U> &&other) noexcept
requires std::is_convertible_v<U *, T *>
: ptr(other.ptr), control_block(other.control_block) {
other.ptr = nullptr;
other.control_block = nullptr;
}
/**
* @brief Move assignment operator
*/
@@ -173,6 +212,22 @@ template <typename T> struct Ref {
return *this;
}
/**
* @brief Converting move assignment operator for polymorphism (Derived ->
* Base)
*/
template <typename U>
Ref &operator=(Ref<U> &&other) noexcept
requires std::is_convertible_v<U *, T *>
{
release();
ptr = other.ptr;
control_block = other.control_block;
other.ptr = nullptr;
other.control_block = nullptr;
return *this;
}
/**
* @brief Reset to empty state
*/
@@ -233,6 +288,7 @@ private:
friend Ref<U> make_ref(Args &&...args);
template <typename U> friend struct WeakRef;
template <typename U> friend struct Ref;
};
/**
@@ -302,6 +358,83 @@ template <typename T> struct WeakRef {
}
}
/**
* @brief Converting copy constructor from WeakRef for polymorphism
*/
template <typename U>
WeakRef(const WeakRef<U> &other) noexcept
requires std::is_convertible_v<U *, T *>
: control_block(other.control_block) {
if (control_block) {
control_block->increment_weak();
}
}
/**
* @brief Converting copy constructor from Ref for polymorphism
*/
template <typename U>
WeakRef(const Ref<U> &ref) noexcept
requires std::is_convertible_v<U *, T *>
: control_block(ref.control_block) {
if (control_block) {
control_block->increment_weak();
}
}
/**
* @brief Converting copy assignment from WeakRef for polymorphism
*/
template <typename U>
WeakRef &operator=(const WeakRef<U> &other) noexcept
requires std::is_convertible_v<U *, T *>
{
release();
control_block = other.control_block;
if (control_block) {
control_block->increment_weak();
}
return *this;
}
/**
* @brief Converting copy assignment from Ref for polymorphism
*/
template <typename U>
WeakRef &operator=(const Ref<U> &ref) noexcept
requires std::is_convertible_v<U *, T *>
{
release();
control_block = ref.control_block;
if (control_block) {
control_block->increment_weak();
}
return *this;
}
/**
* @brief Converting move constructor from WeakRef for polymorphism
*/
template <typename U>
WeakRef(WeakRef<U> &&other) noexcept
requires std::is_convertible_v<U *, T *>
: control_block(other.control_block) {
other.control_block = nullptr;
}
/**
* @brief Converting move assignment from WeakRef for polymorphism
*/
template <typename U>
WeakRef &operator=(WeakRef<U> &&other) noexcept
requires std::is_convertible_v<U *, T *>
{
release();
control_block = other.control_block;
other.control_block = nullptr;
return *this;
}
/**
* @brief Copy assignment from WeakRef
*/
@@ -393,6 +526,7 @@ private:
}
template <typename U> friend struct Ref;
template <typename U> friend struct WeakRef;
};
/**