166 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			166 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================== | ||
|  |     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 |