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