Used a more uniform of logging and added a commandline parser.
[UnsignedByte.git] / src / Resource / smart_ptr.h
blob1a94c81140fdd02a048c44fef57a09a62887f4e4
1 #ifndef SMART_PTR_H
2 #define SMART_PTR_H
4 /**
5 * @file smart_ptr.h
6 * This file contains the SmartPtr definition.
8 * Based on CONFIG_USE_BOOST_POINTERS we can alternate using a custom SmartPtr class and boost::shared_ptr.
9 * Currently we use boost::shared_ptr since the custom pointer doesn't provide static_cast.
11 * @see SmartPtr
12 */
14 #if 0
15 /** Statement is only executed because debug mode is enabled. */
16 #define DEB(x) x
17 #else
18 /** Statement is not executed because debug mode is disabled. */
19 #define DEB(x)
20 #endif
21 #if 0
22 /** Statement is only executed because debug mode is enabled. */
23 #define DEB2(x) x
24 #else
25 /** Statement is not executed because debug mode is disabled. */
26 #define DEB2(x)
27 #endif
29 /** When defined this enables the use of boost::shared_pointer instead of a homebrow SmartPtr. */
30 #define CONFIG_USE_BOOST_POINTERS
31 #ifdef CONFIG_USE_BOOST_POINTERS
33 #include <boost/shared_ptr.hpp>
34 #include <boost/enable_shared_from_this.hpp>
36 /** Define SmartPtr as the type to use for smart pointers. */
37 #define SmartPtr boost::shared_ptr
39 /** Define boost::checked_delete as the method used to delete objects. */
40 #define SmartPtrDelete(target) void boost::checked_delete<target>(target* x);
42 #else
44 /** Define SmartPtr as the class that will be used to delete objects. */
45 #define SmartPtrDelete(target) class SmartPtr<target>
47 /**
48 * The reference counting class
50 class SmartPtrCount
52 int m_refCount;
54 public:
55 /**
56 * Construct a reference counting class for row pointer data
57 * \param data pointer
59 SmartPtrCount()
60 : m_refCount( 1 )
62 DEB( printf("SmartPtrCount ctor...\n"));
65 /**
66 * Destructor
68 virtual ~SmartPtrCount()
70 DEB( printf("SmartPtrCount dtor...\n"));
73 /**
74 * Increase reference counting by 1
76 void IncRef() { m_refCount ++ ; }
78 /**
79 * Decrease reference counting by 1
81 void DecRef() { m_refCount -- ; }
82 /**
83 * Return the current reference counting
84 * \return current reference counting
86 int GetRefCount() { return m_refCount; }
89 /**
90 * A smart pointer class that provides a reference counting and auto delete memory.
92 * This class is similar to std::auto_ptr, with 2 exceptions:
93 * - This class uses reference counting
94 * - We dont provide a release() function (because of the reference counting)
95 * It is recommended to use this class instead of using raw pointer wherever possible.
97 * \note smart pointer to NULL is valid.
99 template <class T>
100 class SmartPtr
102 T* m_data;
103 SmartPtrCount* m_ref;
105 public:
107 * Construct smart pointer from ptr
108 * \param ptr pointer
110 SmartPtr(T* ptr)
112 DEB( printf("SmartPtr T* ctor...\n"));
113 // create a fresh copy
114 CreateFresh( ptr );
118 * Default constructor
120 SmartPtr()
121 : m_data(NULL)
123 DEB( printf("SmartPtr ctor...\n"));
124 m_ref = new SmartPtrCount();
128 * Copy constructor
129 * \param rhs right hand side
131 SmartPtr(const SmartPtr& rhs)
132 : m_data(NULL),
133 m_ref(NULL)
135 DEB( printf("SmartPtr SmartPtr ctor...\n"));
136 *this = rhs;
139 template<class Y>
140 SmartPtr(SmartPtr<Y> const& rhs)
141 : m_data(rhs.m_data),
142 m_ref(rhs.m_ref)
144 DEB( printf("SmartPtr SmartPtr<Y> ctor...\n"));
145 m_ref->IncRef();
149 * Assignment operator
150 * \param rhs right hand side
151 * \return reference to this
153 SmartPtr& operator=(const SmartPtr& rhs)
155 DEB2( printf("SmartPtr = operator...\n"));
157 // increase the reference count
158 if( m_ref == rhs.m_ref )
160 DEB2( printf("m_ref = rhs.m_ref\n") );
161 return *this;
164 // Delete previous reference
165 DeleteRefCount();
167 // TODO: What to do here?
168 if( !rhs.m_ref )
170 DEB2( printf("!rhs.m_ref\n") );
171 return *this;
174 DEB2( printf("no returns so far\n") );
176 m_data = rhs.m_data;
177 m_ref = rhs.m_ref;
178 m_ref->IncRef();
179 return *this;
183 * Destructor
185 virtual ~SmartPtr()
187 DEB( printf("SmartPtr dtor...\n"));
188 DeleteRefCount();
192 * Replace the current pointer with ptr
193 * if the current ptr is not NULL, it will be freed (reference counting free) before assingning the new ptr
194 * \param ptr new pointer
196 void reset(T* ptr = 0)
198 DeleteRefCount();
199 CreateFresh( ptr );
203 * Return pointer the row data pointer
204 * \return pointer to the row data pointer
206 T* get() const
208 return m_data;
212 * Overload the '->' operator
213 * \return pointer to the row data pointer
215 T* operator->() const
217 return m_data;
221 * Dereference operator
222 * \return dereference the row data
224 T& operator*() const
226 return *(m_data);
230 * Test for NULL operator
231 * \return true if the internal row data or the reference counting class are NULL false otherwise
233 bool operator!() const
235 return (!m_ref || !m_data);
239 * test for bool operation
240 * \return true of the internal raw data exist and it is not null
242 operator bool() const
244 return m_ref && m_data;
247 void print() const
249 printf("%d: %p (%p)\n", m_ref->GetRefCount(), m_data, this);
252 private:
253 void DeleteRefCount()
255 DEB2( printf("DeleteRefCount()\n") );
256 // decrease the ref count (or delete pointer if it is 1)
257 if( m_ref )
259 DEB2( printf("m_ref\n") );
260 if( m_ref->GetRefCount() <= 1 )
262 DEB2( printf("m_ref->GetRefCount() <= 1\n") );
263 delete m_ref;
264 m_ref = NULL;
265 delete m_data;
266 m_data = NULL;
268 else
270 DEB2( printf("m_ref->GetRefCount() = %d\n", m_ref->GetRefCount()) );
271 m_ref->DecRef();
274 else
276 DEB2( printf("!m_ref\n") );
280 void CreateFresh(T* ptr)
282 m_ref = new SmartPtrCount();
283 m_data = ptr;
286 template<class Y> friend class SmartPtr;
289 #endif // CONFIG_USE_BOOST_POINTERS
290 #endif // SMART_PTR_H