17 #ifndef MBED_CALLBACK_H 18 #define MBED_CALLBACK_H 23 #include "platform/mbed_assert.h" 24 #include "platform/mbed_toolchain.h" 53 template <
bool B,
typename R = nil>
61 template <
typename M, M>
63 static const bool value =
true;
67 #define MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M) \ 68 typename detail::enable_if< \ 69 detail::is_type<M, &F::operator()>::value && \ 70 sizeof(F) <= sizeof(uintptr_t) \ 71 >::type = detail::nil() 77 template <
typename R,
typename... ArgTs>
99 func._ops->move(
this, &func);
108 template<
typename T,
typename U>
111 generate(method_context<T, R(T::*)(ArgTs...)>(obj, method));
118 template<
typename T,
typename U>
119 Callback(
const U *obj, R(T::*method)(ArgTs...)
const)
121 generate(method_context<
const T, R(T::*)(ArgTs...)
const>(obj, method));
128 template<
typename T,
typename U>
129 Callback(
volatile U *obj, R(T::*method)(ArgTs...)
volatile)
131 generate(method_context<
volatile T, R(T::*)(ArgTs...)
volatile>(obj, method));
138 template<
typename T,
typename U>
139 Callback(
const volatile U *obj, R(T::*method)(ArgTs...)
const volatile)
141 generate(method_context<
const volatile T, R(T::*)(ArgTs...)
const volatile>(obj, method));
148 template<
typename T,
typename U>
151 generate(function_context<R(*)(T *, ArgTs...), T>(func, arg));
158 template<
typename T,
typename U>
159 Callback(R(*func)(
const T *, ArgTs...),
const U *arg)
161 generate(function_context<R(*)(
const T *, ArgTs...),
const T>(func, arg));
168 template<
typename T,
typename U>
169 Callback(R(*func)(
volatile T *, ArgTs...),
volatile U *arg)
171 generate(function_context<R(*)(
volatile T *, ArgTs...),
volatile T>(func, arg));
178 template<
typename T,
typename U>
179 Callback(R(*func)(
const volatile T *, ArgTs...),
const volatile U *arg)
181 generate(function_context<R(*)(
const volatile T *, ArgTs...),
const volatile T>(func, arg));
188 template <
typename F>
189 Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)))
198 template <
typename F>
199 Callback(
const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)
const))
208 template <
typename F>
209 Callback(
volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)
volatile))
218 template <
typename F>
219 Callback(
const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)
const volatile))
230 template<
typename T,
typename U>
232 "Arguments to callback have been reordered to Callback(func, arg)")
244 template<
typename T,
typename U>
246 "Arguments to callback have been reordered to Callback(func, arg)")
247 Callback(const U *obj, R(*func)(const T *, ArgTs...))
258 template<
typename T,
typename U>
260 "Arguments to callback have been reordered to Callback(func, arg)")
261 Callback(volatile U *obj, R(*func)(volatile T *, ArgTs...))
272 template<
typename T,
typename U>
274 "Arguments to callback have been reordered to Callback(func, arg)")
275 Callback(const volatile U *obj, R(*func)(const volatile T *, ArgTs...))
295 "Replaced by simple assignment 'Callback cb = func")
296 void attach(R(*func)(ArgTs...))
308 "Replaced by simple assignment 'Callback cb = func")
321 template<
typename T,
typename U>
323 "Replaced by simple assignment 'Callback cb = func")
324 void attach(U *obj, R(T::*method)(ArgTs...))
336 template<
typename T,
typename U>
338 "Replaced by simple assignment 'Callback cb = func")
339 void attach(const U *obj, R(T::*method)(ArgTs...) const)
351 template<
typename T,
typename U>
353 "Replaced by simple assignment 'Callback cb = func")
354 void attach(volatile U *obj, R(T::*method)(ArgTs...) volatile)
366 template<
typename T,
typename U>
368 "Replaced by simple assignment 'Callback cb = func")
369 void attach(const volatile U *obj, R(T::*method)(ArgTs...) const volatile)
381 template <
typename T,
typename U>
383 "Replaced by simple assignment 'Callback cb = func")
384 void attach(R(*func)(T *, ArgTs...), U *arg)
396 template <
typename T,
typename U>
398 "Replaced by simple assignment 'Callback cb = func")
399 void attach(R(*func)(const T *, ArgTs...), const U *arg)
411 template <
typename T,
typename U>
413 "Replaced by simple assignment 'Callback cb = func")
414 void attach(R(*func)(volatile T *, ArgTs...), volatile U *arg)
426 template <
typename T,
typename U>
428 "Replaced by simple assignment 'Callback cb = func")
429 void attach(R(*func)(const volatile T *, ArgTs...), const volatile U *arg)
441 template <
typename F>
443 "Replaced by simple assignment 'Callback cb = func")
444 void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)))
456 template <
typename F>
458 "Replaced by simple assignment 'Callback cb = func")
459 void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) const))
471 template <
typename F>
473 "Replaced by simple assignment 'Callback cb = func")
474 void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) volatile))
486 template <
typename F>
488 "Replaced by simple assignment 'Callback cb = func")
489 void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) const volatile))
501 template <
typename T,
typename U>
503 "Arguments to callback have been reordered to attach(func, arg)")
504 void attach(U *obj, R(*func)(T *, ArgTs...))
516 template <
typename T,
typename U>
518 "Arguments to callback have been reordered to attach(func, arg)")
519 void attach(const U *obj, R(*func)(const T *, ArgTs...))
531 template <
typename T,
typename U>
533 "Arguments to callback have been reordered to attach(func, arg)")
534 void attach(volatile U *obj, R(*func)(volatile T *, ArgTs...))
546 template <
typename T,
typename U>
548 "Arguments to callback have been reordered to attach(func, arg)")
549 void attach(const volatile U *obj, R(*func)(const volatile T *, ArgTs...))
572 return _ops->call(
this, args...);
579 return call(args...);
584 operator bool()
const 593 return memcmp(&l, &r,
sizeof(
Callback)) == 0;
609 static R
thunk(
void *func, ArgTs... args)
611 return static_cast<Callback *
>(func)->call(args...);
620 void (*_staticfunc)(ArgTs...);
621 void (*_boundfunc)(_class *, ArgTs...);
622 void (_class::*_methodfunc)(ArgTs...);
628 R(*call)(
const void *, ArgTs...);
629 void (*move)(
void *,
const void *);
630 void (*dtor)(
void *);
634 template <
typename F>
635 void generate(
const F &f)
637 static const ops ops = {
638 &Callback::function_call<F>,
639 &Callback::function_move<F>,
640 &Callback::function_dtor<F>,
644 "Type F must not exceed the size of the Callback class");
651 template <
typename F>
652 static R function_call(
const void *p, ArgTs... args)
654 return (*(F *)p)(args...);
657 template <
typename F>
658 static void function_move(
void *d,
const void *p)
663 template <
typename F>
664 static void function_dtor(
void *p)
670 template <
typename O,
typename M>
671 struct method_context {
675 method_context(O *obj, M method)
676 : method(method), obj(obj) {}
678 R operator()(ArgTs... args)
const 680 return (obj->*method)(args...);
684 template <
typename F,
typename A>
685 struct function_context {
689 function_context(F func, A *arg)
690 : func(func), arg(arg) {}
692 R operator()(ArgTs... args)
const 694 return func(arg, args...);
708 template <
typename R,
typename... ArgTs>
719 template <
typename R,
typename... ArgTs>
731 template<
typename T,
typename U,
typename R,
typename... ArgTs>
734 return Callback<R(ArgTs...)>(obj, method);
743 template<
typename T,
typename U,
typename R,
typename... ArgTs>
746 return Callback<R(ArgTs...)>(obj, method);
755 template<
typename T,
typename U,
typename R,
typename... ArgTs>
758 return Callback<R(ArgTs...)>(obj, method);
767 template<
typename T,
typename U,
typename R,
typename... ArgTs>
768 Callback<R(ArgTs...)>
callback(
const volatile U *obj, R(T::*method)(ArgTs...)
const volatile)
770 return Callback<R(ArgTs...)>(obj, method);
779 template <
typename T,
typename U,
typename R,
typename... ArgTs>
782 return Callback<R(ArgTs...)>(func, arg);
791 template <
typename T,
typename U,
typename R,
typename... ArgTs>
794 return Callback<R(ArgTs...)>(func, arg);
803 template <
typename T,
typename U,
typename R,
typename... ArgTs>
806 return Callback<R(ArgTs...)>(func, arg);
815 template <
typename T,
typename U,
typename R,
typename... ArgTs>
816 Callback<R(ArgTs...)>
callback(R(*func)(
const volatile T *, ArgTs...),
const volatile U *arg)
818 return Callback<R(ArgTs...)>(func, arg);
829 template <
typename T,
typename U,
typename R,
typename... ArgTs>
831 "Arguments to callback have been reordered to callback(func, arg)")
834 return Callback<R(ArgTs...)>(func, obj);
845 template <
typename T,
typename U,
typename R,
typename... ArgTs>
847 "Arguments to callback have been reordered to callback(func, arg)")
850 return Callback<R(ArgTs...)>(func, obj);
861 template <
typename T,
typename U,
typename R,
typename... ArgTs>
863 "Arguments to callback have been reordered to callback(func, arg)")
866 return Callback<R(ArgTs...)>(func, obj);
877 template <
typename T,
typename U,
typename R,
typename... ArgTs>
879 "Arguments to callback have been reordered to callback(func, arg)")
880 Callback<R(ArgTs...)>
callback(const volatile U *obj, R(*func)(const volatile T *, ArgTs...))
882 return Callback<R(ArgTs...)>(func, obj);
R call(ArgTs...args) const
Call the attached function.
Callback & operator=(const Callback &that)
Assign a callback.
Callback(const F f,)
Create a Callback with a function object.
static R thunk(void *func, ArgTs...args)
Static thunk for passing as C-style function.
Callback(const U *obj, R(T::*method)(ArgTs...) const)
Create a Callback with a member function.
Callback(R(*func)(volatile T *, ArgTs...), volatile U *arg)
Create a Callback with a static function and bound pointer.
Callback(R(*func)(const T *, ArgTs...), const U *arg)
Create a Callback with a static function and bound pointer.
Callback(R(*func)(ArgTs...)=0)
Create a Callback with a static function.
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Callback(const Callback< R(ArgTs...)> &func)
Attach a Callback.
~Callback()
Destroy a callback.
Callback(volatile F f,)
Create a Callback with a function object.
Callback(R(*func)(const volatile T *, ArgTs...), const volatile U *arg)
Create a Callback with a static function and bound pointer.
R operator()(ArgTs...args) const
Call the attached function.
Callback(U *obj, R(T::*method)(ArgTs...))
Create a Callback with a member function.
Callback(const volatile F f,)
Create a Callback with a function object.
Callback(const volatile U *obj, R(T::*method)(ArgTs...) const volatile)
Create a Callback with a member function.
Callback(R(*func)(T *, ArgTs...), U *arg)
Create a Callback with a static function and bound pointer.
Callback(volatile U *obj, R(T::*method)(ArgTs...) volatile)
Create a Callback with a member function.
Callback(F f,)
Create a Callback with a function object.
Callback class based on template specialization.
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.