delegate: curried functions can accept linked parameters either by value or by reference
This commit is contained in:
5
TODO
5
TODO
@@ -22,7 +22,6 @@
|
||||
* tags revenge: if it's possible, reintroduce them but without a link to entities (see #169 for more details)
|
||||
|
||||
Ready to go:
|
||||
==> req: ref to value with curried functions
|
||||
* add on-the-fly sort functionality (is it possible?)
|
||||
* (even more) optimized standard views are possible!
|
||||
* induce-respect policy
|
||||
* add on-the-fly sort functionality
|
||||
* introduce induce-respect policy
|
||||
|
||||
@@ -229,10 +229,10 @@ As shown previously, it accepts functions having type `void(int)`. However, we
|
||||
can do something more in this case, because of how the delegate class is
|
||||
implemented internally (that is something that goes beyond the purposes of this
|
||||
document).<br/>
|
||||
In particular, the delegate accepts also functions having type `void(T, int)`,
|
||||
as long as `sizeof(T)` is lower than or equal to `sizeof(void *)`. The first
|
||||
parameter is stored directly by the delegate class and passed to the connected
|
||||
function when needed.
|
||||
In particular, the delegate accepts also functions having type equivalent to
|
||||
`void(T &, int)`, as long as `sizeof(T)` is lower than or equal to
|
||||
`sizeof(void *)`. The first parameter is stored directly by the delegate class
|
||||
and passed to the connected function when needed.
|
||||
|
||||
In other terms, this works as well with the above definition:
|
||||
|
||||
@@ -245,7 +245,11 @@ delegate(42);
|
||||
|
||||
In this case, the function `g` is invoked with parameters `'c'` and `42`.
|
||||
However, the function type of the delegate is still `void(int)`, mainly because
|
||||
this is also the signature of its function call operator.
|
||||
this is also the signature of its function call operator.<br/>
|
||||
When the curried function gets the linked parameter by reference, it can modify
|
||||
it and the new value will be stored in place of the previous one. It's highly
|
||||
discouraged to accept the parameter by reference, unless you know exactly what
|
||||
you're doing. Prefer accepting it by value if possible.
|
||||
|
||||
# Event dispatcher
|
||||
|
||||
|
||||
@@ -159,11 +159,11 @@ public:
|
||||
static_assert(sizeof(Type) <= sizeof(void *));
|
||||
static_assert(std::is_trivially_copyable_v<Type>);
|
||||
static_assert(std::is_trivially_destructible_v<Type>);
|
||||
static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type, Args...>);
|
||||
static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>);
|
||||
new (&storage) Type{value_or_instance};
|
||||
|
||||
fn = [](storage_type &storage, Args... args) -> Ret {
|
||||
Type value_or_instance = *reinterpret_cast<Type *>(&storage);
|
||||
Type &value_or_instance = *reinterpret_cast<Type *>(&storage);
|
||||
return std::invoke(Candidate, value_or_instance, args...);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,10 +5,15 @@ int delegate_function(const int &i) {
|
||||
return i*i;
|
||||
}
|
||||
|
||||
int curried_function(int i, int j) {
|
||||
int curried_function_by_value(int i, int j) {
|
||||
return i+j;
|
||||
}
|
||||
|
||||
int curried_function_by_ref(int &value) {
|
||||
value *= 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
struct delegate_functor {
|
||||
int operator()(int i) {
|
||||
return i+i;
|
||||
@@ -194,10 +199,19 @@ TEST(Delegate, ConstInstance) {
|
||||
ASSERT_EQ(delegate, entt::delegate<int(int)>{});
|
||||
}
|
||||
|
||||
TEST(Delegate, CurriedFunction) {
|
||||
TEST(Delegate, CurriedFunctionByValue) {
|
||||
entt::delegate<int(int)> delegate;
|
||||
delegate.connect<&curried_function>(3);
|
||||
delegate.connect<&curried_function_by_value>(3);
|
||||
|
||||
ASSERT_TRUE(delegate);
|
||||
ASSERT_EQ(delegate(1), 4);
|
||||
}
|
||||
|
||||
TEST(Delegate, CurriedFunctionByRef) {
|
||||
entt::delegate<int()> delegate;
|
||||
delegate.connect<&curried_function_by_ref>(2);
|
||||
|
||||
ASSERT_TRUE(delegate);
|
||||
ASSERT_EQ(delegate(), 4);
|
||||
ASSERT_EQ(delegate(), 8);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user