#include #include #include namespace mpl = boost::mpl; namespace proto = boost::proto; namespace fusion = boost::fusion; using proto::_; struct placeholder { friend std::ostream &operator <<(std::ostream &sout, placeholder) { return sout << "var_"; } }; proto::terminal::type const var_ = {{}}; // Work around annoyng msvc compiler bugs ... #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #define _left(x) call #define _right(x) call #define _make_minus(x,y) call #define _make_assign(x,y) call #endif struct Solve : proto::or_< // Solved: proto::assign, _> // Rewrite "var_ + x = y" to "var_ = y - x" , proto::when< proto::assign< proto::plus< proto::terminal, _>, _ > , proto::_make_assign( proto::_left(proto::_left) , proto::_make_minus( proto::_right, proto::_right(proto::_left) ) ) > // Rewrite "x + var_ = y" to "var_ = y - x" , proto::when< proto::assign< proto::plus< _, proto::terminal>, _ > , proto::_make_assign( proto::_right(proto::_left) , proto::_make_minus( proto::_right, proto::_left(proto::_left) ) ) > // Rewrite "x + ? = y" to "Solve(? = y - x)" , proto::when< proto::assign< proto::plus< proto::terminal<_>, _>, _ > , Solve( proto::_make_assign( proto::_right(proto::_left) , proto::_make_minus( proto::_right, proto::_left(proto::_left) ) ) ) > // Rewrite "? + x = y" to "Solve(? = y - x)" , proto::when< proto::assign< proto::plus< _, proto::terminal<_> >, _ > , Solve( proto::_make_assign( proto::_left(proto::_left) , proto::_make_minus( proto::_right, proto::_right(proto::_left) ) ) ) > > {}; int main() { BOOST_PROTO_AUTO(expr1, var_ + 1 = 2 ); BOOST_MPL_ASSERT(( proto::matches)); proto::display_expr( expr1 ); proto::display_expr(Solve()(expr1)); std::cout << "--------------------\n"; BOOST_PROTO_AUTO(expr2, 3 + var_ = 2 ); BOOST_MPL_ASSERT(( proto::matches)); proto::display_expr( expr2 ); proto::display_expr(Solve()(expr2)); std::cout << "--------------------\n"; BOOST_PROTO_AUTO(expr3, 3 + var_ + 1 = 2 ); BOOST_MPL_ASSERT(( proto::matches)); proto::display_expr( expr3 ); proto::display_expr(Solve()(expr3)); std::cout << "--------------------\n"; BOOST_PROTO_AUTO(expr4, proto::lit(5) + 3 + var_ + 1 + 4 = 2 ); BOOST_MPL_ASSERT(( proto::matches)); proto::display_expr( expr4 ); proto::display_expr(Solve()(expr4)); std::cout << "--------------------\n"; }