139 lines
2.5 KiB
C++
139 lines
2.5 KiB
C++
|
|
|
|
#ifndef CLASS_REFCOUNT
|
|
#define CLASS_REFCOUNT
|
|
|
|
template<typename T> class refcounted
|
|
{
|
|
T* ptr;
|
|
size_t* refcount;
|
|
|
|
public:
|
|
refcounted()
|
|
{
|
|
ptr = NULL, refcount = NULL;
|
|
}
|
|
|
|
refcounted(T* _ptr)
|
|
{
|
|
ptr = _ptr;
|
|
|
|
refcount = new size_t(1);
|
|
}
|
|
|
|
refcounted(const refcounted& other):
|
|
ptr(other.ptr),
|
|
refcount(other.refcount)
|
|
{
|
|
VALGRIND_CHECK_VALUE_IS_DEFINED(other.ptr);
|
|
VALGRIND_CHECK_VALUE_IS_DEFINED(other.refcount);
|
|
|
|
if (refcount)
|
|
{
|
|
(*refcount)++;
|
|
}
|
|
}
|
|
|
|
refcounted(refcounted&& other) noexcept :
|
|
ptr(std::move(other.ptr)),
|
|
refcount(std::move(other.refcount))
|
|
{
|
|
;
|
|
}
|
|
|
|
auto begin()
|
|
{
|
|
return ptr->begin();
|
|
}
|
|
|
|
auto end()
|
|
{
|
|
return ptr->end();
|
|
}
|
|
|
|
auto begin() const
|
|
{
|
|
return ptr->begin();
|
|
}
|
|
|
|
auto end() const
|
|
{
|
|
return ptr->end();
|
|
}
|
|
|
|
operator bool() const
|
|
{
|
|
return !!ptr;
|
|
}
|
|
|
|
const T operator*() const
|
|
{
|
|
return *ptr;
|
|
}
|
|
|
|
T* operator->()
|
|
{
|
|
return ptr;
|
|
}
|
|
|
|
const T* operator->() const
|
|
{
|
|
return ptr;
|
|
}
|
|
|
|
auto operator <=> (const struct refcounted& other) const
|
|
{
|
|
return (*(const T*) ptr <=> **other);
|
|
}
|
|
|
|
refcounted& operator=(const refcounted& other)
|
|
{
|
|
if (ptr)
|
|
{
|
|
assert(refcount);
|
|
|
|
if (!--*refcount)
|
|
{
|
|
// decrement the old refcount, possibly free old ptr
|
|
assert(!"TODO");
|
|
}
|
|
}
|
|
|
|
ptr = other.ptr;
|
|
|
|
refcount = other.refcount;
|
|
|
|
if (refcount)
|
|
{
|
|
(*refcount)++;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
~refcounted()
|
|
{
|
|
if (refcount)
|
|
{
|
|
if (!--*refcount)
|
|
{
|
|
delete ptr;
|
|
|
|
delete refcount;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|