BAN: Add RefCounted<> and Unique<>
We have now maybe functional smart pointers
This commit is contained in:
parent
1687028ed5
commit
f10a57dcec
|
@ -1,11 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <BAN/Errors.h>
|
||||||
|
#include <BAN/Move.h>
|
||||||
|
#include <BAN/NoCopyMove.h>
|
||||||
|
|
||||||
#if defined(__is_kernel)
|
#if defined(__is_kernel)
|
||||||
#include <kernel/kmalloc.h>
|
#include <kernel/kmalloc.h>
|
||||||
#else
|
#else
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace BAN
|
namespace BAN
|
||||||
{
|
{
|
||||||
#if defined(__is_kernel)
|
#if defined(__is_kernel)
|
||||||
|
@ -18,24 +25,136 @@ namespace BAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class OwnPtr
|
class Unique
|
||||||
{
|
{
|
||||||
|
BAN_NON_COPYABLE(Unique<T>);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
OwnPtr(const Args&... args)
|
Unique(const Args&... args)
|
||||||
{
|
{
|
||||||
m_pointer = new T(args...);
|
m_pointer = new T(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
~OwnPtr()
|
~Unique()
|
||||||
{
|
{
|
||||||
delete m_pointer;
|
delete m_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return m_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* m_pointer = nullptr;
|
T* m_pointer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class RefCounted
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RefCounted() { }
|
||||||
|
RefCounted(T* pointer)
|
||||||
|
{
|
||||||
|
if (pointer)
|
||||||
|
{
|
||||||
|
m_pointer = pointer;
|
||||||
|
m_count = new int32_t(1);
|
||||||
|
ASSERT(m_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RefCounted(const RefCounted<T>& other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
RefCounted(RefCounted<T>&& other)
|
||||||
|
{
|
||||||
|
*this = Move(other);
|
||||||
|
}
|
||||||
|
~RefCounted()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
static RefCounted<T> Create(Args... args)
|
||||||
|
{
|
||||||
|
return RefCounted<T>(new T(Forward<Args>(args)...), new int32_t(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
RefCounted<T>& operator=(const RefCounted<T>& other)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
if (other)
|
||||||
|
{
|
||||||
|
m_pointer = other.m_pointer;
|
||||||
|
m_count = other.m_count;
|
||||||
|
(*m_count)++;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefCounted<T>& operator=(RefCounted<T>&& other)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
m_pointer = other.m_pointer;
|
||||||
|
m_count = other.m_count;
|
||||||
|
other.m_pointer = nullptr;
|
||||||
|
other.m_count = nullptr;
|
||||||
|
if (!(*this))
|
||||||
|
Reset();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator*() { return *m_pointer;}
|
||||||
|
const T& operator*() const { return *m_pointer;}
|
||||||
|
|
||||||
|
T* operator->() { return m_pointer; }
|
||||||
|
const T* operator->() const { return m_pointer; }
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
ASSERT(!m_count == !m_pointer);
|
||||||
|
if (!m_count)
|
||||||
|
return;
|
||||||
|
(*m_count)--;
|
||||||
|
if (*m_count == 0)
|
||||||
|
{
|
||||||
|
delete m_count;
|
||||||
|
delete m_pointer;
|
||||||
|
}
|
||||||
|
m_count = nullptr;
|
||||||
|
m_pointer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
ASSERT(!m_count == !m_pointer);
|
||||||
|
return m_count && *m_count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const RefCounted<T>& other) const
|
||||||
|
{
|
||||||
|
if (m_pointer != other.m_pointer)
|
||||||
|
return false;
|
||||||
|
ASSERT(m_count == other.m_count);
|
||||||
|
return !m_count || *m_count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefCounted(T* pointer, int32_t* count)
|
||||||
|
: m_pointer(pointer)
|
||||||
|
, m_count(count)
|
||||||
|
{
|
||||||
|
ASSERT(!pointer == !count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* m_pointer = nullptr;
|
||||||
|
int32_t* m_count = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* operator new(size_t, void* addr) { return addr; }
|
inline void* operator new(size_t, void* addr) { return addr; }
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define BAN_NON_COPYABLE(class) \
|
||||||
|
private: \
|
||||||
|
class(const class&) = delete; \
|
||||||
|
class& operator=(const class&) = delete
|
||||||
|
|
||||||
|
#define BAN_NON_MOVABLE(class) \
|
||||||
|
private: \
|
||||||
|
class(class&&) = delete; \
|
||||||
|
class& operator=(class&&) = delete
|
Loading…
Reference in New Issue