From 888906a6da7f10ec7884e18c5cbc19bba21b2d42 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 22 Sep 2024 02:39:09 +0200 Subject: [PATCH] [util] Add some functionality to smart pointer Basically lets us deal with objects that manage their own destruction, which ideally shold be all of them at some point. Also adds some missing comparison operators. --- src/util/rc/util_rc_ptr.h | 70 ++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/util/rc/util_rc_ptr.h b/src/util/rc/util_rc_ptr.h index d6c0c3632..c528120bc 100644 --- a/src/util/rc/util_rc_ptr.h +++ b/src/util/rc/util_rc_ptr.h @@ -4,7 +4,7 @@ #include namespace dxvk { - + /** * \brief Pointer for reference-counted objects * @@ -17,50 +17,50 @@ namespace dxvk { template friend class Rc; public: - - Rc() { } + + Rc() = default; Rc(std::nullptr_t) { } - + Rc(T* object) : m_object(object) { this->incRef(); } - + Rc(const Rc& other) : m_object(other.m_object) { this->incRef(); } - + template Rc(const Rc& other) : m_object(other.m_object) { this->incRef(); } - + Rc(Rc&& other) : m_object(other.m_object) { other.m_object = nullptr; } - + template Rc(Rc&& other) : m_object(other.m_object) { other.m_object = nullptr; } - + Rc& operator = (std::nullptr_t) { this->decRef(); m_object = nullptr; return *this; } - + Rc& operator = (const Rc& other) { other.incRef(); this->decRef(); m_object = other.m_object; return *this; } - + template Rc& operator = (const Rc& other) { other.incRef(); @@ -68,14 +68,14 @@ namespace dxvk { m_object = other.m_object; return *this; } - + Rc& operator = (Rc&& other) { this->decRef(); this->m_object = other.m_object; other.m_object = nullptr; return *this; } - + template Rc& operator = (Rc&& other) { this->decRef(); @@ -83,40 +83,58 @@ namespace dxvk { other.m_object = nullptr; return *this; } - + ~Rc() { this->decRef(); m_object = nullptr; } - + T& operator * () const { return *m_object; } T* operator -> () const { return m_object; } T* ptr() const { return m_object; } - - bool operator == (const Rc& other) const { return m_object == other.m_object; } - bool operator != (const Rc& other) const { return m_object != other.m_object; } - + + template bool operator == (const Rc& other) const { return m_object == other.m_object; } + template bool operator != (const Rc& other) const { return m_object != other.m_object; } + + template bool operator == (Tx* other) const { return m_object == other; } + template bool operator != (Tx* other) const { return m_object != other; } + bool operator == (std::nullptr_t) const { return m_object == nullptr; } bool operator != (std::nullptr_t) const { return m_object != nullptr; } + explicit operator bool () const { + return m_object != nullptr; + } + private: - + T* m_object = nullptr; - + force_inline void incRef() const { if (m_object != nullptr) m_object->incRef(); } - + force_inline void decRef() const { if (m_object != nullptr) { - if (m_object->decRef() == 0) - delete m_object; + if constexpr (std::is_void_vdecRef())>) { + m_object->decRef(); + } else { + // Deprecated, objects should manage themselves now. + if (!m_object->decRef()) + delete m_object; + } } } - + }; - + + template + bool operator == (Tx* a, const Rc& b) { return b == a; } + + template + bool operator != (Tx* a, const Rc& b) { return b != a; } + } template