#include using namespace boost; // Terminals struct A_ {}; typedef proto::terminal A_terminal; struct B_ {}; typedef proto::terminal B_terminal; struct C_ {}; typedef proto::terminal C_terminal; struct D_ {}; typedef proto::terminal D_terminal; struct fun_ {}; typedef proto::terminal fun_terminal; // Functions struct A: proto::function {}; struct B: proto::function {}; struct C: proto::function {}; struct D: proto::function {}; // Comparator template struct grammar_less: mpl::false_ {}; template<> struct grammar_less: mpl::true_ {}; template struct grammar_less: grammar_less {}; template<> struct grammar_less: mpl::true_ {}; template struct grammar_less: grammar_less {}; template<> struct grammar_less: mpl::true_ {}; template struct grammar_less: grammar_less {}; BOOST_MPL_ASSERT_NOT((grammar_less)); BOOST_MPL_ASSERT ((grammar_less)); BOOST_MPL_ASSERT ((grammar_less)); BOOST_MPL_ASSERT ((grammar_less)); // How to do this correctly? struct sorted_argument_function: proto::and_ < proto::function, proto::if_ < grammar_less() > > {}; int main() { fun_terminal::type fun; A_terminal::type a; B_terminal::type b; C_terminal::type c; D_terminal::type d; BOOST_PROTO_ASSERT_MATCHES(a(0), A); BOOST_PROTO_ASSERT_MATCHES(b(0), B); BOOST_PROTO_ASSERT_MATCHES(c(0), C); BOOST_PROTO_ASSERT_MATCHES(d(0), D); // These should compile BOOST_PROTO_ASSERT_MATCHES((fun(a(0), d(0))), sorted_argument_function); BOOST_PROTO_ASSERT_MATCHES((fun(b(0), c(0))), sorted_argument_function); BOOST_PROTO_ASSERT_MATCHES_NOT((fun(b(0), a(0))), sorted_argument_function); }