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.11 2010/12/16 13:59:22 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 #define CMSSW_POOLALLOCATOR 00089 00090 #ifdef CMSSW_POOLALLOCATOR 00091 #include "DataFormats/GeometrySurface/interface/BlockWipedAllocator.h" 00092 #else 00093 template<typename T> 00094 struct LocalCache { 00095 std::auto_ptr<T> ptr; 00096 }; 00097 00098 #endif 00099 00100 class ReferenceCountedPoolAllocated 00101 #ifdef CMSSW_POOLALLOCATOR 00102 : public BlockWipedPoolAllocated 00103 #endif 00104 { 00105 00106 public: 00107 static int s_alive; 00108 static int s_referenced; 00109 00110 ReferenceCountedPoolAllocated() : referenceCount_(0) { 00111 s_alive++; 00112 } 00113 00114 ReferenceCountedPoolAllocated( const ReferenceCountedPoolAllocated& iRHS ) : referenceCount_(0) { 00115 s_alive++; 00116 } 00117 00118 const ReferenceCountedPoolAllocated& operator=( const ReferenceCountedPoolAllocated& ) { 00119 return *this; 00120 } 00121 00122 virtual ~ReferenceCountedPoolAllocated() { 00123 s_alive--; 00124 } 00125 00126 // ---------- const member functions --------------------- 00127 00128 void addReference() const { ++referenceCount_ ; s_referenced++; } 00129 void removeReference() const { 00130 s_referenced--; 00131 if( 0 == --referenceCount_ ) { 00132 delete const_cast<ReferenceCountedPoolAllocated*>(this); 00133 } 00134 } 00135 00136 unsigned int references() const {return referenceCount_;} 00137 00138 // ---------- static member functions -------------------- 00139 00140 // ---------- member functions --------------------------- 00141 00142 private: 00143 00144 // ---------- member data -------------------------------- 00145 mutable unsigned int referenceCount_; 00146 }; 00147 00148 inline void intrusive_ptr_add_ref( const ReferenceCountedPoolAllocated* iRef ) { 00149 iRef->addReference(); 00150 } 00151 00152 inline void intrusive_ptr_release( const ReferenceCountedPoolAllocated* iRef ) { 00153 iRef->removeReference(); 00154 } 00155 00156 // condition uses naive RefCount 00157 typedef BasicReferenceCounted ReferenceCountedInConditions; 00158 00159 00160 // transient objects in algo and events are "poo allocated" 00161 typedef ReferenceCountedPoolAllocated ReferenceCountedInEvent; 00162 00163 // just to avoid changing all around 00164 // typedef ReferenceCountedPoolAllocated ReferenceCounted; 00165 typedef BasicReferenceCounted ReferenceCounted; 00166 00167 00168 00169 #endif /* SURFACE_REFERENCECOUNTED_H */