// // copy_ptr.hpp // pointers // // Created by Sam Jaffe on 12/6/16. // #pragma once #include #include "pointer_fwd.hpp" #include "ptr_compare.hpp" namespace detail { template T * copy_ptr_from_ptr(T const * ptr) { return ptr ? new T(*ptr) : nullptr; } template using clone_func = T* (T::*)() const; template Clone> T * clone_ptr_from_ptr(T const * ptr) { return ptr ? (ptr->*Clone)() : nullptr; } } template > class copy_ptr { public: using element_type = T; using pointer = element_type *; using reference = element_type &; copy_ptr() noexcept : _ptr(nullptr) {} copy_ptr(T * const & p) = delete; copy_ptr(T * && p) noexcept(std::is_nothrow_move_constructible::value) : _ptr(std::move(p)) {} copy_ptr(copy_ptr const & other) : _ptr(Copy(other._ptr)) {} copy_ptr(copy_ptr && other) noexcept(noexcept(swap(_ptr, other._ptr))) : _ptr(nullptr) { swap(_ptr, other._ptr); } static copy_ptr copy_of(T * const & p) { return Copy(p); } template explicit operator copy_ptr() const { return Copy(_ptr); } ~copy_ptr() { delete _ptr; } copy_ptr & operator=(copy_ptr const & other) noexcept(noexcept(swap(_ptr, other._ptr))) { swap(_ptr, copy_ptr{other}._ptr); return *this; } copy_ptr & operator=(copy_ptr && other) noexcept(noexcept(swap(_ptr, other._ptr))) { swap(_ptr, other._ptr); return *this; } operator bool() const noexcept { return static_cast(_ptr); } pointer get() const noexcept { return _ptr; } pointer operator->() const noexcept { return get(); } reference operator*() const noexcept { return *get(); } private: T * _ptr; }; template Clone> using clone_ptr = copy_ptr>; POINTER_TEMPLATE_COMPARE_FULL( copy_ptr, (typename T1, T1*(*C1)(T1*)), (T1, C1), (typename T2, T2*(*C2)(T2*)), (T2, C2))