ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ReferenceCountedHandle.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ReferenceCountedHandle.hh
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 //
27 //
28 //
29 // Class G4ReferenceCountedHandle
30 //
31 // Class description:
32 //
33 // A class to provide reference counting mechanism.
34 // It is a templated class, acting as a smart pointer,
35 // wrapping the type to be counted. It performs the reference counting
36 // during the life-time of the counted object. When its count reaches zero
37 // the counted object is destroyed by explicit call to its destructor.
38 // This class provides overloaded operators *() and ->() to allow similar
39 // syntax as for the normal "dumb" pointers.
40 // The basic rule for the use of this class is that a handle must always
41 // be exchanged by reference never dinamically allocated (i.e. never
42 // instantiated using 'new').
43 // The validity of a smart pointer object can be verified by using the
44 // operator !() or operator bool(). I.e.:
45 // if( !smartPtrObj ) { ... } // Problem! We must initialize it first!
46 // else { ... } // OK!
47 // Trying to 'delete' a smart pointer object will generate a compilation
48 // error (since we're dealing with objects, not pointers!).
49 
50 // Author: Radovan Chytracek, CERN (Radovan.Chytracek@cern.ch)
51 // Date: November 2001
52 // ----------------------------------------------------------------------
53 #ifndef _G4REFERENCECOUNTEDHANDLE_H_
54 #define _G4REFERENCECOUNTEDHANDLE_H_ 1
55 
56 #include "G4Types.hh"
57 #include "G4Allocator.hh"
58 
59 template <class X> class G4CountedObject;
60 
61 template <class X>
63 {
64 
65 public: // with description
66 
67  inline G4ReferenceCountedHandle( X* rep = 0 );
68  // Constructor.
69 
71  // Copy constructor.
72 
74  // Destructor.
75 
77  // Assignment operator by reference.
78 
79  inline G4ReferenceCountedHandle<X>& operator =( X* objPtr );
80  // Assignment operator by pointer.
81 
82  inline unsigned int Count() const;
83  // Forward to Counter class.
84 
85  inline X* operator ->() const;
86  // Operator -> allowing the access to counted object.
87  // The check for 0-ness is left out for performance reasons,
88  // see operator () below.
89  // May be called on initialised smart-pointer only!
90 
91  inline G4bool operator !() const;
92  // Validity test operator.
93 
94  inline operator bool() const;
95  // Boolean operator.
96 
97  inline X* operator ()() const;
98  // Functor operator (for convenience).
99 
100  // There is no provision that this class is subclassed.
101  // If it is subclassed & new data members are added then the
102  // following "new" & "delete" will fail and give errors.
103  //
104  inline void* operator new( size_t );
105  // Operator new defined for G4Allocator.
106 
107  inline void operator delete( void *pObj );
108  // Operator delete defined for G4Allocator.
109 
110 private:
111 
113  // The object subject to reference counting.
114 };
115 
116 extern G4GLOB_DLL
118 
119 template <class X>
120 class G4CountedObject
121 {
122 
124 
125 public: // with description
126 
127  G4CountedObject( X* pObj = 0 );
128  // Constructor.
129 
131  // Destructor.
132 
133  inline void AddRef();
134  // Increase the count.
135 
136  inline void Release();
137  // Decrease the count and if zero destroy itself.
138 
139  // There is no provision that this class is subclassed.
140  // If it is subclassed & new data members are added then the
141  // following "new" & "delete" will fail and give errors.
142  //
143  inline void* operator new( size_t );
144  // Operator new defined for G4Allocator.
145 
146  inline void operator delete( void *pObj );
147  // operator delete defined for G4Allocator.
148 
149 private:
150 
151  unsigned int fCount;
152  // Reference counter.
153  X* fRep;
154  // The counted object.
155 };
156 
157 extern G4GLOB_DLL
159 
160 // --------- G4CountedObject<X> Inline function definitions ---------
161 
162 template <class X>
164  : fCount(0), fRep( pObj )
165 {
166  if( pObj != 0 ) fCount = 1;
167 }
168 
169 template <class X>
171 {
172  delete fRep;
173 }
174 
175 template <class X>
177 {
178  ++fCount;
179 }
180 
181 template <class X>
183 {
184  if( --fCount == 0 ) delete this;
185 }
186 
187 template <class X>
188 void* G4CountedObject<X>::operator new( size_t )
189 {
192  return( (void *)aCountedObjectAllocator()->MallocSingle() );
193 }
194 
195 template <class X>
196 void G4CountedObject<X>::operator delete( void *pObj )
197 {
198  aCountedObjectAllocator()->FreeSingle( (G4CountedObject<void>*)pObj );
199 }
200 
201 // --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
202 
203 template <class X>
206  : fObj( 0 )
207 {
208  if( rep != 0 )
209  fObj = new G4CountedObject<X>( rep );
210 }
211 
212 template <class X>
215  : fObj( right.fObj )
216 {
217  fObj->AddRef();
218 }
219 
220 template <class X>
222 {
223  if( fObj ) fObj->Release();
224 }
225 
226 template <class X>
229 {
230  if( fObj != right.fObj )
231  {
232  if( fObj )
233  fObj->Release();
234  this->fObj = right.fObj;
235  fObj->AddRef();
236  }
237  return *this;
238 }
239 
240 template <class X>
242  operator =( X* objPtr )
243 {
244  if( fObj )
245  fObj->Release();
246  this->fObj = new G4CountedObject<X>( objPtr );
247  return *this;
248 }
249 
250 template <class X>
252 {
253  return( fObj ? fObj->fCount : 0 );
254 }
255 
256 template <class X>
258 {
259  return( fObj ? fObj->fRep : 0 );
260 }
261 
262 template <class X>
264 {
265  return( ( !fObj ) ? true : false );
266 }
267 
268 template <class X>
270 {
271  return( ( fObj ) ? true : false );
272 }
273 
274 template <class X>
276 {
277  return( fObj ? fObj->fRep : 0 );
278 }
279 
280 template <class X>
282 {
283  if (!aRCHAllocator())
285  return( (void *)aRCHAllocator()->MallocSingle() );
286 }
287 
288 template <class X>
289 void G4ReferenceCountedHandle<X>::operator delete( void *pObj )
290 {
291  aRCHAllocator()->FreeSingle( (G4ReferenceCountedHandle<void>*)pObj );
292 }
293 
294 #endif // _G4REFERENCECOUNTEDHANDLE_H_