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 23:38:04 2016 -0500
Revision:
18:a0fde14b6c39
Parent:
14:79be4e700cc9
Increase to 5 args

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 18:a0fde14b6c39 17 template <typename R, typename B0, typename A0, typename A1, typename A2, typename A3, typename A4>
Christopher Haster 18:a0fde14b6c39 18 class Composer<R(B0), B0(A0, A1, A2, A3, A4)> {
Christopher Haster 18:a0fde14b6c39 19 public:
Christopher Haster 18:a0fde14b6c39 20 /** Create an uncomposed Composer
Christopher Haster 18:a0fde14b6c39 21 */
Christopher Haster 18:a0fde14b6c39 22 Composer() {}
Christopher Haster 18:a0fde14b6c39 23
Christopher Haster 18:a0fde14b6c39 24 /** Create a Composer, composing two functions
Christopher Haster 18:a0fde14b6c39 25 */
Christopher Haster 18:a0fde14b6c39 26 Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2, A3, A4)> g) {
Christopher Haster 18:a0fde14b6c39 27 attach(f, g);
Christopher Haster 18:a0fde14b6c39 28 }
Christopher Haster 18:a0fde14b6c39 29
Christopher Haster 18:a0fde14b6c39 30 /** Create a Composer, composing functions and methods
Christopher Haster 18:a0fde14b6c39 31 */
Christopher Haster 18:a0fde14b6c39 32 template <typename FT, typename FM>
Christopher Haster 18:a0fde14b6c39 33 Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2, A3, A4)> g) {
Christopher Haster 18:a0fde14b6c39 34 attach(fobj, fmethod, g);
Christopher Haster 18:a0fde14b6c39 35 }
Christopher Haster 18:a0fde14b6c39 36
Christopher Haster 18:a0fde14b6c39 37 /** Create a Composer, composing functions and methods
Christopher Haster 18:a0fde14b6c39 38 */
Christopher Haster 18:a0fde14b6c39 39 template <typename GT, typename GM>
Christopher Haster 18:a0fde14b6c39 40 Composer(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
Christopher Haster 18:a0fde14b6c39 41 attach(f, gobj, gmethod);
Christopher Haster 18:a0fde14b6c39 42 }
Christopher Haster 18:a0fde14b6c39 43
Christopher Haster 18:a0fde14b6c39 44 /** Create a Composer, composing functions and methods
Christopher Haster 18:a0fde14b6c39 45 */
Christopher Haster 18:a0fde14b6c39 46 template <typename FT, typename FM, typename GT, typename GM>
Christopher Haster 18:a0fde14b6c39 47 Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
Christopher Haster 18:a0fde14b6c39 48 attach(fobj, fmethod, gobj, gmethod);
Christopher Haster 18:a0fde14b6c39 49 }
Christopher Haster 18:a0fde14b6c39 50
Christopher Haster 18:a0fde14b6c39 51 /** Compose two functions
Christopher Haster 18:a0fde14b6c39 52 */
Christopher Haster 18:a0fde14b6c39 53 void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2, A3, A4)> g) {
Christopher Haster 18:a0fde14b6c39 54 _f.attach(f);
Christopher Haster 18:a0fde14b6c39 55 _g.attach(g);
Christopher Haster 18:a0fde14b6c39 56 }
Christopher Haster 18:a0fde14b6c39 57
Christopher Haster 18:a0fde14b6c39 58 /** Compose functions and methods
Christopher Haster 18:a0fde14b6c39 59 */
Christopher Haster 18:a0fde14b6c39 60 template <typename FT, typename FM>
Christopher Haster 18:a0fde14b6c39 61 void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2, A3, A4)> g) {
Christopher Haster 18:a0fde14b6c39 62 attach(FuncPtr<R(B0)>(fobj, fmethod), g);
Christopher Haster 18:a0fde14b6c39 63 }
Christopher Haster 18:a0fde14b6c39 64
Christopher Haster 18:a0fde14b6c39 65 /** Compose functions and methods
Christopher Haster 18:a0fde14b6c39 66 */
Christopher Haster 18:a0fde14b6c39 67 template <typename GT, typename GM>
Christopher Haster 18:a0fde14b6c39 68 void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
Christopher Haster 18:a0fde14b6c39 69 attach(f, FuncPtr<B0(A0, A1, A2, A3, A4)>(gobj, gmethod));
Christopher Haster 18:a0fde14b6c39 70 }
Christopher Haster 18:a0fde14b6c39 71
Christopher Haster 18:a0fde14b6c39 72 /** Compose functions and methods
Christopher Haster 18:a0fde14b6c39 73 */
Christopher Haster 18:a0fde14b6c39 74 template <typename FT, typename FM, typename GT, typename GM>
Christopher Haster 18:a0fde14b6c39 75 void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
Christopher Haster 18:a0fde14b6c39 76 attach(FuncPtr<R(B0)>(fobj, fmethod),
Christopher Haster 18:a0fde14b6c39 77 FuncPtr<B0(A0, A1, A2, A3, A4)>(gobj, gmethod));
Christopher Haster 18:a0fde14b6c39 78 }
Christopher Haster 18:a0fde14b6c39 79
Christopher Haster 18:a0fde14b6c39 80 /** Call the composed functions
Christopher Haster 18:a0fde14b6c39 81 */
Christopher Haster 18:a0fde14b6c39 82 R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 18:a0fde14b6c39 83 return _f(_g(a0, a1, a2, a3, a4));
Christopher Haster 18:a0fde14b6c39 84 }
Christopher Haster 18:a0fde14b6c39 85
Christopher Haster 18:a0fde14b6c39 86 /** Call the composed functions
Christopher Haster 18:a0fde14b6c39 87 */
Christopher Haster 18:a0fde14b6c39 88 R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 18:a0fde14b6c39 89 return call(a0, a1, a2, a3, a4);
Christopher Haster 18:a0fde14b6c39 90 }
Christopher Haster 18:a0fde14b6c39 91
Christopher Haster 18:a0fde14b6c39 92 /** Test if functions have been composed
Christopher Haster 18:a0fde14b6c39 93 */
Christopher Haster 18:a0fde14b6c39 94 operator bool() const {
Christopher Haster 18:a0fde14b6c39 95 return _f && _g;
Christopher Haster 18:a0fde14b6c39 96 }
Christopher Haster 18:a0fde14b6c39 97
Christopher Haster 18:a0fde14b6c39 98 /** Static thunk for passing as C-style function
Christopher Haster 18:a0fde14b6c39 99 * @param func Composer to call passed as void pointer
Christopher Haster 18:a0fde14b6c39 100 */
Christopher Haster 18:a0fde14b6c39 101 static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 18:a0fde14b6c39 102 return static_cast<Composer<R(B0), B0(A0, A1, A2, A3, A4)>*>(func)
Christopher Haster 18:a0fde14b6c39 103 ->call(a0, a1, a2, a3, a4);
Christopher Haster 18:a0fde14b6c39 104 }
Christopher Haster 18:a0fde14b6c39 105
Christopher Haster 18:a0fde14b6c39 106 private:
Christopher Haster 18:a0fde14b6c39 107 FuncPtr<R(B0)> _f;
Christopher Haster 18:a0fde14b6c39 108 FuncPtr<B0(A0, A1, A2, A3, A4)> _g;
Christopher Haster 18:a0fde14b6c39 109 };
Christopher Haster 18:a0fde14b6c39 110
Christopher Haster 18:a0fde14b6c39 111 /** Static function composition
Christopher Haster 18:a0fde14b6c39 112 */
Christopher Haster 5:5c91c61f50b6 113 template <typename R, typename B0, typename A0, typename A1, typename A2, typename A3>
Christopher Haster 5:5c91c61f50b6 114 class Composer<R(B0), B0(A0, A1, A2, A3)> {
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, A3)> 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, A3)> 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 18:a0fde14b6c39 136 Composer(FuncPtr<R(B0)> 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, A3)> 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, A3)> 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, A3)>(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, A3)>(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, A3 a3) {
Christopher Haster 5:5c91c61f50b6 179 return _f(_g(a0, a1, a2, a3));
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, A3 a3) {
Christopher Haster 5:5c91c61f50b6 185 return call(a0, a1, a2, a3);
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, A3 a3) {
Christopher Haster 5:5c91c61f50b6 198 return static_cast<Composer<R(B0), B0(A0, A1, A2, A3)>*>(func)
Christopher Haster 5:5c91c61f50b6 199 ->call(a0, a1, a2, a3);
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, A3)> _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, typename A2>
Christopher Haster 5:5c91c61f50b6 210 class Composer<R(B0), B0(A0, A1, A2)> {
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, A2)> 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, A2)> 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 18:a0fde14b6c39 232 Composer(FuncPtr<R(B0)> 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, A2)> 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, A2)> 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, A2)>(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, A2)>(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, A2 a2) {
Christopher Haster 5:5c91c61f50b6 275 return _f(_g(a0, a1, a2));
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, A2 a2) {
Christopher Haster 5:5c91c61f50b6 281 return call(a0, a1, a2);
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, A2 a2) {
Christopher Haster 5:5c91c61f50b6 294 return static_cast<Composer<R(B0), B0(A0, A1, A2)>*>(func)
Christopher Haster 5:5c91c61f50b6 295 ->call(a0, a1, a2);
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, A2)> _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, typename A1>
Christopher Haster 5:5c91c61f50b6 306 class Composer<R(B0), B0(A0, A1)> {
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, A1)> 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, A1)> 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 18:a0fde14b6c39 328 Composer(FuncPtr<R(B0)> 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, A1)> 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, A1)> 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, A1)>(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, A1)>(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, A1 a1) {
Christopher Haster 5:5c91c61f50b6 371 return _f(_g(a0, a1));
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, A1 a1) {
Christopher Haster 5:5c91c61f50b6 377 return call(a0, a1);
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, A1 a1) {
Christopher Haster 5:5c91c61f50b6 390 return static_cast<Composer<R(B0), B0(A0, A1)>*>(func)
Christopher Haster 5:5c91c61f50b6 391 ->call(a0, a1);
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, A1)> _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, typename A0>
Christopher Haster 5:5c91c61f50b6 402 class Composer<R(B0), B0(A0)> {
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(A0)> 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(A0)> 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 18:a0fde14b6c39 424 Composer(FuncPtr<R(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(A0)> 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(A0)> 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(A0)>(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(A0)>(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(A0 a0) {
Christopher Haster 5:5c91c61f50b6 467 return _f(_g(a0));
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()(A0 a0) {
Christopher Haster 5:5c91c61f50b6 473 return call(a0);
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, A0 a0) {
Christopher Haster 5:5c91c61f50b6 486 return static_cast<Composer<R(B0), B0(A0)>*>(func)
Christopher Haster 5:5c91c61f50b6 487 ->call(a0);
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(A0)> _g;
Christopher Haster 5:5c91c61f50b6 493 };
Christopher Haster 5:5c91c61f50b6 494
Christopher Haster 5:5c91c61f50b6 495 /** Static function composition
Christopher Haster 5:5c91c61f50b6 496 */
Christopher Haster 5:5c91c61f50b6 497 template <typename R, typename B0>
Christopher Haster 5:5c91c61f50b6 498 class Composer<R(B0), B0()> {
Christopher Haster 5:5c91c61f50b6 499 public:
Christopher Haster 5:5c91c61f50b6 500 /** Create an uncomposed Composer
Christopher Haster 5:5c91c61f50b6 501 */
Christopher Haster 5:5c91c61f50b6 502 Composer() {}
Christopher Haster 5:5c91c61f50b6 503
Christopher Haster 5:5c91c61f50b6 504 /** Create a Composer, composing two functions
Christopher Haster 5:5c91c61f50b6 505 */
Christopher Haster 5:5c91c61f50b6 506 Composer(FuncPtr<R(B0)> f, FuncPtr<B0()> g) {
Christopher Haster 5:5c91c61f50b6 507 attach(f, g);
Christopher Haster 5:5c91c61f50b6 508 }
Christopher Haster 5:5c91c61f50b6 509
Christopher Haster 5:5c91c61f50b6 510 /** Create a Composer, composing functions and methods
Christopher Haster 5:5c91c61f50b6 511 */
Christopher Haster 5:5c91c61f50b6 512 template <typename FT, typename FM>
Christopher Haster 5:5c91c61f50b6 513 Composer(FT *fobj, FM fmethod, FuncPtr<B0()> g) {
Christopher Haster 5:5c91c61f50b6 514 attach(fobj, fmethod, g);
Christopher Haster 5:5c91c61f50b6 515 }
Christopher Haster 5:5c91c61f50b6 516
Christopher Haster 5:5c91c61f50b6 517 /** Create a Composer, composing functions and methods
Christopher Haster 5:5c91c61f50b6 518 */
Christopher Haster 5:5c91c61f50b6 519 template <typename GT, typename GM>
Christopher Haster 18:a0fde14b6c39 520 Composer(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
Christopher Haster 5:5c91c61f50b6 521 attach(f, gobj, gmethod);
Christopher Haster 5:5c91c61f50b6 522 }
Christopher Haster 5:5c91c61f50b6 523
Christopher Haster 5:5c91c61f50b6 524 /** Create a Composer, composing functions and methods
Christopher Haster 5:5c91c61f50b6 525 */
Christopher Haster 5:5c91c61f50b6 526 template <typename FT, typename FM, typename GT, typename GM>
Christopher Haster 5:5c91c61f50b6 527 Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
Christopher Haster 5:5c91c61f50b6 528 attach(fobj, fmethod, gobj, gmethod);
Christopher Haster 5:5c91c61f50b6 529 }
Christopher Haster 5:5c91c61f50b6 530
Christopher Haster 5:5c91c61f50b6 531 /** Compose two functions
Christopher Haster 5:5c91c61f50b6 532 */
Christopher Haster 5:5c91c61f50b6 533 void attach(FuncPtr<R(B0)> f, FuncPtr<B0()> g) {
Christopher Haster 5:5c91c61f50b6 534 _f.attach(f);
Christopher Haster 5:5c91c61f50b6 535 _g.attach(g);
Christopher Haster 5:5c91c61f50b6 536 }
Christopher Haster 5:5c91c61f50b6 537
Christopher Haster 5:5c91c61f50b6 538 /** Compose functions and methods
Christopher Haster 5:5c91c61f50b6 539 */
Christopher Haster 5:5c91c61f50b6 540 template <typename FT, typename FM>
Christopher Haster 5:5c91c61f50b6 541 void attach(FT *fobj, FM fmethod, FuncPtr<B0()> g) {
Christopher Haster 5:5c91c61f50b6 542 attach(FuncPtr<R(B0)>(fobj, fmethod), g);
Christopher Haster 5:5c91c61f50b6 543 }
Christopher Haster 5:5c91c61f50b6 544
Christopher Haster 5:5c91c61f50b6 545 /** Compose functions and methods
Christopher Haster 5:5c91c61f50b6 546 */
Christopher Haster 5:5c91c61f50b6 547 template <typename GT, typename GM>
Christopher Haster 5:5c91c61f50b6 548 void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
Christopher Haster 5:5c91c61f50b6 549 attach(f, FuncPtr<B0()>(gobj, gmethod));
Christopher Haster 5:5c91c61f50b6 550 }
Christopher Haster 5:5c91c61f50b6 551
Christopher Haster 5:5c91c61f50b6 552 /** Compose functions and methods
Christopher Haster 5:5c91c61f50b6 553 */
Christopher Haster 5:5c91c61f50b6 554 template <typename FT, typename FM, typename GT, typename GM>
Christopher Haster 5:5c91c61f50b6 555 void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
Christopher Haster 5:5c91c61f50b6 556 attach(FuncPtr<R(B0)>(fobj, fmethod),
Christopher Haster 5:5c91c61f50b6 557 FuncPtr<B0()>(gobj, gmethod));
Christopher Haster 5:5c91c61f50b6 558 }
Christopher Haster 5:5c91c61f50b6 559
Christopher Haster 5:5c91c61f50b6 560 /** Call the composed functions
Christopher Haster 5:5c91c61f50b6 561 */
Christopher Haster 5:5c91c61f50b6 562 R call() {
Christopher Haster 5:5c91c61f50b6 563 return _f(_g());
Christopher Haster 5:5c91c61f50b6 564 }
Christopher Haster 5:5c91c61f50b6 565
Christopher Haster 5:5c91c61f50b6 566 /** Call the composed functions
Christopher Haster 5:5c91c61f50b6 567 */
Christopher Haster 5:5c91c61f50b6 568 R operator()() {
Christopher Haster 5:5c91c61f50b6 569 return call();
Christopher Haster 5:5c91c61f50b6 570 }
Christopher Haster 5:5c91c61f50b6 571
Christopher Haster 5:5c91c61f50b6 572 /** Test if functions have been composed
Christopher Haster 5:5c91c61f50b6 573 */
Christopher Haster 8:71037a47492d 574 operator bool() const {
Christopher Haster 5:5c91c61f50b6 575 return _f && _g;
Christopher Haster 5:5c91c61f50b6 576 }
Christopher Haster 5:5c91c61f50b6 577
Christopher Haster 5:5c91c61f50b6 578 /** Static thunk for passing as C-style function
Christopher Haster 5:5c91c61f50b6 579 * @param func Composer to call passed as void pointer
Christopher Haster 5:5c91c61f50b6 580 */
Christopher Haster 5:5c91c61f50b6 581 static R thunk(void *func) {
Christopher Haster 5:5c91c61f50b6 582 return static_cast<Composer<R(B0), B0()>*>(func)
Christopher Haster 5:5c91c61f50b6 583 ->call();
Christopher Haster 5:5c91c61f50b6 584 }
Christopher Haster 5:5c91c61f50b6 585
Christopher Haster 5:5c91c61f50b6 586 private:
Christopher Haster 5:5c91c61f50b6 587 FuncPtr<R(B0)> _f;
Christopher Haster 5:5c91c61f50b6 588 FuncPtr<B0()> _g;
Christopher Haster 5:5c91c61f50b6 589 };
Christopher Haster 5:5c91c61f50b6 590
Christopher Haster 5:5c91c61f50b6 591
Christopher Haster 5:5c91c61f50b6 592 #endif