From 412697bbb875fcbb7d4f5bffa1d7f74a283b28cf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 5 Jan 2026 21:49:33 -0500 Subject: [PATCH] refactor: move xo::facet::typeseq to xo-reflectutil/ prep for adding xo-arena/ --- CMakeLists.txt | 2 +- cmake/xo_reflectutilConfig.cmake.in | 7 +-- include/xo/reflectutil/typeseq.hpp | 88 +++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 include/xo/reflectutil/typeseq.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a231f5d..4f3f6de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets # ---------------------------------------------------------------- # dependencies -xo_headeronly_dependency(${SELF_LIB} xo_flatstring) +#xo_headeronly_dependency(${SELF_LIB} xo_flatstring) #xo_headeronly_dependency(${SELF_LIB} randomgen) # etc.. diff --git a/cmake/xo_reflectutilConfig.cmake.in b/cmake/xo_reflectutilConfig.cmake.in index b7a5a0a..26df0fc 100644 --- a/cmake/xo_reflectutilConfig.cmake.in +++ b/cmake/xo_reflectutilConfig.cmake.in @@ -6,12 +6,7 @@ include(CMakeFindDependencyMacro) # must coordinate with xo_dependency() calls # in xo-reactor/src/reactor/CMakeLists.txt # -find_dependency(xo_flatstring) -#find_dependency(subsys) -#find_dependency(Eigen3) -#find_dependency(webutil) -#find_dependency(printjson) -#find_dependency(callback) +#find_dependency(xo_flatstring) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/include/xo/reflectutil/typeseq.hpp b/include/xo/reflectutil/typeseq.hpp new file mode 100644 index 0000000..dd0b869 --- /dev/null +++ b/include/xo/reflectutil/typeseq.hpp @@ -0,0 +1,88 @@ +/** @file typeseq.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace reflect { + /** + * Tag here so we can preserve header-only implementation + * and still have static variable + */ + template + struct typeseq_impl { + explicit typeseq_impl(int32_t s) : seqno_{s} {} + + /** Can't have this be constexpr. + * We need ids in shared libraries to be generated + * at load time to avoid false positives + * + * Return unique id number for each type. + * Numbers are sequentially allocated, so can use + * as vector indices + * + * Conversely note that built-in typeinfo may + * return false negatives across library boundaries + * when using clang. + **/ + template + static typeseq_impl id() { + static bool armed = true; + static int32_t id = 0; + + if (armed) { + armed = false; + id = ++s_next_id; + } + + return typeseq_impl(id); + + } + + /** 'anonymous' sentinel type. + * Niche uses for this, e.g. untyped allocator + **/ + static typeseq_impl anon() { + return typeseq_impl(-1); + } + + int32_t seqno() const { return seqno_; } + + private: + static int32_t s_next_id; + + int32_t seqno_; + }; + + template + int32_t typeseq_impl::s_next_id = 0; + + template + inline bool + operator==(const typeseq_impl & lhs, const typeseq_impl & rhs) { + return lhs.seqno() == rhs.seqno(); + } + + template + inline bool + operator!=(const typeseq_impl & lhs, const typeseq_impl & rhs) { + return lhs.seqno() != rhs.seqno(); + } + + template + inline std::ostream & + operator<<(std::ostream & s, const typeseq_impl & x) { + s << x.seqno(); + return s; + } + + using typeseq = typeseq_impl<>; + } /*namespace reflect*/ +} /*namespace xo*/ + +/* end typeseq.hpp */