Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/support/meta_compiler.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-2011 Joel de Guzman | |
3 http://spirit.sourceforge.net/ | |
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_SPIRIT_META_COMPILER_OCTOBER_16_2008_1258PM | |
9 #define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_1258PM | |
10 | |
11 #if defined(_MSC_VER) | |
12 #pragma once | |
13 #endif | |
14 | |
15 #include <boost/config.hpp> | |
16 #include <boost/spirit/include/phoenix_limits.hpp> | |
17 #include <boost/detail/workaround.hpp> | |
18 #include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto | |
19 #include <boost/proto/proto.hpp> | |
20 #include <boost/spirit/home/support/make_component.hpp> | |
21 #include <boost/spirit/home/support/modify.hpp> | |
22 #include <boost/spirit/home/support/detail/make_cons.hpp> | |
23 #include <boost/spirit/home/support/unused.hpp> | |
24 #include <boost/spirit/home/support/assert_msg.hpp> | |
25 #include <boost/utility/enable_if.hpp> | |
26 #include <boost/type_traits/remove_reference.hpp> | |
27 | |
28 namespace boost { namespace spirit | |
29 { | |
30 // Some defaults... | |
31 | |
32 template <typename Domain, typename Tag, typename Enable = void> | |
33 struct use_operator : mpl::false_ {}; | |
34 | |
35 template <typename Domain, typename T, typename Enable = void> | |
36 struct use_function : mpl::false_ {}; | |
37 | |
38 template <typename Domain, typename T, typename Enable = void> | |
39 struct use_directive : mpl::false_ {}; | |
40 | |
41 template <typename Domain, typename T, typename Enable /* = void */> | |
42 struct is_modifier_directive : mpl::false_ {}; | |
43 | |
44 template <typename Domain, typename T, typename Enable = void> | |
45 struct use_terminal : mpl::false_ {}; | |
46 | |
47 template <typename Domain, typename T, typename Enable /*= void*/> | |
48 struct flatten_tree : mpl::false_ {}; | |
49 | |
50 // Our meta-compiler. This is the main engine that hooks Spirit | |
51 // to the proto expression template engine. | |
52 | |
53 template <typename Domain> | |
54 struct meta_compiler | |
55 { | |
56 struct meta_grammar; | |
57 | |
58 BOOST_SPIRIT_ASSERT_MSG(( | |
59 !use_operator<Domain, proto::tag::subscript>::value | |
60 ), error_proto_tag_subscript_cannot_be_used, ()); | |
61 | |
62 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1400) | |
63 // this is the non-broken part for compilers properly supporting | |
64 // partial template specialization (VC7.1 does not) | |
65 struct cases | |
66 { | |
67 template <typename Tag, typename Enable = void> | |
68 struct case_ | |
69 : proto::not_<proto::_> | |
70 {}; | |
71 | |
72 /////////////////////////////////////////////////////////////////// | |
73 // terminals | |
74 /////////////////////////////////////////////////////////////////// | |
75 template <typename Enable> | |
76 struct case_<proto::tag::terminal, Enable> | |
77 : proto::when< | |
78 proto::if_<use_terminal<Domain, proto::_value>()>, | |
79 detail::make_terminal<Domain> | |
80 > | |
81 {}; | |
82 | |
83 template <typename Tag> | |
84 struct case_<Tag, typename enable_if<use_operator<Domain, Tag> >::type> | |
85 : proto::or_< | |
86 /////////////////////////////////////////////////////////////////// | |
87 // binary operators | |
88 /////////////////////////////////////////////////////////////////// | |
89 proto::when<proto::binary_expr<Tag, meta_grammar, meta_grammar>, | |
90 detail::make_binary<Domain, Tag, meta_grammar> | |
91 >, | |
92 /////////////////////////////////////////////////////////////////// | |
93 // unary operators | |
94 /////////////////////////////////////////////////////////////////// | |
95 proto::when<proto::unary_expr<Tag, meta_grammar>, | |
96 detail::make_unary<Domain, Tag, meta_grammar> | |
97 > | |
98 > | |
99 {}; | |
100 | |
101 template <typename Enable> | |
102 struct case_<proto::tag::subscript, Enable> | |
103 : proto::or_< | |
104 /////////////////////////////////////////////////////////////////// | |
105 // directives | |
106 /////////////////////////////////////////////////////////////////// | |
107 proto::when<proto::binary_expr<proto::tag::subscript | |
108 , proto::and_< | |
109 proto::terminal<proto::_> | |
110 , proto::if_<use_directive<Domain, proto::_value >()> > | |
111 , meta_grammar>, | |
112 detail::make_directive<Domain, meta_grammar> | |
113 >, | |
114 /////////////////////////////////////////////////////////////////// | |
115 // semantic actions | |
116 /////////////////////////////////////////////////////////////////// | |
117 proto::when<proto::binary_expr<proto::tag::subscript | |
118 , meta_grammar, proto::_>, | |
119 detail::make_action<Domain, meta_grammar> | |
120 > | |
121 > | |
122 {}; | |
123 }; | |
124 #else | |
125 // this part actually constitutes invalid C++ code, but it allows us to | |
126 // convince VC7.1 to do what we want | |
127 struct cases | |
128 { | |
129 template <typename Tag, typename Enable = void> | |
130 struct case_ | |
131 : proto::not_<proto::_> | |
132 {}; | |
133 | |
134 /////////////////////////////////////////////////////////////////// | |
135 // terminals | |
136 /////////////////////////////////////////////////////////////////// | |
137 template <> | |
138 struct case_<proto::tag::terminal> | |
139 : proto::when< | |
140 proto::if_<use_terminal<Domain, proto::_value>()>, | |
141 detail::make_terminal<Domain> | |
142 > | |
143 {}; | |
144 | |
145 template <typename Tag> | |
146 struct case_<Tag> | |
147 : proto::or_< | |
148 /////////////////////////////////////////////////////////////////// | |
149 // binary operators | |
150 /////////////////////////////////////////////////////////////////// | |
151 proto::when<proto::binary_expr< | |
152 typename enable_if<use_operator<Domain, Tag>, Tag>::type | |
153 , meta_grammar, meta_grammar> | |
154 , detail::make_binary<Domain, Tag, meta_grammar> | |
155 >, | |
156 /////////////////////////////////////////////////////////////////// | |
157 // unary operators | |
158 /////////////////////////////////////////////////////////////////// | |
159 proto::when<proto::unary_expr< | |
160 typename enable_if<use_operator<Domain, Tag>, Tag>::type | |
161 , meta_grammar> | |
162 , detail::make_unary<Domain, Tag, meta_grammar> | |
163 > | |
164 > | |
165 {}; | |
166 | |
167 template <> | |
168 struct case_<proto::tag::subscript> | |
169 : proto::or_< | |
170 /////////////////////////////////////////////////////////////////// | |
171 // directives | |
172 /////////////////////////////////////////////////////////////////// | |
173 proto::when<proto::binary_expr<proto::tag::subscript | |
174 , proto::and_< | |
175 proto::terminal<proto::_> | |
176 , proto::if_<use_directive<Domain, proto::_value >()> > | |
177 , meta_grammar>, | |
178 detail::make_directive<Domain, meta_grammar> | |
179 >, | |
180 /////////////////////////////////////////////////////////////////// | |
181 // semantic actions | |
182 /////////////////////////////////////////////////////////////////// | |
183 proto::when<proto::binary_expr<proto::tag::subscript | |
184 , meta_grammar, proto::_>, | |
185 detail::make_action<Domain, meta_grammar> | |
186 > | |
187 > | |
188 {}; | |
189 }; | |
190 #endif | |
191 | |
192 struct meta_grammar | |
193 : proto::switch_<cases> | |
194 {}; | |
195 }; | |
196 | |
197 namespace result_of | |
198 { | |
199 // Default case | |
200 template <typename Domain, typename Expr | |
201 , typename Modifiers = unused_type, typename Enable = void> | |
202 struct compile | |
203 { | |
204 typedef typename meta_compiler<Domain>::meta_grammar meta_grammar; | |
205 typedef typename meta_grammar:: | |
206 template result<meta_grammar(Expr, mpl::void_, Modifiers)>::type | |
207 type; | |
208 }; | |
209 | |
210 // If Expr is not a proto expression, make it a terminal | |
211 template <typename Domain, typename Expr, typename Modifiers> | |
212 struct compile<Domain, Expr, Modifiers, | |
213 typename disable_if<proto::is_expr<Expr> >::type> | |
214 : compile<Domain, typename proto::terminal<Expr>::type, Modifiers> {}; | |
215 } | |
216 | |
217 namespace traits | |
218 { | |
219 // Check if Expr matches the domain's grammar | |
220 template <typename Domain, typename Expr> | |
221 struct matches : | |
222 proto::matches< | |
223 typename proto::result_of::as_expr< | |
224 typename remove_reference<Expr>::type>::type, | |
225 typename meta_compiler<Domain>::meta_grammar | |
226 > | |
227 { | |
228 }; | |
229 } | |
230 | |
231 namespace detail | |
232 { | |
233 template <typename Domain> | |
234 struct compiler | |
235 { | |
236 // Default case | |
237 template <typename Expr, typename Modifiers> | |
238 static typename spirit::result_of::compile<Domain, Expr, Modifiers>::type | |
239 compile(Expr const& expr, Modifiers modifiers, mpl::true_) | |
240 { | |
241 typename meta_compiler<Domain>::meta_grammar compiler; | |
242 return compiler(expr, mpl::void_(), modifiers); | |
243 } | |
244 | |
245 // If Expr is not a proto expression, make it a terminal | |
246 template <typename Expr, typename Modifiers> | |
247 static typename spirit::result_of::compile<Domain, Expr, Modifiers>::type | |
248 compile(Expr const& expr, Modifiers modifiers, mpl::false_) | |
249 { | |
250 typename meta_compiler<Domain>::meta_grammar compiler; | |
251 typedef typename detail::as_meta_element<Expr>::type expr_; | |
252 typename proto::terminal<expr_>::type term = {expr}; | |
253 return compiler(term, mpl::void_(), modifiers); | |
254 } | |
255 }; | |
256 } | |
257 | |
258 template <typename Domain, typename Expr> | |
259 inline typename result_of::compile<Domain, Expr, unused_type>::type | |
260 compile(Expr const& expr) | |
261 { | |
262 typedef typename proto::is_expr<Expr>::type is_expr; | |
263 return detail::compiler<Domain>::compile(expr, unused, is_expr()); | |
264 } | |
265 | |
266 template <typename Domain, typename Expr, typename Modifiers> | |
267 inline typename result_of::compile<Domain, Expr, Modifiers>::type | |
268 compile(Expr const& expr, Modifiers modifiers) | |
269 { | |
270 typedef typename proto::is_expr<Expr>::type is_expr; | |
271 return detail::compiler<Domain>::compile(expr, modifiers, is_expr()); | |
272 } | |
273 | |
274 /////////////////////////////////////////////////////////////////////////// | |
275 template <typename Elements, template <typename Subject> class generator> | |
276 struct make_unary_composite | |
277 { | |
278 typedef typename | |
279 fusion::result_of::value_at_c<Elements, 0>::type | |
280 element_type; | |
281 typedef generator<element_type> result_type; | |
282 result_type operator()(Elements const& elements, unused_type) const | |
283 { | |
284 return result_type(fusion::at_c<0>(elements)); | |
285 } | |
286 }; | |
287 | |
288 template <typename Elements, template <typename Left, typename Right> class generator> | |
289 struct make_binary_composite | |
290 { | |
291 typedef typename | |
292 fusion::result_of::value_at_c<Elements, 0>::type | |
293 left_type; | |
294 typedef typename | |
295 fusion::result_of::value_at_c<Elements, 1>::type | |
296 right_type; | |
297 typedef generator<left_type, right_type> result_type; | |
298 | |
299 result_type operator()(Elements const& elements, unused_type) const | |
300 { | |
301 return result_type( | |
302 fusion::at_c<0>(elements) | |
303 , fusion::at_c<1>(elements) | |
304 ); | |
305 } | |
306 }; | |
307 | |
308 template <typename Elements, template <typename Elements_> class generator> | |
309 struct make_nary_composite | |
310 { | |
311 typedef generator<Elements> result_type; | |
312 result_type operator()(Elements const& elements, unused_type) const | |
313 { | |
314 return result_type(elements); | |
315 } | |
316 }; | |
317 | |
318 }} | |
319 | |
320 #endif |