From 3bdf617f14ddcd9796f19324626e4239f20b5a3c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 5 Mar 2026 13:02:12 +1100 Subject: [PATCH] xo-interpreter2 stack: refactor: string clases -> xo-stringtable2/ --- CMakeLists.txt | 9 +++ idl/GCObject.json5 | 83 +++++++++++++++++++++ include/xo/gc/GCObject.hpp | 22 ++++++ include/xo/gc/detail/AGCObject.hpp | 87 ++++++++++++++++++++++ include/xo/gc/detail/IGCObject_Any.hpp | 93 ++++++++++++++++++++++++ include/xo/gc/detail/IGCObject_Xfer.hpp | 95 +++++++++++++++++++++++++ include/xo/gc/detail/RGCObject.hpp | 93 ++++++++++++++++++++++++ src/gc/IGCObject_Any.cpp | 48 +++++++++++++ 8 files changed, 530 insertions(+) create mode 100644 idl/GCObject.json5 create mode 100644 include/xo/gc/GCObject.hpp create mode 100644 include/xo/gc/detail/AGCObject.hpp create mode 100644 include/xo/gc/detail/IGCObject_Any.hpp create mode 100644 include/xo/gc/detail/IGCObject_Xfer.hpp create mode 100644 include/xo/gc/detail/RGCObject.hpp create mode 100644 src/gc/IGCObject_Any.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b4b0319..702f6e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,15 @@ add_definitions(${PROJECT_CXX_FLAGS}) # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-gc-facet-gcobject + FACET GCObject + INPUT idl/GCObject.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-alloc2-facet-resourcevisitor diff --git a/idl/GCObject.json5 b/idl/GCObject.json5 new file mode 100644 index 0000000..4374758 --- /dev/null +++ b/idl/GCObject.json5 @@ -0,0 +1,83 @@ +{ + mode: "facet", + output_cpp_dir: "src/gc", + output_hpp_dir: "include/xo/gc", + output_impl_subdir: "detail", + includes: [ + "", + "", + "", + "", + ], + // extra includes in GCObject.hpp, if any + user_hpp_includes: [], + namespace1: "xo", + namespace2: "mm", + pretext: [ + "namespace xo { namespace mm { class ACollector; }}", + ], + facet: "GCObject", + detail_subdir: "detail", + brief: "xxx", + using_doxygen: true, + doc: [ + "GC hooks for collector-aware data" + ], + types: [ + // using size_type = std::size_t + { + name: "size_type", + doc: ["type for an amount of memory"], + definition: "std::size_t", + }, + { + name: "AAllocator", + doc: ["fomo allocator type"], + definition: "xo::mm::AAllocator", + }, + { + name: "ACollector", + doc: ["fomo collector type"], + definition: "xo::mm::ACollector", + }, + ], + const_methods: [ + // size_type shallow_size() const noexcept + { + name: "shallow_size", + doc: ["memory consumption for this instance"], + return_type: "size_type", + args: [], + const: true, + noexcept: true, + attributes: [], + }, + // Opaque shallow_copy(obj>) const noexcept + { + name: "shallow_copy", + doc: ["copy instance using allocator"], + return_type: "Opaque", + args:[ + {type: "obj", name: "mm"}, + ], + const: true, + noexcept: true, + attributes: [], + }, + ], + nonconst_methods: [ + // size_type forward_children(obj) const noexcept + { + name: "forward_children", + doc: ["during GC: forward immdiate children"], + return_type: "size_type", + args: [ + {type: "obj", name: "gc"}, + ], + const: true, + noexcept: true, + attributes: [], + }, + ], + router_facet_explicit_content: [] +} diff --git a/include/xo/gc/GCObject.hpp b/include/xo/gc/GCObject.hpp new file mode 100644 index 0000000..759e937 --- /dev/null +++ b/include/xo/gc/GCObject.hpp @@ -0,0 +1,22 @@ +/** @file GCObject.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObject.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/GCObject.json5] + **/ + +#pragma once + +#include "detail/AGCObject.hpp" +#include "detail/IGCObject_Any.hpp" +#include "detail/IGCObject_Xfer.hpp" +#include "detail/RGCObject.hpp" + + +/* end GCObject.hpp */ diff --git a/include/xo/gc/detail/AGCObject.hpp b/include/xo/gc/detail/AGCObject.hpp new file mode 100644 index 0000000..6f6e7b9 --- /dev/null +++ b/include/xo/gc/detail/AGCObject.hpp @@ -0,0 +1,87 @@ +/** @file AGCObject.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObject.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/GCObject.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include +#include +#include +#include +#include +#include +#include + +namespace xo { namespace mm { class ACollector; }} + +namespace xo { +namespace mm { + +using Copaque = const void *; +using Opaque = void *; + +/** +GC hooks for collector-aware data +**/ +class AGCObject { +public: + /** @defgroup mm-gcobject-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + /** type for an amount of memory **/ + using size_type = std::size_t; + /** fomo allocator type **/ + using AAllocator = xo::mm::AAllocator; + /** fomo collector type **/ + using ACollector = xo::mm::ACollector; + ///@} + + /** @defgroup mm-gcobject-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; + /** memory consumption for this instance **/ + virtual size_type shallow_size(Copaque data) const noexcept = 0; + /** copy instance using allocator **/ + virtual Opaque shallow_copy(Copaque data, obj mm) const noexcept = 0; + + // nonconst methods + /** during GC: forward immdiate children **/ + virtual size_type forward_children(Opaque data, obj gc) const noexcept = 0; + ///@} +}; /*AGCObject*/ + +/** Implementation IGCObject_DRepr of AGCObject for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = IGCObject_DRepr; + * }; + * + * then IGCObject_ImplType --> IGCObject_DRepr + **/ +template +using IGCObject_ImplType = xo::facet::FacetImplType; + +} /*namespace mm*/ +} /*namespace xo*/ + +/* AGCObject.hpp */ diff --git a/include/xo/gc/detail/IGCObject_Any.hpp b/include/xo/gc/detail/IGCObject_Any.hpp new file mode 100644 index 0000000..9ff7bb2 --- /dev/null +++ b/include/xo/gc/detail/IGCObject_Any.hpp @@ -0,0 +1,93 @@ +/** @file IGCObject_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObject.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/GCObject.json5] + **/ + +#pragma once + +#include "AGCObject.hpp" +#include + +namespace xo { namespace mm { class IGCObject_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::mm::IGCObject_Any; +}; + +} +} + +namespace xo { +namespace mm { + + /** @class IGCObject_Any + * @brief AGCObject implementation for empty variant instance + **/ + class IGCObject_Any : public AGCObject { + public: + /** @defgroup mm-gcobject-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using size_type = AGCObject::size_type; + using AAllocator = AGCObject::AAllocator; + using ACollector = AGCObject::ACollector; + + ///@} + /** @defgroup mm-gcobject-any-methods **/ + ///@{ + + const AGCObject * iface() const { return std::launder(this); } + + // from AGCObject + + // builtin methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods + [[noreturn]] size_type shallow_size(Copaque) const noexcept override { _fatal(); } + [[noreturn]] Opaque shallow_copy(Copaque, obj) const noexcept override { _fatal(); } + + // nonconst methods + [[noreturn]] size_type forward_children(Opaque, obj) const noexcept override; + + ///@} + + private: + /** @defgraoup mm-gcobject-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup mm-gcobject-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace mm */ +} /*namespace xo */ + +/* IGCObject_Any.hpp */ diff --git a/include/xo/gc/detail/IGCObject_Xfer.hpp b/include/xo/gc/detail/IGCObject_Xfer.hpp new file mode 100644 index 0000000..7f094ab --- /dev/null +++ b/include/xo/gc/detail/IGCObject_Xfer.hpp @@ -0,0 +1,95 @@ +/** @file IGCObject_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObject.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/GCObject.json5] + **/ + +#pragma once + +#include +#include +#include +#include + +namespace xo { +namespace mm { + /** @class IGCObject_Xfer + **/ + template + class IGCObject_Xfer : public AGCObject { + public: + /** @defgroup mm-gcobject-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = IGCObject_DRepr; + /** integer identifying a type **/ + using typeseq = AGCObject::typeseq; + using size_type = AGCObject::size_type; + using AAllocator = AGCObject::AAllocator; + using ACollector = AGCObject::ACollector; + ///@} + + /** @defgroup mm-gcobject-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from AGCObject + + // builtin methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods + size_type shallow_size(Copaque data) const noexcept override { + return I::shallow_size(_dcast(data)); + } + Opaque shallow_copy(Copaque data, obj mm) const noexcept override { + return I::shallow_copy(_dcast(data), mm); + } + + // non-const methods + size_type forward_children(Opaque data, obj gc) const noexcept override { + return I::forward_children(_dcast(data), gc); + } + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup mm-gcobject-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + IGCObject_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + IGCObject_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace mm */ +} /*namespace xo*/ + +/* end IGCObject_Xfer.hpp */ diff --git a/include/xo/gc/detail/RGCObject.hpp b/include/xo/gc/detail/RGCObject.hpp new file mode 100644 index 0000000..d24994a --- /dev/null +++ b/include/xo/gc/detail/RGCObject.hpp @@ -0,0 +1,93 @@ +/** @file RGCObject.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/GCObject.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/GCObject.json5] + **/ + +#pragma once + +#include "AGCObject.hpp" + +namespace xo { +namespace mm { + +/** @class RGCObject + **/ +template +class RGCObject : public Object { +private: + using O = Object; + +public: + /** @defgroup mm-gcobject-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + using size_type = AGCObject::size_type; + using AAllocator = AGCObject::AAllocator; + using ACollector = AGCObject::ACollector; + ///@} + + /** @defgroup mm-gcobject-router-ctors **/ + ///@{ + RGCObject() {} + RGCObject(Object::DataPtr data) : Object{std::move(data)} {} + RGCObject(const AGCObject * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup mm-gcobject-router-methods **/ + ///@{ + + // explicit injected content + + // builtin methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods + size_type shallow_size() const noexcept { + return O::iface()->shallow_size(O::data()); + } + Opaque shallow_copy(obj mm) const noexcept { + return O::iface()->shallow_copy(O::data(), mm); + } + + // non-const methods (still const in router!) + size_type forward_children(obj gc) noexcept { + return O::iface()->forward_children(O::data(), gc); + } + + ///@} + /** @defgroup mm-gcobject-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RGCObject::_valid = xo::facet::valid_object_router(); + +} /*namespace mm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::mm::RGCObject; + }; +} } + +/* end RGCObject.hpp */ diff --git a/src/gc/IGCObject_Any.cpp b/src/gc/IGCObject_Any.cpp new file mode 100644 index 0000000..95c8cc8 --- /dev/null +++ b/src/gc/IGCObject_Any.cpp @@ -0,0 +1,48 @@ +/** @file IGCObject_Any.cpp + * + **/ + +#include "detail/IGCObject_Any.hpp" +#include +#include + +namespace xo { +namespace mm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +IGCObject_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " IGCObject_Any method" + << std::endl; + std::terminate(); +} + +typeseq +IGCObject_Any::s_typeseq = typeseq::id(); + +bool +IGCObject_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + +auto +IGCObject_Any::forward_children(Opaque, obj) const noexcept -> size_type +{ + _fatal(); +} + + +} /*namespace mm*/ +} /*namespace xo*/ + +/* end IGCObject_Any.cpp */