2020-04-19 19:46:37 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
// Simple lightweight reference counting pointer alternative for std::shared_ptr which stores the reference counter in the handled object itself.
|
2021-08-14 08:04:45 +00:00
|
|
|
|
2021-10-30 07:34:38 +00:00
|
|
|
// Base class for handled objects
|
2020-04-19 19:46:37 +00:00
|
|
|
class RefCountedBase
|
|
|
|
{
|
|
|
|
public:
|
2021-08-14 08:04:45 +00:00
|
|
|
void IncRef() { refCount++; }
|
|
|
|
void DecRef() { if (--refCount <= 0) delete this; }
|
2020-04-19 19:46:37 +00:00
|
|
|
private:
|
2021-08-14 08:04:45 +00:00
|
|
|
int refCount = 0;
|
2020-04-19 19:46:37 +00:00
|
|
|
protected:
|
2021-08-14 08:04:45 +00:00
|
|
|
virtual ~RefCountedBase() = default;
|
2020-04-19 19:46:37 +00:00
|
|
|
};
|
2021-08-14 08:04:45 +00:00
|
|
|
|
|
|
|
// The actual pointer object
|
2020-04-19 19:46:37 +00:00
|
|
|
template<class T>
|
|
|
|
class RefCountedPtr
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~RefCountedPtr()
|
|
|
|
{
|
|
|
|
if (ptr) ptr->DecRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
RefCountedPtr() : ptr(nullptr)
|
|
|
|
{}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
explicit RefCountedPtr(T* p) : ptr(p)
|
|
|
|
{
|
|
|
|
if (ptr) ptr->IncRef();
|
|
|
|
}
|
2021-08-14 08:04:45 +00:00
|
|
|
|
|
|
|
RefCountedPtr(const RefCountedPtr& r) : ptr(r.ptr)
|
|
|
|
{
|
|
|
|
if (ptr) ptr->IncRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
RefCountedPtr(RefCountedPtr&& r) : ptr(r.ptr)
|
|
|
|
{
|
|
|
|
r.ptr = nullptr;
|
|
|
|
}
|
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
RefCountedPtr & operator=(const RefCountedPtr& r)
|
|
|
|
{
|
2021-08-14 08:04:45 +00:00
|
|
|
if (this != &r)
|
2020-04-19 19:46:37 +00:00
|
|
|
{
|
|
|
|
if (ptr) ptr->DecRef();
|
|
|
|
ptr = r.ptr;
|
|
|
|
if (ptr) ptr->IncRef();
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
RefCountedPtr& operator=(T* r)
|
|
|
|
{
|
|
|
|
if (ptr != r)
|
|
|
|
{
|
|
|
|
if (ptr) ptr->DecRef();
|
|
|
|
ptr = r;
|
|
|
|
if (ptr) ptr->IncRef();
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-08-14 08:04:45 +00:00
|
|
|
RefCountedPtr & operator=(RefCountedPtr&& r)
|
2020-04-19 19:46:37 +00:00
|
|
|
{
|
2021-08-14 08:04:45 +00:00
|
|
|
if (this != &r)
|
|
|
|
{
|
|
|
|
if (ptr) ptr->DecRef();
|
|
|
|
ptr = r.ptr;
|
|
|
|
r.ptr = nullptr;
|
|
|
|
}
|
2020-04-19 19:46:37 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(T* p) const
|
|
|
|
{
|
|
|
|
return ptr == p;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(T* p) const
|
|
|
|
{
|
|
|
|
return ptr != p;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const RefCountedPtr &p) const
|
|
|
|
{
|
|
|
|
return ptr == p.ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const RefCountedPtr& p) const
|
|
|
|
{
|
|
|
|
return ptr != p.ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
T& operator* () const
|
|
|
|
{
|
|
|
|
return *ptr;
|
|
|
|
}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
T* operator-> () const
|
|
|
|
{
|
|
|
|
return ptr;
|
|
|
|
}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
T* get() const
|
|
|
|
{
|
|
|
|
return ptr;
|
|
|
|
}
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
private:
|
2021-12-30 09:30:21 +00:00
|
|
|
|
2020-04-19 19:46:37 +00:00
|
|
|
T * ptr;
|
|
|
|
};
|