// // copy_ptr.hpp // pointers // // Created by Sam Jaffe on 12/6/16. // #pragma once #include #include #include "pointer_fwd.hpp" namespace detail { template T * copy_ptr_from_ptr(T * ptr) { return ptr ? new T(*ptr) : nullptr; } } template > class copy_ptr { public: using element_type = T; using pointer = element_type *; using reference = element_type &; copy_ptr() : _ptr(nullptr) {} copy_ptr(P const & p) = delete; copy_ptr(P && p) : _ptr(std::move(p)) {} copy_ptr(copy_ptr const & other) : _ptr(Copy(other._ptr)) {} copy_ptr(copy_ptr &&) = default; template explicit operator copy_ptr() const { return Copy(_ptr); } ~copy_ptr() { delete _ptr; } copy_ptr & operator=(copy_ptr const & other) { swap(copy_ptr{other}); return *this; } copy_ptr & operator=(copy_ptr &&) = default; operator bool() const { return static_cast(_ptr); } pointer get() const { return _ptr; } pointer operator->() const { return get(); } reference operator*() const { return *get(); } private: P _ptr; }; template bool operator==(copy_ptr const&lhs, copy_ptr const&rhs) { return lhs.get() == rhs.get(); } template bool operator!=(copy_ptr const&lhs, copy_ptr const&rhs) { return !(lhs == rhs); } template bool operator< (copy_ptr const&lhs, copy_ptr const&rhs) { typedef typename std::common_type< typename copy_ptr::pointer, typename copy_ptr::pointer>::type V; return std::less(lhs.get(), rhs.get()); } template bool operator> (copy_ptr const&lhs, copy_ptr const&rhs) { return rhs < lhs; } template bool operator<=(copy_ptr const&lhs, copy_ptr const&rhs) { return !(rhs < lhs); } template bool operator>=(copy_ptr const&lhs, copy_ptr const&rhs) { return !(lhs < rhs); } template bool operator==(copy_ptr const&lhs, std::nullptr_t) { return !lhs; } template bool operator==(std::nullptr_t, copy_ptr const&rhs) { return !rhs; } template bool operator!=(copy_ptr const&lhs, std::nullptr_t) { return static_cast(lhs); } template bool operator!=(std::nullptr_t, copy_ptr const&rhs) { return static_cast(rhs); } template bool operator< (copy_ptr const&lhs, std::nullptr_t) { typedef typename copy_ptr::pointer V; return std::less(lhs.get(), nullptr); } template bool operator< (std::nullptr_t, copy_ptr const&rhs) { typedef typename copy_ptr::pointer V; return std::less(nullptr, rhs.get()); } template bool operator> (copy_ptr const&lhs, std::nullptr_t) { return nullptr < lhs; } template bool operator> (std::nullptr_t, copy_ptr const&rhs) { return rhs < nullptr; } template bool operator<=(copy_ptr const&lhs, std::nullptr_t) { return !(nullptr < lhs); } template bool operator<=(std::nullptr_t, copy_ptr const&rhs) { return !(rhs < nullptr); } template bool operator>=(copy_ptr const&lhs, std::nullptr_t) { return !(lhs < nullptr); } template bool operator>=(std::nullptr_t, copy_ptr const&rhs) { return !(nullptr < rhs); }