#include struct omp_for_eval { typedef void result_type; template result_type operator()( Init const& init , Cond const& cond , Step const& step , Do const& do_ , Context & ctx ) const { #pragma omp parallel for( boost::phoenix::eval(init, ctx); boost::phoenix::eval(cond, ctx); boost::phoenix::eval(step, ctx) ) { boost::phoenix::eval(do_, ctx); } } }; //////////////////////////////////////////////////////////////////////////////// // Define new custom expression BOOST_PHOENIX_DEFINE_EXPRESSION( (omp_for) , (boost::phoenix::meta_grammar) // Cond (boost::phoenix::meta_grammar) // Init (boost::phoenix::meta_grammar) // Step (boost::phoenix::meta_grammar) // Do ) namespace boost { namespace phoenix { template <> struct default_actions::when< ::rule::omp_for> : boost::phoenix::call< ::omp_for_eval> {}; }} template struct omp_for_gen { omp_for_gen(Init const& init, Cond const& cond, Step const& step) : init(init), cond(cond), step(step) {} template typename expression::omp_for::type const operator[](Do const& do_) const { return expression:: omp_for:: make(init, cond, step, do_); } Init init; Cond cond; Step step; }; template inline omp_for_gen const omp_for(Init const& init, Cond const& cond, Step const& step) { return omp_for_gen(init, cond, step); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Define new evaluation scheme struct parallel_actions { template struct when : boost::phoenix::default_actions::when {}; }; template <> struct parallel_actions::when : boost::phoenix::call {}; // Doing the same as actor::operator template typename boost::result_of< boost::phoenix::evaluator( Expr const & , typename boost::phoenix::result_of::context< boost::phoenix::vector4 , parallel_actions >::type ) >::type parallel_eval(Expr const & expr, A0 & a0, A1 & a1, A2 & a2) { boost::phoenix::vector4 env = {boost::addressof(expr), a0, a1, a2}; return boost::phoenix::eval(expr, boost::phoenix::context(env, parallel_actions())); } // changing evaluation mechanism on the fly BOOST_PHOENIX_DEFINE_EXPRESSION( (parallel) , (boost::phoenix::meta_grammar) ) namespace boost { namespace phoenix { template <> struct default_actions::when< ::rule::parallel> : proto::call< evaluator( proto::_child0 , functional::context( _env , parallel_actions() ) , int() ) > {}; }} template typename expression::parallel::type const parallel(Expr const & expr) { return expression::parallel::make(expr); } //////////////////////////////////////////////////////////////////////////////// #include #include int main() { using boost::phoenix::arg_names::_1; using boost::phoenix::arg_names::_2; using boost::phoenix::arg_names::_3; using boost::phoenix::local_names::_a; using boost::phoenix::local_names::_b; using boost::phoenix::local_names::_c; using boost::phoenix::let; using boost::phoenix::bind; using boost::phoenix::lambda; using boost::phoenix::nothing; const int NUM = 67108864; { std::vector a(NUM, 1); std::vector b(NUM, 2); std::vector c(NUM, 0); ( let(_a = begin(_1), _b = begin(_2), _c = begin(_3)) [ for_(nothing, _a != end(_1), (++_a, ++_b, ++_c)) [ *_c = *_a + *_b ] ] , std::cout << accumulate(_3, 0) << "\n" )(a, b, c); } { std::vector a(NUM, 1); std::vector b(NUM, 2); std::vector c(NUM, 0); ( let(_a = begin(_1), _b = begin(_2), _c = begin(_3)) [ omp_for(nothing, _a != end(_1), (++_a, ++_b, ++_c)) [ *_c = *_a + *_b ] , std::cout << accumulate(_3, 0) << "\n" ] )(a, b, c); } { std::vector a(NUM, 1); std::vector b(NUM, 2); std::vector c(NUM, 0); parallel_eval( let(_a = begin(_1), _b = begin(_2), _c = begin(_3)) [ for_(nothing, _a != end(_1), (++_a, ++_b, ++_c)) [ *_c = *_a + *_b ] , std::cout << accumulate(_3, 0) << "\n" ] , a, b, c); } { std::vector a(NUM, 1); std::vector b(NUM, 2); std::vector c(NUM, 0); ( let(_a = begin(_1), _b = begin(_2), _c = begin(_3)) [ parallel( for_(nothing, _a != end(_1), (++_a, ++_b, ++_c)) [ *_c = *_a + *_b ] ) ] , std::cout << accumulate(_3, 0) << "\n" )(a, b, c); } }