G4ReferenceCountedHandle.hh

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // Class G4ReferenceCountedHandle
00031 //
00032 // Class description:
00033 //
00034 // A class to provide reference counting mechanism.
00035 // It is a templated class, acting as a smart pointer,
00036 // wrapping the type to be counted. It performs the reference counting
00037 // during the life-time of the counted object. When its count reaches zero
00038 // the counted object is destroyed by explicit call to its destructor.
00039 // This class provides overloaded operators *() and ->() to allow similar
00040 // syntax as for the normal "dumb" pointers.
00041 // The basic rule for the use of this class is that a handle must always
00042 // be exchanged by reference never dinamically allocated (i.e. never
00043 // instantiated using 'new').
00044 // The validity of a smart pointer object can be verified by using the
00045 // operator !() or operator bool(). I.e.:
00046 //    if( !smartPtrObj ) { ... } // Problem! We must initialize it first!
00047 //    else               { ... } // OK!
00048 // Trying to 'delete' a smart pointer object will generate a compilation
00049 // error (since we're dealing with objects, not pointers!).
00050 
00051 // Author:      Radovan Chytracek, CERN  (Radovan.Chytracek@cern.ch)
00052 // Version:     3.0
00053 // Date:        November 2001
00054 // ----------------------------------------------------------------------
00055 #ifndef _G4REFERENCECOUNTEDHANDLE_H_
00056 #define _G4REFERENCECOUNTEDHANDLE_H_ 1
00057 
00058 #include "G4Allocator.hh"
00059 
00060 template <class X> class G4CountedObject;
00061 
00062 template <class X>
00063 class G4ReferenceCountedHandle
00064 {
00065 
00066 public:  // with description
00067 
00068   inline G4ReferenceCountedHandle( X* rep = 0 );
00069     // Constructor.
00070   
00071   inline G4ReferenceCountedHandle( const G4ReferenceCountedHandle<X>& right );
00072     // Copy constructor.
00073   
00074   inline ~G4ReferenceCountedHandle();
00075     // Destructor.
00076   
00077   inline G4ReferenceCountedHandle<X>&
00078     operator =( const G4ReferenceCountedHandle<X>& right );
00079     // Assignment operator by reference.
00080   
00081   inline G4ReferenceCountedHandle<X>& operator =( X* objPtr );
00082     // Assignment operator by pointer.
00083   
00084   inline unsigned int Count() const;
00085     // Forward to Counter class.
00086   
00087   inline X* operator ->() const;
00088     // Operator -> allowing the access to counted object.
00089     // The check for 0-ness is left out for performance reasons,
00090     // see operator () below.
00091     // May be called on initialised smart-pointer only!
00092   
00093   inline G4bool operator !() const;
00094     // Validity test operator.
00095   
00096   inline operator bool() const;
00097     // Boolean operator.
00098   
00099   inline X* operator ()() const;
00100     // Functor operator (for convenience).
00101   
00102   // There is no provision that this class is subclassed.
00103   // If it is subclassed & new data members are added then the
00104   // following "new" & "delete" will fail and give errors. 
00105   //
00106   inline void* operator new( size_t );
00107     // Operator new defined for G4Allocator.
00108   
00109   inline void operator delete( void *pObj );
00110     // Operator delete defined for G4Allocator.
00111 
00112 public:
00113 
00114 #ifdef G4RF_DEBUG
00115   void* operator new( size_t, void *pObj );
00116     // This is required on some compilers (Windows/VC++, Linux/g++) when this
00117     // class is used in the context of STL container. It generates a warning
00118     // saying something about not existing correspondent delete...
00119 #endif
00120 
00121 private:
00122 
00123   G4CountedObject<X>*     fObj;
00124     // The object subject to reference counting.
00125 };
00126 
00127 #ifdef G4GLOB_ALLOC_EXPORT
00128   extern G4DLLEXPORT G4Allocator<G4ReferenceCountedHandle<void> > aRCHAllocator;
00129 #else
00130   extern G4DLLIMPORT G4Allocator<G4ReferenceCountedHandle<void> > aRCHAllocator;
00131 #endif
00132 
00133 template <class X>
00134 class G4CountedObject
00135 {
00136 
00137   friend class G4ReferenceCountedHandle<X>;
00138 
00139 public:  // with description
00140 
00141   G4CountedObject( X* pObj = 0 );
00142     // Constructor.
00143 
00144   ~G4CountedObject();
00145     // Destructor.
00146 
00147   inline void AddRef();
00148     // Increase the count.
00149 
00150   inline void Release();
00151     // Decrease the count and if zero destroy itself.
00152   
00153   // There is no provision that this class is subclassed.
00154   // If it is subclassed & new data members are added then the
00155   // following "new" & "delete" will fail and give errors.
00156   //
00157   inline void* operator new( size_t );
00158     // Operator new defined for G4Allocator.
00159 
00160   inline void operator delete( void *pObj );
00161     // operator delete defined for G4Allocator.
00162 
00163 private:
00164 
00165   unsigned int fCount;
00166     // Reference counter.
00167   X* fRep;
00168     // The counted object.
00169 };
00170 
00171 #ifdef G4GLOB_ALLOC_EXPORT
00172   extern G4DLLEXPORT G4Allocator<G4CountedObject<void> > aCountedObjectAllocator;
00173 #else
00174   extern G4DLLIMPORT G4Allocator<G4CountedObject<void> > aCountedObjectAllocator;
00175 #endif
00176 
00177 // --------- G4CountedObject<X> Inline function definitions ---------
00178 
00179 template <class X>
00180 G4CountedObject<X>::G4CountedObject( X* pObj )
00181  : fCount(0), fRep( pObj )
00182 {
00183     if( pObj != 0 ) {
00184       fCount = 1;
00185     }
00186 }
00187 
00188 template <class X>
00189 G4CountedObject<X>::~G4CountedObject()
00190 {
00191     delete fRep;
00192 }
00193     
00194 template <class X>
00195 void G4CountedObject<X>::AddRef()
00196 {
00197     ++fCount;
00198 }
00199     
00200 template <class X>
00201 void G4CountedObject<X>::Release()
00202 {
00203     if( --fCount == 0 ) delete this;
00204 }
00205 
00206 template <class X>
00207 void* G4CountedObject<X>::operator new( size_t )
00208 {
00209     return( (void *)aCountedObjectAllocator.MallocSingle() );
00210 }
00211     
00212 template <class X>
00213 void G4CountedObject<X>::operator delete( void *pObj )
00214 {
00215     aCountedObjectAllocator.FreeSingle( (G4CountedObject<void>*)pObj );
00216 }
00217 
00218 // --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
00219 
00220 template <class X>
00221 G4ReferenceCountedHandle<X>::
00222  G4ReferenceCountedHandle( X* rep )
00223  : fObj( 0 )
00224 {
00225   if( rep != 0 ) {
00226       fObj = new G4CountedObject<X>( rep );
00227   }
00228 }
00229 
00230 template <class X>
00231 G4ReferenceCountedHandle<X>::
00232  G4ReferenceCountedHandle( const G4ReferenceCountedHandle<X>& right )
00233  : fObj( right.fObj )
00234 {
00235     fObj->AddRef();
00236 }
00237   
00238 template <class X>
00239 G4ReferenceCountedHandle<X>::~G4ReferenceCountedHandle()
00240 {
00241     if( fObj ) fObj->Release();
00242 }
00243   
00244 template <class X>
00245 G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::
00246  operator =( const G4ReferenceCountedHandle<X>& right )
00247 {
00248     if( fObj != right.fObj ) {
00249       if( fObj )
00250         fObj->Release();
00251       this->fObj = right.fObj;
00252       fObj->AddRef();
00253     }
00254     return *this;
00255 }
00256   
00257 template <class X>
00258 G4ReferenceCountedHandle<X>& G4ReferenceCountedHandle<X>::
00259  operator =( X* objPtr )
00260 {
00261     if( fObj )
00262       fObj->Release();
00263     this->fObj = new  G4CountedObject<X>( objPtr );
00264     return *this;
00265 }
00266   
00267 template <class X>
00268 unsigned int G4ReferenceCountedHandle<X>::Count() const
00269 {
00270     return( fObj ? fObj->fCount : 0 );
00271 }
00272   
00273 template <class X>
00274 X* G4ReferenceCountedHandle<X>::operator ->() const
00275 {
00276     return( fObj ? fObj->fRep : 0 );
00277 }
00278   
00279 template <class X>
00280 G4bool G4ReferenceCountedHandle<X>::operator !() const
00281 {
00282     return( ( !fObj ) ? true : false );
00283 }
00284   
00285 template <class X>
00286 G4ReferenceCountedHandle<X>::operator bool() const
00287 {
00288     return( ( fObj ) ? true : false );
00289 }
00290   
00291 template <class X>
00292 X* G4ReferenceCountedHandle<X>::operator ()() const
00293 {
00294     return( fObj ? fObj->fRep : 0 );
00295 }
00296   
00297 template <class X>
00298 void* G4ReferenceCountedHandle<X>::operator new( size_t )
00299 {
00300     return( (void *)aRCHAllocator.MallocSingle() );
00301 }
00302   
00303 template <class X>
00304 void G4ReferenceCountedHandle<X>::operator delete( void *pObj )
00305 {
00306     aRCHAllocator.FreeSingle( (G4ReferenceCountedHandle<void>*)pObj );
00307 }
00308 
00309 #ifdef G4RF_DEBUG
00310 template <class X>
00311 void* G4ReferenceCountedHandle<X>::operator new( size_t, void *pObj )
00312 {
00313     return pObj;
00314 }
00315 #endif
00316 
00317 #endif // _G4REFERENCECOUNTEDHANDLE_H_
00318 

Generated on Mon May 27 17:49:42 2013 for Geant4 by  doxygen 1.4.7