// This file may be redistributed and modified only under the terms of // the GNU Lesser General Public License (See COPYING for details). // Copyright (C) 2000 Aloril // Copyright (C) 2000-2005 Al Riddoch #ifndef ATLAS_OBJECTS_SMARTPTR_H #define ATLAS_OBJECTS_SMARTPTR_H #include namespace Atlas { namespace Objects { class NullSmartPtrDereference : public Atlas::Exception { public: NullSmartPtrDereference() : Atlas::Exception("Null SmartPtr dereferenced") {} virtual ~NullSmartPtrDereference() throw (); }; template class SmartPtr { public: typedef T DataT; typedef typename T::iterator iterator; typedef typename T::const_iterator const_iterator; SmartPtr() : ptr(T::alloc()) { } SmartPtr(const SmartPtr& a) : ptr(a.get()) { incRef(); } SmartPtr(T *a_ptr) : ptr(a_ptr) { incRef(); } template explicit SmartPtr(const SmartPtr& a) : ptr(a.get()) { } ~SmartPtr() { decRef(); } SmartPtr& operator=(const SmartPtr& a) { if (a.get() != this->get()) { decRef(); ptr = a.get(); incRef(); } return *this; } template operator SmartPtr() const { return SmartPtr(ptr); } template operator SmartPtr() const { return SmartPtr(ptr); } bool isValid() const { return ptr != 0; } T& operator*() const { if (ptr == 0) { throw NullSmartPtrDereference(); } return *ptr; } T* operator->() const { if (ptr == 0) { throw NullSmartPtrDereference(); } return ptr; } T* get() const { return ptr; } SmartPtr copy() const { SmartPtr ret = SmartPtr(ptr->copy()); ret.decRef(); return ret; } SmartPtr getDefaultObject() const { return SmartPtr(ptr->getDefaultObject()); } // If you want to make these protected, please ensure that the // detructor is made virtual to ensure your new class bahaves // correctly. private: void decRef() const { if (ptr != 0) { ptr->decRef(); } } void incRef() const { if (ptr != 0) { ptr->incRef(); } } T * ptr; }; template returnPtrType smart_dynamic_cast(const SmartPtr & o) { return returnPtrType(dynamic_cast(o.get())); } template returnPtrType smart_static_cast(const SmartPtr & o) { return returnPtrType((typename returnPtrType::DataT *)o.get()); } } } // namespace Atlas::Objects #endif // ATLAS_OBJECTS_SMARTPTR_H