source: trunk/source/global/management/include/G4ReferenceCountedHandle.hh @ 833

Last change on this file since 833 was 833, checked in by garnier, 16 years ago

import all except CVS

File size: 8.9 KB
Line 
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// $Id: G4ReferenceCountedHandle.hh,v 1.15 2006/06/29 19:02:46 gunter Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// Class G4ReferenceCountedHandle
32//
33// Class description:
34//
35// A class to provide reference counting mechanism.
36// It is a templated class, acting as a smart pointer,
37// wrapping the type to be counted. It performs the reference counting
38// during the life-time of the counted object. When its count reaches zero
39// the counted object is destroyed by explicit call to its destructor.
40// This class provides overloaded operators *() and ->() to allow similar
41// syntax as for the normal "dumb" pointers.
42// The basic rule for the use of this class is that a handle must always
43// be exchanged by reference never dinamically allocated (i.e. never
44// instantiated using 'new').
45// The validity of a smart pointer object can be verified by using the
46// operator !() or operator bool(). I.e.:
47//    if( !smartPtrObj ) { ... } // Problem! We must initialize it first!
48//    else               { ... } // OK!
49// Trying to 'delete' a smart pointer object will generate a compilation
50// error (since we're dealing with objects, not pointers!).
51
52// Author:      Radovan Chytracek, CERN  (Radovan.Chytracek@cern.ch)
53// Version:     3.0
54// Date:        November 2001
55// ----------------------------------------------------------------------
56#ifndef _G4REFERENCECOUNTEDHANDLE_H_
57#define _G4REFERENCECOUNTEDHANDLE_H_ 1
58
59#include "G4Allocator.hh"
60
61template <class X> class G4CountedObject;
62
63template <class X>
64class G4ReferenceCountedHandle
65{
66
67public:  // with description
68
69  inline G4ReferenceCountedHandle( X* rep = 0 );
70    // Constructor.
71 
72  inline G4ReferenceCountedHandle( const G4ReferenceCountedHandle<X>& right );
73    // Copy constructor.
74 
75  inline ~G4ReferenceCountedHandle();
76    // Destructor.
77 
78  inline G4ReferenceCountedHandle<X>&
79    operator =( const G4ReferenceCountedHandle<X>& right );
80    // Assignment operator by reference.
81 
82  inline G4ReferenceCountedHandle<X>& operator =( X* objPtr );
83    // Assignment operator by pointer.
84 
85  inline unsigned int Count() const;
86    // Forward to Counter class.
87 
88  inline X* operator ->() const;
89    // Operator -> allowing the access to counted object.
90    // The check for 0-ness is left out for performance reasons,
91    // see operator () below.
92    // May be called on initialised smart-pointer only!
93 
94  inline G4bool operator !() const;
95    // Validity test operator.
96 
97  inline operator bool() const;
98    // Boolean operator.
99 
100  inline X* operator ()() const;
101    // Functor operator (for convenience).
102 
103  // There is no provision that this class is subclassed.
104  // If it is subclassed & new data members are added then the
105  // following "new" & "delete" will fail and give errors.
106  //
107  inline void* operator new( size_t );
108    // Operator new defined for G4Allocator.
109 
110  inline void operator delete( void *pObj );
111    // Operator delete defined for G4Allocator.
112
113public:
114
115#ifdef G4RF_DEBUG
116  void* operator new( size_t, void *pObj );
117    // This is required on some compilers (Windows/VC++, Linux/g++) when this
118    // class is used in the context of STL container. It generates a warning
119    // saying something about not existing correspondent delete...
120#endif
121
122private:
123
124  G4CountedObject<X>*     fObj;
125    // The object subject to reference counting.
126
127  static G4Allocator<G4ReferenceCountedHandle<X> > aRCHAllocator;
128};
129
130template <class X>
131class G4CountedObject
132{
133
134  friend class G4ReferenceCountedHandle<X>;
135
136public:  // with description
137
138  G4CountedObject( X* pObj = 0 );
139    // Constructor.
140
141  ~G4CountedObject();
142    // Destructor.
143
144  inline void AddRef();
145    // Increase the count.
146
147  inline void Release();
148    // Decrease the count and if zero destroy itself.
149 
150  // There is no provision that this class is subclassed.
151  // If it is subclassed & new data members are added then the
152  // following "new" & "delete" will fail and give errors.
153  //
154  inline void* operator new( size_t );
155    // Operator new defined for G4Allocator.
156
157  inline void operator delete( void *pObj );
158    // operator delete defined for G4Allocator.
159
160private:
161
162  unsigned int fCount;
163    // Reference counter.
164  X* fRep;
165    // The counted object.
166
167  static G4Allocator<G4CountedObject<X> > aCountedObjectAllocator;
168};
169
170
171// --------- G4CountedObject<X> Inline function definitions ---------
172
173template <class X>
174G4CountedObject<X>::G4CountedObject( X* pObj )
175 : fCount(0), fRep( pObj )
176{
177    if( pObj != 0 ) {
178      fCount = 1;
179    }
180}
181
182template <class X>
183G4CountedObject<X>::~G4CountedObject()
184{
185    delete fRep;
186}
187   
188template <class X>
189void G4CountedObject<X>::AddRef()
190{
191    ++fCount;
192}
193   
194template <class X>
195void G4CountedObject<X>::Release()
196{
197    if( --fCount == 0 ) delete this;
198}
199
200template <class X>
201void* G4CountedObject<X>::operator new( size_t )
202{
203    return( (void *)aCountedObjectAllocator.MallocSingle() );
204}
205   
206template <class X>
207void G4CountedObject<X>::operator delete( void *pObj )
208{
209    aCountedObjectAllocator.FreeSingle( (G4CountedObject<X>*)pObj );
210}
211
212// --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
213
214template <class X>
215G4ReferenceCountedHandle<X>::
216 G4ReferenceCountedHandle( X* rep )
217 : fObj( 0 )
218{
219  if( rep != 0 ) {
220      fObj = new G4CountedObject<X>( rep );
221  }
222}
223
224template <class X>
225G4ReferenceCountedHandle<X>::
226 G4ReferenceCountedHandle( const G4ReferenceCountedHandle<X>& right )
227 : fObj( right.fObj )
228{
229    fObj->AddRef();
230}
231 
232template <class X>
233G4ReferenceCountedHandle<X>::~G4ReferenceCountedHandle()
234{
235    if( fObj ) fObj->Release();
236}
237 
238template <class X>
239G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::
240 operator =( const G4ReferenceCountedHandle<X>& right )
241{
242    if( fObj != right.fObj ) {
243      if( fObj )
244        fObj->Release();
245      this->fObj = right.fObj;
246      fObj->AddRef();
247    }
248    return *this;
249}
250 
251template <class X>
252G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::
253 operator =( X* objPtr )
254{
255    if( fObj )
256      fObj->Release();
257    this->fObj = new  G4CountedObject<X>( objPtr );
258    return *this;
259}
260 
261template <class X>
262unsigned int G4ReferenceCountedHandle<X>::Count() const
263{
264    return( fObj ? fObj->fCount : 0 );
265}
266 
267template <class X>
268X* G4ReferenceCountedHandle<X>::operator ->() const
269{
270    return( fObj ? fObj->fRep : 0 );
271}
272 
273template <class X>
274G4bool G4ReferenceCountedHandle<X>::operator !() const
275{
276    return( ( !fObj ) ? true : false );
277}
278 
279template <class X>
280G4ReferenceCountedHandle<X>::operator bool() const
281{
282    return( ( fObj ) ? true : false );
283}
284 
285template <class X>
286X* G4ReferenceCountedHandle<X>::operator ()() const
287{
288    return( fObj ? fObj->fRep : 0 );
289}
290 
291template <class X>
292void* G4ReferenceCountedHandle<X>::operator new( size_t )
293{
294    return( (void *)aRCHAllocator.MallocSingle() );
295}
296 
297template <class X>
298void G4ReferenceCountedHandle<X>::operator delete( void *pObj )
299{
300    aRCHAllocator.FreeSingle( (G4ReferenceCountedHandle<X>*)pObj );
301}
302
303#ifdef G4RF_DEBUG
304template <class X>
305void* G4ReferenceCountedHandle<X>::operator new( size_t, void *pObj )
306{
307    return pObj;
308}
309#endif
310
311// ------------------ Static allocators definitions -----------------
312
313template <class X>
314G4Allocator<G4CountedObject<X> >
315  G4CountedObject<X>::aCountedObjectAllocator;
316
317template <class X>
318G4Allocator<G4ReferenceCountedHandle<X> >
319  G4ReferenceCountedHandle<X>::aRCHAllocator;
320
321#endif // _G4REFERENCECOUNTEDHANDLE_H_
322
Note: See TracBrowser for help on using the repository browser.