/*============================================================================= Copyright (c) 2001-2007 Joel de Guzman Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #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 result_of::make_omp_for::type const operator[](Do const& do_) const { return make_omp_for(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::phoenix::result_of::eval< Expr const & , typename boost::phoenix::result_of::make_context< typename boost::phoenix::result_of::make_env< Expr const * , A0 & , A1 & , A2 & >::type , parallel_actions >::type >::type parallel_eval(Expr & expr, A0 & a0, A1 & a1, A2 & a2) { Expr const * this_ = boost::addressof(expr); return boost::phoenix::eval( expr , boost::phoenix::make_context( boost::phoenix::make_env(this_, a0, a1, a2) , 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::make_context( _env , parallel_actions() ) , unused()//mpl::void_() ) > {}; }} template typename result_of::make_parallel::type parallel(Expr const & expr) { return make_parallel(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 = 1; { 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); } }