// Copyright (C) 2010 von Karman Institute for Fluid Dynamics, Belgium // // This software is distributed under the terms of the // GNU Lesser General Public License version 3 (LGPLv3). // See doc/lgpl.txt and doc/gpl.txt for the license text. #ifndef CF_Solver_Actions_Proto_ExpressionGroup_hpp #define CF_Solver_Actions_Proto_ExpressionGroup_hpp #include #include #include /// @file /// Grammar and transform to make grouping expressions possible /// @author Bart Janssens namespace CF { namespace Solver { namespace Actions { namespace Proto { /// Primitive transform to evaluate a group of expressions template struct ExpressionGroup : boost::proto::transform< ExpressionGroup > { template struct impl : boost::proto::transform_impl { typedef void result_type; /// Fusion functor to evaluate each child expression using the GrammarT supplied in the template argument struct evaluate_expr { evaluate_expr(typename impl::state_param state, typename impl::data_param data) : m_state(state), m_data(data) { } template void operator()(ChildExprT& expr) const { GrammarT()(expr, m_state, m_data); } private: typename impl::state_param m_state; typename impl::data_param m_data; }; void operator ()( typename impl::expr_param expr , typename impl::state_param state , typename impl::data_param data ) const { boost::fusion::for_each(boost::proto::flatten(boost::proto::right(expr)), evaluate_expr(state, data) ); } }; }; /// Tags a terminal that triggers expression grouping struct ExpressionGroupTag {}; /// Use group << (expr1, expr2, ..., exprN) to evaluate a group of expressions. /// State can also be set for the expressions, using group(state) << (expr1, expr2, ..., exprN) static boost::proto::terminal< ExpressionGroupTag >::type group = {}; /// Matches and evaluates groups of expressions matching GrammarT template struct GroupGrammar : boost::proto::or_ < boost::proto::when < boost::proto::shift_left< boost::proto::terminal, boost::proto::comma >, boost::proto::call< ExpressionGroup > >, boost::proto::when // This variant allows passing a state as parameter < boost::proto::shift_left< boost::proto::function< boost::proto::terminal, boost::proto::terminal >, boost::proto::comma >, boost::proto::call< ExpressionGroup >(boost::proto::_expr, boost::proto::_value(boost::proto::_child1(boost::proto::_left))) > > { }; } // Proto } // Actions } // Solver } // CF #endif // CF_Solver_Actions_Proto_ExpressionGroup_hpp