SmartPtr.h

00001 /***************************************************************************
00002  *                                                                         *
00003  *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
00004  *       mailto: <tevs@mpi-sb.mpg.de>                                      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  ***************************************************************************/
00012 
00013 #ifndef __NR_SMART_PTR_H_
00014 #define __NR_SMART_PTR_H_
00015 
00016 
00017 //----------------------------------------------------------------------------------
00018 // Includes
00019 //----------------------------------------------------------------------------------
00020 #include "Prerequisities.h"
00021 
00022 namespace nrEngine{
00023 
00024         //! All smart pointers created whithin this deleter could not be deleted outside
00025         /**
00026         * This is an null_deleter - deleter. We need this to create smart pointer
00027         * (SharedPtr<T>) from our singleton objects. Each pointer created with null
00028         * deleter can not be released otherwhere else here. So we can give smart pointer
00029         * to our singleton back and we can be sure, that our singleton object will not
00030         * be deleted before Release-Function will be executed
00031         * @see ::boost.org for smart pointers
00032         * \ingroup gp
00033         **/
00034         struct _NRExport null_deleter{
00035                 void operator()(void const *) const
00036                 {
00037                 }
00038         };
00039         
00040 #define SharedPtr boost::shared_ptr
00041 
00042 #if 0
00043         /**
00044          * In our engine we are use always smart pointers, so that you do not have 
00045          * to care about the lifetime of them. We provide our own pointer definition
00046          * rather than using boost's for example. Boosts pointers are fine, but they
00047          * depends on a big library and could not be changed in a way, which are
00048          * usefull for our puprose.
00049          * 
00050          * The pointer does provide a reference counting mechanism. But rather then 
00051          * deriving the classes which could be referenced by this pointer, we store
00052          * the counter
00053          * \ingroup gp
00054          **/
00055         template <typename T> 
00056         class RefPtr {
00057                 private:
00058                 
00059                         //! Store here the reference counter
00060                         int32 mCounter;
00061                         
00062                         //! here we store the pointer itself
00063                         T* mPointer;
00064                 
00065                         //! Reference the object, so it will increment the counter 
00066                         void ref() 
00067                         {
00068                                 mCount ++;
00069                         }
00070                 
00071                         //! Decrement the counter and release object if counter is equal 0
00072                         void unref()
00073                         { 
00074                                 mCounter --;
00075                                 if (mCounter == 0){
00076                                         delete mPointer;
00077                                 }
00078                         }
00079 
00080                 public:
00081                 
00082                         //! Define the pointer as a friend of it's own
00083                         template <class Y> friend class RefPtr; 
00084                         
00085                         //! Create a pointer and initialze it with a NULL pointer
00086                         RefPtr() : mPointer(0), mCounter(0)
00087                         {
00088                         }
00089                         
00090                         //! Create a smart pointer from a given raw pointer 
00091                         RefPtr(T* raw) : mPointer(0), mCounter(0)
00092                         {
00093                                 // if the given object is valid, so reference it
00094                                 if (raw){
00095                                         mPointer = raw;
00096                                         ref();
00097                                 }
00098                         }
00099                 
00100                         //! Copyconstructor, copy the pointer and reference it again
00101                         RefPtr(const RefPtr<T>& ptr) : mPointer(ptr.mPointer)
00102                         {
00103                                 if (mPointer) ref();
00104                         }
00105                         
00106                         //! Release the pointer, delete the holding object only if it reference counter goes to null
00107                         ~RefPtr()
00108                         {
00109                                 if (mPointer) unref();
00110                                 mPointer = 0;
00111                         }
00112 
00113 
00114                         //! Assigment of a raw pointer. Use it with care, because now the RefPtr gets ownership 
00115                         NR_FORCEINLINE RefPtr& operator=(T* ptr)
00116                         {
00117                          if (_ptr==ptr) return *this;
00118             T* tmp_ptr = _ptr;
00119             _ptr = ptr;
00120             if (_ptr) _ptr->ref();
00121             // unref second to prevent any deletion of any object which might
00122             // be referenced by the other object. i.e rp is child of the
00123             // original _ptr.
00124             if (tmp_ptr) tmp_ptr->unref();
00125             return *this;
00126                                 if (mPointer == ptr) return *this;
00127                                 if ()
00128                                 {
00129                                         release(); 
00130                                         counter = new Counter; 
00131                                         rawPtr = raw; 
00132                                 }
00133                                 return *this;
00134                         }
00135         
00136         template <typename Y>
00137         ptr& operator=(Y* raw)
00138         {
00139                 if (raw)
00140                 {
00141                         release();
00142                         counter = new Counter; 
00143                         rawPtr = static_cast<X*>(raw);
00144                 }
00145                 return *this;
00146         }
00147         
00148         /* 
00149                 assignment to long to allow ptr< X > = NULL, 
00150                 also allows raw pointer assignment by conversion. 
00151                 Raw pointer assignment is really dangerous!
00152                 If the raw pointer is being used elsewhere, 
00153                 it will get deleted prematurely. 
00154         */ 
00155         ptr& operator=(long num)
00156         {
00157                 if (num == 0)  //pointer set to null
00158                 {
00159                         release(); 
00160                 }
00161         
00162                 else //assign raw pointer by conversion
00163                 {
00164                         release();
00165                         counter = new Counter; 
00166                         rawPtr = reinterpret_cast<X*>(num);
00167                 }       
00168         
00169                 return *this; 
00170         } 
00171         
00172         /*
00173                 Member Access
00174         */
00175                 X* operator->() const 
00176                 {
00177                         return GetRawPointer(); 
00178                 }
00179         
00180         
00181         /*
00182                 Dereference the pointer
00183         */
00184                 X& operator* () const 
00185                 {
00186                         return *GetRawPointer(); 
00187                 }
00188         
00189         
00190         /*
00191                 Conversion/casting operators
00192         */
00193                 operator bool() const
00194                 {
00195                         return IsValid();
00196                 }
00197         
00198                 template <typename Y>
00199                 operator Y*() const
00200                 {
00201                         return static_cast<Y*>(rawPtr);  
00202                 }
00203         
00204                 template <typename Y>
00205                 operator const Y*() const
00206                 {
00207                         return static_cast<const Y*>(rawPtr);
00208                 }
00209         
00210         
00211         /*
00212                 Provide access to the raw pointer 
00213         */
00214         
00215                 X* GetRawPointer() const         
00216                 {
00217                         if (rawPtr == 0) throw new NullPointerException;
00218                         return rawPtr;
00219                 }
00220         
00221                 
00222         /* 
00223                 Is there only one reference on the counter?
00224         */
00225                 bool IsUnique() const
00226                 {
00227                         if (counter && counter->count == 1) return true; 
00228                         else return false; 
00229                 }
00230                 
00231                 bool IsValid() const
00232                 {
00233                         if (counter && rawPtr) return true;
00234                         else return false; 
00235                 }
00236         
00237                 unsigned GetCount() const
00238                 {
00239                         if (counter) return counter->count;
00240                         else return 0;
00241                 }
00242         
00243         };
00244         
00245         
00246         template <typename X, typename Y>
00247         bool operator==(const ptr< X >& lptr, const ptr< Y >& rptr) 
00248         {
00249                 return lptr.GetRawPointer() == rptr.GetRawPointer(); 
00250         }
00251         
00252         template <typename X, typename Y>
00253         bool operator==(const ptr< X >& lptr, Y* raw) 
00254         {
00255                 return lptr.GetRawPointer() == raw ; 
00256         }
00257         
00258         template <typename X>
00259         bool operator==(const ptr< X >& lptr, long num)
00260         {
00261                 if (num == 0 && !lptr.IsValid())  //both pointer and address are null
00262                 {
00263                         return true; 
00264                 }
00265         
00266                 else //convert num to a pointer, compare addresses
00267                 {
00268                         return lptr == reinterpret_cast<X*>(num);
00269                 }
00270                 
00271         } 
00272         
00273         template <typename X, typename Y>
00274         bool operator!=(const ptr< X >& lptr, const ptr< Y >& rptr) 
00275         {
00276                 return ( !operator==(lptr, rptr) );
00277         }
00278         
00279         template <typename X, typename Y>
00280         bool operator!=(const ptr< X >& lptr, Y* raw) 
00281         {
00282                         return ( !operator==(lptr, raw) );
00283         }
00284         
00285         template <typename X>
00286         bool operator!=(const ptr< X >& lptr, long num)
00287         {
00288                 return (!operator==(lptr, num) ); 
00289         }
00290         
00291         template <typename X, typename Y>
00292         bool operator&&(const ptr< X >& lptr, const ptr< Y >& rptr)
00293         {
00294                 return lptr.IsValid() &&  rptr.IsValid();
00295         }
00296         
00297         template <typename X>
00298         bool operator&&(const ptr< X >& lptr, bool rval)
00299         {
00300                 return lptr.IsValid() && rval;
00301         }
00302         
00303         template <typename X>
00304         bool operator&&(bool lval, const ptr< X >& rptr)
00305         {
00306                 return lval &&  rptr.IsValid();
00307         }
00308         
00309         template <typename X, typename Y>
00310         bool operator||(const ptr< X >& lptr, const ptr< Y >& rptr)
00311         {
00312                 return lptr.IsValid() || rptr.IsValid();
00313         }
00314         
00315         template <typename X>
00316         bool operator||(const ptr< X >& lptr, bool rval)
00317         {
00318                 return lptr.IsValid() || rval;
00319         }
00320         
00321         template <typename X>
00322         bool operator||(bool lval, const ptr< X >& rptr)
00323         {
00324                 return lval || rptr.IsValid(); 
00325         }
00326         
00327         template <typename X>
00328         bool operator!(const ptr< X >& p)
00329         {
00330                 return (!p.IsValid());
00331         }
00332         
00333         
00334         /* less than comparisons for storage in containers */
00335         template <typename X, typename Y>
00336         bool operator< (const ptr< X >& lptr, const ptr < Y >& rptr)
00337         {
00338                 return lptr.GetRawPointer() < rptr.GetRawPointer();
00339         }
00340         
00341         template <typename X, typename Y>
00342         bool operator< (const ptr< X >& lptr, Y* raw)
00343         {
00344                 return lptr.GetRawPointer() < raw;
00345         }
00346         
00347         template <typename X, typename Y>
00348         bool operator< (X* raw, const ptr< Y >& rptr)
00349         {
00350                 raw < rptr.GetRawPointer();
00351         }
00352 #endif
00353 }; // end namespace
00354 
00355 #endif

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1