xo-gc stack: streamline object pointer forwarding

This commit is contained in:
Roland Conybeare 2026-02-13 15:15:08 -05:00
commit ff5bff1aa5
2 changed files with 38 additions and 7 deletions

View file

@ -159,7 +159,7 @@ namespace xo {
* }
**/
template <typename ATo, typename AFrom>
obj<ATo> try_variant(obj<AFrom> from) {
obj<ATo> try_variant(obj<AFrom> from) noexcept {
return try_variant<ATo>(from._typeseq(), from.data());
}
@ -173,7 +173,7 @@ namespace xo {
* = FacetRegistry::variant<ABar>(foo._typeseq(), foo.opaque_data());
**/
template <typename AFacet>
obj<AFacet> try_variant(typeseq repr_id, void * data) {
obj<AFacet> try_variant(typeseq repr_id, void * data) noexcept {
const AFacet * iface = this->lookup<AFacet>(repr_id);
if (iface)
@ -246,6 +246,7 @@ namespace xo {
obj<AOther,DRepr>
obj<AFacet,DRepr>::to_facet()
{
if (this->data()) {
if constexpr (std::is_same_v<DRepr, DVariantPlaceholder>) {
// return type has type-erased data
return FacetRegistry::instance().variant<AOther,AFacet>(*this);
@ -253,6 +254,30 @@ namespace xo {
// return type has known data
return obj<AOther,DRepr>(this->data());
}
} else {
return obj<AOther,DRepr>();
}
}
// 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>::try_to_facet() noexcept
{
if (this->data()) {
if constexpr (std::is_same_v<DRepr, DVariantPlaceholder>) {
// return type has type-erased data
return FacetRegistry::instance().try_variant<AOther,AFacet>(*this);
} else {
// return type has known data
return obj<AOther,DRepr>(this->data());
}
} else {
return obj<AOther,DRepr>();
}
}
} /*namespace facet*/

View file

@ -137,6 +137,12 @@ namespace xo {
template <typename AOther>
obj<AOther,DRepr> to_facet();
/** like to_facet<AOther>(),
* but on failure return empty obj instead of throwing exception
**/
template <typename AOther>
obj<AOther,DRepr> try_to_facet() noexcept;
/** enabled when RRouter<AFacet> provides _preincrement.
* Note we don't need this trick for comparison operators,
* since return type is fixed.