X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/d63d2c3c6cbbd574dda4f8b00ebe6c661735edd5..cbfa5ce869fed89e2ac9d2ec762ca6210317add2:/lib/base/smartptr.h diff --git a/lib/base/smartptr.h b/lib/base/smartptr.h index 029fd1dc..be83528f 100644 --- a/lib/base/smartptr.h +++ b/lib/base/smartptr.h @@ -3,12 +3,28 @@ #include "object.h" #include +#include +#include + +inline void ptrAssert(void *p) { if (!p) *(unsigned long*)0=0; } template class ePtr { protected: T *ptr; + char m_ptrStr[sizeof(void*)*2+1]; + void updatePtrStr() + { + if (ptr) { + if (sizeof(void*) > 4) + sprintf(m_ptrStr, "%llx", (unsigned long long)ptr); + else + sprintf(m_ptrStr, "%lx", (unsigned long)ptr); + } + else + strcpy(m_ptrStr, "NIL"); + } public: T &operator*() { return *ptr; } ePtr(): ptr(0) @@ -18,43 +34,172 @@ public: { if (c) c->AddRef(); + updatePtrStr(); } - ePtr(const ePtr &c) + ePtr(const ePtr &c): ptr(c.ptr) { - ptr=c.ptr; if (ptr) ptr->AddRef(); + updatePtrStr(); } ePtr &operator=(T *c) { + if (c) + c->AddRef(); if (ptr) ptr->Release(); ptr=c; - if (ptr) - ptr->AddRef(); + updatePtrStr(); return *this; } - ePtr &operator=(ePtr &c) + { + if (c.ptr) + c.ptr->AddRef(); + if (ptr) + ptr->Release(); + ptr=c.ptr; + updatePtrStr(); + return *this; + } + ~ePtr() { if (ptr) ptr->Release(); + } + char *getPtrString() + { + return m_ptrStr; + } +#ifndef SWIG + T* grabRef() { if (!ptr) return 0; ptr->AddRef(); return ptr; } + T* &ptrref() { ASSERT(!ptr); return ptr; } + operator bool() const { return !!this->ptr; } +#endif + T* operator->() const { ptrAssert(ptr); return ptr; } + operator T*() const { return this->ptr; } +}; + + +template +class eUsePtr +{ +protected: + T *ptr; +public: + T &operator*() { return *ptr; } + eUsePtr(): ptr(0) + { + } + eUsePtr(T *c): ptr(c) + { + if (c) + { + c->AddRef(); + c->AddUse(); + } + } + eUsePtr(const eUsePtr &c) + { ptr=c.ptr; if (ptr) + { ptr->AddRef(); + ptr->AddUse(); + } + } + eUsePtr &operator=(T *c) + { + if (c) + { + c->AddRef(); + c->AddUse(); + } + if (ptr) + { + ptr->ReleaseUse(); + ptr->Release(); + } + ptr=c; return *this; } - - ~ePtr() + eUsePtr &operator=(eUsePtr &c) { + if (c.ptr) + { + c.ptr->AddRef(); + c.ptr->AddUse(); + } if (ptr) + { + ptr->ReleaseUse(); ptr->Release(); + } + ptr=c.ptr; + return *this; } - T* &ptrref() { assert(!ptr); return ptr; } - T* operator->() { assert(ptr); return ptr; } - const T* operator->() const { assert(ptr); return ptr; } + ~eUsePtr() + { + if (ptr) + { + ptr->ReleaseUse(); + ptr->Release(); + } + } +#ifndef SWIG + T* grabRef() { if (!ptr) return 0; ptr->AddRef(); ptr->AddUse(); return ptr; } + T* &ptrref() { ASSERT(!ptr); return ptr; } +#endif + T* operator->() const { ptrAssert(ptr); return ptr; } operator T*() const { return this->ptr; } }; + +#ifndef SWIG +template +class eMutablePtr: public ePtr +{ + /* read doc/iObject about the ePtrHelper */ + template + class ePtrHelper + { + T1 *m_obj; + public: + inline ePtrHelper(T1 *obj): m_obj(obj) + { + m_obj->AddRef(); + } + inline ~ePtrHelper() + { + m_obj->Release(); + } + inline T1* operator->() { return m_obj; } + }; +protected: + T *ptr; +public: + eMutablePtr(): ePtr(0) + { + } + eMutablePtr(T *c): ePtr(c) + { + } + eMutablePtr(const eMutablePtr &c): ePtr(c) + { + } + eMutablePtr &operator=(T *c) + { + ePtr::operator=(c); + return *this; + } + ePtrHelper operator->() { ptrAssert(ptr); return ePtrHelper(ptr); } + /* for const objects, we don't need the helper, as they can't */ + /* be changed outside the program flow. at least this is */ + /* what the compiler assumes, so in case you're using const */ + /* eMutablePtrs note that they have to be const. */ + const T* operator->() const { ptrAssert(ptr); return ptr; } +}; +#endif + #endif