CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_7_hltpatch2/src/TrackingTools/TrajectoryState/interface/ProxyBase.h

Go to the documentation of this file.
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