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