// -*- c++ -*- #pragma once #ifndef __XOT_REF_H__ #define __XOT_REF_H__ #include #include #include #include #include //#define XOT_REF_DEBUG 1 namespace Xot { class EmptyClass {}; template class RefCountable : public SuperClass { public: virtual void retain () { reference(+1); #ifdef XOT_REF_DEBUG doutln( "%s: %d -> %d", typeid(this).name(), count() - 1, count()); #endif } virtual void release () { assert(count() >= 0); bool del = !retained() || reference(-1) == 0; #ifdef XOT_REF_DEBUG doutln( "%s: %d -> %d, refcount:%s, delete:%s", typeid(this).name(), count() + 1, count(), retained() ? "yes" : "no", del ? "yes" : "no"); #endif if (del) delete this; } protected: RefCountable () : refcount(0) { } virtual ~RefCountable () { } private: int refcount; bool retained () const { return refcount & 0x1; } int count () const { return refcount >> 1; } int reference (int add) { assert(add != 0); int c = count() + add; refcount = c << 1 | 0x1;// bit for retained flag. return c; } RefCountable (const RefCountable&); RefCountable& operator = (const RefCountable&); };// RefCountable template class Ref { typedef Ref This; public: Ref (T* ptr = NULL) : ptr(ptr) { if (ptr) ptr->retain(); } Ref (const This& obj) : ptr(obj.ptr) { if (ptr) ptr->retain(); } Ref& operator = (T* ptr) { reset(ptr); return *this; } Ref& operator = (const This& obj) { if (&obj == this) return *this; reset(obj.ptr); return *this; } ~Ref () { if (ptr) ptr->release(); } void reset (T* ptr = NULL) { if (this->ptr == ptr) return; if (this->ptr) this->ptr->release(); this->ptr = ptr; if (this->ptr) this->ptr->retain(); } T* get () {return ptr;} const T* get () const {return ptr;} T* operator -> () {return get();} const T* operator -> () const {return get();} T& operator * () {return *get();} const T& operator * () const {return *get();} operator T* () {return get();} operator const T* () const {return get();} bool operator == (T* ptr) const {return this->ptr == ptr;} bool operator != (T* ptr) const {return !operator==(ptr);} bool operator == (const T* ptr) const {return this->ptr == ptr;} bool operator != (const T* ptr) const {return !operator==(ptr);} bool operator == (const This& obj) const {return ptr == obj.ptr;} bool operator != (const This& obj) const {return !operator==(obj);} operator bool () const {return ptr != NULL;} bool operator ! () const {return !operator bool();} private: T* ptr; };// Ref }// Xot #endif//EOH