48#ifndef ETL_DELEGATE_CPP11_INCLUDED
49#define ETL_DELEGATE_CPP11_INCLUDED
58#include "../type_list.h"
69 delegate_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
70 :
exception(reason_, file_name_, line_number_)
82 delegate_uninitialised(string_type file_name_, numeric_type line_number_)
83 : delegate_exception(ETL_ERROR_TEXT(
"delegate:uninitialised", ETL_DELEGATE_FILE_ID
"A"), file_name_, line_number_)
100 struct is_delegate : etl::bool_constant<etl::is_base_of<delegate_tag, T>::value>
105 template <
typename T>
106 inline constexpr bool is_delegate_v = is_delegate<T>::value;
112 template <
typename T>
118 template <
typename TReturn,
typename... TArgs>
123 using return_type = TReturn;
124 using argument_types = etl::type_list<TArgs...>;
141 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
142 ETL_CONSTEXPR14
delegate(TLambda& instance) ETL_NOEXCEPT
144 assign((
void*)(&instance), lambda_stub<TLambda>);
150 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
151 ETL_CONSTEXPR14 delegate(
const TLambda& instance) ETL_NOEXCEPT
153 assign((
void*)(&instance), const_lambda_stub<TLambda>);
159 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TArgs...)>, TLambda>::value,
void>>
160 ETL_CONSTEXPR14 delegate(TLambda&& instance) =
delete;
165 template <TReturn(*Method)(TArgs...)>
169 return delegate(ETL_NULLPTR, function_stub<Method>);
175 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
179 return delegate((
void*)(&instance), lambda_stub<TLambda>);
185 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
189 return delegate((
void*)(&instance), const_lambda_stub<TLambda>);
195 template <
typename T, TReturn(T::*Method)(TArgs...)>
199 return delegate((
void*)(&instance), method_stub<T, Method>);
206 template <
typename T, TReturn(T::*Method)(TArgs...)>
213 template <
typename T, TReturn(T::*Method)(TArgs...)
const>
217 return delegate((
void*)(&instance), const_method_stub<T, Method>);
223 template <
typename T, TReturn(T::*Method)(TArgs...)
const>
229 template <
typename T, T& Instance, TReturn(T::*Method)(TArgs...)>
233 return delegate(method_instance_stub<T, Method, Instance>);
240 template <
typename T, TReturn(T::* Method)(TArgs...), T& Instance>
244 return delegate(method_instance_stub<T, Method, Instance>);
250 template <
typename T, T
const& Instance, TReturn(T::*Method)(TArgs...)
const>
254 return delegate(const_method_instance_stub<T, Method, Instance>);
261 template <
typename T, TReturn(T::* Method)(TArgs...)
const, T
const& Instance>
265 return delegate(const_method_instance_stub<T, Method, Instance>);
268#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
273 template <
typename T, T& Instance>
277 return delegate(operator_instance_stub<T, Instance>);
284 template <TReturn(*Method)(TArgs...)>
285 ETL_CONSTEXPR14
void set() ETL_NOEXCEPT
287 assign(ETL_NULLPTR, function_stub<Method>);
293 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
294 ETL_CONSTEXPR14
void set(TLambda& instance) ETL_NOEXCEPT
296 assign((
void*)(&instance), lambda_stub<TLambda>);
302 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
303 ETL_CONSTEXPR14
void set(
const TLambda& instance) ETL_NOEXCEPT
305 assign((
void*)(&instance), const_lambda_stub<TLambda>);
311 template <
typename T, TReturn(T::* Method)(TArgs...)>
312 ETL_CONSTEXPR14
void set(T& instance) ETL_NOEXCEPT
314 assign((
void*)(&instance), method_stub<T, Method>);
320 template <
typename T, TReturn(T::* Method)(TArgs...)
const>
321 ETL_CONSTEXPR14
void set(T& instance) ETL_NOEXCEPT
323 assign((
void*)(&instance), const_method_stub<T, Method>);
329 template <
typename T, T& Instance, TReturn(T::* Method)(TArgs...)>
330 ETL_CONSTEXPR14
void set() ETL_NOEXCEPT
332 assign(ETL_NULLPTR, method_instance_stub<T, Method, Instance>);
339 template <
typename T, TReturn(T::* Method)(TArgs...), T& Instance>
340 ETL_CONSTEXPR14
void set() ETL_NOEXCEPT
342 assign(ETL_NULLPTR, method_instance_stub<T, Method, Instance>);
348 template <
typename T, T
const& Instance, TReturn(T::* Method)(TArgs...)
const>
349 ETL_CONSTEXPR14
void set() ETL_NOEXCEPT
351 assign(ETL_NULLPTR, const_method_instance_stub<T, Method, Instance>);
358 template <
typename T, TReturn(T::* Method)(TArgs...)
const, T
const& Instance>
359 ETL_CONSTEXPR14
void set() ETL_NOEXCEPT
361 assign(ETL_NULLPTR, const_method_instance_stub<T, Method, Instance>);
367 ETL_CONSTEXPR14
void clear() ETL_NOEXCEPT
375 template <
typename... TCallArgs>
379 ETL_STATIC_ASSERT((
sizeof...(TCallArgs) ==
sizeof...(TArgs)),
"Incorrect number of parameters passed to delegate");
380 ETL_STATIC_ASSERT((etl::type_lists_are_convertible<etl::type_list<TCallArgs&&...>, argument_types>::value),
"Incompatible parameter types passed to delegate");
384 return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
391 template <
typename TRet = TReturn,
typename... TCallArgs>
393 typename etl::enable_if_t<etl::is_same<TRet, void>::value,
bool>
396 ETL_STATIC_ASSERT((
sizeof...(TCallArgs) ==
sizeof...(TArgs)),
"Incorrect number of parameters passed to delegate");
397 ETL_STATIC_ASSERT((etl::type_lists_are_convertible<etl::type_list<TCallArgs&&...>, argument_types>::value),
"Incompatible parameter types passed to delegate");
401 (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
414 template <
typename TRet = TReturn,
typename... TCallArgs>
419 ETL_STATIC_ASSERT((
sizeof...(TCallArgs) ==
sizeof...(TArgs)),
"Incorrect number of parameters passed to delegate");
420 ETL_STATIC_ASSERT((etl::type_lists_are_convertible<etl::type_list<TCallArgs&&...>, argument_types>::value),
"Incompatible parameter types passed to delegate");
426 result = (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
436 template <
typename TAlternative,
typename... TCallArgs>
437 ETL_CONSTEXPR14 TReturn
call_or(TAlternative&& alternative, TCallArgs&&... args)
const
439 ETL_STATIC_ASSERT((
sizeof...(TCallArgs) ==
sizeof...(TArgs)),
"Incorrect number of parameters passed to delegate");
440 ETL_STATIC_ASSERT((etl::type_lists_are_convertible<etl::type_list<TCallArgs&&...>, argument_types>::value),
"Incompatible parameter types passed to delegate");
444 return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
448 return etl::forward<TAlternative>(alternative)(etl::forward<TCallArgs>(args)...);
456 template <TReturn(*Method)(TArgs...),
typename... TCallArgs>
457 ETL_CONSTEXPR14 TReturn
call_or(TCallArgs&&... args)
const
459 ETL_STATIC_ASSERT((
sizeof...(TCallArgs) ==
sizeof...(TArgs)),
"Incorrect number of parameters passed to delegate");
460 ETL_STATIC_ASSERT((etl::type_lists_are_convertible<etl::type_list<TCallArgs&&...>, argument_types>::value),
"Incompatible parameter types passed to delegate");
464 return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
468 return (Method)(etl::forward<TCallArgs>(args)...);
480 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
481 ETL_CONSTEXPR14
delegate& operator =(TLambda& instance) ETL_NOEXCEPT
483 assign((
void*)(&instance), lambda_stub<TLambda>);
490 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value,
void>>
491 ETL_CONSTEXPR14
delegate& operator =(
const TLambda& instance) ETL_NOEXCEPT
493 assign((
void*)(&instance), const_lambda_stub<TLambda>);
503 return invocation == rhs.invocation;
511 return invocation != rhs.invocation;
520 return invocation.stub != ETL_NULLPTR;
527 ETL_CONSTEXPR14
operator bool() const ETL_NOEXCEPT
534 using stub_type = TReturn(*)(
void* object, TArgs...);
539 template <
typename TCallableType,
typename =
void>
540 struct is_invocable_with
543 template <
typename TCallableType>
544 struct is_invocable_with<TCallableType,
etl::void_t<decltype(etl::declval<TCallableType&>()(etl::declval<TArgs>()...))>>
545 :
etl::bool_constant<etl::is_convertible<decltype(etl::declval<TCallableType&>()(etl::declval<TArgs>()...)), TReturn>::value>
548 template <
typename TCallableType,
typename =
void>
551 template <
typename TCallableType>
552 struct is_invocable_with_const<TCallableType, etl::void_t<decltype(etl::declval<const TCallableType&>()(etl::declval<TArgs>()...))>>
553 : etl::bool_constant<etl::is_convertible<decltype(etl::declval<const TCallableType&>()(etl::declval<TArgs>()...)), TReturn>::value>
556 template <
typename TCallableType>
557 struct is_compatible_callable
558 : etl::bool_constant<is_invocable_with<TCallableType>::value || is_invocable_with_const<TCallableType>::value>
564 struct invocation_element
566 invocation_element() =
default;
569 ETL_CONSTEXPR14 invocation_element(
void* object_, stub_type stub_) ETL_NOEXCEPT
576 ETL_CONSTEXPR14
bool operator ==(
const invocation_element& rhs)
const ETL_NOEXCEPT
578 return (rhs.stub == stub) && (rhs.object == object);
582 ETL_CONSTEXPR14
bool operator !=(
const invocation_element& rhs)
const ETL_NOEXCEPT
584 return (rhs.stub != stub) || (rhs.object != object);
588 ETL_CONSTEXPR14
void clear() ETL_NOEXCEPT
590 object = ETL_NULLPTR;
595 void*
object = ETL_NULLPTR;
596 stub_type stub = ETL_NULLPTR;
602 ETL_CONSTEXPR14 delegate(
void*
object, stub_type stub) ETL_NOEXCEPT
603 : invocation(
object, stub)
610 ETL_CONSTEXPR14 delegate(stub_type stub) ETL_NOEXCEPT
611 : invocation(ETL_NULLPTR, stub)
618 ETL_CONSTEXPR14
void assign(
void*
object, stub_type stub) ETL_NOEXCEPT
620 invocation.object = object;
621 invocation.stub = stub;
627 template <
typename T, TReturn(T::*Method)(TArgs...)>
628 static ETL_CONSTEXPR14 TReturn method_stub(
void*
object, TArgs... args)
630 T* p =
static_cast<T*
>(object);
631 return (p->*Method)(etl::forward<TArgs>(args)...);
637 template <
typename T, TReturn(T::*Method)(TArgs...)
const>
638 static ETL_CONSTEXPR14 TReturn const_method_stub(
void*
object, TArgs... args)
640 T*
const p =
static_cast<T*
>(object);
641 return (p->*Method)(etl::forward<TArgs>(args)...);
647 template <
typename T, TReturn(T::*Method)(TArgs...), T& Instance>
648 static ETL_CONSTEXPR14 TReturn method_instance_stub(
void*, TArgs... args)
650 return (Instance.*Method)(etl::forward<TArgs>(args)...);
656 template <
typename T, TReturn(T::*Method)(TArgs...)
const,
const T& Instance>
657 static ETL_CONSTEXPR14 TReturn const_method_instance_stub(
void*, TArgs... args)
659 return (Instance.*Method)(etl::forward<TArgs>(args)...);
662#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
666 template <
typename T, T& Instance>
667 static ETL_CONSTEXPR14 TReturn operator_instance_stub(
void*, TArgs... args)
669 return Instance.operator()(etl::forward<TArgs>(args)...);
676 template <TReturn(*Method)(TArgs...)>
677 static ETL_CONSTEXPR14 TReturn function_stub(
void*, TArgs... args)
679 return (Method)(etl::forward<TArgs>(args)...);
685 template <
typename TLambda>
686 static ETL_CONSTEXPR14 TReturn lambda_stub(
void*
object, TArgs... arg)
688 ETL_STATIC_ASSERT(is_compatible_callable<TLambda>::value,
"etl::delegate: bound lambda/functor is not compatible with the delegate signature");
690 TLambda* p =
static_cast<TLambda*
>(object);
691 return (p->operator())(etl::forward<TArgs>(arg)...);
697 template <
typename TLambda>
698 static ETL_CONSTEXPR14 TReturn const_lambda_stub(
void*
object, TArgs... arg)
700 ETL_STATIC_ASSERT(is_compatible_callable<TLambda>::value,
"etl::delegate: bound lambda/functor is not compatible with the delegate signature");
702 const TLambda* p =
static_cast<const TLambda*
>(object);
703 return (p->operator())(etl::forward<TArgs>(arg)...);
709 invocation_element invocation;
716 template <auto Function>
718 constexpr auto make_delegate() ETL_NOEXCEPT
720 using function_type =
typename etl::function_traits<
decltype(Function)>::function_type;
728 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value,
void>>
730 constexpr auto make_delegate(TLambda& instance) ETL_NOEXCEPT
732 using function_type =
typename etl::function_traits<
decltype(&TLambda::operator())>::function_type;
734 return etl::delegate<function_type>(instance);
740 template <
typename T, T& Instance>
742 constexpr auto make_delegate() ETL_NOEXCEPT
744 using function_type =
typename etl::function_traits<
decltype(&T::operator())>::function_type;
752 template <
typename T, auto Method, T& Instance,
typename = etl::enable_if_t<!etl::function_traits<decltype(Method)>::is_const>>
754 constexpr auto make_delegate() ETL_NOEXCEPT
756 using function_type =
typename etl::function_traits<
decltype(Method)>::function_type;
764 template <
typename T, auto Method, const T& Instance,
typename = etl::enable_if_t<etl::function_traits<decltype(Method)>::is_const>>
766 constexpr auto make_delegate() ETL_NOEXCEPT
768 using function_type =
typename etl::function_traits<
decltype(Method)>::function_type;
776 template <
typename T, auto Method>
778 constexpr auto make_delegate(T& instance) ETL_NOEXCEPT
780 using function_type =
typename etl::function_traits<
decltype(Method)>::function_type;
788 template <
typename T, auto Method>
790 constexpr auto make_delegate(
const T& instance) ETL_NOEXCEPT
792 using function_type =
typename etl::function_traits<
decltype(Method)>::function_type;
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create(const TLambda &instance) ETL_NOEXCEPT
Create from const Lambda or Functor.
Definition delegate_cpp11.h:187
ETL_CONSTEXPR14 void set(TLambda &instance) ETL_NOEXCEPT
Set from Lambda or Functor.
Definition delegate_cpp11.h:294
ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT
Clear the delegate.
Definition delegate_cpp11.h:367
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
Set from function (Compile time).
Definition delegate_cpp11.h:285
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
Definition delegate_cpp11.h:275
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create(T &instance) ETL_NOEXCEPT
Create from instance method (Run time).
Definition delegate_cpp11.h:197
ETL_CONSTEXPR14 TReturn call_or(TCallArgs &&... args) const
Definition delegate_cpp11.h:457
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
Create from function (Compile time).
Definition delegate_cpp11.h:167
static ETL_CONSTEXPR14 delegate create(T &&instance)=delete
Disable create from rvalue instance method (Run time).
ETL_CONSTEXPR14 etl::enable_if_t< etl::is_same< TRet, void >::value, bool > call_if(TCallArgs &&... args) const
Definition delegate_cpp11.h:394
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create(T &&instance)=delete
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create(TLambda &instance) ETL_NOEXCEPT
Create from Lambda or Functor.
Definition delegate_cpp11.h:177
ETL_CONSTEXPR14 return_type operator()(TCallArgs &&... args) const
Execute the delegate.
Definition delegate_cpp11.h:377
ETL_CONSTEXPR14 TReturn call_or(TAlternative &&alternative, TCallArgs &&... args) const
Definition delegate_cpp11.h:437
ETL_CONSTEXPR14 delegate() ETL_NOEXCEPT
Default constructor.
Definition delegate_cpp11.h:129
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
Create from instance method (Compile time).
Definition delegate_cpp11.h:231
static ETL_NODISCARD ETL_CONSTEXPR14 delegate create(const T &instance) ETL_NOEXCEPT
Create from const instance method (Run time).
Definition delegate_cpp11.h:215
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
Set from instance method (Compile time).
Definition delegate_cpp11.h:330
ETL_CONSTEXPR14 void set(T &instance) ETL_NOEXCEPT
Set from instance method (Run time).
Definition delegate_cpp11.h:312
ETL_CONSTEXPR14 void set(const TLambda &instance) ETL_NOEXCEPT
Set from const Lambda or Functor.
Definition delegate_cpp11.h:303
ETL_CONSTEXPR14 etl::enable_if_t<!etl::is_same< TRet, void >::value, etl::optional< TReturn > > call_if(TCallArgs &&... args) const
Definition delegate_cpp11.h:417
ETL_NODISCARD ETL_CONSTEXPR14 bool is_valid() const ETL_NOEXCEPT
Returns true if the delegate is valid.
Definition delegate_cpp11.h:518
The base class for delegate exceptions.
Definition delegate_cpp03.h:149
The exception thrown when the delegate is uninitialised.
Definition delegate_cpp03.h:162
Declaration.
Definition delegate_cpp03.h:191
Definition optional.h:1321
ETL_CONSTEXPR14 bool operator==(const etl::expected< TValue, TError > &lhs, const etl::expected< TValue2, TError2 > &rhs)
Equivalence operators.
Definition expected.h:962
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
Definition exception.h:47
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits_generator.h:899
bitset_ext
Definition absolute.h:39
T * create(Args &&... args)
Creates the object from a type. Variadic parameter constructor.
Definition variant_pool_generator.h:348
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1151
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1139
Definition type_traits_generator.h:912
Definition delegate_cpp03.h:176
is_delegate
Definition delegate_cpp03.h:184