1 /*============================================================================== 2 Copyright (c) 2001-2010 Joel de Guzman 3 Copyright (c) 2010 Eric Niebler 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #ifndef BOOST_PHOENIX_STATEMENT_IF_HPP 9 #define BOOST_PHOENIX_STATEMENT_IF_HPP 10 11 #include <boost/phoenix/config.hpp> 12 #include <boost/phoenix/core/limits.hpp> 13 #include <boost/phoenix/core/actor.hpp> 14 #include <boost/phoenix/core/call.hpp> 15 #include <boost/phoenix/core/expression.hpp> 16 #include <boost/phoenix/core/meta_grammar.hpp> 17 #include <boost/phoenix/core/is_actor.hpp> 18 19 #ifdef BOOST_MSVC 20 #pragma warning(push) 21 #pragma warning(disable: 4355) // 'this' used in base member initializer list 22 #endif 23 24 namespace boost { namespace phoenix 25 { 26 template <typename> struct if_actor; 27 }} 28 29 BOOST_PHOENIX_DEFINE_EXPRESSION_EXT( 30 if_actor 31 , (boost)(phoenix)(if_) 32 , (meta_grammar) // Cond 33 (meta_grammar) // Then 34 ) 35 36 BOOST_PHOENIX_DEFINE_EXPRESSION( 37 (boost)(phoenix)(if_else_statement) 38 , (meta_grammar) // Cond 39 (meta_grammar) // Then 40 (meta_grammar) // Else 41 ) 42 43 namespace boost { namespace phoenix 44 { 45 //////////////////////////////////////////////////////////////////////////// 46 // If-Else statements 47 //////////////////////////////////////////////////////////////////////////// 48 49 // Function for evaluating lambdas like: 50 // if_( foo )[ bar ] 51 // and 52 // if_( foo )[ bar ].else_[ baz ] 53 struct if_else_eval 54 { 55 typedef void result_type; 56 57 template<typename Cond, typename Then, typename Context> 58 result_type operator ()boost::phoenix::if_else_eval59 operator()(Cond const & cond, Then const & then, Context const & ctx) const 60 { 61 if(boost::phoenix::eval(cond, ctx)) 62 boost::phoenix::eval(then, ctx); 63 } 64 65 template<typename Cond, typename Then, typename Else, typename Context> 66 result_type operator ()boost::phoenix::if_else_eval67 operator()( 68 Cond const & cond 69 , Then const & then 70 , Else const & else_ 71 , Context const & ctx 72 ) const 73 { 74 if(boost::phoenix::eval(cond, ctx)) 75 boost::phoenix::eval(then, ctx); 76 else 77 boost::phoenix::eval(else_, ctx); 78 } 79 }; 80 81 template <typename Dummy> 82 struct default_actions::when<rule::if_, Dummy> 83 : call<if_else_eval, Dummy> 84 {}; 85 86 template <typename Dummy> 87 struct default_actions::when<rule::if_else_statement, Dummy> 88 : call<if_else_eval, Dummy> 89 {}; 90 91 92 // Generator for .else_[ expr ] branch. 93 template<typename Cond, typename Then> 94 struct else_gen 95 { else_genboost::phoenix::else_gen96 else_gen(Cond const & cond_, Then const & then_) 97 : cond(cond_) 98 , then(then_) {} 99 100 template<typename Else> 101 typename expression::if_else_statement<Cond, Then, Else>::type const operator []boost::phoenix::else_gen102 operator[](Else const & else_) const 103 { 104 return expression::if_else_statement<Cond, Then, Else>::make(cond, then, else_); 105 } 106 107 Cond cond; 108 Then then; 109 }; 110 111 // We subclass actor so we can provide the member else_ (which is an 112 // else_gen responsible for the .else_[ expr ] branch). 113 template<typename Expr> 114 struct if_actor : actor<Expr> 115 { 116 typedef actor<Expr> base_type; 117 if_actorboost::phoenix::if_actor118 if_actor(base_type const & base) 119 : base_type(base) 120 , else_(proto::child_c<0>(*this), proto::child_c<1>(*this)) 121 {} 122 123 typedef typename proto::result_of::child_c<Expr, 0>::type cond_type; 124 typedef typename proto::result_of::child_c<Expr, 1>::type then_type; 125 126 else_gen<cond_type, then_type> else_; 127 }; 128 129 template <typename Expr> 130 struct is_actor<if_actor<Expr> > 131 : mpl::true_ 132 {}; 133 134 // Generator for if( cond )[ then ] branch. 135 template<typename Cond> 136 struct if_gen 137 { if_genboost::phoenix::if_gen138 if_gen(Cond const & cond_) 139 : cond(cond_) {} 140 141 template<typename Then> 142 typename expression::if_<Cond, Then>::type const operator []boost::phoenix::if_gen143 operator[](Then const & then) const 144 { 145 return expression::if_<Cond, Then>::make(cond, then); 146 } 147 148 Cond cond; 149 }; 150 151 template<typename Cond> 152 inline 153 if_gen<Cond> const if_(Cond const & cond)154 if_(Cond const & cond) 155 { 156 return if_gen<Cond>(cond); 157 } 158 159 }} 160 161 #ifdef BOOST_MSVC 162 #pragma warning(pop) 163 #endif 164 165 #endif 166