Re: Decision Tables



On Jan 29, 9:26 pm, kwikius <a...@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
On Jan 28, 5:20 pm, Ben Bacarisse <ben.use...@xxxxxxxxx> wrote:





Another way to go about this (when you don't have closures) is to
encode the actions that match into a stack machine.  One simple
encoding is as function pointers (invented language):

void match_first_name(rM, cM) { push(rM.FirstName == cM.FirstName); }
void match_last_name(rM, cM)  { push(rM.LastName == cM.LastName); }
void match_country(rM, cM)    { push(rM.Country == cM.Country); }

void match_and(rM, cM)        { push(pop() & pop()); }
void match_or(rM, cM)         { push(pop() | pop()); }
void match_not(rM, cM)        { push(!pop()); }

Your complex matches then become short NULL terminated arrays for
these:

complex_match[] = { match_contry, match_not, match_first_name,
                    match_or, NULL };

FWIW heres a C++ variant, which seems to work...

Hmm ... A faster version :

#include <string>

// data entries
struct D{
D(std::string const & fn,std::string const & ln, std::string const
& c)
: first_name(fn),last_name(ln),country(c){}
std::string first_name;
std::string last_name;
std::string country;
};

// D member comparison
template <std::string D::* M>
struct Dpred {
Dpred( D const & lhs, D const & rhs)
: b (lhs.*M == rhs.*M){}

bool operator()() const
{
return b;
}
private:
bool b;
};

// comp ops...
template <std::string D::* M>
inline bool operator ! (Dpred<M> const & in)
{
return ! in();
}
template <std::string D::* L,std::string D::* R>
inline bool operator || (Dpred<L> const & lhs, Dpred<R> const & rhs)
{
return lhs() || rhs();
}
template <std::string D::* L>
inline bool operator || (Dpred<L> const & lhs, bool rhs)
{
return lhs() || rhs;
}
template <std::string D::* R>
inline bool operator || (bool lhs,Dpred<R> const & rhs)
{
return lhs || rhs();
}
template <std::string D::* L,std::string D::* R>
inline bool operator && (Dpred<L> const & lhs, Dpred<R> const & rhs)
{
return lhs() && rhs();
}
template <std::string D::* L>
inline bool operator && (Dpred<L> const & lhs, bool rhs)
{
return lhs() && rhs;
}
template <std::string D::* R>
inline bool operator && (bool lhs,Dpred<R> const & rhs)
{
return lhs && rhs();
}

#include <iostream>

int main()
{
D d1("John","Smith","England");
D d2("John","Jones","England");

typedef Dpred<&D::first_name> d_first_name;
typedef Dpred<&D::last_name> d_last_name;
typedef Dpred<&D::country> d_country;

std::cout << (d_first_name(d1,d2) && d_last_name(d1,d2) &&
d_country(d1,d2)) << '\n';

d_first_name first_name(d1,d2);
d_last_name last_name(d1,d2);
d_country country(d1,d2);

std::cout << (first_name && (last_name || country)) << '\n';
std::cout << (first_name && !last_name && country) << '\n';

}

regards
Andy Little
.



Relevant Pages