Fixes for delegates with lambdas

This commit is contained in:
John Wellbelove 2019-08-13 12:58:45 +01:00
parent 5a7e181100
commit c11c9cfdb6

View File

@ -49,6 +49,7 @@ Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibl
#define ETL_DELEGATE_INCLUDED
#include "platform.h"
#include "type_traits.h"
#if ETL_CPP11_SUPPORTED == 0
#error NOT SUPPORTED FOR C++03 OR BELOW
@ -71,16 +72,15 @@ namespace etl
//*************************************************************************
// Copy constructor.
//*************************************************************************
delegate(const delegate& other)
{
other.invocation.clone(invocation);
}
delegate(const delegate& other) = default;
//*************************************************************************
// Constructor from lambda or functor.
//*************************************************************************
template <typename TLambda>
delegate(const TLambda& instance)
template <typename TLambda,
typename TDummy = typename etl::enable_if<!etl::is_same<TLambda,
etl::delegate<TReturn(TParams...)>>::value, int>::type>
delegate(TLambda& instance)
{
assign((void*)(&instance), lambda_stub<TLambda>);
}
@ -97,8 +97,10 @@ namespace etl
//*************************************************************************
/// Create from Lambda or Functor.
//*************************************************************************
template <typename TLambda>
static delegate create(const TLambda& instance)
template <typename TLambda,
typename TDummy = typename etl::enable_if<!etl::is_same<TLambda,
etl::delegate<TReturn(TParams...)>>::value, int>::type>
static delegate create(TLambda& instance)
{
return delegate((void*)(&instance), lambda_stub<TLambda>);
}
@ -112,6 +114,13 @@ namespace etl
return delegate((void*)(&instance), method_stub<T, Method>);
}
//*************************************************************************
/// Create from instance method (Run time).
/// Deleted for rvalue references.
//*************************************************************************
template <typename T, TReturn(T::*Method)(TParams...)>
static delegate create(T&& instance) = delete;
//*************************************************************************
/// Create from const instance method (Run time).
//*************************************************************************
@ -121,6 +130,9 @@ namespace etl
return delegate((void*)(&instance), const_method_stub<T, Method>);
}
template <typename T, TReturn(T::*Method)(TParams...) const>
static delegate create(T&& instance) = delete;
//*************************************************************************
/// Create from instance method (Compile time).
//*************************************************************************
@ -142,6 +154,7 @@ namespace etl
#if !defined(ETL_COMPILER_GCC)
//*************************************************************************
/// Create from instance function operator (Compile time).
/// At the time of writing, GCC appears to have trouble with this.
//*************************************************************************
template <typename T, T& Instance>
static delegate create()
@ -161,17 +174,15 @@ namespace etl
//*************************************************************************
/// Create from function (Compile time).
//*************************************************************************
delegate& operator =(const delegate& other)
{
other.invocation.clone(invocation);
return *this;
}
delegate& operator =(const delegate& rhs) = default;
//*************************************************************************
/// Create from Lambda or Functor.
//*************************************************************************
template <typename TLambda>
delegate& operator =(const TLambda& instance)
template <typename TLambda,
typename TDummy = typename etl::enable_if<!etl::is_same<TLambda,
etl::delegate<TReturn(TParams...)>>::value, int>::type>
delegate& operator =(TLambda& instance)
{
assign((void*)(&instance), lambda_stub<TLambda>);
return *this;
@ -180,17 +191,17 @@ namespace etl
//*************************************************************************
/// Checks equality.
//*************************************************************************
bool operator == (const delegate& other) const
bool operator == (const delegate& rhs) const
{
return invocation == other.invocation;
return invocation == rhs.invocation;
}
//*************************************************************************
/// Returns <b>true</b> if the delegate is valid.
//*************************************************************************
bool operator != (const delegate& other) const
bool operator != (const delegate& rhs) const
{
return invocation != other.invocation;
return invocation != rhs.invocation;
}
//*************************************************************************
@ -228,22 +239,15 @@ namespace etl
}
//***********************************************************************
void clone(invocation_element& target) const
bool operator ==(const invocation_element& rhs) const
{
target.stub = stub;
target.object = object;
return (rhs.stub == stub) && (rhs.object == object);
}
//***********************************************************************
bool operator ==(const invocation_element& another) const
bool operator !=(const invocation_element& rhs) const
{
return (another.stub == stub) && (another.object == object);
}
//***********************************************************************
bool operator !=(const invocation_element& another) const
{
return (another.stub != stub) || (another.object != object);
return (rhs.stub != stub) || (rhs.object != object);
}
//***********************************************************************