• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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