Merge branch 'claude1'

This commit is contained in:
Roland Conybeare 2026-02-18 12:39:43 -05:00
commit 625ecf20c5
711 changed files with 40140 additions and 1136 deletions

View file

@ -102,10 +102,12 @@ add_subdirectory(xo-alloc2) # experiment w/ facet object model
add_subdirectory(xo-gc)
add_subdirectory(xo-object)
add_subdirectory(xo-object2) # experiment w/ facet object model
add_subdirectory(xo-procedure2) # schematika procedure abstraction + runtime context (fomo)
add_subdirectory(xo-ordinaltree)
#
add_subdirectory(xo-tokenizer2) # schematika tokenizer (fomo)
add_subdirectory(xo-expression2) # schematika expressions (fomo)
add_subdirectory(xo-reader2) # schematika expression parser (fomo)
add_subdirectory(xo-interpreter2) # schematika interpreter (fomo)
#
add_subdirectory(xo-webutil)

View file

@ -59,6 +59,20 @@ let
});
};
# ghostty tests require ptys
ghostty-overlay = self: super: {
ghostty = super.ghostty.overrideAttrs (old: {
doCheck = false;
});
};
# fish tests require ptys
fish-overlay = self: super: {
fish = super.fish.overrideAttrs (old: {
doCheck = false;
});
};
# # nixGL not present in my nixpkgs snapshot
# nixgl-overlay = self: super: {
# nixGL = import (self.fetchFromGitHub {
@ -192,6 +206,8 @@ let
swtpm-overlay
mailutils-overlay
notmuch-overlay
ghostty-overlay
fish-overlay
# nixgl-overlay
# llvm-overlay
xo-overlay
@ -240,6 +256,10 @@ let
pkgs.emacsPackages.notmuch
pkgs.inconsolata-lgc
pkgs.fontconfig
pkgs.ghostty
pkgs.timg
pkgs.fish
pkgs.nushell
];
# xo general-purpose devutils

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0.0.0

View file

@ -1 +0,0 @@
libEGL_nvidia.so.580.95.05

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.0

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.580.95.05

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.580.95.05

1
etc/hostubuntu/libdrm.so Symbolic link
View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libdrm.so

1
etc/hostubuntu/libdrm.so.2 Symbolic link
View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libdrm.so.2

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0

1
etc/hostubuntu/libgbm.so Symbolic link
View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libgbm.so

1
etc/hostubuntu/libgbm.so.1 Symbolic link
View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libgbm.so.1

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libgbm.so.1.0.0

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.580.95.05

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libnvidia-glsi.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libnvidia-glsi.so.580.95.05

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libnvidia-glvkspirv.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libnvidia-glvkspirv.so.580.95.05

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libnvidia-gpucomp.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libnvidia-gpucomp.so.580.95.05

View file

@ -0,0 +1 @@
/usr/lib/x86_64-linux-gnu/libnvidia-tls.so.580.126.09

View file

@ -1 +0,0 @@
/usr/lib/x86_64-linux-gnu/libnvidia-tls.so.580.95.05

View file

@ -1,16 +1,16 @@
/* GcStatistics.hpp
/** @file GcStatistics.hpp
*
* author: Roland Conybeare, Aug 2025
*/
* @author Roland Conybeare, Aug 2025
**/
#pragma once
#include "generation.hpp"
#include "CircularBuffer.hpp"
#include "xo/reflect/TypeDescr.hpp"
#include "xo/unit/quantity.hpp"
#include "xo/unit/quantity_iostream.hpp"
#include "xo/indentlog/print/pretty.hpp"
#include <xo/reflect/TypeDescr.hpp>
#include <xo/unit/quantity.hpp>
#include <xo/unit/quantity_iostream.hpp>
#include <xo/indentlog/print/pretty.hpp>
#include <ostream>
#include <array>

View file

@ -18,6 +18,22 @@ add_definitions(${PROJECT_CXX_FLAGS})
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacet(
TARGET xo-alloc2-facet-resourcevisitor
FACET ResourceVisitor
INPUT idl/ResourceVisitor.json5
OUTPUT_HPP_DIR include/xo/alloc2
OUTPUT_IMPL_SUBDIR visitor
)
# ----------------------------------------------------------------
xo_add_genfacet_all(xo-alloc2-genfacet-all)
# ----------------------------------------------------------------
# must complete definition of expression lib before configuring examples
add_subdirectory(src/alloc2)
add_subdirectory(utest)

View file

@ -0,0 +1,52 @@
{
mode: "facet",
output_cpp_dir: "src/alloc2",
output_hpp_dir: "include/xo/alloc2",
output_impl_subdir: "visitor",
includes: [
"\"Allocator.hpp\""
],
// extra includes in ResourceVisitor.hpp, if any
user_hpp_includes: [],
namespace1: "xo",
namespace2: "mm",
// text after includes, before AResourceVisitor
pretext: [ "// {pretext} here" ],
facet: "ResourceVisitor",
detail_subdir: "visitor",
brief: "visitor to inspect resource consumption",
using_doxygen: true,
doc: [
"Visitor to receive measured resource consumption"
],
types: [
// using size_type = std::size_t
{
name: "size_type",
doc: ["type for length of a sequence"],
definition: "std::size_t",
},
// // using AGCObject = xo::mm::AGCObject
// {
// name: "AGCObject",
// doc: ["facet for types with GC support"],
// definition: "xo::mm::AGCObject",
// }
],
const_methods: [
// bool on_memory(name, allocated, committed, reserved) const noexcept
{
name: "on_allocator",
doc: ["report memory consumption"],
return_type: "void",
args: [
{type: "obj<AAllocator>", name: "mm"},
],
const: true,
noexcept: true,
attributes: [],
},
],
nonconst_methods: [
],
}

View file

@ -0,0 +1,17 @@
/** @file Arena.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
// reminder: we can't put this AAllocator
// (or APrintable for that matter) support in xo-arena,
// because xo-arena is a dependency of xo-facet, which is in turn
// a dependency of xo-alloc2
//
#include <xo/arena/DArena.hpp>
#include "arena/IAllocator_DArena.hpp"
/* end Arena.hpp */

View file

@ -0,0 +1,22 @@
/** @file ResourceVisitor.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/ResourceVisitor.json5]
* 2. jinja2 template for facet .hpp file:
* [facet.hpp.j2]
* 3. idl for facet methods
* [idl/ResourceVisitor.json5]
**/
#pragma once
#include "visitor/AResourceVisitor.hpp"
#include "visitor/IResourceVisitor_Any.hpp"
#include "visitor/IResourceVisitor_Xfer.hpp"
#include "visitor/RResourceVisitor.hpp"
/* end ResourceVisitor.hpp */

View file

@ -0,0 +1,116 @@
/** @file abox.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include "Allocator.hpp"
#include <xo/facet/obj.hpp>
#include <cassert>
namespace xo {
namespace mm {
/** object with owned state
* - with default DRepr argument:
* type-erased container (runtime polymorphism).
* - with sepcific DRepr argument:
* typed container (comptime polymorphism).
*
* Similar to box<AFacet,DRepr> (see box.hpp in xo-facet/):
* 1. inherits fat object pointer with AFacet*, DRepr* pair
* 2. automatically calls polymorphic DRepr::~DRepr when
* abox goes out of scope.
* Unlike box<AFacet,DRepr>:
* 3. gets memory from explicit arena-like allocator
* 4. calls dtor DRepr::~DRepr(), but not delete.
* Does not retain allocator.
**/
template <typename AFacet, typename DRepr = xo::facet::DVariantPlaceholder>
struct abox : public xo::facet::RoutingType<AFacet, xo::facet::OObject<AFacet, DRepr>> {
using DVariantPlaceholder = xo::facet::DVariantPlaceholder;
using Super = xo::facet::RoutingType<AFacet, xo::facet::OObject<AFacet, DRepr>>;
abox() : Super() {}
/** abox takes ownership of data @p *d;
* will destroy when abox goes out of scope.
*
* Note this is not useful when DRepr=DVariablePlaceholder
**/
explicit abox(Super::DataPtr d) : Super(d) {}
/** Adopt instance that has interface @p iface and (type-erased here)
* representation @p data
**/
abox(const AFacet * iface, void * data)
requires std::is_same_v<DRepr, DVariantPlaceholder>
: Super(iface, data)
{}
/** (copy ctor not supported -- ownership is unique) **/
abox(const abox & other) = delete;
/** Move constructor **/
template <typename DOther>
abox(abox<AFacet, DOther> && other)
requires (std::is_same_v<DRepr, DVariantPlaceholder>
|| std::is_same_v<DRepr, DOther>)
: xo::facet::RoutingType<AFacet,xo::facet::OObject<AFacet,DRepr>>()
{
/* replacing .iface_ along w/ .data_ */
this->from_obj(other);
other.reset_opaque(nullptr);
}
/** allocates for sizeof(DRepr), so DRepr must not use flexible array **/
template <typename... Args>
static abox make(obj<AAllocator> alloc, Args&&... args) {
void * mem = alloc.alloc_for<DRepr>();
if (mem) {
DRepr * data = ::new (mem) DRepr(std::forward<Args>(args)...);
assert(data);
return abox(data);
} else {
assert(false);
return abox();
}
}
// --------------------------------
/** explicit conversion to obj<AFacet,DRepr> **/
obj<AFacet, DRepr> to_op() const noexcept {
return obj<AFacet, DRepr>(this->iface(), this->data());
}
/** Take ownership from unowned object **/
template <typename DOther>
abox & adopt(const obj<AFacet, DOther> & other)
requires (std::is_same_v<DRepr, DVariantPlaceholder>
|| std::is_same_v<DRepr, DOther>)
{
/* replace .iface_ along w/ .data_ */
this->from_obj(other);
return *this;
}
~abox() {
auto p = this->data();
if (p) {
this->_drop();
}
}
};
} /*namespace mm*/
using mm::abox;
} /*namespace xo*/
/* end abox.hpp */

View file

@ -5,6 +5,7 @@
#pragma once
#include <xo/arena/MemorySizeInfo.hpp>
#include <xo/arena/AllocError.hpp>
#include "AllocInfo.hpp"
//#include "AllocIterator.hpp"
@ -33,9 +34,11 @@ namespace xo {
struct AAllocator {
/** @defgroup mm-allocator-type-traits allocator type traits **/
///@{
/** @brief type used for allocation amounts **/
/** memory size report **/
using MemorySizeInfo = xo::mm::MemorySizeInfo;
/** type used for allocation amounts **/
using size_type = std::size_t;
/** @brief type used for allocation responses **/
/** type used for allocation responses **/
using value_type = std::byte *;
/** object header, if configured **/
using header_type = std::uint64_t;
@ -62,6 +65,10 @@ namespace xo {
/** RTTI: unique id# for actual runtime data representation **/
virtual typeseq _typeseq() const noexcept = 0;
/** destroy instance @p d. Calls c++ destructor for actual runtime type.
* does not recover memory.
**/
virtual void _drop(Opaque d) const noexcept = 0;
/** optional name for allocator @p d .
* Allows labeling allocators, for diagnostics/instrumentation.
**/
@ -91,6 +98,12 @@ namespace xo {
* Includes alloc headers and guard regions
**/
virtual size_type allocated(Copaque d) const noexcept = 0;
/** call @p fn(i,n,info) for each memory pool owned by this allocator.
* Note: using std::function instead of obj<> to avoid leveling trouble
* with DArena
**/
virtual void visit_pools(Copaque d,
const MemorySizeVisitor & fn) const = 0;
/** true iff allocator @p d is responsible for memory at address @p p.
**/
virtual bool contains(Copaque d, const void * p) const noexcept = 0;
@ -142,10 +155,6 @@ namespace xo {
virtual value_type alloc_copy(Opaque d, value_type src) const = 0;
/** reset allocator @p d to empty state. **/
virtual void clear(Opaque d) const = 0;
/** Destruct allocator @p d.
* Releases allocator memory to operating system.
**/
virtual void destruct_data(Opaque d) const = 0;
///@}
}; /*AAllocator*/

View file

@ -32,7 +32,10 @@ namespace xo {
const AAllocator * iface() const { return std::launder(this); }
// from AAllocator
// builtin methods
typeseq _typeseq() const noexcept override { return s_typeseq; }
void _drop(Opaque) const noexcept override { _fatal(); }
// const methods
[[noreturn]] std::string_view name(Copaque) const noexcept override { _fatal(); }
@ -42,6 +45,8 @@ namespace xo {
[[noreturn]] size_type available(Copaque) const noexcept override { _fatal(); }
[[noreturn]] size_type allocated(Copaque) const noexcept override { _fatal(); }
[[noreturn]] bool contains(Copaque, const void *) const noexcept override { _fatal(); }
[[noreturn]] void visit_pools(Copaque,
const MemorySizeVisitor &) const override { _fatal(); }
[[noreturn]] AllocError last_error(Copaque) const noexcept override { _fatal(); }
[[noreturn]] AllocInfo alloc_info(Copaque, value_type) const noexcept override { _fatal(); }
// defn in .cpp - problematic to require compiler know vt<AAllocIterator> defn here
@ -55,7 +60,6 @@ namespace xo {
[[noreturn]] value_type sub_alloc(Opaque, std::size_t, bool) const override { _fatal(); }
[[noreturn]] value_type alloc_copy(Opaque, value_type) const override { _fatal(); }
[[noreturn]] void clear(Opaque) const override { _fatal(); }
[[noreturn]] void destruct_data(Opaque) const override { _fatal(); }
private:
[[noreturn]] static void _fatal();

View file

@ -36,10 +36,14 @@ namespace xo {
// from AAllocator
// const methods
// builtin methods
/** return typeseq for @tparam DRepr **/
typeseq _typeseq() const noexcept override { return s_typeseq; }
/** invoke native c++ dtor **/
void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); }
// const methods
std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); }
size_type reserved(Copaque d) const noexcept override { return I::reserved(_dcast(d)); }
size_type size(Copaque d) const noexcept override { return I::size(_dcast(d)); }
@ -49,6 +53,7 @@ namespace xo {
bool contains(Copaque d, const void * p) const noexcept override {
return I::contains(_dcast(d), p);
}
void visit_pools(Copaque d, const MemorySizeVisitor & fn) const override { I::visit_pools(_dcast(d), fn); }
AllocError last_error(Copaque d) const noexcept override { return I::last_error(_dcast(d)); }
AllocInfo alloc_info(Copaque d, value_type mem) const noexcept override {
return I::alloc_info(_dcast(d), mem);
@ -73,7 +78,6 @@ namespace xo {
value_type alloc_copy(Opaque d,
value_type src) const override { return I::alloc_copy(_dcast(d), src); }
void clear(Opaque d) const override { return I::clear(_dcast(d)); }
void destruct_data(Opaque d) const override { return I::destruct_data(_dcast(d)); }
///@}
private:

View file

@ -27,14 +27,40 @@ namespace xo {
RAllocator() {}
RAllocator(Object::DataPtr data) : Object{std::move(data)} {}
RAllocator(const AAllocator * iface, void * data)
requires std::is_same_v<typename Object::DataType, xo::facet::DVariantPlaceholder>
: Object(iface, data) {}
template <typename T>
void * alloc_for(size_type n = sizeof(T)) noexcept {
return O::iface()->alloc(O::data(), typeseq::id<T>(), n);
}
template <typename T>
void * alloc_copy_for(const T * src) noexcept {
return O::iface()->alloc_copy(O::data(), (std::byte*)const_cast<T *>(src));
}
template <typename T>
T * std_copy_for(const T * src) noexcept {
T * copy = (T *)(this->alloc_copy_for(src));
if (copy) {
*copy = *src;
}
return copy;
}
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
void _drop() const noexcept { O::iface()->_drop(O::data()); }
std::string_view name() const noexcept { return O::iface()->name(O::data()); }
size_type reserved() const noexcept { return O::iface()->reserved(O::data()); }
size_type size() const noexcept { return O::iface()->size(O::data()); }
size_type committed() const noexcept { return O::iface()->committed(O::data()); }
size_type available() const noexcept { return O::iface()->available(O::data()); }
size_type allocated() const noexcept { return O::iface()->allocated(O::data()); }
void visit_pools(const MemorySizeVisitor & fn) const { O::iface()->visit_pools(O::data(), fn); }
bool contains(const void * p) const noexcept { return O::iface()->contains(O::data(), p); }
AllocError last_error() const noexcept { return O::iface()->last_error(O::data()); }
AllocInfo alloc_info(value_type mem) const noexcept { return O::iface()->alloc_info(O::data(), mem); }

View file

@ -0,0 +1,15 @@
/** @file alloc2_register_facets.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
namespace xo {
namespace mm {
/** Register alloc2 (facet,impl) combinations with Facet Registry **/
bool alloc2_register_facets();
}
}
/* end alloc2_register_facets.hpp */

View file

@ -40,6 +40,8 @@ namespace xo {
static size_type committed(const DArena &) noexcept;
static size_type available(const DArena &) noexcept;
static size_type allocated(const DArena &) noexcept;
static void visit_pools(const DArena &,
const MemorySizeVisitor & visitor);
static bool contains(const DArena &, const void * p) noexcept;
static AllocError last_error(const DArena &) noexcept;
/** retrieve allocation bookkeeping info for @p mem from arena @p d **/

View file

@ -0,0 +1,112 @@
/** @file dp.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include "Allocator.hpp"
#include <xo/facet/obj.hpp>
#include <cassert>
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<AFacet,DRepr>
**/
template <typename DRepr>
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<DRepr> && other)
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
/** allocates for sizeof(DRepr), so DRepr must not use flexible array **/
template <typename... Args>
static dp make(obj<AAllocator> alloc, Args&&... args) {
void * mem = alloc.alloc_for<DRepr>();
if (mem) {
DRepr * data = ::new (mem) DRepr(std::forward<Args>(args)...);
assert(data);
return dp(data);
} else {
assert(false);
return dp();
}
}
dp<DRepr> & operator=(const dp<DRepr> & x) = delete;
/** move assignment **/
dp<DRepr> & operator=(dp<DRepr> && 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_; }
#ifdef NOT_YET
/** explicit conversion to obj<AFacet,DRepr> **/
obj<AFacet, DRepr> to_op() const noexcept {
return obj<AFacet, DRepr>(this->iface(), this->data());
}
#endif
#ifdef NOT_YET
/** Take ownership from unowned object **/
template <typename AFacet>
dp & adopt(const obj<AFacet, DRepr> & other)
requires (std::is_same_v<DRepr, DVariantPlaceholder>
|| std::is_same_v<DRepr, DOther>)
{
/* 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 */

View file

@ -0,0 +1,23 @@
/** @file init_alloc2.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include <xo/subsys/Subsystem.hpp>
namespace xo {
/* tag to represent the xo-alloc2/ subsystem within ordered initialization */
enum S_alloc2_tag {};
template <>
struct InitSubsys<S_alloc2_tag> {
static void init();
static InitEvidence require();
};
} /*namespace xo*/
/* end init_alloc2.hpp */

View file

@ -0,0 +1,76 @@
/** @file AResourceVisitor.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/ResourceVisitor.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [abstract_facet.hpp.j2]
* 3. idl for facet methods
* [idl/ResourceVisitor.json5]
**/
#pragma once
// includes (via {facet_includes})
#include "Allocator.hpp"
#include <xo/facet/obj.hpp>
#include <xo/facet/facet_implementation.hpp>
#include <xo/facet/typeseq.hpp>
// {pretext} here
namespace xo {
namespace mm {
using Copaque = const void *;
using Opaque = void *;
/**
Visitor to receive measured resource consumption
**/
class AResourceVisitor {
public:
/** @defgroup mm-resourcevisitor-type-traits **/
///@{
// types
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
using Copaque = const void *;
using Opaque = void *;
/** type for length of a sequence **/
using size_type = std::size_t;
///@}
/** @defgroup mm-resourcevisitor-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;
/** report memory consumption **/
virtual void on_allocator(Copaque data, obj<AAllocator> mm) const noexcept = 0;
// nonconst methods
///@}
}; /*AResourceVisitor*/
/** Implementation IResourceVisitor_DRepr of AResourceVisitor for state DRepr
* should provide a specialization:
*
* template <>
* struct xo::facet::FacetImplementation<AResourceVisitor, DRepr> {
* using Impltype = IResourceVisitor_DRepr;
* };
*
* then IResourceVisitor_ImplType<DRepr> --> IResourceVisitor_DRepr
**/
template <typename DRepr>
using IResourceVisitor_ImplType = xo::facet::FacetImplType<AResourceVisitor, DRepr>;
} /*namespace mm*/
} /*namespace xo*/
/* AResourceVisitor.hpp */

View file

@ -0,0 +1,89 @@
/** @file IResourceVisitor_Any.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/ResourceVisitor.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/ResourceVisitor.json5]
**/
#pragma once
#include "AResourceVisitor.hpp"
#include <xo/facet/obj.hpp>
namespace xo { namespace mm { class IResourceVisitor_Any; } }
namespace xo {
namespace facet {
template <>
struct FacetImplementation<xo::mm::AResourceVisitor,
DVariantPlaceholder>
{
using ImplType = xo::mm::IResourceVisitor_Any;
};
}
}
namespace xo {
namespace mm {
/** @class IResourceVisitor_Any
* @brief AResourceVisitor implementation for empty variant instance
**/
class IResourceVisitor_Any : public AResourceVisitor {
public:
/** @defgroup mm-resourcevisitor-any-type-traits **/
///@{
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
using size_type = AResourceVisitor::size_type;
///@}
/** @defgroup mm-resourcevisitor-any-methods **/
///@{
const AResourceVisitor * iface() const { return std::launder(this); }
// from AResourceVisitor
// builtin methods
typeseq _typeseq() const noexcept override { return s_typeseq; }
[[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); }
// const methods
[[noreturn]] void on_allocator(Copaque, obj<AAllocator>) const noexcept override { _fatal(); }
// nonconst methods
///@}
private:
/** @defgraoup mm-resourcevisitor-any-private-methods **/
///@{
[[noreturn]] static void _fatal();
///@}
public:
/** @defgroup mm-resourcevisitor-any-member-vars **/
///@{
static typeseq s_typeseq;
static bool _valid;
///@}
};
} /*namespace mm */
} /*namespace xo */
/* IResourceVisitor_Any.hpp */

View file

@ -0,0 +1,84 @@
/** @file IResourceVisitor_Xfer.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/ResourceVisitor.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/ResourceVisitor.json5]
**/
#pragma once
#include "Allocator.hpp"
namespace xo {
namespace mm {
/** @class IResourceVisitor_Xfer
**/
template <typename DRepr, typename IResourceVisitor_DRepr>
class IResourceVisitor_Xfer : public AResourceVisitor {
public:
/** @defgroup mm-resourcevisitor-xfer-type-traits **/
///@{
/** actual implementation (not generated; often delegates to DRepr) **/
using Impl = IResourceVisitor_DRepr;
/** integer identifying a type **/
using typeseq = AResourceVisitor::typeseq;
using size_type = AResourceVisitor::size_type;
///@}
/** @defgroup mm-resourcevisitor-xfer-methods **/
///@{
static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
static DRepr & _dcast(Opaque d) { return *(DRepr *)d; }
// from AResourceVisitor
// builtin methods
typeseq _typeseq() const noexcept override { return s_typeseq; }
void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); }
// const methods
void on_allocator(Copaque data, obj<AAllocator> mm) const noexcept override {
return I::on_allocator(_dcast(data), mm);
}
// non-const methods
///@}
private:
using I = Impl;
public:
/** @defgroup mm-resourcevisitor-xfer-member-vars **/
///@{
/** typeseq for template parameter DRepr **/
static typeseq s_typeseq;
/** true iff satisfies facet implementation **/
static bool _valid;
///@}
};
template <typename DRepr, typename IResourceVisitor_DRepr>
xo::facet::typeseq
IResourceVisitor_Xfer<DRepr, IResourceVisitor_DRepr>::s_typeseq
= xo::facet::typeseq::id<DRepr>();
template <typename DRepr, typename IResourceVisitor_DRepr>
bool
IResourceVisitor_Xfer<DRepr, IResourceVisitor_DRepr>::_valid
= xo::facet::valid_facet_implementation<AResourceVisitor,
IResourceVisitor_Xfer>();
} /*namespace mm */
} /*namespace xo*/
/* end IResourceVisitor_Xfer.hpp */

View file

@ -0,0 +1,85 @@
/** @file RResourceVisitor.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/ResourceVisitor.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/ResourceVisitor.json5]
**/
#pragma once
#include "AResourceVisitor.hpp"
namespace xo {
namespace mm {
/** @class RResourceVisitor
**/
template <typename Object>
class RResourceVisitor : public Object {
private:
using O = Object;
public:
/** @defgroup mm-resourcevisitor-router-type-traits **/
///@{
using ObjectType = Object;
using DataPtr = Object::DataPtr;
using typeseq = xo::reflect::typeseq;
using size_type = AResourceVisitor::size_type;
///@}
/** @defgroup mm-resourcevisitor-router-ctors **/
///@{
RResourceVisitor() {}
RResourceVisitor(Object::DataPtr data) : Object{std::move(data)} {}
RResourceVisitor(const AResourceVisitor * iface, void * data)
requires std::is_same_v<typename Object::DataType, xo::facet::DVariantPlaceholder>
: Object(iface, data) {}
///@}
/** @defgroup mm-resourcevisitor-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
void on_allocator(obj<AAllocator> mm) const noexcept {
return O::iface()->on_allocator(O::data(), mm);
}
// non-const methods (still const in router!)
///@}
/** @defgroup mm-resourcevisitor-member-vars **/
///@{
static bool _valid;
///@}
};
template <typename Object>
bool
RResourceVisitor<Object>::_valid = xo::facet::valid_object_router<Object>();
} /*namespace mm*/
} /*namespace xo*/
namespace xo { namespace facet {
template <typename Object>
struct RoutingFor<xo::mm::AResourceVisitor, Object> {
using RoutingType = xo::mm::RResourceVisitor<Object>;
};
} }
/* end RResourceVisitor.hpp */

View file

@ -3,24 +3,22 @@
set(SELF_LIB xo_alloc2)
set(SELF_SRCS
# AllocError.cpp
# AllocInfo.cpp
# cmpresult.cpp
init_alloc2.cpp
alloc2_register_facets.cpp
AAllocator.cpp
# ArenaConfig.cpp
# DArena.cpp
IAllocator_Any.cpp
IAllocator_DArena.cpp
IAllocIterator_Any.cpp
# DArenaIterator.cpp
IAllocIterator_DArenaIterator.cpp
IResourceVisitor_Any.cpp
)
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
# note: deps here must also appear in cmake/xo_alloc2Config.cmake.in
xo_dependency(${SELF_LIB} xo_arena)
xo_dependency(${SELF_LIB} xo_facet)
xo_dependency(${SELF_LIB} subsys)
xo_dependency(${SELF_LIB} indentlog)

View file

@ -52,6 +52,13 @@ namespace xo {
return s.allocated();
}
void
IAllocator_DArena::visit_pools(const DArena & s,
const MemorySizeVisitor & visitor)
{
s.visit_pools(visitor);
}
bool
IAllocator_DArena::contains(const DArena & s,
const void * p) noexcept

View file

@ -0,0 +1,41 @@
/** @file IResourceVisitor_Any.cpp
*
**/
#include "visitor/IResourceVisitor_Any.hpp"
#include <iostream>
namespace xo {
namespace mm {
using xo::facet::DVariantPlaceholder;
using xo::facet::typeseq;
using xo::facet::valid_facet_implementation;
void
IResourceVisitor_Any::_fatal()
{
/* control here on uninitialized IAllocator_Any.
* Initialized instance will have specific implementation type
*/
std::cerr << "fatal"
<< ": attempt to call uninitialized"
<< " IResourceVisitor_Any method"
<< std::endl;
std::terminate();
}
typeseq
IResourceVisitor_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool
IResourceVisitor_Any::_valid
= valid_facet_implementation<AResourceVisitor, IResourceVisitor_Any>();
// nonconst methods
} /*namespace mm*/
} /*namespace xo*/
/* end IResourceVisitor_Any.cpp */

View file

@ -0,0 +1,33 @@
/** @file alloc2_register_facets.cpp
*
* @author Roland Conybeare, Feb 2026
**/
#include "alloc2_register_facets.hpp"
#include <xo/alloc2/Arena.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/indentlog/scope.hpp>
namespace xo {
using xo::facet::FacetRegistry;
//using xo::facet::TypeRegistry;
using xo::reflect::typeseq;
namespace mm {
bool
alloc2_register_facets()
{
scope log(XO_DEBUG(true));
FacetRegistry::register_impl<AAllocator, DArena>();
log && log(xtag("DArena.tseq", typeseq::id<DArena>()));
return true;
}
} /*namespace scm*/
} /*namespace xo*/
/* end alloc2_register_facets.cpp */

View file

@ -0,0 +1,36 @@
/** @file init_alloc2.cpp
*
* @author Roland Conybeare, Feb 2026
**/
#include "init_alloc2.hpp"
#include "alloc2_register_facets.hpp"
namespace xo {
using xo::mm::alloc2_register_facets;
// using xo::mm::alloc2_register_types;
// using xo::mm::CollectorTypeRegistry;
void
InitSubsys<S_alloc2_tag>::init()
{
alloc2_register_facets();
}
InitEvidence
InitSubsys<S_alloc2_tag>::require()
{
InitEvidence retval;
/* direct subsystem deps for xo-alloc2/ (if/when) */
//retval ^= InitSubsys<S_foo_tag>>::require();
/* xo-alloc2/'s own initialization code */
retval ^= Subsystem::provide<S_alloc2_tag>("alloc2", &init);
return retval;
}
} /*namespace xo*/
/* end init_alloc2.cpp */

View file

@ -169,7 +169,7 @@ namespace xo {
/* arbitrary alloc size */
size_t req_z = 13;
byte * mem = a1o.alloc(typeseq::anon(), req_z);
byte * mem = a1o.alloc(typeseq::sentinel(), req_z);
REQUIRE(arena.error_count_ == 0);
REQUIRE(mem != nullptr);

View file

@ -159,7 +159,7 @@ namespace xo {
REQUIRE(a1o.allocated() == 0);
size_t z0 = 1;
byte * m0 = a1o.alloc(typeseq::anon(), 1);
byte * m0 = a1o.alloc(typeseq::sentinel(), 1);
REQUIRE(m0);
REQUIRE(a1o.last_error().error_ == error::ok);
@ -171,7 +171,7 @@ namespace xo {
REQUIRE(a1o.committed() <= a1o.reserved());
size_t z1 = 16;
byte * m1 = a1o.alloc(typeseq::anon(), z1);
byte * m1 = a1o.alloc(typeseq::sentinel(), z1);
REQUIRE(m1);
REQUIRE(a1o.last_error().error_ == error::ok);
@ -209,7 +209,7 @@ namespace xo {
REQUIRE(a1o.allocated() == 0);
size_t z0 = 1;
byte * m0 = a1o.alloc(typeseq::anon(), 1);
byte * m0 = a1o.alloc(typeseq::sentinel(), 1);
REQUIRE(m0);
@ -253,7 +253,7 @@ namespace xo {
REQUIRE(a1o.allocated() == 0);
size_t z0 = 1;
byte * m0 = a1o.alloc(typeseq::anon(), 1);
byte * m0 = a1o.alloc(typeseq::sentinel(), 1);
REQUIRE(m0);
@ -306,7 +306,7 @@ namespace xo {
REQUIRE(a1o.allocated() == 0);
size_t z0 = cfg.hugepage_z_ + 1;
byte * m0 = a1o.alloc(typeseq::anon(), z0);
byte * m0 = a1o.alloc(typeseq::sentinel(), z0);
REQUIRE(!m0);

View file

@ -67,7 +67,7 @@ namespace utest {
bool ok_flag = true;
std::byte * mem = mm.alloc(typeseq::anon(), z);
std::byte * mem = mm.alloc(typeseq::sentinel(), z);
log && log(xtag("i_alloc", i_alloc),
xtag("si", si),

View file

@ -11,6 +11,13 @@
namespace xo {
namespace mm {
/** @brief per-alloc header
*
* Appears immediately before each allocation when
* ArenaConfig.store_header_flag_ is set.
*
* See AllocInfo.hpp for encoding of @ref repr_
**/
struct AllocHeader {
using repr_type = std::uintptr_t;
using size_type = std::size_t;

View file

@ -17,6 +17,30 @@ namespace xo {
* @brief configuration for a @ref DArena instance
**/
struct ArenaConfig {
/** @defgroup mm-arenaconfig-ctors **/
///@{
/** NOTE: not providing explicit ctors so we can use designated initializers **/
ArenaConfig with_name(std::string name) const {
ArenaConfig copy(*this);
copy.name_ = name;
return copy;
}
ArenaConfig with_size(std::size_t z) const {
ArenaConfig copy(*this);
copy.size_ = z;
return copy;
}
ArenaConfig with_store_header_flag(bool x) const {
ArenaConfig copy(*this);
copy.store_header_flag_ = x;
return copy;
}
///@}
/** @defgroup mm-arenaconfig-instance-vars ArenaConfig members **/
///@{
@ -30,7 +54,7 @@ namespace xo {
std::size_t hugepage_z_ = 2 * 1024 * 1024;
/** true to store header (8 bytes) at the beginning of each allocation.
* necessary and sufficient to allows iterating over allocs
* present in arena
* present in arena.
**/
bool store_header_flag_ = false;
/** configuration for per-alloc header **/

View file

@ -0,0 +1,58 @@
/** @file ArenaHashMapConfig.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include <string>
#include <cstdint>
namespace xo {
namespace map {
/** @class ArenaHashMapConfig
*
* @brief configuration for a @ref DArenaHashMap instance
**/
struct ArenaHashMapConfig {
/** @defgroup map-arenahashmapconfig-ctors **/
///@{
ArenaHashMapConfig with_name(std::string name) const {
ArenaHashMapConfig copy(*this);
copy.name_ = name;
return copy;
}
ArenaHashMapConfig with_hint_max_capacity(std::size_t z) const {
ArenaHashMapConfig copy(*this);
copy.hint_max_capacity_ = z;
return copy;
}
ArenaHashMapConfig with_debug_flag(bool x) const {
ArenaHashMapConfig copy(*this);
copy.debug_flag_ = x;
return copy;
}
///@}
/** @defgroup mm-arenahashmapconfig-instance-vars ArenaHashMapConfig members **/
///@{
/** optional name, for diagnostics **/
std::string name_;
/** desired hard max hashmap size -> reserved virtual memory
* hint: actual max may be larger, because of power-of-2 considerations.
**/
std::size_t hint_max_capacity_ = 0;
/** true to enable debug logging **/
bool debug_flag_ = false;
///@}
};
} /*namespace map*/
} /*namespace xo*/
/* end ArenaHashMapConfig.hpp */

View file

@ -7,6 +7,7 @@
#include "ArenaConfig.hpp"
#include "AllocError.hpp"
#include "MemorySizeInfo.hpp"
#include "AllocInfo.hpp"
#include <xo/reflectutil/typeseq.hpp>
@ -62,6 +63,13 @@ namespace xo {
sub_complete,
};
/** @brief Checkpoint for unwinding arena state **/
struct Checkpoint {
Checkpoint() = default;
explicit Checkpoint(std::byte * x) : free_{x} {}
std::byte * free_ = nullptr;
};
///@}
/** @defgroup mm-arena-ctors arena constructors and destructors **/
@ -72,7 +80,9 @@ namespace xo {
/** null ctor **/
DArena() = default;
/** ctor from already-mapped (but not committed) address range **/
/** create arena from @p cfg. Will reserve memory for allocation **/
DArena(const ArenaConfig & cfg);
/** ctor from already-mapped (but not committed) address range [lo,hi] **/
DArena(const ArenaConfig & cfg,
size_type page_z,
size_type arena_align_z,
@ -115,34 +125,6 @@ namespace xo {
**/
bool contains(const void * addr) const noexcept { return (lo_ <= addr) && (addr < hi_); }
#ifdef OBSOLETE
/** obtain uncommitted contiguous memory range comprising
* a whole multiple of @p align_z bytes, of at least size @p req_z,
* aligned on a @p align_z boundary. Uncommitted memory is not (yet)
* backed by physical memory.
*
* If @p enable_hugepage_flag is true and THP
* (transparent huge pages) are available, use THP for arena memory.
* This relieves TLB and page table memory when @p req_z is a lot larger than
* page size (likely 4KB). Cost is that arena will consum physical memory in unit
* of @p align_z. Arena may waste up to @p align_z bytes of memory as a result.
*
* If @p enable_hugepage_flag is true, @p align_z should be huge page size
* (probably 2MB) for optimal performance.
*
* At present the THP feature is not supported on OSX.
* May be supportable through mach_vm_allocate().
*
* Note that we reject MAP_HUGETLB|MAP_HUGE_2MB flags to mmap here,
* since requires previously-reserved memory in /proc/sys/vm/nr_hugepages.
*
* @return pair giving reserved memory address range [lo,hi)
**/
static range_type map_aligned_range(size_type req_z,
size_type align_z,
bool enable_hugepage_flag);
#endif
/** true if arena is mapped i.e. has a reserved address range **/
bool is_mapped() const noexcept { return (lo_ != nullptr) && (hi_ != nullptr); }
@ -158,6 +140,11 @@ namespace xo {
**/
AllocHeader * end_header() const noexcept;
/** report memory use for this arena to @p fn.
* For DArena reporting just one pool = arena's memory range
**/
void visit_pools(const MemorySizeVisitor & fn) const;
/** get header from allocated object address **/
header_type * obj2hdr(void * obj) noexcept;
@ -165,7 +152,8 @@ namespace xo {
*
* Require:
* 1. @p mem is address returned by allocation on this arena
* i.e. by @ref IAllocator_DArena::alloc() or @ref IAllocator_DArena::alloc_super()
* i.e. by @ref IAllocator_DArena::alloc() or
* @ref IAllocator_DArena::alloc_super()
* 2. @p mem has not been invalidated since it was allocated
* i.e. by call to @ref DArena::clear
*
@ -218,6 +206,15 @@ namespace xo {
/** create initial guard **/
void establish_initial_guard() noexcept;
/** checkpoint arena state. Revert to the same state with
* @ref restore
**/
Checkpoint checkpoint() noexcept { return Checkpoint(free_); }
/** restore arena state to previously-established checkpoint **/
void restore(Checkpoint ckp) noexcept { free_ = ckp.free_; }
/** discard all allocated memory, return to empty state
* Promise:
* - committed memory unchanged

View file

@ -5,6 +5,7 @@
#pragma once
#include "ArenaHashMapConfig.hpp"
#include "DArenaVector.hpp"
#include "hashmap/verify_policy.hpp"
#include "hashmap/HashMapStore.hpp"
@ -30,8 +31,10 @@ namespace xo {
*
* Replicates (to the extent feasible) std::unordered_map<K,V>
*
* @tparam K key type.
* @tparam V value type.
* @tparam Key key type.
* @tparam Value value type.
* @tparam Hash hash function for keys
* @tparam Equal equality function for keys
**/
template <typename Key,
typename Value,
@ -45,6 +48,7 @@ namespace xo {
using value_type = std::pair<const Key, Value>;
using key_hash = Hash;
using key_equal = Equal;
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
using byte = std::byte;
using group_type = detail::ControlGroup;
using store_type = detail::HashMapStore<Key, Value>;
@ -54,9 +58,12 @@ namespace xo {
public:
/** create hash map **/
DArenaHashMap(size_type hint_max_capacity,
DArenaHashMap(const ArenaHashMapConfig & cfg);
DArenaHashMap(const std::string & name,
size_type hint_max_capacity,
bool debug_flag = false);
DArenaHashMap(Hash && hash = Hash(),
DArenaHashMap(const std::string & name,
Hash && hash = Hash(),
Equal && eq = Equal(),
size_type hint_max_capacity = 0,
bool debug_flag = false);
@ -76,6 +83,10 @@ namespace xo {
iterator begin() { return _promote_iterator(_begin_aux()); }
iterator end() { return _promote_iterator(_end_aux()); }
void visit_pools(const MemorySizeVisitor & visitor) const {
return store_.visit_pools(visitor);
}
/** insert @p kv_pair into hash map.
* Replaces any previous value stored under the same key.
*
@ -191,9 +202,16 @@ namespace xo {
};
template <typename Key, typename Value, typename Hash, typename Equal>
DArenaHashMap<Key, Value, Hash, Equal>::DArenaHashMap(size_type hint_max_capacity,
DArenaHashMap<Key, Value, Hash, Equal>::DArenaHashMap(const ArenaHashMapConfig & cfg)
: DArenaHashMap(cfg.name_, Hash(), Equal(), cfg.hint_max_capacity_, cfg.debug_flag_)
{
}
template <typename Key, typename Value, typename Hash, typename Equal>
DArenaHashMap<Key, Value, Hash, Equal>::DArenaHashMap(const std::string & name,
size_type hint_max_capacity,
bool debug_flag)
: DArenaHashMap(Hash(), Equal(), hint_max_capacity, debug_flag)
: DArenaHashMap(name, Hash(), Equal(), hint_max_capacity, debug_flag)
{
}
@ -202,13 +220,14 @@ namespace xo {
* last 16 bytes will be copy of first 16 bytes
*/
template <typename Key, typename Value, typename Hash, typename Equal>
DArenaHashMap<Key, Value, Hash, Equal>::DArenaHashMap(Hash && hash,
DArenaHashMap<Key, Value, Hash, Equal>::DArenaHashMap(const std::string & name,
Hash && hash,
Equal && eq,
size_type hint_max_capacity,
bool debug_flag)
: hash_{std::move(hash)},
equal_{std::move(eq)},
store_{"arenahashmap", lub_exp2(lub_group_mult(hint_max_capacity))},
store_{name, lub_exp2(lub_group_mult(hint_max_capacity))},
debug_flag_{debug_flag}
{
}

View file

@ -79,6 +79,11 @@ namespace xo {
constexpr T * data() { return reinterpret_cast<T*>(store_.lo_); }
constexpr const T * data() const { return reinterpret_cast<const T*>(store_.lo_); }
/** arena used for element storage
* (Might prefer obj<AResourceVisitor> here; refrain to avoid leveling violation)
**/
void visit_pools(const MemorySizeVisitor & fn) const { store_.visit_pools(fn); }
/** reserve space, if possible, for at least @p z elements.
* Always limited by ArenaConfig.size_
**/
@ -109,6 +114,7 @@ namespace xo {
private:
size_type size_ = 0;
DArena store_;
DArena::Checkpoint zero_ckp_;
};
template <typename T>
@ -117,14 +123,16 @@ namespace xo {
size_type arena_align_z,
DArena::value_type lo,
DArena::value_type hi)
: store_{cfg, page_z, arena_align_z, lo, hi}
: store_{cfg, page_z, arena_align_z, lo, hi},
zero_ckp_{store_.checkpoint()}
{}
template <typename T>
DArenaVector<T>::DArenaVector(DArenaVector && other)
: size_{other.size_}, store_{std::move(other.store_)}
: size_{other.size_}, store_{std::move(other.store_)}, zero_ckp_{std::move(other.zero_ckp_)}
{
other.size_ = 0;
other.zero_ckp_ = DArena::Checkpoint();
}
template <typename T>
@ -148,8 +156,10 @@ namespace xo {
{
this->size_ = other.size_;
this->store_ = std::move(other.store_);
this->zero_ckp_ = std::move(other.zero_ckp_);
other.size_ = 0;
other.zero_ckp_ = DArena::Checkpoint();
return *this;
}
@ -161,6 +171,7 @@ namespace xo {
DArenaVector<T> retval;
retval.store_ = std::move(DArena::map(cfg));
retval.zero_ckp_ = retval.store_.checkpoint();
return retval;
}
@ -174,9 +185,11 @@ namespace xo {
template <typename T>
void
DArenaVector<T>::resize(size_type z) {
// new arena size in bytes
size_t req_z = z * sizeof(T);
if (z > size_) {
// expand arena to accomodate
size_t req_z = z * sizeof(T);
store_.expand(req_z);
@ -203,6 +216,14 @@ namespace xo {
}
}
// rewind to checkpoint, then reallocate.
// This is for form's sake, so that DArena considers memory
// to be 'allocated'. DArenaVector<T> doesn't care for itself,
// but this preserves expected behavior of visit_pools().
//
store_.restore(zero_ckp_);
store_.alloc(xo::reflect::typeseq::id<std::byte>(), req_z);
this->size_ = z;
}

View file

@ -83,6 +83,9 @@ namespace xo {
const_span_type occupied_range() const noexcept { return occupied_range_; }
const_span_type input_range() const noexcept { return input_range_; }
/** report memory-size info for this buffer to @p fn **/
void visit_pools(const MemorySizeVisitor & fn) const;
/** verify DCircularBuffer invariants.
* Act on failure according to policy @p p
* (combination of throw|log bits)

View file

@ -0,0 +1,54 @@
/** @file ErrorArena.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include "DArena.hpp"
namespace xo {
namespace mm {
/** @brief Dedicated arena for error reporting
*
* Reserving memory for error messaages.
* Motivation
* 1. so we have room to report an out-of-memory condition
* 2. so we have place to allocate for an error that
* doesn't interfere with other allocator state
*
* Expect to reset arena between errors, so only need
* enough room to report one error.
*
* To initialize explicitly:
* @code
* // before any other ErrorArena method calls:
* ErrorArena::init_once(cfg...);
*
* // do stuff with ErrorArena..
* ErrorArena::instance()
* @endcode
*
* Reminder: can't use obj<AAllocator> here,
* would be leveling violation.
**/
class ErrorArena {
public:
/** default configuration for error arena **/
static ArenaConfig default_config();
/** idempotent initialization **/
static void init_once(const ArenaConfig & cfg = default_config());
/** get initialized instnace **/
static DArena * instance();
private:
static DArena s_instance;
};
} /*namespace mm*/
} /*namespace xo*/
/* end ErrorArena.hpp */

View file

@ -0,0 +1,66 @@
/** @file MemorySizeInfo.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include <xo/reflectutil/typeseq.hpp>
#include <functional>
#include <string_view>
#include <cstddef>
namespace xo {
namespace mm {
struct MemorySizeDetail {
using typeseq = xo::reflect::typeseq;
/** identifies a c++ type T. See xo/facet/TypeRegistry **/
typeseq tseq_;
/** number of T-instances **/
uint32_t n_alloc_ = 0;
/** bytes used by T-instances **/
uint32_t z_alloc_ = 0;
};
struct MemorySizeInfo {
using size_type = std::size_t;
using DetailArrayType = std::array<MemorySizeDetail, 32>;
MemorySizeInfo() = default;
MemorySizeInfo(std::string_view name,
std::size_t u, std::size_t a, std::size_t c, std::size_t r,
DetailArrayType * detail)
: resource_name_{name},
used_{u}, allocated_{a}, committed_{c}, reserved_{r}, detail_{detail}
{}
static MemorySizeInfo sentinel() { return MemorySizeInfo(); }
/** resource name **/
std::string_view resource_name_;
/** memory used (excluding wasted space) **/
std::size_t used_ = 0;
/** memory allocated (including wasted space e.g. empty slots in hash tables **/
std::size_t allocated_ = 0;
/** memory committed (backed by physical memory) **/
std::size_t committed_ = 0;
/** memory reserved:
* virtual memory addresses range obtained, whether or not committed
**/
std::size_t reserved_ = 0;
/** optional histogram with per-data-type counts **/
DetailArrayType * detail_ = nullptr;
};
/** function that visits MemorySizeInfo for a collection of @p n memory pools.
* Each pool reported with index @p i in [0, n), with associated
* size record @p info.
**/
using MemorySizeVisitor = std::function<void (const MemorySizeInfo & info)>;
}
}
/* end MemorySizeInfo.hpp */

View file

@ -0,0 +1,236 @@
/** @file arena_streambuf.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include "DArena.hpp"
//#include "print/quoted_char.hpp"
#include <iostream>
#include <string_view>
#include <vector>
#include <cstring> // e.g. for std::memcpy()
#include <cstdint>
#include <cassert>
namespace xo {
namespace mm {
/** @brief Arena-based buffer for logging and pretty-printing
*
* Arena-based using mmap
* Write to self-extending storage array
* Track position relative to start of line
**/
class arena_streambuf : public std::streambuf {
public:
struct rewind_state {
explicit rewind_state(std::size_t solpos, std::size_t color_esc, std::uint32_t p)
: solpos{solpos}, color_escape_chars{color_esc}, pos{p} {}
std::size_t solpos = 0;
std::size_t color_escape_chars = 0;
std::uint32_t pos = 0;
};
public:
/** arena should be ready-to-allocate i.e. have committed > 0 **/
arena_streambuf(DArena * arena, bool debug_flag = false) : arena_{arena}, debug_flag_{debug_flag} {
this->reset_stream();
} /*ctor*/
std::streamsize capacity() const { return arena_->committed(); }
const char * lo() const { return this->pbase(); }
const char * hi() const { return this->lo() + this->capacity(); }
std::uint32_t pos() const { return this->pptr() - this->pbase(); }
/** output position (relative to pbase) when local state last computed. Exposed here for unit tests **/
std::size_t _local_ppos() const { return local_ppos_; }
/** position (relative to pbase) one character after last \n or \r. For unit tests **/
std::uint32_t _solpos() const { return solpos_; }
/** start of incomplete color-escape sequence **/
const char * _color_escape_start() const { return color_escape_start_; }
/** number of non-printing chars after @ref solpos_ from completed color-escape sequences **/
std::uint32_t _color_escape_chars() const { return color_escape_chars_; }
/** number of visible characters since start of line (last \n or \r) **/
std::uint32_t lpos() const;
rewind_state checkpoint() const;
bool debug_flag() const { return debug_flag_; }
operator std::string_view () const { return std::string_view(this->pbase(), this->pptr()); }
void reset_stream();
void rewind_to(rewind_state s);
protected:
/** expand buffer storage (by 2x), preserve current contents **/
void expand_to(std::size_t new_z);
virtual std::streamsize xsputn(const char * s, std::streamsize n) override;
virtual int_type overflow(int_type new_ch) override;
/* off. offset, relative to starting point dir.
* dir.
* which. in|out|both
*
* Note that off=0,dir=cur,which=out reads offset
*/
virtual pos_type seekoff(off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which) override;
private:
void _update_local_state_char(const char * p_lo, const char * p)
{
if ((*p == '\n') || (*p == '\r')) {
this->solpos_ = (p+1 - this->pbase());
/* reset, since these chars relevant as correction to solpos */
this->color_escape_chars_ = 0;
/* -> incomplete color escape, broken by newline */
this->color_escape_start_ = nullptr;
} else if (*p == '\033') {
if (debug_flag_) [[unlikely]] {
std::cout << "xsputn: \\033 at p-p_lo=" << (p - p_lo) << std::endl;
}
this->color_escape_start_ = p;
} else if (this->color_escape_start_ != nullptr) {
if (*p == 'm') {
/* escape seq non-printing including both endpoints */
std::int64_t esc_chars = (p+1 - color_escape_start_);
this->color_escape_chars_ += esc_chars;
if (debug_flag_) [[unlikely]] {
std::cout << "xsputn: m at p-p_lo" << (p - p_lo) << " +" << esc_chars
<< " -> color_escape_chars=" << color_escape_chars_ << std::endl;
}
this->color_escape_start_ = nullptr;
} else if (!isdigit(*p) && (*p != '[') && (*p != ';')) {
/* not color escape after all */
this->color_escape_start_ = nullptr;
}
}
}
/** recognize stale local state vars:
* @ref solpos_, @ref color_escape_chars_, @ref color_escape_start_.
*
* Require:
* - {pbase, pptr} in consistent state
* Promise:
* - @c local_ppos_ + @c pbase = @c pptr
* - @c solpos_, @c color_escape_chars_, @c color_escape_start_ all up-to-date
**/
void _check_update_local_state() {
const char * p0 = this->pbase();
const char * pn = this->pptr();
if (debug_flag_) {
std::cerr << "_check_update_local_state:" << std::endl;
std::cerr << " buf: (p0=" << (void*)p0 << ", pn=" << (void*)pn << ")" << std::endl;
std::cerr << " solpos_=" << solpos_ << ", color_escape_chars_=" << color_escape_chars_ << std::endl;
}
if (p0 + local_ppos_ == pn) [[likely]] {
// solpos_, color_escape_chars_, color_escape_start_ all up-to-date
} else {
// [pnew, pn): input that hasn't been incorporated into
// {solpos_, color_escape_chars_, color_escape_start_)
const char * pnew = this->pbase() + this->local_ppos_;
if (debug_flag_) {
std::cerr << "_check_update_local_state: range: (pnew=" << (void*)pnew << ", pn=" << (void*)pn << ")" << std::endl;
}
for(const char * p = pnew; p < pn; ++p) {
this->_update_local_state_char(p0, p);
}
}
// solpos_, color_escape_chars_, color_escape_start_ all up-to-date
// for current buffered contents
this->local_ppos_ = pn - p0;
if (debug_flag_) {
std::cerr << "_check_update_local_state: pos=" << pos();
std::cerr << ", solpos=" << solpos_;
std::cerr << ", color_escape_chars=" << color_escape_chars_ << std::endl;
}
assert(pos() >= solpos_ + color_escape_chars_);
}
private:
/*
* pbase: start of buffered text. Thils will be arena_->lo_
*
*
* pbase pptr epptr
* v >e1< >e2< v v
* |xx\xxEEExxx\xxxxxxxEExxxxEExxxxxxxEExxx\xEExxxxxx..................|
* ^ ^<------new------->
* solpos local_ppos
*
* solpos : first character after newline (stale)
* color_escape_pos : e1+e2+.. (stale)
* new : new characters not reflected
* in local_ppos_, color_escape_chars_ etc.
*
* Legend:
* [\] newline
* [x] visible character
* [E] color escape chars
*
*
* after _check_update_local_state():
*
*
* pbase pptr epptr
* v >e1< v v
* |xx\xxEEExxx\xxxxxxxEExxxxEExxxxxxxEExxx\xEExxxxxx..................|
* ^ ^
* solpos local_ppos
*
*/
/** @defgroup logstreambuf-instance-vars **/
///@{
/** value of pptr (relative to pbase) when _check_update_local_state() last ran **/
std::size_t local_ppos_ = 0;
/** position (relative to pbase) one character after last \n or \r.
* Use to drive @ref lpos. This _has_ to be lazy, since
* xsputn() isn'g guaranteed to be called when there's room in
* in buffer.
**/
std::size_t solpos_ = 0;
/** number of non-printing chars after @ref solpos_, from
* completed color escape sequences.
* (ansi color escapes = text between '\033' and 'm')
**/
std::size_t color_escape_chars_ = 0;
/** non-null: start of incomplete color escape sequence **/
const char * color_escape_start_ = nullptr;
/** buffered output stored here.
* We don't use arena's allocation api, just treat as a block of available memory
**/
DArena * arena_ = nullptr;;
/** true to debug log_streambuf itself **/
bool debug_flag_ = false;
///@}
}; /*log_streambuf*/
} /*namespace mm*/
} /*namespace xo*/
/* end arena_streambuf.hpp */

View file

@ -19,6 +19,8 @@ namespace xo {
using group_type = detail::ControlGroup;
using control_vector_type = xo::mm::DArenaVector<uint8_t>;
using slot_vector_type = xo::mm::DArenaVector<value_type>;
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
using MemorySizeInfo = xo::mm::MemorySizeInfo;
public:
/** group_exp2: number of groups {x, 2^x} **/
@ -31,12 +33,14 @@ namespace xo {
n_slot_{group_exp2.second * c_group_size},
control_{control_vector_type::map
(xo::mm::ArenaConfig{
.name_ = name,
.size_ = control_size(n_slot_)})},
.name_ = name + "-ctl",
.size_ = control_size(n_slot_),
.store_header_flag_ = false})},
slots_{slot_vector_type::map
(xo::mm::ArenaConfig{
.name_ = name,
.size_ = n_slot_ * sizeof(value_type)})}
.name_ = name + "-slots",
.size_ = n_slot_ * sizeof(value_type),
.store_header_flag_ = false})}
{
/* here: arenas have allocated address range, but no committed memory yet */
@ -47,6 +51,23 @@ namespace xo {
size_type capacity() const noexcept { return n_group_ * c_group_size; }
float load_factor() const noexcept { return size_ / static_cast<float>(n_slot_); }
void visit_pools(const MemorySizeVisitor & visitor) const {
// complexity here in service of HashMapStore-specific value for MemorySizeInfo.used
MemorySizeInfo ctl_info;
MemorySizeInfo slot_info;
control_.visit_pools([&ctl_info](const auto & x) { ctl_info = x; });
slots_.visit_pools([&slot_info](const auto & x) { slot_info = x; });
// control: 1 byte per (key,value) pair
ctl_info.used_ = size_;
slot_info.used_ = size_ * sizeof(value_type);
visitor(ctl_info);
visitor(slot_info);
}
void resize_from_empty(const std::pair<size_type,
size_type> & group_exp2)
{

View file

@ -2,6 +2,8 @@
set(SELF_LIB xo_arena)
set(SELF_SRCS
arena_streambuf.cpp
ErrorArena.cpp
cmpresult.cpp
mmap_util.cpp
AllocError.cpp

View file

@ -65,6 +65,11 @@ namespace xo {
return DArena(cfg, page_z, align_z, span.lo(), span.hi());
} /*map*/
DArena::DArena(const ArenaConfig & cfg)
{
*this = map(cfg);
}
DArena::DArena(const ArenaConfig & cfg,
size_type page_z,
size_type arena_align_z,
@ -165,6 +170,51 @@ namespace xo {
return (header_type *)((byte *)obj - sizeof(header_type));
}
void
DArena::visit_pools(const MemorySizeVisitor & fn) const {
/** arena can't tell purpose of allocated memory;
* must assume it's all used
**/
// assemble histogram
MemorySizeInfo::DetailArrayType detail_v;
MemorySizeInfo::DetailArrayType * p_detail = nullptr;
if (config_.store_header_flag_) {
p_detail = &detail_v;
for (const auto & ix : *this) {
typeseq ix_tseq(ix.tseq());
// totals in detail_v[0]
MemorySizeDetail & d = detail_v[0];
++d.n_alloc_;
d.z_alloc_ += ix.size();
// O(n) insertion here
for (size_t i = 1; i < detail_v.size(); ++i) {
if (detail_v[i].tseq_.is_sentinel()
|| (detail_v[i].tseq_ == ix_tseq))
{
MemorySizeDetail & d = detail_v[i];
d.tseq_ = ix_tseq;
++d.n_alloc_;
d.z_alloc_ += ix.size();
break;
}
}
}
}
fn(MemorySizeInfo(config_.name_,
this->allocated() /*used*/,
this->allocated(),
this->committed(),
this->reserved(),
p_detail));
}
AllocInfo
DArena::alloc_info(value_type mem) const noexcept
{
@ -272,7 +322,7 @@ namespace xo {
(complete_flag
? alloc_mode::sub_complete
: alloc_mode::sub_incomplete),
typeseq::anon() /*typeseq: ignored*/,
typeseq::sentinel() /*typeseq: ignored*/,
0 /*age - ignored */);
}

View file

@ -75,10 +75,23 @@ namespace xo {
mapped_range_{reserved_range_.prefix(0)},
occupied_range_{mapped_range_.prefix(0)},
input_range_{occupied_range_.prefix(0)},
pinned_spans_{}
pinned_spans_{DArenaVector<span_type>::map(ArenaConfig().with_name(config.name_ + "-pins"))}
{
}
void
DCircularBuffer::visit_pools(const MemorySizeVisitor & visitor) const
{
visitor(MemorySizeInfo(config_.name_,
occupied_range_.size() /*used*/,
occupied_range_.size(),
mapped_range_.size(),
reserved_range_.size(),
nullptr /*detail*/));
pinned_spans_.visit_pools(visitor);
}
bool
DCircularBuffer::verify_ok(verify_policy policy) const
{

View file

@ -0,0 +1,43 @@
/** @file ErrorArena.cpp
*
* @author Roland Conybeare, Feb 2026
**/
#include "ErrorArena.hpp"
namespace xo {
namespace mm {
DArena
ErrorArena::s_instance;
ArenaConfig
ErrorArena::default_config()
{
return ArenaConfig().with_name("error-arena").with_size(16 * 1024);
}
namespace {
bool s_init_done = false;
}
void
ErrorArena::init_once(const ArenaConfig & cfg)
{
if (!s_init_done) {
s_init_done = true;
s_instance = DArena::map(cfg);
}
}
DArena *
ErrorArena::instance()
{
init_once(default_config());
return &s_instance;
}
} /*namespace mm*/
} /*namespace xo*/
/* end ErrorArena.cpp */

View file

@ -0,0 +1,214 @@
/** @file arena_streambuf.cpp
*
* @author Roland Conybeare, Feb 2026
**/
#include "arena_streambuf.hpp"
namespace xo {
namespace mm {
std::uint32_t
arena_streambuf::lpos() const
{
if (debug_flag_) {
std::cerr << "log_streambuf::lpos: enter" << std::endl;
}
// logically-const. lazy implementation
arena_streambuf * self = const_cast<arena_streambuf *>(this);
self->_check_update_local_state();
return pos() - solpos_ - color_escape_chars_;
}
auto
arena_streambuf::checkpoint() const -> rewind_state
{
// logically-const. lazy implementation
arena_streambuf * self = const_cast<arena_streambuf *>(this);
self->_check_update_local_state();
return rewind_state(solpos_, color_escape_chars_, pos());
}
void
arena_streambuf::reset_stream()
{
assert(arena_);
assert(arena_->committed() > 0);
char * p_lo = (char *)(arena_->lo_);
char * p_hi = (char *)(arena_->limit_);
/* tells parent our buffer extent */
this->setp(p_lo, p_hi);
this->local_ppos_ = 0;
this->solpos_ = 0;
this->color_escape_chars_ = 0;
this->color_escape_start_ = nullptr;
}
void
arena_streambuf::rewind_to(rewind_state s)
{
if (debug_flag_) {
std::cout << "rewind_to: pos " << pos() << "->" << s.pos
<< " solpos " << solpos_ << "->" << s.solpos
<< " color_esc " << color_escape_chars_ << "->" << s.color_escape_chars
<< std::endl;
}
/* .setp(): using just for side effect: sets .pptr to .pbase */
this->setp(this->pbase(), this->epptr());
/* advance pptr to saved position */
this->pbump(s.pos);
this->local_ppos_ = this->pptr() - this->pbase();
this->solpos_ = s.solpos;
this->color_escape_chars_ = s.color_escape_chars;
/* assuming we never try to capture rewind state with incomplete color escape */
this->color_escape_start_ = nullptr;
}
void
arena_streambuf::expand_to(std::size_t new_z)
{
char * old_pptr = pptr();
std::streamsize old_n = old_pptr - pbase();
assert(old_n <= static_cast<std::streamsize>(arena_->allocated()));
assert(new_z > arena_->committed());
/* note: local_ppos_ invariant across expand_to() */
arena_->expand(new_z);
char * p_base = (char *)(arena_->lo_);
char * p_hi = (char *)(arena_->limit_);
this->setp(p_base, p_hi);
this->pbump(old_n);
}
std::streamsize
arena_streambuf::xsputn(const char * s, std::streamsize n)
{
/* s must be an address in [this->lo() .. this->lo() + capacity()] */
assert(hi() >= pptr());
if (pptr() + n > hi()) {
std::size_t new_z = std::max(2 * arena_->committed(), std::size_t(this->pos() + n + 1));
if (new_z > arena_->reserved())
new_z = arena_->reserved();
this->expand_to(new_z);
}
if (debug_flag_) {
std::cout << "xsputn: pbase=" << (void *)(this->pbase())
<< ", pptr=" << (void*)(this->pptr())
<< "(+" << (this->pptr() - this->lo()) << ")"
<< ", n=" << n << " -> (+" << (this->pptr() + n - this->lo()) << ")"
<< ", arena.size=" << this->arena_->committed()
<< std::endl;
}
std::streamsize ncopied = 0;
if (this->pptr() + n > this->hi()) {
ncopied = this->hi() - this->pptr();
} else {
ncopied = n;
}
if (false /*debug_flag_*/) {
std::cout << "xsputn: copying ncopied=" << ncopied << " (/n=" << n << ") bytes into range [lo,hi)"
<< ", lo=" << (void*)this->pptr()
<< ", hi=" << (void*)(this->pptr() + n)
<< std::endl;
}
std::memcpy(this->pptr(), s, ncopied);
this->pbump(ncopied);
/* now {pbase, pptr} consistent with new input */
this->_check_update_local_state();
return ncopied;
}
auto
arena_streambuf::overflow(int_type new_ch) -> int_type
{
char * old_base = this->pbase();
char * old_pptr = this->pptr();
/* #of chars buffered */
std::streamsize old_n = old_pptr - old_base;
assert(old_n <= static_cast<std::streamsize>(arena_->committed()));
// if (debug_flag_) {
// std::cout << "overflow: new_ch=" << quoted_char(new_ch) << std::endl;
// }
/* increase buffer size */
this->expand_to(2 * arena_->committed());
arena_->lo_[old_n] = static_cast<std::byte>(new_ch);
this->pbump(1);
if ((new_ch == static_cast<int_type>('\n')) || (new_ch == static_cast<int_type>('\r'))) {
this->solpos_ = this->pos();
// what if new_ch starts color escape ?
}
if (new_ch == std::char_traits<char>::eof()) {
/* reminder: returning eof sets badbit on ostream */
return std::char_traits<char>::not_eof(new_ch);
} else {
return new_ch;
}
}
auto
arena_streambuf::seekoff(off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which) -> pos_type
{
//std::cout << "seekoff: off=" << off << ", dir=" << dir << ", which=" << which << std::endl;
if (debug_flag_) {
std::cout << "seekoff(off,dir,which)" << std::endl;
}
// Only output stream is supported
if (which != std::ios_base::out)
throw std::runtime_error("log_streambuf: only output mode supported");
if (dir == std::ios_base::cur) {
this->pbump(off);
} else if (dir == std::ios_base::end) {
/* .setp(): using for side effect: sets .pptr to .pbase */
this->setp(this->pbase(), this->epptr());
this->pbump(off);
} else if (dir == std::ios_base::beg) {
/* .setp(): using for side effect: sets .pptr to .pbase */
this->setp(this->pbase(), this->epptr());
this->pbump(this->capacity() + off);
}
return this->pptr() - this->pbase();
} /*seekoff*/
} /*namespace mm*/
} /*namespace xo*/
/* end arena_streambuf.cpp */

View file

@ -147,7 +147,7 @@ namespace xo {
REQUIRE(arena.allocated() == 0);
size_t z0 = 1;
byte * m0 = arena.alloc(typeseq::anon(), 1);
byte * m0 = arena.alloc(typeseq::sentinel(), 1);
REQUIRE(m0);
REQUIRE(arena.last_error().error_ == error::ok);
@ -159,7 +159,7 @@ namespace xo {
REQUIRE(arena.committed() <= arena.reserved());
size_t z1 = 16;
byte * m1 = arena.alloc(typeseq::anon(), z1);
byte * m1 = arena.alloc(typeseq::sentinel(), z1);
REQUIRE(m1);
REQUIRE(arena.last_error().error_ == error::ok);
@ -195,7 +195,7 @@ namespace xo {
REQUIRE(arena.allocated() == 0);
size_t z0 = 1;
byte * m0 = arena.alloc(typeseq::anon(), 1);
byte * m0 = arena.alloc(typeseq::sentinel(), 1);
REQUIRE(m0);

View file

@ -24,7 +24,7 @@ namespace xo {
{
using HashMap = DArenaHashMap<int, int>;
HashMap map;
HashMap map("utest");
REQUIRE(map.empty());
REQUIRE(map.size() == 0);
@ -36,7 +36,7 @@ namespace xo {
{
using HashMap = DArenaHashMap<int, int>;
HashMap map(257);
HashMap map("utest", 257);
REQUIRE(map.empty());
REQUIRE(map.size() == 0);
@ -49,7 +49,7 @@ namespace xo {
{
using HashMap = DArenaHashMap<int, int>;
HashMap map;
HashMap map("utest");
REQUIRE(map.empty());
REQUIRE(map.size() == 0);
@ -209,7 +209,7 @@ namespace xo {
*/
for (std::uint32_t n = 0; n <= 8; ) {
HashMap hash_map;
HashMap hash_map("utest");
auto test_fn = [&rgen, &hash_map](bool dbg_flag,
std::uint32_t n)
@ -245,7 +245,7 @@ namespace xo {
using HashMap = DArenaHashMap<int, int>;
HashMap map;
HashMap map("utest");
// copy keys here so we can print stuff
std::vector<int> key_v;
@ -336,7 +336,7 @@ namespace xo {
{
using HashMap = DArenaHashMap<std::string_view, int>;
HashMap map(1024);
HashMap map("utest", 1024);
REQUIRE(map.verify_ok());

View file

@ -670,7 +670,7 @@ macro(xo_toplevel_compile_options)
)
if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
endif()
if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
set(CMAKE_CXX_STANDARD_REQUIRED True)
@ -1677,9 +1677,6 @@ function(xo_add_genfacet)
TARGET # Name for this generation target
FACET # facet name
INPUT # Input .json5 file
OUTPUT_HPP_DIR # Directory for .hpp files
OUTPUT_IMPL_SUBDIR # Subdirectory name for impl headers
OUTPUT_CPP_DIR # Directory for .cpp files
)
set(multiValueArgs "")
@ -1693,40 +1690,18 @@ function(xo_add_genfacet)
if(NOT DEFINED GF_FACET)
message(FATAL_ERROR "xo_add_genfacet: FACET is required")
endif()
if(NOT DEFINED GF_OUTPUT_HPP_DIR)
message(FATAL_ERROR "xo_add_genfacet: OUTPUT_HPP_DIR is required")
endif()
if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR)
message(FATAL_ERROR "xo_add_genfacet: OUTPUT_IMPL_SUBDIR is required")
endif()
if(NOT DEFINED GF_OUTPUT_CPP_DIR)
message(FATAL_ERROR "xo_add_genfacet: OUTPUT_CPP_DIR is required")
endif()
find_program(GENFACET_EXECUTABLE NAMES genfacet
HINTS ${CMAKE_SOURCE_DIR}/xo-facet/codegen
DOC "path to xo genfacet code generator"
REQUIRED)
message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}")
set(generatedFiles
${GF_OUTPUT_HPP_DIR}/${GF_FACET}.hpp
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/A${GF_FACET}.hpp
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Any.hpp
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Xfer.hpp
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${GF_FACET}.hpp
${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_Any.cpp)
#message(STATUS "generatedFiles=${generatedFiles}")
# Build the genfacet command
add_custom_command(
OUTPUT ${generatedFiles}
COMMAND ${GENFACET_EXECUTABLE}
--input ${GF_INPUT}
--output-hpp ${GF_OUTPUT_HPP_DIR}
--output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR}
--output-cpp ${GF_OUTPUT_CPP_DIR}
OUTPUT ${GF_INPUT}.out
COMMAND ${GENFACET_EXECUTABLE} --input ${GF_INPUT}
DEPENDS ${GF_INPUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating facet source files from ${GF_INPUT}"
@ -1734,7 +1709,9 @@ function(xo_add_genfacet)
)
# Create a target for this generation
add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles})
add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}.out)
set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET})
endfunction()
function(xo_add_genfacetimpl)
@ -1767,16 +1744,6 @@ function(xo_add_genfacetimpl)
if(NOT DEFINED GF_INPUT)
message(FATAL_ERROR "xo_add_genfacetimpl: INPUT is required")
endif()
if(NOT DEFINED GF_OUTPUT_HPP_DIR)
message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_HPP_DIR is required")
endif()
if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR)
message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_IMPL_SUBDIR is required")
endif()
if(NOT DEFINED GF_OUTPUT_CPP_DIR)
message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_CPP_DIR is required")
endif()
if(NOT DEFINED GF_FACET_DIR)
if (NOT DEFINED GF_FACET_PKG)
message(FATAL_ERROR "xo_add_genfacetimpl: FACET_PKG or FACET_DIR required")
@ -1792,21 +1759,12 @@ function(xo_add_genfacetimpl)
REQUIRED)
message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}")
set(generatedFiles
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_D${GF_REPR}.hpp
${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_D${GF_REPR}.cpp)
# Build the genfacet command.
# But careful: can't have the same generated files in two different rules,
# so need to remove overlaps here
add_custom_command(
OUTPUT ${generatedFiles}
COMMAND ${GENFACET_EXECUTABLE}
--input ${GF_INPUT}
--facet-dir ${GF_FACET_DIR}
--output-hpp ${GF_OUTPUT_HPP_DIR}
--output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR}
--output-cpp ${GF_OUTPUT_CPP_DIR}
OUTPUT ${GF_INPUT}.out
COMMAND ${GENFACET_EXECUTABLE} --input ${GF_INPUT} --facet-dir ${GF_FACET_DIR}
DEPENDS ${GF_INPUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating facet source files from ${GF_INPUT}"
@ -1814,5 +1772,17 @@ function(xo_add_genfacetimpl)
)
# Create a target for this generation
add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles})
add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}.out)
set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET})
endfunction()
# create umbrella target for all genfacet targets in current directory
function(xo_add_genfacet_all target_name)
get_property(genfacet_targets DIRECTORY PROPERTY XO_GENFACET_TARGETS)
if(genfacet_targets)
add_custom_target(${target_name} DEPENDS ${genfacet_targets})
else()
message(WARNING "xo_add_genfacet_all: no genfacet targets found")
endif()
endfunction()

View file

@ -3,6 +3,7 @@
# Generated by cmake - rerun to reconfigure
dry_run_flag=false
testing=@ENABLE_TESTING@
# Parse arguments
while [[ $# -gt 0 ]]; do
@ -10,6 +11,12 @@ while [[ $# -gt 0 ]]; do
-n|--dry-run)
dry_run_flag=true
;;
--enable-testing)
testing=1
;;
--disable-testing)
testing=0
;;
--)
break;
;;
@ -35,7 +42,7 @@ CMAKE_CMD=(
-DCMAKE_PREFIX_PATH=@CMAKE_PREFIX_PATH@
-DCMAKE_CXX_STANDARD=@CMAKE_CXX_STANDARD@
-DXO_CMAKE_CONFIG_EXECUTABLE=@XO_CMAKE_CONFIG_EXECUTABLE@
-DENABLE_TESTING=@ENABLE_TESTING@
-DENABLE_TESTING=$testing
-DXO_ENABLE_DOCS=@XO_ENABLE_DOCS@
-DXO_ENABLE_ASM=@XO_ENABLE_ASM@
-DXO_ENABLE_EXAMPLES=@XO_ENABLE_EXAMPLES@

View file

@ -29,9 +29,80 @@ xo_add_genfacet(
INPUT idl/SymbolTable.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/expression2
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-symboltable-localsymtab
FACET_PKG xo_expression2
FACET SymbolTable
REPR LocalSymtab
INPUT idl/ISymbolTable_DLocalSymtab.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR symtab
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-localsymtab
FACET_PKG xo_gc
FACET GCObject
REPR LocalSymtab
INPUT idl/IGCObject_DLocalSymtab.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR symtab
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-localsymtab
FACET_PKG xo_printable2
FACET Printable
REPR LocalSymtab
INPUT idl/IPrintable_DLocalSymtab.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR symtab
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-symboltable-globalsymtab
FACET_PKG xo_expression2
FACET SymbolTable
REPR GlobalSymtab
INPUT idl/ISymbolTable_DGlobalSymtab.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR symtab
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-globalsymtab
FACET_PKG xo_gc
FACET GCObject
REPR GlobalSymtab
INPUT idl/IGCObject_DGlobalSymtab.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR symtab
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-globalsymtab
FACET_PKG xo_printable2
FACET Printable
REPR GlobalSymtab
INPUT idl/IPrintable_DGlobalSymtab.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR symtab
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacet(
TARGET xo-expression2-facet-expression
@ -39,9 +110,10 @@ xo_add_genfacet(
INPUT idl/Expression.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/expression2
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-constant
@ -51,9 +123,32 @@ xo_add_genfacetimpl(
INPUT idl/IExpression_DConstant.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/expression2
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-constant
FACET_PKG xo_gc
FACET GCObject
REPR Constant
INPUT idl/IGCObject_DConstant.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-constant
FACET_PKG xo_printable2
FACET Printable
REPR Constant
INPUT idl/IPrintable_DConstant.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-variable
@ -63,9 +158,242 @@ xo_add_genfacetimpl(
INPUT idl/IExpression_DVariable.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/expression2
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-variable
FACET_PKG xo_gc
FACET GCObject
REPR Variable
INPUT idl/IGCObject_DVariable.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-variable
FACET_PKG xo_printable2
FACET Printable
REPR Variable
INPUT idl/IPrintable_DVariable.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-varref
FACET_PKG xo_expression2
FACET Expression
REPR VarRef
INPUT idl/IExpression_DVarRef.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-varref
FACET_PKG xo_gc
FACET GCObject
REPR VarRef
INPUT idl/IGCObject_DVarRef.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-varref
FACET_PKG xo_printable2
FACET Printable
REPR VarRef
INPUT idl/IPrintable_DVarRef.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-defineexpr
FACET_PKG xo_expression2
FACET Expression
REPR DefineExpr
INPUT idl/IExpression_DDefineExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-defineexpr
FACET_PKG xo_gc
FACET GCObject
REPR DefineExpr
INPUT idl/IGCObject_DDefineExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR define
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-defineexpr
FACET_PKG xo_printable2
FACET Printable
REPR DefineExpr
INPUT idl/IPrintable_DDefineExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-applyexpr
FACET_PKG xo_expression2
FACET Expression
REPR ApplyExpr
INPUT idl/IExpression_DApplyExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-applyexpr
FACET_PKG xo_gc
FACET GCObject
REPR ApplyExpr
INPUT idl/IGCObject_DApplyExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-applyexpr
FACET_PKG xo_printable2
FACET Printable
REPR ApplyExpr
INPUT idl/IPrintable_DApplyExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-lambdaexpr
FACET_PKG xo_expression2
FACET Expression
REPR LambdaExpr
INPUT idl/IExpression_DLambdaExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-lambdaexpr
FACET_PKG xo_gc
FACET GCObject
REPR LambdaExpr
INPUT idl/IGCObject_DLambdaExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-lambdaexpr
FACET_PKG xo_printable2
FACET Printable
REPR LambdaExpr
INPUT idl/IPrintable_DLambdaExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-ifelseexpr
FACET_PKG xo_expression2
FACET Expression
REPR IfElseExpr
INPUT idl/IExpression_DIfElseExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-ifelseexpr
FACET_PKG xo_gc
FACET GCObject
REPR IfElseExpr
INPUT idl/IGCObject_DIfElseExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-ifelseexpr
FACET_PKG xo_printable2
FACET Printable
REPR IfElseExpr
INPUT idl/IPrintable_DIfElseExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-expression-sequenceexpr
FACET_PKG xo_expression2
FACET Expression
REPR SequenceExpr
INPUT idl/IExpression_DSequenceExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-sequenceexpr
FACET_PKG xo_gc
FACET GCObject
REPR SequenceExpr
INPUT idl/IGCObject_DSequenceExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-sequenceexpr
FACET_PKG xo_printable2
FACET Printable
REPR SequenceExpr
INPUT idl/IPrintable_DSequenceExpr.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-gcobject-uniquestring
@ -75,7 +403,6 @@ xo_add_genfacetimpl(
INPUT idl/IGCObject_DUniqueString.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/expression2
)
# note: manual target; generated code committed to git
@ -83,26 +410,24 @@ xo_add_genfacetimpl(
TARGET xo-expression2-facetimpl-printable-uniquestring
FACET_PKG xo_printable2
FACET Printable
REPR DUniqueString
REPR UniqueString
INPUT idl/IPrintable_DUniqueString.json5
OUTPUT_HPP_DIR include/xo/expression2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/expression2
)
# ----------------------------------------------------------------
# header-only library
xo_add_genfacet_all(xo-expression2-genfacet-all)
# ----------------------------------------------------------------
# shared library
add_subdirectory(src/expression2)
# ----------------------------------------------------------------
# cmake helper (for external xo-expression2 users)
xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets)
# ----------------------------------------------------------------
# input dependencies
#
# NOTE: dependency set here must be kept consistent with
# xo-expression2/cmake/xo_expression2Config.cmake.in
#xo_headeronly_dependency(${SELF_LIB} xo_flatstring)
# end CMakeLists.txt

View file

@ -8,7 +8,7 @@ include(CMakeFindDependencyMacro)
#
find_dependency(xo_gc)
find_dependency(reflect)
find_dependency(xo_object2)
find_dependency(xo_procedure2)
find_dependency(xo_printable2)
find_dependency(xo_flatstring)
find_dependency(cmake)

View file

@ -1,5 +1,8 @@
{
mode: "facet",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"TypeRef.hpp\"",
"\"exprtype.hpp\"",
"<xo/reflect/TypeDescr.hpp>"],
@ -67,4 +70,5 @@
attributes: [],
}
],
router_facet_explicit_content: [ ],
}

View file

@ -0,0 +1,15 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Expression.json5",
brief: "provide AExpression interface for DApplyExpr state",
using_doxygen: true,
repr: "DApplyExpr",
doc: ["doc for IExpression+DApplyExpr" ],
}

View file

@ -1,5 +1,8 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",

View file

@ -0,0 +1,15 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Expression.json5",
brief: "provide AExpression interface for DDefineExpr state",
using_doxygen: true,
repr: "DDefineExpr",
doc: ["doc for IExpression+DDefineExpr" ],
}

View file

@ -0,0 +1,15 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Expression.json5",
brief: "provide AExpression interface for DIfElseExpr state",
using_doxygen: true,
repr: "DIfElseExpr",
doc: ["doc for IExpression+DIfElseExpr" ],
}

View file

@ -0,0 +1,15 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Expression.json5",
brief: "provide AExpression interface for DLambdaExpr state",
using_doxygen: true,
repr: "DLambdaExpr",
doc: ["doc for IExpression+DLambdaExpr" ],
}

View file

@ -0,0 +1,15 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Expression.json5",
brief: "provide AExpression interface for DSequenceExpr state",
using_doxygen: true,
repr: "DSequenceExpr",
doc: ["doc for something or other IExpression+DSequenceExpr" ],
}

View file

@ -0,0 +1,15 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Expression.json5",
brief: "provide AExpression interface for DVarRef state",
using_doxygen: true,
repr: "DVarRef",
doc: ["doc for IExpression+DVarRef" ],
}

View file

@ -1,5 +1,8 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "\"Expression.hpp\"" ],
local_types: [ ],
namespace1: "xo",

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DApplyExpr",
using_doxygen: true,
repr: "DApplyExpr",
doc: [ "implement AGCObject for DApplyExpr" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DConstant",
using_doxygen: true,
repr: "DConstant",
doc: [ "implement AGCObject for DConstant" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "define",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DDefineExpr",
using_doxygen: true,
repr: "DDefineExpr",
doc: [ "implement AGCObject for DDefineExpr" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "symtab",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DGlobalSymtab",
using_doxygen: true,
repr: "DGlobalSymtab",
doc: [ "implement AGCObject for DGlobalSymtab" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DIfElseExpr",
using_doxygen: true,
repr: "DIfElseExpr",
doc: [ "implement AGCObject for DIfElseExpr" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DLambdaExpr",
using_doxygen: true,
repr: "DLambdaExpr",
doc: [ "implement AGCObject for DLambdaExpr" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "symtab",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DLocalSymtab",
using_doxygen: true,
repr: "DLocalSymtab",
doc: [ "implement AGCObject for DLocalSymtab" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DSequenceExpr",
using_doxygen: true,
repr: "DSequenceExpr",
doc: [ "implement AGCObject for DSequenceExpr" ],
}

View file

@ -1,5 +1,8 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DVarRef",
using_doxygen: true,
repr: "DVarRef",
doc: [ "implement AGCObject for DVarRef" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [
"<xo/gc/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DVariable",
using_doxygen: true,
repr: "DVariable",
doc: [ "implement AGCObject for DVariable" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Printable.json5",
brief: "provide APrintable interface for DApplyExpr",
using_doxygen: true,
repr: "DApplyExpr",
doc: [ "implement APrintable for DApplyExpr" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Printable.json5",
brief: "provide APrintable interface for DConstant",
using_doxygen: true,
repr: "DConstant",
doc: [ "implement APrintable for DConstant" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Printable.json5",
brief: "provide APrintable interface for DDefineExpr",
using_doxygen: true,
repr: "DDefineExpr",
doc: [ "implement APrintable for DDefineExpr" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "symtab",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Printable.json5",
brief: "provide APrintable interface for DGlobalSymtab",
using_doxygen: true,
repr: "DGlobalSymtab",
doc: [ "implement APrintable for DGlobalSymtab" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Printable.json5",
brief: "provide APrintable interface for DIfElseExpr",
using_doxygen: true,
repr: "DIfElseExpr",
doc: [ "implement APrintable for DIfElseExpr" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "detail",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Printable.json5",
brief: "provide APrintable interface for DLambdaExpr",
using_doxygen: true,
repr: "DLambdaExpr",
doc: [ "implement APrintable for DLambdaExpr" ],
}

Some files were not shown because too many files have changed in this diff Show more