mirror of https://github.com/swig/swig
199 lines
2.9 KiB
C++
199 lines
2.9 KiB
C++
#ifndef TEST_SUITE_REFCOUNT_H
|
|
#define TEST_SUITE_REFCOUNT_H
|
|
|
|
struct RCObjBase {
|
|
/*!
|
|
Return the numbers of active references.
|
|
|
|
\return The internal \c refCount value.
|
|
*/
|
|
int ref_count() const
|
|
{
|
|
return refCount;
|
|
}
|
|
|
|
/*!
|
|
Add one reference.
|
|
|
|
\return The reference counter value.
|
|
*/
|
|
int addref() const
|
|
{
|
|
return add_ref();
|
|
}
|
|
|
|
/*!
|
|
Delete one reference. If the refCount is zero, the
|
|
object is deleted.
|
|
|
|
\return The reference counter value, which can be zero after
|
|
deletion.
|
|
*/
|
|
int delref() const
|
|
{
|
|
if (ref_count() == 0 || del_ref() == 0 )
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return ref_count();
|
|
}
|
|
|
|
protected:
|
|
RCObjBase();
|
|
RCObjBase(const RCObjBase& );
|
|
virtual ~RCObjBase() = 0;
|
|
|
|
private:
|
|
|
|
RCObjBase& operator=(const RCObjBase& );
|
|
|
|
friend struct RCObj;
|
|
|
|
int add_ref() const
|
|
{
|
|
return ++refCount;
|
|
}
|
|
|
|
int del_ref() const
|
|
{
|
|
return --refCount;
|
|
}
|
|
|
|
mutable int refCount;
|
|
};
|
|
|
|
struct RCObj : virtual RCObjBase {
|
|
protected:
|
|
RCObj()
|
|
{
|
|
}
|
|
};
|
|
|
|
/*! Reference an RCObj object
|
|
\return The input pointer \a r
|
|
*/
|
|
template <class T>
|
|
inline
|
|
T* addref(T* r)
|
|
{
|
|
return (r && r->addref() ) ? r : 0;
|
|
}
|
|
|
|
/*! Unreference an RCObj object.
|
|
\return The input pointer \a r or nil if the object was deleted.
|
|
*/
|
|
template <class T>
|
|
inline
|
|
T* delref(T* r)
|
|
{
|
|
return ( r && r->delref() ) ? r : 0;
|
|
}
|
|
|
|
|
|
|
|
RCObjBase::RCObjBase()
|
|
: refCount(0)
|
|
{
|
|
}
|
|
|
|
|
|
RCObjBase::~RCObjBase()
|
|
{
|
|
}
|
|
|
|
RCObjBase::RCObjBase(const RCObjBase&)
|
|
: refCount(0)
|
|
{
|
|
}
|
|
|
|
|
|
RCObjBase& RCObjBase::operator=(const RCObjBase&)
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
|
|
template <class T>
|
|
struct RCPtr {
|
|
typedef T* pointer_type;
|
|
typedef T& refernce_type;
|
|
typedef T value_type;
|
|
|
|
RCPtr();
|
|
RCPtr(T* realPtr);
|
|
RCPtr(const RCPtr& rhs);
|
|
|
|
~RCPtr();
|
|
|
|
RCPtr& operator=(const RCPtr& rhs);
|
|
|
|
RCPtr& operator=(T* realPtr);
|
|
|
|
T* operator->() { return pointee; }
|
|
T& operator*() { return *pointee; }
|
|
|
|
const T* operator->() const { return pointee; }
|
|
const T& operator*() const { return *pointee; }
|
|
|
|
operator T*() { return pointee; }
|
|
operator T&() { return *pointee; }
|
|
|
|
operator const T*() const { return pointee; }
|
|
operator const T&() const { return *pointee; }
|
|
|
|
T* get() { return pointee; }
|
|
T* get() const { return pointee; }
|
|
|
|
|
|
private:
|
|
T* pointee;
|
|
};
|
|
|
|
|
|
template <class T>
|
|
inline
|
|
RCPtr<T>::RCPtr()
|
|
: pointee(0)
|
|
{
|
|
}
|
|
|
|
template <class T>
|
|
inline
|
|
RCPtr<T>::RCPtr(T* realPtr)
|
|
: pointee(realPtr)
|
|
{
|
|
addref(pointee);
|
|
}
|
|
|
|
template <class T>
|
|
inline
|
|
RCPtr<T>::RCPtr(const RCPtr& rhs)
|
|
: pointee(rhs.pointee)
|
|
{
|
|
addref(pointee);
|
|
}
|
|
|
|
template <class T>
|
|
inline
|
|
RCPtr<T>::~RCPtr()
|
|
{
|
|
delref(pointee);
|
|
}
|
|
|
|
template <class T>
|
|
inline
|
|
RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs)
|
|
{
|
|
if (pointee != rhs.pointee) {
|
|
delref(pointee);
|
|
pointee = rhs.pointee;
|
|
addref(pointee);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
|
|
|
|
#endif // TEST_SUITE_REFCOUNT_H
|