Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Delegate construction with tag type #2668

Merged
merged 9 commits into from
Nov 15, 2023
Merged
25 changes: 25 additions & 0 deletions Core/include/Acts/Utilities/Delegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ namespace Acts {
/// Ownership enum for @c Delegate
enum class DelegateType { Owning, NonOwning };

template <auto C>
struct DelegateFuncTag {
explicit constexpr DelegateFuncTag() = default;
};

// Specialization needed for defaulting ownership and for R(Args...) syntax
template <typename, typename H = void, DelegateType = DelegateType::NonOwning>
class Delegate;
Expand Down Expand Up @@ -91,6 +96,26 @@ class Delegate<R(Args...), H, O> {
connect(callable);
}

/// Constructor with a compile-time free function pointer
/// @tparam Callable The compile-time free function pointer
/// @note @c DelegateFuncTag is used to communicate the callable type
template <auto Callable>
Delegate(DelegateFuncTag<Callable>) {
connect<Callable>();
}

/// Constructor with a compile-time member function pointer and instance
/// @tparam Callable The compile-time member function pointer
/// @tparam Type The type of the instance the member function should be called on
/// @param instance The instance on which the member function pointer should be called on
/// @note @c Delegate does not assume owner ship over @p instance.
/// @note @c DelegateFuncTag is used to communicate the callable type
template <auto Callable, typename Type, DelegateType T = kOwnership,
typename = std::enable_if_t<T == DelegateType::NonOwning>>
Delegate(DelegateFuncTag<Callable>, const Type *instance) {
connect<Callable>(instance);
}

/// Constructor from rvalue reference is deleted, should catch construction
/// with temporary objects and thus invalid pointers
template <typename Callable, typename = isNoFunPtr<Callable>>
Expand Down
15 changes: 15 additions & 0 deletions Tests/UnitTests/Core/Utilities/DelegateTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@ BOOST_AUTO_TEST_CASE(ConnectRuntime) {
}
}

BOOST_AUTO_TEST_CASE(ConnectConstructFuncPtr) {
Delegate<int(int, int)> add{DelegateFuncTag<&sumImpl>{}};
BOOST_CHECK(add);
BOOST_CHECK(add.connected());
BOOST_CHECK_EQUAL(add(4, 4), 8);

Subtractor s{18};
Delegate<int(int)> sub{DelegateFuncTag<&Subtractor::execute>{}, &s};

BOOST_CHECK(sub);
BOOST_CHECK(sub.connected());

BOOST_CHECK_EQUAL(sub(7), 7 - 18);
}

void modify(int& v, int a) {
v = a;
}
Expand Down
Loading