// // not_null.hpp // pointer // // Created by Sam Jaffe on 9/24/15. // // #pragma once #include #include #include "pointer_fwd.hpp" #include "ptr_compare.hpp" #include "maybe_null.hpp" class null_pointer_exception : public std::invalid_argument { using std::invalid_argument::invalid_argument; }; 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(T const & p) : _ptr(p) { validate(); } not_null(T && p) : _ptr(std::move(p)) { validate(); } not_null(not_null const&) = default; template explicit operator maybe_null() const { return _ptr; } template explicit operator not_null() const { return _ptr; } not_null& operator=(not_null const&) = default; template not_null& operator=(not_null const&other) { _ptr = other._ptr; return *this; } explicit operator maybe_null() const; operator bool() const { return true; } pointer get() const { return std::addressof(operator*()); } reference operator*() const { return *_ptr; } pointer operator->() const { return get(); } private: void validate() { if (get() == nullptr) { throw null_pointer_exception{"not_null cannot be null"}; } } T _ptr; }; POINTER_TEMPLATE_COMPARE( not_null )