//#include "stdafx.h" #include #include #include #include #include #include #include #include #include namespace mpl = boost::mpl; namespace proto = boost::proto; namespace fusion = boost::fusion; using proto::_; using proto::_a; struct term { friend std::ostream &operator<<(std::ostream &sout, term const &) { return sout << "term"; } }; template struct newterm { friend std::ostream &operator<<(std::ostream &sout, newterm const &) { return sout << "newterm<" << I::value << ">"; } }; proto::terminal::type const a = {{}}; proto::terminal::type const b = {{}}; proto::terminal::type const c = {{}}; using proto::functional::make_pair; using proto::functional::first; using proto::functional::second; using proto::functional::push_back; using proto::functional::unpack_expr; #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) #define _make_terminal(x) call #define Renumber(x,y) proto::call #define push_back(x,y) proto::call #define make_pair(x,y) proto::call #define unpack_expr(x,y) proto::call #define first(x) proto::call #define second(x) proto::call #endif struct Renumber; struct RenumberFun : proto::fold< _ , make_pair(fusion::vector0<>(), proto::_state) , proto::let< _a(Renumber(_, second(proto::_state))) , make_pair( push_back(first(proto::_state), first(_a)) , second(_a) ) > > {}; struct Renumber : proto::or_< proto::when< proto::terminal , make_pair( proto::_make_terminal(newterm()) , mpl::next() ) > , proto::when< proto::terminal<_> , make_pair(proto::_byval(_), proto::_state) > , proto::otherwise< proto::let< _a(RenumberFun) , make_pair( proto::lazy >(first(_a))> , second(_a) ) > > > {}; #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) #undef _make_terminal #undef Renumber #undef push_back #undef make_pair #undef unpack_expr #undef first #undef second #endif int main() { proto::display_expr(((a * a) + 1) + (b - c)); proto::display_expr(Renumber()(((a * a) + 1) + (b - c), mpl::int_<42>()).first); }