diff --git a/include/xo/facet/FacetRegistry.hpp b/include/xo/facet/FacetRegistry.hpp index 9b7e7ad..a69735a 100644 --- a/include/xo/facet/FacetRegistry.hpp +++ b/include/xo/facet/FacetRegistry.hpp @@ -7,8 +7,9 @@ #pragma once +#include "TypeRegistry.hpp" #include "facet_implementation.hpp" -#include "typeseq.hpp" +//#include "typeseq.hpp" #include "obj.hpp" #include #include @@ -74,6 +75,9 @@ namespace xo { static void register_impl() { static FacetImplType impl; + TypeRegistry::register_type(); + TypeRegistry::register_type(); + instance()._register_impl(typeseq::id(), typeseq::id(), &impl); diff --git a/include/xo/facet/TypeRegistry.hpp b/include/xo/facet/TypeRegistry.hpp new file mode 100644 index 0000000..1909163 --- /dev/null +++ b/include/xo/facet/TypeRegistry.hpp @@ -0,0 +1,137 @@ +/** @file TypeRegistry.hpp + * + * @brief Runtime facet implementation lookup + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "typeseq.hpp" +#include +#include +#include + +namespace xo { + namespace facet { + + /** @class TypeRegistry + * + * @brief Runtime registry for types. + * + * Just assigns ids and remembers names. + * Not a full reflection implementation + **/ + class TypeRegistry { + public: + using ReprType = xo::mm::DArenaVector; + using ArenaConfig = xo::mm::ArenaConfig; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using typeseq = xo::reflect::typeseq; + + /** singleton instance. + * @p hint_max_capacity is a lower bound for registry capacity. + * Only honored the first time instance is called. + **/ + static TypeRegistry & instance(uint32_t hint_max_capacity = 1024) { + static TypeRegistry s_instance(hint_max_capacity); + return s_instance; + } + + /** Type-safe registration + * + * Registers the compile-time FacetImplementation + * for runtime lookup. + * + * @tparam AFacet abstract facet type + * @tparam DRepr data representation type + **/ + template + static void register_type() { + typerecd r = typerecd::recd(); + + instance()._register_type(r); + } + + /** Number of registered (facet, repr) pairs **/ + std::size_t size() const { return registry_.size(); } + + std::string_view id2name(typeseq id) const noexcept { + return instance()._id2name(id); + } + + /** visit memory pools owned by facet registry **/ + void visit_pools(const MemorySizeVisitor & visitor) { + registry_.visit_pools(visitor); + } + + /** Check if type is registered **/ + bool contains(typeseq id) const + { + if ((0 <= id.seqno()) + && (id.seqno() < static_cast(registry_.size()))) + { + return (registry_.at(id.seqno()).seqno() == id.seqno()); + } + + return false; + } + + void dump(std::ostream * p_out) const { + (*p_out) << std::endl; + (*p_out) << " " << item.name() << std::endl; + } + (*p_out) << ">" << std::endl; + } + + private: + /** Register a facet implementation (type-erased) + * + * @param facet_id typeseq for abstract facet (e.g., APrintable) + * @param repr_id typeseq for data representation (e.g., DFloat) + * @param impl pointer to stateless implementation instance + **/ + void _register_type(const typerecd & recd) + { + if ((recd.seqno() >= 0) + && (static_cast(registry_.size()) <= recd.seqno())) + { + registry_.resize(recd.seqno() + 1); + } + + registry_.at(recd.seqno()) = recd; + } + + /** Get typename from @p id. + **/ + std::string_view _id2name(typeseq id) const + { + if ((0 <= id.seqno()) + && (static_cast(id.seqno()) < registry_.size())) + { + return registry_.at(id.seqno()).name(); + } + + return typerecd::sentinel().name(); + } + + private: + TypeRegistry(uint32_t hint_max_capacity) + : registry_(ReprType::map(ArenaConfig() + .with_name("types") + .with_size(hint_max_capacity + * sizeof(typerecd)))) + {} + + /** runtime lookup table (AFacet,DRepr) -> impl **/ + ReprType registry_; + }; + + } /*namespace facet*/ +} /*namespace xo*/ + +/* end TypeRegistry.hpp */ diff --git a/include/xo/facet/typeseq.hpp b/include/xo/facet/typeseq.hpp index 23b84a9..d43d9e6 100644 --- a/include/xo/facet/typeseq.hpp +++ b/include/xo/facet/typeseq.hpp @@ -12,7 +12,7 @@ namespace xo { namespace facet { // Re-export from xo::arena namespace - using xo::reflect::typeseq_impl; + using xo::reflect::typerecd; using xo::reflect::typeseq; } } /*namespace xo*/