#pragma once #include "com_include.h" namespace dxvk { /** * \brief Increment public ref count * * If the pointer is not \c nullptr, this * calls \c AddRef for the given object. * \returns Pointer to the object */ template T* ref(T* object) { if (object != nullptr) object->AddRef(); return object; } /** * \brief Ref count methods for public references */ template struct ComRef_ { static void incRef(T* ptr) { ptr->AddRef(); } static void decRef(T* ptr) { ptr->Release(); } }; /** * \brief Ref count methods for private references */ template struct ComRef_ { static void incRef(T* ptr) { ptr->AddRefPrivate(); } static void decRef(T* ptr) { ptr->ReleasePrivate(); } }; /** * \brief COM pointer * * Implements automatic reference * counting for COM objects. */ template class Com { using ComRef = ComRef_; public: Com() { } Com(std::nullptr_t) { } Com(T* object) : m_ptr(object) { this->incRef(); } Com(const Com& other) : m_ptr(other.m_ptr) { this->incRef(); } Com(Com&& other) : m_ptr(other.m_ptr) { other.m_ptr = nullptr; } Com& operator = (T* object) { this->decRef(); m_ptr = object; this->incRef(); return *this; } Com& operator = (const Com& other) { other.incRef(); this->decRef(); m_ptr = other.m_ptr; return *this; } Com& operator = (Com&& other) { this->decRef(); this->m_ptr = other.m_ptr; other.m_ptr = nullptr; return *this; } Com& operator = (std::nullptr_t) { this->decRef(); m_ptr = nullptr; return *this; } ~Com() { this->decRef(); } T* operator -> () const { return m_ptr; } T** operator & () { return &m_ptr; } T* const* operator & () const { return &m_ptr; } template bool operator == (const Com& other) const { return m_ptr == other.m_ptr; } template bool operator != (const Com& other) const { return m_ptr != other.m_ptr; } bool operator == (const T* other) const { return m_ptr == other; } bool operator != (const T* other) const { return m_ptr != other; } bool operator == (std::nullptr_t) const { return m_ptr == nullptr; } bool operator != (std::nullptr_t) const { return m_ptr != nullptr; } T* ref() const { return dxvk::ref(m_ptr); } T* ptr() const { return m_ptr; } Com pubRef() const { return m_ptr; } Com prvRef() const { return m_ptr; } private: T* m_ptr = nullptr; void incRef() const { if (m_ptr != nullptr) ComRef::incRef(m_ptr); } void decRef() const { if (m_ptr != nullptr) ComRef::decRef(m_ptr); } }; }