Skip to content

Commit

Permalink
Simplify type erasure
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi-Armstrong committed Nov 30, 2024
1 parent 8f4ca8d commit b4b064a
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 33 deletions.
13 changes: 7 additions & 6 deletions tesseract_common/include/tesseract_common/any_poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,16 @@ TESSERACT_COMMON_IGNORE_WARNINGS_POP
{ \
using K##AnyInstanceBase = tesseract_common::TypeErasureInstance<C, tesseract_common::TypeErasureInterface>; \
using K##AnyInstance = tesseract_common::detail_any::AnyInstance<C>; \
using K##AnyInstanceWrapper = tesseract_common::TypeErasureInstanceWrapper<K##AnyInstance>; \
} \
BOOST_CLASS_EXPORT_KEY(tesseract_serialization::any_poly::K##AnyInstanceBase) \
BOOST_CLASS_EXPORT_KEY(tesseract_serialization::any_poly::K##AnyInstance) \
BOOST_CLASS_EXPORT_KEY(tesseract_serialization::any_poly::K##AnyInstanceWrapper) \
BOOST_CLASS_TRACKING(tesseract_serialization::any_poly::K##AnyInstanceBase, boost::serialization::track_never) \
BOOST_CLASS_TRACKING(tesseract_serialization::any_poly::K##AnyInstance, boost::serialization::track_never) \
BOOST_CLASS_TRACKING(tesseract_serialization::any_poly::K##AnyInstanceWrapper, boost::serialization::track_never)
BOOST_CLASS_TRACKING(tesseract_serialization::any_poly::K##AnyInstance, boost::serialization::track_never)

/** @brief If shared library, this must go in the cpp after the implicit instantiation of the serialize function */
#define TESSERACT_ANY_EXPORT_IMPLEMENT(K) \
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_serialization::any_poly::K##AnyInstanceBase) \
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_serialization::any_poly::K##AnyInstance) \
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_serialization::any_poly::K##AnyInstanceWrapper)
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_serialization::any_poly::K##AnyInstance)

/**
* @brief This should not be used within shared libraries use the two above.
Expand Down Expand Up @@ -102,6 +98,11 @@ struct AnyInstance : tesseract_common::TypeErasureInstance<T, tesseract_common::

BOOST_CONCEPT_ASSERT((AnyConcept<T>));

std::unique_ptr<tesseract_common::TypeErasureInterface> clone() const final
{
return std::make_unique<AnyInstance<T>>(this->get());
}

private:
friend class boost::serialization::access;
friend struct tesseract_common::Serialization;
Expand Down
33 changes: 6 additions & 27 deletions tesseract_common/include/tesseract_common/type_erasure.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,34 +95,12 @@ struct TypeErasureInstance : ConceptInterface
return this->getType() == other.getType() && this->get() == *static_cast<const ConceptValueType*>(other.recover());
}

ConcreteType value_;

private:
friend class boost::serialization::access;
friend struct tesseract_common::Serialization;
template <class Archive>
void serialize(Archive& ar, const unsigned int /*version*/) // NOLINT
std::unique_ptr<tesseract_common::TypeErasureInterface> clone() const override
{
// If this line is removed a exception is thrown for unregistered cast need to too look into this.
ar& boost::serialization::make_nvp("base", boost::serialization::base_object<ConceptInterface>(*this));
ar& boost::serialization::make_nvp("impl", value_);
throw std::runtime_error("This should never be called!");
}
};

template <typename F>
struct TypeErasureInstanceWrapper : F // NOLINT
{
using ConceptValueType = typename F::ConceptValueType;
using ConceptInterfaceType = typename F::ConceptInterfaceType;

TypeErasureInstanceWrapper() = default;
TypeErasureInstanceWrapper(const ConceptValueType& x) : F(x) {}
TypeErasureInstanceWrapper(TypeErasureInstanceWrapper&& x) noexcept : F(std::move(x)) {}

std::unique_ptr<TypeErasureInterface> clone() const final
{
return std::make_unique<TypeErasureInstanceWrapper<F>>(this->get());
}
ConcreteType value_;

private:
friend class boost::serialization::access;
Expand All @@ -131,7 +109,8 @@ struct TypeErasureInstanceWrapper : F // NOLINT
void serialize(Archive& ar, const unsigned int /*version*/) // NOLINT
{
// If this line is removed a exception is thrown for unregistered cast need to too look into this.
ar& boost::serialization::make_nvp("base", boost::serialization::base_object<F>(*this));
ar& boost::serialization::make_nvp("base", boost::serialization::base_object<ConceptInterface>(*this));
ar& boost::serialization::make_nvp("impl", value_);
}
};

Expand All @@ -152,7 +131,7 @@ struct TypeErasureBase

template <typename T, generic_ctor_enabler<T> = 0>
TypeErasureBase(T&& value) // NOLINT
: value_(std::make_unique<TypeErasureInstanceWrapper<ConceptInstance<uncvref_t<T>>>>(value))
: value_(std::make_unique<ConceptInstance<uncvref_t<T>>>(value))
{
}

Expand Down

0 comments on commit b4b064a

Please sign in to comment.