Embedded Template Library 1.0
Loading...
Searching...
No Matches
delegate_cpp11.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2019 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31/******************************************************************************
32
33Copyright (C) 2017 by Sergey A Kryukov: derived work
34http://www.SAKryukov.org
35http://www.codeproject.com/Members/SAKryukov
36
37Based on original work by Sergey Ryazanov:
38"The Impossibly Fast C++ Delegates", 18 Jul 2005
39https://www.codeproject.com/articles/11015/the-impossibly-fast-c-delegates
40
41MIT license:
42http://en.wikipedia.org/wiki/MIT_License
43
44Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibly-Fast-Cplusplus-Delegates-Fixed
45
46******************************************************************************/
47
48#ifndef ETL_DELEGATE_CPP11_INCLUDED
49#define ETL_DELEGATE_CPP11_INCLUDED
50
51#include "../platform.h"
52#include "../error_handler.h"
53#include "../exception.h"
54#include "../type_traits.h"
55#include "../function_traits.h"
56#include "../utility.h"
57#include "../optional.h"
58#include "../type_list.h"
59
60namespace etl
61{
62 //***************************************************************************
64 //***************************************************************************
65 class delegate_exception : public exception
66 {
67 public:
68
69 delegate_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
70 : exception(reason_, file_name_, line_number_)
71 {
72 }
73 };
74
75 //***************************************************************************
77 //***************************************************************************
79 {
80 public:
81
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_)
84 {
85 }
86 };
87
88 //*****************************************************************
91 //*****************************************************************
92 struct delegate_tag
93 {
94 };
95
96 //***************************************************************************
98 //***************************************************************************
99 template <typename T>
100 struct is_delegate : etl::bool_constant<etl::is_base_of<delegate_tag, T>::value>
101 {
102 };
103
104#if ETL_USING_CPP17
105 template <typename T>
106 inline constexpr bool is_delegate_v = is_delegate<T>::value;
107#endif
108
109 //*************************************************************************
111 //*************************************************************************
112 template <typename T>
113 class delegate;
114
115 //*************************************************************************
117 //*************************************************************************
118 template <typename TReturn, typename... TArgs>
119 class delegate<TReturn(TArgs...)> final : public delegate_tag
120 {
121 public:
122
123 using return_type = TReturn;
124 using argument_types = etl::type_list<TArgs...>;
125
126 //*************************************************************************
128 //*************************************************************************
129 ETL_CONSTEXPR14 delegate() ETL_NOEXCEPT
130 {
131 }
132
133 //*************************************************************************
134 // Copy constructor.
135 //*************************************************************************
136 ETL_CONSTEXPR14 delegate(const delegate& other) = default;
137
138 //*************************************************************************
139 // Construct from lambda or functor.
140 //*************************************************************************
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
143 {
144 assign((void*)(&instance), lambda_stub<TLambda>);
145 }
146
147 //*************************************************************************
148 // Construct from const lambda or functor.
149 //*************************************************************************
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
152 {
153 assign((void*)(&instance), const_lambda_stub<TLambda>);
154 }
155
156 //*************************************************************************
157 // Delete construction from rvalue reference lambda or functor.
158 //*************************************************************************
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;
161
162 //*************************************************************************
164 //*************************************************************************
165 template <TReturn(*Method)(TArgs...)>
166 ETL_NODISCARD
167 static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
168 {
169 return delegate(ETL_NULLPTR, function_stub<Method>);
170 }
171
172 //*************************************************************************
174 //*************************************************************************
175 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
176 ETL_NODISCARD
177 static ETL_CONSTEXPR14 delegate create(TLambda& instance) ETL_NOEXCEPT
178 {
179 return delegate((void*)(&instance), lambda_stub<TLambda>);
180 }
181
182 //*************************************************************************
184 //*************************************************************************
185 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
186 ETL_NODISCARD
187 static ETL_CONSTEXPR14 delegate create(const TLambda& instance) ETL_NOEXCEPT
188 {
189 return delegate((void*)(&instance), const_lambda_stub<TLambda>);
190 }
191
192 //*************************************************************************
194 //*************************************************************************
195 template <typename T, TReturn(T::*Method)(TArgs...)>
196 ETL_NODISCARD
197 static ETL_CONSTEXPR14 delegate create(T& instance) ETL_NOEXCEPT
198 {
199 return delegate((void*)(&instance), method_stub<T, Method>);
200 }
201
202 //*************************************************************************
205 //*************************************************************************
206 template <typename T, TReturn(T::*Method)(TArgs...)>
207 ETL_NODISCARD
208 static ETL_CONSTEXPR14 delegate create(T&& instance) = delete;
209
210 //*************************************************************************
212 //*************************************************************************
213 template <typename T, TReturn(T::*Method)(TArgs...) const>
214 ETL_NODISCARD
215 static ETL_CONSTEXPR14 delegate create(const T& instance) ETL_NOEXCEPT
216 {
217 return delegate((void*)(&instance), const_method_stub<T, Method>);
218 }
219
220 //*************************************************************************
222 //*************************************************************************
223 template <typename T, TReturn(T::*Method)(TArgs...) const>
224 static ETL_CONSTEXPR14 delegate create(T&& instance) = delete;
225
226 //*************************************************************************
228 //*************************************************************************
229 template <typename T, T& Instance, TReturn(T::*Method)(TArgs...)>
230 ETL_NODISCARD
231 static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
232 {
233 return delegate(method_instance_stub<T, Method, Instance>);
234 }
235
236 //*************************************************************************
239 //*************************************************************************
240 template <typename T, TReturn(T::* Method)(TArgs...), T& Instance>
241 ETL_NODISCARD
242 static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
243 {
244 return delegate(method_instance_stub<T, Method, Instance>);
245 }
246
247 //*************************************************************************
249 //*************************************************************************
250 template <typename T, T const& Instance, TReturn(T::*Method)(TArgs...) const>
251 ETL_NODISCARD
252 static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
253 {
254 return delegate(const_method_instance_stub<T, Method, Instance>);
255 }
256
257 //*************************************************************************
260 //*************************************************************************
261 template <typename T, TReturn(T::* Method)(TArgs...) const, T const& Instance>
262 ETL_NODISCARD
263 static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
264 {
265 return delegate(const_method_instance_stub<T, Method, Instance>);
266 }
267
268#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
269 //*************************************************************************
272 //*************************************************************************
273 template <typename T, T& Instance>
274 ETL_NODISCARD
275 static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
276 {
277 return delegate(operator_instance_stub<T, Instance>);
278 }
279#endif
280
281 //*************************************************************************
283 //*************************************************************************
284 template <TReturn(*Method)(TArgs...)>
285 ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
286 {
287 assign(ETL_NULLPTR, function_stub<Method>);
288 }
289
290 //*************************************************************************
292 //*************************************************************************
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
295 {
296 assign((void*)(&instance), lambda_stub<TLambda>);
297 }
298
299 //*************************************************************************
301 //*************************************************************************
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
304 {
305 assign((void*)(&instance), const_lambda_stub<TLambda>);
306 }
307
308 //*************************************************************************
310 //*************************************************************************
311 template <typename T, TReturn(T::* Method)(TArgs...)>
312 ETL_CONSTEXPR14 void set(T& instance) ETL_NOEXCEPT
313 {
314 assign((void*)(&instance), method_stub<T, Method>);
315 }
316
317 //*************************************************************************
319 //*************************************************************************
320 template <typename T, TReturn(T::* Method)(TArgs...) const>
321 ETL_CONSTEXPR14 void set(T& instance) ETL_NOEXCEPT
322 {
323 assign((void*)(&instance), const_method_stub<T, Method>);
324 }
325
326 //*************************************************************************
328 //*************************************************************************
329 template <typename T, T& Instance, TReturn(T::* Method)(TArgs...)>
330 ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
331 {
332 assign(ETL_NULLPTR, method_instance_stub<T, Method, Instance>);
333 }
334
335 //*************************************************************************
338 //*************************************************************************
339 template <typename T, TReturn(T::* Method)(TArgs...), T& Instance>
340 ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
341 {
342 assign(ETL_NULLPTR, method_instance_stub<T, Method, Instance>);
343 }
344
345 //*************************************************************************
347 //*************************************************************************
348 template <typename T, T const& Instance, TReturn(T::* Method)(TArgs...) const>
349 ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
350 {
351 assign(ETL_NULLPTR, const_method_instance_stub<T, Method, Instance>);
352 }
353
354 //*************************************************************************
357 //*************************************************************************
358 template <typename T, TReturn(T::* Method)(TArgs...) const, T const& Instance>
359 ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
360 {
361 assign(ETL_NULLPTR, const_method_instance_stub<T, Method, Instance>);
362 }
363
364 //*************************************************************************
366 //*************************************************************************
367 ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT
368 {
369 invocation.clear();
370 }
371
372 //*************************************************************************
374 //*************************************************************************
375 template <typename... TCallArgs>
376 ETL_CONSTEXPR14
377 return_type operator()(TCallArgs&&... args) const
378 {
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");
381
383
384 return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
385 }
386
387 //*************************************************************************
390 //*************************************************************************
391 template <typename TRet = TReturn, typename... TCallArgs>
392 ETL_CONSTEXPR14
393 typename etl::enable_if_t<etl::is_same<TRet, void>::value, bool>
394 call_if(TCallArgs&&... args) const
395 {
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");
398
399 if (is_valid())
400 {
401 (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
402 return true;
403 }
404 else
405 {
406 return false;
407 }
408 }
409
410 //*************************************************************************
413 //*************************************************************************
414 template <typename TRet = TReturn, typename... TCallArgs>
415 ETL_CONSTEXPR14
416 typename etl::enable_if_t<!etl::is_same<TRet, void>::value, etl::optional<TReturn>>
417 call_if(TCallArgs&&... args) const
418 {
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");
421
423
424 if (is_valid())
425 {
426 result = (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
427 }
428
429 return result;
430 }
431
432 //*************************************************************************
435 //*************************************************************************
436 template <typename TAlternative, typename... TCallArgs>
437 ETL_CONSTEXPR14 TReturn call_or(TAlternative&& alternative, TCallArgs&&... args) const
438 {
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");
441
442 if (is_valid())
443 {
444 return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
445 }
446 else
447 {
448 return etl::forward<TAlternative>(alternative)(etl::forward<TCallArgs>(args)...);
449 }
450 }
451
452 //*************************************************************************
455 //*************************************************************************
456 template <TReturn(*Method)(TArgs...), typename... TCallArgs>
457 ETL_CONSTEXPR14 TReturn call_or(TCallArgs&&... args) const
458 {
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");
461
462 if (is_valid())
463 {
464 return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
465 }
466 else
467 {
468 return (Method)(etl::forward<TCallArgs>(args)...);
469 }
470 }
471
472 //*************************************************************************
474 //*************************************************************************
475 delegate& operator =(const delegate& rhs) = default;
476
477 //*************************************************************************
479 //*************************************************************************
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
482 {
483 assign((void*)(&instance), lambda_stub<TLambda>);
484 return *this;
485 }
486
487 //*************************************************************************
489 //*************************************************************************
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
492 {
493 assign((void*)(&instance), const_lambda_stub<TLambda>);
494 return *this;
495 }
496
497 //*************************************************************************
499 //*************************************************************************
500 ETL_NODISCARD
501 ETL_CONSTEXPR14 bool operator == (const delegate& rhs) const ETL_NOEXCEPT
502 {
503 return invocation == rhs.invocation;
504 }
505
506 //*************************************************************************
508 //*************************************************************************
509 ETL_CONSTEXPR14 bool operator != (const delegate& rhs) const ETL_NOEXCEPT
510 {
511 return invocation != rhs.invocation;
512 }
513
514 //*************************************************************************
516 //*************************************************************************
517 ETL_NODISCARD
518 ETL_CONSTEXPR14 bool is_valid() const ETL_NOEXCEPT
519 {
520 return invocation.stub != ETL_NULLPTR;
521 }
522
523 //*************************************************************************
525 //*************************************************************************
526 ETL_NODISCARD
527 ETL_CONSTEXPR14 operator bool() const ETL_NOEXCEPT
528 {
529 return is_valid();
530 }
531
532 private:
533
534 using stub_type = TReturn(*)(void* object, TArgs...);
535
536 //*************************************************************************
537 // Callable compatibility: detects if C (or const C) is invocable with (TArgs...) and returns a type
538 // convertible to TReturn. Works with generic lambdas and functors.
539 template <typename TCallableType, typename = void>
540 struct is_invocable_with
541 : etl::false_type {};
542
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>
546 {};
547
548 template <typename TCallableType, typename = void>
549 struct is_invocable_with_const : etl::false_type {};
550
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>
554 {};
555
556 template <typename TCallableType>
557 struct is_compatible_callable
558 : etl::bool_constant<is_invocable_with<TCallableType>::value || is_invocable_with_const<TCallableType>::value>
559 {};
560
561 //*************************************************************************
563 //*************************************************************************
564 struct invocation_element
565 {
566 invocation_element() = default;
567
568 //***********************************************************************
569 ETL_CONSTEXPR14 invocation_element(void* object_, stub_type stub_) ETL_NOEXCEPT
570 : object(object_)
571 , stub(stub_)
572 {
573 }
574
575 //***********************************************************************
576 ETL_CONSTEXPR14 bool operator ==(const invocation_element& rhs) const ETL_NOEXCEPT
577 {
578 return (rhs.stub == stub) && (rhs.object == object);
579 }
580
581 //***********************************************************************
582 ETL_CONSTEXPR14 bool operator !=(const invocation_element& rhs) const ETL_NOEXCEPT
583 {
584 return (rhs.stub != stub) || (rhs.object != object);
585 }
586
587 //***********************************************************************
588 ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT
589 {
590 object = ETL_NULLPTR;
591 stub = ETL_NULLPTR;
592 }
593
594 //***********************************************************************
595 void* object = ETL_NULLPTR;
596 stub_type stub = ETL_NULLPTR;
597 };
598
599 //*************************************************************************
601 //*************************************************************************
602 ETL_CONSTEXPR14 delegate(void* object, stub_type stub) ETL_NOEXCEPT
603 : invocation(object, stub)
604 {
605 }
606
607 //*************************************************************************
609 //*************************************************************************
610 ETL_CONSTEXPR14 delegate(stub_type stub) ETL_NOEXCEPT
611 : invocation(ETL_NULLPTR, stub)
612 {
613 }
614
615 //*************************************************************************
617 //*************************************************************************
618 ETL_CONSTEXPR14 void assign(void* object, stub_type stub) ETL_NOEXCEPT
619 {
620 invocation.object = object;
621 invocation.stub = stub;
622 }
623
624 //*************************************************************************
626 //*************************************************************************
627 template <typename T, TReturn(T::*Method)(TArgs...)>
628 static ETL_CONSTEXPR14 TReturn method_stub(void* object, TArgs... args)
629 {
630 T* p = static_cast<T*>(object);
631 return (p->*Method)(etl::forward<TArgs>(args)...);
632 }
633
634 //*************************************************************************
636 //*************************************************************************
637 template <typename T, TReturn(T::*Method)(TArgs...) const>
638 static ETL_CONSTEXPR14 TReturn const_method_stub(void* object, TArgs... args)
639 {
640 T* const p = static_cast<T*>(object);
641 return (p->*Method)(etl::forward<TArgs>(args)...);
642 }
643
644 //*************************************************************************
646 //*************************************************************************
647 template <typename T, TReturn(T::*Method)(TArgs...), T& Instance>
648 static ETL_CONSTEXPR14 TReturn method_instance_stub(void*, TArgs... args)
649 {
650 return (Instance.*Method)(etl::forward<TArgs>(args)...);
651 }
652
653 //*************************************************************************
655 //*************************************************************************
656 template <typename T, TReturn(T::*Method)(TArgs...) const, const T& Instance>
657 static ETL_CONSTEXPR14 TReturn const_method_instance_stub(void*, TArgs... args)
658 {
659 return (Instance.*Method)(etl::forward<TArgs>(args)...);
660 }
661
662#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
663 //*************************************************************************
665 //*************************************************************************
666 template <typename T, T& Instance>
667 static ETL_CONSTEXPR14 TReturn operator_instance_stub(void*, TArgs... args)
668 {
669 return Instance.operator()(etl::forward<TArgs>(args)...);
670 }
671#endif
672
673 //*************************************************************************
675 //*************************************************************************
676 template <TReturn(*Method)(TArgs...)>
677 static ETL_CONSTEXPR14 TReturn function_stub(void*, TArgs... args)
678 {
679 return (Method)(etl::forward<TArgs>(args)...);
680 }
681
682 //*************************************************************************
684 //*************************************************************************
685 template <typename TLambda>
686 static ETL_CONSTEXPR14 TReturn lambda_stub(void* object, TArgs... arg)
687 {
688 ETL_STATIC_ASSERT(is_compatible_callable<TLambda>::value, "etl::delegate: bound lambda/functor is not compatible with the delegate signature");
689
690 TLambda* p = static_cast<TLambda*>(object);
691 return (p->operator())(etl::forward<TArgs>(arg)...);
692 }
693
694 //*************************************************************************
696 //*************************************************************************
697 template <typename TLambda>
698 static ETL_CONSTEXPR14 TReturn const_lambda_stub(void* object, TArgs... arg)
699 {
700 ETL_STATIC_ASSERT(is_compatible_callable<TLambda>::value, "etl::delegate: bound lambda/functor is not compatible with the delegate signature");
701
702 const TLambda* p = static_cast<const TLambda*>(object);
703 return (p->operator())(etl::forward<TArgs>(arg)...);
704 }
705
706 //*************************************************************************
708 //*************************************************************************
709 invocation_element invocation;
710 };
711
712#if ETL_USING_CPP17
713 //*************************************************************************
715 //*************************************************************************
716 template <auto Function>
717 ETL_NODISCARD
718 constexpr auto make_delegate() ETL_NOEXCEPT
719 {
720 using function_type = typename etl::function_traits<decltype(Function)>::function_type;
721
722 return etl::delegate<function_type>::template create<Function>();
723 }
724
725 //*************************************************************************
727 //*************************************************************************
728 template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value, void>>
729 ETL_NODISCARD
730 constexpr auto make_delegate(TLambda& instance) ETL_NOEXCEPT
731 {
732 using function_type = typename etl::function_traits<decltype(&TLambda::operator())>::function_type;
733
734 return etl::delegate<function_type>(instance);
735 }
736
737 //*************************************************************************
739 //*************************************************************************
740 template <typename T, T& Instance>
741 ETL_NODISCARD
742 constexpr auto make_delegate() ETL_NOEXCEPT
743 {
744 using function_type = typename etl::function_traits<decltype(&T::operator())>::function_type;
745
746 return etl::delegate<function_type>::template create<T, Instance>();
747 }
748
749 //*************************************************************************
751 //*************************************************************************
752 template <typename T, auto Method, T& Instance, typename = etl::enable_if_t<!etl::function_traits<decltype(Method)>::is_const>>
753 ETL_NODISCARD
754 constexpr auto make_delegate() ETL_NOEXCEPT
755 {
756 using function_type = typename etl::function_traits<decltype(Method)>::function_type;
757
758 return etl::delegate<function_type>::template create<T, Method, Instance>();
759 }
760
761 //*************************************************************************
763 //*************************************************************************
764 template <typename T, auto Method, const T& Instance, typename = etl::enable_if_t<etl::function_traits<decltype(Method)>::is_const>>
765 ETL_NODISCARD
766 constexpr auto make_delegate() ETL_NOEXCEPT
767 {
768 using function_type = typename etl::function_traits<decltype(Method)>::function_type;
769
770 return etl::delegate<function_type>::template create<T, Method, Instance>();
771 }
772
773 //*************************************************************************
775 //*************************************************************************
776 template <typename T, auto Method>
777 ETL_NODISCARD
778 constexpr auto make_delegate(T& instance) ETL_NOEXCEPT
779 {
780 using function_type = typename etl::function_traits<decltype(Method)>::function_type;
781
782 return etl::delegate<function_type>::template create<T, Method>(instance);
783 }
784
785 //*************************************************************************
787 //*************************************************************************
788 template <typename T, auto Method>
789 ETL_NODISCARD
790 constexpr auto make_delegate(const T& instance) ETL_NOEXCEPT
791 {
792 using function_type = typename etl::function_traits<decltype(Method)>::function_type;
793
794 return etl::delegate<function_type>::template create<T, Method>(instance);
795 }
796#endif
797}
798
799#endif
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