/** @file dp.hpp * * @author Roland Conybeare, Feb 2026 **/ #pragma once #include "Allocator.hpp" #include #include namespace xo { namespace mm { /** unimorphic "data pointer" with known representation and owned memory. * runs dtor *but not delete*. Does not store allocator! * * Compare with abox **/ template struct dp { using repr_type = DRepr; public: dp() = default; /** dp takes ownership of data @p ptr; * will run dtor when dp goes out of scope. * * Note this is not useful when DRepr=DVariablePlaceholder **/ explicit dp(DRepr * ptr) : ptr_{ptr} {} /** (copy ctor not supported -- ownership is unique) **/ dp(const dp & other) = delete; /** Move constructor **/ dp(dp && other) { ptr_ = other.ptr_; other.ptr_ = nullptr; } /** allocates for sizeof(DRepr), so DRepr must not use flexible array **/ template static dp make(obj alloc, Args&&... args) { void * mem = alloc.alloc_for(); if (mem) { DRepr * data = ::new (mem) DRepr(std::forward(args)...); assert(data); return dp(data); } else { assert(false); return dp(); } } static constexpr bool is_gc_eligible() { return DRepr::is_gc_eligible(); } dp & operator=(const dp & x) = delete; /** move assignment **/ dp & operator=(dp && x) { ptr_ = x.ptr_; x.ptr_ = nullptr; return *this; } // -------------------------------- DRepr * data() const noexcept { return ptr_; } operator bool() const noexcept { return ptr_ != nullptr; } DRepr * operator->() const noexcept { return ptr_; } DRepr & operator*() const noexcept { return *ptr_; } /** transfer responsibility for pointer to caller, * setting dp container's copy to nullptr **/ DRepr * release() noexcept { DRepr * retval = ptr_; this->ptr_ = nullptr; return retval; } #ifdef NOT_YET /** explicit conversion to obj **/ obj to_op() const noexcept { return obj(this->iface(), this->data()); } #endif #ifdef NOT_YET /** Take ownership from unowned object **/ template dp & adopt(const obj & other) requires (std::is_same_v || std::is_same_v) { /* replace .iface_ along w/ .data_ */ this->from_obj(other); return *this; } #endif ~dp() { if (ptr_) { ptr_->~DRepr(); } } private: DRepr * ptr_ = nullptr; }; } /*namespace mm*/ using mm::dp; } /*namespace xo*/ /* end dp.hpp */