|
template<std::convertible_to< T > U>
requires (!std::same_as<std::remove_cvref_t<U>, NotNull>) |
| constexpr | NotNull (U &&u) noexcept(std::is_nothrow_constructible_v< T, U && >) |
| |
template<class U >
requires std::move_constructible<U> && std::constructible_from<T, U&&> |
| constexpr | explicit (!std::convertible_to< U, T >) NotNull(NotNull< U > &&other) noexcept(std::is_nothrow_move_constructible_v< U > &&std::is_nothrow_constructible_v< T, U && >) |
| |
template<class U >
requires std::convertible_to<const U&, T> |
| constexpr | NotNull (const NotNull< U > &other) noexcept(std::is_nothrow_constructible_v< T, const U & >) |
| |
| | NotNull (std::nullptr_t)=delete |
| |
| NotNull & | operator= (std::nullptr_t)=delete |
| |
| constexpr | NotNull (NotNull &&)=default |
| |
| constexpr NotNull & | operator= (NotNull &&)=default |
| |
| constexpr | NotNull (const NotNull &)=default |
| |
| constexpr NotNull & | operator= (const NotNull &)=default |
| |
| constexpr const T & | get () const &noexcept LIFETIMEBOUND |
| |
| constexpr T | get () &&noexcept(std::is_nothrow_move_constructible_v< T >) |
| |
| constexpr decltype(auto) | operator-> () const LIFETIMEBOUND |
| |
| constexpr decltype(auto) | operator* () const LIFETIMEBOUND |
| |
| constexpr | operator T () const &noexcept(std::is_nothrow_copy_constructible_v< T >) |
| |
| constexpr | operator T () &&noexcept(std::is_nothrow_move_constructible_v< T >) |
| |
| template<class U > |
| constexpr auto | operator<=> (const NotNull< U > &other) const |
| |
| template<class U > |
| constexpr bool | operator== (const NotNull< U > &other) const |
| |
template<class T>
requires std::is_class_v<T> && requires(T t) { { t != nullptr } -> std::convertible_to<bool>; }
class util::NotNull< T >
NotNull is intended to be used to denote that a smart pointer type can not hold a nullptr value.
The type is more useful, the earlier in the lifetime of a pointer it is used. So instead of passing an existing pointer into NotNull, it is recommended to use the type when creating the smart pointer. E.g.:
util::NotNull p{std::make_shared<Thing>()};
This makes it obvious that a pointer really is not null and that the constructor will not fail.
NotNull does not support raw pointers. The C++ language provides raw references for this use case, and the C++ standard library provides std::reference_wrapper, where raw references can not be used.
This type is movable, meaning that the inner pointer is null after a move. Clang-tidy static analysis is used to enforce use-after-move violations, so that the null should never be observed. Moreover, the runtime Assume check in the get() member function will ensure the same.
Definition at line 44 of file not_null.h.