all repos — fluxbox @ 0504de454a0a3bf06466029940af480e3caaa8b2

custom fork of the fluxbox windowmanager

Added MemFunIgnoreArgs which ignores aditional arguments.

For example connecting a function that takes two arguments
to a signal that emits three arguments:
struct Functor {
    void show(int a, int b);
};
Functor f;
Signal<void, int, int, int> s3;
s3.connect(MemFunIgnoreArgs(f, &Functor::show));
Henrik Kinnunen fluxgen@fluxbox.org
commit

0504de454a0a3bf06466029940af480e3caaa8b2

parent

5a91ada3c6c9f199b3646465206d4b2b613cad3e

2 files changed, 111 insertions(+), 2 deletions(-)

jump to
M src/FbTk/MemFun.hhsrc/FbTk/MemFun.hh

@@ -38,7 +38,9 @@

void operator ()() { (m_obj.*m_action)(); } - + void call() { + (m_obj.*m_action)(); + } private: Object& m_obj; Action m_action;

@@ -132,6 +134,92 @@ MemFun3<ReturnType, Object, Arg1, Arg2, Arg3>

MemFun( Object& obj, ReturnType (Object:: *action)(Arg1, Arg2, Arg3) ) { return MemFun3<ReturnType, Object, Arg1, Arg2, Arg3>(obj, action); } + +/// Ignores all arguments +template <typename ReturnType, typename Object> +class MemFun0IgnoreArgs: public MemFun0<ReturnType, Object> { +public: + typedef MemFun0<ReturnType, Object> BaseType; + + MemFun0IgnoreArgs(Object& obj, + typename BaseType::Action action): + BaseType(obj, action) { + } + + template <typename IgnoreType1, typename IgnoreType2, typename IgnoreType3> + void operator ()(IgnoreType1&, IgnoreType2&, IgnoreType3&) { + BaseType::operator ()(); + } + + template <typename IgnoreType1, typename IgnoreType2> + void operator ()(IgnoreType1&, IgnoreType2&) { + BaseType::operator ()(); + } + + template <typename IgnoreType1> + void operator ()(IgnoreType1&) { + BaseType::operator ()(); + } +}; + +/// Ignores second and third argument +template <typename ReturnType, typename Object, typename Arg1> +class MemFun1IgnoreArgs: public MemFun1<ReturnType, Object, Arg1> { +public: + typedef MemFun1<ReturnType, Object, Arg1> BaseType; + + MemFun1IgnoreArgs(Object& obj, typename BaseType::Action& action): + BaseType(obj, action) { + } + + template <typename IgnoreType1, typename IgnoreType2> + void operator ()(Arg1 arg1, IgnoreType1&, IgnoreType2&) { + BaseType::operator ()(arg1); + } + + template <typename IgnoreType> + void operator ()(Arg1 arg1, IgnoreType&) { + BaseType::operator ()(arg1); + } +}; + +/// Takes two arguments but ignores the third +template <typename ReturnType, typename Object, typename Arg1, typename Arg2> +class MemFun2IgnoreArgs: public MemFun2<ReturnType, Object, Arg1, Arg2> { +public: + typedef MemFun2<ReturnType, Object, Arg1, Arg2> BaseType; + + MemFun2IgnoreArgs(Object& obj, typename BaseType::Action& action): + BaseType(obj, action) { + } + + template < typename IgnoreType > + void operator ()(Arg1 arg1, Arg2 arg2, IgnoreType&) { + BaseType::operator ()(arg1, arg2); + } +}; + +/// Creates functor that ignores all arguments. +template <typename ReturnType, typename Object> +MemFun0IgnoreArgs<ReturnType, Object> +MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)() ) { + return MemFun0IgnoreArgs<ReturnType, Object>(obj, action); +} + +/// Creates functor that ignores second and third argument. +template <typename ReturnType, typename Object, typename Arg1> +MemFun1IgnoreArgs<ReturnType, Object, Arg1> +MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)(Arg1) ) { + return MemFun1IgnoreArgs<ReturnType, Object, Arg1>(obj, action); +} + +/// Creates functor that ignores third argument. +template <typename ReturnType, typename Object, typename Arg1, typename Arg2> +MemFun2IgnoreArgs<ReturnType, Object, Arg1, Arg2> +MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)(Arg1,Arg2) ) { + return MemFun2IgnoreArgs<ReturnType, Object, Arg1, Arg2>(obj, action); +} + } // namespace FbTk
M src/tests/testSignals.ccsrc/tests/testSignals.cc

@@ -21,7 +21,8 @@ }

}; struct TwoArguments { - void operator ()( int value, const string& message ) { + template <typename T1, typename T2> + void operator ()( const T1& value, const T2& message ) { cout << "Two arguments, (1) = " << value << ", (2) = " << message << endl; } };

@@ -50,6 +51,9 @@ }

void showMessage( int value, const string& message ) { cout << "(" << value << "): " << message << endl; + } + void showMessage2( const string& message1, const string& message2) { + cout << "(" << message1 << ", " << message2 << ")" << endl; } void threeArgs( int value, const string& str, double pi ) { cout << "(" << value << "): " << str << ", pi = " << pi << endl;

@@ -118,4 +122,21 @@

three_args.clear(); three_args.connect(MemFun(obj, &FunctionClass::threeArgs)); three_args.emit(9, "nine", 3.141592); + + // Test ignore signals + { + cout << "----------- Testing ignoring arguments for signal." << endl; + using FbTk::MemFunIgnoreArgs; + // Create a signal that emits with three arguments, and connect + // sinks that takes less than three arguments. + Signal<void, string, string, float> more_args; + more_args.connect(MemFunIgnoreArgs(obj, &FunctionClass::print)); + more_args.connect(MemFunIgnoreArgs(obj, &FunctionClass::takeIt)); + more_args.connect(MemFunIgnoreArgs(obj, &FunctionClass::showMessage2)); + more_args.emit("This should be visible for takeIt(string)", + "Visible to the two args function.", + 2.9); + + } + }