![]() |
![]() |
00001 #ifndef SURFACE_REFERENCECOUNTED_H 00002 #define SURFACE_REFERENCECOUNTED_H 00003 // -*- C++ -*- 00004 // 00005 // Package: Surface 00006 // Class : ReferenceCounted 00007 // 00016 // 00017 // Original Author: Chris Jones 00018 // Created: Fri Jul 15 09:17:20 EDT 2005 00019 // $Id: ReferenceCounted.h,v 1.12 2013/01/20 08:09:02 innocent Exp $ 00020 // 00021 00022 // system include files 00023 #include "boost/intrusive_ptr.hpp" 00024 00025 // user include files 00026 00027 // forward declarations 00028 00029 class BasicReferenceCounted 00030 { 00031 00032 public: 00033 BasicReferenceCounted() : referenceCount_(0) {} 00034 BasicReferenceCounted( const BasicReferenceCounted& iRHS ) : referenceCount_(0) {} 00035 00036 const BasicReferenceCounted& operator=( const BasicReferenceCounted& ) { 00037 return *this; 00038 } 00039 virtual ~BasicReferenceCounted() {} 00040 00041 // ---------- const member functions --------------------- 00042 00043 void addReference() const { ++referenceCount_ ; } 00044 void removeReference() const { if( 0 == --referenceCount_ ) { 00045 delete const_cast<BasicReferenceCounted*>(this); 00046 } 00047 } 00048 00049 unsigned int references() const {return referenceCount_;} 00050 00051 // ---------- static member functions -------------------- 00052 00053 // ---------- member functions --------------------------- 00054 00055 private: 00056 00057 // ---------- member data -------------------------------- 00058 mutable unsigned int referenceCount_; 00059 }; 00060 00061 template <class T> class ReferenceCountingPointer : 00062 public boost::intrusive_ptr<T> 00063 { 00064 public: 00065 ReferenceCountingPointer(T* iT) : boost::intrusive_ptr<T>(iT) {} 00066 ReferenceCountingPointer() {} 00067 }; 00068 00069 template <class T> class ConstReferenceCountingPointer : 00070 public boost::intrusive_ptr<const T> 00071 { 00072 public: 00073 ConstReferenceCountingPointer(const T* iT) : boost::intrusive_ptr<const T>(iT) {} 00074 ConstReferenceCountingPointer() {} 00075 ConstReferenceCountingPointer( const ReferenceCountingPointer<T>& other) : 00076 boost::intrusive_ptr<const T>(&(*other)) {} 00077 }; 00078 00079 inline void intrusive_ptr_add_ref( const BasicReferenceCounted* iRef ) { 00080 iRef->addReference(); 00081 } 00082 00083 inline void intrusive_ptr_release( const BasicReferenceCounted* iRef ) { 00084 iRef->removeReference(); 00085 } 00086 00087 00088 // does not increase ref count 00089 // delete if count is 0 (takes owership of orphans ) 00090 // clone if count is 0 00091 // double delete if deleted after the real owner... 00092 template<typename T> 00093 class MixedReference { 00094 explicit MixedReference(T const * ip=nullptr) noexcept : p(ip){} 00095 ~MixedReference() noexcept { destroy();} 00096 00097 #ifndef CMS_NOCXX11 00098 MixedReference( MixedReference&& rh) noexcept : p(rh.p){rh.p=0;} 00099 MixedReference& operator=( MixedReference&& rh) noexcept { 00100 destroy(); 00101 p=rh.p; rh.p=0; 00102 return *this; 00103 } 00104 #endif 00105 00106 MixedReference( MixedReference const & rh) : p(rh.p? rh.p->clone(): nullptr ){} 00107 MixedReference& operator=( MixedReference const & rh) { 00108 if (rh.p!=p) { 00109 destroy(); 00110 p = rh.p? rh.p->clone(): nullptr; 00111 } 00112 return * this; 00113 } 00114 00115 00116 T const * get() const {return p;} 00117 T const & operator*() const { return *p;} 00118 00119 private: 00120 void destroy() noexcept { 00121 if (p && p->references()==0) { delete const_cast<T*>(p); } 00122 } 00123 T const * p; 00124 }; 00125 00126 00127 #define CMSSW_POOLALLOCATOR 00128 00129 #ifdef CMSSW_POOLALLOCATOR 00130 #include "DataFormats/GeometrySurface/interface/BlockWipedAllocator.h" 00131 #else 00132 template<typename T> 00133 struct LocalCache { 00134 std::auto_ptr<T> ptr; 00135 }; 00136 00137 #endif 00138 00139 class ReferenceCountedPoolAllocated 00140 #ifdef CMSSW_POOLALLOCATOR 00141 : public BlockWipedPoolAllocated 00142 #endif 00143 { 00144 00145 public: 00146 static int s_alive; 00147 static int s_referenced; 00148 00149 ReferenceCountedPoolAllocated() : referenceCount_(0) { 00150 s_alive++; 00151 } 00152 00153 ReferenceCountedPoolAllocated( const ReferenceCountedPoolAllocated& iRHS ) : referenceCount_(0) { 00154 s_alive++; 00155 } 00156 00157 const ReferenceCountedPoolAllocated& operator=( const ReferenceCountedPoolAllocated& ) { 00158 return *this; 00159 } 00160 00161 virtual ~ReferenceCountedPoolAllocated() { 00162 s_alive--; 00163 } 00164 00165 // ---------- const member functions --------------------- 00166 00167 void addReference() const { ++referenceCount_ ; s_referenced++; } 00168 void removeReference() const { 00169 s_referenced--; 00170 if( 0 == --referenceCount_ ) { 00171 delete const_cast<ReferenceCountedPoolAllocated*>(this); 00172 } 00173 } 00174 00175 unsigned int references() const {return referenceCount_;} 00176 00177 // ---------- static member functions -------------------- 00178 00179 // ---------- member functions --------------------------- 00180 00181 private: 00182 00183 // ---------- member data -------------------------------- 00184 mutable unsigned int referenceCount_; 00185 }; 00186 00187 inline void intrusive_ptr_add_ref( const ReferenceCountedPoolAllocated* iRef ) { 00188 iRef->addReference(); 00189 } 00190 00191 inline void intrusive_ptr_release( const ReferenceCountedPoolAllocated* iRef ) { 00192 iRef->removeReference(); 00193 } 00194 00195 // condition uses naive RefCount 00196 typedef BasicReferenceCounted ReferenceCountedInConditions; 00197 00198 00199 // transient objects in algo and events are "poo allocated" 00200 typedef ReferenceCountedPoolAllocated ReferenceCountedInEvent; 00201 00202 // just to avoid changing all around 00203 // typedef ReferenceCountedPoolAllocated ReferenceCounted; 00204 typedef BasicReferenceCounted ReferenceCounted; 00205 00206 00207 00208 #endif /* SURFACE_REFERENCECOUNTED_H */