From 9a9727ff9819663bad1b1c7aec949b170120dde8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 14:12:31 -0500 Subject: [PATCH] xo-expression2 stack: + dp<> template + robustify DGlobalSymtab --- include/xo/alloc2/dp.hpp | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 include/xo/alloc2/dp.hpp diff --git a/include/xo/alloc2/dp.hpp b/include/xo/alloc2/dp.hpp new file mode 100644 index 0000000..6c768ce --- /dev/null +++ b/include/xo/alloc2/dp.hpp @@ -0,0 +1,110 @@ +/** @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 { + 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(); + } + } + + dp & operator=(const dp & x) = delete; + + /** move assignment **/ + dp & operator=(dp && x) { + ptr_ = x.ptr_; + x.ptr_ = nullptr; + } + + // -------------------------------- + + 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_; } + +#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 */