#pragma once template class GpComPtr final { public: GpComPtr(); GpComPtr(const GpComPtr &other); explicit GpComPtr(T *ptr); ~GpComPtr(); GpComPtr &operator=(const GpComPtr &other); GpComPtr &operator=(T *other); bool operator==(const GpComPtr &other) const; bool operator!=(const GpComPtr &other) const; bool operator==(const T *other) const; bool operator!=(const T *other) const; operator T*() const; T *operator->() const; T **GetMutablePtr(); private: T *m_ptr; }; template inline GpComPtr::GpComPtr() : m_ptr(nullptr) { } template inline GpComPtr::GpComPtr(const GpComPtr &other) : m_ptr(other.m_ptr) { if (m_ptr) m_ptr->AddRef(); } template inline GpComPtr::GpComPtr(T *ptr) : m_ptr(ptr) { if (ptr) ptr->AddRef(); } template inline GpComPtr::~GpComPtr() { if (m_ptr) m_ptr->Release(); } template inline GpComPtr &GpComPtr::operator=(const GpComPtr &other) { (*this) = other.m_ptr; return *this; } template inline GpComPtr &GpComPtr::operator=(T *other) { if (other) other->AddRef(); if (m_ptr) m_ptr->Release(); m_ptr = other; return *this; } template inline bool GpComPtr::operator==(const GpComPtr &other) const { return m_ptr == other.m_ptr; } template inline bool GpComPtr::operator!=(const GpComPtr &other) const { return !((*this) == other); } template inline bool GpComPtr::operator==(const T *other) const { return m_ptr == other; } template inline bool GpComPtr::operator!=(const T *other) const { return !((*this) == other); } template T **GpComPtr::GetMutablePtr() { return &m_ptr; } template inline GpComPtr::operator T*() const { return m_ptr; } template inline T *GpComPtr::operator->() const { return m_ptr; }