]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | |
59 | 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 | |
67 | 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 | { | |
96 | 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 | |
102 | 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 | ||
118 | 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 | { | |
138 | if_gen(Cond const & cond_) | |
139 | : cond(cond_) {} | |
140 | ||
141 | template<typename Then> | |
142 | typename expression::if_<Cond, Then>::type const | |
143 | 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 | |
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 |