31#ifndef ETL_INPLACE_FUNCTION_INCLUDED
32#define ETL_INPLACE_FUNCTION_INCLUDED
48 #if !defined(ETL_DEFAULT_INPLACE_FUNCTION_SIZE)
49 #define ETL_DEFAULT_INPLACE_FUNCTION_SIZE 32
52 #if !defined(ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT)
53 #define ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT alignof(void*)
61 class inplace_function_exception :
public etl::exception
65 inplace_function_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
66 : exception(reason_, file_name_, line_number_)
74 class inplace_function_uninitialized :
public inplace_function_exception
78 inplace_function_uninitialized(string_type file_name_, numeric_type line_number_)
79 : inplace_function_exception(ETL_ERROR_TEXT(
"inplace_function:uninitialized", ETL_INPLACE_FUNCTION_FILE_ID
"A"), file_name_, line_number_)
84 namespace private_inplace_function
89 template <
typename TReturn,
typename... TArgs>
90 struct inplace_function_vtable
92 using invoke_type = TReturn (*)(
void*, TArgs...);
93 using destroy_type = void (*)(
void*);
94 using move_type = void (*)(
void*,
void*);
95 using copy_type = void (*)(
const void*,
void*);
97 invoke_type invoke =
nullptr;
98 destroy_type destroy =
nullptr;
99 move_type move =
nullptr;
100 copy_type copy =
nullptr;
105 ETL_CONSTEXPR inplace_function_vtable(invoke_type i, destroy_type d, move_type m, copy_type c)
118 template <
typename TObject>
121 TReturn (TObject::*member)(TArgs...);
128 template <
typename TObject>
129 struct const_member_target
131 TReturn (TObject::*member)(TArgs...)
const;
140 template <
typename T>
141 static void copy_construct(
const void* src,
void* dst)
143 ::new (dst) T(*
static_cast<const T*
>(src));
149 template <
typename T,
bool DestroySrc>
150 static void move_construct(
void* src,
void* dst)
152 ::new (dst) T(etl::move(*
static_cast<T*
>(src)));
156 static_cast<T*
>(src)->~T();
165 template <
typename T>
166 static void destroy_stub(
void* p)
168 static_cast<T*
>(p)->~T();
174 template <typename F, typename R = TReturn, etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
175 static R stub_function_ptr(
void* p, TArgs... a)
177 return (*
static_cast<F*
>(p))(etl::forward<TArgs>(a)...);
183 template <typename F, typename R = TReturn, etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
184 static void stub_function_ptr(
void* p, TArgs... a)
186 (*
static_cast<F*
>(p))(etl::forward<TArgs>(a)...);
192 template <typename Target, typename R = TReturn, etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
193 static R stub_member(
void* p, TArgs... a)
195 auto* s =
static_cast<Target*
>(p);
196 return (s->obj.*(s->member))(etl::forward<TArgs>(a)...);
202 template <typename Target, typename R = TReturn, etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
203 static void stub_member(
void* p, TArgs... a)
205 auto* s =
static_cast<Target*
>(p);
206 (s->obj.*(s->member))(etl::forward<TArgs>(a)...);
212 template <typename T, typename R = TReturn, etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
213 static R stub_functor(
void* p, TArgs... a)
215 return (*
static_cast<T*
>(p))(etl::forward<TArgs>(a)...);
221 template <typename T, typename R = TReturn, etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
222 static void stub_functor(
void* p, TArgs... a)
224 (*
static_cast<T*
>(p))(etl::forward<TArgs>(a)...);
230 template <typename T, typename R = TReturn, etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
231 static R stub_const_functor(
void* p, TArgs... a)
233 return (*
static_cast<const T*
>(p))(etl::forward<TArgs>(a)...);
239 template <typename T, typename R = TReturn, etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
240 static void stub_const_functor(
void* p, TArgs... a)
242 (*
static_cast<const T*
>(p))(etl::forward<TArgs>(a)...);
248 template <TReturn (*Function)(TArgs...),
typename R = TReturn, etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
249 static R stub_ct_function(
void*, TArgs... a)
251 return Function(etl::forward<TArgs>(a)...);
257 template <TReturn (*Function)(TArgs...),
typename R = TReturn, etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
258 static void stub_ct_function(
void*, TArgs... a)
260 Function(etl::forward<TArgs>(a)...);
266 template <
typename TObject, TReturn (TObject::*Method)(TArgs...), TObject* Object,
typename R = TReturn,
267 etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
268 static R stub_ct_member(
void*, TArgs... a)
270 return (Object->*Method)(etl::forward<TArgs>(a)...);
276 template <
typename TObject, TReturn (TObject::*Method)(TArgs...), TObject* Object,
typename R = TReturn,
277 etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
278 static void stub_ct_member(
void*, TArgs... a)
280 (Object->*Method)(etl::forward<TArgs>(a)...);
286 template <
typename TObject, TReturn (TObject::*Method)(TArgs...)
const,
const TObject* Object,
typename R = TReturn,
287 etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
288 static R stub_ct_const_member(
void*, TArgs... a)
290 return (Object->*Method)(etl::forward<TArgs>(a)...);
296 template <
typename TObject, TReturn (TObject::*Method)(TArgs...)
const,
const TObject* Object,
typename R = TReturn,
297 etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
298 static void stub_ct_const_member(
void*, TArgs... a)
300 (Object->*Method)(etl::forward<TArgs>(a)...);
306 template <typename TObject, TObject* Object, typename R = TReturn, etl::enable_if_t<!etl::is_void<R>::value,
int> = 0>
307 static R stub_ct_operator(
void*, TArgs... a)
309 return (*Object)(etl::forward<TArgs>(a)...);
315 template <typename TObject, TObject* Object, typename R = TReturn, etl::enable_if_t<etl::is_void<R>::value,
int> = 0>
316 static void stub_ct_operator(
void*, TArgs... a)
318 (*Object)(etl::forward<TArgs>(a)...);
326 static const inplace_function_vtable* for_function_ptr()
328 using function_type = TReturn (*)(TArgs...);
329 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_function_ptr<function_type>,
nullptr,
330 &inplace_function_vtable::template move_construct<function_type, false>,
331 &inplace_function_vtable::template copy_construct<function_type>);
338 template <
typename TObject>
339 static const inplace_function_vtable* for_member()
341 using target_t = member_target<TObject>;
342 constexpr bool destroy_src_on_move = !etl::is_trivially_destructible<TObject>::value;
344 constexpr destroy_type destroy_ptr =
345 etl::is_trivially_destructible<TObject>::value ? nullptr : &inplace_function_vtable::template destroy_stub<target_t>;
347 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_member<target_t>, destroy_ptr,
348 &inplace_function_vtable::template move_construct< target_t, destroy_src_on_move>,
349 &inplace_function_vtable::template copy_construct<target_t>);
356 template <
typename TObject>
357 static const inplace_function_vtable* for_const_member()
359 using target_t = const_member_target<TObject>;
360 constexpr bool destroy_src_on_move = !etl::is_trivially_destructible<TObject>::value;
362 constexpr destroy_type destroy_ptr =
363 etl::is_trivially_destructible<TObject>::value ? nullptr : &inplace_function_vtable::template destroy_stub<target_t>;
365 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_member<target_t>, destroy_ptr,
366 &inplace_function_vtable::template move_construct< target_t, destroy_src_on_move>,
367 &inplace_function_vtable::template copy_construct<target_t>);
374 template <
typename TObject>
375 static const inplace_function_vtable* for_functor()
377 constexpr bool destroy_src_on_move = !etl::is_trivially_destructible<TObject>::value;
379 constexpr destroy_type destroy_ptr =
380 etl::is_trivially_destructible<TObject>::value ? nullptr : &inplace_function_vtable::template destroy_stub<TObject>;
382 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_functor<TObject>, destroy_ptr,
383 &inplace_function_vtable::template move_construct< TObject, destroy_src_on_move>,
384 &inplace_function_vtable::template copy_construct<TObject>);
391 template <
typename TObject>
392 static const inplace_function_vtable* for_const_functor()
394 constexpr bool destroy_src_on_move = !etl::is_trivially_destructible<TObject>::value;
396 constexpr destroy_type destroy_ptr =
397 etl::is_trivially_destructible<TObject>::value ? nullptr : &inplace_function_vtable::template destroy_stub<TObject>;
399 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_const_functor<TObject>, destroy_ptr,
400 &inplace_function_vtable::template move_construct< TObject, destroy_src_on_move>,
401 &inplace_function_vtable::template copy_construct<TObject>);
408 template <TReturn (*Function)(TArgs...)>
409 static const inplace_function_vtable* for_compile_time_function()
411 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_ct_function<Function>,
nullptr,
nullptr,
nullptr);
418 template <
typename TObject, TReturn (TObject::*Method)(TArgs...), TObject* Object>
419 static const inplace_function_vtable* for_compile_time_member()
421 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_ct_member<TObject, Method, Object>,
nullptr,
nullptr,
429 template <
typename TObject, TReturn (TObject::*Method)(TArgs...)
const,
const TObject* Object>
430 static const inplace_function_vtable* for_compile_time_const_member()
432 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_ct_const_member< TObject, Method, Object>,
nullptr,
440 template <
typename TObject, TObject* Object>
441 static const inplace_function_vtable* for_compile_time_operator()
443 static const inplace_function_vtable vtable(&inplace_function_vtable::template stub_ct_operator<TObject, Object>,
nullptr,
nullptr,
nullptr);
452 template <
typename TSignature,
size_t Object_Size = ETL_DEFAULT_INPLACE_FUNCTION_SIZE,
453 size_t Object_Alignment = ETL_DEFAULT_INPLACE_FUNCTION_ALIGNMENT>
454 class inplace_function;
459 template <
typename T>
467 template <
typename TReturn,
typename... TArgs,
size_t Object_Size,
size_t Object_Alignment>
468 struct is_inplace_function< etl::inplace_function<TReturn(TArgs...), Object_Size, Object_Alignment>> : etl::true_type
481 template <
typename TReturn,
typename... TArgs,
size_t Object_Size,
size_t Object_Alignment>
482 class inplace_function<TReturn(TArgs...), Object_Size, Object_Alignment>
486 using this_type = inplace_function<TReturn(TArgs...), Object_Size, Object_Alignment>;
487 using storage_type = etl::uninitialized_buffer<Object_Size, 1, Object_Alignment>;
488 using vtable_type = private_inplace_function::inplace_function_vtable<TReturn, TArgs...>;
489 using function_ptr = TReturn (*)(TArgs...);
493 using function_type = TReturn(TArgs...);
494 using return_type = TReturn;
495 using argument_types = etl::type_list<TArgs...>;
500 inplace_function() noexcept = default;
506 inplace_function(const inplace_function& other)
517 template <
size_t Other_Object_Size,
size_t Other_Object_Alignment>
518 inplace_function(
const etl::inplace_function<TReturn(TArgs...), Other_Object_Size, Other_Object_Alignment>& other)
520 static_assert(Object_Size >= Other_Object_Size,
"etl::inplace_function: Destination object size too small");
521 static_assert(Object_Alignment >= Other_Object_Alignment,
"etl::inplace_function: Destination object alignment too small");
530 inplace_function(inplace_function&& other)
noexcept
541 template <
size_t Other_Object_Size,
size_t Other_Object_Alignment>
542 inplace_function(etl::inplace_function<TReturn(TArgs...), Other_Object_Size, Other_Object_Alignment>&& other)
noexcept
544 static_assert(Object_Size >= Other_Object_Size,
"etl::inplace_function: Destination object size too small");
545 static_assert(Object_Alignment >= Other_Object_Alignment,
"etl::inplace_function: Destination object alignment too small");
553 ~inplace_function() noexcept
562 inplace_function(function_ptr f)
572 inplace_function(etl::nullptr_t)
noexcept
583 template <
typename TObject,
typename TObjectArg>
584 inplace_function(TReturn (TObject::*method)(TArgs...), TObjectArg&& obj)
586 set(method, etl::forward<TObjectArg>(obj));
595 template <
typename TObject,
typename TObjectArg>
596 inplace_function(TReturn (TObject::*method)(TArgs...)
const, TObjectArg&& obj)
598 set(method, etl::forward<TObjectArg>(obj));
606 template < typename TLambda, typename T = typename etl::decay<TLambda>::type,
607 typename = etl::enable_if_t< etl::is_class<T>::value && !is_inplace_function<T>::value,
void>>
608 inplace_function(TLambda& lambda)
618 template < typename TLambda, typename T = typename etl::decay<TLambda>::type,
619 typename = etl::enable_if_t< etl::is_class<T>::value && !is_inplace_function<T>::value,
void>>
620 inplace_function(
const TLambda& lambda)
629 void set(function_ptr f)
632 static_assert(etl::is_invocable_r<TReturn, function_ptr, TArgs...>::value,
633 "etl::inplace_function: function pointer is not compatible with the inplace_function signature");
635 static_assert(Object_Size >=
sizeof(function_ptr),
"etl::inplace_function: storage size too small");
636 static_assert(Object_Alignment >=
alignof(function_ptr),
"etl::inplace_function: storage alignment too small");
641 ::new (storage_ptr()) function_ptr(f);
643 vtable = vtable_type::for_function_ptr();
652 template <typename TObject, typename TObjectArg>
653 void set(TReturn (TObject::*method)(TArgs...), TObjectArg&& obj)
655 using D = etl::decay_t<TObjectArg>;
656 static_assert(etl::is_invocable_r<TReturn,
decltype(method), D&, TArgs...>::value,
657 "etl::inplace_function: bound member function is not compatible with the inplace_function signature");
659 using target_t =
typename vtable_type::template member_target<D>;
661 static_assert(Object_Size >=
sizeof(target_t),
"etl::inplace_function: storage size too small");
662 static_assert(Object_Alignment >=
alignof(target_t),
"etl::inplace_function: storage alignment too small");
665 ::new (storage_ptr()) target_t{method, etl::forward<TObjectArg>(obj)};
666 vtable = vtable_type::template for_member<D>();
675 template <
typename TObject,
typename TObjectArg>
676 void set(TReturn (TObject::*method)(TArgs...)
const, TObjectArg&& obj)
678 using D = etl::decay_t<TObjectArg>;
679 static_assert(etl::is_invocable_r<TReturn,
decltype(method), D&, TArgs...>::value,
680 "etl::inplace_function: bound member function is not compatible with the inplace_function signature");
682 using target_t =
typename vtable_type::template const_member_target<D>;
684 static_assert(Object_Size >=
sizeof(target_t),
"etl::inplace_function: storage size too small");
685 static_assert(Object_Alignment >=
alignof(target_t),
"etl::inplace_function: storage alignment too small");
688 ::new (storage_ptr()) target_t{method, etl::forward<TObjectArg>(obj)};
689 vtable = vtable_type::template for_const_member<D>();
697 template < typename TLambda, typename T = typename etl::decay<TLambda>::type,
698 typename = etl::enable_if_t< etl::is_class<T>::value && !is_inplace_function<T>::value,
void>>
699 void set(TLambda& lambda)
703 static_assert(etl::is_invocable_r<TReturn, T, TArgs...>::value,
704 "etl::inplace_function: bound lambda/functor is not compatible with the inplace_function signature");
706 static_assert(Object_Size >=
sizeof(T),
"etl::inplace_function: Object size too small");
707 static_assert(Object_Alignment >=
alignof(T),
"etl::inplace_function: Object alignment too small");
712 ::new (storage_ptr()) T(lambda);
714 vtable = vtable_type::template for_functor<T>();
722 template < typename TLambda, typename T = typename etl::decay<TLambda>::type,
723 typename = etl::enable_if_t< etl::is_class<T>::value && !is_inplace_function<T>::value,
void>>
724 void set(const TLambda& lambda)
726 static_assert(etl::is_invocable_r<TReturn,
const T, TArgs...>::value,
727 "etl::inplace_function: bound lambda/functor is not compatible with the inplace_function signature");
729 static_assert(Object_Size >=
sizeof(T),
"etl::inplace_function: Object size too small");
730 static_assert(Object_Alignment >=
alignof(T),
"etl::inplace_function: Object alignment too small");
735 ::new (storage_ptr()) T(lambda);
737 vtable = vtable_type::template for_const_functor<T>();
746 template <TReturn (*Function)(TArgs...)>
749 static_assert(etl::is_invocable_r<TReturn,
decltype(Function), TArgs...>::value,
750 "etl::inplace_function: function pointer is not compatible with the inplace_function signature");
753 vtable = vtable_type::template for_compile_time_function<Function>();
763 template <
typename TObject, TReturn (TObject::*Method)(TArgs...), TObject& Instance>
766 static_assert(etl::is_invocable_r<TReturn,
decltype(Method), TObject&, TArgs...>::value,
767 "etl::inplace_function: bound member function is not compatible with the inplace_function signature");
770 vtable = vtable_type::template for_compile_time_member<TObject, Method, &Instance>();
780 template <
typename TObject, TReturn (TObject::*Method)(TArgs...)
const,
const TObject& Instance>
783 static_assert(etl::is_invocable_r<TReturn,
decltype(Method),
const TObject&, TArgs...>::value,
784 "etl::inplace_function: bound member function is not compatible with the inplace_function signature");
787 vtable = vtable_type::template for_compile_time_const_member<TObject, Method, &Instance>();
795 template <
typename TObject, TObject& Instance,
typename T = etl::decay_t<TObject>,
796 typename = etl::enable_if_t< etl::is_
class<T>::value && etl::has_call_operator<T>::value
797 && !etl::function_traits<decltype(&T::operator())>::is_const>>
800 static_assert(etl::is_invocable_r<TReturn, T, TArgs...>::value,
801 "etl::inplace_function: bound lambda/functor is not compatible with the inplace_function signature");
804 vtable = vtable_type::template for_compile_time_operator<TObject, &Instance>();
812 template <
typename TObject, const TObject& Instance,
typename T = etl::decay_t<TObject>,
813 typename = etl::enable_if_t< etl::is_
class<T>::value && etl::has_call_operator<T>::value
814 && etl::function_traits<decltype(&T::operator())>::is_const>>
817 static_assert(etl::is_invocable_r<TReturn,
const T, TArgs...>::value,
818 "etl::inplace_function: bound lambda/functor is not compatible with the inplace_function signature");
821 vtable = vtable_type::template for_compile_time_operator<const TObject, &Instance>();
829 template <TReturn (*Function)(TArgs...)>
830 static this_type create()
832 return this_type(vtable_type::template for_compile_time_function<Function>());
842 template <
typename TObject, TReturn (TObject::*Method)(TArgs...), TObject& Instance>
843 static this_type create()
845 return this_type(vtable_type::template for_compile_time_member<TObject, Method, &Instance>());
855 template <
typename TObject, TReturn (TObject::*Method)(TArgs...)
const,
const TObject& Instance>
856 static this_type create()
858 return this_type(vtable_type::template for_compile_time_const_member<TObject, Method, &Instance>());
867 template <
typename TObject, TObject& Instance>
868 static this_type create()
870 return this_type(vtable_type::template for_compile_time_operator<TObject, &Instance>());
878 inplace_function& operator=(
const inplace_function& rhs)
894 inplace_function& operator=(inplace_function&& rhs)
noexcept
911 inplace_function& operator=(etl::nullptr_t)
noexcept
923 inplace_function& operator=(function_ptr f)
937 template < typename TLambda, typename T = typename etl::decay<TLambda>::type,
938 typename = etl::enable_if_t< etl::is_class<T>::value && !is_inplace_function<T>::value,
void>>
939 inplace_function& operator=(TLambda&& lambda)
941 set(etl::forward<TLambda>(lambda));
950 void swap(inplace_function& other)
noexcept
957 do_swap(vtable, storage_ptr(), other.vtable, other.storage_ptr());
966 bool is_valid() const noexcept
968 return (vtable !=
nullptr);
978 explicit operator bool() const noexcept
989 TReturn operator()(TArgs... args)
const
991 ETL_ASSERT(is_valid(), ETL_ERROR(inplace_function_uninitialized));
993 return vtable->invoke(storage_ptr(), etl::forward<TArgs>(args)...);
1002 template <
typename TRet = TReturn>
1003 typename etl::enable_if_t<etl::is_same<TRet, void>::value,
bool> call_if(TArgs... args)
const
1007 vtable->invoke(storage_ptr(), etl::forward<TArgs>(args)...);
1023 template <
typename TRet = TReturn>
1024 typename etl::enable_if_t<!etl::is_same<TRet, void>::value, etl::optional<TReturn>> call_if(TArgs... args)
const
1026 etl::optional<TReturn> result;
1030 result = vtable->invoke(storage_ptr(), etl::forward<TArgs>(args)...);
1044 template <
typename TAlternative>
1045 TReturn call_or(TAlternative&& alternative, TArgs... args)
const
1049 return vtable->invoke(storage_ptr(), etl::forward<TArgs>(args)...);
1053 return etl::forward<TAlternative>(alternative)(etl::forward<TArgs>(args)...);
1064 template <TReturn (*Alternative)(TArgs...)>
1065 TReturn call_or(TArgs... args)
const
1069 return vtable->invoke(storage_ptr(), etl::forward<TArgs>(args)...);
1073 return (Alternative)(etl::forward<TArgs>(args)...);
1081 void clear() noexcept
1085 if (vtable->destroy)
1087 vtable->destroy(storage_ptr());
1099 static constexpr size_t size() noexcept
1109 static constexpr size_t alignment() noexcept
1111 return Object_Alignment;
1117 template <
typename,
size_t,
size_t>
1118 friend class inplace_function;
1123 explicit inplace_function(
const vtable_type* vt) noexcept
1132 template <
size_t Other_Object_Size,
size_t Other_Object_Alignment>
1133 void clone_from(
const etl::inplace_function<TReturn(TArgs...), Other_Object_Size, Other_Object_Alignment>& other)
1135 vtable = other.vtable;
1137 if (vtable && vtable->copy)
1139 vtable->copy(&other.storage, &storage);
1146 template <
size_t Other_Object_Size,
size_t Other_Object_Alignment>
1147 void move_from(etl::inplace_function<TReturn(TArgs...), Other_Object_Size, Other_Object_Alignment>& other)
1149 vtable = other.vtable;
1151 if (vtable && vtable->move)
1153 vtable->move(&other.storage, &storage);
1156 other.vtable =
nullptr;
1162 static void do_swap(
const vtable_type*& vt_a,
void* storage_a,
const vtable_type*& vt_b,
void* storage_b)
noexcept
1164 const bool a_valid = (vt_a !=
nullptr);
1165 const bool b_valid = (vt_b !=
nullptr);
1167 if (!a_valid && !b_valid)
1177 vt_b->move(storage_b, storage_a);
1179 else if (vt_b->copy)
1181 vt_b->copy(storage_b, storage_a);
1193 vt_a->move(storage_a, storage_b);
1195 else if (vt_a->copy)
1197 vt_a->copy(storage_a, storage_b);
1207 if (!vt_a->move && !vt_a->copy && !vt_b->move && !vt_b->copy)
1209 const vtable_type* tmp = vt_a;
1216 alignas(Object_Alignment)
unsigned char temp[Object_Size];
1221 vt_a->move(storage_a, temp);
1223 else if (vt_a->copy)
1225 vt_a->copy(storage_a, temp);
1231 vt_b->move(storage_b, storage_a);
1233 else if (vt_b->copy)
1235 vt_b->copy(storage_b, storage_a);
1241 vt_a->move(temp, storage_b);
1243 else if (vt_a->copy)
1245 vt_a->copy(temp, storage_b);
1249 const vtable_type* tmp = vt_a;
1257 void* storage_ptr() const noexcept
1259 return const_cast<void*
>(
static_cast<const void*
>(&storage));
1262 const vtable_type* vtable =
nullptr;
1263 storage_type storage;
1271 template <
typename TSignature,
typename TStorage>
1272 using inplace_function_for = etl::inplace_function<TSignature,
sizeof(etl::decay_t<TStorage>),
alignof(etl::decay_t<TStorage>)>;
1279 template <
typename TSignature,
typename T0,
typename... TRest>
1280 using inplace_function_for_any = etl::inplace_function< TSignature, etl::largest<etl::decay_t<T0>, etl::decay_t<TRest>...>::size,
1281 etl::largest<etl::decay_t<T0>, etl::decay_t<TRest>...>::alignment>;
1289 template <
typename TReturn,
typename... TArgs>
1291 etl::inplace_function<TReturn(TArgs...),
sizeof(TReturn (*)(TArgs...)),
alignof(TReturn (*)(TArgs...))>
1292 make_inplace_function(TReturn (*function)(TArgs...))
1294 using function_ptr = TReturn (*)(TArgs...);
1296 return etl::inplace_function_for<TReturn(TArgs...), function_ptr>(function);
1306 template <
typename TObject,
typename TReturn,
typename... TArgs,
1307 typename TTarget =
typename etl::private_inplace_function::inplace_function_vtable< TReturn, TArgs...>::template member_target<TObject>>
1309 etl::inplace_function<TReturn(TArgs...),
sizeof(TTarget),
alignof(TTarget)> make_inplace_function(TReturn (TObject::*method)(TArgs...),
1312 return etl::inplace_function_for<TReturn(TArgs...), TTarget>(method, obj);
1322 typename TObject,
typename TReturn,
typename... TArgs,
1323 typename TTarget =
typename etl::private_inplace_function::inplace_function_vtable< TReturn, TArgs...>::template const_member_target<TObject>>
1325 etl::inplace_function<TReturn(TArgs...),
sizeof(TTarget),
alignof(TTarget)> make_inplace_function(TReturn (TObject::*method)(TArgs...)
const,
1328 return etl::inplace_function_for<TReturn(TArgs...), TTarget>(method, obj);
1337 template < typename TLambda, typename T = typename etl::decay<TLambda>::type,
1338 typename =
typename etl::enable_if_t< etl::is_class<T>::value && !is_inplace_function<T>::value,
void>,
1339 typename TSignature =
typename etl::function_traits<T>::function_type>
1341 etl::inplace_function<TSignature,
sizeof(T),
alignof(T)> make_inplace_function(TLambda&& lambda)
1343 return etl::inplace_function_for<TSignature, T>(etl::forward<TLambda>(lambda));
1351 template <typename TSignature, typename TType, typename T = typename etl::decay<TType>::type,
1352 typename =
typename etl::enable_if_t<!etl::is_class<T>::value,
int>>
1354 inplace_function_for<TSignature, T> make_inplace_function(TType&& function)
1357 using storage_t =
typename etl::conditional<etl::is_function<T>::value,
typename etl::add_pointer<T>::type, T>::type;
1359 return inplace_function_for<TSignature, storage_t>(etl::forward<TType>(function));
1369 template <
auto Function,
typename F =
decltype(Function),
1370 typename = etl::enable_if_t< etl::is_pointer<F>::value && etl::is_function<etl::remove_pointer_t<F>>::value>>
1372 auto make_inplace_function()
1374 using function_type =
typename etl::function_traits<F>::function_type;
1376 return etl::inplace_function<function_type, 1, 1>::template create<Function>();
1386 template <
typename TObject,
auto Method, TObject& Instance,
typename T =
decltype(Method),
1387 typename = etl::enable_if_t<etl::is_member_function_pointer<T>::value>,
typename = etl::enable_if_t<!etl::function_traits<T>::is_const>>
1389 auto make_inplace_function()
1391 using function_type =
typename etl::function_traits<
decltype(Method)>::function_type;
1393 return etl::inplace_function<function_type, 1, 1>::template create< TObject, Method, Instance>();
1403 template <
typename TObject,
auto Method,
const TObject& Instance,
typename T =
decltype(Method),
1404 typename = etl::enable_if_t<etl::is_member_function_pointer<T>::value>,
typename = etl::enable_if_t<etl::function_traits<T>::is_const>>
1406 auto make_inplace_function()
1408 using function_type =
typename etl::function_traits<T>::function_type;
1410 return etl::inplace_function<function_type, 1, 1>::template create< TObject, Method, Instance>();
1419 template <
typename TObject, TObject& Instance,
typename T = etl::decay_t<TObject>,
1420 typename = etl::enable_if_t<etl::is_
class<T>::value && etl::has_call_operator<T>::value>>
1422 auto make_inplace_function()
1424 using function_type =
typename etl::function_traits<
decltype(&TObject::operator())>::function_type;
1426 return etl::inplace_function<function_type, 1, 1>::template create<TObject, Instance>();
1435 template <
typename TSignature,
size_t Object_Size,
size_t Object_Alignment>
1436 void swap(etl::inplace_function<TSignature, Object_Size, Object_Alignment>& lhs,
1437 etl::inplace_function<TSignature, Object_Size, Object_Alignment>& rhs)
noexcept
1448 template <
typename TSignature,
size_t Object_Size,
size_t Object_Alignment>
1450 bool operator==(
const etl::inplace_function<TSignature, Object_Size, Object_Alignment>& lhs, etl::nullptr_t)
1452 return !lhs.is_valid();
1461 template <
typename TSignature,
size_t Object_Size,
size_t Object_Alignment>
1463 bool operator==(etl::nullptr_t,
const etl::inplace_function<TSignature, Object_Size, Object_Alignment>& rhs)
1465 return !rhs.is_valid();
1474 template <
typename TSignature,
size_t Object_Size,
size_t Object_Alignment>
1476 bool operator!=(
const etl::inplace_function<TSignature, Object_Size, Object_Alignment>& lhs, etl::nullptr_t)
1478 return lhs.is_valid();
1487 template <
typename TSignature,
size_t Object_Size,
size_t Object_Alignment>
1489 bool operator!=(etl::nullptr_t,
const etl::inplace_function<TSignature, Object_Size, Object_Alignment>& rhs)
1491 return rhs.is_valid();
void swap(etl::array_view< T > &lhs, etl::array_view< T > &rhs) ETL_NOEXCEPT
Swaps the values.
Definition array_view.h:692
ETL_CONSTEXPR14 bool operator!=(const etl::bitset< Active_Bits, TElement > &lhs, const etl::bitset< Active_Bits, TElement > &rhs) ETL_NOEXCEPT
Definition bitset_new.h:2529
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1192