Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ReferenceCountedHandle.hh
Go to the documentation of this file.
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
55template <class X>
56class G4CountedObject;
57
58template <class X>
60{
61 public:
62 inline G4ReferenceCountedHandle(X* rep = nullptr);
63 // Constructor.
64
66 // Copy constructor.
67
69 // Destructor.
70
72 const G4ReferenceCountedHandle<X>& right);
73 // Assignment operator by reference.
74
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
112
113template <class X>
115{
116 friend class G4ReferenceCountedHandle<X>;
117
118 public:
119 G4CountedObject(X* pObj = nullptr);
120 // Constructor.
121
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
150
151// --------- G4CountedObject<X> Inline function definitions ---------
152
153template <class X>
155 : fRep(pObj)
156{
157 if(pObj != nullptr)
158 fCount = 1;
159}
160
161template <class X>
163{
164 delete fRep;
165}
166
167template <class X>
169{
170 ++fCount;
171}
172
173template <class X>
175{
176 if(--fCount == 0)
177 delete this;
178}
179
180template <class X>
181void* G4CountedObject<X>::operator new(std::size_t)
182{
183 if(aCountedObjectAllocator() == nullptr)
185 return ((void*) aCountedObjectAllocator()->MallocSingle());
186}
187
188template <class X>
189void G4CountedObject<X>::operator delete(void* pObj)
190{
191 aCountedObjectAllocator()->FreeSingle((G4CountedObject<void>*) pObj);
192}
193
194// --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
195
196template <class X>
198{
199 if(rep != nullptr)
200 fObj = new G4CountedObject<X>(rep);
201}
202
203template <class X>
205 const G4ReferenceCountedHandle<X>& right)
206 : fObj(right.fObj)
207{
208 fObj->AddRef();
209}
210
211template <class X>
213{
214 if(fObj != nullptr)
215 fObj->Release();
216}
217
218template <class X>
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
232template <class X>
234{
235 if(fObj != nullptr)
236 fObj->Release();
237 this->fObj = new G4CountedObject<X>(objPtr);
238 return *this;
239}
240
241template <class X>
243{
244 return ((fObj != nullptr) ? fObj->fCount : 0);
245}
246
247template <class X>
249{
250 return ((fObj != nullptr) ? fObj->fRep : 0);
251}
252
253template <class X>
255{
256 return fObj == nullptr;
257}
258
259template <class X>
261{
262 return fObj != nullptr;
263}
264
265template <class X>
267{
268 return ((fObj != nullptr) ? fObj->fRep : nullptr);
269}
270
271template <class X>
273{
274 if(aRCHAllocator() == nullptr)
276 return ((void*) aRCHAllocator()->MallocSingle());
277}
278
279template <class X>
281{
282 aRCHAllocator()->FreeSingle((G4ReferenceCountedHandle<void>*) pObj);
283}
284
285#endif
G4GLOB_DLL G4Allocator< G4CountedObject< void > > *& aCountedObjectAllocator()
G4GLOB_DLL G4Allocator< G4ReferenceCountedHandle< void > > *& aRCHAllocator()
#define G4GLOB_DLL
Definition: G4Types.hh:70
bool G4bool
Definition: G4Types.hh:86
G4CountedObject(X *pObj=nullptr)
G4ReferenceCountedHandle< X > & operator=(X *objPtr)
G4ReferenceCountedHandle< X > & operator=(const G4ReferenceCountedHandle< X > &right)
G4ReferenceCountedHandle(const G4ReferenceCountedHandle< X > &right)