A C++ template library for embedded applications
MIT licensed
Designed and
maintained by
John Wellbelove

delegate


A set of templates to allow a member function, static function (member or free), functor or lambda to be called without
the caller having to know the specific details of the callee apart from the return and parameter type. The templates
allow the called function to be abstracted. Uses variadic templates to enable variable number of function parameters.

The delegate functions may be defined at compile time and/or runtime, depending on the function type.
Most delegates can only be constructed via a create function, except lambdas and functors, which can be created by
the delegate constructor.

This may be used to implement a platform abstraction layer that allows an embedded application to interface with
multiple hardware platforms.

Notes:
<=20.21.0
This class only supports >=C++11.

>=20.22.0
This class is automatically selects C++03 or C++11 versions based on the value of ETL_CPP11_SUPPORTED
The C++03 variant only supports delegates taking 0 or 1 parameter.

etl::delegate is non-owning. You cannot use lambdas that capture variables that will have gone out of scope when
the delegate is called. This would result in  dangling references. Lambdas are not copied; The delegate merely keeps
pointers to lambdas.
____________________________________________________________________________________________________
etl::delegate<TReturn(TParams…)>

20.22.0
For C++03
etl::delegate<TReturn(void)>
etl::delegate<TReturn(TParam)>

For the examples below, assume the following definitions.

class Test
{
public:
 
  int member_function(int);
  static int member_static(int);
  int operator()(int);
  int operator()(int) const;
};

Test test;

int global(int);

auto lambda = [](int i){ return i; };
____________________________________________________________________________________________________
Run time construction

lambdas
etl::delegate<int(int)> d(lambda);
etl::delegate<int(int)> d = lambda;
etl::delegate<int(int)> d = etl::delegate<int(int)>::create(lambda);

d.set(lambda);

Functors
etl::delegate<int(int)> d(test);
etl::delegate<int(int)> d = test;
etl::delegate<int(int)> d = etl::delegate<int(int)>::create(test);

d.set<test>();

Member functions
etl::delegate<int(int)> d = etl::delegate<int(int)>::create<Test, &Test::member_function>(test);

d.set<Test, &Test::member_function>(test);
d.set<Test, test, &Test::member_function>();
____________________________________________________________________________________________________
Compile time construction

Global functions
auto d = etl::delegate<int(int)>::create<global>();

Member functions (if the instance is known at compile time)
auto d = etl::delegate<int(int)>::create<Test, test, &Test::member_function>();

Functors (if the instance is known at compile time)
auto d = etl::delegate<int(int)>::create<Test, test>();
auto d = etl::delegate<int(int)>::create<const Test, test>();
Note: These are disabled for GCC <= v8.1 as it generates an 'Internal Compiler Error'.

Static member functions
auto d = etl::delegate<int(int)>::create<Test::member_static>();
____________________________________________________________________________________________________
Constexpr

Most delegates can be declared as constexpr. (>=C++11 only)
static Test test;
constexpr auto d = etl::delegate<int(int)>::create<Test, test, &Test::member_function>();

All create functions are constexpr under C++14.
All create functions are [[nodiscard]] under C++17.
____________________________________________________________________________________________________
Calling the delegate

The delegate may be called as a function with the defined parameter signature.

etl::delegate<int(int)> d;

int r = d(3);
____________________________________________________________________________________________________
Operations

ETL_CONSTEXPR14 delegate()

Constructs an uninitialised delegate.
____________________________________________________________________________________________________
ETL_CONSTEXPR14 delegate(const delegate& other)

Copy constructs a delegate.
____________________________________________________________________________________________________
TReturn operator()(TParams... args) const

Executes the delegate.
____________________________________________________________________________________________________
20.17.0
bool call_if(TParams... args) const
For delegates returning void.
Calls the delegate if valid.
Returns true if valid, otherwise false.

etl::optional<TReturn> call_if(TParams... args) const
For delegates returning TReturn.
Calls the delegate if valid.
Returns a valid etl::optional<TReturn> containing the return value, if valid.
____________________________________________________________________________________________________
20.17.0

template <typename TAlternative>
TReturn call_or(TAlternative alternative, TParams... args) const
Calls the delegate if valid, otherwise calls alternative.

template <TReturn(*Method)(TParams...)>
TReturn call_or(TParams... args) const
Calls the delegate if valid, otherwise calls Method.
____________________________________________________________________________________________________
ETL_NODISCARD ETL_CONSTEXPR14 bool is_valid() const
ETL_CONSTEXPR14 operator bool() const

Returns true if the delegate has been initialised, otherwise false.
____________________________________________________________________________________________________
ETL_CONSTEXPR14 operator =()
Assigns from another delegate or lambda.
____________________________________________________________________________________________________
ETL_CONSTEXPR14 operator ==()
ETL_CONSTEXPR14 operator !=()
Compares delegates.
delegate.h