// // maybe_null.hpp // pointer // // Created by Sam Jaffe on 9/24/15. // // #pragma once #include #include #include "pointer_fwd.hpp" #include "ptr_compare.hpp" class unchecked_pointer_exception : public std::logic_error { using std::logic_error::logic_error; }; template class maybe_null>; // not permitted template class maybe_null { public: using element_type = typename std::pointer_traits::element_type; using pointer = element_type *; using reference = element_type &; maybe_null() : _ptr(nullptr) {} maybe_null(T const & p) : _ptr(p) { } maybe_null(T && p) : _ptr(std::move(p)) { } maybe_null(maybe_null const&) = default; template explicit operator maybe_null() const { return _ptr; } maybe_null& operator=(maybe_null const&) = default; template maybe_null& operator=(maybe_null const&other) { if (_ptr != other._ptr) { _ptr = other._ptr; #if defined( DEBUG ) tested_ = other.tested_; #endif } return *this; } operator bool() const { #if defined( DEBUG ) tested_ = true; #endif return static_cast(_ptr); } pointer get() const { return std::addressof(*_ptr); } pointer operator->() const { return std::addressof(operator*()); } reference operator*() const { #if defined( DEBUG ) if ( !tested_ ) { throw unchecked_pointer_exception{"did not verify that pointer was non-null"}; } #endif return *_ptr; } private: T _ptr; #if defined( DEBUG ) mutable bool tested_ = false; #endif }; POINTER_TEMPLATE_COMPARE( maybe_null )