Files
geant4/examples/extended/gdml/libgdml/saxana/include/RCObjectHandle.hh
T
2016-06-08 16:57:27 +02:00

233 lines
7.3 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: RCObjectHandle.hh,v 1.2 2002/06/03 12:09:33 radoone Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------
// Comments
//
// --------------------------------------------------------------
//
// Class RCObjectHandle
// Class description:
// A class to provide reference counting mechanism for a class which
// is designed without this support. It is a templated class, a smart pointer,
// wrapping the class to be counted and performs the reference counting
// during the life-time of the counted object. When its count goes to zero
// the counted object is destroyed by explicit call to its destructor.
// This class provides overloaded operators *() and ->() to make the
// maniplutation syntax the same as for the normal "dumb" pointers.
// The basic rule for the use of this class is that it is passed always by
// reference and is not constructed by calling new.
// Before the use of this smart pointer object one can test its validity
// using the operator !() or operator bool().
// if( !smartPtrObj ) { ... } // Problem! We must initialize it first!
// else { ... } // OK!
// The code which tries to delete this object won't compile, because it is
// not a pointer it is an object.
// Author: Radovan Chytracek
// Version: 1.0
// Date: June 2001
// ----------------------------------------------------------------------
#ifndef RC_OBJECT_HANDLE_H
#define RC_OBJECT_HANDLE_H 1
template <class X>
class RCObjectHandle
{
public:
typedef RCObjectHandle RCH;
private: // with description
class CountedObject {
public:
inline CountedObject( X* pObj = 0 )
: fCount(1), fRep( pObj ) {
} // Constructor
inline ~CountedObject() {
delete fRep;
fRep = 0;
} // Destructor
inline X* GetObject() const {
return fRep;
}
inline void SetObject( const X* object ) {
fRep = object;
}
inline unsigned int AddRef() {
return( ++fCount );
} // Forward to Counter class
inline unsigned int Release() {
return( ( fCount > 0 ) ? --fCount : 0 );
} // Forward to Counter class
inline unsigned int Count() const {
return( fCount );
} // Forward to Counter class
private:
unsigned int fCount;
// Reference counter
X* fRep;
// The counted object
};
public: // with description
RCObjectHandle( X* rep = 0 )
: fObj( 0 ) {
if( rep != 0 ) {
fObj = new RCH::CountedObject( rep );
}
} // Constructor
~RCObjectHandle() {
if( 0 == Release() ) {
if( fObj != 0 ) {
delete fObj;
fObj = 0;
}
}
} // Destructor
RCObjectHandle( const RCObjectHandle& right )
: fObj( 0 ) {
fObj = right.GetCountedObject();
AddRef();
} // Copy constructor
template <class T>
RCObjectHandle( const RCObjectHandle<T>& right )
: fObj( 0 ) {
fObj = right.GetCountedObject();
AddRef();
} // Copy constructor
RCObjectHandle& operator =( const RCObjectHandle& right ) {
if( this->fObj != right.GetCountedObject() ) {
if( 0 == this->Release() ) {
if( this->fObj != 0 ) {
delete this->fObj;
}
}
this->fObj = right.GetCountedObject();
this->AddRef();
}
return *this;
} // Assignment operator by reference
template <class T>
RCObjectHandle& operator=( const RCObjectHandle<T>& right ) {
if( this->fObj != right.GetCountedObject() ) {
if( 0 == this->Release() ) {
if( this->fObj != 0 ) {
delete this->fObj;
}
}
this->fObj = right.GetCountedObject();
this->AddRef();
}
return *this;
} // Assignment operator by reference
RCObjectHandle& operator =( const RCObjectHandle* right ) {
if( this->fObj != right->GetCountedObject() ) {
if( 0 == this->Release() ) {
if( this->fObj != 0 ) {
delete this->fObj;
}
}
this->fObj = right->GetCountedObject();
this->AddRef();
}
return *this;
} // Assignment operator by pointer, should not be ever called
RCObjectHandle& operator =( X* pRefObj ) {
if( this->fObj == 0 || pRefObj != this->fObj->GetObject() ) {
if( 0 == Release() ) {
if( fObj != 0 ) {
delete fObj;
}
}
fObj = new RCH::CountedObject( pRefObj );
}
return *this;
} // Assignment operator by pointer to the counted class object
RCH::CountedObject* GetCountedObject() const {
return fObj;
}
inline unsigned int AddRef() {
return( ( fObj != 0 ) ? fObj->AddRef() : 0 );
} // Forward to Counter class
inline unsigned int Release() {
return( (fObj != 0 ) ? fObj->Release() : 0 );
} // Forward to Counter class
inline unsigned int Count() const {
return( ( fObj != 0 ) ? fObj->Count() : 0 );
} // Forward to Counter class
X* operator ->() const {
return( ( fObj != 0 ) ? fObj->GetObject() : 0 );
} // Operator -> allowing the access to counted object
// The check for 0-ness is left out for performance reasons, see operator () bellow
// May be called on initialized smart-pointer only!
bool operator !() const {
return( ( fObj == 0 || fObj->GetObject() == 0 ) ? true : false );
} // Validity test operator
operator bool() const {
return( ( fObj != 0 && fObj->GetObject() != 0 ) ? true : false );
}
X& operator *() const {
return( ( fObj != 0 ) ? *(fObj->GetObject()) : 0 );
} // Dereference operator to make the feeling of dereferencing a pointer to
// the counted object
// May be called on initialized smart-pointer only!
X* operator ()() const {
return( ( fObj != 0 ) ? fObj->GetObject() : 0 );
} // Functor operator (for covinience)
private:
RCH::CountedObject* fObj;
// Object being the subject to reference counting
};
#endif // RC_OBJECT_HANDLE_H