From 0504de454a0a3bf06466029940af480e3caaa8b2 Mon Sep 17 00:00:00 2001 From: Henrik Kinnunen Date: Thu, 18 Mar 2010 10:45:33 +0100 Subject: 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 s3; s3.connect(MemFunIgnoreArgs(f, &Functor::show)); --- src/FbTk/MemFun.hh | 90 +++++++++++++++++++++++++++++++++++++++++++++++- src/tests/testSignals.cc | 23 ++++++++++++- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/src/FbTk/MemFun.hh b/src/FbTk/MemFun.hh index 4c834dd..c2c6b20 100644 --- a/src/FbTk/MemFun.hh +++ b/src/FbTk/MemFun.hh @@ -38,7 +38,9 @@ public: void operator ()() { (m_obj.*m_action)(); } - + void call() { + (m_obj.*m_action)(); + } private: Object& m_obj; Action m_action; @@ -133,6 +135,92 @@ MemFun( Object& obj, ReturnType (Object:: *action)(Arg1, Arg2, Arg3) ) { return MemFun3(obj, action); } +/// Ignores all arguments +template +class MemFun0IgnoreArgs: public MemFun0 { +public: + typedef MemFun0 BaseType; + + MemFun0IgnoreArgs(Object& obj, + typename BaseType::Action action): + BaseType(obj, action) { + } + + template + void operator ()(IgnoreType1&, IgnoreType2&, IgnoreType3&) { + BaseType::operator ()(); + } + + template + void operator ()(IgnoreType1&, IgnoreType2&) { + BaseType::operator ()(); + } + + template + void operator ()(IgnoreType1&) { + BaseType::operator ()(); + } +}; + +/// Ignores second and third argument +template +class MemFun1IgnoreArgs: public MemFun1 { +public: + typedef MemFun1 BaseType; + + MemFun1IgnoreArgs(Object& obj, typename BaseType::Action& action): + BaseType(obj, action) { + } + + template + void operator ()(Arg1 arg1, IgnoreType1&, IgnoreType2&) { + BaseType::operator ()(arg1); + } + + template + void operator ()(Arg1 arg1, IgnoreType&) { + BaseType::operator ()(arg1); + } +}; + +/// Takes two arguments but ignores the third +template +class MemFun2IgnoreArgs: public MemFun2 { +public: + typedef MemFun2 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 +MemFun0IgnoreArgs +MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)() ) { + return MemFun0IgnoreArgs(obj, action); +} + +/// Creates functor that ignores second and third argument. +template +MemFun1IgnoreArgs +MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)(Arg1) ) { + return MemFun1IgnoreArgs(obj, action); +} + +/// Creates functor that ignores third argument. +template +MemFun2IgnoreArgs +MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)(Arg1,Arg2) ) { + return MemFun2IgnoreArgs(obj, action); +} + + } // namespace FbTk #endif // FBTK_MEM_FUN_HH diff --git a/src/tests/testSignals.cc b/src/tests/testSignals.cc index 86096bf..6d68d3a 100644 --- a/src/tests/testSignals.cc +++ b/src/tests/testSignals.cc @@ -21,7 +21,8 @@ struct OneArgument { }; struct TwoArguments { - void operator ()( int value, const string& message ) { + template + void operator ()( const T1& value, const T2& message ) { cout << "Two arguments, (1) = " << value << ", (2) = " << message << endl; } }; @@ -51,6 +52,9 @@ struct FunctionClass { 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 @@ int main() { 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 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); + + } + } -- cgit v0.11.2