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
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
00158 if( m_ref == rhs.m_ref )
00159 {
00160 DEB2( printf("m_ref = rhs.m_ref\n") );
00161 return *this;
00162 }
00163
00164
00165 DeleteRefCount();
00166
00167
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
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