xo-facet: + to_facet() convenience method on obj<A,D>

This commit is contained in:
Roland Conybeare 2026-02-04 16:23:55 -05:00
commit 5c3772e62e
5 changed files with 40 additions and 1 deletions

View file

@ -2,6 +2,7 @@
include(CMakeFindDependencyMacro)
# note: dependencies here must coordinate with xo-facet/CMakeLists.txt
find_dependency(xo_arena)
find_dependency(xo_reflectutil)
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")

View file

@ -236,9 +236,25 @@ namespace xo {
/** runtime lookup table (AFacet,DRepr) -> impl **/
xo::map::DArenaHashMap<key_type, const void *, KeyHash> registry_;
//std::unordered_map<key_type, const void *, KeyHash> registry_;
};
// Deferred definitioon of obj<AFacet,DRepr>::to_facet(),
// since implementation requires FacetRegistry
//
template <typename AFacet, typename DRepr>
template <typename AOther>
obj<AOther,DRepr>
obj<AFacet,DRepr>::to_facet()
{
if constexpr (std::is_same_v<DRepr, DVariantPlaceholder>) {
// return type has type-erased data
return FacetRegistry::instance().variant<AOther,AFacet>(*this);
} else {
// return type has known data
return obj<AOther,DRepr>(this->data());
}
}
} /*namespace facet*/
} /*namespace xo*/

View file

@ -59,6 +59,10 @@ namespace xo {
**/
template <typename AFacet, typename DRepr = DVariantPlaceholder>
struct OObject {
static_assert(has_facet_impl<AFacet, DRepr>,
"Missing FacetImplementation<AFacet,DRepr> specialization. "
"Did you include IFacet_DRepr.hpp (via the convenience header)?");
using FacetType = AFacet;
using ISpecific = FacetImplType<AFacet, DRepr>;
using DataType = DRepr;

View file

@ -92,6 +92,14 @@ namespace xo {
//static_assert(false && "expect specialization <AFacet,DRepr> which should provide ImplType trait");
};
/** true iff FacetImplementation<AFacet,DRepr> has been specialized with ImplType.
* False when specialization header (IFacet_DRepr.hpp) not included.
**/
template <typename AFacet, typename DRepr>
concept has_facet_impl = requires {
typename FacetImplementation<AFacet, DRepr>::ImplType;
};
/** Retrieve facet implementation for a (facet,datatype) pair **/
template <typename AFacet, typename DRepr>
using FacetImplType = FacetImplementation<AFacet, DRepr>::ImplType;

View file

@ -6,6 +6,7 @@
#pragma once
#include "RRouter.hpp"
//#include "FacetRegistry.hpp" // nope, would create include cycle
#include <utility>
#include <cassert>
@ -127,6 +128,15 @@ namespace xo {
return obj(iface, data);
}
/** - runtime polymorphism (DRepr == DVariantPlaceholder)
* (requires FacetRegistry for lookup)
* - comptime polymorphism (DRepr != DVariantPlaceholder)
*
* Definition in FacetRegistry.hpp, to avoid #include dependency
**/
template <typename AOther>
obj<AOther,DRepr> to_facet();
/** enabled when RRouter<AFacet> provides _preincrement.
* Note we don't need this trick for comparison operators,
* since return type is fixed.