// // not_null.hpp // pointer // // Created by Sam Jaffe on 9/24/15. // // #pragma once #include #include "maybe_null.hpp" #include "pointer_fwd.hpp" #include "ptr_compare.hpp" template class not_null>; // A weak_ptr cannot be a not_null template class not_null { public: using element_type = typename std::pointer_traits

::element_type; using pointer = element_type *; using reference = element_type &; explicit not_null(std::nullptr_t) = delete; explicit not_null(int) = delete; not_null(P const & p) : _ptr(p) { validate(); } not_null(P && p) : _ptr(std::move(p)) { validate(); } template ::value>::type> not_null(Y const & p) : _ptr(p) { validate(); } template ::value>::type> not_null(Y && p) : _ptr(std::forward(p)) { validate(); } not_null(not_null const &) noexcept(detail::is_nt_cc

::value) = default; not_null(not_null &&) = delete; template explicit operator maybe_null() const noexcept(detail::is_nt_c::value) { return _ptr; } template explicit operator not_null() const noexcept(detail::is_nt_c::value) { return _ptr; } not_null & operator=(not_null const &) noexcept(detail::is_nt_ca

::value) = default; not_null & operator=(not_null &&) = delete; operator bool() const noexcept { return true; } pointer get() const noexcept { return detail::get_ptr

().get(_ptr); } reference operator*() const noexcept { return *_ptr; } pointer operator->() const noexcept { return get(); } void reset(P const & p) { operator=(not_null(p)); } void reset(P && p) { operator=(not_null(std::forward(p))); } private: void validate() { if (get() == nullptr) { throw null_pointer_exception{"not_null

cannot be null"}; } } P _ptr; }; POINTER_TEMPLATE_COMPARE(not_null)