/*============================================================================== Copyright (c) 2001-2010 Joel de Guzman Copyright (c) 2010 Eric Niebler 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) ==============================================================================*/ #ifndef BOOST_PHOENIX_STATEMENT_IF_HPP #define BOOST_PHOENIX_STATEMENT_IF_HPP #include <boost/phoenix/config.hpp> #include <boost/phoenix/core/limits.hpp> #include <boost/phoenix/core/actor.hpp> #include <boost/phoenix/core/call.hpp> #include <boost/phoenix/core/expression.hpp> #include <boost/phoenix/core/meta_grammar.hpp> #include <boost/phoenix/core/is_actor.hpp> #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable: 4355) // 'this' used in base member initializer list #endif namespace boost { namespace phoenix { template <typename> struct if_actor; }} BOOST_PHOENIX_DEFINE_EXPRESSION_EXT( if_actor , (boost)(phoenix)(if_) , (meta_grammar) // Cond (meta_grammar) // Then ) BOOST_PHOENIX_DEFINE_EXPRESSION( (boost)(phoenix)(if_else_statement) , (meta_grammar) // Cond (meta_grammar) // Then (meta_grammar) // Else ) namespace boost { namespace phoenix { //////////////////////////////////////////////////////////////////////////// // If-Else statements //////////////////////////////////////////////////////////////////////////// // Function for evaluating lambdas like: // if_( foo )[ bar ] // and // if_( foo )[ bar ].else_[ baz ] struct if_else_eval { typedef void result_type; template<typename Cond, typename Then, typename Context> result_type operator()(Cond const & cond, Then const & then, Context const & ctx) const { if(boost::phoenix::eval(cond, ctx)) boost::phoenix::eval(then, ctx); } template<typename Cond, typename Then, typename Else, typename Context> result_type operator()( Cond const & cond , Then const & then , Else const & else_ , Context const & ctx ) const { if(boost::phoenix::eval(cond, ctx)) boost::phoenix::eval(then, ctx); else boost::phoenix::eval(else_, ctx); } }; template <typename Dummy> struct default_actions::when<rule::if_, Dummy> : call<if_else_eval, Dummy> {}; template <typename Dummy> struct default_actions::when<rule::if_else_statement, Dummy> : call<if_else_eval, Dummy> {}; // Generator for .else_[ expr ] branch. template<typename Cond, typename Then> struct else_gen { else_gen(Cond const & cond_, Then const & then_) : cond(cond_) , then(then_) {} template<typename Else> typename expression::if_else_statement<Cond, Then, Else>::type const operator[](Else const & else_) const { return expression::if_else_statement<Cond, Then, Else>::make(cond, then, else_); } Cond cond; Then then; }; // We subclass actor so we can provide the member else_ (which is an // else_gen responsible for the .else_[ expr ] branch). template<typename Expr> struct if_actor : actor<Expr> { typedef actor<Expr> base_type; if_actor(base_type const & base) : base_type(base) , else_(proto::child_c<0>(*this), proto::child_c<1>(*this)) {} typedef typename proto::result_of::child_c<Expr, 0>::type cond_type; typedef typename proto::result_of::child_c<Expr, 1>::type then_type; else_gen<cond_type, then_type> else_; }; template <typename Expr> struct is_actor<if_actor<Expr> > : mpl::true_ {}; // Generator for if( cond )[ then ] branch. template<typename Cond> struct if_gen { if_gen(Cond const & cond_) : cond(cond_) {} template<typename Then> typename expression::if_<Cond, Then>::type const operator[](Then const & then) const { return expression::if_<Cond, Then>::make(cond, then); } Cond cond; }; template<typename Cond> inline if_gen<Cond> const if_(Cond const & cond) { return if_gen<Cond>(cond); } }} #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif