1 /*==============================================================================
2 Copyright (c) 2001-2010 Joel de Guzman
3 Copyright (c) 2010 Thomas Heller
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
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>
23 #pragma warning(disable: 4065) // switch statement contains 'default' but no 'case' labels
26 BOOST_PHOENIX_DEFINE_EXPRESSION(
27 (boost)(phoenix)(switch_case)
28 , (proto::terminal<proto::_>)
32 BOOST_PHOENIX_DEFINE_EXPRESSION(
33 (boost)(phoenix)(switch_default_case)
37 namespace boost { namespace phoenix
41 struct switch_case_grammar;
42 struct switch_case_with_default_grammar;
46 detail::switch_case_grammar
50 detail::switch_case_with_default_grammar
59 struct switch_case_is_nullary
63 switch_case_is_nullary
64 , proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case>
67 switch_case_is_nullary(
71 , switch_case_is_nullary(
78 proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case>
79 , evaluator(proto::_child_c<0>, proto::_state)
84 struct switch_case_grammar
86 proto::comma<switch_case_grammar, phoenix::rule::switch_case>
87 , proto::when<phoenix::rule::switch_case, proto::_>
91 struct switch_case_with_default_grammar
93 proto::comma<switch_case_grammar, phoenix::rule::switch_default_case>
94 , proto::when<phoenix::rule::switch_default_case, proto::_>
101 proto::comma<switch_size, proto::_>
102 , mpl::next<switch_size(proto::_left)>()
104 , proto::when<proto::_, mpl::int_<1>()>
110 BOOST_PHOENIX_DEFINE_EXPRESSION(
111 (boost)(phoenix)(switch_)
112 , (meta_grammar) // Cond
113 (detail::switch_grammar) // Cases
116 namespace boost { namespace phoenix {
118 template <typename Dummy>
119 struct is_nullary::when<rule::switch_, Dummy>
121 evaluator(proto::_child_c<0>, _context)
122 , detail::switch_case_is_nullary(proto::_child_c<1>, _context)
128 typedef void result_type;
130 template <typename Context>
132 operator()(Context const &) const
136 template <typename Cond, typename Cases, typename Context>
138 operator()(Cond const & cond, Cases const & cases, Context const & ctx) const
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()
150 template <typename Context, typename Cond, typename Cases>
155 , Cases const & cases
161 typename proto::result_of::value<
162 typename proto::result_of::child_c<
169 switch(boost::phoenix::eval(cond, ctx))
171 case case_label::value:
172 boost::phoenix::eval(proto::child_c<1>(cases), ctx);
176 template <typename Context, typename Cond, typename Cases>
181 , Cases const & cases
186 switch(boost::phoenix::eval(cond, ctx))
189 boost::phoenix::eval(proto::child_c<0>(cases), ctx);
193 // Bring in the evaluation functions
194 #include <boost/phoenix/statement/detail/switch.hpp>
197 template <typename Dummy>
198 struct default_actions::when<rule::switch_, Dummy>
202 template <int N, typename A>
204 typename proto::result_of::make_expr<
206 , proto::basic_default_domain
215 , proto::basic_default_domain
222 template <typename A>
224 typename proto::result_of::make_expr<
225 tag::switch_default_case
226 , proto::basic_default_domain
233 tag::switch_default_case
234 , proto::basic_default_domain
238 template <typename Cond>
241 switch_gen(Cond const& cond_) : cond(cond_) {}
243 template <typename Cases>
244 typename expression::switch_<
248 operator[](Cases const& cases) const
253 , proto::matches<Cases, detail::switch_grammar>()
260 template <typename Cases>
261 typename expression::switch_<
265 generate(Cases const & cases, mpl::true_) const
267 return expression::switch_<Cond, Cases>::make(cond, cases);
270 template <typename Cases>
271 typename expression::switch_<
275 generate(Cases const &, mpl::false_) const
277 BOOST_MPL_ASSERT_MSG(
279 , INVALID_SWITCH_CASE_STATEMENT
285 template <typename Cond>
287 switch_gen<Cond> const
288 switch_(Cond const& cond)
290 return switch_gen<Cond>(cond);