48#ifndef ETL_DELEGATE_CPP11_INCLUDED
49#define ETL_DELEGATE_CPP11_INCLUDED
51#include "../platform.h"
52#include "../error_handler.h"
53#include "../exception.h"
54#include "../type_traits.h"
55#include "../utility.h"
56#include "../optional.h"
63 class delegate_exception :
public exception
67 delegate_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
68 :
exception(reason_, file_name_, line_number_)
76 class delegate_uninitialised :
public delegate_exception
80 delegate_uninitialised(string_type file_name_, numeric_type line_number_)
81 : delegate_exception(ETL_ERROR_TEXT(
"delegate:uninitialised", ETL_DELEGATE_FILE_ID
"A"), file_name_, line_number_)
89 template <
typename T>
class delegate;
94 template <
typename TReturn,
typename... TParams>
114 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
115 ETL_CONSTEXPR14
delegate(TLambda& instance)
117 assign((
void*)(&instance), lambda_stub<TLambda>);
123 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
124 ETL_CONSTEXPR14 delegate(
const TLambda& instance)
126 assign((
void*)(&instance), const_lambda_stub<TLambda>);
132 template <TReturn(*Method)(TParams...)>
136 return delegate(ETL_NULLPTR, function_stub<Method>);
142 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
146 return delegate((
void*)(&instance), lambda_stub<TLambda>);
152 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
156 return delegate((
void*)(&instance), const_lambda_stub<TLambda>);
162 template <
typename T, TReturn(T::*Method)(TParams...)>
166 return delegate((
void*)(&instance), method_stub<T, Method>);
173 template <
typename T, TReturn(T::*Method)(TParams...)>
180 template <
typename T, TReturn(T::*Method)(TParams...)
const>
184 return delegate((
void*)(&instance), const_method_stub<T, Method>);
190 template <
typename T, TReturn(T::*Method)(TParams...)
const>
196 template <
typename T, T& Instance, TReturn(T::*Method)(TParams...)>
200 return delegate(method_instance_stub<T, Instance, Method>);
206 template <
typename T, T
const& Instance, TReturn(T::*Method)(TParams...)
const>
210 return delegate(const_method_instance_stub<T, Instance, Method>);
213#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
218 template <
typename T, T& Instance>
222 return delegate(operator_instance_stub<T, Instance>);
229 template <TReturn(*Method)(TParams...)>
230 ETL_CONSTEXPR14
void set()
232 assign(ETL_NULLPTR, function_stub<Method>);
238 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
239 ETL_CONSTEXPR14
void set(TLambda& instance)
241 assign((
void*)(&instance), lambda_stub<TLambda>);
247 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
248 ETL_CONSTEXPR14
void set(
const TLambda& instance)
250 assign((
void*)(&instance), const_lambda_stub<TLambda>);
256 template <
typename T, TReturn(T::* Method)(TParams...)>
257 ETL_CONSTEXPR14
void set(T& instance)
259 assign((
void*)(&instance), method_stub<T, Method>);
265 template <
typename T, TReturn(T::* Method)(TParams...)
const>
266 ETL_CONSTEXPR14
void set(T& instance)
268 assign((
void*)(&instance), const_method_stub<T, Method>);
274 template <
typename T, T& Instance, TReturn(T::* Method)(TParams...)>
275 ETL_CONSTEXPR14
void set()
277 assign(ETL_NULLPTR, method_instance_stub<T, Instance, Method>);
283 template <
typename T, T
const& Instance, TReturn(T::* Method)(TParams...)
const>
284 ETL_CONSTEXPR14
void set()
286 assign(ETL_NULLPTR, const_method_instance_stub<T, Instance, Method>);
292 ETL_CONSTEXPR14
void clear()
304 return (*invocation.stub)(invocation.object, etl::forward<TParams>(args)...);
311 template <
typename TRet = TReturn>
312 typename etl::enable_if_t<etl::is_same<TRet, void>::value,
bool>
317 (*invocation.stub)(invocation.object, etl::forward<TParams>(args)...);
330 template <
typename TRet = TReturn>
338 result = (*invocation.stub)(invocation.object, etl::forward<TParams>(args)...);
348 template <
typename TAlternative>
349 TReturn
call_or(TAlternative alternative, TParams... args)
const
353 return (*invocation.stub)(invocation.object, etl::forward<TParams>(args)...);
357 return alternative(etl::forward<TParams>(args)...);
365 template <TReturn(*Method)(TParams...)>
370 return (*invocation.stub)(invocation.object, etl::forward<TParams>(args)...);
374 return (Method)(etl::forward<TParams>(args)...);
386 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
387 ETL_CONSTEXPR14
delegate& operator =(TLambda& instance)
389 assign((
void*)(&instance), lambda_stub<TLambda>);
396 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !
etl::is_same<
etl::delegate<TReturn(TParams...)>, TLambda>::value,
void>>
397 ETL_CONSTEXPR14
delegate& operator =(
const TLambda& instance)
399 assign((
void*)(&instance), const_lambda_stub<TLambda>);
408 return invocation == rhs.invocation;
416 return invocation != rhs.invocation;
423 ETL_CONSTEXPR14
bool is_valid()
const
425 return invocation.stub != ETL_NULLPTR;
431 ETL_CONSTEXPR14
operator bool()
const
438 using stub_type = TReturn(*)(
void* object, TParams...);
443 struct invocation_element
445 invocation_element() =
default;
448 ETL_CONSTEXPR14 invocation_element(
void* object_, stub_type stub_)
455 ETL_CONSTEXPR14
bool operator ==(
const invocation_element& rhs)
const
457 return (rhs.stub == stub) && (rhs.object == object);
461 ETL_CONSTEXPR14
bool operator !=(
const invocation_element& rhs)
const
463 return (rhs.stub != stub) || (rhs.object != object);
467 ETL_CONSTEXPR14
void clear()
469 object = ETL_NULLPTR;
474 void*
object = ETL_NULLPTR;
475 stub_type stub = ETL_NULLPTR;
481 ETL_CONSTEXPR14 delegate(
void*
object, stub_type stub)
482 : invocation(object, stub)
489 ETL_CONSTEXPR14 delegate(stub_type stub)
490 : invocation(ETL_NULLPTR, stub)
497 ETL_CONSTEXPR14
void assign(
void*
object, stub_type stub)
499 invocation.object = object;
500 invocation.stub = stub;
506 template <
typename T, TReturn(T::*Method)(TParams...)>
507 static ETL_CONSTEXPR14 TReturn method_stub(
void*
object, TParams... params)
509 T* p =
static_cast<T*
>(object);
510 return (p->*Method)(etl::forward<TParams>(params)...);
516 template <
typename T, TReturn(T::*Method)(TParams...)
const>
517 static ETL_CONSTEXPR14 TReturn const_method_stub(
void*
object, TParams... params)
519 T*
const p =
static_cast<T*
>(object);
520 return (p->*Method)(etl::forward<TParams>(params)...);
526 template <
typename T, T& Instance, TReturn(T::*Method)(TParams...)>
527 static ETL_CONSTEXPR14 TReturn method_instance_stub(
void*, TParams... params)
529 return (Instance.*Method)(etl::forward<TParams>(params)...);
535 template <
typename T,
const T& Instance, TReturn(T::*Method)(TParams...)
const>
536 static ETL_CONSTEXPR14 TReturn const_method_instance_stub(
void*, TParams... params)
538 return (Instance.*Method)(etl::forward<TParams>(params)...);
541#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
545 template <
typename T, T& Instance>
546 static ETL_CONSTEXPR14 TReturn operator_instance_stub(
void*, TParams... params)
548 return Instance.operator()(etl::forward<TParams>(params)...);
555 template <TReturn(*Method)(TParams...)>
556 static ETL_CONSTEXPR14 TReturn function_stub(
void*, TParams... params)
558 return (Method)(etl::forward<TParams>(params)...);
564 template <
typename TLambda>
565 static ETL_CONSTEXPR14 TReturn lambda_stub(
void*
object, TParams... arg)
567 TLambda* p =
static_cast<TLambda*
>(object);
568 return (p->operator())(etl::forward<TParams>(arg)...);
574 template <
typename TLambda>
575 static ETL_CONSTEXPR14 TReturn const_lambda_stub(
void*
object, TParams... arg)
577 const TLambda* p =
static_cast<const TLambda*
>(object);
578 return (p->operator())(etl::forward<TParams>(arg)...);
584 invocation_element invocation;
etl::enable_if_t<!etl::is_same< TRet, void >::value, etl::optional< TReturn > > call_if(TParams... args) const
Definition: delegate_cpp11.h:332
TReturn operator()(TParams... args) const
Execute the delegate.
Definition: delegate_cpp11.h:300
etl::enable_if_t< etl::is_same< TRet, void >::value, bool > call_if(TParams... args) const
Definition: delegate_cpp11.h:313
TReturn call_or(TAlternative alternative, TParams... args) const
Definition: delegate_cpp11.h:349
TReturn call_or(TParams... args) const
Definition: delegate_cpp11.h:366
The exception thrown when the delegate is uninitialised.
Definition: delegate_cpp03.h:162
Declaration.
Definition: delegate_cpp03.h:175
Definition: optional.h:108
A templated set implementation that uses a fixed size buffer.
Definition: set.h:2502
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
is_same
Definition: type_traits_generator.h:1041
bitset_ext
Definition: absolute.h:38
T * create(Args &&... args)
Creates the object from a type. Variadic parameter constructor.
Definition: variant_pool_generator.h:234
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633