Added SelectArg and MemFunSelectArg*
The MemFunSelectArg* functions can be used to select a specific argument from a signal. For example this would select the string argument as argument to the callback: Signal<void, int, float, string> signal; signal.connect(MemFunSelectArg2(obj, &Object::takesOneStringArg)); signal.emit(10, 3.14, "hello"); ... void Object::takesOneStringArg(const string& value) { ... }
This commit is contained in:
parent
68e90ab84f
commit
ceff86b794
4 changed files with 181 additions and 1 deletions
|
@ -22,6 +22,8 @@
|
|||
#ifndef FBTK_MEM_FUN_HH
|
||||
#define FBTK_MEM_FUN_HH
|
||||
|
||||
#include "SelectArg.hh"
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
/// No argument functor
|
||||
|
@ -218,6 +220,60 @@ MemFunIgnoreArgs( Object& obj, ReturnType (Object:: *action)(Arg1,Arg2) ) {
|
|||
return MemFun2IgnoreArgs<ReturnType, Object, Arg1, Arg2>(obj, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a functor that selects a specific argument of three possible ones
|
||||
* and uses it for the single argument operator.
|
||||
*/
|
||||
template < int ArgNum, typename Functor>
|
||||
class MemFunSelectArgImpl {
|
||||
public:
|
||||
|
||||
MemFunSelectArgImpl(Functor func):
|
||||
m_func(func) {
|
||||
}
|
||||
|
||||
template <typename Type1, typename Type2, typename Type3>
|
||||
void operator ()(Type1 a, Type2 b, Type3 c) {
|
||||
m_func(STLUtil::SelectArg<ArgNum>()(a, b, c));
|
||||
}
|
||||
|
||||
template <typename Type1, typename Type2>
|
||||
void operator ()(Type1 a, Type2 b) {
|
||||
m_func(STLUtil::SelectArg<ArgNum>()(a, b));
|
||||
}
|
||||
|
||||
template <typename Type1>
|
||||
void operator ()(Type1 a) {
|
||||
m_func(a);
|
||||
}
|
||||
|
||||
private:
|
||||
Functor m_func;
|
||||
};
|
||||
|
||||
/// Creates a functor that selects the first argument of three possible ones
|
||||
/// and uses it for the single argument operator.
|
||||
template <typename ReturnType, typename Object, typename Arg1>
|
||||
MemFunSelectArgImpl<0, MemFun1<ReturnType, Object, Arg1> >
|
||||
MemFunSelectArg0(Object& obj, ReturnType (Object:: *action)(Arg1)) {
|
||||
return MemFunSelectArgImpl<0, MemFun1<ReturnType, Object, Arg1> >(MemFun(obj, action));
|
||||
}
|
||||
|
||||
/// Creates a functor that selects the second argument (or first if there is
|
||||
/// only one) of three possible onesand uses it for the single argument operator.
|
||||
template <typename ReturnType, typename Object, typename Arg1>
|
||||
MemFunSelectArgImpl<1, MemFun1<ReturnType, Object, Arg1> >
|
||||
MemFunSelectArg1(Object& obj, ReturnType (Object:: *action)(Arg1)) {
|
||||
return MemFunSelectArgImpl<1, MemFun1<ReturnType, Object, Arg1> >(MemFun(obj, action));
|
||||
}
|
||||
|
||||
/// Creates a functor that selects the third argument (or the last argument if there is
|
||||
/// less than three arguments) of three possible onesand uses it for the single argument operator.
|
||||
template <typename ReturnType, typename Object, typename Arg1>
|
||||
MemFunSelectArgImpl<2, MemFun1<ReturnType, Object, Arg1> >
|
||||
MemFunSelectArg2(Object& obj, ReturnType (Object:: *action)(Arg1)) {
|
||||
return MemFunSelectArgImpl<2, MemFun1<ReturnType, Object, Arg1> >(MemFun(obj, action));
|
||||
}
|
||||
|
||||
} // namespace FbTk
|
||||
|
||||
|
|
|
@ -26,6 +26,25 @@
|
|||
namespace FbTk {
|
||||
namespace STLUtil {
|
||||
|
||||
template<bool C, typename Ta, typename Tb>
|
||||
struct IfThenElse;
|
||||
|
||||
template<typename Ta, typename Tb>
|
||||
struct IfThenElse<true, Ta, Tb> {
|
||||
Ta& operator ()(Ta& ta, Tb& tb) const {
|
||||
return ta;
|
||||
}
|
||||
typedef Ta ResultType;
|
||||
};
|
||||
|
||||
template<typename Ta, typename Tb>
|
||||
struct IfThenElse<false, Ta, Tb> {
|
||||
Tb& operator ()(Ta& ta, Tb& tb) const {
|
||||
return tb;
|
||||
}
|
||||
typedef Tb ResultType;
|
||||
};
|
||||
|
||||
/// calls delete on each item in the container and then clears the container
|
||||
template <typename A>
|
||||
void destroyAndClear(A &a) {
|
||||
|
|
74
src/FbTk/SelectArg.hh
Normal file
74
src/FbTk/SelectArg.hh
Normal file
|
@ -0,0 +1,74 @@
|
|||
// SelectArg.hh for FbTk
|
||||
// Copyright (c) 2010 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef FBTK_STLUTIL_SELECT_ARG_HH
|
||||
#define FBTK_STLUTIL_SELECT_ARG_HH
|
||||
|
||||
#include "STLUtil.hh"
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
namespace STLUtil {
|
||||
|
||||
/**
|
||||
* Selects a single argument from a maximum set of three arguments at compile time.
|
||||
* For example:
|
||||
* \begincode
|
||||
* SelectArg<0>()( 10, 20, "hello" ); // returns first argument ( 10 )
|
||||
* SelectArg<1>()( 10, "hello", 30 ); // returns second argument ( "hello" )
|
||||
* SelectArg<2>()( 10, "hello", 30 ); // returns third argument ( 30 )
|
||||
* \endcode
|
||||
*
|
||||
* The selection of argument 1 and 2 can return the last argument if the
|
||||
* arguments are less or equal to two. For instance:
|
||||
* \begincode
|
||||
* SelectArg<1>()(10); // returns 10
|
||||
* SelectArg<2>()(10, 20); // returns 20
|
||||
* SelectArg<2>()(10); // returns 10
|
||||
* \endcode
|
||||
*/
|
||||
template < int N >
|
||||
struct SelectArg {
|
||||
|
||||
template <typename Type1, typename Type2>
|
||||
typename IfThenElse<N==0, Type1, Type2>::ResultType& operator ()(Type1& a, Type2& b){
|
||||
return IfThenElse<N==0, Type1, Type2>()(a, b);
|
||||
}
|
||||
|
||||
template <typename Type1, typename Type2, typename Type3>
|
||||
typename IfThenElse<N==0, Type1,
|
||||
typename IfThenElse<N==1, Type2, Type3>::ResultType>::ResultType&
|
||||
operator () (Type1& a, Type2& b, Type3& c) {
|
||||
return IfThenElse<N==0, Type1,
|
||||
typename IfThenElse<N==1, Type2, Type3>::ResultType>()
|
||||
(a, IfThenElse<N==1, Type2, Type3>() (b, c) );
|
||||
}
|
||||
|
||||
template < typename Type1 >
|
||||
Type1 operator() (Type1 a) {
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace STLUtil
|
||||
} // end namespace FbTk
|
||||
|
||||
#endif // FBTK_STLUTIL_SELECT_ARG_HH
|
|
@ -49,7 +49,7 @@ struct FunctionClass {
|
|||
}
|
||||
|
||||
void takeIt( string& str ) {
|
||||
cout << "takeIt( " << str << ")" << endl;
|
||||
cout << "FunctionClass::takeIt( " << str << " )" << endl;
|
||||
}
|
||||
|
||||
void showMessage( int value, const string& message ) {
|
||||
|
@ -61,8 +61,21 @@ struct FunctionClass {
|
|||
void threeArgs( int value, const string& str, double pi ) {
|
||||
cout << "(" << value << "): " << str << ", pi = " << pi << endl;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Printer {
|
||||
void printInt(int value) {
|
||||
cout << "Int:" << value << endl;
|
||||
}
|
||||
void printString(string value) {
|
||||
cout << "string:" << value << endl;
|
||||
}
|
||||
void printFloat(float value) {
|
||||
cout << "Float:" << value << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
using FbTk::Signal;
|
||||
using FbTk::SignalTracker;
|
||||
|
@ -161,4 +174,22 @@ int main() {
|
|||
// subject notify its observers
|
||||
source.emit("hello world");
|
||||
}
|
||||
|
||||
// Test argument selector
|
||||
{
|
||||
using namespace FbTk;
|
||||
Signal<void, int, string, float> source;
|
||||
|
||||
Printer printer;
|
||||
source.connect(MemFunSelectArg0(printer, &Printer::printInt));
|
||||
source.connect(MemFunSelectArg1(printer, &Printer::printString));
|
||||
source.connect(MemFunSelectArg2(printer, &Printer::printFloat));
|
||||
|
||||
source.emit(10, "hello", 3.141592);
|
||||
|
||||
Signal<void, string, int> source2;
|
||||
source2.connect(MemFunSelectArg0(printer, &Printer::printString));
|
||||
source2.connect(MemFunSelectArg1(printer, &Printer::printInt));
|
||||
source2.emit("world", 37);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue