#ifndef BLUECORE_REFERENCED_COUNTER_H #define BLUECORE_REFERENCED_COUNTER_H #include namespace BlueCore { class Referenced { public: class DestructionListener { public: virtual void onDestruction(Referenced *referenced) = 0; }; private: std::list _DestructionListeners; unsigned int _ReferenceCount; virtual void destroyReferenced() { while (_DestructionListeners.begin() != _DestructionListeners.end()) { if (_DestructionListeners.front() != 0) _DestructionListeners.front()->onDestruction(this); _DestructionListeners.pop_front(); } delete this; } public: inline Referenced() : _ReferenceCount(0) { } virtual inline ~Referenced() { } inline void addReference() { _ReferenceCount += 1; } inline void removeReference() { if (_ReferenceCount > 0) { _ReferenceCount -= 1; if ( 0 == _ReferenceCount) { destroyReferenced(); } } } inline unsigned int getReferenceCount() { return _ReferenceCount; } inline void addDestructionListener(DestructionListener *listener) { if (listener != 0) _DestructionListeners.push_back(listener); } inline void removeDestructionListener(DestructionListener *listener) { _DestructionListeners.remove(listener); } }; template class ref_ptr { public: ref_ptr() : _Referenced(0) { } ref_ptr(T* referenced) : _Referenced(referenced) { if (_Referenced) _Referenced->addReference(); } ref_ptr(const ref_ptr& op) : _Referenced(op._Referenced) { if (_Referenced) _Referenced->addReference(); } ~ref_ptr() { if (_Referenced) _Referenced->removeReference(); } T* operator ->() const { return _Referenced; } ref_ptr& operator =(T* op) { if (op != _Referenced) { if (_Referenced != 0) _Referenced->removeReference(); _Referenced = op; if (_Referenced) _Referenced->addReference(); } return *this; } bool operator ==(const ref_ptr& ref) { if (_Referenced == ref._Referenced) return true; else return false; } bool operator == (T* ref) { if (_Referenced == ref) return true; else return false; } bool valid() const { return (_Referenced != 0); } operator T*() const { return _Referenced; } T* pointer() const { return _Referenced; } private: T* _Referenced; }; template class weak_ptr : public Referenced::DestructionListener { public: weak_ptr() : _Referenced(0) { } weak_ptr(T* referenced) : _Referenced(referenced) { if (_Referenced) _Referenced->addDestructionListener(this); } weak_ptr(const weak_ptr& op) : _Referenced(op._Referenced) { if (_Referenced) _Referenced->addDestructionListener(this); } virtual ~weak_ptr() { if (_Referenced) _Referenced->removeDestructionListener(this); } T* operator ->() const { return _Referenced; } weak_ptr& operator =(T* op) { if (op != _Referenced && _Referenced != 0) _Referenced->removeDestructionListener(this); _Referenced = op; _Referenced->addDestructionListener(this); return *this; } bool operator ==(const weak_ptr& ref) { if (_Referenced == ref._Referenced) return true; else return false; } bool valid() const { return (_Referenced != 0); } T* pointer() const { return _Referenced; } operator T*() const { return _Referenced; } void onDestruction(Referenced *referenced) { _Referenced = 0; } private: T* _Referenced; }; } // namespace BlueCore #endif