KUDr@3900: /* $Id$ */ KUDr@3900: KUDr@6308: /** @file countedptr.hpp */ KUDr@6308: KUDr@3900: #ifndef COUNTEDPTR_HPP KUDr@3900: #define COUNTEDPTR_HPP KUDr@3900: KUDr@6235: #if 1 // reenable when needed KUDr@3900: /** @file CCountedPtr - smart pointer implementation */ KUDr@3900: KUDr@3900: /** CCountedPtr - simple reference counting smart pointer. rubidium@4549: * rubidium@4549: * One of the standard ways how to maintain object's lifetime. rubidium@4549: * rubidium@4549: * See http://ootips.org/yonat/4dev/smart-pointers.html for more rubidium@4549: * general info about smart pointers. rubidium@4549: * rubidium@4549: * This class implements ref-counted pointer for objects/interfaces that rubidium@4549: * support AddRef() and Release() methods. rubidium@4549: */ KUDr@3900: template KUDr@3900: class CCountedPtr { KUDr@3900: /** redefine the template argument to make it visible for derived classes */ KUDr@3900: public: KUDr@3900: typedef Tcls_ Tcls; KUDr@3900: KUDr@3900: protected: KUDr@3900: /** here we hold our pointer to the target */ KUDr@3900: Tcls* m_pT; KUDr@3900: KUDr@3900: public: KUDr@3900: /** default (NULL) construct or construct from a raw pointer */ KUDr@3900: FORCEINLINE CCountedPtr(Tcls* pObj = NULL) : m_pT(pObj) {AddRef();}; KUDr@3900: KUDr@3900: /** copy constructor (invoked also when initializing from another smart ptr) */ KUDr@3900: FORCEINLINE CCountedPtr(const CCountedPtr& src) : m_pT(src.m_pT) {AddRef();}; KUDr@3900: KUDr@3900: /** destructor releasing the reference */ KUDr@3900: FORCEINLINE ~CCountedPtr() {Release();}; KUDr@3900: KUDr@3900: protected: KUDr@3900: /** add one ref to the underlaying object */ KUDr@3900: FORCEINLINE void AddRef() {if (m_pT != NULL) m_pT->AddRef();} KUDr@3900: KUDr@3900: public: KUDr@3900: /** release smart pointer (and decrement ref count) if not null */ KUDr@3900: FORCEINLINE void Release() {if (m_pT != NULL) {m_pT->Release(); m_pT = NULL;}} KUDr@3900: KUDr@3900: /** dereference of smart pointer - const way */ KUDr@3900: FORCEINLINE const Tcls* operator -> () const {assert(m_pT != NULL); return m_pT;}; KUDr@3900: KUDr@3900: /** dereference of smart pointer - non const way */ KUDr@3900: FORCEINLINE Tcls* operator -> () {assert(m_pT != NULL); return m_pT;}; KUDr@3900: KUDr@3900: /** raw pointer casting operator - const way */ KUDr@3900: FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;} KUDr@3900: KUDr@3900: /** raw pointer casting operator - non-const way */ KUDr@6235: FORCEINLINE operator Tcls*() {return m_pT;} KUDr@3900: KUDr@3900: /** operator & to support output arguments */ KUDr@3900: FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;} KUDr@3900: KUDr@3900: /** assignment operator from raw ptr */ KUDr@3900: FORCEINLINE CCountedPtr& operator = (Tcls* pT) {Assign(pT); return *this;} KUDr@3900: KUDr@3900: /** assignment operator from another smart ptr */ KUDr@6296: FORCEINLINE CCountedPtr& operator = (const CCountedPtr& src) {Assign(src.m_pT); return *this;} KUDr@3900: KUDr@3900: /** assignment operator helper */ KUDr@3900: FORCEINLINE void Assign(Tcls* pT); KUDr@3900: KUDr@3900: /** one way how to test for NULL value */ KUDr@3900: FORCEINLINE bool IsNull() const {return m_pT == NULL;} KUDr@3900: KUDr@3900: /** another way how to test for NULL value */ KUDr@6235: //FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;} KUDr@3900: KUDr@3900: /** yet another way how to test for NULL value */ KUDr@6235: //FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;} KUDr@3900: KUDr@3900: /** assign pointer w/o incrementing ref count */ KUDr@3900: FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;} KUDr@3900: KUDr@3900: /** detach pointer w/o decrementing ref count */ KUDr@3900: FORCEINLINE Tcls* Detach() {Tcls* pT = m_pT; m_pT = NULL; return pT;} KUDr@3900: }; KUDr@3900: KUDr@3900: template KUDr@3900: FORCEINLINE void CCountedPtr::Assign(Tcls* pT) KUDr@3900: { KUDr@3900: // if they are the same, we do nothing KUDr@3900: if (pT != m_pT) { KUDr@3900: if (pT) pT->AddRef(); // AddRef new pointer if any KUDr@3900: Tcls* pTold = m_pT; // save original ptr KUDr@3900: m_pT = pT; // update m_pT to new value KUDr@3900: if (pTold) pTold->Release(); // release old ptr if any KUDr@3900: } KUDr@3900: } KUDr@3900: KUDr@6269: /** KUDr@6269: * Adapter wrapper for CCountedPtr like classes that can't be used directly by stl KUDr@6269: * collections as item type. For example CCountedPtr has overloaded operator & which KUDr@6269: * prevents using CCountedPtr in stl collections (i.e. std::list >) KUDr@6269: */ KUDr@6269: template struct AdaptT { KUDr@6269: T m_t; KUDr@6269: KUDr@6269: /** construct by wrapping the given object */ KUDr@6269: AdaptT(const T &t) KUDr@6269: : m_t(t) KUDr@6269: {} KUDr@6269: KUDr@6269: /** assignment operator */ KUDr@6269: T& operator = (const T &t) KUDr@6269: { KUDr@6269: m_t = t; KUDr@6269: return t; KUDr@6269: } KUDr@6269: KUDr@6269: /** type-cast operator (used when AdaptT is used instead of T) */ KUDr@6269: operator T& () KUDr@6269: { KUDr@6269: return m_t; KUDr@6269: } KUDr@6269: KUDr@6269: /** const type-cast operator (used when AdaptT is used instead of const T) */ KUDr@6269: operator const T& () const KUDr@6269: { KUDr@6269: return m_t; KUDr@6269: } KUDr@6269: }; KUDr@6269: KUDr@6269: KUDr@6256: /** Simple counted object. Use it as base of your struct/class if you want to use KUDr@6256: * basic reference counting. Your struct/class will destroy and free itself when KUDr@6256: * last reference to it is released (using Relese() method). The initial reference KUDr@6256: * count (when it is created) is zero (don't forget AddRef() at least one time if KUDr@6256: * not using CCountedPtr. KUDr@6256: * KUDr@6256: * @see misc/countedobj.cpp for implementation. KUDr@6256: */ KUDr@6256: struct SimpleCountedObject { KUDr@6256: int32 m_ref_cnt; KUDr@6256: KUDr@6256: SimpleCountedObject() KUDr@6256: : m_ref_cnt(0) KUDr@6256: {} KUDr@6256: KUDr@6256: virtual ~SimpleCountedObject() KUDr@6256: {}; KUDr@6256: KUDr@6256: virtual int32 AddRef(); KUDr@6256: virtual int32 Release(); KUDr@6256: virtual void FinalRelease() {}; KUDr@6256: }; KUDr@6256: KUDr@6256: KUDr@6256: KUDr@6256: Darkvater@5094: #endif /* 0 */ KUDr@3900: #endif /* COUNTEDPTR_HPP */