00001 // @(#)root/minuit2:$Id: MnRefCountedPointer.h 20880 2007-11-19 11:23:41Z rdm $ 00002 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT * 00007 * * 00008 **********************************************************************/ 00009 00010 #ifndef ROOT_Minuit2_MnRefCountedPointer 00011 #define ROOT_Minuit2_MnRefCountedPointer 00012 00013 #include "MnReferenceCounter.h" 00014 00015 namespace ROOT { 00016 00017 namespace Minuit2 { 00018 00019 00020 template<class T> class MnRefCountedPointer { 00021 00022 public: 00023 00024 // Default constructor needed for use inside array, vector, etc. 00025 MnRefCountedPointer() : fPtr(0), fCounter(0) {} 00026 00027 MnRefCountedPointer(T* pt) : 00028 fPtr(pt), fCounter(new MnReferenceCounter()) {AddReference();} 00029 00030 MnRefCountedPointer(const MnRefCountedPointer<T>& other) : 00031 fPtr(other.fPtr), fCounter(other.fCounter) {AddReference();} 00032 00033 ~MnRefCountedPointer() { 00034 /* 00035 if(References() == 0) { 00036 if(fPtr) delete fPtr; 00037 if(fCounter) delete fCounter; 00038 } 00039 else RemoveReference(); 00040 */ 00041 if(References() != 0) RemoveReference(); 00042 } 00043 00044 bool IsValid() const {return fPtr != 0;} 00045 00046 MnRefCountedPointer& operator=(const MnRefCountedPointer<T>& other) { 00047 if(fPtr != other.fPtr) { 00048 RemoveReference(); 00049 fPtr = other.fPtr; 00050 fCounter = other.fCounter; 00051 AddReference(); 00052 } 00053 return *this; 00054 } 00055 00056 MnRefCountedPointer& operator=(T* ptr) { 00057 if(fPtr != ptr) { 00058 fPtr = ptr; 00059 fCounter = new MnReferenceCounter(); 00060 } 00061 return *this; 00062 } 00063 00064 T* Get() const {return fPtr;} 00065 00066 T* operator->() const {DoCheck(); return fPtr;} 00067 00068 T& operator*() const {DoCheck(); return *fPtr;} 00069 00070 bool operator==(const T* otherP) const {return fPtr == otherP;} 00071 00072 bool operator<(const T* otherP) const {return fPtr < otherP;} 00073 00074 unsigned int References() const {return fCounter->References();} 00075 00076 void AddReference() const {fCounter->AddReference();} 00077 00078 void RemoveReference() { 00079 fCounter->RemoveReference(); 00080 if(References() == 0) { 00081 delete fPtr; fPtr=0; 00082 delete fCounter; fCounter=0; 00083 } 00084 } 00085 00086 private: 00087 00088 T* fPtr; 00089 MnReferenceCounter* fCounter; 00090 00091 private: 00092 00093 void DoCheck() const {assert(IsValid());} 00094 }; 00095 00096 } // namespace Minuit2 00097 00098 } // namespace ROOT 00099 00100 #endif // ROOT_Minuit2_MnRefCountedPointer