src/Resource/smart_ptr.h

Go to the documentation of this file.
00001 #ifndef SMART_PTR_H
00002 #define SMART_PTR_H
00003 
00014 #if 0
00015 
00016         #define DEB(x) x
00017 #else
00018 
00019         #define DEB(x)
00020 #endif
00021 #if 0
00022 
00023         #define DEB2(x) x
00024 #else
00025 
00026         #define DEB2(x)
00027 #endif
00028 
00030 #define CONFIG_USE_BOOST_POINTERS
00031 #ifdef CONFIG_USE_BOOST_POINTERS
00032 
00033 #include <boost/shared_ptr.hpp>
00034 #include <boost/enable_shared_from_this.hpp>
00035 
00037 #define SmartPtr boost::shared_ptr
00038 
00040 #define SmartPtrDelete(target)  void boost::checked_delete<target>(target* x);
00041 
00042 #else
00043 
00045 #define SmartPtrDelete(target)  class SmartPtr<target>
00046 
00050 class SmartPtrCount
00051 {
00052         int m_refCount;
00053 
00054 public:
00059         SmartPtrCount()
00060                 : m_refCount( 1 )
00061         {
00062                 DEB( printf("SmartPtrCount ctor...\n"));
00063         }
00064 
00068         virtual ~SmartPtrCount()
00069         {
00070                 DEB( printf("SmartPtrCount dtor...\n"));
00071         }
00072 
00076         void IncRef() { m_refCount ++ ; }
00077 
00081         void DecRef() { m_refCount -- ; }
00086         int  GetRefCount() { return m_refCount; }
00087 };
00088 
00099 template <class T>
00100 class SmartPtr
00101 {
00102         T* m_data;
00103         SmartPtrCount* m_ref;
00104 
00105 public:
00110         SmartPtr(T* ptr)
00111         {
00112                 DEB( printf("SmartPtr T* ctor...\n"));
00113                 // create a fresh copy
00114                 CreateFresh( ptr );
00115         }
00116         
00120         SmartPtr()
00121                 : m_data(NULL)
00122         {
00123                 DEB( printf("SmartPtr ctor...\n"));
00124                 m_ref = new SmartPtrCount();
00125         }
00126 
00131         SmartPtr(const SmartPtr& rhs)
00132                 : m_data(NULL),
00133                 m_ref(NULL)
00134         {
00135                 DEB( printf("SmartPtr SmartPtr ctor...\n"));
00136                 *this = rhs;
00137         }
00138         
00139         template<class Y>
00140         SmartPtr(SmartPtr<Y> const& rhs) 
00141                 : m_data(rhs.m_data),
00142                 m_ref(rhs.m_ref)
00143         {
00144                 DEB( printf("SmartPtr SmartPtr<Y> ctor...\n"));
00145                 m_ref->IncRef();
00146         }
00147 
00153         SmartPtr& operator=(const SmartPtr& rhs)
00154         {
00155                 DEB2( printf("SmartPtr = operator...\n"));
00156                 
00157                 // increase the reference count
00158                 if( m_ref == rhs.m_ref )
00159                 {
00160                         DEB2( printf("m_ref = rhs.m_ref\n") );
00161                         return *this;
00162                 }
00163 
00164                 // Delete previous reference 
00165                 DeleteRefCount();
00166 
00167                 // TODO: What to do here?
00168                 if( !rhs.m_ref )
00169                 {
00170                         DEB2( printf("!rhs.m_ref\n") );
00171                         return *this;
00172                 }
00173                 
00174                 DEB2( printf("no returns so far\n") );
00175                 
00176                 m_data = rhs.m_data;
00177                 m_ref = rhs.m_ref;
00178                 m_ref->IncRef();
00179                 return *this;
00180         }
00181 
00185         virtual ~SmartPtr()
00186         {
00187                 DEB( printf("SmartPtr dtor...\n"));
00188                 DeleteRefCount();
00189         }
00190 
00196         void reset(T* ptr = 0)
00197         {       
00198                 DeleteRefCount();
00199                 CreateFresh( ptr );
00200         }
00201 
00206         T* get() const
00207         {
00208                 return m_data;
00209         }
00210 
00215         T* operator->() const 
00216         {
00217                 return m_data;
00218         }
00219 
00224         T& operator*() const
00225         {
00226                 return *(m_data);
00227         }
00228 
00233         bool operator!() const
00234         {
00235                 return (!m_ref || !m_data);
00236         }
00237 
00242         operator bool() const
00243         {
00244                 return m_ref && m_data;
00245         }
00246         
00247         void print() const
00248         {
00249                 printf("%d: %p (%p)\n", m_ref->GetRefCount(), m_data, this);
00250         }
00251 
00252 private:
00253         void DeleteRefCount()
00254         {
00255                 DEB2( printf("DeleteRefCount()\n") );
00256                 // decrease the ref count (or delete pointer if it is 1)
00257                 if( m_ref )
00258                 {
00259                         DEB2( printf("m_ref\n") );
00260                         if( m_ref->GetRefCount() <= 1 )
00261                         {
00262                                 DEB2( printf("m_ref->GetRefCount() <= 1\n") );
00263                                 delete m_ref;
00264                                 m_ref = NULL;
00265                                 delete m_data;
00266                                 m_data = NULL;
00267                         }
00268                         else
00269                         {
00270                                 DEB2( printf("m_ref->GetRefCount() = %d\n", m_ref->GetRefCount()) );
00271                                 m_ref->DecRef();
00272                         }
00273                 }
00274                 else
00275                 {
00276                         DEB2( printf("!m_ref\n") );
00277                 }
00278         };
00279 
00280         void CreateFresh(T* ptr)
00281         {
00282                 m_ref = new SmartPtrCount();
00283                 m_data = ptr;
00284         }
00285         
00286         template<class Y> friend class SmartPtr;
00287 };
00288 
00289 #endif // CONFIG_USE_BOOST_POINTERS
00290 #endif // SMART_PTR_H

Generated for UnsignedByte by  doxygen 1.5.3
SourceForge.net Logo