CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DataFormats/GeometrySurface/interface/ReferenceCounted.h

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