Modified version of Andy Kirkhams FPointer.h http://mbed.org/users/AjK/libraries/FPointer/ll7nhv Advantages: - reduced size of from 12 -> 8 byte by usage of a unnamed union - speedup function call by removing one error check - replaced call() function by () operator - templated: you can define the return and argument types - implementations provided for 1 and 2 arguments, easy extendable to more arguments

Dependencies:   mbed

FunctionPointers.h

Committer:
Renegr
Date:
2011-12-11
Revision:
0:e62fc62bc488

File content as of revision 0:e62fc62bc488:

/* FunctionPointers.h
 * Modified version of Andy Kirkhams FPointer.h
 * http://mbed.org/users/AjK/libraries/FPointer/ll7nhv
 * Advantages:
 * - reduced size of from 12 -> 8 byte by usage of a unnamed union
 * - speedup function call by removing one error check
 * - replaced call() function by () operator
 * - templated: you can define the return and argument types
 * - implementations for 1 and 2 arguments, easy extendable to more arguments
 * Disadvantage:
 * - do NOT call operator() without an attached callback function
 */ 
  
#ifndef FUNCTIONPOINTERS_H 
#define FUNCTIONPOINTERS_H 

template<class Tret=void>
class FPtrRetT {
public:
    FPtrRetT() : obj_callback( NULL), c_callback( NULL)  {
    }

    void attach(Tret (*function)()) {
        c_callback = function;
    }

    template<class T>
    void attach(T& item, Tret (T::*method)()) {
        obj_callback    = reinterpret_cast<FPtrDummy*>(&item);
        method_callback = reinterpret_cast<Tret (FPtrDummy::*)()>(method);
    }

    Tret operator()() const {
        return obj_callback ? (obj_callback->*method_callback)() : (*c_callback)();
    }

private:
    class FPtrDummy;

    FPtrDummy  *obj_callback;
    union {
        Tret (*c_callback)();
        Tret (FPtrDummy::*method_callback)();
    };
};

template<class Tret, class Targ1>
class FPtr1ArgT {
public:
    FPtr1ArgT() : obj_callback( NULL), c_callback( NULL)  {
    }

    void attach(Tret (*function)(Targ1)) {
        c_callback = function;
    }

    template<class T>
    void attach(T& item, Tret (T::*method)(Targ1)) {
        obj_callback    = reinterpret_cast<FPtrDummy*>(&item);
        method_callback = reinterpret_cast<Tret (FPtrDummy::*)(Targ1)>(method);
    }

    Tret operator()(Targ1 arg1) const {
        return obj_callback ? (obj_callback->*method_callback)(arg1) : (*c_callback)(arg1);
    }

private:
    class FPtrDummy;

    FPtrDummy  *obj_callback;
    union {
        Tret (*c_callback)(Targ1);
        Tret (FPtrDummy::*method_callback)(Targ1);
    };
};

template<class Tret, class Targ1, class Targ2>
class FPtr2ArgT {
public:
    FPtr2ArgT() : obj_callback( NULL), c_callback( NULL)  {
    }

    void attach(Tret (*function)(Targ1,Targ2)) {
        c_callback = function;
    }

    template<class T>
    void attach(T& item, Tret (T::*method)(Targ1,Targ2)) {
        obj_callback    = reinterpret_cast<FPointerDummy*>(&item);
        method_callback = reinterpret_cast<Tret (FPtrDummy::*)(Targ1,Targ2)>(method);
    }

    Tret operator()(Targ1 arg1, Targ2 arg2) const {
        return obj_callback ? (obj_callback->*method_callback)(arg1, arg2) : (*c_callback)(arg1, arg2);
    }

private:
    class FPtrDummy;

    FPtrDummy  *obj_callback;
    union {
        Tret (*c_callback)(Targ1,Targ2);
        Tret (FPtrDummy::*method_callback)(Targ1,Targ2);
    };
};

#endif