KUDr@5633: /* $Id$ */ KUDr@5633: belugas@6481: /** @file countedptr.hpp */ belugas@6481: KUDr@5633: #ifndef COUNTEDPTR_HPP KUDr@5633: #define COUNTEDPTR_HPP KUDr@5633: KUDr@5633: #if 0 // reenable when needed KUDr@5633: /** @file CCountedPtr - smart pointer implementation */ KUDr@5633: KUDr@5633: /** CCountedPtr - simple reference counting smart pointer. KUDr@5633: * KUDr@5633: * One of the standard ways how to maintain object's lifetime. KUDr@5633: * KUDr@5633: * See http://ootips.org/yonat/4dev/smart-pointers.html for more KUDr@5633: * general info about smart pointers. KUDr@5633: * KUDr@5633: * This class implements ref-counted pointer for objects/interfaces that KUDr@5633: * support AddRef() and Release() methods. KUDr@5633: */ KUDr@5633: template KUDr@5633: class CCountedPtr { KUDr@5633: /** redefine the template argument to make it visible for derived classes */ KUDr@5633: public: KUDr@5633: typedef Tcls_ Tcls; KUDr@5633: KUDr@5633: protected: KUDr@5633: /** here we hold our pointer to the target */ KUDr@5633: Tcls* m_pT; KUDr@5633: KUDr@5633: public: KUDr@5633: /** default (NULL) construct or construct from a raw pointer */ KUDr@5633: FORCEINLINE CCountedPtr(Tcls* pObj = NULL) : m_pT(pObj) {AddRef();}; KUDr@5633: KUDr@5633: /** copy constructor (invoked also when initializing from another smart ptr) */ KUDr@5633: FORCEINLINE CCountedPtr(const CCountedPtr& src) : m_pT(src.m_pT) {AddRef();}; KUDr@5633: KUDr@5633: /** destructor releasing the reference */ KUDr@5633: FORCEINLINE ~CCountedPtr() {Release();}; KUDr@5633: KUDr@5633: protected: KUDr@5633: /** add one ref to the underlaying object */ KUDr@5633: FORCEINLINE void AddRef() {if (m_pT != NULL) m_pT->AddRef();} KUDr@5633: KUDr@5633: public: KUDr@5633: /** release smart pointer (and decrement ref count) if not null */ KUDr@5633: FORCEINLINE void Release() {if (m_pT != NULL) {m_pT->Release(); m_pT = NULL;}} KUDr@5633: KUDr@5633: /** dereference of smart pointer - const way */ KUDr@5633: FORCEINLINE const Tcls* operator -> () const {assert(m_pT != NULL); return m_pT;}; KUDr@5633: KUDr@5633: /** dereference of smart pointer - non const way */ KUDr@5633: FORCEINLINE Tcls* operator -> () {assert(m_pT != NULL); return m_pT;}; KUDr@5633: KUDr@5633: /** raw pointer casting operator - const way */ KUDr@5633: FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;} KUDr@5633: KUDr@5633: /** raw pointer casting operator - non-const way */ KUDr@5633: FORCEINLINE operator Tcls*() {assert(m_pT == NULL); return m_pT;} KUDr@5633: KUDr@5633: /** operator & to support output arguments */ KUDr@5633: FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;} KUDr@5633: KUDr@5633: /** assignment operator from raw ptr */ KUDr@5633: FORCEINLINE CCountedPtr& operator = (Tcls* pT) {Assign(pT); return *this;} KUDr@5633: KUDr@5633: /** assignment operator from another smart ptr */ KUDr@5633: FORCEINLINE CCountedPtr& operator = (CCountedPtr& src) {Assign(src.m_pT); return *this;} KUDr@5633: KUDr@5633: /** assignment operator helper */ KUDr@5633: FORCEINLINE void Assign(Tcls* pT); KUDr@5633: KUDr@5633: /** one way how to test for NULL value */ KUDr@5633: FORCEINLINE bool IsNull() const {return m_pT == NULL;} KUDr@5633: KUDr@5633: /** another way how to test for NULL value */ KUDr@5633: FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;} KUDr@5633: KUDr@5633: /** yet another way how to test for NULL value */ KUDr@5633: FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;} KUDr@5633: KUDr@5633: /** assign pointer w/o incrementing ref count */ KUDr@5633: FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;} KUDr@5633: KUDr@5633: /** detach pointer w/o decrementing ref count */ KUDr@5633: FORCEINLINE Tcls* Detach() {Tcls* pT = m_pT; m_pT = NULL; return pT;} KUDr@5633: }; KUDr@5633: KUDr@5633: template KUDr@5633: FORCEINLINE void CCountedPtr::Assign(Tcls* pT) KUDr@5633: { KUDr@5633: // if they are the same, we do nothing KUDr@5633: if (pT != m_pT) { KUDr@5633: if (pT) pT->AddRef(); // AddRef new pointer if any KUDr@5633: Tcls* pTold = m_pT; // save original ptr KUDr@5633: m_pT = pT; // update m_pT to new value KUDr@5633: if (pTold) pTold->Release(); // release old ptr if any KUDr@5633: } KUDr@5633: } KUDr@5633: KUDr@5633: #endif /* 0 */ KUDr@5633: #endif /* COUNTEDPTR_HPP */