src/tools/tSafePTR.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #ifndef ArmageTron_SAFEPTR_H
00029 #define ArmageTron_SAFEPTR_H
00030 
00031 #include "aa_config.h"
00032 #include <stddef.h>
00033 #if HAVE_UNISTD_H
00034 // #include <unistd.h>
00035 #endif
00036 
00037 #include "tError.h"
00038 
00039 class tCheckedPTRBase{
00040     friend class tPTRList;
00041     int id;
00042 protected:
00043     void *target;
00044 public:
00045     tCheckedPTRBase(void *x);
00046     tCheckedPTRBase(const tCheckedPTRBase &x);
00047     tCheckedPTRBase();
00048     ~tCheckedPTRBase();
00049 
00050     tCheckedPTRBase& operator=(void *x){target=x; return *this;}
00051     //  void * operator->() const {return target;}
00052     //  void & operator*() const {return *target;}
00053     //operator void *() const {return target;}
00054     operator bool() const{return target!=NULL;}
00055     bool operator !() const{return !target;}
00056 
00057     static void CheckDestructed(void *test);
00058 
00059     static void Check();
00060 };
00061 
00062 
00063 template<class T> class tCheckedPTR:public tCheckedPTRBase{
00064     typedef T myclass;
00065 public:
00066     tCheckedPTR(T *x):tCheckedPTRBase(x){};
00067     tCheckedPTR(const tCheckedPTR<T> &x):tCheckedPTRBase(x.target){};
00068     tCheckedPTR():tCheckedPTRBase(){};
00069     ~tCheckedPTR(){};
00070 
00071     tCheckedPTR<T> &operator=(T *x){tCheckedPTRBase::operator=(x); return *this;}
00072     tCheckedPTR<T> &operator=(const tCheckedPTR<T> &x)
00073     {tCheckedPTRBase::operator=(x.target); return *this;}
00074     T * operator->() const {return reinterpret_cast<T*>(target);}
00075     T & operator*() const {return *reinterpret_cast<T*>(target);}
00076     operator T*() const {return reinterpret_cast<T*>(target);}
00077     //  T** operator&() {return reinterpret_cast<T **>(&target);}
00078 
00079     bool operator==(const T* x)const{return target==x;}
00080     bool operator!=(const T* x)const{return target!=x;}
00081     bool operator==(const tCheckedPTR<T> &x)const{return target==x.target;}
00082     bool operator!=(const tCheckedPTR<T> &x)const{return target!=x.target;}
00083 
00084     void Destroy(){
00085         if (target){
00086             T *dummy=reinterpret_cast<T*>(target);
00087             target=NULL;
00088             delete dummy;
00089         }
00090     }
00091 };
00092 
00093 template<class T> class tCheckedPTRConst:public tCheckedPTRBase{
00094     typedef T myclass;
00095 public:
00096     tCheckedPTRConst():tCheckedPTRBase(NULL){};
00097     tCheckedPTRConst(const T *x):tCheckedPTRBase(reinterpret_cast<void *>(x)){};
00098     tCheckedPTRConst(const tCheckedPTRConst<T> &x):tCheckedPTRBase(x.target){};
00099     tCheckedPTRConst(const tCheckedPTR<T> &x):tCheckedPTRBase(x.operator->()){};
00100     ~tCheckedPTRConst(){};
00101 
00102     tCheckedPTRConst<T> &operator=(const T *x)
00103     {tCheckedPTRBase::operator=(reinterpret_cast<T *>(x)); return *this;}
00104     tCheckedPTRConst<T> &operator=(const tCheckedPTRConst<T> &x)
00105     {tCheckedPTRBase::operator=(x.target); return *this;}
00106     tCheckedPTRConst<T> &operator=(const tCheckedPTR<T> &x)
00107     {tCheckedPTRBase::operator=(x.operator->()); return *this;}
00108 
00109     const T * operator->() const {return target;}
00110     const T & operator*() const {return *reinterpret_cast<T*>(target);}
00111     operator const T*() const {return reinterpret_cast<const T*>(target);}
00112     //  const T** operator&() {return reinterpret_cast<const T **>(&target);}
00113 
00114     bool operator==(const T* x)const{return target==x;}
00115     bool operator!=(const T* x)const{return target!=x;}
00116 
00117     void Destroy(){
00118         if (target){
00119             T *dummy=reinterpret_cast<T *>(target);
00120             target=NULL;
00121             dummy->AddRef();
00122             dummy->Release();
00123         }
00124     }
00125 };
00126 
00127 
00128 
00129 
00130 //#define CHECK_PTR 1
00131 
00132 
00133 template<class T> void SafeDelete(T &x){
00134     x.Destroy();
00135 }
00136 
00137 template<class T> void SafeDeletePtr(T * &x){
00138     if (x){
00139         T *dummy=x;
00140         x=NULL;
00141         delete dummy;
00142     }
00143 }
00144 
00145 #define tDESTROY_PTR(x) SafeDeletePtr(x)
00146 
00147 #ifdef DEBUG
00148 #ifdef CHECK_PTR 
00149 #define tDESTROY(x) SafeDelete(x)
00150 #define tCHECKED_PTR(x) tCheckedPTR<x>
00151 #define tCHECKED_PTR_CONST(x) tCheckedPTRConst<x>
00152 #define tCHECK_DEST tCheckedPTRBase::CheckDestructed(this) 
00153 #define tSAFEPTR
00154 #else
00155 #define tDESTROY(x) SafeDeletePtr(x)
00156 #define tCHECK_DEST 
00157 #define tCHECKED_PTR(x) x *
00158 #define tCHECKED_PTR_CONST(x) const x *
00159 #endif
00160 #else
00161 #define tDESTROY(x) SafeDeletePtr(x)
00162 #define tCHECK_DEST 
00163 #define tCHECKED_PTR(x) x *
00164 #define tCHECKED_PTR_CONST(x) const x *
00165 #endif
00166 
00167 #define tCONTROLLED_PTR(x) tControlledPTR<x>
00168 
00169 
00170 
00171 template<class T> class tControlledPTR{
00172     tCHECKED_PTR(T) target;
00173 
00174     void AddRef(){
00175         if (target)
00176             target->AddRef();
00177     }
00178 
00179     void Release(){
00180         if (target){
00181             //#ifdef tSAFEPTR
00182             T *dummy=reinterpret_cast<T*>(target);
00183             target=NULL;
00184             dummy->Release();
00185             //#else
00186             //      target->Release();
00187             //      target=NULL;
00188             //#endif
00189         }
00190     }
00191 
00192 public:
00193 
00194     tControlledPTR(T *x):target(x){AddRef();}
00195     tControlledPTR(const tCheckedPTR<T> &x):target(x.operator->()){AddRef();}
00196     tControlledPTR(const tControlledPTR<T> &x):target(x.target){AddRef();}
00197     tControlledPTR():target(NULL){};
00198 
00199 
00200     tControlledPTR<T> &operator=(T *x){
00201         if (target!=x){
00202             Release();
00203             target=x;
00204             AddRef();
00205         }
00206         return *this;
00207     }
00208 
00209     tControlledPTR<T> &operator=(const tControlledPTR<T> &x){
00210         if (target!=x.target){
00211             Release();
00212             target=x.target;
00213             AddRef();
00214         }
00215         return *this;
00216     }
00217 
00218     T * operator->() const {
00219         return target;
00220     }
00221 
00222     T & operator*() const {
00223         return *target;
00224     }
00225 
00226     operator T*() const {
00227         return target;
00228     }
00229 
00230     /*
00231       T** operator&() {
00232         return &target;
00233       }
00234     */
00235 
00236     bool operator==(const T* x)const{
00237         return target==x;
00238     }
00239 
00240     bool operator!=(const T* x)const{
00241         return target!=x;
00242     }
00243 
00244     bool operator==(T* x)const{
00245         return target==x;
00246     }
00247 
00248     bool operator!=(T* x)const{
00249         return target!=x;
00250     }
00251 
00252     operator bool()const{
00253         return target!=NULL;
00254     }
00255 
00256     bool operator !()const{
00257         return target==NULL;
00258     }
00259 
00260     bool operator==(const tControlledPTR<T> &x)const{
00261         return target==x.target;
00262     }
00263 
00264     bool operator!=(const tControlledPTR<T> &x)const{
00265         return target!=x.target;
00266     }
00267 
00268     void Destroy(){
00269         if (target){
00270 #ifdef tSAFEPTR
00271             T *dummy=(T *)target;
00272             target=NULL;
00273             delete dummy;
00274 #else
00275             delete target();
00276             target=NULL;
00277 #endif
00278         }
00279     }
00280 
00281 
00282     ~tControlledPTR(){
00283         Release();
00284     };
00285 };
00286 
00287 template<class T> class tJUST_CONTROLLED_PTR{
00288     T * target;
00289 
00290     void AddRef(){
00291         if (target)
00292             target->AddRef();
00293     }
00294 
00295     void Release(){
00296         if (target){
00297             T *dummy=target;
00298             target=NULL;
00299             dummy->Release();
00300         }
00301     }
00302 
00303 public:
00304 
00305     tJUST_CONTROLLED_PTR(T *x):target(x){AddRef();}
00306     tJUST_CONTROLLED_PTR(const tCheckedPTR<T> &x):target(x.operator->()){AddRef();}
00307     tJUST_CONTROLLED_PTR(const tJUST_CONTROLLED_PTR<T> &x):target(x.target){AddRef();}
00308     tJUST_CONTROLLED_PTR():target(NULL){};
00309 
00310 
00311     tJUST_CONTROLLED_PTR<T> &operator=(T *x){
00312         if (target!=x){
00313             Release();
00314             target=x;
00315             AddRef();
00316         }
00317         return *this;
00318     }
00319 
00320     tJUST_CONTROLLED_PTR<T> &operator=(const tJUST_CONTROLLED_PTR<T> &x){
00321         operator=(x.target);
00322         return *this;
00323     }
00324 
00325     T * operator->() const {
00326         return target;
00327     }
00328 
00329     T & operator*() const {
00330         return *target;
00331     }
00332 
00333     operator T*() const {
00334         return target;
00335     }
00336 
00337     /*
00338       T** operator&() {
00339         return &target;
00340       }
00341     */
00342 
00343     bool operator==(const T* x)const{
00344         return target==x;
00345     }
00346 
00347     bool operator!=(const T* x)const{
00348         return target!=x;
00349     }
00350 
00351     bool operator==(const tJUST_CONTROLLED_PTR<T> &x)const{
00352         return target==x.target;
00353     }
00354 
00355     bool operator!=(const tJUST_CONTROLLED_PTR<T> &x)const{
00356         return target!=x.target;
00357     }
00358 
00359     void Destroy(){
00360         if (target){
00361 #ifdef tSAFEPTR
00362             T *dummy=(T *)target;
00363             target=NULL;
00364             delete dummy;
00365 #else
00366             delete target();
00367             target=NULL;
00368 #endif
00369         }
00370     }
00371 
00372 
00373     ~tJUST_CONTROLLED_PTR(){
00374         Release();
00375     };
00376 };
00377 
00378 
00379 template<class T> bool operator==(const T *x, const tJUST_CONTROLLED_PTR<T> &y)
00380 {
00381     return (x == static_cast<const T*>(y));
00382 }
00383 
00384 template<class T> bool operator==(T *x, const tJUST_CONTROLLED_PTR<T> &y)
00385 {
00386     return (x == static_cast<const T*>(y));
00387 }
00388 
00389 template<class T> bool operator==(const T *x, tJUST_CONTROLLED_PTR<T> &y)
00390 {
00391     return (x == static_cast<const T*>(y));
00392 }
00393 
00394 template<class T> bool operator==(T *x, tJUST_CONTROLLED_PTR<T> &y)
00395 {
00396     return (x == static_cast<const T*>(y));
00397 }
00398 
00399 template< class T > class tStackObject: public T
00400 {
00401 public:
00402     tStackObject(){ this->AddRef(); }
00403     template< typename A >
00404     explicit tStackObject( A& a ): T( a ) { this->AddRef(); }
00405     template< typename A, typename B >
00406     tStackObject( A& a, B& b ): T( a, b ) { this->AddRef(); }
00407     template< typename A, typename B, typename C >
00408     tStackObject( A& a, B& b, C& c ): T( a, b, c ) { this->AddRef(); }
00409 
00410     ~tStackObject()
00411     {
00412         if ( this->GetRefcount() != 1 )
00413             st_Breakpoint();
00414 
00415         this->refCtr_ = -1000;
00416     }
00417 };
00418 
00419 #ifdef DEBUG
00420 void st_AddRefBreakpint( void const * object );
00421 void st_ReleaseBreakpint( void const * object );
00422 #endif
00423 
00424 // not thread-safe mutex
00425 struct tNonMutex
00426 {
00427     void acquire(){};
00428     void release(){};
00429 };
00430 
00431 template< class T, class MUTEX = tNonMutex > class tReferencable
00432 {
00433     friend class tStackObject< T >;
00434 
00435 public:
00436     tReferencable()                                                                                             :refCtr_(0) {};
00437     tReferencable                               ( const tReferencable& )                                                :refCtr_(0) {};
00438     tReferencable& operator =	( const tReferencable& ){ return *this; }
00439 
00440     void                AddRef          ()      const
00441     {
00442 #ifdef DEBUG
00443         st_AddRefBreakpint( this );
00444 #endif        
00445         tASSERT( this && refCtr_ >= 0 );
00446         mutex_.acquire();
00447         ++refCtr_;
00448         mutex_.release();
00449         tASSERT( this && refCtr_ >= 0 );
00450     }
00451 
00452     void                Release         () const
00453     {
00454 #ifdef DEBUG
00455         st_ReleaseBreakpint( this );
00456 #endif        
00457 
00458         tASSERT ( this && refCtr_ >= 0 );
00459         mutex_.acquire();
00460         --refCtr_;
00461         mutex_.release();
00462 
00463         if ( refCtr_ <= 0 )
00464         {
00465             refCtr_ = -1000;
00466             delete static_cast< const T* >( this );
00467         }
00468     }
00469 
00470     int                 GetRefcount     () const
00471     {
00472         tASSERT( this );
00473         return refCtr_;
00474     }
00475 protected:
00476     ~tReferencable()
00477     {
00478         tASSERT( this && ( refCtr_ == -1000 || refCtr_ == 0 ) );
00479         refCtr_ = -1000;
00480     }
00481 private:
00482     mutable int refCtr_;
00483     mutable MUTEX mutex_;
00484 };
00485 
00486 
00487 #endif
00488 
00489 
00490 

Generated on Sat Mar 15 22:56:02 2008 for Armagetron Advanced by  doxygen 1.5.4