#include using namespace boost; typedef proto::terminal::type const terminal; struct equation; struct addition: proto::or_ < proto::terminal, proto::plus > {}; struct equation: proto::or_ < proto::equal_to > {}; template struct extension; struct my_domain: proto::domain < proto::pod_generator, equation, proto::default_domain > {}; template struct lhs_extension; struct my_lhs_domain: proto::domain < proto::pod_generator, addition, my_domain > {}; template struct rhs_extension; struct my_rhs_domain: proto::domain < proto::pod_generator, addition, my_domain > {}; template struct extension { BOOST_PROTO_BASIC_EXTENDS( Expr , extension , my_domain ) void test() const {} }; template struct lhs_extension { BOOST_PROTO_BASIC_EXTENDS( Expr , lhs_extension , my_lhs_domain ) }; template struct rhs_extension { BOOST_PROTO_BASIC_EXTENDS( Expr , rhs_extension , my_rhs_domain ) }; template void matches(Expr const& expr) { std::cout << std::boolalpha << proto::matches::value << "\n"; } int main() { lhs_extension const i = {}; rhs_extension const j = {}; matches(i); // false matches(j); // false matches(i + i); // false matches(j + j); // false //matches(i + j); // compile error //matches(j + i); // compile error matches(i == j); // true matches(i == j + j); // true matches(i + i == j); // true matches(i + i == j + j); // true }