SharedPtr.h++

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002    commonc++ - A C++ Common Class Library
00003    Copyright (C) 2005-2012  Mark A Lindner
00004 
00005    This file is part of commonc++.
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public
00018    License along with this library; if not, write to the Free
00019    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020    ---------------------------------------------------------------------------
00021 */
00022 
00023 #ifndef __ccxx_SharedPtr_hxx
00024 #define __ccxx_SharedPtr_hxx
00025 
00026 #include <commonc++/Common.h++>
00027 #include <commonc++/AtomicCounter.h++>
00028 #include <commonc++/NullPointerException.h++>
00029 
00030 namespace ccxx {
00031 
00038 template<class T> class SharedPtr
00039 {
00040   public:
00041 
00043   SharedPtr(T *object = NULL)
00044     : _object(object), _refs(new AtomicCounter(1))
00045   { }
00046 
00048   SharedPtr(const SharedPtr &other)
00049     : _object(other._object),
00050       _refs(other._refs)
00051   {
00052     ++(*_refs);
00053   }
00054 
00056   ~SharedPtr()
00057   {
00058     _release();
00059   }
00060 
00064   template<class U> SharedPtr<U> staticCast()
00065   { return SharedPtr<U>(*this, false); }
00066 
00070   template<class U> SharedPtr<U> dynamicCast()
00071   { return SharedPtr<U>(*this); }
00072 
00074   SharedPtr& operator=(const SharedPtr &other)
00075   {
00076     if(other._object == _object)
00077       return(*this);
00078 
00079     _release();
00080     _object = other._object;
00081     _refs = other._refs;
00082     ++(*_refs);
00083     return(*this);
00084   }
00085 
00087   SharedPtr& operator=(T *object)
00088   {
00089     if(_object != object)
00090     {
00091       _release();
00092       _object = object;
00093       _refs = new AtomicCounter(1);
00094     }
00095 
00096     return(*this);
00097   }
00098 
00100   T* operator->() throw()
00101   { return(_object); }
00102 
00104   const T* operator->() const throw()
00105   { return(_object); }
00106 
00111   T& operator*() throw(NullPointerException)
00112   {
00113     if(! _object)
00114       throw NullPointerException();
00115 
00116     return(*_object);
00117   }
00118 
00123   const T& operator*() const throw(NullPointerException)
00124   {
00125     if(! _object)
00126       throw NullPointerException();
00127     return(*_object);
00128   }
00129 
00131   T* get() const
00132   { return(_object); }
00133 
00135   bool operator!() const throw()
00136   { return(isNull()); }
00137 
00139   operator const void *() const throw()
00140   { return(_object ? this : NULL); }
00141 
00143   bool isNull() const throw()
00144   { return(_object == NULL); }
00145 
00147   bool operator==(const SharedPtr &other) const
00148   { return(_object == other._object); }
00149 
00151   bool operator!=(const SharedPtr &other) const
00152   { return(! operator==(other)); }
00153 
00155   int getRefCount() const throw()
00156   { return(_object ? _refs->get() : 0); }
00157 
00158   private:
00159 
00160   template<class U> friend class SharedPtr;
00161 
00162   template<typename U>
00163     explicit SharedPtr(const SharedPtr<U> &other)
00164       : _object(dynamic_cast<T *>(other._object))
00165   {
00166     if(_object)
00167     {
00168       _refs = other._refs;
00169       ++(*_refs);
00170     }
00171     else
00172       _refs = new AtomicCounter(1);
00173   }
00174 
00175   template<typename U>
00176     SharedPtr(const SharedPtr<U> &other, bool tag)
00177       : _object(static_cast<T *>(other._object)),
00178         _refs(other._refs)
00179   {
00180     ++(*_refs);
00181   }
00182 
00183   void _release()
00184   {
00185     if(--(*_refs) == 0)
00186     {
00187       delete _object;
00188       delete _refs;
00189     }
00190   }
00191 
00192   T *_object;
00193   AtomicCounter *_refs;
00194 };
00195 
00196 }; // namespace ccxx
00197 
00198 #endif // __ccxx_SharedPtr_hxx
00199 
00200 /* end of header file */
Generated on Sat Nov 26 16:49:07 2011 for libcommonc++ by  doxygen 1.6.3