00001 #ifndef Tracker_ProxyBase_H 00002 #define Tracker_ProxyBase_H 00003 00004 #include "TrackingTools/TrajectoryParametrization/interface/TrajectoryStateExceptions.h" 00005 #include "TrackingTools/TrajectoryState/interface/CopyUsingNew.h" 00006 00016 template <class T, class Cloner > 00017 class ProxyBase { 00018 public: 00019 00020 ProxyBase() : theData(0) {} 00021 00022 ProxyBase( T* p) : theData(p) {if (theData) theData->addReference();} 00023 00024 ProxyBase( const ProxyBase& other) { 00025 theData = other.theData; 00026 if (theData) theData->addReference(); 00027 } 00028 00029 virtual ~ProxyBase() { 00030 destroy(); 00031 } 00032 00033 ProxyBase& operator=( const ProxyBase& other) { 00034 if ( theData != other.theData) { 00035 destroy(); 00036 theData = other.theData; 00037 if (theData) theData->addReference(); 00038 } 00039 return *this; 00040 } 00041 00042 00043 void swap(ProxyBase& other) { 00044 std::swap(theData,other.theData); 00045 } 00046 00047 00048 #if defined( __GXX_EXPERIMENTAL_CXX0X__) 00049 ProxyBase(ProxyBase&& other) { 00050 theData = other.theData; 00051 other.theData=0; 00052 } 00053 00054 ProxyBase& operator=(ProxyBase&& other) { 00055 if ( theData != other.theData) { 00056 destroy(); 00057 theData = other.theData; 00058 other.theData=0; 00059 } 00060 return *this; 00061 } 00062 #endif 00063 00064 const T& data() const { check(); return *theData;} 00065 00066 T& unsharedData() { 00067 check(); 00068 if ( references() > 1) { 00069 theData->removeReference(); 00070 theData = Cloner().clone( *theData); 00071 if (theData) theData->addReference(); 00072 } 00073 return *theData; 00074 } 00075 00076 T& sharedData() { check(); return *theData;} 00077 00078 bool isValid() const { return theData != 0;} 00079 00080 void check() const { 00081 if (theData == 0) 00082 throw TrajectoryStateException("Error: uninitialized ProxyBase used"); 00083 } 00084 00085 void destroy() { if (isValid()) theData->removeReference();} 00086 00087 int references() const {return theData->references();} 00088 00089 private: 00090 T* theData; 00091 }; 00092 00093 template <class T, class Cloner > 00094 inline 00095 void swap(ProxyBase<T,Cloner>& lh, const ProxyBase<T,Cloner>& rh) { 00096 lh.swap(rh); 00097 } 00098 00099 #endif // Tracker_ProxyBase_H