SmartPtr.h

00001 // This file may be redistributed and modified only under the terms of
00002 // the GNU Lesser General Public License (See COPYING for details).
00003 // Copyright (C) 2000 Aloril
00004 // Copyright (C) 2000-2005 Al Riddoch
00005 
00006 #ifndef ATLAS_OBJECTS_SMARTPTR_H
00007 #define ATLAS_OBJECTS_SMARTPTR_H
00008 
00009 #include <Atlas/Exception.h>
00010 
00011 namespace Atlas { namespace Objects {
00012 
00013 class NullSmartPtrDereference : public Atlas::Exception
00014 {
00015   public:
00016     NullSmartPtrDereference() : Atlas::Exception("Null SmartPtr dereferenced") {}
00017     virtual ~NullSmartPtrDereference() throw ();
00018 };
00019 
00020 template <class T> 
00021 class SmartPtr
00022 {
00023   public:
00024     typedef T DataT;
00025 
00026     typedef typename T::iterator iterator;
00027     typedef typename T::const_iterator const_iterator;
00028 
00029     SmartPtr() : ptr(T::alloc()) { 
00030     }
00031     SmartPtr(const SmartPtr<T>& a) : ptr(a.get()) {
00032         incRef();
00033     }
00034     SmartPtr(T *a_ptr) : ptr(a_ptr)
00035     {
00036         incRef();
00037     }
00038     template<class oldType>
00039     explicit SmartPtr(const SmartPtr<oldType>& a) : ptr(a.get()) {
00040     }
00041     ~SmartPtr() { 
00042         decRef();
00043     }
00044     SmartPtr& operator=(const SmartPtr<T>& a) {
00045         if (a.get() != this->get()) {
00046             decRef();
00047             ptr = a.get();
00048             incRef();
00049         }
00050         return *this;
00051     }
00052     template<class newType>
00053     operator SmartPtr<newType>() const {
00054         return SmartPtr<newType>(ptr);
00055     }
00056     template<class newType>
00057     operator SmartPtr<const newType>() const {
00058         return SmartPtr<const newType>(ptr);
00059     }
00060     bool isValid() const {
00061         return ptr != 0;
00062     }
00063     T& operator*() const { 
00064         if (ptr == 0) {
00065             throw NullSmartPtrDereference();
00066         }
00067         return *ptr;
00068     }
00069     T* operator->() const {
00070         if (ptr == 0) {
00071             throw NullSmartPtrDereference();
00072         }
00073         return ptr;
00074     }
00075     T* get() const {
00076         return ptr;
00077     }
00078     SmartPtr<T> copy() const
00079     {
00080         SmartPtr<T> ret = SmartPtr(ptr->copy());
00081         ret.decRef();
00082         return ret;
00083     }
00084     SmartPtr<T> getDefaultObject() const
00085     {
00086         return SmartPtr(ptr->getDefaultObject());
00087     }
00088     // If you want to make these protected, please ensure that the
00089     // detructor is made virtual to ensure your new class bahaves
00090     // correctly.
00091   private:
00092     void decRef() const {
00093         if (ptr != 0) {
00094             ptr->decRef();
00095         }
00096     }
00097     void incRef() const {
00098         if (ptr != 0) {
00099             ptr->incRef();
00100         }
00101     }
00102     T * ptr;
00103 };
00104 
00105 template<typename returnPtrType, class fromType>
00106 returnPtrType smart_dynamic_cast(const SmartPtr<fromType> & o)
00107 {
00108     return returnPtrType(dynamic_cast<typename returnPtrType::DataT*>(o.get()));
00109 }
00110 
00111 template<typename returnPtrType, class fromType>
00112 returnPtrType smart_static_cast(const SmartPtr<fromType> & o)
00113 {
00114     return returnPtrType((typename returnPtrType::DataT *)o.get());
00115 }
00116 
00117 } } // namespace Atlas::Objects
00118 
00119 #endif // ATLAS_OBJECTS_SMARTPTR_H

Copyright 2000-2004 the respective authors.

This document can be licensed under the terms of the GNU Free Documentation License or the GNU General Public License and may be freely distributed under the terms given by one of these licenses.