xo-gc stack: streamline object pointer forwarding
This commit is contained in:
parent
af4c37c575
commit
bfae393127
6 changed files with 89 additions and 9 deletions
|
|
@ -36,6 +36,19 @@ namespace xo {
|
|||
return O::iface()->alloc(O::data(), typeseq::id<T>(), sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T * std_copy_for(const T * src) noexcept {
|
||||
// TODO: fix alloc_copy(), should take const std::byte *
|
||||
|
||||
T * copy = (T *)O::iface()->alloc_copy(O::data(), (std::byte*)const_cast<T *>(src));
|
||||
|
||||
if (copy) {
|
||||
*copy = *src;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
void _drop() const noexcept { O::iface()->_drop(O::data()); }
|
||||
std::string_view name() const noexcept { return O::iface()->name(O::data()); }
|
||||
|
|
|
|||
|
|
@ -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,12 +246,37 @@ namespace xo {
|
|||
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);
|
||||
if (this->data()) {
|
||||
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());
|
||||
}
|
||||
} else {
|
||||
// return type has known data
|
||||
return obj<AOther,DRepr>(this->data());
|
||||
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>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -76,5 +76,5 @@
|
|||
attributes: [],
|
||||
},
|
||||
],
|
||||
router_facet_explicit_content: [ ],
|
||||
router_facet_explicit_content: []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,31 @@
|
|||
#include "detail/IGCObject_Xfer.hpp"
|
||||
#include "detail/RGCObject.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
/** defined here to avoid #include cycle, since
|
||||
* template obj<AGCObject,DRepr> awkward to make available there
|
||||
**/
|
||||
template <typename Object>
|
||||
template <typename DRepr>
|
||||
void
|
||||
RCollector<Object>::forward_inplace(xo::facet::obj<AGCObject,DRepr> * p_obj)
|
||||
{
|
||||
this->forward_inplace(p_obj->iface(), (void **)&(p_obj->data_));
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
template <typename DRepr>
|
||||
void
|
||||
RCollector<Object>::forward_inplace(DRepr ** p_repr)
|
||||
{
|
||||
// fetch static interface for DRepr
|
||||
auto iface = xo::facet::impl_for<AGCObject,DRepr>();
|
||||
|
||||
this->forward_inplace(&iface, (void **)p_repr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* end GCObject.hpp */
|
||||
|
||||
/* end GCObject.hpp */
|
||||
|
|
@ -23,6 +23,16 @@ namespace xo {
|
|||
RCollector() = default;
|
||||
RCollector(DataPtr data) : Object{std::move(data)} {}
|
||||
|
||||
/** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/
|
||||
template <typename DRepr>
|
||||
void forward_inplace(obj<AGCObject,DRepr> * p_obj);
|
||||
|
||||
/** another convenience template for forwarding.
|
||||
* Defined in RGCObject.hpp to avoid #include cycle.
|
||||
**/
|
||||
template <typename DRepr>
|
||||
void forward_inplace(DRepr ** pp_repr);
|
||||
|
||||
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
size_type allocated(generation g, role r) const noexcept { return O::iface()->allocated(O::data(), g, r); }
|
||||
size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue