Add OwnedPtr and SharedPtr
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
9afaad8fed
commit
bd4b05e534
61
luna/include/luna/OwnedPtr.h
Normal file
61
luna/include/luna/OwnedPtr.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <luna/Alloc.h>
|
||||||
|
#include <luna/Result.h>
|
||||||
|
|
||||||
|
template <typename T> class OwnedPtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OwnedPtr(T* ptr)
|
||||||
|
{
|
||||||
|
m_ptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~OwnedPtr()
|
||||||
|
{
|
||||||
|
if (m_ptr) delete m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnedPtr(const OwnedPtr<T>& other) = delete;
|
||||||
|
|
||||||
|
OwnedPtr(OwnedPtr<T>&& other)
|
||||||
|
{
|
||||||
|
m_ptr = other.m_ptr;
|
||||||
|
other.m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* ptr() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator*() const
|
||||||
|
{
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, class... Args> Result<OwnedPtr<T>> make_owned(Args... args)
|
||||||
|
{
|
||||||
|
T* raw = TRY(make<T>(args...));
|
||||||
|
return OwnedPtr<T> { raw };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> OwnedPtr<T> adopt_owned(T* ptr)
|
||||||
|
{
|
||||||
|
return OwnedPtr<T> { ptr };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> Result<OwnedPtr<T>> adopt_owned_if_nonnull(T* ptr)
|
||||||
|
{
|
||||||
|
if (ptr) return OwnedPtr<T> { ptr };
|
||||||
|
else
|
||||||
|
return err(ENOMEM);
|
||||||
|
}
|
104
luna/include/luna/SharedPtr.h
Normal file
104
luna/include/luna/SharedPtr.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <luna/Alloc.h>
|
||||||
|
#include <luna/Atomic.h>
|
||||||
|
#include <luna/DebugLog.h>
|
||||||
|
#include <luna/Result.h>
|
||||||
|
#include <luna/ScopeGuard.h>
|
||||||
|
|
||||||
|
namespace __detail
|
||||||
|
{
|
||||||
|
struct RefCount
|
||||||
|
{
|
||||||
|
void ref()
|
||||||
|
{
|
||||||
|
m_ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unref()
|
||||||
|
{
|
||||||
|
m_ref_count--;
|
||||||
|
return m_ref_count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Atomic<int> m_ref_count { 1 };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> class SharedPtr
|
||||||
|
{
|
||||||
|
using RefCount = __detail::RefCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SharedPtr(T* ptr, RefCount* ref_count) : m_ptr(ptr), m_ref_count(ref_count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr(const SharedPtr<T>& other) : m_ptr(other.m_ptr), m_ref_count(other.m_ref_count)
|
||||||
|
{
|
||||||
|
m_ref_count->ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr(SharedPtr<T>&& other) : m_ptr(other.m_ptr), m_ref_count(other.m_ref_count)
|
||||||
|
{
|
||||||
|
other.m_ptr = nullptr;
|
||||||
|
other.m_ref_count = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~SharedPtr()
|
||||||
|
{
|
||||||
|
if (m_ref_count && m_ref_count->unref())
|
||||||
|
{
|
||||||
|
delete m_ref_count;
|
||||||
|
delete m_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T* ptr() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator*() const
|
||||||
|
{
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* m_ptr;
|
||||||
|
RefCount* m_ref_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, class... Args> Result<SharedPtr<T>> make_shared(Args... args)
|
||||||
|
{
|
||||||
|
using RefCount = __detail::RefCount;
|
||||||
|
|
||||||
|
RefCount* ref_count = TRY(make<RefCount>());
|
||||||
|
auto guard = make_scope_guard([&] { delete ref_count; });
|
||||||
|
|
||||||
|
T* ptr = TRY(make<T>(args...));
|
||||||
|
guard.deactivate();
|
||||||
|
|
||||||
|
return SharedPtr<T> { ptr, ref_count };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> Result<SharedPtr<T>> adopt_shared(T* ptr)
|
||||||
|
{
|
||||||
|
using RefCount = __detail::RefCount;
|
||||||
|
|
||||||
|
RefCount* ref_count = TRY(make<RefCount>());
|
||||||
|
|
||||||
|
return SharedPtr<T> { ptr, ref_count };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> Result<SharedPtr<T>> adopt_shared_if_nonnull(T* ptr)
|
||||||
|
{
|
||||||
|
if (ptr) return adopt_shared(ptr);
|
||||||
|
else
|
||||||
|
return err(ENOMEM);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user