#ifndef __GEL_OBJPTR_H #define __GEL_OBJPTR_H namespace Obj { class CRefCounted; /* -Self assignment -http://web.ftech.net/~honeyg/articles/smartp.htm */ template class CSmtPtr { friend class CRefCounted; public: CSmtPtr(); CSmtPtr(T* pT); CSmtPtr(CSmtPtr &ref); ~CSmtPtr(); CSmtPtr & operator=(T* pT); CSmtPtr & operator=(CSmtPtr &ref); T * operator->() const; T & operator*() const; T ** operator&() const; bool operator!() const {return (mp_object == NULL);} operator T*() const {return mp_object;} friend bool operator==(const CSmtPtr& lhs, T* pRhs) {return lhs.mp_object == pRhs;} friend bool operator!=(const CSmtPtr& lhs, T* pRhs) {return lhs.mp_object != pRhs;} T * Convert() const {return mp_object;} void Kill() const; private: void add_ref(); void remove_ref(); T * mp_object; CSmtPtr * mp_prev_ptr; CSmtPtr * mp_next_ptr; }; template inline CSmtPtr::CSmtPtr() { mp_prev_ptr = NULL; mp_next_ptr = NULL; mp_object = NULL; } template inline CSmtPtr::CSmtPtr(T *pT) { mp_prev_ptr = NULL; mp_next_ptr = NULL; mp_object = pT; add_ref(); //printf("WWW in copy constructor for 0x%x\n", mp_object); } template inline CSmtPtr::CSmtPtr(CSmtPtr &ref) { mp_prev_ptr = NULL; mp_next_ptr = NULL; mp_object = ref.mp_object; add_ref(); //printf("WWW in copy constructor 2 for pointer at 0x%x, object 0x%x\n", this, mp_object); } template inline CSmtPtr::~CSmtPtr() { //printf("WWW in destructor for 0x%x\n", mp_object); remove_ref(); } template inline CSmtPtr & CSmtPtr::operator=(T *pT) { //printf("WWW in CSmtPtr::operator=(T *pT) for pointer at 0x%x, object 0x%x (old) and 0x%x (new)\n", this, mp_object, pT); remove_ref(); mp_object = pT; add_ref(); return *this; } template inline CSmtPtr & CSmtPtr::operator=(CSmtPtr &ref) { //printf("WWW in CSmtPtr::operator=(const CSmtPtr &ref) for pointer at 0x%x, object 0x%x (old) and 0x%x (new)\n", this, mp_object, ref.mp_object); remove_ref(); mp_object = ref.mp_object; add_ref(); return *this; } template inline T * CSmtPtr::operator->() const { Dbg_MsgAssert(mp_object, ("NULL smart pointer!")); return (T *) mp_object; } template inline T & CSmtPtr::operator*() const { Dbg_MsgAssert(mp_object, ("NULL smart pointer!")); return *((T *) mp_object); } template inline T ** CSmtPtr::operator&() const { Dbg_MsgAssert(0, ("operator& not supported, comrade!")); } template inline void CSmtPtr::Kill() const { Dbg_MsgAssert(mp_object, ("attempting delete with NULL smart pointer!")); // this will lead to remove_ref() being called on this delete mp_object; } template inline void CSmtPtr::add_ref() { if (mp_object) { //printf("WWW adding ref to 0x%x\n", mp_object); mp_object->AddSmartPointer((CSmtPtr *) this); } } template inline void CSmtPtr::remove_ref() { if (mp_object) { //printf("WWW removing ref from 0x%x\n", mp_object); mp_object->RemoveSmartPointer((CSmtPtr *) this); mp_object = NULL; } } } #endif