Мечтал об этом вопросе за одну ночь .. и придумал изящное решение (вдохновленное соответствующими системами, используемыми в тесте Google ilbraries)
Ядро, если беспорядок становится чем-то вроде этого - что я думаю довольно симпатично.
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 )
;
Последняя строка, которую я еще не реализовал. _
означает совпадение с любой цифрой, OR
означает совпадение с любой (хотя вы можете вложить ее OR(1,OR(2,3))
должно быть в порядке.
Остальная часть кода поддержки представляет собой беспорядок в шаблонных функциях, заставляющих эту работу работать. Если есть интерес, я могу опубликовать более подробное описание того, что происходит ... но это не слишком сложно - просто долго. Я ожидаю, что это тоже можно немного почистить ...
Вероятно, его можно извлечь и обобщить в хорошую библиотеку - хотя я бы, вероятно, посмотрел на адаптацию тестового кода Google вместо того, чтобы основываться на этом коде;)
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 )
;
}