diff --git a/hal/api/Callback.h b/hal/api/Callback.h index f8089ed70a..78a3b0e9d1 100644 --- a/hal/api/Callback.h +++ b/hal/api/Callback.h @@ -32,6 +32,30 @@ namespace mbed { template class Callback; +// Internal sfinae declarations +// +// These are used to eliminate overloads based on type attributes +// 1. Does a function object have a call operator +// 2. Does a function object fit in the available storage +// +// These eliminations are handled cleanly by the compiler and avoid +// massive and misleading error messages when confronted with an +// invalid type (or worse, runtime failures) +namespace detail { + struct nil {}; + + template + struct enable_if { typedef R type; }; + + template + struct enable_if {}; + + template + struct is_type { + static const bool value = true; + }; +} + /** Callback class based on template specialization * * @Note Synchronization level: Not protected @@ -164,6 +188,54 @@ public: generate(function_context(func, arg)); } + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -404,6 +476,58 @@ public: new (this) Callback(func, arg); } + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -768,6 +892,54 @@ public: generate(function_context(func, arg)); } + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -1008,6 +1180,58 @@ public: new (this) Callback(func, arg); } + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -1372,6 +1596,54 @@ public: generate(function_context(func, arg)); } + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -1612,6 +1884,58 @@ public: new (this) Callback(func, arg); } + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -1976,6 +2300,54 @@ public: generate(function_context(func, arg)); } + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -2216,6 +2588,58 @@ public: new (this) Callback(func, arg); } + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -2580,6 +3004,54 @@ public: generate(function_context(func, arg)); } + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -2820,6 +3292,58 @@ public: new (this) Callback(func, arg); } + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -3184,6 +3708,54 @@ public: generate(function_context(func, arg)); } + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + + /** Create a Callback with a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + Callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + generate(f); + } + /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -3424,6 +3996,58 @@ public: new (this) Callback(func, arg); } + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + + /** Attach a function object + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ + template + void attach(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + this->~Callback(); + new (this) Callback(f); + } + /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach @@ -3812,6 +4436,54 @@ Callback callback(R (*func)(const volatile T*), const volatile T *arg) { return Callback(func, arg); } +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -4085,6 +4757,54 @@ Callback callback(R (*func)(const volatile T*, A0), const volatile T *arg return Callback(func, arg); } +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -4358,6 +5078,54 @@ Callback callback(R (*func)(const volatile T*, A0, A1), const volatil return Callback(func, arg); } +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -4631,6 +5399,54 @@ Callback callback(R (*func)(const volatile T*, A0, A1, A2), const return Callback(func, arg); } +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -4904,6 +5720,54 @@ Callback callback(R (*func)(const volatile T*, A0, A1, A2, A3 return Callback(func, arg); } +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -5177,6 +6041,54 @@ Callback callback(R (*func)(const volatile T*, A0, A1, A2 return Callback(func, arg); } +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + +/** Create a callback class with type infered from the arguments + * @param func Function object to attach + * @note The function object is limited to a single word of storage + */ +template +Callback callback(const volatile F f, typename detail::enable_if< + detail::is_type::value && + sizeof(F) <= sizeof(uintptr_t) + >::type = detail::nil()) { + return Callback(f); +} + /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function