Skip to content

Commit

Permalink
Updated etl::delgate to handle const functors correctly
Browse files Browse the repository at this point in the history
Updated version info

Fixed functor delegate enable_if
  • Loading branch information
jwellbelove committed Dec 17, 2022
1 parent 8527d68 commit c9565d1
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 172 deletions.
2 changes: 1 addition & 1 deletion arduino/library-arduino.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Embedded Template Library - Arduino",
"version": "20.35.6",
"version": "20.35.7",
"authors": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"
Expand Down
2 changes: 1 addition & 1 deletion arduino/library-arduino.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Embedded Template Library - Arduino
version=20.35.6
version=20.35.7
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT
Expand Down
2 changes: 1 addition & 1 deletion include/etl/delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ SOFTWARE.

#include "platform.h"

#if ETL_USING_CPP11 && !defined(ETL_CRC_FORCE_CPP03_IMPLEMENTATION)
#if ETL_USING_CPP11 && !defined(ETL_DELEGATE_FORCE_CPP03_IMPLEMENTATION)
#include "private/delegate_cpp11.h"
#else
#include "private/delegate_cpp03.h"
Expand Down
159 changes: 133 additions & 26 deletions include/etl/private/delegate_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@ namespace etl
template <typename T>
class delegate;



template <typename TReturn, typename TParam>
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>
{
private:

typedef delegate<TReturn(TParam)> delegate_type;

public:

using private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>::call_if;
Expand All @@ -202,11 +204,20 @@ namespace etl
// Construct from a functor.
//*************************************************************************
template <typename TFunctor>
delegate(const TFunctor& instance)
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), functor_stub<TFunctor>);
}

//*************************************************************************
// Construct from a const functor.
//*************************************************************************
template <typename TFunctor>
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
}

//*************************************************************************
/// Create from function (Compile time).
//*************************************************************************
Expand All @@ -221,12 +232,23 @@ namespace etl
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value, delegate>::type
create(const TFunctor& instance)
typename etl::enable_if<etl::is_class<TFunctor>::value &&!etl::is_same<delegate_type, TFunctor>::value, delegate>::type
create(TFunctor& instance)
{
return delegate((void*)(&instance), functor_stub<TFunctor>);
}

//*************************************************************************
/// Create from a const Functor.
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
create(const TFunctor& instance)
{
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
}

//*************************************************************************
/// Create from instance method (Run time).
//*************************************************************************
Expand Down Expand Up @@ -273,15 +295,25 @@ namespace etl
}

//*************************************************************************
/// Set from Lambda or Functor.
/// Set from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value, void>::type
set(const TFunctor& instance)
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
set(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
}

//*************************************************************************
/// Set from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
set(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
}

//*************************************************************************
/// Set from instance method (Run time).
//*************************************************************************
Expand Down Expand Up @@ -384,16 +416,27 @@ namespace etl
}

//*************************************************************************
/// Create from Lambda or Functor.
/// Create from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value, delegate&>::type
operator =(const TFunctor& instance)
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
operator =(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
return *this;
}

//*************************************************************************
/// Create from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
operator =(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
return *this;
}

//*************************************************************************
/// Checks equality.
//*************************************************************************
Expand Down Expand Up @@ -549,7 +592,7 @@ namespace etl
}

//*************************************************************************
/// Stub call for a lambda or functor function.
/// Stub call for a functor function.
//*************************************************************************
template <typename TFunctor>
static TReturn functor_stub(void* object, TParam param)
Expand All @@ -558,6 +601,16 @@ namespace etl
return (p->operator())(param);
}

//*************************************************************************
/// Stub call for a functor function.
//*************************************************************************
template <typename TFunctor>
static TReturn const_functor_stub(void* object, TParam param)
{
const TFunctor* p = static_cast<const TFunctor*>(object);
return (p->operator())(param);
}

//*************************************************************************
/// The invocation object.
//*************************************************************************
Expand All @@ -568,9 +621,12 @@ namespace etl
/// Specialisation for void parameter.
//*************************************************************************
template <typename TReturn>
class delegate<TReturn(void)>
: public private_delegate::call_if_impl<delegate<TReturn(void)>, TReturn, void>
class delegate<TReturn(void)> : public private_delegate::call_if_impl<delegate<TReturn(void)>, TReturn, void>
{
private:

typedef delegate<TReturn(void)> delegate_type;

public:

using private_delegate::call_if_impl< delegate<TReturn(void)>, TReturn, void>::call_if;
Expand All @@ -591,14 +647,23 @@ namespace etl
}

//*************************************************************************
// Construct from lambda or functor.
// Construct from functor.
//*************************************************************************
template <typename TFunctor>
delegate(const TFunctor& instance)
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), functor_stub<TFunctor>);
}

//*************************************************************************
// Construct from const functor.
//*************************************************************************
template <typename TFunctor>
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
}

//*************************************************************************
/// Create from function (Compile time).
//*************************************************************************
Expand All @@ -609,16 +674,27 @@ namespace etl
}

//*************************************************************************
/// Create from Lambda or Functor.
/// Create from Functor.
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value, delegate>::type
create(const TFunctor& instance)
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
create(TFunctor& instance)
{
return delegate((void*)(&instance), functor_stub<TFunctor>);
}

//*************************************************************************
/// Create from const Functor.
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
create(const TFunctor& instance)
{
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
}

//*************************************************************************
/// Create from instance method (Run time).
//*************************************************************************
Expand Down Expand Up @@ -665,15 +741,25 @@ namespace etl
}

//*************************************************************************
/// Set from Lambda or Functor.
/// Set from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value, void>::type
set(const TFunctor& instance)
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
set(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
}

//*************************************************************************
/// Set from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
set(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
}

//*************************************************************************
/// Set from instance method (Run time).
//*************************************************************************
Expand Down Expand Up @@ -776,16 +862,27 @@ namespace etl
}

//*************************************************************************
/// Create from Lambda or Functor.
/// Create from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value, delegate&>::type
operator =(const TFunctor& instance)
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
operator =(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
return *this;
}

//*************************************************************************
/// Create from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
operator =(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
return *this;
}

//*************************************************************************
/// Checks equality.
//*************************************************************************
Expand Down Expand Up @@ -941,7 +1038,7 @@ namespace etl
}

//*************************************************************************
/// Stub call for a lambda or functor function.
/// Stub call for a functor function.
//*************************************************************************
template <typename TFunctor>
static TReturn functor_stub(void* object)
Expand All @@ -950,6 +1047,16 @@ namespace etl
return (p->operator())();
}

//*************************************************************************
/// Stub call for a const functor function.
//*************************************************************************
template <typename TFunctor>
static TReturn const_functor_stub(void* object)
{
const TFunctor* p = static_cast<const TFunctor*>(object);
return (p->operator())();
}

//*************************************************************************
/// The invocation object.
//*************************************************************************
Expand Down
Loading

0 comments on commit c9565d1

Please sign in to comment.