comparison DEPENDENCIES/generic/include/boost/spirit/home/phoenix/statement/detail/switch.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 /*=============================================================================
2 Copyright (c) 2001-2007 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #ifndef PHOENIX_STATEMENT_DETAIL_SWITCH_HPP
8 #define PHOENIX_STATEMENT_DETAIL_SWITCH_HPP
9
10 #include <boost/spirit/home/phoenix/core/nothing.hpp>
11 #include <boost/fusion/include/vector.hpp>
12 #include <boost/fusion/include/as_vector.hpp>
13 #include <boost/fusion/include/push_back.hpp>
14 #include <boost/fusion/include/push_front.hpp>
15 #include <boost/fusion/include/begin.hpp>
16 #include <boost/fusion/include/size.hpp>
17 #include <boost/fusion/include/value_of.hpp>
18 #include <boost/fusion/include/is_sequence.hpp>
19 #include <boost/mpl/identity.hpp>
20 #include <boost/mpl/bool.hpp>
21 #include <boost/mpl/eval_if.hpp>
22 #include <boost/mpl/if.hpp>
23
24 namespace boost { namespace phoenix
25 {
26
27 template <typename Actor, typename K, K Value>
28 struct switch_case;
29
30 template <typename Actor>
31 struct default_case;
32
33 namespace detail
34 {
35 template <typename T>
36 struct is_default_case : mpl::bool_<T::is_default> {};
37
38 template <typename A0, typename A1>
39 struct compose_case_a
40 {
41 // here, A0 and A1 are both switch cases
42 typedef typename
43 mpl::if_<
44 is_default_case<A1>
45 , fusion::vector<actor<A1>, actor<A0> >
46 , fusion::vector<actor<A0>, actor<A1> >
47 >::type
48 type;
49
50 static type
51 eval(A0 const& _0, A1 const& _1, mpl::false_)
52 {
53 return type(_0, _1);
54 }
55
56 static type
57 eval(A0 const& _0, A1 const& _1, mpl::true_)
58 {
59 return type(_1, _0);
60 }
61
62 static type
63 eval(A0 const& _0, A1 const& _1)
64 {
65 return eval(_0, _1, is_default_case<A1>());
66 }
67 };
68
69 template <typename Seq, typename Case>
70 struct compose_case_b
71 {
72 typedef typename fusion::result_of::as_vector<
73 typename mpl::eval_if<
74 is_default_case<Case>
75 , fusion::result_of::push_front<Seq const, actor<Case> >
76 , fusion::result_of::push_back<Seq const, actor<Case> >
77 >::type>::type
78 type;
79
80 static type
81 eval(Seq const& seq, Case const& case_, mpl::false_)
82 {
83 return fusion::as_vector(
84 fusion::push_back(seq, actor<Case>(case_)));
85 }
86
87 static type
88 eval(Seq const& seq, Case const& case_, mpl::true_)
89 {
90 return fusion::as_vector(
91 fusion::push_front(seq, actor<Case>(case_)));
92 }
93
94 static type
95 eval(Seq const& seq, Case const& case_)
96 {
97 return eval(seq, case_, is_default_case<Case>());
98 }
99 };
100
101 template <typename Cases>
102 struct ensure_default
103 {
104 typedef
105 is_default_case<
106 typename fusion::result_of::value_of<
107 typename fusion::result_of::begin<Cases>::type
108 >::type
109 >
110 is_default_case_;
111
112 typedef typename
113 mpl::eval_if<
114 is_default_case_
115 , mpl::identity<Cases>
116 , fusion::result_of::push_front<
117 Cases const, actor<default_case<actor<null_actor> > > >
118 >::type
119 type;
120
121 static type
122 eval(Cases const& cases, mpl::false_);
123
124 static type
125 eval(Cases const& cases, mpl::true_)
126 {
127 return cases;
128 }
129
130 static type
131 eval(Cases const& cases)
132 {
133 return eval(cases, is_default_case_());
134 }
135 };
136
137 template <typename Cond, typename Cases>
138 struct switch_composite
139 {
140 BOOST_STATIC_ASSERT(fusion::traits::is_sequence<Cases>::value);
141 typedef ensure_default<Cases> ensure_default_;
142
143 typedef typename
144 fusion::result_of::as_vector<
145 typename fusion::result_of::push_front<
146 typename ensure_default_::type, Cond>::type
147 >::type
148 tuple_type;
149
150 typedef
151 composite<
152 detail::switch_eval<fusion::result_of::size<tuple_type>::value-2>
153 , tuple_type>
154 type;
155
156 static type
157 eval(Cond const& cond, Cases const& cases)
158 {
159 return fusion::as_vector(
160 fusion::push_front(ensure_default_::eval(cases), cond));
161 }
162 };
163
164 template <typename Cond, typename Cases>
165 struct switch_composite_actor
166 {
167 typedef actor<typename switch_composite<Cond, Cases>::type> type;
168 };
169 }
170 }}
171
172 #endif