luau/Analysis/include/Luau/NotNull.h

105 lines
2.1 KiB
C
Raw Normal View History

2022-06-03 21:32:20 +01:00
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#pragma once
#include "Luau/Common.h"
#include <functional>
namespace Luau
{
/** A non-owning, non-null pointer to a T.
*
2022-06-17 01:54:42 +01:00
* A NotNull<T> is notionally identical to a T* with the added restriction that
* it can never store nullptr.
*
* The sole conversion rule from T* to NotNull<T> is the single-argument
* constructor, which is intentionally marked explicit. This constructor
* performs a runtime test to verify that the passed pointer is never nullptr.
*
* Pointer arithmetic, increment, decrement, and array indexing are all
* forbidden.
*
* An implicit coersion from NotNull<T> to T* is afforded, as are the pointer
* indirection and member access operators. (*p and p->prop)
*
* The explicit delete statement is permitted (but not recommended) on a
* NotNull<T> through this implicit conversion.
2022-06-03 21:32:20 +01:00
*/
2022-07-01 00:29:02 +01:00
template<typename T>
2022-06-03 21:32:20 +01:00
struct NotNull
{
explicit NotNull(T* t)
: ptr(t)
{
LUAU_ASSERT(t);
}
explicit NotNull(std::nullptr_t) = delete;
void operator=(std::nullptr_t) = delete;
2022-07-01 00:29:02 +01:00
template<typename U>
2022-06-17 01:54:42 +01:00
NotNull(NotNull<U> other)
: ptr(other.get())
2022-07-01 00:29:02 +01:00
{
}
2022-06-17 01:54:42 +01:00
2022-06-03 21:32:20 +01:00
operator T*() const noexcept
{
return ptr;
}
T& operator*() const noexcept
{
return *ptr;
}
T* operator->() const noexcept
{
return ptr;
}
2022-12-02 10:46:05 +00:00
template<typename U>
bool operator==(NotNull<U> other) const noexcept
{
return get() == other.get();
}
template<typename U>
bool operator!=(NotNull<U> other) const noexcept
{
return get() != other.get();
}
operator bool() const noexcept = delete;
2022-06-03 21:32:20 +01:00
T& operator[](int) = delete;
T& operator+(int) = delete;
T& operator-(int) = delete;
2022-06-17 01:54:42 +01:00
T* get() const noexcept
{
return ptr;
}
private:
2022-06-03 21:32:20 +01:00
T* ptr;
};
2022-07-01 00:29:02 +01:00
} // namespace Luau
2022-06-03 21:32:20 +01:00
namespace std
{
2022-07-01 00:29:02 +01:00
template<typename T>
struct hash<Luau::NotNull<T>>
2022-06-03 21:32:20 +01:00
{
size_t operator()(const Luau::NotNull<T>& p) const
{
2022-06-17 01:54:42 +01:00
return std::hash<T*>()(p.get());
2022-06-03 21:32:20 +01:00
}
};
2022-07-01 00:29:02 +01:00
} // namespace std