]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/phoenix/include/boost/phoenix/statement/switch.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / phoenix / include / boost / phoenix / statement / switch.hpp
1 /*==============================================================================
2 Copyright (c) 2001-2010 Joel de Guzman
3 Copyright (c) 2010 Thomas Heller
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_SWITCH_HPP
9 #define BOOST_PHOENIX_STATEMENT_SWITCH_HPP
10
11 #include <boost/phoenix/core/limits.hpp>
12 #include <boost/fusion/iterator/advance.hpp>
13 #include <boost/phoenix/core/call.hpp>
14 #include <boost/phoenix/core/expression.hpp>
15 #include <boost/phoenix/core/meta_grammar.hpp>
16 #include <boost/phoenix/core/is_nullary.hpp>
17 #include <boost/phoenix/support/iterate.hpp>
18 #include <boost/proto/make_expr.hpp>
19 #include <boost/proto/fusion.hpp>
20
21 #ifdef _MSC_VER
22 #pragma warning(push)
23 #pragma warning(disable: 4065) // switch statement contains 'default' but no 'case' labels
24 #endif
25
26 BOOST_PHOENIX_DEFINE_EXPRESSION(
27 (boost)(phoenix)(switch_case)
28 , (proto::terminal<proto::_>)
29 (meta_grammar)
30 )
31
32 BOOST_PHOENIX_DEFINE_EXPRESSION(
33 (boost)(phoenix)(switch_default_case)
34 , (meta_grammar)
35 )
36
37 namespace boost { namespace phoenix
38 {
39 namespace detail
40 {
41 struct switch_case_grammar;
42 struct switch_case_with_default_grammar;
43 struct switch_grammar
44 : proto::or_<
45 proto::when<
46 detail::switch_case_grammar
47 , mpl::false_()
48 >
49 , proto::when<
50 detail::switch_case_with_default_grammar
51 , mpl::true_()
52 >
53 >
54 {};
55 }
56
57 namespace detail
58 {
59 struct switch_case_is_nullary
60 : proto::or_<
61 proto::when<
62 proto::comma<
63 switch_case_is_nullary
64 , proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case>
65 >
66 , mpl::and_<
67 switch_case_is_nullary(
68 proto::_child_c<0>
69 , proto::_state
70 )
71 , switch_case_is_nullary(
72 proto::_child_c<1>
73 , proto::_state
74 )
75 >()
76 >
77 , proto::when<
78 proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case>
79 , evaluator(proto::_child_c<0>, proto::_state)
80 >
81 >
82 {};
83
84 struct switch_case_grammar
85 : proto::or_<
86 proto::comma<switch_case_grammar, phoenix::rule::switch_case>
87 , proto::when<phoenix::rule::switch_case, proto::_>
88 >
89 {};
90
91 struct switch_case_with_default_grammar
92 : proto::or_<
93 proto::comma<switch_case_grammar, phoenix::rule::switch_default_case>
94 , proto::when<phoenix::rule::switch_default_case, proto::_>
95 >
96 {};
97
98 struct switch_size
99 : proto::or_<
100 proto::when<
101 proto::comma<switch_size, proto::_>
102 , mpl::next<switch_size(proto::_left)>()
103 >
104 , proto::when<proto::_, mpl::int_<1>()>
105 >
106 {};
107 }
108 }}
109
110 BOOST_PHOENIX_DEFINE_EXPRESSION(
111 (boost)(phoenix)(switch_)
112 , (meta_grammar) // Cond
113 (detail::switch_grammar) // Cases
114 )
115
116 namespace boost { namespace phoenix {
117
118 template <typename Dummy>
119 struct is_nullary::when<rule::switch_, Dummy>
120 : proto::and_<
121 evaluator(proto::_child_c<0>, _context)
122 , detail::switch_case_is_nullary(proto::_child_c<1>, _context)
123 >
124 {};
125
126 struct switch_eval
127 {
128 typedef void result_type;
129
130 template <typename Context>
131 result_type
132 operator()(Context const &) const
133 {
134 }
135
136 template <typename Cond, typename Cases, typename Context>
137 result_type
138 operator()(Cond const & cond, Cases const & cases, Context const & ctx) const
139 {
140 this->evaluate(
141 ctx
142 , cond
143 , cases
144 , typename detail::switch_size::impl<Cases, int, proto::empty_env>::result_type()
145 , typename detail::switch_grammar::impl<Cases, int, proto::empty_env>::result_type()
146 );
147 }
148
149 private:
150 template <typename Context, typename Cond, typename Cases>
151 result_type
152 evaluate(
153 Context const & ctx
154 , Cond const & cond
155 , Cases const & cases
156 , mpl::int_<1>
157 , mpl::false_
158 ) const
159 {
160 typedef
161 typename proto::result_of::value<
162 typename proto::result_of::child_c<
163 Cases
164 , 0
165 >::type
166 >::type
167 case_label;
168
169 switch(boost::phoenix::eval(cond, ctx))
170 {
171 case case_label::value:
172 boost::phoenix::eval(proto::child_c<1>(cases), ctx);
173 }
174 }
175
176 template <typename Context, typename Cond, typename Cases>
177 result_type
178 evaluate(
179 Context const & ctx
180 , Cond const & cond
181 , Cases const & cases
182 , mpl::int_<1>
183 , mpl::true_
184 ) const
185 {
186 switch(boost::phoenix::eval(cond, ctx))
187 {
188 default:
189 boost::phoenix::eval(proto::child_c<0>(cases), ctx);
190 }
191 }
192
193 // Bring in the evaluation functions
194 #include <boost/phoenix/statement/detail/switch.hpp>
195 };
196
197 template <typename Dummy>
198 struct default_actions::when<rule::switch_, Dummy>
199 : call<switch_eval>
200 {};
201
202 template <int N, typename A>
203 inline
204 typename proto::result_of::make_expr<
205 tag::switch_case
206 , proto::basic_default_domain
207 , mpl::int_<N>
208 , A
209 >::type const
210 case_(A const & a)
211 {
212 return
213 proto::make_expr<
214 tag::switch_case
215 , proto::basic_default_domain
216 >(
217 mpl::int_<N>()
218 , a
219 );
220 }
221
222 template <typename A>
223 inline
224 typename proto::result_of::make_expr<
225 tag::switch_default_case
226 , proto::basic_default_domain
227 , A
228 >::type const
229 default_(A const& a)
230 {
231 return
232 proto::make_expr<
233 tag::switch_default_case
234 , proto::basic_default_domain
235 >(a);
236 }
237
238 template <typename Cond>
239 struct switch_gen
240 {
241 switch_gen(Cond const& cond_) : cond(cond_) {}
242
243 template <typename Cases>
244 typename expression::switch_<
245 Cond
246 , Cases
247 >::type
248 operator[](Cases const& cases) const
249 {
250 return
251 this->generate(
252 cases
253 , proto::matches<Cases, detail::switch_grammar>()
254 );
255 }
256
257 private:
258 Cond const& cond;
259
260 template <typename Cases>
261 typename expression::switch_<
262 Cond
263 , Cases
264 >::type
265 generate(Cases const & cases, mpl::true_) const
266 {
267 return expression::switch_<Cond, Cases>::make(cond, cases);
268 }
269
270 template <typename Cases>
271 typename expression::switch_<
272 Cond
273 , Cases
274 >::type
275 generate(Cases const &, mpl::false_) const
276 {
277 BOOST_MPL_ASSERT_MSG(
278 false
279 , INVALID_SWITCH_CASE_STATEMENT
280 , (Cases)
281 );
282 }
283 };
284
285 template <typename Cond>
286 inline
287 switch_gen<Cond> const
288 switch_(Cond const& cond)
289 {
290 return switch_gen<Cond>(cond);
291 }
292
293 }}
294
295 #ifdef _MSC_VER
296 #pragma warning(pop)
297 #endif
298
299 #endif
300