diff options
Diffstat (limited to 'Examples/test-suite/refcount.h')
| -rw-r--r-- | Examples/test-suite/refcount.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/Examples/test-suite/refcount.h b/Examples/test-suite/refcount.h new file mode 100644 index 0000000..7d07e72 --- /dev/null +++ b/Examples/test-suite/refcount.h @@ -0,0 +1,198 @@ +#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__ |
