No more shared pointers
This commit is contained in:
+54
-171
@@ -5,13 +5,13 @@
|
||||
#define DEFINE_REF(x) \
|
||||
typedef ::Seele::RefPtr<x> P##x; \
|
||||
typedef ::Seele::UniquePtr<x> UP##x; \
|
||||
typedef ::Seele::WeakPtr<x> W##x;
|
||||
typedef ::Seele::OwningPtr<x> O##x;
|
||||
|
||||
#define DECLARE_REF(x) \
|
||||
class x; \
|
||||
typedef ::Seele::RefPtr<x> P##x; \
|
||||
typedef ::Seele::UniquePtr<x> UP##x; \
|
||||
typedef ::Seele::WeakPtr<x> W##x;
|
||||
typedef ::Seele::OwningPtr<x> O##x;
|
||||
|
||||
|
||||
#define DECLARE_NAME_REF(nmsp, x) \
|
||||
@@ -20,86 +20,63 @@
|
||||
class x; \
|
||||
typedef RefPtr<x> P##x; \
|
||||
typedef UniquePtr<x> UP##x; \
|
||||
typedef WeakPtr<x> W##x; \
|
||||
typedef OwningPtr<x> O##x; \
|
||||
}
|
||||
|
||||
std::map<void*, void*>& getRegisteredObjects();
|
||||
std::mutex& getRegisteredObjectLock();
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template <typename T, typename Deleter>
|
||||
class RefPtr;
|
||||
template <typename T, typename Deleter>
|
||||
class RefObject
|
||||
template <typename T, typename Deleter = std::default_delete<T>>
|
||||
class OwningPtr
|
||||
{
|
||||
public:
|
||||
RefObject(T *ptr, Deleter&& deleter)
|
||||
: handle(ptr)
|
||||
, deleter(std::move(deleter))
|
||||
, refCount(1)
|
||||
OwningPtr()
|
||||
: pointer(nullptr)
|
||||
{
|
||||
}
|
||||
RefObject(const RefObject &rhs) = delete;
|
||||
RefObject(RefObject &&rhs)
|
||||
: handle(std::move(rhs.handle)), refCount(std::move(rhs.refCount))
|
||||
OwningPtr(T* ptr)
|
||||
: pointer(ptr)
|
||||
{}
|
||||
template<typename F>
|
||||
OwningPtr(OwningPtr<F>&& other)
|
||||
{
|
||||
pointer = static_cast<T*>(other.pointer);
|
||||
}
|
||||
~RefObject()
|
||||
OwningPtr(const OwningPtr& other) = delete;
|
||||
OwningPtr(OwningPtr&& other)
|
||||
{
|
||||
pointer = other.pointer;
|
||||
other.pointer = nullptr;
|
||||
}
|
||||
OwningPtr& operator=(const OwningPtr& other) = delete;
|
||||
OwningPtr& operator=(OwningPtr&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
std::scoped_lock lock(getRegisteredObjectLock());
|
||||
getRegisteredObjects().erase(handle);
|
||||
}
|
||||
// #pragma warning( disable: 4150)
|
||||
deleter(handle);
|
||||
handle = nullptr;
|
||||
// #pragma warning( default: 4150)
|
||||
}
|
||||
RefObject &operator=(const RefObject &rhs) = delete;
|
||||
RefObject &operator=(RefObject &&rhs)
|
||||
{
|
||||
if (*this != rhs)
|
||||
{
|
||||
handle = std::move(rhs.handle);
|
||||
refCount = std::move(rhs.refCount);
|
||||
rhs.handle = nullptr;
|
||||
rhs.refCount = 0;
|
||||
pointer = other.pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const RefObject &rhs) const
|
||||
constexpr T* operator->()
|
||||
{
|
||||
return handle == rhs.handle;
|
||||
return pointer;
|
||||
}
|
||||
auto operator<=>(const RefObject& rhs) const
|
||||
constexpr const T* operator->() const
|
||||
{
|
||||
return handle <=> rhs.handle;
|
||||
return pointer;
|
||||
}
|
||||
void addRef()
|
||||
constexpr bool operator==(const OwningPtr& rhs) const noexcept
|
||||
{
|
||||
refCount++;
|
||||
return pointer == rhs.pointer;
|
||||
}
|
||||
void removeRef()
|
||||
constexpr auto operator<=>(const OwningPtr& rhs) const noexcept
|
||||
{
|
||||
refCount--;
|
||||
if (refCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
T *getHandle() const
|
||||
{
|
||||
return handle;
|
||||
return pointer <=> rhs.pointer;
|
||||
}
|
||||
private:
|
||||
T *handle;
|
||||
Deleter deleter;
|
||||
std::atomic_uint64_t refCount;
|
||||
friend class RefPtr<T, Deleter>;
|
||||
T* pointer;
|
||||
};
|
||||
|
||||
template <typename T, typename Deleter = std::default_delete<T>>
|
||||
template <typename T>
|
||||
class RefPtr
|
||||
{
|
||||
public:
|
||||
@@ -111,97 +88,48 @@ public:
|
||||
: object(nullptr)
|
||||
{
|
||||
}
|
||||
RefPtr(T *ptr, Deleter deleter = Deleter())
|
||||
RefPtr(T *ptr)
|
||||
: object(ptr)
|
||||
{
|
||||
std::scoped_lock l(getRegisteredObjectLock());
|
||||
auto registeredObj = getRegisteredObjects().find(ptr);
|
||||
// get here for thread safetly
|
||||
auto registeredEnd = getRegisteredObjects().end();
|
||||
if (registeredObj == registeredEnd)
|
||||
{
|
||||
object = new RefObject<T, Deleter>(ptr, std::move(deleter));
|
||||
getRegisteredObjects()[ptr] = object;
|
||||
}
|
||||
else
|
||||
{
|
||||
object = (RefObject<T, Deleter> *)registeredObj->second;
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
constexpr explicit RefPtr(RefObject<T, Deleter> *other) noexcept
|
||||
: object(other)
|
||||
{
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
constexpr RefPtr(const RefPtr &other) noexcept
|
||||
: object(other.object)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
constexpr RefPtr(RefPtr &&rhs) noexcept
|
||||
: object(std::move(rhs.object))
|
||||
{
|
||||
rhs.object = nullptr;
|
||||
//Dont change references, they stay the same
|
||||
}
|
||||
template <typename F>
|
||||
constexpr RefPtr(const RefPtr<F> &other)
|
||||
{
|
||||
if(other == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
F *f = other.getObject()->getHandle();
|
||||
assert(static_cast<T *>(f));
|
||||
object = (RefObject<T, Deleter> *)other.getObject();
|
||||
object->addRef();
|
||||
object = other.cast<T>();
|
||||
}
|
||||
|
||||
template <typename F, typename DeleterF = std::default_delete<F>>
|
||||
constexpr RefPtr<F, DeleterF> cast()
|
||||
constexpr RefPtr(OwningPtr<T>& owning)
|
||||
{
|
||||
T *t = object->getHandle();
|
||||
object = owning.getHandle();
|
||||
}
|
||||
constexpr RefPtr(const OwningPtr<T>& owning)
|
||||
{
|
||||
object = owning.getHandle();
|
||||
}
|
||||
template <typename F>
|
||||
constexpr const RefPtr<F> cast() const
|
||||
{
|
||||
T *t = object;
|
||||
F *f = dynamic_cast<F *>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F, DeleterF> *newObject = (RefObject<F, DeleterF> *)object;
|
||||
return RefPtr<F, DeleterF>(newObject);
|
||||
return RefPtr<F>(f);
|
||||
}
|
||||
|
||||
template <typename F, typename DeleterF = std::default_delete<F>>
|
||||
constexpr const RefPtr<F, DeleterF> cast() const
|
||||
{
|
||||
T *t = object->getHandle();
|
||||
F *f = dynamic_cast<F *>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F, DeleterF> *newObject = (RefObject<F, DeleterF> *)object;
|
||||
return RefPtr<F, DeleterF>(newObject);
|
||||
}
|
||||
|
||||
constexpr RefPtr &operator=(const RefPtr &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = other.object;
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -209,10 +137,6 @@ public:
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = std::move(rhs.object);
|
||||
rhs.object = nullptr;
|
||||
}
|
||||
@@ -220,10 +144,6 @@ public:
|
||||
}
|
||||
constexpr ~RefPtr()
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
}
|
||||
constexpr bool operator==(const RefPtr& rhs) const noexcept
|
||||
{
|
||||
@@ -235,32 +155,22 @@ public:
|
||||
}
|
||||
constexpr T *operator->()
|
||||
{
|
||||
assert(object != nullptr);
|
||||
return object->handle;
|
||||
return object;
|
||||
}
|
||||
constexpr const T *operator->() const
|
||||
{
|
||||
assert(object != nullptr);
|
||||
return object->handle;
|
||||
return object;
|
||||
}
|
||||
constexpr RefObject<T, Deleter> *getObject() const noexcept
|
||||
constexpr T* getHandle()
|
||||
{
|
||||
return object;
|
||||
}
|
||||
constexpr T *getHandle()
|
||||
constexpr const T* getHandle() const
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
constexpr const T *getHandle() const
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
constexpr RefPtr<T, Deleter> clone()
|
||||
{
|
||||
return RefPtr<T, Deleter>(new T(*getHandle()));
|
||||
return object;
|
||||
}
|
||||
private:
|
||||
RefObject<T, Deleter> *object;
|
||||
T* object;
|
||||
};
|
||||
template <typename T>
|
||||
class UniquePtr
|
||||
@@ -319,31 +229,4 @@ public:
|
||||
private:
|
||||
T *handle;
|
||||
};
|
||||
//A weak pointer has no ownership over an object and thus cant delete it
|
||||
template <typename T>
|
||||
class WeakPtr
|
||||
{
|
||||
public:
|
||||
WeakPtr()
|
||||
: pointer(nullptr)
|
||||
{
|
||||
}
|
||||
WeakPtr(RefPtr<T> &sharedPtr)
|
||||
: pointer(sharedPtr)
|
||||
{
|
||||
}
|
||||
WeakPtr &operator=(WeakPtr<T> &weakPtr)
|
||||
{
|
||||
pointer = weakPtr.pointer;
|
||||
return *this;
|
||||
}
|
||||
WeakPtr &operator=(RefPtr<T> &sharedPtr)
|
||||
{
|
||||
pointer = sharedPtr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<T> pointer;
|
||||
};
|
||||
} // namespace Seele
|
||||
|
||||
Reference in New Issue
Block a user