I dreamed about this issue overnight .. and came up with a neat solution (inspired by the corresponding systems used in google test tags)
The kernel, if the mess becomes something like this, which I think is pretty pretty.
Params(1,2,3,4) .do_if( match(1,_,3,5), functionA ) .do_if( match(1,_,3,4), functionB ) .do_if( match( _, OR(2,3),3,5), functionC )
The last line has not yet been implemented. _ means match any digit, OR means match (although you can nest it OR(1,OR(2,3)) should be fine.
The rest of the support code is a mess of template functions to make this work. If I have an interest, I can post a more detailed description of what is happening ... but its not too difficult - just a long time. I expect it can be cleaned too ...
It can probably be pulled out and generalized into a beautiful library too, although I would probably look at adapting the google test code instead of doing something from it;)
struct RawParams { RawParams( int a, int b, int c, int d) : a_(a), b_(b), c_(c), d_(d) {} int a_,b_,c_,d_; }; struct ParamsContinue { RawParams * p_; ParamsContinue() : p_(0) {} ParamsContinue( RawParams * p ) : p_(p) {} template<typename CONDITION, typename FN> ParamsContinue do_if( CONDITION cond, FN fn ) { if( !p_ ) { return ParamsContinue(); } if( cond(p_->a_,p_->b_,p_->c_,p_->d_) ) { fn(); return ParamsContinue(); } return *this; } }; struct Params { Params( int a, int b, int c, int d) : params_(a,b,c,d) {} RawParams params_; template<typename CONDITION, typename FN> ParamsContinue do_if( CONDITION cond, FN fn ) { return ParamsContinue(¶ms_).do_if(cond,fn); } }; struct AnySingleMatcher { bool operator()(int i) const { return true; } }; AnySingleMatcher _; template<typename M1, typename M2, typename M3, typename M4> struct Match { Match( M1 in_m1, M2 in_m2, M3 in_m3, M4 in_m4 ) : m1(in_m1), m2(in_m2), m3(in_m3), m4(in_m4) {} bool operator()( int a, int b, int c, int d) const { return m1(a)&&m2(b)&&m3(c)&&m4(d); } M1 m1; M2 m2; M3 m3; M4 m4; }; struct AnyMatcher {}; struct IntMatcher { IntMatcher(int i) : i_(i) {} bool operator()(int v) const { return v==i_; } int i_; }; template<typename T> struct as_matcher { typedef T type; static T as( T t ) { return t; } }; template<> struct as_matcher<int> { typedef IntMatcher type; static IntMatcher as( int i ) { return IntMatcher( i ); } }; template<typename M1, typename M2, typename M3, typename M4 > Match< typename as_matcher<M1>::type, typename as_matcher<M2>::type, typename as_matcher<M3>::type, typename as_matcher<M4>::type > match( M1 m1, M2 m2, M3 m3, M4 m4 ) { return Match< typename as_matcher<M1>::type, typename as_matcher<M2>::type, typename as_matcher<M3>::type, typename as_matcher<M4>::type >( as_matcher<M1>::as(m1), as_matcher<M2>::as(m2), as_matcher<M3>::as(m3), as_matcher<M4>::as(m4) ); }; template<typename T1, typename T2> struct OrMatcher { OrMatcher( T1 t1, T2 t2 ) : t1_(t1), t2_(t2) {} T1 t1_; T2 t2_; bool operator()(int i) const { return t1_(i) || t2_(i); } }; template<typename T1, typename T2> OrMatcher< typename as_matcher<T1>::type, typename as_matcher<T2>::type > OR( T1 t1, T2 t2 ) { return OrMatcher< typename as_matcher<T1>::type, typename as_matcher<T2>::type >( as_matcher<T1>::as(t1),as_matcher<T2>::as(t2) ); }; #include <iostream> void functionA(){ std::cout<<"In A"<<std::endl;}; void functionB(){ std::cout<<"In B"<<std::endl;}; void functionC(){ std::cout<<"In C"<<std::endl;}; void functionD(){ std::cout<<"In D"<<std::endl;}; int main() { Params(1,2,3,4) .do_if( match(1,_,3,5), functionA ) .do_if( match(1,_,3,4), functionB ) .do_if( match( _, OR(2,3),3,5), functionC ) // .do_if( match(1,_,4,6)|match(3,_,5,8) ), functionD ) ;
}