Files
banan-os/BAN/include/BAN/UniqPtr.h
Bananymous b5647ff258 BAN: Rewrite RefPtr,UniqPtr const semantics
const RefPtr<T> now allows accessing T as non-const. Also add default
hash function for RefPtr and UniqPtr based on the pointer value
2026-04-25 22:10:01 +03:00

88 lines
1.6 KiB
C++

#pragma once
#include <BAN/Errors.h>
#include <BAN/Hash.h>
#include <BAN/NoCopyMove.h>
namespace BAN
{
template<typename T>
class UniqPtr
{
BAN_NON_COPYABLE(UniqPtr);
public:
UniqPtr() = default;
template<typename U>
UniqPtr(UniqPtr<U>&& other)
{
m_pointer = other.m_pointer;
other.m_pointer = nullptr;
}
~UniqPtr()
{
clear();
}
static UniqPtr adopt(T* pointer)
{
UniqPtr uniq;
uniq.m_pointer = pointer;
return uniq;
}
// NOTE: don't use is_constructible_v<T, Args...> as UniqPtr<T> is allowed with friends
template<typename... Args>
static BAN::ErrorOr<UniqPtr> create(Args&&... args) requires requires(Args&&... args) { T(forward<Args>(args)...); }
{
UniqPtr uniq;
uniq.m_pointer = new T(BAN::forward<Args>(args)...);
if (uniq.m_pointer == nullptr)
return BAN::Error::from_errno(ENOMEM);
return uniq;
}
template<typename U>
UniqPtr& operator=(UniqPtr<U>&& other)
{
clear();
m_pointer = other.m_pointer;
other.m_pointer = nullptr;
return *this;
}
T* ptr() const { return m_pointer; }
T& operator*() const { ASSERT(!empty()); return *ptr(); }
T* operator->() const { ASSERT(!empty()); return ptr(); }
bool empty() const { return m_pointer == nullptr; }
explicit operator bool() const { return m_pointer; }
void clear()
{
if (m_pointer)
delete m_pointer;
m_pointer = nullptr;
}
private:
T* m_pointer = nullptr;
template<typename U>
friend class UniqPtr;
};
template<typename T>
struct hash<UniqPtr<T>>
{
constexpr hash_t operator()(const UniqPtr<T>& ptr) const
{
return hash<T*>()(ptr.ptr());
}
};
}