/* * SharedPtr.h * * Copyright (C) 2008 Johannes Thorn * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef MAD_COMMON_SHAREDPTR_H_ #define MAD_COMMON_SHAREDPTR_H_ namespace Mad { namespace Common { template class SharedPtr { protected: class Counter { public: Counter(T *o) : object(o), refCount(1), cCount(new unsigned int(1)) {} Counter(T *o, unsigned int *count) : object(o), refCount(1), cCount(count) {++*cCount;} virtual ~Counter() { if(--cCount) return; if(object) delete object; delete cCount; } T *object; unsigned int refCount; unsigned int *cCount; }; Counter *counter; template class CastPtr : public SharedPtr { public: CastPtr(T *o, unsigned int *cCount) : SharedPtr(o, cCount) {} }; SharedPtr(T *o, unsigned int *cCount) : counter(new Counter(o, cCount)) {} public: SharedPtr(T *o = 0) : counter(new Counter(o)) {} SharedPtr(const SharedPtr &c) : counter(c.counter) { ++counter->refCount; } virtual ~SharedPtr() { if(--counter->refCount == 0) delete counter; } SharedPtr& operator=(const SharedPtr& c) { ++c.counter->refCount; if(--counter->refCount == 0) delete counter; counter = c.counter; return *this; } bool empty() const { return counter->object; } T* operator->() {return counter->object;} T& operator*() {return *counter->object;} const T* operator->() const {return counter->object;} const T& operator*() const {return *counter->object;} bool operator<(const SharedPtr &o) const {return counter->object < o.counter->object;} bool operator==(const SharedPtr &o) const {return counter->object == o.counter->object;} template SharedPtr cast() const { return CastPtr(counter->object, counter->cCount); } }; } } #endif /*MAD_COMMON_SHAREDPTR_H_*/