22    static_assert(!std::is_reference_v<T>, 
"NotNull does not work with references");
 
   23    static_assert(!std::is_const_v<T>);
 
   26    constexpr explicit NotNull() = 
delete;
 
   28    constexpr explicit NotNull(
const T& u) : ptr_(u) { 
UASSERT_MSG(ptr_, 
"Trying to construct NotNull from null"); }
 
   30    constexpr explicit NotNull(T&& u) : ptr_(std::move(u)) {
 
   31        UASSERT_MSG(ptr_, 
"Trying to construct NotNull from null");
 
   34    template <
typename U, 
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
 
   35    constexpr explicit NotNull(U&& u) : ptr_(std::forward<U>(u)) {
 
   36        UASSERT_MSG(ptr_, 
"Trying to construct NotNull from null");
 
   39    template <
typename U, 
typename = std::enable_if_t<std::is_convertible_v<U*, T>>>
 
   40    constexpr  NotNull(U& u) : ptr_(std::addressof(u)) {}
 
   42    template <
typename U, 
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
 
   43    constexpr NotNull(
const NotNull<U>& other) : ptr_(other.GetBase()) {
 
   44        UASSERT_MSG(ptr_, 
"Trying to construct NotNull from null (moved-from) NotNull");
 
   47    template <
typename U, 
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
 
   48    constexpr NotNull(
NotNull<U>&& other) : ptr_(std::move(other).GetBase()) {
 
   49        UASSERT_MSG(ptr_, 
"Trying to construct NotNull from null (moved-from) NotNull");
 
   52    constexpr NotNull(std::nullptr_t) = 
delete;
 
   54    NotNull(
const NotNull& other) 
noexcept = 
default;
 
   55    NotNull(
NotNull&& other) 
noexcept = 
default;
 
   60    constexpr NotNull& operator=(std::nullptr_t) = 
delete;
 
   62    constexpr const T& GetBase() 
const& {
 
   63        UASSERT_MSG(ptr_, 
"Trying to access a null (moved-from) NotNull");
 
   67    constexpr T&& GetBase() && {
 
   68        UASSERT_MSG(ptr_, 
"Trying to access a null (moved-from) NotNull");
 
   69        return std::move(ptr_);
 
   72    constexpr  operator 
const T&() 
const& { 
return GetBase(); }
 
   74    constexpr  operator 
bool() = 
delete;
 
   76    constexpr decltype(
auto) operator->() 
const& { 
return GetBase(); }
 
   78    constexpr decltype(
auto) operator*() 
const& { 
return *GetBase(); }
 
   81    constexpr bool operator==(
const NotNull<U>& other) 
const& {
 
   82        return GetBase() == other.GetBase();
 
   86    constexpr bool operator!=(
const NotNull<U>& other) 
const& {
 
   87        return GetBase() != other.GetBase();