diff --git a/include/podio/detail/Link.h b/include/podio/detail/Link.h index b7f38da73..c9ddd1b38 100644 --- a/include/podio/detail/Link.h +++ b/include/podio/detail/Link.h @@ -5,6 +5,7 @@ #include "podio/detail/LinkObj.h" #include "podio/utilities/MaybeSharedPtr.h" #include "podio/utilities/TypeHelpers.h" +#include #ifdef PODIO_JSON_OUTPUT #include "nlohmann/json.hpp" @@ -262,8 +263,16 @@ class LinkT { void set(T value) { if constexpr (std::is_same_v) { setFrom(std::move(value)); - } else { + } else if constexpr (std::is_same_v) { + setTo(std::move(value)); + } else if constexpr (detail::isInterfaceInitializableFrom && + !detail::isInterfaceInitializableFrom) { + setFrom(std::move(value)); + } else if constexpr (detail::isInterfaceInitializableFrom && + !detail::isInterfaceInitializableFrom) { setTo(std::move(value)); + } else { + static_assert(detail::always_false, "Argument type is ambiguous, can't determine link direction"); } } diff --git a/include/podio/utilities/TypeHelpers.h b/include/podio/utilities/TypeHelpers.h index d774644d7..b2a568f13 100644 --- a/include/podio/utilities/TypeHelpers.h +++ b/include/podio/utilities/TypeHelpers.h @@ -40,6 +40,11 @@ namespace det { namespace detail { + // A helper variable template that is always false, used for static_asserts + // and other compile-time checks that should always fail. + template + inline constexpr bool always_false = false; + /// Helper struct to determine whether a given type T is in a tuple of types /// that act as a type list in this case template diff --git a/tests/unittests/links.cpp b/tests/unittests/links.cpp index 0bb939731..eba6bd5da 100644 --- a/tests/unittests/links.cpp +++ b/tests/unittests/links.cpp @@ -460,6 +460,21 @@ TEST_CASE("Links with interfaces", "[links][interface-types]") { link.set(hit); REQUIRE(link.get() == hit); REQUIRE(link.get() == cluster); + + // Check determining `set` direction for a link going in a reverse direction + using ReverseInterfaceLinkCollection = + podio::LinkCollection; + auto rColl = ReverseInterfaceLinkCollection{}; + auto rLink = rColl.create(); + + rLink.set(cluster); + rLink.set(iface); + REQUIRE(rLink.get() == iface); + REQUIRE(rLink.get() == cluster); + + rLink.set(hit); + REQUIRE(rLink.get() == hit); + REQUIRE(rLink.get() == cluster); } #ifdef PODIO_JSON_OUTPUT