From f4071256e8e193ac98e53bbc72d43aa5ef838adb 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 --- codegen/router_facet.hpp.j2 | 3 +- include/xo/facet/FacetRegistry.hpp | 76 ++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/codegen/router_facet.hpp.j2 b/codegen/router_facet.hpp.j2 index 9d323de..2c702b5 100644 --- a/codegen/router_facet.hpp.j2 +++ b/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/include/xo/facet/FacetRegistry.hpp b/include/xo/facet/FacetRegistry.hpp index 27db9d0..2a3aa48 100644 --- a/include/xo/facet/FacetRegistry.hpp +++ b/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: