xo-facet: + to_facet() convenience method on obj<A,D>
This commit is contained in:
parent
24912ffd38
commit
5c3772e62e
5 changed files with 40 additions and 1 deletions
|
|
@ -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@")
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue