1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 14:52:10 +01:00

[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.
This commit is contained in:
Philip Rebohle 2024-09-22 02:39:09 +02:00 committed by Philip Rebohle
parent 06baa48c2b
commit 888906a6da

View File

@ -4,7 +4,7 @@
#include <ostream>
namespace dxvk {
/**
* \brief Pointer for reference-counted objects
*
@ -17,50 +17,50 @@ namespace dxvk {
template<typename Tx>
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<typename Tx>
Rc(const Rc<Tx>& other)
: m_object(other.m_object) {
this->incRef();
}
Rc(Rc&& other)
: m_object(other.m_object) {
other.m_object = nullptr;
}
template<typename Tx>
Rc(Rc<Tx>&& 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<typename Tx>
Rc& operator = (const Rc<Tx>& 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<typename Tx>
Rc& operator = (Rc<Tx>&& 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<typename Tx> bool operator == (const Rc<Tx>& other) const { return m_object == other.m_object; }
template<typename Tx> bool operator != (const Rc<Tx>& other) const { return m_object != other.m_object; }
template<typename Tx> bool operator == (Tx* other) const { return m_object == other; }
template<typename Tx> 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_v<decltype(m_object->decRef())>) {
m_object->decRef();
} else {
// Deprecated, objects should manage themselves now.
if (!m_object->decRef())
delete m_object;
}
}
}
};
template<typename Tx, typename Ty>
bool operator == (Tx* a, const Rc<Ty>& b) { return b == a; }
template<typename Tx, typename Ty>
bool operator != (Tx* a, const Rc<Ty>& b) { return b != a; }
}
template<typename T>