Flexible templated function class and related utilities that avoid dynamic memory allocation without limiting functionality
FuncPtr provides a flexible templated function class and related utilities while avoiding dynamic memory allocation and avoiding limited functionality.
FuncPtr provides an intuitive template interface:
FuncPtr<void(const char *)> func(puts); func("hello!\n"); // prints hello!
Several function types are supported by FuncPtr:
// Simple C functions void func(); FuncPtr<void()> fp(func); // C++ Methods struct Thing { void func(); }; Thing thing; FuncPtr<void()> fp(&thing, &Thing::func); // C functions with context void func(Thing *); FuncPtr<void()> fp(&thing, func); // Function objects struct Thing { void operator()(); }; Thing thing; FuncPtr<void()> fp(&thing);
There is no dynamic memory allocation, managing memory is placed entirely on the user. More advanced function manipulation can be accomplished with statically allocated classes:
// Function binding Binder<void(const char *), const char *> bind(putc, "hi!"); bind(); // prints hi! // Function composition Composer<int(const char *), const char *(int)> comp(puts, itoa); comp(10); // prints 10 // Function chaining Chainer<void(const char *), 2> chain; chain.attach(puts); chain.attach(puts); chain("hi!\n"); // prints hi! twice
FuncPtr allows easy support of a large range of function types in C++ APIs with very few lines of code:
class Thing { public: // The following two methods are sufficient for supporting // every supported function type void attach(FuncPtr<void()> func) { _func.attach(func); } template<typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void()>(obj, method)); } private: FuncPtr<void()> _func; }
Additionally, FuncPtrs have several utilities for easy integration with C APIs:
// C style callbacks void register_callback(void (*callback)(void *), void *data); register_callback(&FuncPtr<void()>::thunk, &func); // C style functions without context void register_callback(void (*callback)()); Thunker thunk(func); register_callback(thunk); // mbed style callbacks void register_callback(T *obj, void (T::*M)()); register_callback(&func, &FuncPtr<void()>::call);
Diff: Binder.h
- Revision:
- 4:627e19790dd9
- Parent:
- 3:84b61e1b050c
- Child:
- 8:71037a47492d
--- a/Binder.h Sun Apr 17 14:23:39 2016 -0500 +++ b/Binder.h Sun Apr 17 14:54:03 2016 -0500 @@ -63,7 +63,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -130,7 +130,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -197,7 +197,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -264,7 +264,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -331,7 +331,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -398,7 +398,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -465,7 +465,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -532,7 +532,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -599,7 +599,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function @@ -666,7 +666,7 @@ /** Test if function has been bound */ operator bool(void) const { - return static_cast<bool>(_func); + return _func; } /** Static thunk for passing as C-style function