#ifndef SHARED_REF_H_ #define SHARED_REF_H_ template class SharedRef { private: template class Share { public: Share(CP1 cp1) : Count(1), Payload(cp1) { } unsigned int Count; T Payload; }; public: SharedRef(P1 p1) : Link(new Share(p1)) { } SharedRef(const SharedRef& anOther) : Link(anOther.Link) { ++Link->Count; } ~SharedRef() { unref(); } SharedRef& operator=(const SharedRef& anOther) { unref(); Link = anOther.Link; ++Link->Count; return *this; } T* operator->() { return &Link->Payload; } const T* operator->() const { return &Link->Payload; } private: void unref() { --Link->Count; if (!Link->Count) delete Link; } Share* Link; }; class SharedPtrShare { public: SharedPtrShare(void* ct) : Count(1), Payload(ct) { } unsigned int Count; void* Payload; }; template class SharedPtr { private: public: SharedPtr() : Link(0) { } SharedPtr(T* t) : Link(0) { if (t) Link = new SharedPtrShare(t); } SharedPtr(const SharedPtr& anOther) : Link(anOther.Link) { if (Link) ++Link->Count; } SharedPtr(SharedPtrShare* aLink) : Link(aLink) { if (Link) ++Link->Count; } ~SharedPtr() { unref(); } SharedPtr& operator=(const SharedPtr& anOther) { // Guard against unreffing in case of self-assignment SharedPtr Guard(anOther); unref(); Link = anOther.Link; if (Link) ++Link->Count; return *this; } T* operator->() { return static_cast(Link->Payload); } const T* operator->() const { return static_cast(Link->Payload); } bool isNull() const { return !Link || !Link->Payload; } const T& cref() const { return *(static_cast(Link->Payload)); } template SharedPtr validCast() { if (Link) { V* v = static_cast(Link->Payload); v=v; return SharedPtr(Link); } return SharedPtr(); } template SharedPtr dynamicCast() { if (Link && dynamic_cast(static_cast(Link->Payload))) return SharedPtr(Link); return SharedPtr(); } private: void unref() { if (!Link) return; --Link->Count; if (!Link->Count) { T* t = static_cast(Link->Payload); delete t; delete Link; Link = 0; } } SharedPtrShare* Link; }; #endif