Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/management/include/G4ReferenceCountedHandle.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // G4ReferenceCountedHandle
 27 //
 28 // Class description:
 29 //
 30 // A class to provide reference counting mechanism.
 31 // It is a templated class, acting as a smart pointer,
 32 // wrapping the type to be counted. It performs the reference counting
 33 // during the life-time of the counted object. When its count reaches zero
 34 // the counted object is destroyed by explicit call to its destructor.
 35 // This class provides overloaded operators *() and ->() to allow similar
 36 // syntax as for the normal "dumb" pointers.
 37 // The basic rule for the use of this class is that a handle must always
 38 // be exchanged by reference never dinamically allocated (i.e. never
 39 // instantiated using 'new').
 40 // The validity of a smart pointer object can be verified by using the
 41 // operator !() or operator bool(). I.e.:
 42 //    if( !smartPtrObj ) { ... } // Problem! We must initialize it first!
 43 //    else               { ... } // OK!
 44 // Trying to 'delete' a smart pointer object will generate a compilation
 45 // error (since we're dealing with objects, not pointers!).
 46 
 47 // Author: Radovan Chytracek, CERN - November 2001
 48 // --------------------------------------------------------------------
 49 #ifndef G4REFERENCECOUNTEDHANDLE_HH
 50 #define G4REFERENCECOUNTEDHANDLE_HH 1
 51 
 52 #include "G4Allocator.hh"
 53 #include "G4Types.hh"
 54 
 55 template <class X>
 56 class G4CountedObject;
 57 
 58 template <class X>
 59 class G4ReferenceCountedHandle
 60 {
 61  public:
 62   inline G4ReferenceCountedHandle(X* rep = nullptr);
 63   // Constructor.
 64 
 65   inline G4ReferenceCountedHandle(const G4ReferenceCountedHandle<X>& right);
 66   // Copy constructor.
 67 
 68   inline ~G4ReferenceCountedHandle();
 69   // Destructor.
 70 
 71   inline G4ReferenceCountedHandle<X>& operator=(
 72     const G4ReferenceCountedHandle<X>& right);
 73   // Assignment operator by reference.
 74 
 75   inline G4ReferenceCountedHandle<X>& operator=(X* objPtr);
 76   // Assignment operator by pointer.
 77 
 78   inline unsigned int Count() const;
 79   // Forward to Counter class.
 80 
 81   inline X* operator->() const;
 82   // Operator -> allowing the access to counted object.
 83   // The check for 0-ness is left out for performance reasons,
 84   // see operator () below.
 85   // May be called on initialised smart-pointer only!
 86 
 87   inline G4bool operator!() const;
 88   // Validity test operator.
 89 
 90   inline operator bool() const;
 91   // Boolean operator.
 92 
 93   inline X* operator()() const;
 94   // Functor operator (for convenience).
 95 
 96   // There is no provision that this class is subclassed.
 97   // If it is subclassed & new data members are added then the
 98   // following "new" & "delete" will fail and give errors.
 99   //
100   inline void* operator new(std::size_t);
101   // Operator new defined for G4Allocator.
102 
103   inline void operator delete(void* pObj);
104   // Operator delete defined for G4Allocator.
105 
106  private:
107   G4CountedObject<X>* fObj = nullptr;
108   // The object subject to reference counting.
109 };
110 
111 extern G4GLOB_DLL G4Allocator<G4ReferenceCountedHandle<void>>*& aRCHAllocator();
112 
113 template <class X>
114 class G4CountedObject
115 {
116   friend class G4ReferenceCountedHandle<X>;
117 
118  public:
119   G4CountedObject(X* pObj = nullptr);
120   // Constructor.
121 
122   ~G4CountedObject();
123   // Destructor.
124 
125   inline void AddRef();
126   // Increase the count.
127 
128   inline void Release();
129   // Decrease the count and if zero destroy itself.
130 
131   // There is no provision that this class is subclassed.
132   // If it is subclassed & new data members are added then the
133   // following "new" & "delete" will fail and give errors.
134   //
135   inline void* operator new(std::size_t);
136   // Operator new defined for G4Allocator.
137 
138   inline void operator delete(void* pObj);
139   // operator delete defined for G4Allocator.
140 
141  private:
142   unsigned int fCount = 0;
143   // Reference counter.
144   X* fRep = nullptr;
145   // The counted object.
146 };
147 
148 extern G4GLOB_DLL G4Allocator<G4CountedObject<void>>*&
149 aCountedObjectAllocator();
150 
151 // --------- G4CountedObject<X> Inline function definitions ---------
152 
153 template <class X>
154 G4CountedObject<X>::G4CountedObject(X* pObj)
155   : fRep(pObj)
156 {
157   if(pObj != nullptr)
158     fCount = 1;
159 }
160 
161 template <class X>
162 G4CountedObject<X>::~G4CountedObject()
163 {
164   delete fRep;
165 }
166 
167 template <class X>
168 void G4CountedObject<X>::AddRef()
169 {
170   ++fCount;
171 }
172 
173 template <class X>
174 void G4CountedObject<X>::Release()
175 {
176   if(--fCount == 0)
177     delete this;
178 }
179 
180 template <class X>
181 void* G4CountedObject<X>::operator new(std::size_t)
182 {
183   if(aCountedObjectAllocator() == nullptr)
184     aCountedObjectAllocator() = new G4Allocator<G4CountedObject<void>>;
185   return ((void*) aCountedObjectAllocator()->MallocSingle());
186 }
187 
188 template <class X>
189 void G4CountedObject<X>::operator delete(void* pObj)
190 {
191   aCountedObjectAllocator()->FreeSingle((G4CountedObject<void>*) pObj);
192 }
193 
194 // --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
195 
196 template <class X>
197 G4ReferenceCountedHandle<X>::G4ReferenceCountedHandle(X* rep)
198 {
199   if(rep != nullptr)
200     fObj = new G4CountedObject<X>(rep);
201 }
202 
203 template <class X>
204 G4ReferenceCountedHandle<X>::G4ReferenceCountedHandle(
205   const G4ReferenceCountedHandle<X>& right)
206   : fObj(right.fObj)
207 {
208   fObj->AddRef();
209 }
210 
211 template <class X>
212 G4ReferenceCountedHandle<X>::~G4ReferenceCountedHandle()
213 {
214   if(fObj != nullptr)
215     fObj->Release();
216 }
217 
218 template <class X>
219 G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::operator=(
220   const G4ReferenceCountedHandle<X>& right)
221 {
222   if(fObj != right.fObj)
223   {
224     if(fObj != nullptr)
225       fObj->Release();
226     this->fObj = right.fObj;
227     fObj->AddRef();
228   }
229   return *this;
230 }
231 
232 template <class X>
233 G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::operator=(X* objPtr)
234 {
235   if(fObj != nullptr)
236     fObj->Release();
237   this->fObj = new G4CountedObject<X>(objPtr);
238   return *this;
239 }
240 
241 template <class X>
242 unsigned int G4ReferenceCountedHandle<X>::Count() const
243 {
244   return ((fObj != nullptr) ? fObj->fCount : 0);
245 }
246 
247 template <class X>
248 X* G4ReferenceCountedHandle<X>::operator->() const
249 {
250   return ((fObj != nullptr) ? fObj->fRep : 0);
251 }
252 
253 template <class X>
254 G4bool G4ReferenceCountedHandle<X>::operator!() const
255 {
256   return fObj == nullptr;
257 }
258 
259 template <class X>
260 G4ReferenceCountedHandle<X>::operator bool() const
261 {
262   return fObj != nullptr;
263 }
264 
265 template <class X>
266 X* G4ReferenceCountedHandle<X>::operator()() const
267 {
268   return ((fObj != nullptr) ? fObj->fRep : nullptr);
269 }
270 
271 template <class X>
272 void* G4ReferenceCountedHandle<X>::operator new(std::size_t)
273 {
274   if(aRCHAllocator() == nullptr)
275     aRCHAllocator() = new G4Allocator<G4ReferenceCountedHandle<void>>;
276   return ((void*) aRCHAllocator()->MallocSingle());
277 }
278 
279 template <class X>
280 void G4ReferenceCountedHandle<X>::operator delete(void* pObj)
281 {
282   aRCHAllocator()->FreeSingle((G4ReferenceCountedHandle<void>*) pObj);
283 }
284 
285 #endif
286