forked from KolibriOS/kolibrios
75 lines
2.2 KiB
C
75 lines
2.2 KiB
C
|
#ifndef __refcount_h__
|
||
|
#define __refcount_h__
|
||
|
|
||
|
#include "lispassert.h"
|
||
|
#include "yacasbase.h"
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// RefPtr - Smart pointer for (intrusive) reference counting.
|
||
|
// Simply, an object's reference count is the number of RefPtrs refering to it.
|
||
|
// The RefPtr will delete the referenced object when the count reaches zero.
|
||
|
|
||
|
/*TODO: this might be improved a little by having RefPtr wrap the object being
|
||
|
pointed to so the user of RefPtr does not need to add ReferenceCount explicitly.
|
||
|
One can use RefPtr on any arbitrary object from that moment on.
|
||
|
*/
|
||
|
|
||
|
typedef ReferenceType ReferenceCount;
|
||
|
|
||
|
template<class T>
|
||
|
class RefPtr : public YacasBase // derived, so we can 'NEW LispPtr[nnn]'
|
||
|
{
|
||
|
public:
|
||
|
// Default constructor (not explicit, so it auto-initializes)
|
||
|
inline RefPtr() : iPtr(NULL) {}
|
||
|
// Construct from pointer to T
|
||
|
explicit RefPtr(T *ptr) : iPtr(ptr) { if (ptr) { ptr->iReferenceCount++; } }
|
||
|
// Copy constructor
|
||
|
RefPtr(const RefPtr &refPtr) : iPtr(refPtr.ptr()) { if (iPtr) { iPtr->iReferenceCount++; } }
|
||
|
// Destructor
|
||
|
~RefPtr()
|
||
|
{
|
||
|
if (iPtr)
|
||
|
{
|
||
|
iPtr->iReferenceCount--;
|
||
|
if (iPtr->iReferenceCount == 0)
|
||
|
{
|
||
|
delete iPtr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Assignment from pointer
|
||
|
RefPtr &operator=(T *ptr)
|
||
|
{
|
||
|
if (ptr)
|
||
|
{
|
||
|
ptr->iReferenceCount++;
|
||
|
}
|
||
|
if (iPtr)
|
||
|
{
|
||
|
iPtr->iReferenceCount--;
|
||
|
if (iPtr->iReferenceCount == 0)
|
||
|
{
|
||
|
delete iPtr;
|
||
|
}
|
||
|
}
|
||
|
iPtr = ptr;
|
||
|
return *this;
|
||
|
}
|
||
|
// Assignment from another
|
||
|
RefPtr &operator=(const RefPtr &refPtr) { return this->operator=(refPtr.ptr()); }
|
||
|
|
||
|
operator T*() const { return iPtr; } // implicit conversion to pointer to T
|
||
|
T &operator*() const { return *iPtr; } // so (*refPtr) is a reference to T
|
||
|
T *operator->() const { return iPtr; } // so (refPtr->member) accesses T's member
|
||
|
T *ptr() const { return iPtr; } // so (refPtr.ptr()) returns the pointer to T (boost calls this method 'get')
|
||
|
bool operator!() const { return !iPtr; } // is null pointer
|
||
|
|
||
|
private:
|
||
|
T *iPtr;
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|