From c11c9cfdb6e685aae2d8404a43b555027f7ec782 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 13 Aug 2019 12:58:45 +0100 Subject: [PATCH] Fixes for delegates with lambdas --- include/etl/delegate.h | 64 ++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/include/etl/delegate.h b/include/etl/delegate.h index 3d264bcd..5539c61c 100644 --- a/include/etl/delegate.h +++ b/include/etl/delegate.h @@ -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 - delegate(const TLambda& instance) + template >::value, int>::type> + delegate(TLambda& instance) { assign((void*)(&instance), lambda_stub); } @@ -97,8 +97,10 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template - static delegate create(const TLambda& instance) + template >::value, int>::type> + static delegate create(TLambda& instance) { return delegate((void*)(&instance), lambda_stub); } @@ -112,6 +114,13 @@ namespace etl return delegate((void*)(&instance), method_stub); } + //************************************************************************* + /// Create from instance method (Run time). + /// Deleted for rvalue references. + //************************************************************************* + template + 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); } + template + 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 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 - delegate& operator =(const TLambda& instance) + template >::value, int>::type> + delegate& operator =(TLambda& instance) { assign((void*)(&instance), lambda_stub); 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 true 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); } //***********************************************************************