1 // This file may be redistributed and modified only under the terms of 2 // the GNU Lesser General Public License (See COPYING for details). 3 // Copyright (C) 2000 Aloril 4 // Copyright (C) 2000-2005 Al Riddoch 5 6 // $Id$ 7 8 #ifndef ATLAS_OBJECTS_SMARTPTR_H 9 #define ATLAS_OBJECTS_SMARTPTR_H 10 11 #include <Atlas/Exception.h> 12 13 namespace Atlas { namespace Objects { 14 15 class NullSmartPtrDereference : public Atlas::Exception 16 { 17 public: NullSmartPtrDereference()18 NullSmartPtrDereference() : Atlas::Exception("Null SmartPtr dereferenced") {} 19 virtual ~NullSmartPtrDereference(); 20 }; 21 22 template <class T> 23 class SmartPtr 24 { 25 public: 26 typedef T DataT; 27 28 typedef typename T::iterator iterator; 29 typedef typename T::const_iterator const_iterator; 30 SmartPtr()31 SmartPtr() : ptr(T::alloc()) { 32 } SmartPtr(const SmartPtr<T> & a)33 SmartPtr(const SmartPtr<T>& a) : ptr(a.get()) { 34 incRef(); 35 } SmartPtr(T * a_ptr)36 SmartPtr(T *a_ptr) : ptr(a_ptr) 37 { 38 incRef(); 39 } 40 template<class oldType> SmartPtr(const SmartPtr<oldType> & a)41 explicit SmartPtr(const SmartPtr<oldType>& a) : ptr(a.get()) { 42 } ~SmartPtr()43 ~SmartPtr() { 44 decRef(); 45 } 46 SmartPtr& operator=(const SmartPtr<T>& a) { 47 if (a.get() != this->get()) { 48 decRef(); 49 ptr = a.get(); 50 incRef(); 51 } 52 return *this; 53 } 54 template<class newType> 55 operator SmartPtr<newType>() const { 56 return SmartPtr<newType>(ptr); 57 } 58 template<class newType> 59 operator SmartPtr<const newType>() const { 60 return SmartPtr<const newType>(ptr); 61 } isValid()62 bool isValid() const { 63 return ptr != 0; 64 } 65 T& operator*() const { 66 if (ptr == 0) { 67 throw NullSmartPtrDereference(); 68 } 69 return *ptr; 70 } 71 T* operator->() const { 72 if (ptr == 0) { 73 throw NullSmartPtrDereference(); 74 } 75 return ptr; 76 } get()77 T* get() const { 78 return ptr; 79 } copy()80 SmartPtr<T> copy() const 81 { 82 SmartPtr<T> ret = SmartPtr(ptr->copy()); 83 ret.decRef(); 84 return ret; 85 } getDefaultObject()86 SmartPtr<T> getDefaultObject() const 87 { 88 return SmartPtr(ptr->getDefaultObject()); 89 } 90 // If you want to make these protected, please ensure that the 91 // detructor is made virtual to ensure your new class bahaves 92 // correctly. 93 private: decRef()94 void decRef() const { 95 if (ptr != 0) { 96 ptr->decRef(); 97 } 98 } incRef()99 void incRef() const { 100 if (ptr != 0) { 101 ptr->incRef(); 102 } 103 } 104 T * ptr; 105 }; 106 107 template<typename returnPtrType, class fromType> smart_dynamic_cast(const SmartPtr<fromType> & o)108returnPtrType smart_dynamic_cast(const SmartPtr<fromType> & o) 109 { 110 return returnPtrType(dynamic_cast<typename returnPtrType::DataT*>(o.get())); 111 } 112 113 template<typename returnPtrType, class fromType> smart_static_cast(const SmartPtr<fromType> & o)114returnPtrType smart_static_cast(const SmartPtr<fromType> & o) 115 { 116 return returnPtrType((typename returnPtrType::DataT *)o.get()); 117 } 118 119 } } // namespace Atlas::Objects 120 121 #endif // ATLAS_OBJECTS_SMARTPTR_H 122