#ifndef SMARTPTR_H #define SMARTPTR_H #ifdef _WIN32 #pragma once #endif class CRefCountAccessor { public: template< class T > static void AddRef(T* pObj) { pObj->AddRef(); } template< class T > static void Release(T* pObj) { pObj->Release(); } }; class CRefCountAccessorLongName { public: template< class T > static void AddRef(T* pObj) { pObj->AddReference(); } template< class T > static void Release(T* pObj) { pObj->ReleaseReference(); } }; template < typename T > class CPlainAutoPtr { public: explicit CPlainAutoPtr(T* p = NULL) : m_p(p) {} ~CPlainAutoPtr(void) { Delete(); } public: void Delete(void) { delete Detach(); } private: CPlainAutoPtr(CPlainAutoPtr const& x); CPlainAutoPtr& operator = (CPlainAutoPtr const& x); public: void Attach(T* p) { m_p = p; } T* Detach(void) { T* p(m_p); m_p = NULL; return p; } public: bool IsValid(void) const { return m_p != NULL; } T* Get(void) const { return m_p; } T* operator -> (void) const { return Get(); } T& operator * (void) const { return *Get(); } private: T* m_p; }; template < typename T > class CArrayAutoPtr : public CPlainAutoPtr < T > { public: explicit CArrayAutoPtr(T* p = NULL) { this->Attach(p); } ~CArrayAutoPtr(void) { this->Delete(); } public: void Delete(void) { delete[] CPlainAutoPtr < T >::Detach(); } public: T& operator [] (int k) const { return CPlainAutoPtr < T >::Get()[k]; } }; template class CSmartPtr { public: CSmartPtr(); CSmartPtr(T* pObj); CSmartPtr(const CSmartPtr& other); ~CSmartPtr(); T* operator=(T* pObj); void operator=(const CSmartPtr& other); const T* operator->() const; T* operator->(); bool operator!() const; bool operator==(const T* pOther) const; bool IsValid() const; T* GetObject() const; void MarkDeleted(); private: T* m_pObj; }; template< class T, class RefCountAccessor > inline CSmartPtr::CSmartPtr() { m_pObj = NULL; } template< class T, class RefCountAccessor > inline CSmartPtr::CSmartPtr(T* pObj) { m_pObj = NULL; *this = pObj; } template< class T, class RefCountAccessor > inline CSmartPtr::CSmartPtr(const CSmartPtr& other) { m_pObj = NULL; *this = other; } template< class T, class RefCountAccessor > inline CSmartPtr::~CSmartPtr() { if (m_pObj) { RefCountAccessor::Release(m_pObj); } } template< class T, class RefCountAccessor > inline T* CSmartPtr::operator=(T* pObj) { if (pObj == m_pObj) return pObj; if (pObj) { RefCountAccessor::AddRef(pObj); } if (m_pObj) { RefCountAccessor::Release(m_pObj); } m_pObj = pObj; return pObj; } template< class T, class RefCountAccessor > inline void CSmartPtr::MarkDeleted() { m_pObj = NULL; } template< class T, class RefCountAccessor > inline void CSmartPtr::operator=(const CSmartPtr& other) { *this = other.m_pObj; } template< class T, class RefCountAccessor > inline const T* CSmartPtr::operator->() const { return m_pObj; } template< class T, class RefCountAccessor > inline T* CSmartPtr::operator->() { return m_pObj; } template< class T, class RefCountAccessor > inline bool CSmartPtr::operator!() const { return !m_pObj; } template< class T, class RefCountAccessor > inline bool CSmartPtr::operator==(const T* pOther) const { return m_pObj == pOther; } template< class T, class RefCountAccessor > inline bool CSmartPtr::IsValid() const { return m_pObj != NULL; } template< class T, class RefCountAccessor > inline T* CSmartPtr::GetObject() const { return m_pObj; } template < typename T > class CAutoPushPop { public: explicit CAutoPushPop(T& var) : m_rVar(var), m_valPop(var) {} CAutoPushPop(T& var, T const& valPush) : m_rVar(var), m_valPop(var) { m_rVar = valPush; } CAutoPushPop(T& var, T const& valPush, T const& valPop) : m_rVar(var), m_valPop(var) { m_rVar = valPush; } ~CAutoPushPop() { m_rVar = m_valPop; } private: CAutoPushPop(CAutoPushPop const& x); CAutoPushPop& operator = (CAutoPushPop const& x); public: T& Get() { return m_rVar; } private: T& m_rVar; T m_valPop; }; #endif