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