// // 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() : _ptr(nullptr) {} copy_ptr(T * const & p) = delete; copy_ptr(T * && 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: 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))