From 09ee3a20acdab96ccc4ebfe88014c2dd4e987a3c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 9 Jan 2026 17:48:54 -0500 Subject: [PATCH] xo-objectd2 xo-printable xo-facet: pp working for List(Integer) Also streamline facet switching --- FAQ-DEV.md | 24 +++ xo-arena/utest/random_hash_ops.hpp | 4 + xo-facet/codegen/router_facet.hpp.j2 | 3 +- xo-facet/include/xo/facet/FacetRegistry.hpp | 76 ++++++++-- xo-object2/include/xo/object2/DInteger.hpp | 23 ++- xo-object2/include/xo/object2/DList.hpp | 38 ++++- .../xo/object2/IPrintable_DInteger.hpp | 57 +++++++ .../include/xo/object2/IPrintable_DList.hpp | 2 +- .../xo/object2/object2_register_types.hpp | 3 + xo-object2/src/object2/CMakeLists.txt | 4 +- xo-object2/src/object2/DInteger.cpp | 32 ++++ xo-object2/src/object2/DList.cpp | 17 ++- .../src/object2/IPrintable_DInteger.cpp | 28 ++++ .../src/object2/object2_register_types.cpp | 39 +++++ xo-object2/utest/CMakeLists.txt | 1 + xo-object2/utest/Printable.test.cpp | 141 ++++++++++++++++++ xo-object2/utest/X1Collector.test.cpp | 2 +- .../include/xo/printable2/Printable.hpp | 5 +- .../xo/printable2/detail/APrintable.hpp | 2 +- .../xo/printable2/detail/IPrintable_Any.hpp | 4 +- .../xo/printable2/detail/IPrintable_Xfer.hpp | 4 +- .../xo/printable2/detail/RPrintable.hpp | 5 +- .../printable2/detail/ppdetail_Printable.hpp | 21 +++ 23 files changed, 508 insertions(+), 27 deletions(-) create mode 100644 FAQ-DEV.md create mode 100644 xo-object2/include/xo/object2/IPrintable_DInteger.hpp create mode 100644 xo-object2/src/object2/DInteger.cpp create mode 100644 xo-object2/src/object2/IPrintable_DInteger.cpp create mode 100644 xo-object2/utest/Printable.test.cpp create mode 100644 xo-printable2/include/xo/printable2/detail/ppdetail_Printable.hpp diff --git a/FAQ-DEV.md b/FAQ-DEV.md new file mode 100644 index 00000000..0fdd39fc --- /dev/null +++ b/FAQ-DEV.md @@ -0,0 +1,24 @@ +Error like this: + +``` +/home/roland/proj/xo-umbrella2-claude1/./xo-facet/include/xo/facet/OObject.hpp:63:19: required from ‘struct xo::facet::OObject’ + 63 | using ISpecific = FacetImplType; + | ^~~~~~~~~ +/home/roland/proj/xo-umbrella2-claude1/./xo-gc/include/xo/gc/detail/RGCObject.hpp:15:16: required from ‘struct xo::mm::RGCObject >’ + 15 | struct RGCObject : public Object { + | ^~~~~~~~~ +/home/roland/proj/xo-umbrella2-claude1/./xo-facet/include/xo/facet/obj.hpp:49:16: required from ‘struct xo::facet::obj’ + 49 | struct obj : public RoutingType> { + | ^~~ +/home/roland/proj/xo-umbrella2-claude1/xo-object2/utest/Printable.test.cpp:81:57: required from here + 81 | auto l0_o = with_facet::mkobj(l0); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ +/home/roland/proj/xo-umbrella2-claude1/./xo-facet/include/xo/facet/facet_implementation.hpp:97:15: error: no type named ‘ImplType’ in ‘struct xo::facet::FacetImplementation’ + 97 | using FacetImplType = FacetImplementation::ImplType; + | ^~~~~~~~~~~~~ +``` + +means implementation `xo::mm::AGCObject` for `xo::scm::DList` is not availabel to compiler. +Either missing implementation or missing header. + +In example implementation would be in a file `IGCObject_DList.hpp` diff --git a/xo-arena/utest/random_hash_ops.hpp b/xo-arena/utest/random_hash_ops.hpp index 52d443fa..affc56d9 100644 --- a/xo-arena/utest/random_hash_ops.hpp +++ b/xo-arena/utest/random_hash_ops.hpp @@ -76,6 +76,10 @@ namespace utest { * * test function should use REQUIRE_ORCAPTURE() / REQUIRE_ORFAIL(). * It should *not* use REQUIRE() or CHECK(). + * + * @p test_name banner for initial log message (only printed on 2nd pass) + * @p test_fn function to invoke test pass. + * @p n test size/id (cosmetic - printed in log messages) **/ static inline bool bimodal_test(std::string test_name, std::function test_fn, diff --git a/xo-facet/codegen/router_facet.hpp.j2 b/xo-facet/codegen/router_facet.hpp.j2 index 9d323de7..2c702b5e 100644 --- a/xo-facet/codegen/router_facet.hpp.j2 +++ b/xo-facet/codegen/router_facet.hpp.j2 @@ -32,6 +32,7 @@ public: {% endif %} using ObjectType = Object; using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; {% for ty in types %} using {{ty.name}} = {{abstract_facet}}::{{ty.name}}; {% endfor %} @@ -53,7 +54,7 @@ public: {% endif %} // const methods - int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } {% for md in const_methods %} {{md.return_type}} {{md.name}}({{md.args | argsnodata}}) {{md | qualifiers}} override { return O::iface()->{{md.name}}({{md.args | argrouting}}); diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index 27db9d0f..2a3aa48c 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -10,6 +10,8 @@ #include "facet_implementation.hpp" #include "typeseq.hpp" #include "obj.hpp" +#include +#include #include #include @@ -36,6 +38,7 @@ namespace xo { **/ class FacetRegistry { public: + using typeseq = xo::reflect::typeseq; using key_type = std::pair; /** hash function for key_type **/ @@ -102,7 +105,7 @@ namespace xo { template const AFacet * lookup(typeseq repr_id) const { return static_cast - (this->_lookup(typeseq::id(), repr_id)); + (this->_lookup(typeseq::id(), repr_id)); } /** Runtime polymorphism: @@ -113,10 +116,40 @@ namespace xo { * = ...; // Foo instance with variant impl * obj bar * = FacetRegistry::variant(foo); + * + * // exception thrown if bar has null data + * + * assert(bar); **/ template obj variant(obj from) { - return variant(from._typeseq(), from.data()); + auto retval = try_variant(from); + + if (!retval) + throw std::runtime_error(tostr("FacetRegistry::try_variant failed", + xtag("AFrom.tseq", typeseq::id()), + xtag("ATo.tseq", typeseq::id()))); + + return retval; + } + + /** Runtime polymorphism: + * Switch @param from from interface @tp AFrom to interface @tp ATo. + * + * Use: + * obj foo + * = ...; // Foo instance with variant impl + * obj bar + * = FacetRegistry::try_variant(foo); + * if (bar) { + * // success + * } else { + * // foo::DataType doesn't appear to support ABar + * } + **/ + template + obj try_variant(obj from) { + return try_variant(from._typeseq(), from.data()); } /** Runtime polymorphism: @@ -129,9 +162,24 @@ namespace xo { * = FacetRegistry::variant(foo._typeseq(), foo.opaque_data()); **/ template - obj variant(typeseq repr_id, void * data) { + obj try_variant(typeseq repr_id, void * data) { const AFacet * iface = this->lookup(repr_id); - return obj::variant(iface, data);; + + if (iface) + return obj(iface, data); + else + return obj(); + } + + void dump(std::ostream * p_out) { + (*p_out) << std::endl; + (*p_out) << " " << kv.second << std::endl; + } + (*p_out) << ">" << std::endl; } private: @@ -142,8 +190,8 @@ namespace xo { * @param impl pointer to stateless implementation instance **/ void _register_impl(typeseq facet_id, - typeseq repr_id, - const void * impl) + typeseq repr_id, + const void * impl) { registry_[key_type(facet_id, repr_id)] = impl; } @@ -155,12 +203,20 @@ namespace xo { const void * _lookup(typeseq facet_id, typeseq repr_id) const { + scope log(XO_DEBUG(false)); + log && log(xtag("facet_id", facet_id), + xtag("repr_id", repr_id)); + auto ix = registry_.find(key_type(facet_id, repr_id)); - if (ix == registry_.end()) - return nullptr; - else - return ix->second; + const void *retval = nullptr; + + if (ix != registry_.end()) + retval = ix->second; + + log && log(xtag("retval", retval)); + + return retval; } private: diff --git a/xo-object2/include/xo/object2/DInteger.hpp b/xo-object2/include/xo/object2/DInteger.hpp index 3457af79..25921474 100644 --- a/xo-object2/include/xo/object2/DInteger.hpp +++ b/xo-object2/include/xo/object2/DInteger.hpp @@ -5,11 +5,32 @@ #pragma once +#include +#include #include namespace xo { namespace scm { - using DInteger = std::int64_t; + struct DInteger { + using AAllocator = xo::mm::AAllocator; + using ppindentinfo = xo::print::ppindentinfo; + + explicit DInteger(long x) : value_{x} {} + + /** allocate boxed value @p x using memory from @p mm **/ + static DInteger * make(obj mm, + long x); + + double value() const noexcept { return value_; } + + bool pretty(const ppindentinfo & ppii) const; + + operator long() const noexcept { return value_; } + + private: + /** boxed integer value **/ + long value_; + }; } /*nmaespace obj*/ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/DList.hpp b/xo-object2/include/xo/object2/DList.hpp index dc0729bf..1e863a60 100644 --- a/xo-object2/include/xo/object2/DList.hpp +++ b/xo-object2/include/xo/object2/DList.hpp @@ -13,6 +13,7 @@ namespace xo { namespace scm { + // TODO: consider renaming to DCons struct DList { using size_type = std::size_t; using AGCObject = xo::mm::AGCObject; @@ -22,8 +23,27 @@ namespace xo { DList(xo::obj h, DList * r) : head_{h}, rest_{r} {} + template + static obj nil(); + + /** shortcut for + * cons(mm, cdr, cdr.data()) + **/ + template + static obj cons(obj mm, + obj car, + obj cdr); + /** sentinel for null list **/ - static DList * null(); + static DList * _nil(); + + /** list with first element @p car, + * followed by contents of list @p cdr. + * Shares structure with @p cdr + **/ + static DList * _cons(obj mm, + obj car, + DList * cdr); /** list with one element @p h1, allocated from @p mm **/ static DList * list(obj mm, @@ -51,6 +71,22 @@ namespace xo { DList * rest_ = nullptr; }; + template + obj + DList::nil() + { + return obj(DList::_nil()); + } + + template + obj + DList::cons(obj mm, + obj car, + obj cdr) + { + return obj(DList::_cons(mm, car, cdr.data())); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/IPrintable_DInteger.hpp b/xo-object2/include/xo/object2/IPrintable_DInteger.hpp new file mode 100644 index 00000000..d18b25ab --- /dev/null +++ b/xo-object2/include/xo/object2/IPrintable_DInteger.hpp @@ -0,0 +1,57 @@ +/** @file IPrintable_DInteger.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DInteger.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DInteger.json5] + **/ + +#pragma once + +#include +#include +#include "DInteger.hpp" + +namespace xo { namespace scm { class IPrintable_DInteger; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DInteger + **/ + class IPrintable_DInteger { + public: + /** @defgroup scm-printable-dinteger-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + ///@} + /** @defgroup scm-printable-dinteger-methods **/ + ///@{ + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DInteger & self, const ppindentinfo & ppii); + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ diff --git a/xo-object2/include/xo/object2/IPrintable_DList.hpp b/xo-object2/include/xo/object2/IPrintable_DList.hpp index 6a38f020..ac4c5315 100644 --- a/xo-object2/include/xo/object2/IPrintable_DList.hpp +++ b/xo-object2/include/xo/object2/IPrintable_DList.hpp @@ -54,4 +54,4 @@ See [xo-indentlog/xo/indentlog/pretty.hpp] **/ } /*namespace scm*/ } /*namespace xo*/ -/* end */ \ No newline at end of file +/* end */ diff --git a/xo-object2/include/xo/object2/object2_register_types.hpp b/xo-object2/include/xo/object2/object2_register_types.hpp index 9b2656a1..110779cb 100644 --- a/xo-object2/include/xo/object2/object2_register_types.hpp +++ b/xo-object2/include/xo/object2/object2_register_types.hpp @@ -13,6 +13,9 @@ namespace xo { * Return true iff all types register successfully. **/ bool object2_register_types(obj gc); + + /** Register object2 (facet,impl) combinations with FacetRegistry **/ + bool object2_register_facets(); } } diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index 62754f96..d784e881 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -7,10 +7,12 @@ set(SELF_SRCS IGCObject_DList.cpp ISequence_Any.cpp ISequence_DList.cpp - IPrintable_DFloat.cpp IPrintable_DList.cpp + IPrintable_DFloat.cpp + IPrintable_DInteger.cpp DList.cpp DFloat.cpp + DInteger.cpp object2_register_types.cpp ) diff --git a/xo-object2/src/object2/DInteger.cpp b/xo-object2/src/object2/DInteger.cpp new file mode 100644 index 00000000..1aa3efb1 --- /dev/null +++ b/xo-object2/src/object2/DInteger.cpp @@ -0,0 +1,32 @@ +/** @file DInteger.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DInteger.hpp" +#include + +namespace xo { + using xo::facet::typeseq; + using xo::print::ppdetail_atomic; + + namespace scm { + DInteger * + DInteger::make(obj mm, + long x) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DInteger)); + + return new (mem) DInteger(x); + } + + bool + DInteger::pretty(const ppindentinfo & ppii) const + { + return ppdetail_atomic::print_pretty(ppii, value_); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DInteger.cpp */ diff --git a/xo-object2/src/object2/DList.cpp b/xo-object2/src/object2/DList.cpp index 8d851e78..777d5033 100644 --- a/xo-object2/src/object2/DList.cpp +++ b/xo-object2/src/object2/DList.cpp @@ -19,18 +19,28 @@ namespace xo { static DList s_null(obj(), nullptr); DList * - DList::null() + DList::_nil() { return &s_null; } + DList * + DList::_cons(obj mm, + obj car, + DList * cdr) + { + void * mem = mm.alloc(typeseq::id(), sizeof(DList)); + + return new (mem) DList(car, cdr); + } + DList * DList::list(obj mm, obj h1) { void * mem = mm.alloc(typeseq::id(), sizeof(DList)); - return new (mem) DList(h1, DList::null()); + return new (mem) DList(h1, DList::_nil()); } DList * @@ -112,7 +122,8 @@ namespace xo { obj elt = FacetRegistry::instance().variant(l->head_); - // what if no converter registered ? + + assert(elt); if (!pps->print_upto(elt)) return false; diff --git a/xo-object2/src/object2/IPrintable_DInteger.cpp b/xo-object2/src/object2/IPrintable_DInteger.cpp new file mode 100644 index 00000000..8e9bc774 --- /dev/null +++ b/xo-object2/src/object2/IPrintable_DInteger.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DInteger.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DInteger.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DInteger.json5] +**/ + +#include "IPrintable_DInteger.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DInteger::pretty(const DInteger & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DInteger.cpp */ diff --git a/xo-object2/src/object2/object2_register_types.cpp b/xo-object2/src/object2/object2_register_types.cpp index e472401a..131b8cfc 100644 --- a/xo-object2/src/object2/object2_register_types.cpp +++ b/xo-object2/src/object2/object2_register_types.cpp @@ -4,22 +4,36 @@ **/ #include "object2_register_types.hpp" + #include "IGCObject_DList.hpp" #include "IGCObject_DFloat.hpp" #include "IGCObject_DInteger.hpp" +#include "IPrintable_DList.hpp" +//#include "IPrintable_DFloat.hpp" +#include "IPrintable_DInteger.hpp" + +#include +#include + namespace xo { + using xo::print::APrintable; + using xo::mm::AAllocator; using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::IGCObject_Any; + using xo::facet::FacetRegistry; using xo::facet::impl_for; using xo::facet::typeseq; + using xo::scope; namespace scm { bool object2_register_types(obj gc) { + scope log(XO_DEBUG(true)); + bool ok = true; ok &= gc.install_type(impl_for()); @@ -28,6 +42,31 @@ namespace xo { return ok; } + + bool + object2_register_facets() + { + scope log(XO_DEBUG(true)); + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); +// FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + log && log(xtag("DList.tseq", typeseq::id())); + log && log(xtag("DFloat.tseq", typeseq::id())); + log && log(xtag("DInteger.tseq", typeseq::id())); + + log && log(xtag("AAllocator.tseq", typeseq::id())); + log && log(xtag("APrintable.tseq", typeseq::id())); + log && log(xtag("AGCObject.tseq", typeseq::id())); + + return true; + } } } /*namespace xo*/ diff --git a/xo-object2/utest/CMakeLists.txt b/xo-object2/utest/CMakeLists.txt index 258f56a1..70544571 100644 --- a/xo-object2/utest/CMakeLists.txt +++ b/xo-object2/utest/CMakeLists.txt @@ -4,6 +4,7 @@ set(UTEST_EXE utest.object2) set(UTEST_SRCS object2_utest_main.cpp X1Collector.test.cpp + Printable.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-object2/utest/Printable.test.cpp b/xo-object2/utest/Printable.test.cpp new file mode 100644 index 00000000..d385a8e9 --- /dev/null +++ b/xo-object2/utest/Printable.test.cpp @@ -0,0 +1,141 @@ +/** @file Printable.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DList.hpp" +#include "object2_register_types.hpp" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +namespace ut { + using xo::scm::object2_register_types; + using xo::scm::object2_register_facets; + using xo::scm::DList; + using xo::scm::DInteger; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::facet::typeseq; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::scope; + using xo::xtag; + using std::string; + + namespace { + struct testcase_pp { + explicit testcase_pp(size_t gc_z, size_t gc_threshold, int z, const std::string & expected) + : gc_gen_size_{gc_z}, gc_trigger_threshold_{gc_threshold}, expected_{expected} { + for (int i = 0; i < z; ++i) { + list_.push_back(1000 + 197 * i); + } + } + + size_t gc_gen_size_ = 0; + size_t gc_trigger_threshold_ = 0; + std::vector list_; + std::string expected_; + }; + + std::vector + s_testcase_v = { + testcase_pp(16384, 8192, 0, "()"), + testcase_pp(16384, 8192, 1, "(1000)"), + testcase_pp(16384, 8192, 2, "(1000 1197)"), + testcase_pp(16384, 8192, 5, "(1000 1197 1394 1591 1788)"), + testcase_pp(16384, 8192, 10, "(1000 1197 1394 1591 1788 1985 2182 2379 2576 2773)"), + testcase_pp(16384, 8192, 20, "(...)"), + }; + } + + TEST_CASE("printable1", "[pp][x1][list]") + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + bool ok = object2_register_facets(); + REQUIRE(ok); + + FacetRegistry::instance().dump(&std::cerr); + + for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) { + try { + const testcase_pp & tc = s_testcase_v[i_tc]; + + CollectorConfig cfg{ + .name_ = "pp_test", + .arena_config_ = ArenaConfig{ + .size_ = tc.gc_gen_size_, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{tc.gc_trigger_threshold_, + tc.gc_trigger_threshold_}}, + .debug_flag_ = c_debug_flag + }; + + DX1Collector gc(cfg); + auto gc_o = with_facet::mkobj(&gc); + auto c_o = with_facet::mkobj(&gc); + + bool ok = object2_register_types(c_o); + REQUIRE(ok); + + auto l0_o = DList::nil(); + + c_o.add_gc_root(&l0_o); + + for(int ip1 = tc.list_.size(); ip1 > 0; --ip1) { + // auto xi_o = Integer::make(g_o, ...); + DInteger * xi = DInteger::make(gc_o, tc.list_[ip1 - 1]); + auto xi_o = with_facet::mkobj(xi); + + l0_o = DList::cons(gc_o, xi_o, l0_o); + } + + // TODO: log_streambuf using DArena + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj l0_po(static_cast(l0_o.data())); + REQUIRE(l0_po._typeseq() == typeseq::id()); + + pps.pretty(l0_po); + + REQUIRE(ss.str() == string(tc.expected_)); + } catch (std::exception & ex) { + std::cerr << "caught exception: " << ex.what() << std::endl; + REQUIRE(false); + } + } + } /* TEST_CASE(printable1) */ +} + +/* end Printable.test.cpp */ diff --git a/xo-object2/utest/X1Collector.test.cpp b/xo-object2/utest/X1Collector.test.cpp index 8b37c8ab..9d4256a1 100644 --- a/xo-object2/utest/X1Collector.test.cpp +++ b/xo-object2/utest/X1Collector.test.cpp @@ -74,7 +74,7 @@ namespace ut { TEST_CASE("x1", "[gc][x1]") { - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) { diff --git a/xo-printable2/include/xo/printable2/Printable.hpp b/xo-printable2/include/xo/printable2/Printable.hpp index b077d115..2e2064f5 100644 --- a/xo-printable2/include/xo/printable2/Printable.hpp +++ b/xo-printable2/include/xo/printable2/Printable.hpp @@ -18,4 +18,7 @@ #include "detail/IPrintable_Xfer.hpp" #include "detail/RPrintable.hpp" -/* end Printable.hpp */ \ No newline at end of file +// todo: additional includes in idl above +#include "detail/ppdetail_Printable.hpp" + +/* end Printable.hpp */ diff --git a/xo-printable2/include/xo/printable2/detail/APrintable.hpp b/xo-printable2/include/xo/printable2/detail/APrintable.hpp index a66eb4a2..c9217ba8 100644 --- a/xo-printable2/include/xo/printable2/detail/APrintable.hpp +++ b/xo-printable2/include/xo/printable2/detail/APrintable.hpp @@ -47,7 +47,7 @@ public: /** Pretty-printing support for this object. See [xo-indentlog/xo/indentlog/pretty.hpp] **/ - virtual bool pretty(Copaque data, const ppindentinfo & ppii) = 0; + virtual bool pretty(Copaque data, const ppindentinfo & ppii) const = 0; // nonconst methods ///@} diff --git a/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp b/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp index b765ae97..794284d8 100644 --- a/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp +++ b/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp @@ -56,7 +56,7 @@ namespace print { // const methods typeseq _typeseq() const noexcept override { return s_typeseq; } - [[noreturn]] bool pretty(Copaque, const ppindentinfo &) override { _fatal(); } + [[noreturn]] bool pretty(Copaque, const ppindentinfo &) const override { _fatal(); } // nonconst methods @@ -83,4 +83,4 @@ namespace print { } /*namespace print */ } /*namespace xo */ -/* IPrintable_Any.hpp */ \ No newline at end of file +/* IPrintable_Any.hpp */ diff --git a/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp b/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp index a9f28ac9..8ee71003 100644 --- a/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp +++ b/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp @@ -41,7 +41,7 @@ namespace print { // const methods typeseq _typeseq() const noexcept override { return s_typeseq; } - bool pretty(Copaque data, const ppindentinfo & ppii) override { + bool pretty(Copaque data, const ppindentinfo & ppii) const override { return I::pretty(_dcast(data), ppii); } @@ -78,4 +78,4 @@ namespace print { } /*namespace print */ } /*namespace xo*/ -/* end IPrintable_Xfer.hpp */ \ No newline at end of file +/* end IPrintable_Xfer.hpp */ diff --git a/xo-printable2/include/xo/printable2/detail/RPrintable.hpp b/xo-printable2/include/xo/printable2/detail/RPrintable.hpp index 78297814..12a6105c 100644 --- a/xo-printable2/include/xo/printable2/detail/RPrintable.hpp +++ b/xo-printable2/include/xo/printable2/detail/RPrintable.hpp @@ -31,6 +31,7 @@ public: using ObjectType = Object; using DataPtr = Object::DataPtr; using ppindentinfo = APrintable::ppindentinfo; + using typeseq = xo::facet::typeseq; ///@} /** @defgroup print-printable-router-ctors **/ @@ -46,8 +47,8 @@ public: ///@{ // const methods - int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } - bool pretty(const ppindentinfo & ppii) { + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + bool pretty(const ppindentinfo & ppii) const { return O::iface()->pretty(O::data(), ppii); } diff --git a/xo-printable2/include/xo/printable2/detail/ppdetail_Printable.hpp b/xo-printable2/include/xo/printable2/detail/ppdetail_Printable.hpp new file mode 100644 index 00000000..ba7a3d82 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/ppdetail_Printable.hpp @@ -0,0 +1,21 @@ +/** @file ppdetail_Printable.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include +#include "Printable.hpp" + +namespace xo { + namespace print { + template + struct ppdetail> { + static bool print_pretty(const ppindentinfo & ppii, + const xo::facet::obj & x) { + return x.pretty(ppii); + } + }; + } +} /*namespace xo*/ + +/* end ppdetail_Printable.hpp */