Finish reference.hpp

This commit is contained in:
2025-09-10 21:58:08 -04:00
parent 7c4d928807
commit 6aaca4c171

View File

@@ -103,7 +103,10 @@ struct ControlBlock {
} // namespace detail } // namespace detail
template <typename T> struct Ref { template <typename T> struct Ref {
T *get() { /**
* @brief Get raw pointer to managed object
*/
T *get() const {
if (!control_block) if (!control_block)
return nullptr; return nullptr;
constexpr size_t cb_size = sizeof(detail::ControlBlock); constexpr size_t cb_size = sizeof(detail::ControlBlock);
@@ -114,12 +117,120 @@ template <typename T> struct Ref {
padded_cb_size); 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) {} Ref() : control_block(nullptr) {}
private:
explicit Ref(detail::ControlBlock *cb) : control_block(cb) {}
detail::ControlBlock *control_block; 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> template <typename U, typename... Args>
friend Ref<U> make_ref(Args &&...args); friend Ref<U> make_ref(Args &&...args);
@@ -127,6 +238,10 @@ private:
}; };
template <typename T> struct WeakRef { 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() { Ref<T> lock() {
if (!control_block) { if (!control_block) {
return Ref<T>(); return Ref<T>();
@@ -155,12 +270,109 @@ template <typename T> struct WeakRef {
return Ref<T>(control_block); 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) {} WeakRef() : control_block(nullptr) {}
private:
explicit WeakRef(detail::ControlBlock *cb) : control_block(cb) {}
detail::ControlBlock *control_block; 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; template <typename U> friend struct Ref;
}; };