#pragma once #include #include #include namespace AMDiS { // A pointer class that deletes only when owning the pointer template class ClonablePtr { private: struct alloc_tag {}; ///< hidden helper struct, used by \ref make public: using Self = ClonablePtr; using element_type = T; /// Default constructor, creates a non-owned nullptr ClonablePtr() = default; /// Constructor from pointer. Can only be used via make method, /// Transfers ownership. ClonablePtr(owner* p, alloc_tag) noexcept : p(p) , is_owner(true) {} /// Constructor from reference explicit ClonablePtr(T& ref) noexcept : p(&ref) , is_owner(false) {} /// Constructor from std::unique_ptr explicit ClonablePtr(std::unique_ptr& ptr) : p(ptr.release()) , is_owner(true) {} explicit ClonablePtr(std::unique_ptr&& ptr) : p(ptr.release()) , is_owner(true) {} /// Destructor, deletes in case of owner only ~ClonablePtr() noexcept { if (is_owner) delete p; } /// Copy constructor, creates a clone of the pointed to object ClonablePtr(Self const& that) noexcept( std::is_nothrow_copy_constructible::value ) : p(new T(*that.p)) , is_owner(true) {} /// Move constructor, copies the pointer only. ClonablePtr(Self&& that) noexcept : p(that.p) , is_owner(that.is_owner) { that.p = nullptr; that.is_owner = false; } /// Copy and move assignment operator, using the copy-and-swap idiom Self& operator=(Self that) noexcept { swap(that); return *this; } /// Factory method. creates a new Object of type T and stores the pointer. template static Self make(Args&&... args) noexcept( std::is_nothrow_constructible...>::value ) { return {new T(FWD(args)...), Self::alloc_tag()}; } /// Access-method by dereferencing T& operator*() const noexcept { return *p; } /// Access-method by pointer access T* operator->() const noexcept { return p; } /// retrieve the underlying pointer T* get() const noexcept { return p; } /// Test whether pointer is NULL operator bool() const noexcept { return !(p == NULL); } void swap(Self& that) noexcept { using std::swap; swap(p, that.p); swap(is_owner, that.is_owner); } private: T* p = nullptr; ///< managed pointer bool is_owner = false; ///< true, if class is owner of pointer, false otherwise }; template void swap(ClonablePtr& a, ClonablePtr& b) noexcept { a.swap(b); } } // end namespace AMDiS