source: nrEngine/include/SmartPtr.h @ 15

Revision 15, 8.0 KB checked in by art, 12 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13#ifndef __NR_SMART_PTR_H_
14#define __NR_SMART_PTR_H_
15
16
17//----------------------------------------------------------------------------------
18// Includes
19//----------------------------------------------------------------------------------
20#include "Prerequisities.h"
21
22namespace nrEngine{
23
24        //! All smart pointers created whithin this deleter could not be deleted outside
25        /**
26        * This is an null_deleter - deleter. We need this to create smart pointer
27        * (SharedPtr<T>) from our singleton objects. Each pointer created with null
28        * deleter can not be released otherwhere else here. So we can give smart pointer
29        * to our singleton back and we can be sure, that our singleton object will not
30        * be deleted before Release-Function will be executed
31        * @see ::boost.org for smart pointers
32        * \ingroup gp
33        **/
34        struct _NRExport null_deleter{
35                void operator()(void const *) const
36                {
37                }
38        };
39       
40#define SharedPtr boost::shared_ptr
41
42#if 0
43        /**
44         * In our engine we are use always smart pointers, so that you do not have
45         * to care about the lifetime of them. We provide our own pointer definition
46         * rather than using boost's for example. Boosts pointers are fine, but they
47         * depends on a big library and could not be changed in a way, which are
48         * usefull for our puprose.
49         *
50         * The pointer does provide a reference counting mechanism. But rather then
51         * deriving the classes which could be referenced by this pointer, we store
52         * the counter
53         * \ingroup gp
54         **/
55        template <typename T>
56        class RefPtr {
57                private:
58               
59                        //! Store here the reference counter
60                        int32 mCounter;
61                       
62                        //! here we store the pointer itself
63                        T* mPointer;
64               
65                        //! Reference the object, so it will increment the counter
66                        void ref()
67                        {
68                                mCount ++;
69                        }
70               
71                        //! Decrement the counter and release object if counter is equal 0
72                        void unref()
73                        {
74                                mCounter --;
75                                if (mCounter == 0){
76                                        delete mPointer;
77                                }
78                        }
79
80                public:
81               
82                        //! Define the pointer as a friend of it's own
83                        template <class Y> friend class RefPtr;
84                       
85                        //! Create a pointer and initialze it with a NULL pointer
86                        RefPtr() : mPointer(0), mCounter(0)
87                        {
88                        }
89                       
90                        //! Create a smart pointer from a given raw pointer
91                        RefPtr(T* raw) : mPointer(0), mCounter(0)
92                        {
93                                // if the given object is valid, so reference it
94                                if (raw){
95                                        mPointer = raw;
96                                        ref();
97                                }
98                        }
99               
100                        //! Copyconstructor, copy the pointer and reference it again
101                        RefPtr(const RefPtr<T>& ptr) : mPointer(ptr.mPointer)
102                        {
103                                if (mPointer) ref();
104                        }
105                       
106                        //! Release the pointer, delete the holding object only if it reference counter goes to null
107                        ~RefPtr()
108                        {
109                                if (mPointer) unref();
110                                mPointer = 0;
111                        }
112
113
114                        //! Assigment of a raw pointer. Use it with care, because now the RefPtr gets ownership
115                        NR_FORCEINLINE RefPtr& operator=(T* ptr)
116                        {
117                         if (_ptr==ptr) return *this;
118            T* tmp_ptr = _ptr;
119            _ptr = ptr;
120            if (_ptr) _ptr->ref();
121            // unref second to prevent any deletion of any object which might
122            // be referenced by the other object. i.e rp is child of the
123            // original _ptr.
124            if (tmp_ptr) tmp_ptr->unref();
125            return *this;
126                                if (mPointer == ptr) return *this;
127                                if ()
128                                {
129                                        release();
130                                        counter = new Counter;
131                                        rawPtr = raw;
132                                }
133                                return *this;
134                        }
135       
136        template <typename Y>
137        ptr& operator=(Y* raw)
138        {
139                if (raw)
140                {
141                        release();
142                        counter = new Counter;
143                        rawPtr = static_cast<X*>(raw);
144                }
145                return *this;
146        }
147       
148        /*
149                assignment to long to allow ptr< X > = NULL,
150                also allows raw pointer assignment by conversion.
151                Raw pointer assignment is really dangerous!
152                If the raw pointer is being used elsewhere,
153                it will get deleted prematurely.
154        */
155        ptr& operator=(long num)
156        {
157                if (num == 0)  //pointer set to null
158                {
159                        release();
160                }
161       
162                else //assign raw pointer by conversion
163                {
164                        release();
165                        counter = new Counter;
166                        rawPtr = reinterpret_cast<X*>(num);
167                }       
168       
169                return *this;
170        }
171       
172        /*
173                Member Access
174        */
175                X* operator->() const
176                {
177                        return GetRawPointer();
178                }
179       
180       
181        /*
182                Dereference the pointer
183        */
184                X& operator* () const
185                {
186                        return *GetRawPointer();
187                }
188       
189       
190        /*
191                Conversion/casting operators
192        */
193                operator bool() const
194                {
195                        return IsValid();
196                }
197       
198                template <typename Y>
199                operator Y*() const
200                {
201                        return static_cast<Y*>(rawPtr); 
202                }
203       
204                template <typename Y>
205                operator const Y*() const
206                {
207                        return static_cast<const Y*>(rawPtr);
208                }
209       
210       
211        /*
212                Provide access to the raw pointer
213        */
214       
215                X* GetRawPointer() const         
216                {
217                        if (rawPtr == 0) throw new NullPointerException;
218                        return rawPtr;
219                }
220       
221               
222        /*
223                Is there only one reference on the counter?
224        */
225                bool IsUnique() const
226                {
227                        if (counter && counter->count == 1) return true;
228                        else return false;
229                }
230               
231                bool IsValid() const
232                {
233                        if (counter && rawPtr) return true;
234                        else return false;
235                }
236       
237                unsigned GetCount() const
238                {
239                        if (counter) return counter->count;
240                        else return 0;
241                }
242       
243        };
244       
245       
246        template <typename X, typename Y>
247        bool operator==(const ptr< X >& lptr, const ptr< Y >& rptr)
248        {
249                return lptr.GetRawPointer() == rptr.GetRawPointer();
250        }
251       
252        template <typename X, typename Y>
253        bool operator==(const ptr< X >& lptr, Y* raw)
254        {
255                return lptr.GetRawPointer() == raw ;
256        }
257       
258        template <typename X>
259        bool operator==(const ptr< X >& lptr, long num)
260        {
261                if (num == 0 && !lptr.IsValid())  //both pointer and address are null
262                {
263                        return true;
264                }
265       
266                else //convert num to a pointer, compare addresses
267                {
268                        return lptr == reinterpret_cast<X*>(num);
269                }
270               
271        }
272       
273        template <typename X, typename Y>
274        bool operator!=(const ptr< X >& lptr, const ptr< Y >& rptr)
275        {
276                return ( !operator==(lptr, rptr) );
277        }
278       
279        template <typename X, typename Y>
280        bool operator!=(const ptr< X >& lptr, Y* raw)
281        {
282                        return ( !operator==(lptr, raw) );
283        }
284       
285        template <typename X>
286        bool operator!=(const ptr< X >& lptr, long num)
287        {
288                return (!operator==(lptr, num) );
289        }
290       
291        template <typename X, typename Y>
292        bool operator&&(const ptr< X >& lptr, const ptr< Y >& rptr)
293        {
294                return lptr.IsValid() &&  rptr.IsValid();
295        }
296       
297        template <typename X>
298        bool operator&&(const ptr< X >& lptr, bool rval)
299        {
300                return lptr.IsValid() && rval;
301        }
302       
303        template <typename X>
304        bool operator&&(bool lval, const ptr< X >& rptr)
305        {
306                return lval &&  rptr.IsValid();
307        }
308       
309        template <typename X, typename Y>
310        bool operator||(const ptr< X >& lptr, const ptr< Y >& rptr)
311        {
312                return lptr.IsValid() || rptr.IsValid();
313        }
314       
315        template <typename X>
316        bool operator||(const ptr< X >& lptr, bool rval)
317        {
318                return lptr.IsValid() || rval;
319        }
320       
321        template <typename X>
322        bool operator||(bool lval, const ptr< X >& rptr)
323        {
324                return lval || rptr.IsValid();
325        }
326       
327        template <typename X>
328        bool operator!(const ptr< X >& p)
329        {
330                return (!p.IsValid());
331        }
332       
333       
334        /* less than comparisons for storage in containers */
335        template <typename X, typename Y>
336        bool operator< (const ptr< X >& lptr, const ptr < Y >& rptr)
337        {
338                return lptr.GetRawPointer() < rptr.GetRawPointer();
339        }
340       
341        template <typename X, typename Y>
342        bool operator< (const ptr< X >& lptr, Y* raw)
343        {
344                return lptr.GetRawPointer() < raw;
345        }
346       
347        template <typename X, typename Y>
348        bool operator< (X* raw, const ptr< Y >& rptr)
349        {
350                raw < rptr.GetRawPointer();
351        }
352#endif
353}; // end namespace
354
355#endif
Note: See TracBrowser for help on using the repository browser.