112 lines
3.2 KiB
C++
112 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include <Core/Common/CoreUtils.h>
|
|
#include <type_traits>
|
|
|
|
namespace Juliet
|
|
{
|
|
template <typename Type, typename OtherType>
|
|
concept NonNullPtr_Convertible = std::is_convertible_v<OtherType*, Type*>;
|
|
|
|
template <typename Type, typename OtherType>
|
|
concept NonNullPtr_SameType = std::is_same_v<OtherType*, Type*>;
|
|
|
|
template <typename Type>
|
|
class NonNullPtr
|
|
{
|
|
public:
|
|
NonNullPtr(Type* ptr)
|
|
: InternalPtr(ptr)
|
|
{
|
|
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
|
|
}
|
|
|
|
template <typename OtherType>
|
|
requires NonNullPtr_Convertible<OtherType*, Type*>
|
|
NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
|
|
: InternalPtr(otherPtr.Get())
|
|
{
|
|
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
|
|
}
|
|
|
|
// Assignment
|
|
NonNullPtr& operator=(Type* ptr)
|
|
{
|
|
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
|
|
InternalPtr = ptr;
|
|
return *this;
|
|
}
|
|
|
|
template <typename OtherType>
|
|
requires NonNullPtr_Convertible<OtherType*, Type*>
|
|
NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
|
|
{
|
|
InternalPtr = otherPtr.Get();
|
|
return *this;
|
|
}
|
|
|
|
// Accessors
|
|
operator Type*() const
|
|
{
|
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
|
return InternalPtr;
|
|
}
|
|
|
|
Type* Get() const
|
|
{
|
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
|
return InternalPtr;
|
|
}
|
|
|
|
Type& operator*() const
|
|
{
|
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
|
return *InternalPtr;
|
|
}
|
|
|
|
Type* operator->() const
|
|
{
|
|
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
|
|
return InternalPtr;
|
|
}
|
|
|
|
// Comparisons
|
|
bool operator==(const NonNullPtr& otherPtr) const { return InternalPtr == otherPtr.InternalPtr; }
|
|
|
|
template <typename OtherType>
|
|
requires NonNullPtr_SameType<Type, OtherType>
|
|
bool operator==(OtherType* otherRawPtr) const
|
|
{
|
|
return InternalPtr == otherRawPtr;
|
|
}
|
|
|
|
template <typename OtherType>
|
|
requires NonNullPtr_SameType<Type, OtherType>
|
|
friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
|
|
{
|
|
return otherRawPtr == nonNullPtr.InternalPtr;
|
|
}
|
|
|
|
// Forbid assigning a nullptr at compile time
|
|
NonNullPtr(std::nullptr_t)
|
|
: InternalPtr(nullptr)
|
|
{
|
|
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
|
|
}
|
|
|
|
NonNullPtr& operator=(std::nullptr_t)
|
|
{
|
|
static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
|
|
return *this;
|
|
}
|
|
|
|
explicit operator bool() const { return true; }
|
|
|
|
private:
|
|
Type* InternalPtr;
|
|
};
|
|
|
|
template <typename T>
|
|
NonNullPtr(T*) -> NonNullPtr<T>;
|
|
} // namespace Juliet
|