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);
Composer.h@14:79be4e700cc9, 2016-04-17 (annotated)
- Committer:
- Christopher Haster
- Date:
- Sun Apr 17 21:25:00 2016 -0500
- Revision:
- 14:79be4e700cc9
- Parent:
- 13:4d8a50d4967e
- Child:
- 18:a0fde14b6c39
Removed funcptr namespace
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Christopher Haster |
5:5c91c61f50b6 | 1 | /* Composer |
Christopher Haster |
5:5c91c61f50b6 | 2 | * Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 3 | */ |
Christopher Haster |
5:5c91c61f50b6 | 4 | #ifndef COMPOSER_H |
Christopher Haster |
5:5c91c61f50b6 | 5 | #define COMPOSER_H |
Christopher Haster |
5:5c91c61f50b6 | 6 | |
Christopher Haster |
5:5c91c61f50b6 | 7 | #include "FuncPtr.h" |
Christopher Haster |
5:5c91c61f50b6 | 8 | |
Christopher Haster |
5:5c91c61f50b6 | 9 | |
Christopher Haster |
5:5c91c61f50b6 | 10 | /** Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 11 | */ |
Christopher Haster |
5:5c91c61f50b6 | 12 | template <typename F, typename G> |
Christopher Haster |
5:5c91c61f50b6 | 13 | class Composer; |
Christopher Haster |
5:5c91c61f50b6 | 14 | |
Christopher Haster |
5:5c91c61f50b6 | 15 | /** Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 16 | */ |
Christopher Haster |
5:5c91c61f50b6 | 17 | template <typename R, typename B0, typename A0, typename A1, typename A2, typename A3> |
Christopher Haster |
5:5c91c61f50b6 | 18 | class Composer<R(B0), B0(A0, A1, A2, A3)> { |
Christopher Haster |
5:5c91c61f50b6 | 19 | public: |
Christopher Haster |
5:5c91c61f50b6 | 20 | /** Create an uncomposed Composer |
Christopher Haster |
5:5c91c61f50b6 | 21 | */ |
Christopher Haster |
5:5c91c61f50b6 | 22 | Composer() {} |
Christopher Haster |
5:5c91c61f50b6 | 23 | |
Christopher Haster |
5:5c91c61f50b6 | 24 | /** Create a Composer, composing two functions |
Christopher Haster |
5:5c91c61f50b6 | 25 | */ |
Christopher Haster |
5:5c91c61f50b6 | 26 | Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2, A3)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 27 | attach(f, g); |
Christopher Haster |
5:5c91c61f50b6 | 28 | } |
Christopher Haster |
5:5c91c61f50b6 | 29 | |
Christopher Haster |
5:5c91c61f50b6 | 30 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 31 | */ |
Christopher Haster |
5:5c91c61f50b6 | 32 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 33 | Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2, A3)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 34 | attach(fobj, fmethod, g); |
Christopher Haster |
5:5c91c61f50b6 | 35 | } |
Christopher Haster |
5:5c91c61f50b6 | 36 | |
Christopher Haster |
5:5c91c61f50b6 | 37 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 38 | */ |
Christopher Haster |
5:5c91c61f50b6 | 39 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 40 | Composer(FuncPtr<B0(A0, A1, A2, A3)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 41 | attach(f, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 42 | } |
Christopher Haster |
5:5c91c61f50b6 | 43 | |
Christopher Haster |
5:5c91c61f50b6 | 44 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 45 | */ |
Christopher Haster |
5:5c91c61f50b6 | 46 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 47 | Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 48 | attach(fobj, fmethod, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 49 | } |
Christopher Haster |
5:5c91c61f50b6 | 50 | |
Christopher Haster |
5:5c91c61f50b6 | 51 | /** Compose two functions |
Christopher Haster |
5:5c91c61f50b6 | 52 | */ |
Christopher Haster |
5:5c91c61f50b6 | 53 | void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2, A3)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 54 | _f.attach(f); |
Christopher Haster |
5:5c91c61f50b6 | 55 | _g.attach(g); |
Christopher Haster |
5:5c91c61f50b6 | 56 | } |
Christopher Haster |
5:5c91c61f50b6 | 57 | |
Christopher Haster |
5:5c91c61f50b6 | 58 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 59 | */ |
Christopher Haster |
5:5c91c61f50b6 | 60 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 61 | void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2, A3)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 62 | attach(FuncPtr<R(B0)>(fobj, fmethod), g); |
Christopher Haster |
5:5c91c61f50b6 | 63 | } |
Christopher Haster |
5:5c91c61f50b6 | 64 | |
Christopher Haster |
5:5c91c61f50b6 | 65 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 66 | */ |
Christopher Haster |
5:5c91c61f50b6 | 67 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 68 | void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 69 | attach(f, FuncPtr<B0(A0, A1, A2, A3)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 70 | } |
Christopher Haster |
5:5c91c61f50b6 | 71 | |
Christopher Haster |
5:5c91c61f50b6 | 72 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 73 | */ |
Christopher Haster |
5:5c91c61f50b6 | 74 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 75 | void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 76 | attach(FuncPtr<R(B0)>(fobj, fmethod), |
Christopher Haster |
5:5c91c61f50b6 | 77 | FuncPtr<B0(A0, A1, A2, A3)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 78 | } |
Christopher Haster |
5:5c91c61f50b6 | 79 | |
Christopher Haster |
5:5c91c61f50b6 | 80 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 81 | */ |
Christopher Haster |
5:5c91c61f50b6 | 82 | R call(A0 a0, A1 a1, A2 a2, A3 a3) { |
Christopher Haster |
5:5c91c61f50b6 | 83 | return _f(_g(a0, a1, a2, a3)); |
Christopher Haster |
5:5c91c61f50b6 | 84 | } |
Christopher Haster |
5:5c91c61f50b6 | 85 | |
Christopher Haster |
5:5c91c61f50b6 | 86 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 87 | */ |
Christopher Haster |
5:5c91c61f50b6 | 88 | R operator()(A0 a0, A1 a1, A2 a2, A3 a3) { |
Christopher Haster |
5:5c91c61f50b6 | 89 | return call(a0, a1, a2, a3); |
Christopher Haster |
5:5c91c61f50b6 | 90 | } |
Christopher Haster |
5:5c91c61f50b6 | 91 | |
Christopher Haster |
5:5c91c61f50b6 | 92 | /** Test if functions have been composed |
Christopher Haster |
5:5c91c61f50b6 | 93 | */ |
Christopher Haster |
8:71037a47492d | 94 | operator bool() const { |
Christopher Haster |
5:5c91c61f50b6 | 95 | return _f && _g; |
Christopher Haster |
5:5c91c61f50b6 | 96 | } |
Christopher Haster |
5:5c91c61f50b6 | 97 | |
Christopher Haster |
5:5c91c61f50b6 | 98 | /** Static thunk for passing as C-style function |
Christopher Haster |
5:5c91c61f50b6 | 99 | * @param func Composer to call passed as void pointer |
Christopher Haster |
5:5c91c61f50b6 | 100 | */ |
Christopher Haster |
5:5c91c61f50b6 | 101 | static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) { |
Christopher Haster |
5:5c91c61f50b6 | 102 | return static_cast<Composer<R(B0), B0(A0, A1, A2, A3)>*>(func) |
Christopher Haster |
5:5c91c61f50b6 | 103 | ->call(a0, a1, a2, a3); |
Christopher Haster |
5:5c91c61f50b6 | 104 | } |
Christopher Haster |
5:5c91c61f50b6 | 105 | |
Christopher Haster |
5:5c91c61f50b6 | 106 | private: |
Christopher Haster |
5:5c91c61f50b6 | 107 | FuncPtr<R(B0)> _f; |
Christopher Haster |
5:5c91c61f50b6 | 108 | FuncPtr<B0(A0, A1, A2, A3)> _g; |
Christopher Haster |
5:5c91c61f50b6 | 109 | }; |
Christopher Haster |
5:5c91c61f50b6 | 110 | |
Christopher Haster |
5:5c91c61f50b6 | 111 | /** Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 112 | */ |
Christopher Haster |
5:5c91c61f50b6 | 113 | template <typename R, typename B0, typename A0, typename A1, typename A2> |
Christopher Haster |
5:5c91c61f50b6 | 114 | class Composer<R(B0), B0(A0, A1, A2)> { |
Christopher Haster |
5:5c91c61f50b6 | 115 | public: |
Christopher Haster |
5:5c91c61f50b6 | 116 | /** Create an uncomposed Composer |
Christopher Haster |
5:5c91c61f50b6 | 117 | */ |
Christopher Haster |
5:5c91c61f50b6 | 118 | Composer() {} |
Christopher Haster |
5:5c91c61f50b6 | 119 | |
Christopher Haster |
5:5c91c61f50b6 | 120 | /** Create a Composer, composing two functions |
Christopher Haster |
5:5c91c61f50b6 | 121 | */ |
Christopher Haster |
5:5c91c61f50b6 | 122 | Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 123 | attach(f, g); |
Christopher Haster |
5:5c91c61f50b6 | 124 | } |
Christopher Haster |
5:5c91c61f50b6 | 125 | |
Christopher Haster |
5:5c91c61f50b6 | 126 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 127 | */ |
Christopher Haster |
5:5c91c61f50b6 | 128 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 129 | Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 130 | attach(fobj, fmethod, g); |
Christopher Haster |
5:5c91c61f50b6 | 131 | } |
Christopher Haster |
5:5c91c61f50b6 | 132 | |
Christopher Haster |
5:5c91c61f50b6 | 133 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 134 | */ |
Christopher Haster |
5:5c91c61f50b6 | 135 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 136 | Composer(FuncPtr<B0(A0, A1, A2)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 137 | attach(f, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 138 | } |
Christopher Haster |
5:5c91c61f50b6 | 139 | |
Christopher Haster |
5:5c91c61f50b6 | 140 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 141 | */ |
Christopher Haster |
5:5c91c61f50b6 | 142 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 143 | Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 144 | attach(fobj, fmethod, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 145 | } |
Christopher Haster |
5:5c91c61f50b6 | 146 | |
Christopher Haster |
5:5c91c61f50b6 | 147 | /** Compose two functions |
Christopher Haster |
5:5c91c61f50b6 | 148 | */ |
Christopher Haster |
5:5c91c61f50b6 | 149 | void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 150 | _f.attach(f); |
Christopher Haster |
5:5c91c61f50b6 | 151 | _g.attach(g); |
Christopher Haster |
5:5c91c61f50b6 | 152 | } |
Christopher Haster |
5:5c91c61f50b6 | 153 | |
Christopher Haster |
5:5c91c61f50b6 | 154 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 155 | */ |
Christopher Haster |
5:5c91c61f50b6 | 156 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 157 | void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 158 | attach(FuncPtr<R(B0)>(fobj, fmethod), g); |
Christopher Haster |
5:5c91c61f50b6 | 159 | } |
Christopher Haster |
5:5c91c61f50b6 | 160 | |
Christopher Haster |
5:5c91c61f50b6 | 161 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 162 | */ |
Christopher Haster |
5:5c91c61f50b6 | 163 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 164 | void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 165 | attach(f, FuncPtr<B0(A0, A1, A2)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 166 | } |
Christopher Haster |
5:5c91c61f50b6 | 167 | |
Christopher Haster |
5:5c91c61f50b6 | 168 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 169 | */ |
Christopher Haster |
5:5c91c61f50b6 | 170 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 171 | void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 172 | attach(FuncPtr<R(B0)>(fobj, fmethod), |
Christopher Haster |
5:5c91c61f50b6 | 173 | FuncPtr<B0(A0, A1, A2)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 174 | } |
Christopher Haster |
5:5c91c61f50b6 | 175 | |
Christopher Haster |
5:5c91c61f50b6 | 176 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 177 | */ |
Christopher Haster |
5:5c91c61f50b6 | 178 | R call(A0 a0, A1 a1, A2 a2) { |
Christopher Haster |
5:5c91c61f50b6 | 179 | return _f(_g(a0, a1, a2)); |
Christopher Haster |
5:5c91c61f50b6 | 180 | } |
Christopher Haster |
5:5c91c61f50b6 | 181 | |
Christopher Haster |
5:5c91c61f50b6 | 182 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 183 | */ |
Christopher Haster |
5:5c91c61f50b6 | 184 | R operator()(A0 a0, A1 a1, A2 a2) { |
Christopher Haster |
5:5c91c61f50b6 | 185 | return call(a0, a1, a2); |
Christopher Haster |
5:5c91c61f50b6 | 186 | } |
Christopher Haster |
5:5c91c61f50b6 | 187 | |
Christopher Haster |
5:5c91c61f50b6 | 188 | /** Test if functions have been composed |
Christopher Haster |
5:5c91c61f50b6 | 189 | */ |
Christopher Haster |
8:71037a47492d | 190 | operator bool() const { |
Christopher Haster |
5:5c91c61f50b6 | 191 | return _f && _g; |
Christopher Haster |
5:5c91c61f50b6 | 192 | } |
Christopher Haster |
5:5c91c61f50b6 | 193 | |
Christopher Haster |
5:5c91c61f50b6 | 194 | /** Static thunk for passing as C-style function |
Christopher Haster |
5:5c91c61f50b6 | 195 | * @param func Composer to call passed as void pointer |
Christopher Haster |
5:5c91c61f50b6 | 196 | */ |
Christopher Haster |
5:5c91c61f50b6 | 197 | static R thunk(void *func, A0 a0, A1 a1, A2 a2) { |
Christopher Haster |
5:5c91c61f50b6 | 198 | return static_cast<Composer<R(B0), B0(A0, A1, A2)>*>(func) |
Christopher Haster |
5:5c91c61f50b6 | 199 | ->call(a0, a1, a2); |
Christopher Haster |
5:5c91c61f50b6 | 200 | } |
Christopher Haster |
5:5c91c61f50b6 | 201 | |
Christopher Haster |
5:5c91c61f50b6 | 202 | private: |
Christopher Haster |
5:5c91c61f50b6 | 203 | FuncPtr<R(B0)> _f; |
Christopher Haster |
5:5c91c61f50b6 | 204 | FuncPtr<B0(A0, A1, A2)> _g; |
Christopher Haster |
5:5c91c61f50b6 | 205 | }; |
Christopher Haster |
5:5c91c61f50b6 | 206 | |
Christopher Haster |
5:5c91c61f50b6 | 207 | /** Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 208 | */ |
Christopher Haster |
5:5c91c61f50b6 | 209 | template <typename R, typename B0, typename A0, typename A1> |
Christopher Haster |
5:5c91c61f50b6 | 210 | class Composer<R(B0), B0(A0, A1)> { |
Christopher Haster |
5:5c91c61f50b6 | 211 | public: |
Christopher Haster |
5:5c91c61f50b6 | 212 | /** Create an uncomposed Composer |
Christopher Haster |
5:5c91c61f50b6 | 213 | */ |
Christopher Haster |
5:5c91c61f50b6 | 214 | Composer() {} |
Christopher Haster |
5:5c91c61f50b6 | 215 | |
Christopher Haster |
5:5c91c61f50b6 | 216 | /** Create a Composer, composing two functions |
Christopher Haster |
5:5c91c61f50b6 | 217 | */ |
Christopher Haster |
5:5c91c61f50b6 | 218 | Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 219 | attach(f, g); |
Christopher Haster |
5:5c91c61f50b6 | 220 | } |
Christopher Haster |
5:5c91c61f50b6 | 221 | |
Christopher Haster |
5:5c91c61f50b6 | 222 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 223 | */ |
Christopher Haster |
5:5c91c61f50b6 | 224 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 225 | Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 226 | attach(fobj, fmethod, g); |
Christopher Haster |
5:5c91c61f50b6 | 227 | } |
Christopher Haster |
5:5c91c61f50b6 | 228 | |
Christopher Haster |
5:5c91c61f50b6 | 229 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 230 | */ |
Christopher Haster |
5:5c91c61f50b6 | 231 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 232 | Composer(FuncPtr<B0(A0, A1)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 233 | attach(f, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 234 | } |
Christopher Haster |
5:5c91c61f50b6 | 235 | |
Christopher Haster |
5:5c91c61f50b6 | 236 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 237 | */ |
Christopher Haster |
5:5c91c61f50b6 | 238 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 239 | Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 240 | attach(fobj, fmethod, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 241 | } |
Christopher Haster |
5:5c91c61f50b6 | 242 | |
Christopher Haster |
5:5c91c61f50b6 | 243 | /** Compose two functions |
Christopher Haster |
5:5c91c61f50b6 | 244 | */ |
Christopher Haster |
5:5c91c61f50b6 | 245 | void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 246 | _f.attach(f); |
Christopher Haster |
5:5c91c61f50b6 | 247 | _g.attach(g); |
Christopher Haster |
5:5c91c61f50b6 | 248 | } |
Christopher Haster |
5:5c91c61f50b6 | 249 | |
Christopher Haster |
5:5c91c61f50b6 | 250 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 251 | */ |
Christopher Haster |
5:5c91c61f50b6 | 252 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 253 | void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 254 | attach(FuncPtr<R(B0)>(fobj, fmethod), g); |
Christopher Haster |
5:5c91c61f50b6 | 255 | } |
Christopher Haster |
5:5c91c61f50b6 | 256 | |
Christopher Haster |
5:5c91c61f50b6 | 257 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 258 | */ |
Christopher Haster |
5:5c91c61f50b6 | 259 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 260 | void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 261 | attach(f, FuncPtr<B0(A0, A1)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 262 | } |
Christopher Haster |
5:5c91c61f50b6 | 263 | |
Christopher Haster |
5:5c91c61f50b6 | 264 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 265 | */ |
Christopher Haster |
5:5c91c61f50b6 | 266 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 267 | void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 268 | attach(FuncPtr<R(B0)>(fobj, fmethod), |
Christopher Haster |
5:5c91c61f50b6 | 269 | FuncPtr<B0(A0, A1)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 270 | } |
Christopher Haster |
5:5c91c61f50b6 | 271 | |
Christopher Haster |
5:5c91c61f50b6 | 272 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 273 | */ |
Christopher Haster |
5:5c91c61f50b6 | 274 | R call(A0 a0, A1 a1) { |
Christopher Haster |
5:5c91c61f50b6 | 275 | return _f(_g(a0, a1)); |
Christopher Haster |
5:5c91c61f50b6 | 276 | } |
Christopher Haster |
5:5c91c61f50b6 | 277 | |
Christopher Haster |
5:5c91c61f50b6 | 278 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 279 | */ |
Christopher Haster |
5:5c91c61f50b6 | 280 | R operator()(A0 a0, A1 a1) { |
Christopher Haster |
5:5c91c61f50b6 | 281 | return call(a0, a1); |
Christopher Haster |
5:5c91c61f50b6 | 282 | } |
Christopher Haster |
5:5c91c61f50b6 | 283 | |
Christopher Haster |
5:5c91c61f50b6 | 284 | /** Test if functions have been composed |
Christopher Haster |
5:5c91c61f50b6 | 285 | */ |
Christopher Haster |
8:71037a47492d | 286 | operator bool() const { |
Christopher Haster |
5:5c91c61f50b6 | 287 | return _f && _g; |
Christopher Haster |
5:5c91c61f50b6 | 288 | } |
Christopher Haster |
5:5c91c61f50b6 | 289 | |
Christopher Haster |
5:5c91c61f50b6 | 290 | /** Static thunk for passing as C-style function |
Christopher Haster |
5:5c91c61f50b6 | 291 | * @param func Composer to call passed as void pointer |
Christopher Haster |
5:5c91c61f50b6 | 292 | */ |
Christopher Haster |
5:5c91c61f50b6 | 293 | static R thunk(void *func, A0 a0, A1 a1) { |
Christopher Haster |
5:5c91c61f50b6 | 294 | return static_cast<Composer<R(B0), B0(A0, A1)>*>(func) |
Christopher Haster |
5:5c91c61f50b6 | 295 | ->call(a0, a1); |
Christopher Haster |
5:5c91c61f50b6 | 296 | } |
Christopher Haster |
5:5c91c61f50b6 | 297 | |
Christopher Haster |
5:5c91c61f50b6 | 298 | private: |
Christopher Haster |
5:5c91c61f50b6 | 299 | FuncPtr<R(B0)> _f; |
Christopher Haster |
5:5c91c61f50b6 | 300 | FuncPtr<B0(A0, A1)> _g; |
Christopher Haster |
5:5c91c61f50b6 | 301 | }; |
Christopher Haster |
5:5c91c61f50b6 | 302 | |
Christopher Haster |
5:5c91c61f50b6 | 303 | /** Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 304 | */ |
Christopher Haster |
5:5c91c61f50b6 | 305 | template <typename R, typename B0, typename A0> |
Christopher Haster |
5:5c91c61f50b6 | 306 | class Composer<R(B0), B0(A0)> { |
Christopher Haster |
5:5c91c61f50b6 | 307 | public: |
Christopher Haster |
5:5c91c61f50b6 | 308 | /** Create an uncomposed Composer |
Christopher Haster |
5:5c91c61f50b6 | 309 | */ |
Christopher Haster |
5:5c91c61f50b6 | 310 | Composer() {} |
Christopher Haster |
5:5c91c61f50b6 | 311 | |
Christopher Haster |
5:5c91c61f50b6 | 312 | /** Create a Composer, composing two functions |
Christopher Haster |
5:5c91c61f50b6 | 313 | */ |
Christopher Haster |
5:5c91c61f50b6 | 314 | Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 315 | attach(f, g); |
Christopher Haster |
5:5c91c61f50b6 | 316 | } |
Christopher Haster |
5:5c91c61f50b6 | 317 | |
Christopher Haster |
5:5c91c61f50b6 | 318 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 319 | */ |
Christopher Haster |
5:5c91c61f50b6 | 320 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 321 | Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 322 | attach(fobj, fmethod, g); |
Christopher Haster |
5:5c91c61f50b6 | 323 | } |
Christopher Haster |
5:5c91c61f50b6 | 324 | |
Christopher Haster |
5:5c91c61f50b6 | 325 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 326 | */ |
Christopher Haster |
5:5c91c61f50b6 | 327 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 328 | Composer(FuncPtr<B0(A0)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 329 | attach(f, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 330 | } |
Christopher Haster |
5:5c91c61f50b6 | 331 | |
Christopher Haster |
5:5c91c61f50b6 | 332 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 333 | */ |
Christopher Haster |
5:5c91c61f50b6 | 334 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 335 | Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 336 | attach(fobj, fmethod, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 337 | } |
Christopher Haster |
5:5c91c61f50b6 | 338 | |
Christopher Haster |
5:5c91c61f50b6 | 339 | /** Compose two functions |
Christopher Haster |
5:5c91c61f50b6 | 340 | */ |
Christopher Haster |
5:5c91c61f50b6 | 341 | void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 342 | _f.attach(f); |
Christopher Haster |
5:5c91c61f50b6 | 343 | _g.attach(g); |
Christopher Haster |
5:5c91c61f50b6 | 344 | } |
Christopher Haster |
5:5c91c61f50b6 | 345 | |
Christopher Haster |
5:5c91c61f50b6 | 346 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 347 | */ |
Christopher Haster |
5:5c91c61f50b6 | 348 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 349 | void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0)> g) { |
Christopher Haster |
5:5c91c61f50b6 | 350 | attach(FuncPtr<R(B0)>(fobj, fmethod), g); |
Christopher Haster |
5:5c91c61f50b6 | 351 | } |
Christopher Haster |
5:5c91c61f50b6 | 352 | |
Christopher Haster |
5:5c91c61f50b6 | 353 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 354 | */ |
Christopher Haster |
5:5c91c61f50b6 | 355 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 356 | void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 357 | attach(f, FuncPtr<B0(A0)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 358 | } |
Christopher Haster |
5:5c91c61f50b6 | 359 | |
Christopher Haster |
5:5c91c61f50b6 | 360 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 361 | */ |
Christopher Haster |
5:5c91c61f50b6 | 362 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 363 | void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 364 | attach(FuncPtr<R(B0)>(fobj, fmethod), |
Christopher Haster |
5:5c91c61f50b6 | 365 | FuncPtr<B0(A0)>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 366 | } |
Christopher Haster |
5:5c91c61f50b6 | 367 | |
Christopher Haster |
5:5c91c61f50b6 | 368 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 369 | */ |
Christopher Haster |
5:5c91c61f50b6 | 370 | R call(A0 a0) { |
Christopher Haster |
5:5c91c61f50b6 | 371 | return _f(_g(a0)); |
Christopher Haster |
5:5c91c61f50b6 | 372 | } |
Christopher Haster |
5:5c91c61f50b6 | 373 | |
Christopher Haster |
5:5c91c61f50b6 | 374 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 375 | */ |
Christopher Haster |
5:5c91c61f50b6 | 376 | R operator()(A0 a0) { |
Christopher Haster |
5:5c91c61f50b6 | 377 | return call(a0); |
Christopher Haster |
5:5c91c61f50b6 | 378 | } |
Christopher Haster |
5:5c91c61f50b6 | 379 | |
Christopher Haster |
5:5c91c61f50b6 | 380 | /** Test if functions have been composed |
Christopher Haster |
5:5c91c61f50b6 | 381 | */ |
Christopher Haster |
8:71037a47492d | 382 | operator bool() const { |
Christopher Haster |
5:5c91c61f50b6 | 383 | return _f && _g; |
Christopher Haster |
5:5c91c61f50b6 | 384 | } |
Christopher Haster |
5:5c91c61f50b6 | 385 | |
Christopher Haster |
5:5c91c61f50b6 | 386 | /** Static thunk for passing as C-style function |
Christopher Haster |
5:5c91c61f50b6 | 387 | * @param func Composer to call passed as void pointer |
Christopher Haster |
5:5c91c61f50b6 | 388 | */ |
Christopher Haster |
5:5c91c61f50b6 | 389 | static R thunk(void *func, A0 a0) { |
Christopher Haster |
5:5c91c61f50b6 | 390 | return static_cast<Composer<R(B0), B0(A0)>*>(func) |
Christopher Haster |
5:5c91c61f50b6 | 391 | ->call(a0); |
Christopher Haster |
5:5c91c61f50b6 | 392 | } |
Christopher Haster |
5:5c91c61f50b6 | 393 | |
Christopher Haster |
5:5c91c61f50b6 | 394 | private: |
Christopher Haster |
5:5c91c61f50b6 | 395 | FuncPtr<R(B0)> _f; |
Christopher Haster |
5:5c91c61f50b6 | 396 | FuncPtr<B0(A0)> _g; |
Christopher Haster |
5:5c91c61f50b6 | 397 | }; |
Christopher Haster |
5:5c91c61f50b6 | 398 | |
Christopher Haster |
5:5c91c61f50b6 | 399 | /** Static function composition |
Christopher Haster |
5:5c91c61f50b6 | 400 | */ |
Christopher Haster |
5:5c91c61f50b6 | 401 | template <typename R, typename B0> |
Christopher Haster |
5:5c91c61f50b6 | 402 | class Composer<R(B0), B0()> { |
Christopher Haster |
5:5c91c61f50b6 | 403 | public: |
Christopher Haster |
5:5c91c61f50b6 | 404 | /** Create an uncomposed Composer |
Christopher Haster |
5:5c91c61f50b6 | 405 | */ |
Christopher Haster |
5:5c91c61f50b6 | 406 | Composer() {} |
Christopher Haster |
5:5c91c61f50b6 | 407 | |
Christopher Haster |
5:5c91c61f50b6 | 408 | /** Create a Composer, composing two functions |
Christopher Haster |
5:5c91c61f50b6 | 409 | */ |
Christopher Haster |
5:5c91c61f50b6 | 410 | Composer(FuncPtr<R(B0)> f, FuncPtr<B0()> g) { |
Christopher Haster |
5:5c91c61f50b6 | 411 | attach(f, g); |
Christopher Haster |
5:5c91c61f50b6 | 412 | } |
Christopher Haster |
5:5c91c61f50b6 | 413 | |
Christopher Haster |
5:5c91c61f50b6 | 414 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 415 | */ |
Christopher Haster |
5:5c91c61f50b6 | 416 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 417 | Composer(FT *fobj, FM fmethod, FuncPtr<B0()> g) { |
Christopher Haster |
5:5c91c61f50b6 | 418 | attach(fobj, fmethod, g); |
Christopher Haster |
5:5c91c61f50b6 | 419 | } |
Christopher Haster |
5:5c91c61f50b6 | 420 | |
Christopher Haster |
5:5c91c61f50b6 | 421 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 422 | */ |
Christopher Haster |
5:5c91c61f50b6 | 423 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 424 | Composer(FuncPtr<B0()> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 425 | attach(f, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 426 | } |
Christopher Haster |
5:5c91c61f50b6 | 427 | |
Christopher Haster |
5:5c91c61f50b6 | 428 | /** Create a Composer, composing functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 429 | */ |
Christopher Haster |
5:5c91c61f50b6 | 430 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 431 | Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 432 | attach(fobj, fmethod, gobj, gmethod); |
Christopher Haster |
5:5c91c61f50b6 | 433 | } |
Christopher Haster |
5:5c91c61f50b6 | 434 | |
Christopher Haster |
5:5c91c61f50b6 | 435 | /** Compose two functions |
Christopher Haster |
5:5c91c61f50b6 | 436 | */ |
Christopher Haster |
5:5c91c61f50b6 | 437 | void attach(FuncPtr<R(B0)> f, FuncPtr<B0()> g) { |
Christopher Haster |
5:5c91c61f50b6 | 438 | _f.attach(f); |
Christopher Haster |
5:5c91c61f50b6 | 439 | _g.attach(g); |
Christopher Haster |
5:5c91c61f50b6 | 440 | } |
Christopher Haster |
5:5c91c61f50b6 | 441 | |
Christopher Haster |
5:5c91c61f50b6 | 442 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 443 | */ |
Christopher Haster |
5:5c91c61f50b6 | 444 | template <typename FT, typename FM> |
Christopher Haster |
5:5c91c61f50b6 | 445 | void attach(FT *fobj, FM fmethod, FuncPtr<B0()> g) { |
Christopher Haster |
5:5c91c61f50b6 | 446 | attach(FuncPtr<R(B0)>(fobj, fmethod), g); |
Christopher Haster |
5:5c91c61f50b6 | 447 | } |
Christopher Haster |
5:5c91c61f50b6 | 448 | |
Christopher Haster |
5:5c91c61f50b6 | 449 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 450 | */ |
Christopher Haster |
5:5c91c61f50b6 | 451 | template <typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 452 | void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 453 | attach(f, FuncPtr<B0()>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 454 | } |
Christopher Haster |
5:5c91c61f50b6 | 455 | |
Christopher Haster |
5:5c91c61f50b6 | 456 | /** Compose functions and methods |
Christopher Haster |
5:5c91c61f50b6 | 457 | */ |
Christopher Haster |
5:5c91c61f50b6 | 458 | template <typename FT, typename FM, typename GT, typename GM> |
Christopher Haster |
5:5c91c61f50b6 | 459 | void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) { |
Christopher Haster |
5:5c91c61f50b6 | 460 | attach(FuncPtr<R(B0)>(fobj, fmethod), |
Christopher Haster |
5:5c91c61f50b6 | 461 | FuncPtr<B0()>(gobj, gmethod)); |
Christopher Haster |
5:5c91c61f50b6 | 462 | } |
Christopher Haster |
5:5c91c61f50b6 | 463 | |
Christopher Haster |
5:5c91c61f50b6 | 464 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 465 | */ |
Christopher Haster |
5:5c91c61f50b6 | 466 | R call() { |
Christopher Haster |
5:5c91c61f50b6 | 467 | return _f(_g()); |
Christopher Haster |
5:5c91c61f50b6 | 468 | } |
Christopher Haster |
5:5c91c61f50b6 | 469 | |
Christopher Haster |
5:5c91c61f50b6 | 470 | /** Call the composed functions |
Christopher Haster |
5:5c91c61f50b6 | 471 | */ |
Christopher Haster |
5:5c91c61f50b6 | 472 | R operator()() { |
Christopher Haster |
5:5c91c61f50b6 | 473 | return call(); |
Christopher Haster |
5:5c91c61f50b6 | 474 | } |
Christopher Haster |
5:5c91c61f50b6 | 475 | |
Christopher Haster |
5:5c91c61f50b6 | 476 | /** Test if functions have been composed |
Christopher Haster |
5:5c91c61f50b6 | 477 | */ |
Christopher Haster |
8:71037a47492d | 478 | operator bool() const { |
Christopher Haster |
5:5c91c61f50b6 | 479 | return _f && _g; |
Christopher Haster |
5:5c91c61f50b6 | 480 | } |
Christopher Haster |
5:5c91c61f50b6 | 481 | |
Christopher Haster |
5:5c91c61f50b6 | 482 | /** Static thunk for passing as C-style function |
Christopher Haster |
5:5c91c61f50b6 | 483 | * @param func Composer to call passed as void pointer |
Christopher Haster |
5:5c91c61f50b6 | 484 | */ |
Christopher Haster |
5:5c91c61f50b6 | 485 | static R thunk(void *func) { |
Christopher Haster |
5:5c91c61f50b6 | 486 | return static_cast<Composer<R(B0), B0()>*>(func) |
Christopher Haster |
5:5c91c61f50b6 | 487 | ->call(); |
Christopher Haster |
5:5c91c61f50b6 | 488 | } |
Christopher Haster |
5:5c91c61f50b6 | 489 | |
Christopher Haster |
5:5c91c61f50b6 | 490 | private: |
Christopher Haster |
5:5c91c61f50b6 | 491 | FuncPtr<R(B0)> _f; |
Christopher Haster |
5:5c91c61f50b6 | 492 | FuncPtr<B0()> _g; |
Christopher Haster |
5:5c91c61f50b6 | 493 | }; |
Christopher Haster |
5:5c91c61f50b6 | 494 | |
Christopher Haster |
5:5c91c61f50b6 | 495 | |
Christopher Haster |
5:5c91c61f50b6 | 496 | #endif |