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));
This commit is contained in:
Henrik Kinnunen 2010-03-18 10:45:33 +01:00
parent 5a91ada3c6
commit 0504de454a
2 changed files with 111 additions and 2 deletions

View file

@ -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<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
#endif // FBTK_MEM_FUN_HH

View file

@ -21,7 +21,8 @@ struct OneArgument {
};
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;
}
};
@ -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<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);
}
}