diff --git a/CMakeLists.txt b/CMakeLists.txt index bef04e3b..7232c203 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,13 +77,13 @@ set(DOX_EXCLUDE_PATTERNS [=[ add_subdirectory(xo-cmake) add_subdirectory(xo-facet) # sep iface,data add_subdirectory(xo-indentlog) +add_subdirectory(xo-reflectutil) # header-only reflect support add_subdirectory(xo-allocutil) add_subdirectory(xo-refcnt) add_subdirectory(xo-subsys) add_subdirectory(xo-randomgen) add_subdirectory(xo-flatstring) add_subdirectory(xo-pyutil) -add_subdirectory(xo-reflectutil) add_subdirectory(xo-reflect) add_subdirectory(xo-pyreflect) add_subdirectory(xo-ratio) diff --git a/xo-facet/CMakeLists.txt b/xo-facet/CMakeLists.txt index e1804f25..ad8a4cb4 100644 --- a/xo-facet/CMakeLists.txt +++ b/xo-facet/CMakeLists.txt @@ -25,6 +25,10 @@ add_subdirectory(utest) set(SELF_LIB xo_facet) xo_add_headeronly_library(${SELF_LIB}) + +# note: dependencies here must coordinate with cmake/xo_facetConfig.cmake.in +xo_headeronly_dependency(${SELF_LIB} xo_reflectutil) + xo_install_library4(${SELF_LIB} ${PROJECT_NAME}Targets) xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) diff --git a/xo-facet/cmake/xo_facetConfig.cmake.in b/xo-facet/cmake/xo_facetConfig.cmake.in index c25a5c24..88709824 100644 --- a/xo-facet/cmake/xo_facetConfig.cmake.in +++ b/xo-facet/cmake/xo_facetConfig.cmake.in @@ -1,7 +1,7 @@ @PACKAGE_INIT@ include(CMakeFindDependencyMacro) -#find_dependency(indentlog) -#find_dependency(xo_flatstring) +# note: dependencies here must coordinate with xo-facet/CMakeLists.txt +find_dependency(xo_reflectutil) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/xo-facet/include/xo/facet/typeseq.hpp b/xo-facet/include/xo/facet/typeseq.hpp index ab85821c..23b84a92 100644 --- a/xo-facet/include/xo/facet/typeseq.hpp +++ b/xo-facet/include/xo/facet/typeseq.hpp @@ -1,87 +1,19 @@ /** @file typeseq.hpp + * + * @brief Re-export typeseq from xo-arena for backwards compatibility * * @author Roland Conybeare, Dec 2025 **/ #pragma once -#include -#include +#include namespace xo { namespace facet { - /** - * 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<>; + // Re-export from xo::arena namespace + using xo::reflect::typeseq_impl; + using xo::reflect::typeseq; } } /*namespace xo*/ diff --git a/xo-reflectutil/CMakeLists.txt b/xo-reflectutil/CMakeLists.txt index a231f5dc..4f3f6dee 100644 --- a/xo-reflectutil/CMakeLists.txt +++ b/xo-reflectutil/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/xo-reflectutil/cmake/xo_reflectutilConfig.cmake.in b/xo-reflectutil/cmake/xo_reflectutilConfig.cmake.in index b7a5a0a2..26df0fc7 100644 --- a/xo-reflectutil/cmake/xo_reflectutilConfig.cmake.in +++ b/xo-reflectutil/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/xo-reflectutil/include/xo/reflectutil/typeseq.hpp b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp new file mode 100644 index 00000000..dd0b869a --- /dev/null +++ b/xo-reflectutil/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 */