boo/include/boo/BooObject.hpp

55 lines
1.6 KiB
C++

#ifndef BOOOBJECT_HPP
#define BOOOBJECT_HPP
#include <atomic>
#include <mutex>
namespace boo
{
class IObj
{
std::atomic_int m_refCount = {0};
protected:
virtual ~IObj() = default;
public:
virtual std::unique_lock<std::recursive_mutex> destructorLock()=0;
void increment() { m_refCount++; }
void decrement()
{
if (m_refCount.fetch_sub(1) == 1)
{
auto lk = destructorLock();
delete this;
}
}
};
template<class SubCls>
class ObjToken
{
SubCls* m_obj = nullptr;
public:
ObjToken() = default;
ObjToken(SubCls* obj) : m_obj(obj) { if (m_obj) m_obj->increment(); }
ObjToken(const ObjToken& other) : m_obj(other.m_obj) { if (m_obj) m_obj->increment(); }
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
ObjToken& operator=(SubCls* obj)
{ if (m_obj) m_obj->decrement(); m_obj = obj; if (m_obj) m_obj->increment(); return *this; }
ObjToken& operator=(const ObjToken& other)
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; if (m_obj) m_obj->increment(); return *this; }
ObjToken& operator=(ObjToken&& other)
{ if (m_obj) m_obj->decrement(); m_obj = other.m_obj; other.m_obj = nullptr; return *this; }
~ObjToken() { if (m_obj) m_obj->decrement(); }
SubCls* get() const { return m_obj; }
SubCls* operator->() const { return m_obj; }
SubCls& operator*() const { return *m_obj; }
template<class T> T* cast() const { return static_cast<T*>(m_obj); }
operator bool() const { return m_obj != nullptr; }
void reset() { if (m_obj) m_obj->decrement(); m_obj = nullptr; }
};
}
#endif // BOOOBJECT_HPP