cmtkSmartConstPtr.h

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2565 $
00026 //
00027 //  $LastChangedDate: 2010-11-29 13:56:46 -0800 (Mon, 29 Nov 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #ifndef __cmtkSmartConstPtr_h_included_
00034 #define __cmtkSmartConstPtr_h_included_
00035 
00036 #include <cmtkconfig.h>
00037 
00038 #ifndef NULL
00039 #  define NULL 0
00040 #endif
00041 
00042 #include <algorithm>
00043 #include <cassert>
00044 
00045 #include <System/cmtkSafeCounter.h>
00046 
00047 namespace
00048 cmtk
00049 {
00050 
00053 
00056 template<class T>
00057 class SmartConstPointer
00058 {
00059 public:
00061   typedef SmartConstPointer<T> Self;
00062 
00064   typedef const T* PointerType;
00065 
00067   static Self Null;
00068   
00070   unsigned int GetReferenceCount() const 
00071   { 
00072     return this->m_ReferenceCount->Get(); 
00073   }
00074 
00079   SmartConstPointer() 
00080     : m_ReferenceCount( new SafeCounter( 1 ) )
00081   { 
00082     this->m_Object.ptrConst = NULL;
00083   }
00084   
00089   explicit SmartConstPointer( T *const object ) 
00090     : m_ReferenceCount( new SafeCounter( 1 ) )
00091   { 
00092     this->m_Object.ptrConst = object;
00093   }
00094 
00098   template<class T2>
00099   SmartConstPointer( const SmartConstPointer<T2>& ptr ) 
00100     : m_ReferenceCount( ptr.m_ReferenceCount )
00101   {
00102     this->m_Object.ptrConst = ptr.m_Object.ptrConst;
00103     this->m_ReferenceCount->Increment();
00104   }
00105   
00109   SmartConstPointer( const Self& ptr ) 
00110     : m_ReferenceCount( ptr.m_ReferenceCount )
00111   {
00112     this->m_Object.ptrConst = ptr.m_Object.ptrConst;
00113     this->m_ReferenceCount->Increment();
00114   }
00115   
00117   ~SmartConstPointer() 
00118   {
00119     assert( this->m_ReferenceCount != NULL ); // we may have m_Object=NULL, but m_ReferenceCount should never be!
00120     if ( ! this->m_ReferenceCount->Decrement() ) 
00121       {
00122       delete this->m_ReferenceCount;
00123 #ifdef DEBUG
00124       this->m_ReferenceCount = NULL;
00125 #endif
00126       if ( this->m_Object.ptrConst ) 
00127         {
00128         delete this->m_Object.ptrConst;
00129 #ifdef DEBUG
00130         this->m_Object.ptrConst = NULL;
00131 #endif
00132         }
00133       }
00134   }
00135 
00137   const T& operator*() const { return *this->m_Object.ptrConst; }
00138 
00140   const T* operator->() const { return this->m_Object.ptrConst; }
00141 
00143   operator const T*() const { return m_Object.ptrConst; }
00144   
00146   const T* GetConstPtr() const { return this->m_Object.ptrConst; }
00147 
00151   const T* ReleasePtr() 
00152   { 
00153     const T* object = this->m_Object.ptrConst; 
00154     this->m_Object.ptrConst = NULL; 
00155     return object; 
00156   }
00157 
00167   const Self& operator= ( const Self other ) const
00168   {
00169     using std::swap;
00170     swap( this->m_ReferenceCount, other.m_ReferenceCount );
00171     swap( this->m_Object.ptrConst, other.m_Object.ptrConst );
00172 
00173     return *this;
00174   }
00175 
00178   bool operator== ( const Self& other ) const 
00179   {
00180     return (this->m_Object.ptrConst == other.m_Object.ptrConst);
00181   }
00182   
00185   bool operator!= ( const Self& other ) const 
00186   {
00187     return (this->m_Object.ptrConst != other.m_Object.ptrConst);
00188   }
00189   
00192   bool operator< ( const Self& other ) const 
00193   {
00194     return ( this->m_Object.ptrConst < other.m_Object.ptrConst );
00195   }
00196   
00198   template<class T2> 
00199   static Self DynamicCastFrom( const T2& from_P )
00200   {
00201     return Self( dynamic_cast<typename Self::PointerType>( from_P.GetConstPtr() ), from_P.m_ReferenceCount );
00202   }
00203 
00204 protected:
00206   mutable SafeCounter* m_ReferenceCount;
00207   
00209   mutable union
00210   {
00212     const T* ptrConst;
00214     T* ptr;
00215   } m_Object;
00216   
00220   SmartConstPointer( const T *const object, SafeCounter *const counter ) 
00221   {
00222     this->m_Object.ptrConst = object;
00223     this->m_ReferenceCount = counter;
00224     this->m_ReferenceCount->Increment();
00225   }
00226   
00228   template<class T2> friend class SmartConstPointer;
00229 };
00230 
00231 template<typename T> SmartConstPointer<T> SmartConstPointer<T>::Null;
00232 
00234 
00235 } // namespace cmtk
00236 
00237 #endif // define __cmtkSmartConstPtr_h_included_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines