Geant4-11
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:
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) ? true : false);
257}
258
259template <class X>
261{
262 return ((fObj != nullptr) ? true : false);
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)