/***************************************************************************
reference.t - Reference is a template class
that allows C++ to manage references to classes
as a smart pointer might, detecting when a reference
is destroyed and decrementing the reference count
on the instance. Once the reference count reaches
zero then the memory is cleaned up.
warnings : Crippled, reference count can wrap in certain C++ semantic conditions.
-------------------
begin :
1998
copyright :
email :
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef POINTER_HEADER_
#define POINTER_HEADER_
#include
#ifdef WIN32
#include
#else
#include
#endif
#include
#include
#include
#ifndef NULL
#define NULL 0x00000000
#endif
// #define _CDEBUG_ 1
//--------------------------------------------------------------------
template class Reference
{
// Constructors and destructor
public:
Reference() : _ref(NULL) { }
Reference(T* ptr_) : _ref(ptr_) { IncrRefCount(); }
Reference(void * ptr_) : _ref((T*)ptr_)
{ if ( _ref!=NULL) IncrRefCount(); }
Reference( const Reference &other )
{ _ref=other._ref;
if ( _ref!=NULL )
IncrRefCount();
}
virtual ~Reference()
{
if ( _ref!=NULL )
DecrRefCount();
}
Reference & operator = ( Reference ptr_ )
{
if ( _ref != NULL )
DecrRefCount( );
_ref=ptr_._ref;
if ( _ref!=NULL )
IncrRefCount();
return *this;
}
Reference & operator = (T* ptr_)
{
if ( _ref != NULL )
DecrRefCount( );
_ref=ptr_;
if ( _ref!=NULL )
IncrRefCount();
return *this;
}
T* operator -> () { assert(_ref!=NULL); return _ref; }
T& operator * () { assert(_ref!=NULL); return *_ref; }
operator T* () { assert(_ref!=NULL); return _ref; }
bool operator == (Reference ptr) { return _ref == ptr._ref; }
bool operator != (Reference ptr) { return _ref != ptr._ref; }
bool operator == (T* ptr_) { return _ref == ptr_; }
bool operator != (T* ptr_) { return _ref != ptr_; }
// Shallow copy cloning, to deep copy clone override
// the clone method on Object
static T* clone( Reference ptr )
{
T* retval = (T*)malloc( sizeof(T) );
memcpy(retval,ptr._ref,sizeof(T));
retval->clone(ptr._ref);
return retval;
}
bool const isNull() { return _ref == NULL; }
long const getRefCount() { return _ref->refcount(); }
T* getPointer() { return _ref; }
T* recast() { return _ref; }
T* getPointerForceIncref( ) { IncrRefCount(); return _ref; }
private:
void IncrRefCount()
{
if ( _ref!=NULL )
{
#ifdef _CDEBUG_
gBytesCount=gBytesCount+sizeof(T);
#endif
_ref->incref( );
}
}
void DecrRefCount()
{
if ( _ref!=NULL )
{
#ifdef _CDEBUG_
gBytesCount=gBytesCount-sizeof(T);
#endif
_ref->decref( );
if ( _ref->refcount() == 0 )
{
// printf("%d->del()\n",_ref);
_ref->mark_deleted( );
delete _ref;
#ifdef _CDEBUG_
gFreedCount=gFreedCount+sizeof(T);
cerr << typeid(this).name()
<< " Active bytes:" << gBytesCount
<< " Freed bytes:" << gFreedCount << endl;
#endif
}
_ref = NULL;
}
}
#ifdef _CDEBUG_
static unsigned long gBytesCount;
static unsigned long gFreedCount;
#endif
private:
T* _ref;
};
#ifdef _CDEBUG_
template
unsigned long Reference::gBytesCount=0;
template
unsigned long Reference::gFreedCount=0;
#endif
#endif