Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:59:02

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4ReferenceCountedHandle
0027 //
0028 // Class description:
0029 //
0030 // A class to provide reference counting mechanism.
0031 // It is a templated class, acting as a smart pointer,
0032 // wrapping the type to be counted. It performs the reference counting
0033 // during the life-time of the counted object. When its count reaches zero
0034 // the counted object is destroyed by explicit call to its destructor.
0035 // This class provides overloaded operators *() and ->() to allow similar
0036 // syntax as for the normal "dumb" pointers.
0037 // The basic rule for the use of this class is that a handle must always
0038 // be exchanged by reference never dinamically allocated (i.e. never
0039 // instantiated using 'new').
0040 // The validity of a smart pointer object can be verified by using the
0041 // operator !() or operator bool(). I.e.:
0042 //    if( !smartPtrObj ) { ... } // Problem! We must initialize it first!
0043 //    else               { ... } // OK!
0044 // Trying to 'delete' a smart pointer object will generate a compilation
0045 // error (since we're dealing with objects, not pointers!).
0046 
0047 // Author: Radovan Chytracek, CERN - November 2001
0048 // --------------------------------------------------------------------
0049 #ifndef G4REFERENCECOUNTEDHANDLE_HH
0050 #define G4REFERENCECOUNTEDHANDLE_HH 1
0051 
0052 #include "G4Allocator.hh"
0053 #include "G4Types.hh"
0054 
0055 template <class X>
0056 class G4CountedObject;
0057 
0058 template <class X>
0059 class G4ReferenceCountedHandle
0060 {
0061  public:
0062   inline G4ReferenceCountedHandle(X* rep = nullptr);
0063   // Constructor.
0064 
0065   inline G4ReferenceCountedHandle(const G4ReferenceCountedHandle<X>& right);
0066   // Copy constructor.
0067 
0068   inline ~G4ReferenceCountedHandle();
0069   // Destructor.
0070 
0071   inline G4ReferenceCountedHandle<X>& operator=(
0072     const G4ReferenceCountedHandle<X>& right);
0073   // Assignment operator by reference.
0074 
0075   inline G4ReferenceCountedHandle<X>& operator=(X* objPtr);
0076   // Assignment operator by pointer.
0077 
0078   inline unsigned int Count() const;
0079   // Forward to Counter class.
0080 
0081   inline X* operator->() const;
0082   // Operator -> allowing the access to counted object.
0083   // The check for 0-ness is left out for performance reasons,
0084   // see operator () below.
0085   // May be called on initialised smart-pointer only!
0086 
0087   inline G4bool operator!() const;
0088   // Validity test operator.
0089 
0090   inline operator bool() const;
0091   // Boolean operator.
0092 
0093   inline X* operator()() const;
0094   // Functor operator (for convenience).
0095 
0096   // There is no provision that this class is subclassed.
0097   // If it is subclassed & new data members are added then the
0098   // following "new" & "delete" will fail and give errors.
0099   //
0100   inline void* operator new(std::size_t);
0101   // Operator new defined for G4Allocator.
0102 
0103   inline void operator delete(void* pObj);
0104   // Operator delete defined for G4Allocator.
0105 
0106  private:
0107   G4CountedObject<X>* fObj = nullptr;
0108   // The object subject to reference counting.
0109 };
0110 
0111 extern G4GLOB_DLL G4Allocator<G4ReferenceCountedHandle<void>>*& aRCHAllocator();
0112 
0113 template <class X>
0114 class G4CountedObject
0115 {
0116   friend class G4ReferenceCountedHandle<X>;
0117 
0118  public:
0119   G4CountedObject(X* pObj = nullptr);
0120   // Constructor.
0121 
0122   ~G4CountedObject();
0123   // Destructor.
0124 
0125   inline void AddRef();
0126   // Increase the count.
0127 
0128   inline void Release();
0129   // Decrease the count and if zero destroy itself.
0130 
0131   // There is no provision that this class is subclassed.
0132   // If it is subclassed & new data members are added then the
0133   // following "new" & "delete" will fail and give errors.
0134   //
0135   inline void* operator new(std::size_t);
0136   // Operator new defined for G4Allocator.
0137 
0138   inline void operator delete(void* pObj);
0139   // operator delete defined for G4Allocator.
0140 
0141  private:
0142   unsigned int fCount = 0;
0143   // Reference counter.
0144   X* fRep = nullptr;
0145   // The counted object.
0146 };
0147 
0148 extern G4GLOB_DLL G4Allocator<G4CountedObject<void>>*&
0149 aCountedObjectAllocator();
0150 
0151 // --------- G4CountedObject<X> Inline function definitions ---------
0152 
0153 template <class X>
0154 G4CountedObject<X>::G4CountedObject(X* pObj)
0155   : fRep(pObj)
0156 {
0157   if(pObj != nullptr)
0158     fCount = 1;
0159 }
0160 
0161 template <class X>
0162 G4CountedObject<X>::~G4CountedObject()
0163 {
0164   delete fRep;
0165 }
0166 
0167 template <class X>
0168 void G4CountedObject<X>::AddRef()
0169 {
0170   ++fCount;
0171 }
0172 
0173 template <class X>
0174 void G4CountedObject<X>::Release()
0175 {
0176   if(--fCount == 0)
0177     delete this;
0178 }
0179 
0180 template <class X>
0181 void* G4CountedObject<X>::operator new(std::size_t)
0182 {
0183   if(aCountedObjectAllocator() == nullptr)
0184     aCountedObjectAllocator() = new G4Allocator<G4CountedObject<void>>;
0185   return ((void*) aCountedObjectAllocator()->MallocSingle());
0186 }
0187 
0188 template <class X>
0189 void G4CountedObject<X>::operator delete(void* pObj)
0190 {
0191   aCountedObjectAllocator()->FreeSingle((G4CountedObject<void>*) pObj);
0192 }
0193 
0194 // --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
0195 
0196 template <class X>
0197 G4ReferenceCountedHandle<X>::G4ReferenceCountedHandle(X* rep)
0198 {
0199   if(rep != nullptr)
0200     fObj = new G4CountedObject<X>(rep);
0201 }
0202 
0203 template <class X>
0204 G4ReferenceCountedHandle<X>::G4ReferenceCountedHandle(
0205   const G4ReferenceCountedHandle<X>& right)
0206   : fObj(right.fObj)
0207 {
0208   fObj->AddRef();
0209 }
0210 
0211 template <class X>
0212 G4ReferenceCountedHandle<X>::~G4ReferenceCountedHandle()
0213 {
0214   if(fObj != nullptr)
0215     fObj->Release();
0216 }
0217 
0218 template <class X>
0219 G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::operator=(
0220   const G4ReferenceCountedHandle<X>& right)
0221 {
0222   if(fObj != right.fObj)
0223   {
0224     if(fObj != nullptr)
0225       fObj->Release();
0226     this->fObj = right.fObj;
0227     fObj->AddRef();
0228   }
0229   return *this;
0230 }
0231 
0232 template <class X>
0233 G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::operator=(X* objPtr)
0234 {
0235   if(fObj != nullptr)
0236     fObj->Release();
0237   this->fObj = new G4CountedObject<X>(objPtr);
0238   return *this;
0239 }
0240 
0241 template <class X>
0242 unsigned int G4ReferenceCountedHandle<X>::Count() const
0243 {
0244   return ((fObj != nullptr) ? fObj->fCount : 0);
0245 }
0246 
0247 template <class X>
0248 X* G4ReferenceCountedHandle<X>::operator->() const
0249 {
0250   return ((fObj != nullptr) ? fObj->fRep : 0);
0251 }
0252 
0253 template <class X>
0254 G4bool G4ReferenceCountedHandle<X>::operator!() const
0255 {
0256   return fObj == nullptr;
0257 }
0258 
0259 template <class X>
0260 G4ReferenceCountedHandle<X>::operator bool() const
0261 {
0262   return fObj != nullptr;
0263 }
0264 
0265 template <class X>
0266 X* G4ReferenceCountedHandle<X>::operator()() const
0267 {
0268   return ((fObj != nullptr) ? fObj->fRep : nullptr);
0269 }
0270 
0271 template <class X>
0272 void* G4ReferenceCountedHandle<X>::operator new(std::size_t)
0273 {
0274   if(aRCHAllocator() == nullptr)
0275     aRCHAllocator() = new G4Allocator<G4ReferenceCountedHandle<void>>;
0276   return ((void*) aRCHAllocator()->MallocSingle());
0277 }
0278 
0279 template <class X>
0280 void G4ReferenceCountedHandle<X>::operator delete(void* pObj)
0281 {
0282   aRCHAllocator()->FreeSingle((G4ReferenceCountedHandle<void>*) pObj);
0283 }
0284 
0285 #endif