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