Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2007 Joel de Guzman
|
Chris@16
|
3
|
Chris@16
|
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 ==============================================================================*/
|
Chris@16
|
7 #ifndef PHOENIX_STATEMENT_SWITCH_HPP
|
Chris@16
|
8 #define PHOENIX_STATEMENT_SWITCH_HPP
|
Chris@16
|
9
|
Chris@16
|
10 #include <boost/spirit/home/phoenix/core/composite.hpp>
|
Chris@16
|
11 #include <boost/spirit/home/phoenix/core/compose.hpp>
|
Chris@16
|
12 #include <boost/spirit/home/phoenix/core/nothing.hpp>
|
Chris@16
|
13 #include <boost/spirit/home/phoenix/statement/detail/switch_eval.hpp>
|
Chris@16
|
14 #include <boost/spirit/home/phoenix/statement/detail/switch.hpp>
|
Chris@16
|
15 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
16 #include <boost/mpl/not.hpp>
|
Chris@16
|
17
|
Chris@16
|
18 namespace boost { namespace phoenix
|
Chris@16
|
19 {
|
Chris@16
|
20 template <typename Derived, typename Actor>
|
Chris@16
|
21 struct switch_case_base
|
Chris@16
|
22 {
|
Chris@16
|
23 typedef Derived derived_t;
|
Chris@16
|
24 typedef Actor actor_t;
|
Chris@16
|
25 typedef typename Actor::no_nullary no_nullary;
|
Chris@16
|
26
|
Chris@16
|
27 template <typename Env>
|
Chris@16
|
28 struct result
|
Chris@16
|
29 {
|
Chris@16
|
30 typedef typename Actor::eval_type::template result<Env>::type type;
|
Chris@16
|
31 };
|
Chris@16
|
32
|
Chris@16
|
33 switch_case_base(Actor const& actor)
|
Chris@16
|
34 : actor(actor) {}
|
Chris@16
|
35
|
Chris@16
|
36 template <typename Env>
|
Chris@16
|
37 typename result<Env>::type
|
Chris@16
|
38 eval(Env const& env) const
|
Chris@16
|
39 {
|
Chris@16
|
40 return actor.eval(env);
|
Chris@16
|
41 }
|
Chris@16
|
42
|
Chris@16
|
43 Actor actor;
|
Chris@16
|
44 };
|
Chris@16
|
45
|
Chris@16
|
46 template <typename Actor, typename K, K Value>
|
Chris@16
|
47 struct switch_case : switch_case_base<switch_case<Actor, K, Value>, Actor>
|
Chris@16
|
48 {
|
Chris@16
|
49 typedef switch_case_base<switch_case<Actor, K, Value>, Actor> base_t;
|
Chris@16
|
50 static K const value = Value;
|
Chris@16
|
51 static bool const is_default = false;
|
Chris@16
|
52
|
Chris@16
|
53 switch_case(Actor const& actor)
|
Chris@16
|
54 : base_t(actor) {}
|
Chris@16
|
55 };
|
Chris@16
|
56
|
Chris@16
|
57 template <typename Actor>
|
Chris@16
|
58 struct default_case : switch_case_base<default_case<Actor>, Actor>
|
Chris@16
|
59 {
|
Chris@16
|
60 typedef switch_case_base<default_case<Actor>, Actor> base_t;
|
Chris@16
|
61 static bool const is_default = true;
|
Chris@16
|
62
|
Chris@16
|
63 default_case(Actor const& actor)
|
Chris@16
|
64 : base_t(actor) {}
|
Chris@16
|
65 };
|
Chris@16
|
66
|
Chris@16
|
67 template <typename Cond>
|
Chris@16
|
68 struct switch_gen
|
Chris@16
|
69 {
|
Chris@16
|
70 switch_gen(Cond const& cond)
|
Chris@16
|
71 : cond(cond) {}
|
Chris@16
|
72
|
Chris@16
|
73 template <typename Cases>
|
Chris@16
|
74 typename lazy_enable_if<
|
Chris@16
|
75 fusion::traits::is_sequence<Cases>
|
Chris@16
|
76 , detail::switch_composite_actor<Cond, Cases>
|
Chris@16
|
77 >::type
|
Chris@16
|
78 operator[](Cases const& cases) const
|
Chris@16
|
79 {
|
Chris@16
|
80 typedef typename
|
Chris@16
|
81 detail::switch_composite<Cond, Cases>
|
Chris@16
|
82 switch_composite;
|
Chris@16
|
83 return switch_composite::eval(cond, cases);
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 template <typename D, typename A>
|
Chris@16
|
87 actor<typename detail::
|
Chris@16
|
88 switch_composite<Cond, fusion::vector<actor<D> > >::type>
|
Chris@16
|
89 operator[](switch_case_base<D, A> const& case_) const
|
Chris@16
|
90 {
|
Chris@16
|
91 typedef typename
|
Chris@16
|
92 detail::switch_composite<Cond, fusion::vector<actor<D> > >
|
Chris@16
|
93 switch_composite;
|
Chris@16
|
94 return switch_composite::eval(cond,
|
Chris@16
|
95 fusion::vector<actor<D> >(static_cast<D const&>(case_)));
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 Cond cond;
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template <typename Cond>
|
Chris@16
|
102 inline switch_gen<typename as_actor<Cond>::type>
|
Chris@16
|
103 switch_(Cond const& cond)
|
Chris@16
|
104 {
|
Chris@16
|
105 return switch_gen<typename as_actor<Cond>::type>(
|
Chris@16
|
106 as_actor<Cond>::convert(cond));
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 template <int N, typename A0>
|
Chris@16
|
110 switch_case<typename as_actor<A0>::type, int, N>
|
Chris@16
|
111 case_(A0 const& _0)
|
Chris@16
|
112 {
|
Chris@16
|
113 return switch_case<typename as_actor<A0>::type, int, N>
|
Chris@16
|
114 (as_actor<A0>::convert(_0));
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 template <typename A0>
|
Chris@16
|
118 default_case<typename as_actor<A0>::type>
|
Chris@16
|
119 default_(A0 const& _0)
|
Chris@16
|
120 {
|
Chris@16
|
121 return default_case<typename as_actor<A0>::type>
|
Chris@16
|
122 (as_actor<A0>::convert(_0));
|
Chris@16
|
123 }
|
Chris@16
|
124
|
Chris@16
|
125 template <typename D0, typename A0, typename D1, typename A1>
|
Chris@16
|
126 inline typename detail::compose_case_a<D0, D1>::type
|
Chris@16
|
127 operator,(
|
Chris@16
|
128 switch_case_base<D0, A0> const& _0
|
Chris@16
|
129 , switch_case_base<D1, A1> const& _1
|
Chris@16
|
130 )
|
Chris@16
|
131 {
|
Chris@16
|
132 return detail::compose_case_a<D0, D1>::eval(
|
Chris@16
|
133 static_cast<D0 const&>(_0)
|
Chris@16
|
134 , static_cast<D1 const&>(_1)
|
Chris@16
|
135 );
|
Chris@16
|
136 }
|
Chris@16
|
137
|
Chris@16
|
138 template <typename Seq, typename D, typename A>
|
Chris@16
|
139 inline typename
|
Chris@16
|
140 lazy_enable_if<
|
Chris@16
|
141 fusion::traits::is_sequence<Seq>
|
Chris@16
|
142 , detail::compose_case_b<Seq, D>
|
Chris@16
|
143 >::type
|
Chris@16
|
144 operator,(Seq const& seq, switch_case_base<D, A> const& case_)
|
Chris@16
|
145 {
|
Chris@16
|
146 return detail::compose_case_b<Seq, D>::eval(
|
Chris@16
|
147 seq, static_cast<D const&>(case_));
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 // Implementation of routines in detail/switch.hpp that depend on
|
Chris@16
|
151 // the completeness of default_case.
|
Chris@16
|
152 namespace detail {
|
Chris@16
|
153 template <typename Cases>
|
Chris@16
|
154 typename ensure_default<Cases>::type
|
Chris@16
|
155 ensure_default<Cases>::eval(Cases const& cases, mpl::false_)
|
Chris@16
|
156 {
|
Chris@16
|
157 actor<default_case<actor<null_actor> > > default_
|
Chris@16
|
158 = default_case<actor<null_actor> >(nothing);
|
Chris@16
|
159 return fusion::push_front(cases, default_);
|
Chris@16
|
160 }
|
Chris@16
|
161 }
|
Chris@16
|
162 }}
|
Chris@16
|
163
|
Chris@16
|
164 #endif
|