Finish reference.hpp
This commit is contained in:
@@ -103,7 +103,10 @@ struct ControlBlock {
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct Ref {
|
||||
T *get() {
|
||||
/**
|
||||
* @brief Get raw pointer to managed object
|
||||
*/
|
||||
T *get() const {
|
||||
if (!control_block)
|
||||
return nullptr;
|
||||
constexpr size_t cb_size = sizeof(detail::ControlBlock);
|
||||
@@ -114,12 +117,120 @@ template <typename T> struct Ref {
|
||||
padded_cb_size);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit Ref(detail::ControlBlock *cb) : control_block(cb) {}
|
||||
/**
|
||||
* @brief Dereference operator
|
||||
*/
|
||||
T &operator*() const { return *get(); }
|
||||
|
||||
/**
|
||||
* @brief Arrow operator
|
||||
*/
|
||||
T *operator->() const { return get(); }
|
||||
|
||||
/**
|
||||
* @brief Check if Ref is valid (not empty)
|
||||
*/
|
||||
explicit operator bool() const noexcept { return control_block != nullptr; }
|
||||
|
||||
/**
|
||||
* @brief Destructor - decrements strong reference count
|
||||
*/
|
||||
~Ref() { release(); }
|
||||
|
||||
/**
|
||||
* @brief Copy constructor - increments strong reference count
|
||||
*/
|
||||
Ref(const Ref &other) noexcept : control_block(other.control_block) {
|
||||
if (control_block) {
|
||||
control_block->increment_strong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment operator
|
||||
*/
|
||||
Ref &operator=(const Ref &other) noexcept {
|
||||
if (this != &other) {
|
||||
release();
|
||||
control_block = other.control_block;
|
||||
if (control_block) {
|
||||
control_block->increment_strong();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor - transfers ownership
|
||||
*/
|
||||
Ref(Ref &&other) noexcept : control_block(other.control_block) {
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator
|
||||
*/
|
||||
Ref &operator=(Ref &&other) noexcept {
|
||||
if (this != &other) {
|
||||
release();
|
||||
control_block = other.control_block;
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset to empty state
|
||||
*/
|
||||
void reset() noexcept {
|
||||
release();
|
||||
control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Equality comparison
|
||||
*/
|
||||
bool operator==(const Ref &other) const noexcept {
|
||||
return control_block == other.control_block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inequality comparison
|
||||
*/
|
||||
bool operator!=(const Ref &other) const noexcept { return !(*this == other); }
|
||||
|
||||
/**
|
||||
* @brief Default constructor - creates empty Ref
|
||||
*/
|
||||
Ref() : control_block(nullptr) {}
|
||||
|
||||
private:
|
||||
explicit Ref(detail::ControlBlock *cb) : control_block(cb) {}
|
||||
|
||||
detail::ControlBlock *control_block;
|
||||
|
||||
/**
|
||||
* @brief Release current reference and handle cleanup
|
||||
*/
|
||||
void release() noexcept {
|
||||
if (control_block) {
|
||||
uint64_t prev = control_block->decrement_strong();
|
||||
uint32_t prev_strong = static_cast<uint32_t>(prev);
|
||||
|
||||
// If this was the last strong reference, destroy the object
|
||||
if (prev_strong == 1) {
|
||||
T *obj = get();
|
||||
obj->~T();
|
||||
|
||||
// If no weak references either, free the entire allocation
|
||||
uint32_t prev_weak = static_cast<uint32_t>(prev >> 32);
|
||||
if (prev_weak == 0) {
|
||||
std::free(control_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U, typename... Args>
|
||||
friend Ref<U> make_ref(Args &&...args);
|
||||
|
||||
@@ -127,6 +238,10 @@ private:
|
||||
};
|
||||
|
||||
template <typename T> struct WeakRef {
|
||||
/**
|
||||
* @brief Attempt to promote WeakRef to Ref
|
||||
* @return Valid Ref if object still alive, empty Ref otherwise
|
||||
*/
|
||||
Ref<T> lock() {
|
||||
if (!control_block) {
|
||||
return Ref<T>();
|
||||
@@ -155,12 +270,109 @@ template <typename T> struct WeakRef {
|
||||
return Ref<T>(control_block);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit WeakRef(detail::ControlBlock *cb) : control_block(cb) {}
|
||||
/**
|
||||
* @brief Destructor - decrements weak reference count
|
||||
*/
|
||||
~WeakRef() { release(); }
|
||||
|
||||
/**
|
||||
* @brief Copy constructor from WeakRef
|
||||
*/
|
||||
WeakRef(const WeakRef &other) noexcept : control_block(other.control_block) {
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor from Ref
|
||||
*/
|
||||
WeakRef(const Ref<T> &ref) noexcept : control_block(ref.control_block) {
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment from WeakRef
|
||||
*/
|
||||
WeakRef &operator=(const WeakRef &other) noexcept {
|
||||
if (this != &other) {
|
||||
release();
|
||||
control_block = other.control_block;
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment from Ref
|
||||
*/
|
||||
WeakRef &operator=(const Ref<T> &ref) noexcept {
|
||||
release();
|
||||
control_block = ref.control_block;
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*/
|
||||
WeakRef(WeakRef &&other) noexcept : control_block(other.control_block) {
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move assignment
|
||||
*/
|
||||
WeakRef &operator=(WeakRef &&other) noexcept {
|
||||
if (this != &other) {
|
||||
release();
|
||||
control_block = other.control_block;
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset to empty state
|
||||
*/
|
||||
void reset() noexcept {
|
||||
release();
|
||||
control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default constructor - creates empty WeakRef
|
||||
*/
|
||||
WeakRef() : control_block(nullptr) {}
|
||||
|
||||
private:
|
||||
explicit WeakRef(detail::ControlBlock *cb) : control_block(cb) {}
|
||||
|
||||
detail::ControlBlock *control_block;
|
||||
|
||||
/**
|
||||
* @brief Release current weak reference and handle cleanup
|
||||
*/
|
||||
void release() noexcept {
|
||||
if (control_block) {
|
||||
uint64_t prev = control_block->decrement_weak();
|
||||
uint32_t prev_strong = static_cast<uint32_t>(prev);
|
||||
uint32_t prev_weak = static_cast<uint32_t>(prev >> 32);
|
||||
|
||||
// If this was the last weak reference and no strong references, free
|
||||
// control block
|
||||
if (prev_weak == 1 && prev_strong == 0) {
|
||||
std::free(control_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U> friend struct Ref;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user