Fix polymorphic WeakRef bug
This commit is contained in:
@@ -221,7 +221,7 @@ template <typename T> struct Ref {
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
return WeakRef<T>(control_block);
|
||||
return WeakRef<T>(ptr, control_block);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,7 +328,7 @@ template <typename T> struct WeakRef {
|
||||
expected_strong, expected_strong + 1, std::memory_order_acquire,
|
||||
std::memory_order_relaxed)) {
|
||||
// Success - we incremented the strong count
|
||||
return Ref<T>(get_object_ptr(), control_block);
|
||||
return Ref<T>(ptr, control_block);
|
||||
}
|
||||
// CAS failed, expected_strong now contains the current value, retry
|
||||
}
|
||||
@@ -384,7 +384,8 @@ template <typename T> struct WeakRef {
|
||||
template <typename U>
|
||||
WeakRef(WeakRef<U> &&other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
: control_block(other.control_block) {
|
||||
: ptr(other.ptr), control_block(other.control_block) {
|
||||
other.ptr = nullptr;
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
@@ -396,7 +397,9 @@ template <typename T> struct WeakRef {
|
||||
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;
|
||||
}
|
||||
@@ -416,7 +419,9 @@ template <typename T> struct WeakRef {
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*/
|
||||
WeakRef(WeakRef &&other) noexcept : control_block(other.control_block) {
|
||||
WeakRef(WeakRef &&other) noexcept
|
||||
: ptr(other.ptr), control_block(other.control_block) {
|
||||
other.ptr = nullptr;
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
@@ -426,7 +431,9 @@ template <typename T> struct WeakRef {
|
||||
WeakRef &operator=(WeakRef &&other) noexcept {
|
||||
if (this != &other) {
|
||||
release();
|
||||
ptr = other.ptr;
|
||||
control_block = other.control_block;
|
||||
other.ptr = nullptr;
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
return *this;
|
||||
@@ -440,7 +447,7 @@ template <typename T> struct WeakRef {
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
return WeakRef(control_block);
|
||||
return WeakRef(ptr, control_block);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -448,31 +455,22 @@ template <typename T> struct WeakRef {
|
||||
*/
|
||||
void reset() noexcept {
|
||||
release();
|
||||
ptr = nullptr;
|
||||
control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default constructor - creates empty WeakRef
|
||||
*/
|
||||
WeakRef() : control_block(nullptr) {}
|
||||
WeakRef() : ptr(nullptr), control_block(nullptr) {}
|
||||
|
||||
private:
|
||||
explicit WeakRef(detail::ControlBlock *cb) : control_block(cb) {}
|
||||
explicit WeakRef(T *object_ptr, detail::ControlBlock *cb)
|
||||
: ptr(object_ptr), control_block(cb) {}
|
||||
|
||||
T *ptr;
|
||||
detail::ControlBlock *control_block;
|
||||
|
||||
// Helper to calculate object pointer from control block
|
||||
T *get_object_ptr() const {
|
||||
if (!control_block)
|
||||
return nullptr;
|
||||
constexpr size_t cb_size = sizeof(detail::ControlBlock);
|
||||
constexpr size_t alignment = alignof(T);
|
||||
constexpr size_t padded_cb_size =
|
||||
(cb_size + alignment - 1) & ~(alignment - 1);
|
||||
return reinterpret_cast<T *>(reinterpret_cast<char *>(control_block) +
|
||||
padded_cb_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release current weak reference and handle cleanup
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user