Flexible templated function class and related utilities that avoid dynamic memory allocation without limiting functionality

Dependents:   SimpleHTTPExample

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);

Committer:
Christopher Haster
Date:
Sun Apr 17 14:54:18 2016 -0500
Revision:
5:5c91c61f50b6
Child:
8:71037a47492d
Added Composer class for static function composition

Who changed what in which revision?

UserRevisionLine numberNew 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 5:5c91c61f50b6 94 operator bool(void) 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 5:5c91c61f50b6 190 operator bool(void) 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 5:5c91c61f50b6 286 operator bool(void) 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 5:5c91c61f50b6 382 operator bool(void) 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 5:5c91c61f50b6 478 operator bool(void) 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