Mistake on this page?
Report an issue in GitHub or email us
Callback.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2015 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MBED_CALLBACK_H
18 #define MBED_CALLBACK_H
19 
20 #include <string.h>
21 #include <stdint.h>
22 #include <new>
23 #include "platform/mbed_assert.h"
24 #include "platform/mbed_toolchain.h"
25 
26 namespace mbed {
27 /** \addtogroup platform */
28 /** @{*/
29 /**
30  * \defgroup platform_Callback Callback class
31  * @{
32  */
33 
34 /** Callback class based on template specialization
35  *
36  * @note Synchronization level: Not protected
37  */
38 template <typename F>
39 class Callback;
40 
41 // Internal sfinae declarations
42 //
43 // These are used to eliminate overloads based on type attributes
44 // 1. Does a function object have a call operator
45 // 2. Does a function object fit in the available storage
46 //
47 // These eliminations are handled cleanly by the compiler and avoid
48 // massive and misleading error messages when confronted with an
49 // invalid type (or worse, runtime failures)
50 namespace detail {
51 struct nil {};
52 
53 template <bool B, typename R = nil>
54 struct enable_if {
55  typedef R type;
56 };
57 
58 template <typename R>
59 struct enable_if<false, R> {};
60 
61 template <typename M, M>
62 struct is_type {
63  static const bool value = true;
64 };
65 }
66 
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()
72 
73 /** Callback class based on template specialization
74  *
75  * @note Synchronization level: Not protected
76  */
77 template <typename R>
78 class Callback<R()> {
79 public:
80  /** Create a Callback with a static function
81  * @param func Static function to attach
82  */
83  Callback(R(*func)() = 0)
84  {
85  if (!func) {
86  memset(this, 0, sizeof(Callback));
87  } else {
88  generate(func);
89  }
90  }
91 
92  /** Attach a Callback
93  * @param func The Callback to attach
94  */
95  Callback(const Callback<R()> &func)
96  {
97  if (func._ops) {
98  func._ops->move(this, &func);
99  }
100  _ops = func._ops;
101  }
102 
103  /** Create a Callback with a member function
104  * @param obj Pointer to object to invoke member function on
105  * @param method Member function to attach
106  */
107  template<typename T, typename U>
108  Callback(U *obj, R(T::*method)())
109  {
110  generate(method_context<T, R(T::*)()>(obj, method));
111  }
112 
113  /** Create a Callback with a member function
114  * @param obj Pointer to object to invoke member function on
115  * @param method Member function to attach
116  */
117  template<typename T, typename U>
118  Callback(const U *obj, R(T::*method)() const)
119  {
120  generate(method_context<const T, R(T::*)() const>(obj, method));
121  }
122 
123  /** Create a Callback with a member function
124  * @param obj Pointer to object to invoke member function on
125  * @param method Member function to attach
126  */
127  template<typename T, typename U>
128  Callback(volatile U *obj, R(T::*method)() volatile)
129  {
130  generate(method_context<volatile T, R(T::*)() volatile>(obj, method));
131  }
132 
133  /** Create a Callback with a member function
134  * @param obj Pointer to object to invoke member function on
135  * @param method Member function to attach
136  */
137  template<typename T, typename U>
138  Callback(const volatile U *obj, R(T::*method)() const volatile)
139  {
140  generate(method_context<const volatile T, R(T::*)() const volatile>(obj, method));
141  }
142 
143  /** Create a Callback with a static function and bound pointer
144  * @param func Static function to attach
145  * @param arg Pointer argument to function
146  */
147  template<typename T, typename U>
148  Callback(R(*func)(T *), U *arg)
149  {
150  generate(function_context<R(*)(T *), T>(func, arg));
151  }
152 
153  /** Create a Callback with a static function and bound pointer
154  * @param func Static function to attach
155  * @param arg Pointer argument to function
156  */
157  template<typename T, typename U>
158  Callback(R(*func)(const T *), const U *arg)
159  {
160  generate(function_context<R(*)(const T *), const T>(func, arg));
161  }
162 
163  /** Create a Callback with a static function and bound pointer
164  * @param func Static function to attach
165  * @param arg Pointer argument to function
166  */
167  template<typename T, typename U>
168  Callback(R(*func)(volatile T *), volatile U *arg)
169  {
170  generate(function_context<R(*)(volatile T *), volatile T>(func, arg));
171  }
172 
173  /** Create a Callback with a static function and bound pointer
174  * @param func Static function to attach
175  * @param arg Pointer argument to function
176  */
177  template<typename T, typename U>
178  Callback(R(*func)(const volatile T *), const volatile U *arg)
179  {
180  generate(function_context<R(*)(const volatile T *), const volatile T>(func, arg));
181  }
182 
183  /** Create a Callback with a function object
184  * @param f Function object to attach
185  * @note The function object is limited to a single word of storage
186  */
187  template <typename F>
188  Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)()))
189  {
190  generate(f);
191  }
192 
193  /** Create a Callback with a function object
194  * @param f Function object to attach
195  * @note The function object is limited to a single word of storage
196  */
197  template <typename F>
198  Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)() const))
199  {
200  generate(f);
201  }
202 
203  /** Create a Callback with a function object
204  * @param f Function object to attach
205  * @note The function object is limited to a single word of storage
206  */
207  template <typename F>
208  Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)() volatile))
209  {
210  generate(f);
211  }
212 
213  /** Create a Callback with a function object
214  * @param f Function object to attach
215  * @note The function object is limited to a single word of storage
216  */
217  template <typename F>
218  Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)() const volatile))
219  {
220  generate(f);
221  }
222 
223  /** Create a Callback with a static function and bound pointer
224  * @param obj Pointer to object to bind to function
225  * @param func Static function to attach
226  * @deprecated
227  * Arguments to callback have been reordered to Callback(func, arg)
228  */
229  template<typename T, typename U>
230  MBED_DEPRECATED_SINCE("mbed-os-5.1",
231  "Arguments to callback have been reordered to Callback(func, arg)")
232  Callback(U *obj, R(*func)(T *))
233  {
234  new (this) Callback(func, obj);
235  }
236 
237  /** Create a Callback with a static function and bound pointer
238  * @param obj Pointer to object to bind to function
239  * @param func Static function to attach
240  * @deprecated
241  * Arguments to callback have been reordered to Callback(func, arg)
242  */
243  template<typename T, typename U>
244  MBED_DEPRECATED_SINCE("mbed-os-5.1",
245  "Arguments to callback have been reordered to Callback(func, arg)")
246  Callback(const U *obj, R(*func)(const T *))
247  {
248  new (this) Callback(func, obj);
249  }
250 
251  /** Create a Callback with a static function and bound pointer
252  * @param obj Pointer to object to bind to function
253  * @param func Static function to attach
254  * @deprecated
255  * Arguments to callback have been reordered to Callback(func, arg)
256  */
257  template<typename T, typename U>
258  MBED_DEPRECATED_SINCE("mbed-os-5.1",
259  "Arguments to callback have been reordered to Callback(func, arg)")
260  Callback(volatile U *obj, R(*func)(volatile T *))
261  {
262  new (this) Callback(func, obj);
263  }
264 
265  /** Create a Callback with a static function and bound pointer
266  * @param obj Pointer to object to bind to function
267  * @param func Static function to attach
268  * @deprecated
269  * Arguments to callback have been reordered to Callback(func, arg)
270  */
271  template<typename T, typename U>
272  MBED_DEPRECATED_SINCE("mbed-os-5.1",
273  "Arguments to callback have been reordered to Callback(func, arg)")
274  Callback(const volatile U *obj, R(*func)(const volatile T *))
275  {
276  new (this) Callback(func, obj);
277  }
278 
279  /** Destroy a callback
280  */
282  {
283  if (_ops) {
284  _ops->dtor(this);
285  }
286  }
287 
288  /** Attach a static function
289  * @param func Static function to attach
290  * @deprecated
291  * Replaced by simple assignment 'Callback cb = func'
292  */
293  MBED_DEPRECATED_SINCE("mbed-os-5.4",
294  "Replaced by simple assignment 'Callback cb = func")
295  void attach(R(*func)())
296  {
297  this->~Callback();
298  new (this) Callback(func);
299  }
300 
301  /** Attach a Callback
302  * @param func The Callback to attach
303  * @deprecated
304  * Replaced by simple assignment 'Callback cb = func'
305  */
306  MBED_DEPRECATED_SINCE("mbed-os-5.4",
307  "Replaced by simple assignment 'Callback cb = func")
308  void attach(const Callback<R()> &func)
309  {
310  this->~Callback();
311  new (this) Callback(func);
312  }
313 
314  /** Attach a member function
315  * @param obj Pointer to object to invoke member function on
316  * @param method Member function to attach
317  * @deprecated
318  * Replaced by simple assignment 'Callback cb = func'
319  */
320  template<typename T, typename U>
321  MBED_DEPRECATED_SINCE("mbed-os-5.4",
322  "Replaced by simple assignment 'Callback cb = func")
323  void attach(U *obj, R(T::*method)())
324  {
325  this->~Callback();
326  new (this) Callback(obj, method);
327  }
328 
329  /** Attach a member function
330  * @param obj Pointer to object to invoke member function on
331  * @param method Member function to attach
332  * @deprecated
333  * Replaced by simple assignment 'Callback cb = func'
334  */
335  template<typename T, typename U>
336  MBED_DEPRECATED_SINCE("mbed-os-5.4",
337  "Replaced by simple assignment 'Callback cb = func")
338  void attach(const U *obj, R(T::*method)() const)
339  {
340  this->~Callback();
341  new (this) Callback(obj, method);
342  }
343 
344  /** Attach a member function
345  * @param obj Pointer to object to invoke member function on
346  * @param method Member function to attach
347  * @deprecated
348  * Replaced by simple assignment 'Callback cb = func'
349  */
350  template<typename T, typename U>
351  MBED_DEPRECATED_SINCE("mbed-os-5.4",
352  "Replaced by simple assignment 'Callback cb = func")
353  void attach(volatile U *obj, R(T::*method)() volatile)
354  {
355  this->~Callback();
356  new (this) Callback(obj, method);
357  }
358 
359  /** Attach a member function
360  * @param obj Pointer to object to invoke member function on
361  * @param method Member function to attach
362  * @deprecated
363  * Replaced by simple assignment 'Callback cb = func'
364  */
365  template<typename T, typename U>
366  MBED_DEPRECATED_SINCE("mbed-os-5.4",
367  "Replaced by simple assignment 'Callback cb = func")
368  void attach(const volatile U *obj, R(T::*method)() const volatile)
369  {
370  this->~Callback();
371  new (this) Callback(obj, method);
372  }
373 
374  /** Attach a static function with a bound pointer
375  * @param func Static function to attach
376  * @param arg Pointer argument to function
377  * @deprecated
378  * Replaced by simple assignment 'Callback cb = func'
379  */
380  template <typename T, typename U>
381  MBED_DEPRECATED_SINCE("mbed-os-5.4",
382  "Replaced by simple assignment 'Callback cb = func")
383  void attach(R(*func)(T *), U *arg)
384  {
385  this->~Callback();
386  new (this) Callback(func, arg);
387  }
388 
389  /** Attach a static function with a bound pointer
390  * @param func Static function to attach
391  * @param arg Pointer argument to function
392  * @deprecated
393  * Replaced by simple assignment 'Callback cb = func'
394  */
395  template <typename T, typename U>
396  MBED_DEPRECATED_SINCE("mbed-os-5.4",
397  "Replaced by simple assignment 'Callback cb = func")
398  void attach(R(*func)(const T *), const U *arg)
399  {
400  this->~Callback();
401  new (this) Callback(func, arg);
402  }
403 
404  /** Attach a static function with a bound pointer
405  * @param func Static function to attach
406  * @param arg Pointer argument to function
407  * @deprecated
408  * Replaced by simple assignment 'Callback cb = func'
409  */
410  template <typename T, typename U>
411  MBED_DEPRECATED_SINCE("mbed-os-5.4",
412  "Replaced by simple assignment 'Callback cb = func")
413  void attach(R(*func)(volatile T *), volatile U *arg)
414  {
415  this->~Callback();
416  new (this) Callback(func, arg);
417  }
418 
419  /** Attach a static function with a bound pointer
420  * @param func Static function to attach
421  * @param arg Pointer argument to function
422  * @deprecated
423  * Replaced by simple assignment 'Callback cb = func'
424  */
425  template <typename T, typename U>
426  MBED_DEPRECATED_SINCE("mbed-os-5.4",
427  "Replaced by simple assignment 'Callback cb = func")
428  void attach(R(*func)(const volatile T *), const volatile U *arg)
429  {
430  this->~Callback();
431  new (this) Callback(func, arg);
432  }
433 
434  /** Attach a function object
435  * @param f Function object to attach
436  * @note The function object is limited to a single word of storage
437  * @deprecated
438  * Replaced by simple assignment 'Callback cb = func'
439  */
440  template <typename F>
441  MBED_DEPRECATED_SINCE("mbed-os-5.4",
442  "Replaced by simple assignment 'Callback cb = func")
443  void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)()))
444  {
445  this->~Callback();
446  new (this) Callback(f);
447  }
448 
449  /** Attach a function object
450  * @param f Function object to attach
451  * @note The function object is limited to a single word of storage
452  * @deprecated
453  * Replaced by simple assignment 'Callback cb = func'
454  */
455  template <typename F>
456  MBED_DEPRECATED_SINCE("mbed-os-5.4",
457  "Replaced by simple assignment 'Callback cb = func")
458  void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)() const))
459  {
460  this->~Callback();
461  new (this) Callback(f);
462  }
463 
464  /** Attach a function object
465  * @param f Function object to attach
466  * @note The function object is limited to a single word of storage
467  * @deprecated
468  * Replaced by simple assignment 'Callback cb = func'
469  */
470  template <typename F>
471  MBED_DEPRECATED_SINCE("mbed-os-5.4",
472  "Replaced by simple assignment 'Callback cb = func")
473  void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)() volatile))
474  {
475  this->~Callback();
476  new (this) Callback(f);
477  }
478 
479  /** Attach a function object
480  * @param f Function object to attach
481  * @note The function object is limited to a single word of storage
482  * @deprecated
483  * Replaced by simple assignment 'Callback cb = func'
484  */
485  template <typename F>
486  MBED_DEPRECATED_SINCE("mbed-os-5.4",
487  "Replaced by simple assignment 'Callback cb = func")
488  void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)() const volatile))
489  {
490  this->~Callback();
491  new (this) Callback(f);
492  }
493 
494  /** Attach a static function with a bound pointer
495  * @param obj Pointer to object to bind to function
496  * @param func Static function to attach
497  * @deprecated
498  * Arguments to callback have been reordered to attach(func, arg)
499  */
500  template <typename T, typename U>
501  MBED_DEPRECATED_SINCE("mbed-os-5.1",
502  "Arguments to callback have been reordered to attach(func, arg)")
503  void attach(U *obj, R(*func)(T *))
504  {
505  this->~Callback();
506  new (this) Callback(func, obj);
507  }
508 
509  /** Attach a static function with a bound pointer
510  * @param obj Pointer to object to bind to function
511  * @param func Static function to attach
512  * @deprecated
513  * Arguments to callback have been reordered to attach(func, arg)
514  */
515  template <typename T, typename U>
516  MBED_DEPRECATED_SINCE("mbed-os-5.1",
517  "Arguments to callback have been reordered to attach(func, arg)")
518  void attach(const U *obj, R(*func)(const T *))
519  {
520  this->~Callback();
521  new (this) Callback(func, obj);
522  }
523 
524  /** Attach a static function with a bound pointer
525  * @param obj Pointer to object to bind to function
526  * @param func Static function to attach
527  * @deprecated
528  * Arguments to callback have been reordered to attach(func, arg)
529  */
530  template <typename T, typename U>
531  MBED_DEPRECATED_SINCE("mbed-os-5.1",
532  "Arguments to callback have been reordered to attach(func, arg)")
533  void attach(volatile U *obj, R(*func)(volatile T *))
534  {
535  this->~Callback();
536  new (this) Callback(func, obj);
537  }
538 
539  /** Attach a static function with a bound pointer
540  * @param obj Pointer to object to bind to function
541  * @param func Static function to attach
542  * @deprecated
543  * Arguments to callback have been reordered to attach(func, arg)
544  */
545  template <typename T, typename U>
546  MBED_DEPRECATED_SINCE("mbed-os-5.1",
547  "Arguments to callback have been reordered to attach(func, arg)")
548  void attach(const volatile U *obj, R(*func)(const volatile T *))
549  {
550  this->~Callback();
551  new (this) Callback(func, obj);
552  }
553 
554  /** Assign a callback
555  */
557  {
558  if (this != &that) {
559  this->~Callback();
560  new (this) Callback(that);
561  }
562 
563  return *this;
564  }
565 
566  /** Call the attached function
567  */
568  R call() const
569  {
570  MBED_ASSERT(_ops);
571  return _ops->call(this);
572  }
573 
574  /** Call the attached function
575  */
576  R operator()() const
577  {
578  return call();
579  }
580 
581  /** Test if function has been attached
582  */
583  operator bool() const
584  {
585  return _ops;
586  }
587 
588  /** Test for equality
589  */
590  friend bool operator==(const Callback &l, const Callback &r)
591  {
592  return memcmp(&l, &r, sizeof(Callback)) == 0;
593  }
594 
595  /** Test for inequality
596  */
597  friend bool operator!=(const Callback &l, const Callback &r)
598  {
599  return !(l == r);
600  }
601 
602  /** Static thunk for passing as C-style function
603  * @param func Callback to call passed as void pointer
604  * @return the value as determined by func which is of
605  * type and determined by the signature of func
606  */
607  static R thunk(void *func)
608  {
609  return static_cast<Callback *>(func)->call();
610  }
611 
612 private:
613  // Stored as pointer to function and pointer to optional object
614  // Function pointer is stored as union of possible function types
615  // to guarantee proper size and alignment
616  struct _class;
617  union {
618  void (*_staticfunc)();
619  void (*_boundfunc)(_class *);
620  void (_class::*_methodfunc)();
621  } _func;
622  void *_obj;
623 
624  // Dynamically dispatched operations
625  const struct ops {
626  R(*call)(const void *);
627  void (*move)(void *, const void *);
628  void (*dtor)(void *);
629  } *_ops;
630 
631  // Generate operations for function object
632  template <typename F>
633  void generate(const F &f)
634  {
635  static const ops ops = {
636  &Callback::function_call<F>,
637  &Callback::function_move<F>,
638  &Callback::function_dtor<F>,
639  };
640 
641  MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
642  "Type F must not exceed the size of the Callback class");
643  memset(this, 0, sizeof(Callback));
644  new (this) F(f);
645  _ops = &ops;
646  }
647 
648  // Function attributes
649  template <typename F>
650  static R function_call(const void *p)
651  {
652  return (*(F *)p)();
653  }
654 
655  template <typename F>
656  static void function_move(void *d, const void *p)
657  {
658  new (d) F(*(F *)p);
659  }
660 
661  template <typename F>
662  static void function_dtor(void *p)
663  {
664  ((F *)p)->~F();
665  }
666 
667  // Wrappers for functions with context
668  template <typename O, typename M>
669  struct method_context {
670  M method;
671  O *obj;
672 
673  method_context(O *obj, M method)
674  : method(method), obj(obj) {}
675 
676  R operator()() const
677  {
678  return (obj->*method)();
679  }
680  };
681 
682  template <typename F, typename A>
683  struct function_context {
684  F func;
685  A *arg;
686 
687  function_context(F func, A *arg)
688  : func(func), arg(arg) {}
689 
690  R operator()() const
691  {
692  return func(arg);
693  }
694  };
695 };
696 
697 /** Callback class based on template specialization
698  *
699  * @note Synchronization level: Not protected
700  */
701 template <typename R, typename A0>
702 class Callback<R(A0)> {
703 public:
704  /** Create a Callback with a static function
705  * @param func Static function to attach
706  */
707  Callback(R(*func)(A0) = 0)
708  {
709  if (!func) {
710  memset(this, 0, sizeof(Callback));
711  } else {
712  generate(func);
713  }
714  }
715 
716  /** Attach a Callback
717  * @param func The Callback to attach
718  */
719  Callback(const Callback<R(A0)> &func)
720  {
721  if (func._ops) {
722  func._ops->move(this, &func);
723  }
724  _ops = func._ops;
725  }
726 
727  /** Create a Callback with a member function
728  * @param obj Pointer to object to invoke member function on
729  * @param method Member function to attach
730  */
731  template<typename T, typename U>
732  Callback(U *obj, R(T::*method)(A0))
733  {
734  generate(method_context<T, R(T::*)(A0)>(obj, method));
735  }
736 
737  /** Create a Callback with a member function
738  * @param obj Pointer to object to invoke member function on
739  * @param method Member function to attach
740  */
741  template<typename T, typename U>
742  Callback(const U *obj, R(T::*method)(A0) const)
743  {
744  generate(method_context<const T, R(T::*)(A0) const>(obj, method));
745  }
746 
747  /** Create a Callback with a member function
748  * @param obj Pointer to object to invoke member function on
749  * @param method Member function to attach
750  */
751  template<typename T, typename U>
752  Callback(volatile U *obj, R(T::*method)(A0) volatile)
753  {
754  generate(method_context<volatile T, R(T::*)(A0) volatile>(obj, method));
755  }
756 
757  /** Create a Callback with a member function
758  * @param obj Pointer to object to invoke member function on
759  * @param method Member function to attach
760  */
761  template<typename T, typename U>
762  Callback(const volatile U *obj, R(T::*method)(A0) const volatile)
763  {
764  generate(method_context<const volatile T, R(T::*)(A0) const volatile>(obj, method));
765  }
766 
767  /** Create a Callback with a static function and bound pointer
768  * @param func Static function to attach
769  * @param arg Pointer argument to function
770  */
771  template<typename T, typename U>
772  Callback(R(*func)(T *, A0), U *arg)
773  {
774  generate(function_context<R(*)(T *, A0), T>(func, arg));
775  }
776 
777  /** Create a Callback with a static function and bound pointer
778  * @param func Static function to attach
779  * @param arg Pointer argument to function
780  */
781  template<typename T, typename U>
782  Callback(R(*func)(const T *, A0), const U *arg)
783  {
784  generate(function_context<R(*)(const T *, A0), const T>(func, arg));
785  }
786 
787  /** Create a Callback with a static function and bound pointer
788  * @param func Static function to attach
789  * @param arg Pointer argument to function
790  */
791  template<typename T, typename U>
792  Callback(R(*func)(volatile T *, A0), volatile U *arg)
793  {
794  generate(function_context<R(*)(volatile T *, A0), volatile T>(func, arg));
795  }
796 
797  /** Create a Callback with a static function and bound pointer
798  * @param func Static function to attach
799  * @param arg Pointer argument to function
800  */
801  template<typename T, typename U>
802  Callback(R(*func)(const volatile T *, A0), const volatile U *arg)
803  {
804  generate(function_context<R(*)(const volatile T *, A0), const volatile T>(func, arg));
805  }
806 
807  /** Create a Callback with a function object
808  * @param f Function object to attach
809  * @note The function object is limited to a single word of storage
810  */
811  template <typename F>
812  Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0)))
813  {
814  generate(f);
815  }
816 
817  /** Create a Callback with a function object
818  * @param f Function object to attach
819  * @note The function object is limited to a single word of storage
820  */
821  template <typename F>
822  Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0) const))
823  {
824  generate(f);
825  }
826 
827  /** Create a Callback with a function object
828  * @param f Function object to attach
829  * @note The function object is limited to a single word of storage
830  */
831  template <typename F>
832  Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0) volatile))
833  {
834  generate(f);
835  }
836 
837  /** Create a Callback with a function object
838  * @param f Function object to attach
839  * @note The function object is limited to a single word of storage
840  */
841  template <typename F>
842  Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0) const volatile))
843  {
844  generate(f);
845  }
846 
847  /** Create a Callback with a static function and bound pointer
848  * @param obj Pointer to object to bind to function
849  * @param func Static function to attach
850  * @deprecated
851  * Arguments to callback have been reordered to Callback(func, arg)
852  */
853  template<typename T, typename U>
854  MBED_DEPRECATED_SINCE("mbed-os-5.1",
855  "Arguments to callback have been reordered to Callback(func, arg)")
856  Callback(U *obj, R(*func)(T *, A0))
857  {
858  new (this) Callback(func, obj);
859  }
860 
861  /** Create a Callback with a static function and bound pointer
862  * @param obj Pointer to object to bind to function
863  * @param func Static function to attach
864  * @deprecated
865  * Arguments to callback have been reordered to Callback(func, arg)
866  */
867  template<typename T, typename U>
868  MBED_DEPRECATED_SINCE("mbed-os-5.1",
869  "Arguments to callback have been reordered to Callback(func, arg)")
870  Callback(const U *obj, R(*func)(const T *, A0))
871  {
872  new (this) Callback(func, obj);
873  }
874 
875  /** Create a Callback with a static function and bound pointer
876  * @param obj Pointer to object to bind to function
877  * @param func Static function to attach
878  * @deprecated
879  * Arguments to callback have been reordered to Callback(func, arg)
880  */
881  template<typename T, typename U>
882  MBED_DEPRECATED_SINCE("mbed-os-5.1",
883  "Arguments to callback have been reordered to Callback(func, arg)")
884  Callback(volatile U *obj, R(*func)(volatile T *, A0))
885  {
886  new (this) Callback(func, obj);
887  }
888 
889  /** Create a Callback with a static function and bound pointer
890  * @param obj Pointer to object to bind to function
891  * @param func Static function to attach
892  * @deprecated
893  * Arguments to callback have been reordered to Callback(func, arg)
894  */
895  template<typename T, typename U>
896  MBED_DEPRECATED_SINCE("mbed-os-5.1",
897  "Arguments to callback have been reordered to Callback(func, arg)")
898  Callback(const volatile U *obj, R(*func)(const volatile T *, A0))
899  {
900  new (this) Callback(func, obj);
901  }
902 
903  /** Destroy a callback
904  */
906  {
907  if (_ops) {
908  _ops->dtor(this);
909  }
910  }
911 
912  /** Attach a static function
913  * @param func Static function to attach
914  * @deprecated
915  * Replaced by simple assignment 'Callback cb = func'
916  */
917  MBED_DEPRECATED_SINCE("mbed-os-5.4",
918  "Replaced by simple assignment 'Callback cb = func")
919  void attach(R(*func)(A0))
920  {
921  this->~Callback();
922  new (this) Callback(func);
923  }
924 
925  /** Attach a Callback
926  * @param func The Callback to attach
927  * @deprecated
928  * Replaced by simple assignment 'Callback cb = func'
929  */
930  MBED_DEPRECATED_SINCE("mbed-os-5.4",
931  "Replaced by simple assignment 'Callback cb = func")
932  void attach(const Callback<R(A0)> &func)
933  {
934  this->~Callback();
935  new (this) Callback(func);
936  }
937 
938  /** Attach a member function
939  * @param obj Pointer to object to invoke member function on
940  * @param method Member function to attach
941  * @deprecated
942  * Replaced by simple assignment 'Callback cb = func'
943  */
944  template<typename T, typename U>
945  MBED_DEPRECATED_SINCE("mbed-os-5.4",
946  "Replaced by simple assignment 'Callback cb = func")
947  void attach(U *obj, R(T::*method)(A0))
948  {
949  this->~Callback();
950  new (this) Callback(obj, method);
951  }
952 
953  /** Attach a member function
954  * @param obj Pointer to object to invoke member function on
955  * @param method Member function to attach
956  * @deprecated
957  * Replaced by simple assignment 'Callback cb = func'
958  */
959  template<typename T, typename U>
960  MBED_DEPRECATED_SINCE("mbed-os-5.4",
961  "Replaced by simple assignment 'Callback cb = func")
962  void attach(const U *obj, R(T::*method)(A0) const)
963  {
964  this->~Callback();
965  new (this) Callback(obj, method);
966  }
967 
968  /** Attach a member function
969  * @param obj Pointer to object to invoke member function on
970  * @param method Member function to attach
971  * @deprecated
972  * Replaced by simple assignment 'Callback cb = func'
973  */
974  template<typename T, typename U>
975  MBED_DEPRECATED_SINCE("mbed-os-5.4",
976  "Replaced by simple assignment 'Callback cb = func")
977  void attach(volatile U *obj, R(T::*method)(A0) volatile)
978  {
979  this->~Callback();
980  new (this) Callback(obj, method);
981  }
982 
983  /** Attach a member function
984  * @param obj Pointer to object to invoke member function on
985  * @param method Member function to attach
986  * @deprecated
987  * Replaced by simple assignment 'Callback cb = func'
988  */
989  template<typename T, typename U>
990  MBED_DEPRECATED_SINCE("mbed-os-5.4",
991  "Replaced by simple assignment 'Callback cb = func")
992  void attach(const volatile U *obj, R(T::*method)(A0) const volatile)
993  {
994  this->~Callback();
995  new (this) Callback(obj, method);
996  }
997 
998  /** Attach a static function with a bound pointer
999  * @param func Static function to attach
1000  * @param arg Pointer argument to function
1001  * @deprecated
1002  * Replaced by simple assignment 'Callback cb = func'
1003  */
1004  template <typename T, typename U>
1005  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1006  "Replaced by simple assignment 'Callback cb = func")
1007  void attach(R(*func)(T *, A0), U *arg)
1008  {
1009  this->~Callback();
1010  new (this) Callback(func, arg);
1011  }
1012 
1013  /** Attach a static function with a bound pointer
1014  * @param func Static function to attach
1015  * @param arg Pointer argument to function
1016  * @deprecated
1017  * Replaced by simple assignment 'Callback cb = func'
1018  */
1019  template <typename T, typename U>
1020  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1021  "Replaced by simple assignment 'Callback cb = func")
1022  void attach(R(*func)(const T *, A0), const U *arg)
1023  {
1024  this->~Callback();
1025  new (this) Callback(func, arg);
1026  }
1027 
1028  /** Attach a static function with a bound pointer
1029  * @param func Static function to attach
1030  * @param arg Pointer argument to function
1031  * @deprecated
1032  * Replaced by simple assignment 'Callback cb = func'
1033  */
1034  template <typename T, typename U>
1035  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1036  "Replaced by simple assignment 'Callback cb = func")
1037  void attach(R(*func)(volatile T *, A0), volatile U *arg)
1038  {
1039  this->~Callback();
1040  new (this) Callback(func, arg);
1041  }
1042 
1043  /** Attach a static function with a bound pointer
1044  * @param func Static function to attach
1045  * @param arg Pointer argument to function
1046  * @deprecated
1047  * Replaced by simple assignment 'Callback cb = func'
1048  */
1049  template <typename T, typename U>
1050  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1051  "Replaced by simple assignment 'Callback cb = func")
1052  void attach(R(*func)(const volatile T *, A0), const volatile U *arg)
1053  {
1054  this->~Callback();
1055  new (this) Callback(func, arg);
1056  }
1057 
1058  /** Attach a function object
1059  * @param f Function object to attach
1060  * @note The function object is limited to a single word of storage
1061  * @deprecated
1062  * Replaced by simple assignment 'Callback cb = func'
1063  */
1064  template <typename F>
1065  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1066  "Replaced by simple assignment 'Callback cb = func")
1067  void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0)))
1068  {
1069  this->~Callback();
1070  new (this) Callback(f);
1071  }
1072 
1073  /** Attach a function object
1074  * @param f Function object to attach
1075  * @note The function object is limited to a single word of storage
1076  * @deprecated
1077  * Replaced by simple assignment 'Callback cb = func'
1078  */
1079  template <typename F>
1080  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1081  "Replaced by simple assignment 'Callback cb = func")
1082  void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0) const))
1083  {
1084  this->~Callback();
1085  new (this) Callback(f);
1086  }
1087 
1088  /** Attach a function object
1089  * @param f Function object to attach
1090  * @note The function object is limited to a single word of storage
1091  * @deprecated
1092  * Replaced by simple assignment 'Callback cb = func'
1093  */
1094  template <typename F>
1095  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1096  "Replaced by simple assignment 'Callback cb = func")
1097  void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0) volatile))
1098  {
1099  this->~Callback();
1100  new (this) Callback(f);
1101  }
1102 
1103  /** Attach a function object
1104  * @param f Function object to attach
1105  * @note The function object is limited to a single word of storage
1106  * @deprecated
1107  * Replaced by simple assignment 'Callback cb = func'
1108  */
1109  template <typename F>
1110  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1111  "Replaced by simple assignment 'Callback cb = func")
1112  void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0) const volatile))
1113  {
1114  this->~Callback();
1115  new (this) Callback(f);
1116  }
1117 
1118  /** Attach a static function with a bound pointer
1119  * @param obj Pointer to object to bind to function
1120  * @param func Static function to attach
1121  * @deprecated
1122  * Arguments to callback have been reordered to attach(func, arg)
1123  */
1124  template <typename T, typename U>
1125  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1126  "Arguments to callback have been reordered to attach(func, arg)")
1127  void attach(U *obj, R(*func)(T *, A0))
1128  {
1129  this->~Callback();
1130  new (this) Callback(func, obj);
1131  }
1132 
1133  /** Attach a static function with a bound pointer
1134  * @param obj Pointer to object to bind to function
1135  * @param func Static function to attach
1136  * @deprecated
1137  * Arguments to callback have been reordered to attach(func, arg)
1138  */
1139  template <typename T, typename U>
1140  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1141  "Arguments to callback have been reordered to attach(func, arg)")
1142  void attach(const U *obj, R(*func)(const T *, A0))
1143  {
1144  this->~Callback();
1145  new (this) Callback(func, obj);
1146  }
1147 
1148  /** Attach a static function with a bound pointer
1149  * @param obj Pointer to object to bind to function
1150  * @param func Static function to attach
1151  * @deprecated
1152  * Arguments to callback have been reordered to attach(func, arg)
1153  */
1154  template <typename T, typename U>
1155  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1156  "Arguments to callback have been reordered to attach(func, arg)")
1157  void attach(volatile U *obj, R(*func)(volatile T *, A0))
1158  {
1159  this->~Callback();
1160  new (this) Callback(func, obj);
1161  }
1162 
1163  /** Attach a static function with a bound pointer
1164  * @param obj Pointer to object to bind to function
1165  * @param func Static function to attach
1166  * @deprecated
1167  * Arguments to callback have been reordered to attach(func, arg)
1168  */
1169  template <typename T, typename U>
1170  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1171  "Arguments to callback have been reordered to attach(func, arg)")
1172  void attach(const volatile U *obj, R(*func)(const volatile T *, A0))
1173  {
1174  this->~Callback();
1175  new (this) Callback(func, obj);
1176  }
1177 
1178  /** Assign a callback
1179  */
1181  {
1182  if (this != &that) {
1183  this->~Callback();
1184  new (this) Callback(that);
1185  }
1186 
1187  return *this;
1188  }
1189 
1190  /** Call the attached function
1191  */
1192  R call(A0 a0) const
1193  {
1194  MBED_ASSERT(_ops);
1195  return _ops->call(this, a0);
1196  }
1197 
1198  /** Call the attached function
1199  */
1200  R operator()(A0 a0) const
1201  {
1202  return call(a0);
1203  }
1204 
1205  /** Test if function has been attached
1206  */
1207  operator bool() const
1208  {
1209  return _ops;
1210  }
1211 
1212  /** Test for equality
1213  */
1214  friend bool operator==(const Callback &l, const Callback &r)
1215  {
1216  return memcmp(&l, &r, sizeof(Callback)) == 0;
1217  }
1218 
1219  /** Test for inequality
1220  */
1221  friend bool operator!=(const Callback &l, const Callback &r)
1222  {
1223  return !(l == r);
1224  }
1225 
1226  /** Static thunk for passing as C-style function
1227  * @param func Callback to call passed as void pointer
1228  * @param a0 An argument to be called with function func
1229  * @return the value as determined by func which is of
1230  * type and determined by the signature of func
1231  */
1232  static R thunk(void *func, A0 a0)
1233  {
1234  return static_cast<Callback *>(func)->call(a0);
1235  }
1236 
1237 private:
1238  // Stored as pointer to function and pointer to optional object
1239  // Function pointer is stored as union of possible function types
1240  // to guarantee proper size and alignment
1241  struct _class;
1242  union {
1243  void (*_staticfunc)(A0);
1244  void (*_boundfunc)(_class *, A0);
1245  void (_class::*_methodfunc)(A0);
1246  } _func;
1247  void *_obj;
1248 
1249  // Dynamically dispatched operations
1250  const struct ops {
1251  R(*call)(const void *, A0);
1252  void (*move)(void *, const void *);
1253  void (*dtor)(void *);
1254  } *_ops;
1255 
1256  // Generate operations for function object
1257  template <typename F>
1258  void generate(const F &f)
1259  {
1260  static const ops ops = {
1261  &Callback::function_call<F>,
1262  &Callback::function_move<F>,
1263  &Callback::function_dtor<F>,
1264  };
1265 
1266  MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
1267  "Type F must not exceed the size of the Callback class");
1268  memset(this, 0, sizeof(Callback));
1269  new (this) F(f);
1270  _ops = &ops;
1271  }
1272 
1273  // Function attributes
1274  template <typename F>
1275  static R function_call(const void *p, A0 a0)
1276  {
1277  return (*(F *)p)(a0);
1278  }
1279 
1280  template <typename F>
1281  static void function_move(void *d, const void *p)
1282  {
1283  new (d) F(*(F *)p);
1284  }
1285 
1286  template <typename F>
1287  static void function_dtor(void *p)
1288  {
1289  ((F *)p)->~F();
1290  }
1291 
1292  // Wrappers for functions with context
1293  template <typename O, typename M>
1294  struct method_context {
1295  M method;
1296  O *obj;
1297 
1298  method_context(O *obj, M method)
1299  : method(method), obj(obj) {}
1300 
1301  R operator()(A0 a0) const
1302  {
1303  return (obj->*method)(a0);
1304  }
1305  };
1306 
1307  template <typename F, typename A>
1308  struct function_context {
1309  F func;
1310  A *arg;
1311 
1312  function_context(F func, A *arg)
1313  : func(func), arg(arg) {}
1314 
1315  R operator()(A0 a0) const
1316  {
1317  return func(arg, a0);
1318  }
1319  };
1320 };
1321 
1322 /** Callback class based on template specialization
1323  *
1324  * @note Synchronization level: Not protected
1325  */
1326 template <typename R, typename A0, typename A1>
1327 class Callback<R(A0, A1)> {
1328 public:
1329  /** Create a Callback with a static function
1330  * @param func Static function to attach
1331  */
1332  Callback(R(*func)(A0, A1) = 0)
1333  {
1334  if (!func) {
1335  memset(this, 0, sizeof(Callback));
1336  } else {
1337  generate(func);
1338  }
1339  }
1340 
1341  /** Attach a Callback
1342  * @param func The Callback to attach
1343  */
1344  Callback(const Callback<R(A0, A1)> &func)
1345  {
1346  if (func._ops) {
1347  func._ops->move(this, &func);
1348  }
1349  _ops = func._ops;
1350  }
1351 
1352  /** Create a Callback with a member function
1353  * @param obj Pointer to object to invoke member function on
1354  * @param method Member function to attach
1355  */
1356  template<typename T, typename U>
1357  Callback(U *obj, R(T::*method)(A0, A1))
1358  {
1359  generate(method_context<T, R(T::*)(A0, A1)>(obj, method));
1360  }
1361 
1362  /** Create a Callback with a member function
1363  * @param obj Pointer to object to invoke member function on
1364  * @param method Member function to attach
1365  */
1366  template<typename T, typename U>
1367  Callback(const U *obj, R(T::*method)(A0, A1) const)
1368  {
1369  generate(method_context<const T, R(T::*)(A0, A1) const>(obj, method));
1370  }
1371 
1372  /** Create a Callback with a member function
1373  * @param obj Pointer to object to invoke member function on
1374  * @param method Member function to attach
1375  */
1376  template<typename T, typename U>
1377  Callback(volatile U *obj, R(T::*method)(A0, A1) volatile)
1378  {
1379  generate(method_context<volatile T, R(T::*)(A0, A1) volatile>(obj, method));
1380  }
1381 
1382  /** Create a Callback with a member function
1383  * @param obj Pointer to object to invoke member function on
1384  * @param method Member function to attach
1385  */
1386  template<typename T, typename U>
1387  Callback(const volatile U *obj, R(T::*method)(A0, A1) const volatile)
1388  {
1389  generate(method_context<const volatile T, R(T::*)(A0, A1) const volatile>(obj, method));
1390  }
1391 
1392  /** Create a Callback with a static function and bound pointer
1393  * @param func Static function to attach
1394  * @param arg Pointer argument to function
1395  */
1396  template<typename T, typename U>
1397  Callback(R(*func)(T *, A0, A1), U *arg)
1398  {
1399  generate(function_context<R(*)(T *, A0, A1), T>(func, arg));
1400  }
1401 
1402  /** Create a Callback with a static function and bound pointer
1403  * @param func Static function to attach
1404  * @param arg Pointer argument to function
1405  */
1406  template<typename T, typename U>
1407  Callback(R(*func)(const T *, A0, A1), const U *arg)
1408  {
1409  generate(function_context<R(*)(const T *, A0, A1), const T>(func, arg));
1410  }
1411 
1412  /** Create a Callback with a static function and bound pointer
1413  * @param func Static function to attach
1414  * @param arg Pointer argument to function
1415  */
1416  template<typename T, typename U>
1417  Callback(R(*func)(volatile T *, A0, A1), volatile U *arg)
1418  {
1419  generate(function_context<R(*)(volatile T *, A0, A1), volatile T>(func, arg));
1420  }
1421 
1422  /** Create a Callback with a static function and bound pointer
1423  * @param func Static function to attach
1424  * @param arg Pointer argument to function
1425  */
1426  template<typename T, typename U>
1427  Callback(R(*func)(const volatile T *, A0, A1), const volatile U *arg)
1428  {
1429  generate(function_context<R(*)(const volatile T *, A0, A1), const volatile T>(func, arg));
1430  }
1431 
1432  /** Create a Callback with a function object
1433  * @param f Function object to attach
1434  * @note The function object is limited to a single word of storage
1435  */
1436  template <typename F>
1437  Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1)))
1438  {
1439  generate(f);
1440  }
1441 
1442  /** Create a Callback with a function object
1443  * @param f Function object to attach
1444  * @note The function object is limited to a single word of storage
1445  */
1446  template <typename F>
1447  Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1) const))
1448  {
1449  generate(f);
1450  }
1451 
1452  /** Create a Callback with a function object
1453  * @param f Function object to attach
1454  * @note The function object is limited to a single word of storage
1455  */
1456  template <typename F>
1457  Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1) volatile))
1458  {
1459  generate(f);
1460  }
1461 
1462  /** Create a Callback with a function object
1463  * @param f Function object to attach
1464  * @note The function object is limited to a single word of storage
1465  */
1466  template <typename F>
1467  Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1) const volatile))
1468  {
1469  generate(f);
1470  }
1471 
1472  /** Create a Callback with a static function and bound pointer
1473  * @param obj Pointer to object to bind to function
1474  * @param func Static function to attach
1475  * @deprecated
1476  * Arguments to callback have been reordered to Callback(func, arg)
1477  */
1478  template<typename T, typename U>
1479  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1480  "Arguments to callback have been reordered to Callback(func, arg)")
1481  Callback(U *obj, R(*func)(T *, A0, A1))
1482  {
1483  new (this) Callback(func, obj);
1484  }
1485 
1486  /** Create a Callback with a static function and bound pointer
1487  * @param obj Pointer to object to bind to function
1488  * @param func Static function to attach
1489  * @deprecated
1490  * Arguments to callback have been reordered to Callback(func, arg)
1491  */
1492  template<typename T, typename U>
1493  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1494  "Arguments to callback have been reordered to Callback(func, arg)")
1495  Callback(const U *obj, R(*func)(const T *, A0, A1))
1496  {
1497  new (this) Callback(func, obj);
1498  }
1499 
1500  /** Create a Callback with a static function and bound pointer
1501  * @param obj Pointer to object to bind to function
1502  * @param func Static function to attach
1503  * @deprecated
1504  * Arguments to callback have been reordered to Callback(func, arg)
1505  */
1506  template<typename T, typename U>
1507  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1508  "Arguments to callback have been reordered to Callback(func, arg)")
1509  Callback(volatile U *obj, R(*func)(volatile T *, A0, A1))
1510  {
1511  new (this) Callback(func, obj);
1512  }
1513 
1514  /** Create a Callback with a static function and bound pointer
1515  * @param obj Pointer to object to bind to function
1516  * @param func Static function to attach
1517  * @deprecated
1518  * Arguments to callback have been reordered to Callback(func, arg)
1519  */
1520  template<typename T, typename U>
1521  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1522  "Arguments to callback have been reordered to Callback(func, arg)")
1523  Callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1))
1524  {
1525  new (this) Callback(func, obj);
1526  }
1527 
1528  /** Destroy a callback
1529  */
1531  {
1532  if (_ops) {
1533  _ops->dtor(this);
1534  }
1535  }
1536 
1537  /** Attach a static function
1538  * @param func Static function to attach
1539  * @deprecated
1540  * Replaced by simple assignment 'Callback cb = func'
1541  */
1542  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1543  "Replaced by simple assignment 'Callback cb = func")
1544  void attach(R(*func)(A0, A1))
1545  {
1546  this->~Callback();
1547  new (this) Callback(func);
1548  }
1549 
1550  /** Attach a Callback
1551  * @param func The Callback to attach
1552  * @deprecated
1553  * Replaced by simple assignment 'Callback cb = func'
1554  */
1555  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1556  "Replaced by simple assignment 'Callback cb = func")
1557  void attach(const Callback<R(A0, A1)> &func)
1558  {
1559  this->~Callback();
1560  new (this) Callback(func);
1561  }
1562 
1563  /** Attach a member function
1564  * @param obj Pointer to object to invoke member function on
1565  * @param method Member function to attach
1566  * @deprecated
1567  * Replaced by simple assignment 'Callback cb = func'
1568  */
1569  template<typename T, typename U>
1570  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1571  "Replaced by simple assignment 'Callback cb = func")
1572  void attach(U *obj, R(T::*method)(A0, A1))
1573  {
1574  this->~Callback();
1575  new (this) Callback(obj, method);
1576  }
1577 
1578  /** Attach a member function
1579  * @param obj Pointer to object to invoke member function on
1580  * @param method Member function to attach
1581  * @deprecated
1582  * Replaced by simple assignment 'Callback cb = func'
1583  */
1584  template<typename T, typename U>
1585  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1586  "Replaced by simple assignment 'Callback cb = func")
1587  void attach(const U *obj, R(T::*method)(A0, A1) const)
1588  {
1589  this->~Callback();
1590  new (this) Callback(obj, method);
1591  }
1592 
1593  /** Attach a member function
1594  * @param obj Pointer to object to invoke member function on
1595  * @param method Member function to attach
1596  * @deprecated
1597  * Replaced by simple assignment 'Callback cb = func'
1598  */
1599  template<typename T, typename U>
1600  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1601  "Replaced by simple assignment 'Callback cb = func")
1602  void attach(volatile U *obj, R(T::*method)(A0, A1) volatile)
1603  {
1604  this->~Callback();
1605  new (this) Callback(obj, method);
1606  }
1607 
1608  /** Attach a member function
1609  * @param obj Pointer to object to invoke member function on
1610  * @param method Member function to attach
1611  * @deprecated
1612  * Replaced by simple assignment 'Callback cb = func'
1613  */
1614  template<typename T, typename U>
1615  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1616  "Replaced by simple assignment 'Callback cb = func")
1617  void attach(const volatile U *obj, R(T::*method)(A0, A1) const volatile)
1618  {
1619  this->~Callback();
1620  new (this) Callback(obj, method);
1621  }
1622 
1623  /** Attach a static function with a bound pointer
1624  * @param func Static function to attach
1625  * @param arg Pointer argument to function
1626  * @deprecated
1627  * Replaced by simple assignment 'Callback cb = func'
1628  */
1629  template <typename T, typename U>
1630  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1631  "Replaced by simple assignment 'Callback cb = func")
1632  void attach(R(*func)(T *, A0, A1), U *arg)
1633  {
1634  this->~Callback();
1635  new (this) Callback(func, arg);
1636  }
1637 
1638  /** Attach a static function with a bound pointer
1639  * @param func Static function to attach
1640  * @param arg Pointer argument to function
1641  * @deprecated
1642  * Replaced by simple assignment 'Callback cb = func'
1643  */
1644  template <typename T, typename U>
1645  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1646  "Replaced by simple assignment 'Callback cb = func")
1647  void attach(R(*func)(const T *, A0, A1), const U *arg)
1648  {
1649  this->~Callback();
1650  new (this) Callback(func, arg);
1651  }
1652 
1653  /** Attach a static function with a bound pointer
1654  * @param func Static function to attach
1655  * @param arg Pointer argument to function
1656  * @deprecated
1657  * Replaced by simple assignment 'Callback cb = func'
1658  */
1659  template <typename T, typename U>
1660  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1661  "Replaced by simple assignment 'Callback cb = func")
1662  void attach(R(*func)(volatile T *, A0, A1), volatile U *arg)
1663  {
1664  this->~Callback();
1665  new (this) Callback(func, arg);
1666  }
1667 
1668  /** Attach a static function with a bound pointer
1669  * @param func Static function to attach
1670  * @param arg Pointer argument to function
1671  * @deprecated
1672  * Replaced by simple assignment 'Callback cb = func'
1673  */
1674  template <typename T, typename U>
1675  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1676  "Replaced by simple assignment 'Callback cb = func")
1677  void attach(R(*func)(const volatile T *, A0, A1), const volatile U *arg)
1678  {
1679  this->~Callback();
1680  new (this) Callback(func, arg);
1681  }
1682 
1683  /** Attach a function object
1684  * @param f Function object to attach
1685  * @note The function object is limited to a single word of storage
1686  * @deprecated
1687  * Replaced by simple assignment 'Callback cb = func'
1688  */
1689  template <typename F>
1690  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1691  "Replaced by simple assignment 'Callback cb = func")
1692  void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1)))
1693  {
1694  this->~Callback();
1695  new (this) Callback(f);
1696  }
1697 
1698  /** Attach a function object
1699  * @param f Function object to attach
1700  * @note The function object is limited to a single word of storage
1701  * @deprecated
1702  * Replaced by simple assignment 'Callback cb = func'
1703  */
1704  template <typename F>
1705  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1706  "Replaced by simple assignment 'Callback cb = func")
1707  void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1) const))
1708  {
1709  this->~Callback();
1710  new (this) Callback(f);
1711  }
1712 
1713  /** Attach a function object
1714  * @param f Function object to attach
1715  * @note The function object is limited to a single word of storage
1716  * @deprecated
1717  * Replaced by simple assignment 'Callback cb = func'
1718  */
1719  template <typename F>
1720  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1721  "Replaced by simple assignment 'Callback cb = func")
1722  void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1) volatile))
1723  {
1724  this->~Callback();
1725  new (this) Callback(f);
1726  }
1727 
1728  /** Attach a function object
1729  * @param f Function object to attach
1730  * @note The function object is limited to a single word of storage
1731  * @deprecated
1732  * Replaced by simple assignment 'Callback cb = func'
1733  */
1734  template <typename F>
1735  MBED_DEPRECATED_SINCE("mbed-os-5.4",
1736  "Replaced by simple assignment 'Callback cb = func")
1737  void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1) const volatile))
1738  {
1739  this->~Callback();
1740  new (this) Callback(f);
1741  }
1742 
1743  /** Attach a static function with a bound pointer
1744  * @param obj Pointer to object to bind to function
1745  * @param func Static function to attach
1746  * @deprecated
1747  * Arguments to callback have been reordered to attach(func, arg)
1748  */
1749  template <typename T, typename U>
1750  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1751  "Arguments to callback have been reordered to attach(func, arg)")
1752  void attach(U *obj, R(*func)(T *, A0, A1))
1753  {
1754  this->~Callback();
1755  new (this) Callback(func, obj);
1756  }
1757 
1758  /** Attach a static function with a bound pointer
1759  * @param obj Pointer to object to bind to function
1760  * @param func Static function to attach
1761  * @deprecated
1762  * Arguments to callback have been reordered to attach(func, arg)
1763  */
1764  template <typename T, typename U>
1765  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1766  "Arguments to callback have been reordered to attach(func, arg)")
1767  void attach(const U *obj, R(*func)(const T *, A0, A1))
1768  {
1769  this->~Callback();
1770  new (this) Callback(func, obj);
1771  }
1772 
1773  /** Attach a static function with a bound pointer
1774  * @param obj Pointer to object to bind to function
1775  * @param func Static function to attach
1776  * @deprecated
1777  * Arguments to callback have been reordered to attach(func, arg)
1778  */
1779  template <typename T, typename U>
1780  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1781  "Arguments to callback have been reordered to attach(func, arg)")
1782  void attach(volatile U *obj, R(*func)(volatile T *, A0, A1))
1783  {
1784  this->~Callback();
1785  new (this) Callback(func, obj);
1786  }
1787 
1788  /** Attach a static function with a bound pointer
1789  * @param obj Pointer to object to bind to function
1790  * @param func Static function to attach
1791  * @deprecated
1792  * Arguments to callback have been reordered to attach(func, arg)
1793  */
1794  template <typename T, typename U>
1795  MBED_DEPRECATED_SINCE("mbed-os-5.1",
1796  "Arguments to callback have been reordered to attach(func, arg)")
1797  void attach(const volatile U *obj, R(*func)(const volatile T *, A0, A1))
1798  {
1799  this->~Callback();
1800  new (this) Callback(func, obj);
1801  }
1802 
1803  /** Assign a callback
1804  */
1806  {
1807  if (this != &that) {
1808  this->~Callback();
1809  new (this) Callback(that);
1810  }
1811 
1812  return *this;
1813  }
1814 
1815  /** Call the attached function
1816  */
1817  R call(A0 a0, A1 a1) const
1818  {
1819  MBED_ASSERT(_ops);
1820  return _ops->call(this, a0, a1);
1821  }
1822 
1823  /** Call the attached function
1824  */
1825  R operator()(A0 a0, A1 a1) const
1826  {
1827  return call(a0, a1);
1828  }
1829 
1830  /** Test if function has been attached
1831  */
1832  operator bool() const
1833  {
1834  return _ops;
1835  }
1836 
1837  /** Test for equality
1838  */
1839  friend bool operator==(const Callback &l, const Callback &r)
1840  {
1841  return memcmp(&l, &r, sizeof(Callback)) == 0;
1842  }
1843 
1844  /** Test for inequality
1845  */
1846  friend bool operator!=(const Callback &l, const Callback &r)
1847  {
1848  return !(l == r);
1849  }
1850 
1851  /** Static thunk for passing as C-style function
1852  * @param func Callback to call passed as void pointer
1853  * @param a0 An argument to be called with function func
1854  * @param a1 An argument to be called with function func
1855  * @return the value as determined by func which is of
1856  * type and determined by the signature of func
1857  */
1858  static R thunk(void *func, A0 a0, A1 a1)
1859  {
1860  return static_cast<Callback *>(func)->call(a0, a1);
1861  }
1862 
1863 private:
1864  // Stored as pointer to function and pointer to optional object
1865  // Function pointer is stored as union of possible function types
1866  // to guarantee proper size and alignment
1867  struct _class;
1868  union {
1869  void (*_staticfunc)(A0, A1);
1870  void (*_boundfunc)(_class *, A0, A1);
1871  void (_class::*_methodfunc)(A0, A1);
1872  } _func;
1873  void *_obj;
1874 
1875  // Dynamically dispatched operations
1876  const struct ops {
1877  R(*call)(const void *, A0, A1);
1878  void (*move)(void *, const void *);
1879  void (*dtor)(void *);
1880  } *_ops;
1881 
1882  // Generate operations for function object
1883  template <typename F>
1884  void generate(const F &f)
1885  {
1886  static const ops ops = {
1887  &Callback::function_call<F>,
1888  &Callback::function_move<F>,
1889  &Callback::function_dtor<F>,
1890  };
1891 
1892  MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
1893  "Type F must not exceed the size of the Callback class");
1894  memset(this, 0, sizeof(Callback));
1895  new (this) F(f);
1896  _ops = &ops;
1897  }
1898 
1899  // Function attributes
1900  template <typename F>
1901  static R function_call(const void *p, A0 a0, A1 a1)
1902  {
1903  return (*(F *)p)(a0, a1);
1904  }
1905 
1906  template <typename F>
1907  static void function_move(void *d, const void *p)
1908  {
1909  new (d) F(*(F *)p);
1910  }
1911 
1912  template <typename F>
1913  static void function_dtor(void *p)
1914  {
1915  ((F *)p)->~F();
1916  }
1917 
1918  // Wrappers for functions with context
1919  template <typename O, typename M>
1920  struct method_context {
1921  M method;
1922  O *obj;
1923 
1924  method_context(O *obj, M method)
1925  : method(method), obj(obj) {}
1926 
1927  R operator()(A0 a0, A1 a1) const
1928  {
1929  return (obj->*method)(a0, a1);
1930  }
1931  };
1932 
1933  template <typename F, typename A>
1934  struct function_context {
1935  F func;
1936  A *arg;
1937 
1938  function_context(F func, A *arg)
1939  : func(func), arg(arg) {}
1940 
1941  R operator()(A0 a0, A1 a1) const
1942  {
1943  return func(arg, a0, a1);
1944  }
1945  };
1946 };
1947 
1948 /** Callback class based on template specialization
1949  *
1950  * @note Synchronization level: Not protected
1951  */
1952 template <typename R, typename A0, typename A1, typename A2>
1953 class Callback<R(A0, A1, A2)> {
1954 public:
1955  /** Create a Callback with a static function
1956  * @param func Static function to attach
1957  */
1958  Callback(R(*func)(A0, A1, A2) = 0)
1959  {
1960  if (!func) {
1961  memset(this, 0, sizeof(Callback));
1962  } else {
1963  generate(func);
1964  }
1965  }
1966 
1967  /** Attach a Callback
1968  * @param func The Callback to attach
1969  */
1970  Callback(const Callback<R(A0, A1, A2)> &func)
1971  {
1972  if (func._ops) {
1973  func._ops->move(this, &func);
1974  }
1975  _ops = func._ops;
1976  }
1977 
1978  /** Create a Callback with a member function
1979  * @param obj Pointer to object to invoke member function on
1980  * @param method Member function to attach
1981  */
1982  template<typename T, typename U>
1983  Callback(U *obj, R(T::*method)(A0, A1, A2))
1984  {
1985  generate(method_context<T, R(T::*)(A0, A1, A2)>(obj, method));
1986  }
1987 
1988  /** Create a Callback with a member function
1989  * @param obj Pointer to object to invoke member function on
1990  * @param method Member function to attach
1991  */
1992  template<typename T, typename U>
1993  Callback(const U *obj, R(T::*method)(A0, A1, A2) const)
1994  {
1995  generate(method_context<const T, R(T::*)(A0, A1, A2) const>(obj, method));
1996  }
1997 
1998  /** Create a Callback with a member function
1999  * @param obj Pointer to object to invoke member function on
2000  * @param method Member function to attach
2001  */
2002  template<typename T, typename U>
2003  Callback(volatile U *obj, R(T::*method)(A0, A1, A2) volatile)
2004  {
2005  generate(method_context<volatile T, R(T::*)(A0, A1, A2) volatile>(obj, method));
2006  }
2007 
2008  /** Create a Callback with a member function
2009  * @param obj Pointer to object to invoke member function on
2010  * @param method Member function to attach
2011  */
2012  template<typename T, typename U>
2013  Callback(const volatile U *obj, R(T::*method)(A0, A1, A2) const volatile)
2014  {
2015  generate(method_context<const volatile T, R(T::*)(A0, A1, A2) const volatile>(obj, method));
2016  }
2017 
2018  /** Create a Callback with a static function and bound pointer
2019  * @param func Static function to attach
2020  * @param arg Pointer argument to function
2021  */
2022  template<typename T, typename U>
2023  Callback(R(*func)(T *, A0, A1, A2), U *arg)
2024  {
2025  generate(function_context<R(*)(T *, A0, A1, A2), T>(func, arg));
2026  }
2027 
2028  /** Create a Callback with a static function and bound pointer
2029  * @param func Static function to attach
2030  * @param arg Pointer argument to function
2031  */
2032  template<typename T, typename U>
2033  Callback(R(*func)(const T *, A0, A1, A2), const U *arg)
2034  {
2035  generate(function_context<R(*)(const T *, A0, A1, A2), const T>(func, arg));
2036  }
2037 
2038  /** Create a Callback with a static function and bound pointer
2039  * @param func Static function to attach
2040  * @param arg Pointer argument to function
2041  */
2042  template<typename T, typename U>
2043  Callback(R(*func)(volatile T *, A0, A1, A2), volatile U *arg)
2044  {
2045  generate(function_context<R(*)(volatile T *, A0, A1, A2), volatile T>(func, arg));
2046  }
2047 
2048  /** Create a Callback with a static function and bound pointer
2049  * @param func Static function to attach
2050  * @param arg Pointer argument to function
2051  */
2052  template<typename T, typename U>
2053  Callback(R(*func)(const volatile T *, A0, A1, A2), const volatile U *arg)
2054  {
2055  generate(function_context<R(*)(const volatile T *, A0, A1, A2), const volatile T>(func, arg));
2056  }
2057 
2058  /** Create a Callback with a function object
2059  * @param f Function object to attach
2060  * @note The function object is limited to a single word of storage
2061  */
2062  template <typename F>
2063  Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2)))
2064  {
2065  generate(f);
2066  }
2067 
2068  /** Create a Callback with a function object
2069  * @param f Function object to attach
2070  * @note The function object is limited to a single word of storage
2071  */
2072  template <typename F>
2073  Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2) const))
2074  {
2075  generate(f);
2076  }
2077 
2078  /** Create a Callback with a function object
2079  * @param f Function object to attach
2080  * @note The function object is limited to a single word of storage
2081  */
2082  template <typename F>
2083  Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2) volatile))
2084  {
2085  generate(f);
2086  }
2087 
2088  /** Create a Callback with a function object
2089  * @param f Function object to attach
2090  * @note The function object is limited to a single word of storage
2091  */
2092  template <typename F>
2093  Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2) const volatile))
2094  {
2095  generate(f);
2096  }
2097 
2098  /** Create a Callback with a static function and bound pointer
2099  * @param obj Pointer to object to bind to function
2100  * @param func Static function to attach
2101  * @deprecated
2102  * Arguments to callback have been reordered to Callback(func, arg)
2103  */
2104  template<typename T, typename U>
2105  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2106  "Arguments to callback have been reordered to Callback(func, arg)")
2107  Callback(U *obj, R(*func)(T *, A0, A1, A2))
2108  {
2109  new (this) Callback(func, obj);
2110  }
2111 
2112  /** Create a Callback with a static function and bound pointer
2113  * @param obj Pointer to object to bind to function
2114  * @param func Static function to attach
2115  * @deprecated
2116  * Arguments to callback have been reordered to Callback(func, arg)
2117  */
2118  template<typename T, typename U>
2119  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2120  "Arguments to callback have been reordered to Callback(func, arg)")
2121  Callback(const U *obj, R(*func)(const T *, A0, A1, A2))
2122  {
2123  new (this) Callback(func, obj);
2124  }
2125 
2126  /** Create a Callback with a static function and bound pointer
2127  * @param obj Pointer to object to bind to function
2128  * @param func Static function to attach
2129  * @deprecated
2130  * Arguments to callback have been reordered to Callback(func, arg)
2131  */
2132  template<typename T, typename U>
2133  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2134  "Arguments to callback have been reordered to Callback(func, arg)")
2135  Callback(volatile U *obj, R(*func)(volatile T *, A0, A1, A2))
2136  {
2137  new (this) Callback(func, obj);
2138  }
2139 
2140  /** Create a Callback with a static function and bound pointer
2141  * @param obj Pointer to object to bind to function
2142  * @param func Static function to attach
2143  * @deprecated
2144  * Arguments to callback have been reordered to Callback(func, arg)
2145  */
2146  template<typename T, typename U>
2147  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2148  "Arguments to callback have been reordered to Callback(func, arg)")
2149  Callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2))
2150  {
2151  new (this) Callback(func, obj);
2152  }
2153 
2154  /** Destroy a callback
2155  */
2157  {
2158  if (_ops) {
2159  _ops->dtor(this);
2160  }
2161  }
2162 
2163  /** Attach a static function
2164  * @param func Static function to attach
2165  * @deprecated
2166  * Replaced by simple assignment 'Callback cb = func'
2167  */
2168  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2169  "Replaced by simple assignment 'Callback cb = func")
2170  void attach(R(*func)(A0, A1, A2))
2171  {
2172  this->~Callback();
2173  new (this) Callback(func);
2174  }
2175 
2176  /** Attach a Callback
2177  * @param func The Callback to attach
2178  * @deprecated
2179  * Replaced by simple assignment 'Callback cb = func'
2180  */
2181  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2182  "Replaced by simple assignment 'Callback cb = func")
2183  void attach(const Callback<R(A0, A1, A2)> &func)
2184  {
2185  this->~Callback();
2186  new (this) Callback(func);
2187  }
2188 
2189  /** Attach a member function
2190  * @param obj Pointer to object to invoke member function on
2191  * @param method Member function to attach
2192  * @deprecated
2193  * Replaced by simple assignment 'Callback cb = func'
2194  */
2195  template<typename T, typename U>
2196  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2197  "Replaced by simple assignment 'Callback cb = func")
2198  void attach(U *obj, R(T::*method)(A0, A1, A2))
2199  {
2200  this->~Callback();
2201  new (this) Callback(obj, method);
2202  }
2203 
2204  /** Attach a member function
2205  * @param obj Pointer to object to invoke member function on
2206  * @param method Member function to attach
2207  * @deprecated
2208  * Replaced by simple assignment 'Callback cb = func'
2209  */
2210  template<typename T, typename U>
2211  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2212  "Replaced by simple assignment 'Callback cb = func")
2213  void attach(const U *obj, R(T::*method)(A0, A1, A2) const)
2214  {
2215  this->~Callback();
2216  new (this) Callback(obj, method);
2217  }
2218 
2219  /** Attach a member function
2220  * @param obj Pointer to object to invoke member function on
2221  * @param method Member function to attach
2222  * @deprecated
2223  * Replaced by simple assignment 'Callback cb = func'
2224  */
2225  template<typename T, typename U>
2226  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2227  "Replaced by simple assignment 'Callback cb = func")
2228  void attach(volatile U *obj, R(T::*method)(A0, A1, A2) volatile)
2229  {
2230  this->~Callback();
2231  new (this) Callback(obj, method);
2232  }
2233 
2234  /** Attach a member function
2235  * @param obj Pointer to object to invoke member function on
2236  * @param method Member function to attach
2237  * @deprecated
2238  * Replaced by simple assignment 'Callback cb = func'
2239  */
2240  template<typename T, typename U>
2241  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2242  "Replaced by simple assignment 'Callback cb = func")
2243  void attach(const volatile U *obj, R(T::*method)(A0, A1, A2) const volatile)
2244  {
2245  this->~Callback();
2246  new (this) Callback(obj, method);
2247  }
2248 
2249  /** Attach a static function with a bound pointer
2250  * @param func Static function to attach
2251  * @param arg Pointer argument to function
2252  * @deprecated
2253  * Replaced by simple assignment 'Callback cb = func'
2254  */
2255  template <typename T, typename U>
2256  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2257  "Replaced by simple assignment 'Callback cb = func")
2258  void attach(R(*func)(T *, A0, A1, A2), U *arg)
2259  {
2260  this->~Callback();
2261  new (this) Callback(func, arg);
2262  }
2263 
2264  /** Attach a static function with a bound pointer
2265  * @param func Static function to attach
2266  * @param arg Pointer argument to function
2267  * @deprecated
2268  * Replaced by simple assignment 'Callback cb = func'
2269  */
2270  template <typename T, typename U>
2271  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2272  "Replaced by simple assignment 'Callback cb = func")
2273  void attach(R(*func)(const T *, A0, A1, A2), const U *arg)
2274  {
2275  this->~Callback();
2276  new (this) Callback(func, arg);
2277  }
2278 
2279  /** Attach a static function with a bound pointer
2280  * @param func Static function to attach
2281  * @param arg Pointer argument to function
2282  * @deprecated
2283  * Replaced by simple assignment 'Callback cb = func'
2284  */
2285  template <typename T, typename U>
2286  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2287  "Replaced by simple assignment 'Callback cb = func")
2288  void attach(R(*func)(volatile T *, A0, A1, A2), volatile U *arg)
2289  {
2290  this->~Callback();
2291  new (this) Callback(func, arg);
2292  }
2293 
2294  /** Attach a static function with a bound pointer
2295  * @param func Static function to attach
2296  * @param arg Pointer argument to function
2297  * @deprecated
2298  * Replaced by simple assignment 'Callback cb = func'
2299  */
2300  template <typename T, typename U>
2301  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2302  "Replaced by simple assignment 'Callback cb = func")
2303  void attach(R(*func)(const volatile T *, A0, A1, A2), const volatile U *arg)
2304  {
2305  this->~Callback();
2306  new (this) Callback(func, arg);
2307  }
2308 
2309  /** Attach a function object
2310  * @param f Function object to attach
2311  * @note The function object is limited to a single word of storage
2312  * @deprecated
2313  * Replaced by simple assignment 'Callback cb = func'
2314  */
2315  template <typename F>
2316  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2317  "Replaced by simple assignment 'Callback cb = func")
2318  void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2)))
2319  {
2320  this->~Callback();
2321  new (this) Callback(f);
2322  }
2323 
2324  /** Attach a function object
2325  * @param f Function object to attach
2326  * @note The function object is limited to a single word of storage
2327  * @deprecated
2328  * Replaced by simple assignment 'Callback cb = func'
2329  */
2330  template <typename F>
2331  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2332  "Replaced by simple assignment 'Callback cb = func")
2333  void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2) const))
2334  {
2335  this->~Callback();
2336  new (this) Callback(f);
2337  }
2338 
2339  /** Attach a function object
2340  * @param f Function object to attach
2341  * @note The function object is limited to a single word of storage
2342  * @deprecated
2343  * Replaced by simple assignment 'Callback cb = func'
2344  */
2345  template <typename F>
2346  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2347  "Replaced by simple assignment 'Callback cb = func")
2348  void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2) volatile))
2349  {
2350  this->~Callback();
2351  new (this) Callback(f);
2352  }
2353 
2354  /** Attach a function object
2355  * @param f Function object to attach
2356  * @note The function object is limited to a single word of storage
2357  * @deprecated
2358  * Replaced by simple assignment 'Callback cb = func'
2359  */
2360  template <typename F>
2361  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2362  "Replaced by simple assignment 'Callback cb = func")
2363  void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2) const volatile))
2364  {
2365  this->~Callback();
2366  new (this) Callback(f);
2367  }
2368 
2369  /** Attach a static function with a bound pointer
2370  * @param obj Pointer to object to bind to function
2371  * @param func Static function to attach
2372  * @deprecated
2373  * Arguments to callback have been reordered to attach(func, arg)
2374  */
2375  template <typename T, typename U>
2376  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2377  "Arguments to callback have been reordered to attach(func, arg)")
2378  void attach(U *obj, R(*func)(T *, A0, A1, A2))
2379  {
2380  this->~Callback();
2381  new (this) Callback(func, obj);
2382  }
2383 
2384  /** Attach a static function with a bound pointer
2385  * @param obj Pointer to object to bind to function
2386  * @param func Static function to attach
2387  * @deprecated
2388  * Arguments to callback have been reordered to attach(func, arg)
2389  */
2390  template <typename T, typename U>
2391  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2392  "Arguments to callback have been reordered to attach(func, arg)")
2393  void attach(const U *obj, R(*func)(const T *, A0, A1, A2))
2394  {
2395  this->~Callback();
2396  new (this) Callback(func, obj);
2397  }
2398 
2399  /** Attach a static function with a bound pointer
2400  * @param obj Pointer to object to bind to function
2401  * @param func Static function to attach
2402  * @deprecated
2403  * Arguments to callback have been reordered to attach(func, arg)
2404  */
2405  template <typename T, typename U>
2406  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2407  "Arguments to callback have been reordered to attach(func, arg)")
2408  void attach(volatile U *obj, R(*func)(volatile T *, A0, A1, A2))
2409  {
2410  this->~Callback();
2411  new (this) Callback(func, obj);
2412  }
2413 
2414  /** Attach a static function with a bound pointer
2415  * @param obj Pointer to object to bind to function
2416  * @param func Static function to attach
2417  * @deprecated
2418  * Arguments to callback have been reordered to attach(func, arg)
2419  */
2420  template <typename T, typename U>
2421  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2422  "Arguments to callback have been reordered to attach(func, arg)")
2423  void attach(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2))
2424  {
2425  this->~Callback();
2426  new (this) Callback(func, obj);
2427  }
2428 
2429  /** Assign a callback
2430  */
2432  {
2433  if (this != &that) {
2434  this->~Callback();
2435  new (this) Callback(that);
2436  }
2437 
2438  return *this;
2439  }
2440 
2441  /** Call the attached function
2442  */
2443  R call(A0 a0, A1 a1, A2 a2) const
2444  {
2445  MBED_ASSERT(_ops);
2446  return _ops->call(this, a0, a1, a2);
2447  }
2448 
2449  /** Call the attached function
2450  */
2451  R operator()(A0 a0, A1 a1, A2 a2) const
2452  {
2453  return call(a0, a1, a2);
2454  }
2455 
2456  /** Test if function has been attached
2457  */
2458  operator bool() const
2459  {
2460  return _ops;
2461  }
2462 
2463  /** Test for equality
2464  */
2465  friend bool operator==(const Callback &l, const Callback &r)
2466  {
2467  return memcmp(&l, &r, sizeof(Callback)) == 0;
2468  }
2469 
2470  /** Test for inequality
2471  */
2472  friend bool operator!=(const Callback &l, const Callback &r)
2473  {
2474  return !(l == r);
2475  }
2476 
2477  /** Static thunk for passing as C-style function
2478  * @param func Callback to call passed as void pointer
2479  * @param a0 An argument to be called with function func
2480  * @param a1 An argument to be called with function func
2481  * @param a2 An argument to be called with function func
2482  * @return the value as determined by func which is of
2483  * type and determined by the signature of func
2484  */
2485  static R thunk(void *func, A0 a0, A1 a1, A2 a2)
2486  {
2487  return static_cast<Callback *>(func)->call(a0, a1, a2);
2488  }
2489 
2490 private:
2491  // Stored as pointer to function and pointer to optional object
2492  // Function pointer is stored as union of possible function types
2493  // to guarantee proper size and alignment
2494  struct _class;
2495  union {
2496  void (*_staticfunc)(A0, A1, A2);
2497  void (*_boundfunc)(_class *, A0, A1, A2);
2498  void (_class::*_methodfunc)(A0, A1, A2);
2499  } _func;
2500  void *_obj;
2501 
2502  // Dynamically dispatched operations
2503  const struct ops {
2504  R(*call)(const void *, A0, A1, A2);
2505  void (*move)(void *, const void *);
2506  void (*dtor)(void *);
2507  } *_ops;
2508 
2509  // Generate operations for function object
2510  template <typename F>
2511  void generate(const F &f)
2512  {
2513  static const ops ops = {
2514  &Callback::function_call<F>,
2515  &Callback::function_move<F>,
2516  &Callback::function_dtor<F>,
2517  };
2518 
2519  MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
2520  "Type F must not exceed the size of the Callback class");
2521  memset(this, 0, sizeof(Callback));
2522  new (this) F(f);
2523  _ops = &ops;
2524  }
2525 
2526  // Function attributes
2527  template <typename F>
2528  static R function_call(const void *p, A0 a0, A1 a1, A2 a2)
2529  {
2530  return (*(F *)p)(a0, a1, a2);
2531  }
2532 
2533  template <typename F>
2534  static void function_move(void *d, const void *p)
2535  {
2536  new (d) F(*(F *)p);
2537  }
2538 
2539  template <typename F>
2540  static void function_dtor(void *p)
2541  {
2542  ((F *)p)->~F();
2543  }
2544 
2545  // Wrappers for functions with context
2546  template <typename O, typename M>
2547  struct method_context {
2548  M method;
2549  O *obj;
2550 
2551  method_context(O *obj, M method)
2552  : method(method), obj(obj) {}
2553 
2554  R operator()(A0 a0, A1 a1, A2 a2) const
2555  {
2556  return (obj->*method)(a0, a1, a2);
2557  }
2558  };
2559 
2560  template <typename F, typename A>
2561  struct function_context {
2562  F func;
2563  A *arg;
2564 
2565  function_context(F func, A *arg)
2566  : func(func), arg(arg) {}
2567 
2568  R operator()(A0 a0, A1 a1, A2 a2) const
2569  {
2570  return func(arg, a0, a1, a2);
2571  }
2572  };
2573 };
2574 
2575 /** Callback class based on template specialization
2576  *
2577  * @note Synchronization level: Not protected
2578  */
2579 template <typename R, typename A0, typename A1, typename A2, typename A3>
2580 class Callback<R(A0, A1, A2, A3)> {
2581 public:
2582  /** Create a Callback with a static function
2583  * @param func Static function to attach
2584  */
2585  Callback(R(*func)(A0, A1, A2, A3) = 0)
2586  {
2587  if (!func) {
2588  memset(this, 0, sizeof(Callback));
2589  } else {
2590  generate(func);
2591  }
2592  }
2593 
2594  /** Attach a Callback
2595  * @param func The Callback to attach
2596  */
2597  Callback(const Callback<R(A0, A1, A2, A3)> &func)
2598  {
2599  if (func._ops) {
2600  func._ops->move(this, &func);
2601  }
2602  _ops = func._ops;
2603  }
2604 
2605  /** Create a Callback with a member function
2606  * @param obj Pointer to object to invoke member function on
2607  * @param method Member function to attach
2608  */
2609  template<typename T, typename U>
2610  Callback(U *obj, R(T::*method)(A0, A1, A2, A3))
2611  {
2612  generate(method_context<T, R(T::*)(A0, A1, A2, A3)>(obj, method));
2613  }
2614 
2615  /** Create a Callback with a member function
2616  * @param obj Pointer to object to invoke member function on
2617  * @param method Member function to attach
2618  */
2619  template<typename T, typename U>
2620  Callback(const U *obj, R(T::*method)(A0, A1, A2, A3) const)
2621  {
2622  generate(method_context<const T, R(T::*)(A0, A1, A2, A3) const>(obj, method));
2623  }
2624 
2625  /** Create a Callback with a member function
2626  * @param obj Pointer to object to invoke member function on
2627  * @param method Member function to attach
2628  */
2629  template<typename T, typename U>
2630  Callback(volatile U *obj, R(T::*method)(A0, A1, A2, A3) volatile)
2631  {
2632  generate(method_context<volatile T, R(T::*)(A0, A1, A2, A3) volatile>(obj, method));
2633  }
2634 
2635  /** Create a Callback with a member function
2636  * @param obj Pointer to object to invoke member function on
2637  * @param method Member function to attach
2638  */
2639  template<typename T, typename U>
2640  Callback(const volatile U *obj, R(T::*method)(A0, A1, A2, A3) const volatile)
2641  {
2642  generate(method_context<const volatile T, R(T::*)(A0, A1, A2, A3) const volatile>(obj, method));
2643  }
2644 
2645  /** Create a Callback with a static function and bound pointer
2646  * @param func Static function to attach
2647  * @param arg Pointer argument to function
2648  */
2649  template<typename T, typename U>
2650  Callback(R(*func)(T *, A0, A1, A2, A3), U *arg)
2651  {
2652  generate(function_context<R(*)(T *, A0, A1, A2, A3), T>(func, arg));
2653  }
2654 
2655  /** Create a Callback with a static function and bound pointer
2656  * @param func Static function to attach
2657  * @param arg Pointer argument to function
2658  */
2659  template<typename T, typename U>
2660  Callback(R(*func)(const T *, A0, A1, A2, A3), const U *arg)
2661  {
2662  generate(function_context<R(*)(const T *, A0, A1, A2, A3), const T>(func, arg));
2663  }
2664 
2665  /** Create a Callback with a static function and bound pointer
2666  * @param func Static function to attach
2667  * @param arg Pointer argument to function
2668  */
2669  template<typename T, typename U>
2670  Callback(R(*func)(volatile T *, A0, A1, A2, A3), volatile U *arg)
2671  {
2672  generate(function_context<R(*)(volatile T *, A0, A1, A2, A3), volatile T>(func, arg));
2673  }
2674 
2675  /** Create a Callback with a static function and bound pointer
2676  * @param func Static function to attach
2677  * @param arg Pointer argument to function
2678  */
2679  template<typename T, typename U>
2680  Callback(R(*func)(const volatile T *, A0, A1, A2, A3), const volatile U *arg)
2681  {
2682  generate(function_context<R(*)(const volatile T *, A0, A1, A2, A3), const volatile T>(func, arg));
2683  }
2684 
2685  /** Create a Callback with a function object
2686  * @param f Function object to attach
2687  * @note The function object is limited to a single word of storage
2688  */
2689  template <typename F>
2690  Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3)))
2691  {
2692  generate(f);
2693  }
2694 
2695  /** Create a Callback with a function object
2696  * @param f Function object to attach
2697  * @note The function object is limited to a single word of storage
2698  */
2699  template <typename F>
2700  Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3) const))
2701  {
2702  generate(f);
2703  }
2704 
2705  /** Create a Callback with a function object
2706  * @param f Function object to attach
2707  * @note The function object is limited to a single word of storage
2708  */
2709  template <typename F>
2710  Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3) volatile))
2711  {
2712  generate(f);
2713  }
2714 
2715  /** Create a Callback with a function object
2716  * @param f Function object to attach
2717  * @note The function object is limited to a single word of storage
2718  */
2719  template <typename F>
2720  Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3) const volatile))
2721  {
2722  generate(f);
2723  }
2724 
2725  /** Create a Callback with a static function and bound pointer
2726  * @param obj Pointer to object to bind to function
2727  * @param func Static function to attach
2728  * @deprecated
2729  * Arguments to callback have been reordered to Callback(func, arg)
2730  */
2731  template<typename T, typename U>
2732  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2733  "Arguments to callback have been reordered to Callback(func, arg)")
2734  Callback(U *obj, R(*func)(T *, A0, A1, A2, A3))
2735  {
2736  new (this) Callback(func, obj);
2737  }
2738 
2739  /** Create a Callback with a static function and bound pointer
2740  * @param obj Pointer to object to bind to function
2741  * @param func Static function to attach
2742  * @deprecated
2743  * Arguments to callback have been reordered to Callback(func, arg)
2744  */
2745  template<typename T, typename U>
2746  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2747  "Arguments to callback have been reordered to Callback(func, arg)")
2748  Callback(const U *obj, R(*func)(const T *, A0, A1, A2, A3))
2749  {
2750  new (this) Callback(func, obj);
2751  }
2752 
2753  /** Create a Callback with a static function and bound pointer
2754  * @param obj Pointer to object to bind to function
2755  * @param func Static function to attach
2756  * @deprecated
2757  * Arguments to callback have been reordered to Callback(func, arg)
2758  */
2759  template<typename T, typename U>
2760  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2761  "Arguments to callback have been reordered to Callback(func, arg)")
2762  Callback(volatile U *obj, R(*func)(volatile T *, A0, A1, A2, A3))
2763  {
2764  new (this) Callback(func, obj);
2765  }
2766 
2767  /** Create a Callback with a static function and bound pointer
2768  * @param obj Pointer to object to bind to function
2769  * @param func Static function to attach
2770  * @deprecated
2771  * Arguments to callback have been reordered to Callback(func, arg)
2772  */
2773  template<typename T, typename U>
2774  MBED_DEPRECATED_SINCE("mbed-os-5.1",
2775  "Arguments to callback have been reordered to Callback(func, arg)")
2776  Callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3))
2777  {
2778  new (this) Callback(func, obj);
2779  }
2780 
2781  /** Destroy a callback
2782  */
2784  {
2785  if (_ops) {
2786  _ops->dtor(this);
2787  }
2788  }
2789 
2790  /** Attach a static function
2791  * @param func Static function to attach
2792  * @deprecated
2793  * Replaced by simple assignment 'Callback cb = func'
2794  */
2795  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2796  "Replaced by simple assignment 'Callback cb = func")
2797  void attach(R(*func)(A0, A1, A2, A3))
2798  {
2799  this->~Callback();
2800  new (this) Callback(func);
2801  }
2802 
2803  /** Attach a Callback
2804  * @param func The Callback to attach
2805  * @deprecated
2806  * Replaced by simple assignment 'Callback cb = func'
2807  */
2808  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2809  "Replaced by simple assignment 'Callback cb = func")
2810  void attach(const Callback<R(A0, A1, A2, A3)> &func)
2811  {
2812  this->~Callback();
2813  new (this) Callback(func);
2814  }
2815 
2816  /** Attach a member function
2817  * @param obj Pointer to object to invoke member function on
2818  * @param method Member function to attach
2819  * @deprecated
2820  * Replaced by simple assignment 'Callback cb = func'
2821  */
2822  template<typename T, typename U>
2823  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2824  "Replaced by simple assignment 'Callback cb = func")
2825  void attach(U *obj, R(T::*method)(A0, A1, A2, A3))
2826  {
2827  this->~Callback();
2828  new (this) Callback(obj, method);
2829  }
2830 
2831  /** Attach a member function
2832  * @param obj Pointer to object to invoke member function on
2833  * @param method Member function to attach
2834  * @deprecated
2835  * Replaced by simple assignment 'Callback cb = func'
2836  */
2837  template<typename T, typename U>
2838  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2839  "Replaced by simple assignment 'Callback cb = func")
2840  void attach(const U *obj, R(T::*method)(A0, A1, A2, A3) const)
2841  {
2842  this->~Callback();
2843  new (this) Callback(obj, method);
2844  }
2845 
2846  /** Attach a member function
2847  * @param obj Pointer to object to invoke member function on
2848  * @param method Member function to attach
2849  * @deprecated
2850  * Replaced by simple assignment 'Callback cb = func'
2851  */
2852  template<typename T, typename U>
2853  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2854  "Replaced by simple assignment 'Callback cb = func")
2855  void attach(volatile U *obj, R(T::*method)(A0, A1, A2, A3) volatile)
2856  {
2857  this->~Callback();
2858  new (this) Callback(obj, method);
2859  }
2860 
2861  /** Attach a member function
2862  * @param obj Pointer to object to invoke member function on
2863  * @param method Member function to attach
2864  * @deprecated
2865  * Replaced by simple assignment 'Callback cb = func'
2866  */
2867  template<typename T, typename U>
2868  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2869  "Replaced by simple assignment 'Callback cb = func")
2870  void attach(const volatile U *obj, R(T::*method)(A0, A1, A2, A3) const volatile)
2871  {
2872  this->~Callback();
2873  new (this) Callback(obj, method);
2874  }
2875 
2876  /** Attach a static function with a bound pointer
2877  * @param func Static function to attach
2878  * @param arg Pointer argument to function
2879  * @deprecated
2880  * Replaced by simple assignment 'Callback cb = func'
2881  */
2882  template <typename T, typename U>
2883  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2884  "Replaced by simple assignment 'Callback cb = func")
2885  void attach(R(*func)(T *, A0, A1, A2, A3), U *arg)
2886  {
2887  this->~Callback();
2888  new (this) Callback(func, arg);
2889  }
2890 
2891  /** Attach a static function with a bound pointer
2892  * @param func Static function to attach
2893  * @param arg Pointer argument to function
2894  * @deprecated
2895  * Replaced by simple assignment 'Callback cb = func'
2896  */
2897  template <typename T, typename U>
2898  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2899  "Replaced by simple assignment 'Callback cb = func")
2900  void attach(R(*func)(const T *, A0, A1, A2, A3), const U *arg)
2901  {
2902  this->~Callback();
2903  new (this) Callback(func, arg);
2904  }
2905 
2906  /** Attach a static function with a bound pointer
2907  * @param func Static function to attach
2908  * @param arg Pointer argument to function
2909  * @deprecated
2910  * Replaced by simple assignment 'Callback cb = func'
2911  */
2912  template <typename T, typename U>
2913  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2914  "Replaced by simple assignment 'Callback cb = func")
2915  void attach(R(*func)(volatile T *, A0, A1, A2, A3), volatile U *arg)
2916  {
2917  this->~Callback();
2918  new (this) Callback(func, arg);
2919  }
2920 
2921  /** Attach a static function with a bound pointer
2922  * @param func Static function to attach
2923  * @param arg Pointer argument to function
2924  * @deprecated
2925  * Replaced by simple assignment 'Callback cb = func'
2926  */
2927  template <typename T, typename U>
2928  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2929  "Replaced by simple assignment 'Callback cb = func")
2930  void attach(R(*func)(const volatile T *, A0, A1, A2, A3), const volatile U *arg)
2931  {
2932  this->~Callback();
2933  new (this) Callback(func, arg);
2934  }
2935 
2936  /** Attach a function object
2937  * @param f Function object to attach
2938  * @note The function object is limited to a single word of storage
2939  * @deprecated
2940  * Replaced by simple assignment 'Callback cb = func'
2941  */
2942  template <typename F>
2943  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2944  "Replaced by simple assignment 'Callback cb = func")
2945  void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3)))
2946  {
2947  this->~Callback();
2948  new (this) Callback(f);
2949  }
2950 
2951  /** Attach a function object
2952  * @param f Function object to attach
2953  * @note The function object is limited to a single word of storage
2954  * @deprecated
2955  * Replaced by simple assignment 'Callback cb = func'
2956  */
2957  template <typename F>
2958  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2959  "Replaced by simple assignment 'Callback cb = func")
2960  void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3) const))
2961  {
2962  this->~Callback();
2963  new (this) Callback(f);
2964  }
2965 
2966  /** Attach a function object
2967  * @param f Function object to attach
2968  * @note The function object is limited to a single word of storage
2969  * @deprecated
2970  * Replaced by simple assignment 'Callback cb = func'
2971  */
2972  template <typename F>
2973  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2974  "Replaced by simple assignment 'Callback cb = func")
2975  void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3) volatile))
2976  {
2977  this->~Callback();
2978  new (this) Callback(f);
2979  }
2980 
2981  /** Attach a function object
2982  * @param f Function object to attach
2983  * @note The function object is limited to a single word of storage
2984  * @deprecated
2985  * Replaced by simple assignment 'Callback cb = func'
2986  */
2987  template <typename F>
2988  MBED_DEPRECATED_SINCE("mbed-os-5.4",
2989  "Replaced by simple assignment 'Callback cb = func")
2990  void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3) const volatile))
2991  {
2992  this->~Callback();
2993  new (this) Callback(f);
2994  }
2995 
2996  /** Attach a static function with a bound pointer
2997  * @param obj Pointer to object to bind to function
2998  * @param func Static function to attach
2999  * @deprecated
3000  * Arguments to callback have been reordered to attach(func, arg)
3001  */
3002  template <typename T, typename U>
3003  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3004  "Arguments to callback have been reordered to attach(func, arg)")
3005  void attach(U *obj, R(*func)(T *, A0, A1, A2, A3))
3006  {
3007  this->~Callback();
3008  new (this) Callback(func, obj);
3009  }
3010 
3011  /** Attach a static function with a bound pointer
3012  * @param obj Pointer to object to bind to function
3013  * @param func Static function to attach
3014  * @deprecated
3015  * Arguments to callback have been reordered to attach(func, arg)
3016  */
3017  template <typename T, typename U>
3018  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3019  "Arguments to callback have been reordered to attach(func, arg)")
3020  void attach(const U *obj, R(*func)(const T *, A0, A1, A2, A3))
3021  {
3022  this->~Callback();
3023  new (this) Callback(func, obj);
3024  }
3025 
3026  /** Attach a static function with a bound pointer
3027  * @param obj Pointer to object to bind to function
3028  * @param func Static function to attach
3029  * @deprecated
3030  * Arguments to callback have been reordered to attach(func, arg)
3031  */
3032  template <typename T, typename U>
3033  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3034  "Arguments to callback have been reordered to attach(func, arg)")
3035  void attach(volatile U *obj, R(*func)(volatile T *, A0, A1, A2, A3))
3036  {
3037  this->~Callback();
3038  new (this) Callback(func, obj);
3039  }
3040 
3041  /** Attach a static function with a bound pointer
3042  * @param obj Pointer to object to bind to function
3043  * @param func Static function to attach
3044  * @deprecated
3045  * Arguments to callback have been reordered to attach(func, arg)
3046  */
3047  template <typename T, typename U>
3048  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3049  "Arguments to callback have been reordered to attach(func, arg)")
3050  void attach(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3))
3051  {
3052  this->~Callback();
3053  new (this) Callback(func, obj);
3054  }
3055 
3056  /** Assign a callback
3057  */
3059  {
3060  if (this != &that) {
3061  this->~Callback();
3062  new (this) Callback(that);
3063  }
3064 
3065  return *this;
3066  }
3067 
3068  /** Call the attached function
3069  */
3070  R call(A0 a0, A1 a1, A2 a2, A3 a3) const
3071  {
3072  MBED_ASSERT(_ops);
3073  return _ops->call(this, a0, a1, a2, a3);
3074  }
3075 
3076  /** Call the attached function
3077  */
3078  R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const
3079  {
3080  return call(a0, a1, a2, a3);
3081  }
3082 
3083  /** Test if function has been attached
3084  */
3085  operator bool() const
3086  {
3087  return _ops;
3088  }
3089 
3090  /** Test for equality
3091  */
3092  friend bool operator==(const Callback &l, const Callback &r)
3093  {
3094  return memcmp(&l, &r, sizeof(Callback)) == 0;
3095  }
3096 
3097  /** Test for inequality
3098  */
3099  friend bool operator!=(const Callback &l, const Callback &r)
3100  {
3101  return !(l == r);
3102  }
3103 
3104  /** Static thunk for passing as C-style function
3105  * @param func Callback to call passed as void pointer
3106  * @param a0 An argument to be called with function func
3107  * @param a1 An argument to be called with function func
3108  * @param a2 An argument to be called with function func
3109  * @param a3 An argument to be called with function func
3110  * @return the value as determined by func which is of
3111  * type and determined by the signature of func
3112  */
3113  static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3)
3114  {
3115  return static_cast<Callback *>(func)->call(a0, a1, a2, a3);
3116  }
3117 
3118 private:
3119  // Stored as pointer to function and pointer to optional object
3120  // Function pointer is stored as union of possible function types
3121  // to guarantee proper size and alignment
3122  struct _class;
3123  union {
3124  void (*_staticfunc)(A0, A1, A2, A3);
3125  void (*_boundfunc)(_class *, A0, A1, A2, A3);
3126  void (_class::*_methodfunc)(A0, A1, A2, A3);
3127  } _func;
3128  void *_obj;
3129 
3130  // Dynamically dispatched operations
3131  const struct ops {
3132  R(*call)(const void *, A0, A1, A2, A3);
3133  void (*move)(void *, const void *);
3134  void (*dtor)(void *);
3135  } *_ops;
3136 
3137  // Generate operations for function object
3138  template <typename F>
3139  void generate(const F &f)
3140  {
3141  static const ops ops = {
3142  &Callback::function_call<F>,
3143  &Callback::function_move<F>,
3144  &Callback::function_dtor<F>,
3145  };
3146 
3147  MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
3148  "Type F must not exceed the size of the Callback class");
3149  memset(this, 0, sizeof(Callback));
3150  new (this) F(f);
3151  _ops = &ops;
3152  }
3153 
3154  // Function attributes
3155  template <typename F>
3156  static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3)
3157  {
3158  return (*(F *)p)(a0, a1, a2, a3);
3159  }
3160 
3161  template <typename F>
3162  static void function_move(void *d, const void *p)
3163  {
3164  new (d) F(*(F *)p);
3165  }
3166 
3167  template <typename F>
3168  static void function_dtor(void *p)
3169  {
3170  ((F *)p)->~F();
3171  }
3172 
3173  // Wrappers for functions with context
3174  template <typename O, typename M>
3175  struct method_context {
3176  M method;
3177  O *obj;
3178 
3179  method_context(O *obj, M method)
3180  : method(method), obj(obj) {}
3181 
3182  R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const
3183  {
3184  return (obj->*method)(a0, a1, a2, a3);
3185  }
3186  };
3187 
3188  template <typename F, typename A>
3189  struct function_context {
3190  F func;
3191  A *arg;
3192 
3193  function_context(F func, A *arg)
3194  : func(func), arg(arg) {}
3195 
3196  R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const
3197  {
3198  return func(arg, a0, a1, a2, a3);
3199  }
3200  };
3201 };
3202 
3203 /** Callback class based on template specialization
3204  *
3205  * @note Synchronization level: Not protected
3206  */
3207 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
3208 class Callback<R(A0, A1, A2, A3, A4)> {
3209 public:
3210  /** Create a Callback with a static function
3211  * @param func Static function to attach
3212  */
3213  Callback(R(*func)(A0, A1, A2, A3, A4) = 0)
3214  {
3215  if (!func) {
3216  memset(this, 0, sizeof(Callback));
3217  } else {
3218  generate(func);
3219  }
3220  }
3221 
3222  /** Attach a Callback
3223  * @param func The Callback to attach
3224  */
3225  Callback(const Callback<R(A0, A1, A2, A3, A4)> &func)
3226  {
3227  if (func._ops) {
3228  func._ops->move(this, &func);
3229  }
3230  _ops = func._ops;
3231  }
3232 
3233  /** Create a Callback with a member function
3234  * @param obj Pointer to object to invoke member function on
3235  * @param method Member function to attach
3236  */
3237  template<typename T, typename U>
3238  Callback(U *obj, R(T::*method)(A0, A1, A2, A3, A4))
3239  {
3240  generate(method_context<T, R(T::*)(A0, A1, A2, A3, A4)>(obj, method));
3241  }
3242 
3243  /** Create a Callback with a member function
3244  * @param obj Pointer to object to invoke member function on
3245  * @param method Member function to attach
3246  */
3247  template<typename T, typename U>
3248  Callback(const U *obj, R(T::*method)(A0, A1, A2, A3, A4) const)
3249  {
3250  generate(method_context<const T, R(T::*)(A0, A1, A2, A3, A4) const>(obj, method));
3251  }
3252 
3253  /** Create a Callback with a member function
3254  * @param obj Pointer to object to invoke member function on
3255  * @param method Member function to attach
3256  */
3257  template<typename T, typename U>
3258  Callback(volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile)
3259  {
3260  generate(method_context<volatile T, R(T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
3261  }
3262 
3263  /** Create a Callback with a member function
3264  * @param obj Pointer to object to invoke member function on
3265  * @param method Member function to attach
3266  */
3267  template<typename T, typename U>
3268  Callback(const volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile)
3269  {
3270  generate(method_context<const volatile T, R(T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
3271  }
3272 
3273  /** Create a Callback with a static function and bound pointer
3274  * @param func Static function to attach
3275  * @param arg Pointer argument to function
3276  */
3277  template<typename T, typename U>
3278  Callback(R(*func)(T *, A0, A1, A2, A3, A4), U *arg)
3279  {
3280  generate(function_context<R(*)(T *, A0, A1, A2, A3, A4), T>(func, arg));
3281  }
3282 
3283  /** Create a Callback with a static function and bound pointer
3284  * @param func Static function to attach
3285  * @param arg Pointer argument to function
3286  */
3287  template<typename T, typename U>
3288  Callback(R(*func)(const T *, A0, A1, A2, A3, A4), const U *arg)
3289  {
3290  generate(function_context<R(*)(const T *, A0, A1, A2, A3, A4), const T>(func, arg));
3291  }
3292 
3293  /** Create a Callback with a static function and bound pointer
3294  * @param func Static function to attach
3295  * @param arg Pointer argument to function
3296  */
3297  template<typename T, typename U>
3298  Callback(R(*func)(volatile T *, A0, A1, A2, A3, A4), volatile U *arg)
3299  {
3300  generate(function_context<R(*)(volatile T *, A0, A1, A2, A3, A4), volatile T>(func, arg));
3301  }
3302 
3303  /** Create a Callback with a static function and bound pointer
3304  * @param func Static function to attach
3305  * @param arg Pointer argument to function
3306  */
3307  template<typename T, typename U>
3308  Callback(R(*func)(const volatile T *, A0, A1, A2, A3, A4), const volatile U *arg)
3309  {
3310  generate(function_context<R(*)(const volatile T *, A0, A1, A2, A3, A4), const volatile T>(func, arg));
3311  }
3312 
3313  /** Create a Callback with a function object
3314  * @param f Function object to attach
3315  * @note The function object is limited to a single word of storage
3316  */
3317  template <typename F>
3318  Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4)))
3319  {
3320  generate(f);
3321  }
3322 
3323  /** Create a Callback with a function object
3324  * @param f Function object to attach
3325  * @note The function object is limited to a single word of storage
3326  */
3327  template <typename F>
3328  Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4) const))
3329  {
3330  generate(f);
3331  }
3332 
3333  /** Create a Callback with a function object
3334  * @param f Function object to attach
3335  * @note The function object is limited to a single word of storage
3336  */
3337  template <typename F>
3338  Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4) volatile))
3339  {
3340  generate(f);
3341  }
3342 
3343  /** Create a Callback with a function object
3344  * @param f Function object to attach
3345  * @note The function object is limited to a single word of storage
3346  */
3347  template <typename F>
3348  Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4) const volatile))
3349  {
3350  generate(f);
3351  }
3352 
3353  /** Create a Callback with a static function and bound pointer
3354  * @param obj Pointer to object to bind to function
3355  * @param func Static function to attach
3356  * @deprecated
3357  * Arguments to callback have been reordered to Callback(func, arg)
3358  */
3359  template<typename T, typename U>
3360  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3361  "Arguments to callback have been reordered to Callback(func, arg)")
3362  Callback(U *obj, R(*func)(T *, A0, A1, A2, A3, A4))
3363  {
3364  new (this) Callback(func, obj);
3365  }
3366 
3367  /** Create a Callback with a static function and bound pointer
3368  * @param obj Pointer to object to bind to function
3369  * @param func Static function to attach
3370  * @deprecated
3371  * Arguments to callback have been reordered to Callback(func, arg)
3372  */
3373  template<typename T, typename U>
3374  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3375  "Arguments to callback have been reordered to Callback(func, arg)")
3376  Callback(const U *obj, R(*func)(const T *, A0, A1, A2, A3, A4))
3377  {
3378  new (this) Callback(func, obj);
3379  }
3380 
3381  /** Create a Callback with a static function and bound pointer
3382  * @param obj Pointer to object to bind to function
3383  * @param func Static function to attach
3384  * @deprecated
3385  * Arguments to callback have been reordered to Callback(func, arg)
3386  */
3387  template<typename T, typename U>
3388  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3389  "Arguments to callback have been reordered to Callback(func, arg)")
3390  Callback(volatile U *obj, R(*func)(volatile T *, A0, A1, A2, A3, A4))
3391  {
3392  new (this) Callback(func, obj);
3393  }
3394 
3395  /** Create a Callback with a static function and bound pointer
3396  * @param obj Pointer to object to bind to function
3397  * @param func Static function to attach
3398  * @deprecated
3399  * Arguments to callback have been reordered to Callback(func, arg)
3400  */
3401  template<typename T, typename U>
3402  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3403  "Arguments to callback have been reordered to Callback(func, arg)")
3404  Callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3, A4))
3405  {
3406  new (this) Callback(func, obj);
3407  }
3408 
3409  /** Destroy a callback
3410  */
3412  {
3413  if (_ops) {
3414  _ops->dtor(this);
3415  }
3416  }
3417 
3418  /** Attach a static function
3419  * @param func Static function to attach
3420  * @deprecated
3421  * Replaced by simple assignment 'Callback cb = func'
3422  */
3423  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3424  "Replaced by simple assignment 'Callback cb = func")
3425  void attach(R(*func)(A0, A1, A2, A3, A4))
3426  {
3427  this->~Callback();
3428  new (this) Callback(func);
3429  }
3430 
3431  /** Attach a Callback
3432  * @param func The Callback to attach
3433  * @deprecated
3434  * Replaced by simple assignment 'Callback cb = func'
3435  */
3436  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3437  "Replaced by simple assignment 'Callback cb = func")
3438  void attach(const Callback<R(A0, A1, A2, A3, A4)> &func)
3439  {
3440  this->~Callback();
3441  new (this) Callback(func);
3442  }
3443 
3444  /** Attach a member function
3445  * @param obj Pointer to object to invoke member function on
3446  * @param method Member function to attach
3447  * @deprecated
3448  * Replaced by simple assignment 'Callback cb = func'
3449  */
3450  template<typename T, typename U>
3451  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3452  "Replaced by simple assignment 'Callback cb = func")
3453  void attach(U *obj, R(T::*method)(A0, A1, A2, A3, A4))
3454  {
3455  this->~Callback();
3456  new (this) Callback(obj, method);
3457  }
3458 
3459  /** Attach a member function
3460  * @param obj Pointer to object to invoke member function on
3461  * @param method Member function to attach
3462  * @deprecated
3463  * Replaced by simple assignment 'Callback cb = func'
3464  */
3465  template<typename T, typename U>
3466  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3467  "Replaced by simple assignment 'Callback cb = func")
3468  void attach(const U *obj, R(T::*method)(A0, A1, A2, A3, A4) const)
3469  {
3470  this->~Callback();
3471  new (this) Callback(obj, method);
3472  }
3473 
3474  /** Attach a member function
3475  * @param obj Pointer to object to invoke member function on
3476  * @param method Member function to attach
3477  * @deprecated
3478  * Replaced by simple assignment 'Callback cb = func'
3479  */
3480  template<typename T, typename U>
3481  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3482  "Replaced by simple assignment 'Callback cb = func")
3483  void attach(volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile)
3484  {
3485  this->~Callback();
3486  new (this) Callback(obj, method);
3487  }
3488 
3489  /** Attach a member function
3490  * @param obj Pointer to object to invoke member function on
3491  * @param method Member function to attach
3492  * @deprecated
3493  * Replaced by simple assignment 'Callback cb = func'
3494  */
3495  template<typename T, typename U>
3496  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3497  "Replaced by simple assignment 'Callback cb = func")
3498  void attach(const volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile)
3499  {
3500  this->~Callback();
3501  new (this) Callback(obj, method);
3502  }
3503 
3504  /** Attach a static function with a bound pointer
3505  * @param func Static function to attach
3506  * @param arg Pointer argument to function
3507  * @deprecated
3508  * Replaced by simple assignment 'Callback cb = func'
3509  */
3510  template <typename T, typename U>
3511  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3512  "Replaced by simple assignment 'Callback cb = func")
3513  void attach(R(*func)(T *, A0, A1, A2, A3, A4), U *arg)
3514  {
3515  this->~Callback();
3516  new (this) Callback(func, arg);
3517  }
3518 
3519  /** Attach a static function with a bound pointer
3520  * @param func Static function to attach
3521  * @param arg Pointer argument to function
3522  * @deprecated
3523  * Replaced by simple assignment 'Callback cb = func'
3524  */
3525  template <typename T, typename U>
3526  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3527  "Replaced by simple assignment 'Callback cb = func")
3528  void attach(R(*func)(const T *, A0, A1, A2, A3, A4), const U *arg)
3529  {
3530  this->~Callback();
3531  new (this) Callback(func, arg);
3532  }
3533 
3534  /** Attach a static function with a bound pointer
3535  * @param func Static function to attach
3536  * @param arg Pointer argument to function
3537  * @deprecated
3538  * Replaced by simple assignment 'Callback cb = func'
3539  */
3540  template <typename T, typename U>
3541  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3542  "Replaced by simple assignment 'Callback cb = func")
3543  void attach(R(*func)(volatile T *, A0, A1, A2, A3, A4), volatile U *arg)
3544  {
3545  this->~Callback();
3546  new (this) Callback(func, arg);
3547  }
3548 
3549  /** Attach a static function with a bound pointer
3550  * @param func Static function to attach
3551  * @param arg Pointer argument to function
3552  * @deprecated
3553  * Replaced by simple assignment 'Callback cb = func'
3554  */
3555  template <typename T, typename U>
3556  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3557  "Replaced by simple assignment 'Callback cb = func")
3558  void attach(R(*func)(const volatile T *, A0, A1, A2, A3, A4), const volatile U *arg)
3559  {
3560  this->~Callback();
3561  new (this) Callback(func, arg);
3562  }
3563 
3564  /** Attach a function object
3565  * @param f Function object to attach
3566  * @note The function object is limited to a single word of storage
3567  * @deprecated
3568  * Replaced by simple assignment 'Callback cb = func'
3569  */
3570  template <typename F>
3571  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3572  "Replaced by simple assignment 'Callback cb = func")
3573  void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4)))
3574  {
3575  this->~Callback();
3576  new (this) Callback(f);
3577  }
3578 
3579  /** Attach a function object
3580  * @param f Function object to attach
3581  * @note The function object is limited to a single word of storage
3582  * @deprecated
3583  * Replaced by simple assignment 'Callback cb = func'
3584  */
3585  template <typename F>
3586  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3587  "Replaced by simple assignment 'Callback cb = func")
3588  void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4) const))
3589  {
3590  this->~Callback();
3591  new (this) Callback(f);
3592  }
3593 
3594  /** Attach a function object
3595  * @param f Function object to attach
3596  * @note The function object is limited to a single word of storage
3597  * @deprecated
3598  * Replaced by simple assignment 'Callback cb = func'
3599  */
3600  template <typename F>
3601  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3602  "Replaced by simple assignment 'Callback cb = func")
3603  void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4) volatile))
3604  {
3605  this->~Callback();
3606  new (this) Callback(f);
3607  }
3608 
3609  /** Attach a function object
3610  * @param f Function object to attach
3611  * @note The function object is limited to a single word of storage
3612  * @deprecated
3613  * Replaced by simple assignment 'Callback cb = func'
3614  */
3615  template <typename F>
3616  MBED_DEPRECATED_SINCE("mbed-os-5.4",
3617  "Replaced by simple assignment 'Callback cb = func")
3618  void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(A0, A1, A2, A3, A4) const volatile))
3619  {
3620  this->~Callback();
3621  new (this) Callback(f);
3622  }
3623 
3624  /** Attach a static function with a bound pointer
3625  * @param obj Pointer to object to bind to function
3626  * @param func Static function to attach
3627  * @deprecated
3628  * Arguments to callback have been reordered to attach(func, arg)
3629  */
3630  template <typename T, typename U>
3631  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3632  "Arguments to callback have been reordered to attach(func, arg)")
3633  void attach(U *obj, R(*func)(T *, A0, A1, A2, A3, A4))
3634  {
3635  this->~Callback();
3636  new (this) Callback(func, obj);
3637  }
3638 
3639  /** Attach a static function with a bound pointer
3640  * @param obj Pointer to object to bind to function
3641  * @param func Static function to attach
3642  * @deprecated
3643  * Arguments to callback have been reordered to attach(func, arg)
3644  */
3645  template <typename T, typename U>
3646  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3647  "Arguments to callback have been reordered to attach(func, arg)")
3648  void attach(const U *obj, R(*func)(const T *, A0, A1, A2, A3, A4))
3649  {
3650  this->~Callback();
3651  new (this) Callback(func, obj);
3652  }
3653 
3654  /** Attach a static function with a bound pointer
3655  * @param obj Pointer to object to bind to function
3656  * @param func Static function to attach
3657  * @deprecated
3658  * Arguments to callback have been reordered to attach(func, arg)
3659  */
3660  template <typename T, typename U>
3661  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3662  "Arguments to callback have been reordered to attach(func, arg)")
3663  void attach(volatile U *obj, R(*func)(volatile T *, A0, A1, A2, A3, A4))
3664  {
3665  this->~Callback();
3666  new (this) Callback(func, obj);
3667  }
3668 
3669  /** Attach a static function with a bound pointer
3670  * @param obj Pointer to object to bind to function
3671  * @param func Static function to attach
3672  * @deprecated
3673  * Arguments to callback have been reordered to attach(func, arg)
3674  */
3675  template <typename T, typename U>
3676  MBED_DEPRECATED_SINCE("mbed-os-5.1",
3677  "Arguments to callback have been reordered to attach(func, arg)")
3678  void attach(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3, A4))
3679  {
3680  this->~Callback();
3681  new (this) Callback(func, obj);
3682  }
3683 
3684  /** Assign a callback
3685  */
3687  {
3688  if (this != &that) {
3689  this->~Callback();
3690  new (this) Callback(that);
3691  }
3692 
3693  return *this;
3694  }
3695 
3696  /** Call the attached function
3697  */
3698  R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const
3699  {
3700  MBED_ASSERT(_ops);
3701  return _ops->call(this, a0, a1, a2, a3, a4);
3702  }
3703 
3704  /** Call the attached function
3705  */
3706  R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const
3707  {
3708  return call(a0, a1, a2, a3, a4);
3709  }
3710 
3711  /** Test if function has been attached
3712  */
3713  operator bool() const
3714  {
3715  return _ops;
3716  }
3717 
3718  /** Test for equality
3719  */
3720  friend bool operator==(const Callback &l, const Callback &r)
3721  {
3722  return memcmp(&l, &r, sizeof(Callback)) == 0;
3723  }
3724 
3725  /** Test for inequality
3726  */
3727  friend bool operator!=(const Callback &l, const Callback &r)
3728  {
3729  return !(l == r);
3730  }
3731 
3732  /** Static thunk for passing as C-style function
3733  * @param func Callback to call passed as void pointer
3734  * @param a0 An argument to be called with function func
3735  * @param a1 An argument to be called with function func
3736  * @param a2 An argument to be called with function func
3737  * @param a3 An argument to be called with function func
3738  * @param a4 An argument to be called with function func
3739  * @return the value as determined by func which is of
3740  * type and determined by the signature of func
3741  */
3742  static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
3743  {
3744  return static_cast<Callback *>(func)->call(a0, a1, a2, a3, a4);
3745  }
3746 
3747 private:
3748  // Stored as pointer to function and pointer to optional object
3749  // Function pointer is stored as union of possible function types
3750  // to guarantee proper size and alignment
3751  struct _class;
3752  union {
3753  void (*_staticfunc)(A0, A1, A2, A3, A4);
3754  void (*_boundfunc)(_class *, A0, A1, A2, A3, A4);
3755  void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
3756  } _func;
3757  void *_obj;
3758 
3759  // Dynamically dispatched operations
3760  const struct ops {
3761  R(*call)(const void *, A0, A1, A2, A3, A4);
3762  void (*move)(void *, const void *);
3763  void (*dtor)(void *);
3764  } *_ops;
3765 
3766  // Generate operations for function object
3767  template <typename F>
3768  void generate(const F &f)
3769  {
3770  static const ops ops = {
3771  &Callback::function_call<F>,
3772  &Callback::function_move<F>,
3773  &Callback::function_dtor<F>,
3774  };
3775 
3776  MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
3777  "Type F must not exceed the size of the Callback class");
3778  memset(this, 0, sizeof(Callback));
3779  new (this) F(f);
3780  _ops = &ops;
3781  }
3782 
3783  // Function attributes
3784  template <typename F>
3785  static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
3786  {
3787  return (*(F *)p)(a0, a1, a2, a3, a4);
3788  }
3789 
3790  template <typename F>
3791  static void function_move(void *d, const void *p)
3792  {
3793  new (d) F(*(F *)p);
3794  }
3795 
3796  template <typename F>
3797  static void function_dtor(void *p)
3798  {
3799  ((F *)p)->~F();
3800  }
3801 
3802  // Wrappers for functions with context
3803  template <typename O, typename M>
3804  struct method_context {
3805  M method;
3806  O *obj;
3807 
3808  method_context(O *obj, M method)
3809  : method(method), obj(obj) {}
3810 
3811  R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const
3812  {
3813  return (obj->*method)(a0, a1, a2, a3, a4);
3814  }
3815  };
3816 
3817  template <typename F, typename A>
3818  struct function_context {
3819  F func;
3820  A *arg;
3821 
3822  function_context(F func, A *arg)
3823  : func(func), arg(arg) {}
3824 
3825  R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const
3826  {
3827  return func(arg, a0, a1, a2, a3, a4);
3828  }
3829  };
3830 };
3831 
3832 // Internally used event type
3834 
3835 
3836 /** Create a callback class with type inferred from the arguments
3837  *
3838  * @param func Static function to attach
3839  * @return Callback with inferred type
3840  */
3841 template <typename R>
3842 Callback<R()> callback(R(*func)() = 0)
3843 {
3844  return Callback<R()>(func);
3845 }
3846 
3847 /** Create a callback class with type inferred from the arguments
3848  *
3849  * @param func Static function to attach
3850  * @return Callback with inferred type
3851  */
3852 template <typename R>
3854 {
3855  return Callback<R()>(func);
3856 }
3857 
3858 /** Create a callback class with type inferred from the arguments
3859  *
3860  * @param obj Optional pointer to object to bind to function
3861  * @param method Member function to attach
3862  * @return Callback with inferred type
3863  */
3864 template<typename T, typename U, typename R>
3865 Callback<R()> callback(U *obj, R(T::*method)())
3866 {
3867  return Callback<R()>(obj, method);
3868 }
3869 
3870 /** Create a callback class with type inferred from the arguments
3871  *
3872  * @param obj Optional pointer to object to bind to function
3873  * @param method Member function to attach
3874  * @return Callback with inferred type
3875  */
3876 template<typename T, typename U, typename R>
3877 Callback<R()> callback(const U *obj, R(T::*method)() const)
3878 {
3879  return Callback<R()>(obj, method);
3880 }
3881 
3882 /** Create a callback class with type inferred from the arguments
3883  *
3884  * @param obj Optional pointer to object to bind to function
3885  * @param method Member function to attach
3886  * @return Callback with inferred type
3887  */
3888 template<typename T, typename U, typename R>
3889 Callback<R()> callback(volatile U *obj, R(T::*method)() volatile)
3890 {
3891  return Callback<R()>(obj, method);
3892 }
3893 
3894 /** Create a callback class with type inferred from the arguments
3895  *
3896  * @param obj Optional pointer to object to bind to function
3897  * @param method Member function to attach
3898  * @return Callback with inferred type
3899  */
3900 template<typename T, typename U, typename R>
3901 Callback<R()> callback(const volatile U *obj, R(T::*method)() const volatile)
3902 {
3903  return Callback<R()>(obj, method);
3904 }
3905 
3906 /** Create a callback class with type inferred from the arguments
3907  *
3908  * @param func Static function to attach
3909  * @param arg Pointer argument to function
3910  * @return Callback with inferred type
3911  */
3912 template <typename T, typename U, typename R>
3913 Callback<R()> callback(R(*func)(T *), U *arg)
3914 {
3915  return Callback<R()>(func, arg);
3916 }
3917 
3918 /** Create a callback class with type inferred from the arguments
3919  *
3920  * @param func Static function to attach
3921  * @param arg Pointer argument to function
3922  * @return Callback with inferred type
3923  */
3924 template <typename T, typename U, typename R>
3925 Callback<R()> callback(R(*func)(const T *), const U *arg)
3926 {
3927  return Callback<R()>(func, arg);
3928 }
3929 
3930 /** Create a callback class with type inferred from the arguments
3931  *
3932  * @param func Static function to attach
3933  * @param arg Pointer argument to function
3934  * @return Callback with inferred type
3935  */
3936 template <typename T, typename U, typename R>
3937 Callback<R()> callback(R(*func)(volatile T *), volatile U *arg)
3938 {
3939  return Callback<R()>(func, arg);
3940 }
3941 
3942 /** Create a callback class with type inferred from the arguments
3943  *
3944  * @param func Static function to attach
3945  * @param arg Pointer argument to function
3946  * @return Callback with inferred type
3947  */
3948 template <typename T, typename U, typename R>
3949 Callback<R()> callback(R(*func)(const volatile T *), const volatile U *arg)
3950 {
3951  return Callback<R()>(func, arg);
3952 }
3953 
3954 /** Create a callback class with type inferred from the arguments
3955  *
3956  * @param obj Optional pointer to object to bind to function
3957  * @param func Static function to attach
3958  * @return Callback with inferred type
3959  * @deprecated
3960  * Arguments to callback have been reordered to callback(func, arg)
3961  */
3962 template <typename T, typename U, typename R>
3963 MBED_DEPRECATED_SINCE("mbed-os-5.1",
3964  "Arguments to callback have been reordered to callback(func, arg)")
3965 Callback<R()> callback(U *obj, R(*func)(T *))
3966 {
3967  return Callback<R()>(func, obj);
3968 }
3969 
3970 /** Create a callback class with type inferred from the arguments
3971  *
3972  * @param obj Optional pointer to object to bind to function
3973  * @param func Static function to attach
3974  * @return Callback with inferred type
3975  * @deprecated
3976  * Arguments to callback have been reordered to callback(func, arg)
3977  */
3978 template <typename T, typename U, typename R>
3979 MBED_DEPRECATED_SINCE("mbed-os-5.1",
3980  "Arguments to callback have been reordered to callback(func, arg)")
3981 Callback<R()> callback(const U *obj, R(*func)(const T *))
3982 {
3983  return Callback<R()>(func, obj);
3984 }
3985 
3986 /** Create a callback class with type inferred from the arguments
3987  *
3988  * @param obj Optional pointer to object to bind to function
3989  * @param func Static function to attach
3990  * @return Callback with inferred type
3991  * @deprecated
3992  * Arguments to callback have been reordered to callback(func, arg)
3993  */
3994 template <typename T, typename U, typename R>
3995 MBED_DEPRECATED_SINCE("mbed-os-5.1",
3996  "Arguments to callback have been reordered to callback(func, arg)")
3997 Callback<R()> callback(volatile U *obj, R(*func)(volatile T *))
3998 {
3999  return Callback<R()>(func, obj);
4000 }
4001 
4002 /** Create a callback class with type inferred from the arguments
4003  *
4004  * @param obj Optional pointer to object to bind to function
4005  * @param func Static function to attach
4006  * @return Callback with inferred type
4007  * @deprecated
4008  * Arguments to callback have been reordered to callback(func, arg)
4009  */
4010 template <typename T, typename U, typename R>
4011 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4012  "Arguments to callback have been reordered to callback(func, arg)")
4013 Callback<R()> callback(const volatile U *obj, R(*func)(const volatile T *))
4014 {
4015  return Callback<R()>(func, obj);
4016 }
4017 
4018 
4019 /** Create a callback class with type inferred from the arguments
4020  *
4021  * @param func Static function to attach
4022  * @return Callback with inferred type
4023  */
4024 template <typename R, typename A0>
4025 Callback<R(A0)> callback(R(*func)(A0) = 0)
4026 {
4027  return Callback<R(A0)>(func);
4028 }
4029 
4030 /** Create a callback class with type inferred from the arguments
4031  *
4032  * @param func Static function to attach
4033  * @return Callback with inferred type
4034  */
4035 template <typename R, typename A0>
4036 Callback<R(A0)> callback(const Callback<R(A0)> &func)
4037 {
4038  return Callback<R(A0)>(func);
4039 }
4040 
4041 /** Create a callback class with type inferred from the arguments
4042  *
4043  * @param obj Optional pointer to object to bind to function
4044  * @param method Member function to attach
4045  * @return Callback with inferred type
4046  */
4047 template<typename T, typename U, typename R, typename A0>
4048 Callback<R(A0)> callback(U *obj, R(T::*method)(A0))
4049 {
4050  return Callback<R(A0)>(obj, method);
4051 }
4052 
4053 /** Create a callback class with type inferred from the arguments
4054  *
4055  * @param obj Optional pointer to object to bind to function
4056  * @param method Member function to attach
4057  * @return Callback with inferred type
4058  */
4059 template<typename T, typename U, typename R, typename A0>
4060 Callback<R(A0)> callback(const U *obj, R(T::*method)(A0) const)
4061 {
4062  return Callback<R(A0)>(obj, method);
4063 }
4064 
4065 /** Create a callback class with type inferred from the arguments
4066  *
4067  * @param obj Optional pointer to object to bind to function
4068  * @param method Member function to attach
4069  * @return Callback with inferred type
4070  */
4071 template<typename T, typename U, typename R, typename A0>
4072 Callback<R(A0)> callback(volatile U *obj, R(T::*method)(A0) volatile)
4073 {
4074  return Callback<R(A0)>(obj, method);
4075 }
4076 
4077 /** Create a callback class with type inferred from the arguments
4078  *
4079  * @param obj Optional pointer to object to bind to function
4080  * @param method Member function to attach
4081  * @return Callback with inferred type
4082  */
4083 template<typename T, typename U, typename R, typename A0>
4084 Callback<R(A0)> callback(const volatile U *obj, R(T::*method)(A0) const volatile)
4085 {
4086  return Callback<R(A0)>(obj, method);
4087 }
4088 
4089 /** Create a callback class with type inferred from the arguments
4090  *
4091  * @param func Static function to attach
4092  * @param arg Pointer argument to function
4093  * @return Callback with inferred type
4094  */
4095 template <typename T, typename U, typename R, typename A0>
4096 Callback<R(A0)> callback(R(*func)(T *, A0), U *arg)
4097 {
4098  return Callback<R(A0)>(func, arg);
4099 }
4100 
4101 /** Create a callback class with type inferred from the arguments
4102  *
4103  * @param func Static function to attach
4104  * @param arg Pointer argument to function
4105  * @return Callback with inferred type
4106  */
4107 template <typename T, typename U, typename R, typename A0>
4108 Callback<R(A0)> callback(R(*func)(const T *, A0), const U *arg)
4109 {
4110  return Callback<R(A0)>(func, arg);
4111 }
4112 
4113 /** Create a callback class with type inferred from the arguments
4114  *
4115  * @param func Static function to attach
4116  * @param arg Pointer argument to function
4117  * @return Callback with inferred type
4118  */
4119 template <typename T, typename U, typename R, typename A0>
4120 Callback<R(A0)> callback(R(*func)(volatile T *, A0), volatile U *arg)
4121 {
4122  return Callback<R(A0)>(func, arg);
4123 }
4124 
4125 /** Create a callback class with type inferred from the arguments
4126  *
4127  * @param func Static function to attach
4128  * @param arg Pointer argument to function
4129  * @return Callback with inferred type
4130  */
4131 template <typename T, typename U, typename R, typename A0>
4132 Callback<R(A0)> callback(R(*func)(const volatile T *, A0), const volatile U *arg)
4133 {
4134  return Callback<R(A0)>(func, arg);
4135 }
4136 
4137 /** Create a callback class with type inferred from the arguments
4138  *
4139  * @param obj Optional pointer to object to bind to function
4140  * @param func Static function to attach
4141  * @return Callback with inferred type
4142  * @deprecated
4143  * Arguments to callback have been reordered to callback(func, arg)
4144  */
4145 template <typename T, typename U, typename R, typename A0>
4146 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4147  "Arguments to callback have been reordered to callback(func, arg)")
4148 Callback<R(A0)> callback(U *obj, R(*func)(T *, A0))
4149 {
4150  return Callback<R(A0)>(func, obj);
4151 }
4152 
4153 /** Create a callback class with type inferred from the arguments
4154  *
4155  * @param obj Optional pointer to object to bind to function
4156  * @param func Static function to attach
4157  * @return Callback with inferred type
4158  * @deprecated
4159  * Arguments to callback have been reordered to callback(func, arg)
4160  */
4161 template <typename T, typename U, typename R, typename A0>
4162 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4163  "Arguments to callback have been reordered to callback(func, arg)")
4164 Callback<R(A0)> callback(const U *obj, R(*func)(const T *, A0))
4165 {
4166  return Callback<R(A0)>(func, obj);
4167 }
4168 
4169 /** Create a callback class with type inferred from the arguments
4170  *
4171  * @param obj Optional pointer to object to bind to function
4172  * @param func Static function to attach
4173  * @return Callback with inferred type
4174  * @deprecated
4175  * Arguments to callback have been reordered to callback(func, arg)
4176  */
4177 template <typename T, typename U, typename R, typename A0>
4178 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4179  "Arguments to callback have been reordered to callback(func, arg)")
4180 Callback<R(A0)> callback(volatile U *obj, R(*func)(volatile T *, A0))
4181 {
4182  return Callback<R(A0)>(func, obj);
4183 }
4184 
4185 /** Create a callback class with type inferred from the arguments
4186  *
4187  * @param obj Optional pointer to object to bind to function
4188  * @param func Static function to attach
4189  * @return Callback with inferred type
4190  * @deprecated
4191  * Arguments to callback have been reordered to callback(func, arg)
4192  */
4193 template <typename T, typename U, typename R, typename A0>
4194 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4195  "Arguments to callback have been reordered to callback(func, arg)")
4196 Callback<R(A0)> callback(const volatile U *obj, R(*func)(const volatile T *, A0))
4197 {
4198  return Callback<R(A0)>(func, obj);
4199 }
4200 
4201 
4202 /** Create a callback class with type inferred from the arguments
4203  *
4204  * @param func Static function to attach
4205  * @return Callback with inferred type
4206  */
4207 template <typename R, typename A0, typename A1>
4208 Callback<R(A0, A1)> callback(R(*func)(A0, A1) = 0)
4209 {
4210  return Callback<R(A0, A1)>(func);
4211 }
4212 
4213 /** Create a callback class with type inferred from the arguments
4214  *
4215  * @param func Static function to attach
4216  * @return Callback with inferred type
4217  */
4218 template <typename R, typename A0, typename A1>
4219 Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func)
4220 {
4221  return Callback<R(A0, A1)>(func);
4222 }
4223 
4224 /** Create a callback class with type inferred from the arguments
4225  *
4226  * @param obj Optional pointer to object to bind to function
4227  * @param method Member function to attach
4228  * @return Callback with inferred type
4229  */
4230 template<typename T, typename U, typename R, typename A0, typename A1>
4231 Callback<R(A0, A1)> callback(U *obj, R(T::*method)(A0, A1))
4232 {
4233  return Callback<R(A0, A1)>(obj, method);
4234 }
4235 
4236 /** Create a callback class with type inferred from the arguments
4237  *
4238  * @param obj Optional pointer to object to bind to function
4239  * @param method Member function to attach
4240  * @return Callback with inferred type
4241  */
4242 template<typename T, typename U, typename R, typename A0, typename A1>
4243 Callback<R(A0, A1)> callback(const U *obj, R(T::*method)(A0, A1) const)
4244 {
4245  return Callback<R(A0, A1)>(obj, method);
4246 }
4247 
4248 /** Create a callback class with type inferred from the arguments
4249  *
4250  * @param obj Optional pointer to object to bind to function
4251  * @param method Member function to attach
4252  * @return Callback with inferred type
4253  */
4254 template<typename T, typename U, typename R, typename A0, typename A1>
4255 Callback<R(A0, A1)> callback(volatile U *obj, R(T::*method)(A0, A1) volatile)
4256 {
4257  return Callback<R(A0, A1)>(obj, method);
4258 }
4259 
4260 /** Create a callback class with type inferred from the arguments
4261  *
4262  * @param obj Optional pointer to object to bind to function
4263  * @param method Member function to attach
4264  * @return Callback with inferred type
4265  */
4266 template<typename T, typename U, typename R, typename A0, typename A1>
4267 Callback<R(A0, A1)> callback(const volatile U *obj, R(T::*method)(A0, A1) const volatile)
4268 {
4269  return Callback<R(A0, A1)>(obj, method);
4270 }
4271 
4272 /** Create a callback class with type inferred from the arguments
4273  *
4274  * @param func Static function to attach
4275  * @param arg Pointer argument to function
4276  * @return Callback with inferred type
4277  */
4278 template <typename T, typename U, typename R, typename A0, typename A1>
4279 Callback<R(A0, A1)> callback(R(*func)(T *, A0, A1), U *arg)
4280 {
4281  return Callback<R(A0, A1)>(func, arg);
4282 }
4283 
4284 /** Create a callback class with type inferred from the arguments
4285  *
4286  * @param func Static function to attach
4287  * @param arg Pointer argument to function
4288  * @return Callback with inferred type
4289  */
4290 template <typename T, typename U, typename R, typename A0, typename A1>
4291 Callback<R(A0, A1)> callback(R(*func)(const T *, A0, A1), const U *arg)
4292 {
4293  return Callback<R(A0, A1)>(func, arg);
4294 }
4295 
4296 /** Create a callback class with type inferred from the arguments
4297  *
4298  * @param func Static function to attach
4299  * @param arg Pointer argument to function
4300  * @return Callback with inferred type
4301  */
4302 template <typename T, typename U, typename R, typename A0, typename A1>
4303 Callback<R(A0, A1)> callback(R(*func)(volatile T *, A0, A1), volatile U *arg)
4304 {
4305  return Callback<R(A0, A1)>(func, arg);
4306 }
4307 
4308 /** Create a callback class with type inferred from the arguments
4309  *
4310  * @param func Static function to attach
4311  * @param arg Pointer argument to function
4312  * @return Callback with inferred type
4313  */
4314 template <typename T, typename U, typename R, typename A0, typename A1>
4315 Callback<R(A0, A1)> callback(R(*func)(const volatile T *, A0, A1), const volatile U *arg)
4316 {
4317  return Callback<R(A0, A1)>(func, arg);
4318 }
4319 
4320 /** Create a callback class with type inferred from the arguments
4321  *
4322  * @param obj Optional pointer to object to bind to function
4323  * @param func Static function to attach
4324  * @return Callback with inferred type
4325  * @deprecated
4326  * Arguments to callback have been reordered to callback(func, arg)
4327  */
4328 template <typename T, typename U, typename R, typename A0, typename A1>
4329 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4330  "Arguments to callback have been reordered to callback(func, arg)")
4331 Callback<R(A0, A1)> callback(U *obj, R(*func)(T *, A0, A1))
4332 {
4333  return Callback<R(A0, A1)>(func, obj);
4334 }
4335 
4336 /** Create a callback class with type inferred from the arguments
4337  *
4338  * @param obj Optional pointer to object to bind to function
4339  * @param func Static function to attach
4340  * @return Callback with inferred type
4341  * @deprecated
4342  * Arguments to callback have been reordered to callback(func, arg)
4343  */
4344 template <typename T, typename U, typename R, typename A0, typename A1>
4345 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4346  "Arguments to callback have been reordered to callback(func, arg)")
4347 Callback<R(A0, A1)> callback(const U *obj, R(*func)(const T *, A0, A1))
4348 {
4349  return Callback<R(A0, A1)>(func, obj);
4350 }
4351 
4352 /** Create a callback class with type inferred from the arguments
4353  *
4354  * @param obj Optional pointer to object to bind to function
4355  * @param func Static function to attach
4356  * @return Callback with inferred type
4357  * @deprecated
4358  * Arguments to callback have been reordered to callback(func, arg)
4359  */
4360 template <typename T, typename U, typename R, typename A0, typename A1>
4361 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4362  "Arguments to callback have been reordered to callback(func, arg)")
4363 Callback<R(A0, A1)> callback(volatile U *obj, R(*func)(volatile T *, A0, A1))
4364 {
4365  return Callback<R(A0, A1)>(func, obj);
4366 }
4367 
4368 /** Create a callback class with type inferred from the arguments
4369  *
4370  * @param obj Optional pointer to object to bind to function
4371  * @param func Static function to attach
4372  * @return Callback with inferred type
4373  * @deprecated
4374  * Arguments to callback have been reordered to callback(func, arg)
4375  */
4376 template <typename T, typename U, typename R, typename A0, typename A1>
4377 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4378  "Arguments to callback have been reordered to callback(func, arg)")
4379 Callback<R(A0, A1)> callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1))
4380 {
4381  return Callback<R(A0, A1)>(func, obj);
4382 }
4383 
4384 
4385 /** Create a callback class with type inferred from the arguments
4386  *
4387  * @param func Static function to attach
4388  * @return Callback with inferred type
4389  */
4390 template <typename R, typename A0, typename A1, typename A2>
4391 Callback<R(A0, A1, A2)> callback(R(*func)(A0, A1, A2) = 0)
4392 {
4393  return Callback<R(A0, A1, A2)>(func);
4394 }
4395 
4396 /** Create a callback class with type inferred from the arguments
4397  *
4398  * @param func Static function to attach
4399  * @return Callback with inferred type
4400  */
4401 template <typename R, typename A0, typename A1, typename A2>
4402 Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func)
4403 {
4404  return Callback<R(A0, A1, A2)>(func);
4405 }
4406 
4407 /** Create a callback class with type inferred from the arguments
4408  *
4409  * @param obj Optional pointer to object to bind to function
4410  * @param method Member function to attach
4411  * @return Callback with inferred type
4412  */
4413 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
4414 Callback<R(A0, A1, A2)> callback(U *obj, R(T::*method)(A0, A1, A2))
4415 {
4416  return Callback<R(A0, A1, A2)>(obj, method);
4417 }
4418 
4419 /** Create a callback class with type inferred from the arguments
4420  *
4421  * @param obj Optional pointer to object to bind to function
4422  * @param method Member function to attach
4423  * @return Callback with inferred type
4424  */
4425 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
4426 Callback<R(A0, A1, A2)> callback(const U *obj, R(T::*method)(A0, A1, A2) const)
4427 {
4428  return Callback<R(A0, A1, A2)>(obj, method);
4429 }
4430 
4431 /** Create a callback class with type inferred from the arguments
4432  *
4433  * @param obj Optional pointer to object to bind to function
4434  * @param method Member function to attach
4435  * @return Callback with inferred type
4436  */
4437 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
4438 Callback<R(A0, A1, A2)> callback(volatile U *obj, R(T::*method)(A0, A1, A2) volatile)
4439 {
4440  return Callback<R(A0, A1, A2)>(obj, method);
4441 }
4442 
4443 /** Create a callback class with type inferred from the arguments
4444  *
4445  * @param obj Optional pointer to object to bind to function
4446  * @param method Member function to attach
4447  * @return Callback with inferred type
4448  */
4449 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
4450 Callback<R(A0, A1, A2)> callback(const volatile U *obj, R(T::*method)(A0, A1, A2) const volatile)
4451 {
4452  return Callback<R(A0, A1, A2)>(obj, method);
4453 }
4454 
4455 /** Create a callback class with type inferred from the arguments
4456  *
4457  * @param func Static function to attach
4458  * @param arg Pointer argument to function
4459  * @return Callback with inferred type
4460  */
4461 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4462 Callback<R(A0, A1, A2)> callback(R(*func)(T *, A0, A1, A2), U *arg)
4463 {
4464  return Callback<R(A0, A1, A2)>(func, arg);
4465 }
4466 
4467 /** Create a callback class with type inferred from the arguments
4468  *
4469  * @param func Static function to attach
4470  * @param arg Pointer argument to function
4471  * @return Callback with inferred type
4472  */
4473 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4474 Callback<R(A0, A1, A2)> callback(R(*func)(const T *, A0, A1, A2), const U *arg)
4475 {
4476  return Callback<R(A0, A1, A2)>(func, arg);
4477 }
4478 
4479 /** Create a callback class with type inferred from the arguments
4480  *
4481  * @param func Static function to attach
4482  * @param arg Pointer argument to function
4483  * @return Callback with inferred type
4484  */
4485 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4486 Callback<R(A0, A1, A2)> callback(R(*func)(volatile T *, A0, A1, A2), volatile U *arg)
4487 {
4488  return Callback<R(A0, A1, A2)>(func, arg);
4489 }
4490 
4491 /** Create a callback class with type inferred from the arguments
4492  *
4493  * @param func Static function to attach
4494  * @param arg Pointer argument to function
4495  * @return Callback with inferred type
4496  */
4497 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4498 Callback<R(A0, A1, A2)> callback(R(*func)(const volatile T *, A0, A1, A2), const volatile U *arg)
4499 {
4500  return Callback<R(A0, A1, A2)>(func, arg);
4501 }
4502 
4503 /** Create a callback class with type inferred from the arguments
4504  *
4505  * @param obj Optional pointer to object to bind to function
4506  * @param func Static function to attach
4507  * @return Callback with inferred type
4508  * @deprecated
4509  * Arguments to callback have been reordered to callback(func, arg)
4510  */
4511 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4512 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4513  "Arguments to callback have been reordered to callback(func, arg)")
4514 Callback<R(A0, A1, A2)> callback(U *obj, R(*func)(T *, A0, A1, A2))
4515 {
4516  return Callback<R(A0, A1, A2)>(func, obj);
4517 }
4518 
4519 /** Create a callback class with type inferred from the arguments
4520  *
4521  * @param obj Optional pointer to object to bind to function
4522  * @param func Static function to attach
4523  * @return Callback with inferred type
4524  * @deprecated
4525  * Arguments to callback have been reordered to callback(func, arg)
4526  */
4527 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4528 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4529  "Arguments to callback have been reordered to callback(func, arg)")
4530 Callback<R(A0, A1, A2)> callback(const U *obj, R(*func)(const T *, A0, A1, A2))
4531 {
4532  return Callback<R(A0, A1, A2)>(func, obj);
4533 }
4534 
4535 /** Create a callback class with type inferred from the arguments
4536  *
4537  * @param obj Optional pointer to object to bind to function
4538  * @param func Static function to attach
4539  * @return Callback with inferred type
4540  * @deprecated
4541  * Arguments to callback have been reordered to callback(func, arg)
4542  */
4543 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4544 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4545  "Arguments to callback have been reordered to callback(func, arg)")
4546 Callback<R(A0, A1, A2)> callback(volatile U *obj, R(*func)(volatile T *, A0, A1, A2))
4547 {
4548  return Callback<R(A0, A1, A2)>(func, obj);
4549 }
4550 
4551 /** Create a callback class with type inferred from the arguments
4552  *
4553  * @param obj Optional pointer to object to bind to function
4554  * @param func Static function to attach
4555  * @return Callback with inferred type
4556  * @deprecated
4557  * Arguments to callback have been reordered to callback(func, arg)
4558  */
4559 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
4560 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4561  "Arguments to callback have been reordered to callback(func, arg)")
4562 Callback<R(A0, A1, A2)> callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2))
4563 {
4564  return Callback<R(A0, A1, A2)>(func, obj);
4565 }
4566 
4567 
4568 /** Create a callback class with type inferred from the arguments
4569  *
4570  * @param func Static function to attach
4571  * @return Callback with inferred type
4572  */
4573 template <typename R, typename A0, typename A1, typename A2, typename A3>
4574 Callback<R(A0, A1, A2, A3)> callback(R(*func)(A0, A1, A2, A3) = 0)
4575 {
4576  return Callback<R(A0, A1, A2, A3)>(func);
4577 }
4578 
4579 /** Create a callback class with type inferred from the arguments
4580  *
4581  * @param func Static function to attach
4582  * @return Callback with inferred type
4583  */
4584 template <typename R, typename A0, typename A1, typename A2, typename A3>
4585 Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func)
4586 {
4587  return Callback<R(A0, A1, A2, A3)>(func);
4588 }
4589 
4590 /** Create a callback class with type inferred from the arguments
4591  *
4592  * @param obj Optional pointer to object to bind to function
4593  * @param method Member function to attach
4594  * @return Callback with inferred type
4595  */
4596 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4597 Callback<R(A0, A1, A2, A3)> callback(U *obj, R(T::*method)(A0, A1, A2, A3))
4598 {
4599  return Callback<R(A0, A1, A2, A3)>(obj, method);
4600 }
4601 
4602 /** Create a callback class with type inferred from the arguments
4603  *
4604  * @param obj Optional pointer to object to bind to function
4605  * @param method Member function to attach
4606  * @return Callback with inferred type
4607  */
4608 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4609 Callback<R(A0, A1, A2, A3)> callback(const U *obj, R(T::*method)(A0, A1, A2, A3) const)
4610 {
4611  return Callback<R(A0, A1, A2, A3)>(obj, method);
4612 }
4613 
4614 /** Create a callback class with type inferred from the arguments
4615  *
4616  * @param obj Optional pointer to object to bind to function
4617  * @param method Member function to attach
4618  * @return Callback with inferred type
4619  */
4620 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4621 Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R(T::*method)(A0, A1, A2, A3) volatile)
4622 {
4623  return Callback<R(A0, A1, A2, A3)>(obj, method);
4624 }
4625 
4626 /** Create a callback class with type inferred from the arguments
4627  *
4628  * @param obj Optional pointer to object to bind to function
4629  * @param method Member function to attach
4630  * @return Callback with inferred type
4631  */
4632 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4633 Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R(T::*method)(A0, A1, A2, A3) const volatile)
4634 {
4635  return Callback<R(A0, A1, A2, A3)>(obj, method);
4636 }
4637 
4638 /** Create a callback class with type inferred from the arguments
4639  *
4640  * @param func Static function to attach
4641  * @param arg Pointer argument to function
4642  * @return Callback with inferred type
4643  */
4644 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4645 Callback<R(A0, A1, A2, A3)> callback(R(*func)(T *, A0, A1, A2, A3), U *arg)
4646 {
4647  return Callback<R(A0, A1, A2, A3)>(func, arg);
4648 }
4649 
4650 /** Create a callback class with type inferred from the arguments
4651  *
4652  * @param func Static function to attach
4653  * @param arg Pointer argument to function
4654  * @return Callback with inferred type
4655  */
4656 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4657 Callback<R(A0, A1, A2, A3)> callback(R(*func)(const T *, A0, A1, A2, A3), const U *arg)
4658 {
4659  return Callback<R(A0, A1, A2, A3)>(func, arg);
4660 }
4661 
4662 /** Create a callback class with type inferred from the arguments
4663  *
4664  * @param func Static function to attach
4665  * @param arg Pointer argument to function
4666  * @return Callback with inferred type
4667  */
4668 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4669 Callback<R(A0, A1, A2, A3)> callback(R(*func)(volatile T *, A0, A1, A2, A3), volatile U *arg)
4670 {
4671  return Callback<R(A0, A1, A2, A3)>(func, arg);
4672 }
4673 
4674 /** Create a callback class with type inferred from the arguments
4675  *
4676  * @param func Static function to attach
4677  * @param arg Pointer argument to function
4678  * @return Callback with inferred type
4679  */
4680 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4681 Callback<R(A0, A1, A2, A3)> callback(R(*func)(const volatile T *, A0, A1, A2, A3), const volatile U *arg)
4682 {
4683  return Callback<R(A0, A1, A2, A3)>(func, arg);
4684 }
4685 
4686 /** Create a callback class with type inferred from the arguments
4687  *
4688  * @param obj Optional pointer to object to bind to function
4689  * @param func Static function to attach
4690  * @return Callback with inferred type
4691  * @deprecated
4692  * Arguments to callback have been reordered to callback(func, arg)
4693  */
4694 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4695 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4696  "Arguments to callback have been reordered to callback(func, arg)")
4697 Callback<R(A0, A1, A2, A3)> callback(U *obj, R(*func)(T *, A0, A1, A2, A3))
4698 {
4699  return Callback<R(A0, A1, A2, A3)>(func, obj);
4700 }
4701 
4702 /** Create a callback class with type inferred from the arguments
4703  *
4704  * @param obj Optional pointer to object to bind to function
4705  * @param func Static function to attach
4706  * @return Callback with inferred type
4707  * @deprecated
4708  * Arguments to callback have been reordered to callback(func, arg)
4709  */
4710 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4711 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4712  "Arguments to callback have been reordered to callback(func, arg)")
4713 Callback<R(A0, A1, A2, A3)> callback(const U *obj, R(*func)(const T *, A0, A1, A2, A3))
4714 {
4715  return Callback<R(A0, A1, A2, A3)>(func, obj);
4716 }
4717 
4718 /** Create a callback class with type inferred from the arguments
4719  *
4720  * @param obj Optional pointer to object to bind to function
4721  * @param func Static function to attach
4722  * @return Callback with inferred type
4723  * @deprecated
4724  * Arguments to callback have been reordered to callback(func, arg)
4725  */
4726 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4727 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4728  "Arguments to callback have been reordered to callback(func, arg)")
4729 Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R(*func)(volatile T *, A0, A1, A2, A3))
4730 {
4731  return Callback<R(A0, A1, A2, A3)>(func, obj);
4732 }
4733 
4734 /** Create a callback class with type inferred from the arguments
4735  *
4736  * @param obj Optional pointer to object to bind to function
4737  * @param func Static function to attach
4738  * @return Callback with inferred type
4739  * @deprecated
4740  * Arguments to callback have been reordered to callback(func, arg)
4741  */
4742 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
4743 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4744  "Arguments to callback have been reordered to callback(func, arg)")
4745 Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3))
4746 {
4747  return Callback<R(A0, A1, A2, A3)>(func, obj);
4748 }
4749 
4750 
4751 /** Create a callback class with type inferred from the arguments
4752  *
4753  * @param func Static function to attach
4754  * @return Callback with inferred type
4755  */
4756 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4757 Callback<R(A0, A1, A2, A3, A4)> callback(R(*func)(A0, A1, A2, A3, A4) = 0)
4758 {
4759  return Callback<R(A0, A1, A2, A3, A4)>(func);
4760 }
4761 
4762 /** Create a callback class with type inferred from the arguments
4763  *
4764  * @param func Static function to attach
4765  * @return Callback with inferred type
4766  */
4767 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4768 Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func)
4769 {
4770  return Callback<R(A0, A1, A2, A3, A4)>(func);
4771 }
4772 
4773 /** Create a callback class with type inferred from the arguments
4774  *
4775  * @param obj Optional pointer to object to bind to function
4776  * @param method Member function to attach
4777  * @return Callback with inferred type
4778  */
4779 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4780 Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R(T::*method)(A0, A1, A2, A3, A4))
4781 {
4782  return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
4783 }
4784 
4785 /** Create a callback class with type inferred from the arguments
4786  *
4787  * @param obj Optional pointer to object to bind to function
4788  * @param method Member function to attach
4789  * @return Callback with inferred type
4790  */
4791 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4792 Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R(T::*method)(A0, A1, A2, A3, A4) const)
4793 {
4794  return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
4795 }
4796 
4797 /** Create a callback class with type inferred from the arguments
4798  *
4799  * @param obj Optional pointer to object to bind to function
4800  * @param method Member function to attach
4801  * @return Callback with inferred type
4802  */
4803 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4804 Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile)
4805 {
4806  return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
4807 }
4808 
4809 /** Create a callback class with type inferred from the arguments
4810  *
4811  * @param obj Optional pointer to object to bind to function
4812  * @param method Member function to attach
4813  * @return Callback with inferred type
4814  */
4815 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4816 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile)
4817 {
4818  return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
4819 }
4820 
4821 /** Create a callback class with type inferred from the arguments
4822  *
4823  * @param func Static function to attach
4824  * @param arg Pointer argument to function
4825  * @return Callback with inferred type
4826  */
4827 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4828 Callback<R(A0, A1, A2, A3, A4)> callback(R(*func)(T *, A0, A1, A2, A3, A4), U *arg)
4829 {
4830  return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
4831 }
4832 
4833 /** Create a callback class with type inferred from the arguments
4834  *
4835  * @param func Static function to attach
4836  * @param arg Pointer argument to function
4837  * @return Callback with inferred type
4838  */
4839 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4840 Callback<R(A0, A1, A2, A3, A4)> callback(R(*func)(const T *, A0, A1, A2, A3, A4), const U *arg)
4841 {
4842  return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
4843 }
4844 
4845 /** Create a callback class with type inferred from the arguments
4846  *
4847  * @param func Static function to attach
4848  * @param arg Pointer argument to function
4849  * @return Callback with inferred type
4850  */
4851 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4852 Callback<R(A0, A1, A2, A3, A4)> callback(R(*func)(volatile T *, A0, A1, A2, A3, A4), volatile U *arg)
4853 {
4854  return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
4855 }
4856 
4857 /** Create a callback class with type inferred from the arguments
4858  *
4859  * @param func Static function to attach
4860  * @param arg Pointer argument to function
4861  * @return Callback with inferred type
4862  */
4863 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4864 Callback<R(A0, A1, A2, A3, A4)> callback(R(*func)(const volatile T *, A0, A1, A2, A3, A4), const volatile U *arg)
4865 {
4866  return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
4867 }
4868 
4869 /** Create a callback class with type inferred from the arguments
4870  *
4871  * @param obj Optional pointer to object to bind to function
4872  * @param func Static function to attach
4873  * @return Callback with inferred type
4874  * @deprecated
4875  * Arguments to callback have been reordered to callback(func, arg)
4876  */
4877 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4878 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4879  "Arguments to callback have been reordered to callback(func, arg)")
4880 Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R(*func)(T *, A0, A1, A2, A3, A4))
4881 {
4882  return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
4883 }
4884 
4885 /** Create a callback class with type inferred from the arguments
4886  *
4887  * @param obj Optional pointer to object to bind to function
4888  * @param func Static function to attach
4889  * @return Callback with inferred type
4890  * @deprecated
4891  * Arguments to callback have been reordered to callback(func, arg)
4892  */
4893 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4894 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4895  "Arguments to callback have been reordered to callback(func, arg)")
4896 Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R(*func)(const T *, A0, A1, A2, A3, A4))
4897 {
4898  return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
4899 }
4900 
4901 /** Create a callback class with type inferred from the arguments
4902  *
4903  * @param obj Optional pointer to object to bind to function
4904  * @param func Static function to attach
4905  * @return Callback with inferred type
4906  * @deprecated
4907  * Arguments to callback have been reordered to callback(func, arg)
4908  */
4909 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4910 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4911  "Arguments to callback have been reordered to callback(func, arg)")
4912 Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R(*func)(volatile T *, A0, A1, A2, A3, A4))
4913 {
4914  return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
4915 }
4916 
4917 /** Create a callback class with type inferred from the arguments
4918  *
4919  * @param obj Optional pointer to object to bind to function
4920  * @param func Static function to attach
4921  * @return Callback with inferred type
4922  * @deprecated
4923  * Arguments to callback have been reordered to callback(func, arg)
4924  */
4925 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
4926 MBED_DEPRECATED_SINCE("mbed-os-5.1",
4927  "Arguments to callback have been reordered to callback(func, arg)")
4928 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3, A4))
4929 {
4930  return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
4931 }
4932 
4933 /**@}*/
4934 
4935 /**@}*/
4936 
4937 } // namespace mbed
4938 
4939 #endif
Callback(R(*func)(A0, A1, A2)=0)
Create a Callback with a static function.
Definition: Callback.h:1958
Callback(const Callback< R()> &func)
Attach a Callback.
Definition: Callback.h:95
Callback(const U *obj, R(T::*method)(A0) const)
Create a Callback with a member function.
Definition: Callback.h:742
~Callback()
Destroy a callback.
Definition: Callback.h:3411
Callback(const Callback< R(A0, A1, A2)> &func)
Attach a Callback.
Definition: Callback.h:1970
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Definition: Callback.h:1839
Callback(R(*func)(volatile T *, A0, A1), volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:1417
Callback(R(*func)(volatile T *, A0, A1, A2, A3, A4), volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:3298
static R thunk(void *func, A0 a0, A1 a1)
Static thunk for passing as C-style function.
Definition: Callback.h:1858
Callback(R(*func)(const T *, A0, A1, A2, A3, A4), const U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:3288
Callback(const F f,)
Create a Callback with a function object.
Definition: Callback.h:2700
Callback(R(*func)(T *, A0, A1), U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:1397
Callback(U *obj, R(T::*method)())
Create a Callback with a member function.
Definition: Callback.h:108
R call(A0 a0, A1 a1, A2 a2) const
Call the attached function.
Definition: Callback.h:2443
Callback(R(*func)(const volatile T *, A0, A1, A2, A3), const volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2680
Callback(U *obj, R(T::*method)(A0, A1, A2))
Create a Callback with a member function.
Definition: Callback.h:1983
Callback(const Callback< R(A0, A1, A2, A3)> &func)
Attach a Callback.
Definition: Callback.h:2597
Callback(const F f,)
Create a Callback with a function object.
Definition: Callback.h:1447
Callback(volatile U *obj, R(T::*method)(A0) volatile)
Create a Callback with a member function.
Definition: Callback.h:752
R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const
Call the attached function.
Definition: Callback.h:3078
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Definition: Callback.h:3720
Callback(const volatile U *obj, R(T::*method)() const volatile)
Create a Callback with a member function.
Definition: Callback.h:138
Callback(R(*func)(A0, A1, A2, A3, A4)=0)
Create a Callback with a static function.
Definition: Callback.h:3213
Callback< R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R(*func)(const volatile T *, A0, A1, A2, A3, A4))
Create a callback class with type inferred from the arguments.
Definition: Callback.h:4928
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Definition: Callback.h:1214
Callback(volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile)
Create a Callback with a member function.
Definition: Callback.h:3258
Callback(volatile U *obj, R(T::*method)() volatile)
Create a Callback with a member function.
Definition: Callback.h:128
R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const
Call the attached function.
Definition: Callback.h:3698
Callback & operator=(const Callback &that)
Assign a callback.
Definition: Callback.h:556
Callback(const volatile U *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile)
Create a Callback with a member function.
Definition: Callback.h:3268
Callback(volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:2710
Callback(const volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:842
Callback(F f,)
Create a Callback with a function object.
Definition: Callback.h:2063
Callback class based on template specialization.
Definition: Callback.h:1327
~Callback()
Destroy a callback.
Definition: Callback.h:281
Callback class based on template specialization.
Definition: Callback.h:702
R call(A0 a0, A1 a1, A2 a2, A3 a3) const
Call the attached function.
Definition: Callback.h:3070
Callback(const Callback< R(A0, A1)> &func)
Attach a Callback.
Definition: Callback.h:1344
Callback(R(*func)(volatile T *), volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:168
Callback(R(*func)(T *, A0, A1, A2, A3), U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2650
Callback(R(*func)(const T *), const U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:158
Callback(R(*func)(A0)=0)
Create a Callback with a static function.
Definition: Callback.h:707
Callback(R(*func)(const T *, A0, A1, A2, A3), const U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2660
Callback(R(*func)(T *), U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:148
Callback & operator=(const Callback &that)
Assign a callback.
Definition: Callback.h:3686
Callback(F f,)
Create a Callback with a function object.
Definition: Callback.h:812
R operator()() const
Call the attached function.
Definition: Callback.h:576
R operator()(A0 a0) const
Call the attached function.
Definition: Callback.h:1200
Callback(R(*func)(A0, A1, A2, A3)=0)
Create a Callback with a static function.
Definition: Callback.h:2585
Callback(volatile U *obj, R(T::*method)(A0, A1, A2, A3) volatile)
Create a Callback with a member function.
Definition: Callback.h:2630
R call() const
Call the attached function.
Definition: Callback.h:568
Callback(const F f,)
Create a Callback with a function object.
Definition: Callback.h:2073
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.
Definition: Callback.h:1846
Callback(R(*func)(const T *, A0, A1), const U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:1407
Callback(R(*func)()=0)
Create a Callback with a static function.
Definition: Callback.h:83
static R thunk(void *func, A0 a0)
Static thunk for passing as C-style function.
Definition: Callback.h:1232
Callback(const F f,)
Create a Callback with a function object.
Definition: Callback.h:3328
Callback(R(*func)(A0, A1)=0)
Create a Callback with a static function.
Definition: Callback.h:1332
Callback(R(*func)(volatile T *, A0, A1, A2, A3), volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2670
Callback(const volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:3348
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.
Definition: Callback.h:3727
Callback(volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:3338
Callback(const volatile U *obj, R(T::*method)(A0) const volatile)
Create a Callback with a member function.
Definition: Callback.h:762
Callback(const volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:218
Callback class based on template specialization.
Definition: Callback.h:1953
static R thunk(void *func, A0 a0, A1 a1, A2 a2)
Static thunk for passing as C-style function.
Definition: Callback.h:2485
Callback(F f,)
Create a Callback with a function object.
Definition: Callback.h:1437
R call(A0 a0) const
Call the attached function.
Definition: Callback.h:1192
Callback(const volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:2720
Callback(R(*func)(const volatile T *), const volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:178
Callback(const Callback< R(A0, A1, A2, A3, A4)> &func)
Attach a Callback.
Definition: Callback.h:3225
R operator()(A0 a0, A1 a1) const
Call the attached function.
Definition: Callback.h:1825
Callback(U *obj, R(T::*method)(A0, A1, A2, A3, A4))
Create a Callback with a member function.
Definition: Callback.h:3238
Callback(const U *obj, R(T::*method)(A0, A1, A2, A3) const)
Create a Callback with a member function.
Definition: Callback.h:2620
Callback(const volatile U *obj, R(T::*method)(A0, A1, A2, A3) const volatile)
Create a Callback with a member function.
Definition: Callback.h:2640
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:65
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Definition: Callback.h:3092
Callback(R(*func)(const volatile T *, A0, A1, A2, A3, A4), const volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:3308
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.
Definition: Callback.h:1221
Callback(const U *obj, R(T::*method)(A0, A1, A2) const)
Create a Callback with a member function.
Definition: Callback.h:1993
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.
Definition: Callback.h:597
~Callback()
Destroy a callback.
Definition: Callback.h:905
Callback & operator=(const Callback &that)
Assign a callback.
Definition: Callback.h:3058
Callback(volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:208
static R thunk(void *func)
Static thunk for passing as C-style function.
Definition: Callback.h:607
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.
Definition: Callback.h:3099
Callback(R(*func)(T *, A0, A1, A2, A3, A4), U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:3278
R call(A0 a0, A1 a1) const
Call the attached function.
Definition: Callback.h:1817
~Callback()
Destroy a callback.
Definition: Callback.h:1530
Callback(F f,)
Create a Callback with a function object.
Definition: Callback.h:188
Callback(const Callback< R(A0)> &func)
Attach a Callback.
Definition: Callback.h:719
Callback class based on template specialization.
Definition: Callback.h:78
Callback(const volatile U *obj, R(T::*method)(A0, A1) const volatile)
Create a Callback with a member function.
Definition: Callback.h:1387
Callback(volatile U *obj, R(T::*method)(A0, A1) volatile)
Create a Callback with a member function.
Definition: Callback.h:1377
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Definition: Callback.h:2465
Callback(U *obj, R(T::*method)(A0, A1))
Create a Callback with a member function.
Definition: Callback.h:1357
Callback(const U *obj, R(T::*method)(A0, A1, A2, A3, A4) const)
Create a Callback with a member function.
Definition: Callback.h:3248
Callback(const F f,)
Create a Callback with a function object.
Definition: Callback.h:198
~Callback()
Destroy a callback.
Definition: Callback.h:2156
Callback class based on template specialization.
Definition: Callback.h:2580
Callback(volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:2083
Callback(R(*func)(const T *, A0, A1, A2), const U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2033
Callback(const volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:2093
Callback(const volatile U *obj, R(T::*method)(A0, A1, A2) const volatile)
Create a Callback with a member function.
Definition: Callback.h:2013
Callback(const U *obj, R(T::*method)() const)
Create a Callback with a member function.
Definition: Callback.h:118
Callback(R(*func)(const volatile T *, A0, A1), const volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:1427
~Callback()
Destroy a callback.
Definition: Callback.h:2783
Callback(U *obj, R(T::*method)(A0))
Create a Callback with a member function.
Definition: Callback.h:732
Callback(volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:832
Callback(volatile U *obj, R(T::*method)(A0, A1, A2) volatile)
Create a Callback with a member function.
Definition: Callback.h:2003
Callback(R(*func)(volatile T *, A0, A1, A2), volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2043
R operator()(A0 a0, A1 a1, A2 a2) const
Call the attached function.
Definition: Callback.h:2451
friend bool operator==(const Callback &l, const Callback &r)
Test for equality.
Definition: Callback.h:590
Callback class based on template specialization.
Definition: Callback.h:3208
Callback(const F f,)
Create a Callback with a function object.
Definition: Callback.h:822
Callback & operator=(const Callback &that)
Assign a callback.
Definition: Callback.h:1180
Callback(volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:1457
Callback(const volatile F f,)
Create a Callback with a function object.
Definition: Callback.h:1467
Callback(R(*func)(const volatile T *, A0), const volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:802
static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3)
Static thunk for passing as C-style function.
Definition: Callback.h:3113
Callback class based on template specialization.
Definition: Callback.h:39
Definition: AnalogIn.h:28
#define MBED_STATIC_ASSERT(expr, msg)
MBED_STATIC_ASSERT Declare compile-time assertions, results in compile-time error if condition is fal...
Definition: mbed_assert.h:110
Callback(const U *obj, R(T::*method)(A0, A1) const)
Create a Callback with a member function.
Definition: Callback.h:1367
Callback & operator=(const Callback &that)
Assign a callback.
Definition: Callback.h:1805
Callback & operator=(const Callback &that)
Assign a callback.
Definition: Callback.h:2431
static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
Static thunk for passing as C-style function.
Definition: Callback.h:3742
Callback(U *obj, R(T::*method)(A0, A1, A2, A3))
Create a Callback with a member function.
Definition: Callback.h:2610
Callback(R(*func)(T *, A0), U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:772
Callback(F f,)
Create a Callback with a function object.
Definition: Callback.h:3318
Callback(R(*func)(const volatile T *, A0, A1, A2), const volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2053
#define MBED_DEPRECATED_SINCE(D, M)
MBED_DEPRECATED("message string") Mark a function declaration as deprecated, if it used then a warnin...
R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const
Call the attached function.
Definition: Callback.h:3706
Callback(R(*func)(volatile T *, A0), volatile U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:792
Callback(F f,)
Create a Callback with a function object.
Definition: Callback.h:2690
Callback(R(*func)(const T *, A0), const U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:782
Callback(R(*func)(T *, A0, A1, A2), U *arg)
Create a Callback with a static function and bound pointer.
Definition: Callback.h:2023
friend bool operator!=(const Callback &l, const Callback &r)
Test for inequality.
Definition: Callback.h:2472
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.