CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/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 #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