
On 9/21/2010 5:55 AM, Thomas Heller wrote:
Solved the mistery. here is the code, explanation comes afterward:
#include
using namespace boost;
typedef proto::terminal<int>::type terminal;
struct addition: proto::or_ < proto::plus
, proto::terminalproto::_ > {}; struct equation: proto::or_ < proto::equal_to
> {}; template<class Expr> struct extension;
struct my_domain: proto::domain < proto::pod_generator< extension>, // we need both grammars in our domain grammar proto::or_
,
That will also work because addition (contrary to its name) will also match lone terminals.
proto::default_domain > {};
template<class Expr> struct extension { BOOST_PROTO_EXTENDS( Expr , extension<Expr> , my_domain ) };
template
void matches(Expr const&) { std::cout << std::boolalpha << proto::matches ::value << "\n"; } int main() { extension<terminal> i; extension<terminal> j;
matches<equation>(i); // 1) false matches<equation>(i == j); // 2) true matches<equation>(i == i + i); // 3) true matches<equation>(i + i == i); // 4) true matches<equation>(i + i == i + i); // 5) true matches<equation>(i + i); // 6) false }
Ok, what happened, why does this work, and why didn't the previous attempt work:
the equation grammar obviously doesn't match case 1) and 6). And that is exactly why proto didn't generate any operator+ overload. In order for a proto overload to be created the following conditions must be true:
1) the operands must be in a compatible domain 2) the left hand operand and the right hand operand must match the grammar specified in the domain
Precisely.
3) the resulting expression must match the grammar specified in the domain.
Right-o.
In our example 1) is always true. 2) and 3) are not true for expressions like 1) and 6). That means, that any binary operator gets disabled whenever the LHS or the RHS is a terminal<_>. because of the equation grammar, terminals or additions can not stand alone, that is why operator creation failed. Makes sense! In order to enable the operators, we just say, our domain can have addition _or_ equation. That's it, operator+ and operator== get enabled. We can still detect invalid expression with proto::matches!
So, everything works as expected!
Thomas wins the prize. This is not a bug in Proto. -- Eric Niebler BoostPro Computing http://www.boostpro.com