Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file fusion.hpp
|
Chris@16
|
3 /// Make any Proto expression a valid Fusion sequence
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
|
Chris@16
|
10 #define BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/config.hpp>
|
Chris@16
|
13 #include <boost/mpl/if.hpp>
|
Chris@16
|
14 #include <boost/mpl/bool.hpp>
|
Chris@16
|
15 #include <boost/mpl/long.hpp>
|
Chris@16
|
16 #include <boost/mpl/sequence_tag_fwd.hpp>
|
Chris@16
|
17 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
18 #include <boost/fusion/include/is_view.hpp>
|
Chris@16
|
19 #include <boost/fusion/include/tag_of_fwd.hpp>
|
Chris@16
|
20 #include <boost/fusion/include/category_of.hpp>
|
Chris@16
|
21 #include <boost/fusion/include/iterator_base.hpp>
|
Chris@16
|
22 #include <boost/fusion/include/intrinsic.hpp>
|
Chris@16
|
23 #include <boost/fusion/include/single_view.hpp>
|
Chris@16
|
24 #include <boost/fusion/include/transform.hpp>
|
Chris@16
|
25 #include <boost/fusion/include/as_list.hpp>
|
Chris@16
|
26 #include <boost/fusion/include/is_segmented.hpp>
|
Chris@16
|
27 #include <boost/fusion/sequence/comparison/enable_comparison.hpp>
|
Chris@16
|
28 #include <boost/proto/proto_fwd.hpp>
|
Chris@16
|
29 #include <boost/proto/traits.hpp>
|
Chris@16
|
30 #include <boost/proto/eval.hpp>
|
Chris@16
|
31 #include <boost/proto/make_expr.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 #ifdef BOOST_MSVC
|
Chris@16
|
34 #pragma warning(push)
|
Chris@16
|
35 #pragma warning(disable : 4510) // default constructor could not be generated
|
Chris@16
|
36 #pragma warning(disable : 4512) // assignment operator could not be generated
|
Chris@16
|
37 #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
|
Chris@16
|
38 #endif
|
Chris@16
|
39
|
Chris@16
|
40 namespace boost { namespace proto
|
Chris@16
|
41 {
|
Chris@16
|
42 namespace detail
|
Chris@16
|
43 {
|
Chris@16
|
44 template<typename Expr, long Pos>
|
Chris@16
|
45 struct expr_iterator
|
Chris@16
|
46 : fusion::iterator_base<expr_iterator<Expr, Pos> >
|
Chris@16
|
47 {
|
Chris@16
|
48 typedef Expr expr_type;
|
Chris@16
|
49 static const long index = Pos;
|
Chris@16
|
50 typedef fusion::random_access_traversal_tag category;
|
Chris@16
|
51 typedef
|
Chris@16
|
52 tag::proto_expr_iterator<
|
Chris@16
|
53 typename Expr::proto_tag
|
Chris@16
|
54 , typename Expr::proto_domain
|
Chris@16
|
55 >
|
Chris@16
|
56 fusion_tag;
|
Chris@16
|
57
|
Chris@16
|
58 explicit expr_iterator(Expr &e)
|
Chris@16
|
59 : expr(e)
|
Chris@16
|
60 {}
|
Chris@16
|
61
|
Chris@16
|
62 Expr &expr;
|
Chris@16
|
63 };
|
Chris@16
|
64
|
Chris@16
|
65 template<typename Tag>
|
Chris@16
|
66 struct as_element
|
Chris@16
|
67 {
|
Chris@16
|
68 template<typename Sig>
|
Chris@16
|
69 struct result;
|
Chris@16
|
70
|
Chris@16
|
71 template<typename This, typename Expr>
|
Chris@16
|
72 struct result<This(Expr)>
|
Chris@16
|
73 : result<This(Expr const &)>
|
Chris@16
|
74 {};
|
Chris@16
|
75
|
Chris@16
|
76 template<typename This, typename Expr>
|
Chris@16
|
77 struct result<This(Expr &)>
|
Chris@16
|
78 : mpl::if_c<
|
Chris@16
|
79 is_same<Tag, typename Expr::proto_tag>::value
|
Chris@16
|
80 , flat_view<Expr>
|
Chris@16
|
81 , fusion::single_view<Expr &>
|
Chris@16
|
82 >
|
Chris@16
|
83 {};
|
Chris@16
|
84
|
Chris@16
|
85 template<typename Expr>
|
Chris@16
|
86 typename result<as_element(Expr &)>::type const
|
Chris@16
|
87 operator ()(Expr &e) const
|
Chris@16
|
88 {
|
Chris@16
|
89 return typename result<as_element(Expr &)>::type(e);
|
Chris@16
|
90 }
|
Chris@16
|
91
|
Chris@16
|
92 template<typename Expr>
|
Chris@16
|
93 typename result<as_element(Expr const &)>::type const
|
Chris@16
|
94 operator ()(Expr const &e) const
|
Chris@16
|
95 {
|
Chris@16
|
96 return typename result<as_element(Expr const &)>::type(e);
|
Chris@16
|
97 }
|
Chris@16
|
98 };
|
Chris@16
|
99
|
Chris@16
|
100 template<typename Expr>
|
Chris@16
|
101 struct flat_view
|
Chris@16
|
102 : fusion::sequence_base<flat_view<Expr> >
|
Chris@16
|
103 {
|
Chris@16
|
104 typedef fusion::forward_traversal_tag category;
|
Chris@16
|
105 typedef
|
Chris@16
|
106 tag::proto_flat_view<
|
Chris@16
|
107 typename Expr::proto_tag
|
Chris@16
|
108 , typename Expr::proto_domain
|
Chris@16
|
109 >
|
Chris@16
|
110 fusion_tag;
|
Chris@16
|
111 typedef
|
Chris@16
|
112 typename fusion::result_of::as_list<
|
Chris@16
|
113 typename fusion::result_of::transform<
|
Chris@16
|
114 Expr
|
Chris@16
|
115 , as_element<typename Expr::proto_tag>
|
Chris@16
|
116 >::type
|
Chris@16
|
117 >::type
|
Chris@16
|
118 segments_type;
|
Chris@16
|
119
|
Chris@16
|
120 explicit flat_view(Expr &e)
|
Chris@16
|
121 : segs_(fusion::as_list(fusion::transform(e, as_element<typename Expr::proto_tag>())))
|
Chris@16
|
122 {}
|
Chris@16
|
123
|
Chris@16
|
124 segments_type segs_;
|
Chris@16
|
125 };
|
Chris@16
|
126 }
|
Chris@16
|
127
|
Chris@16
|
128 namespace result_of
|
Chris@16
|
129 {
|
Chris@16
|
130 template<typename Expr>
|
Chris@16
|
131 struct flatten
|
Chris@16
|
132 : flatten<Expr const &>
|
Chris@16
|
133 {};
|
Chris@16
|
134
|
Chris@16
|
135 template<typename Expr>
|
Chris@16
|
136 struct flatten<Expr &>
|
Chris@16
|
137 {
|
Chris@16
|
138 typedef detail::flat_view<Expr> type;
|
Chris@16
|
139 };
|
Chris@16
|
140 }
|
Chris@16
|
141
|
Chris@16
|
142 namespace functional
|
Chris@16
|
143 {
|
Chris@16
|
144 /// \brief A PolymorphicFunctionObject type that returns a "flattened"
|
Chris@16
|
145 /// view of a Proto expression tree.
|
Chris@16
|
146 ///
|
Chris@16
|
147 /// A PolymorphicFunctionObject type that returns a "flattened"
|
Chris@16
|
148 /// view of a Proto expression tree. For a tree with a top-most node
|
Chris@16
|
149 /// tag of type \c T, the elements of the flattened sequence are
|
Chris@16
|
150 /// determined by recursing into each child node with the same
|
Chris@16
|
151 /// tag type and returning those nodes of different type. So for
|
Chris@16
|
152 /// instance, the Proto expression tree corresponding to the
|
Chris@16
|
153 /// expression <tt>a | b | c</tt> has a flattened view with elements
|
Chris@16
|
154 /// [a, b, c], even though the tree is grouped as
|
Chris@16
|
155 /// <tt>((a | b) | c)</tt>.
|
Chris@16
|
156 struct flatten
|
Chris@16
|
157 {
|
Chris@16
|
158 BOOST_PROTO_CALLABLE()
|
Chris@16
|
159
|
Chris@16
|
160 template<typename Sig>
|
Chris@16
|
161 struct result;
|
Chris@16
|
162
|
Chris@16
|
163 template<typename This, typename Expr>
|
Chris@16
|
164 struct result<This(Expr)>
|
Chris@16
|
165 : result<This(Expr const &)>
|
Chris@16
|
166 {};
|
Chris@16
|
167
|
Chris@16
|
168 template<typename This, typename Expr>
|
Chris@16
|
169 struct result<This(Expr &)>
|
Chris@16
|
170 {
|
Chris@16
|
171 typedef proto::detail::flat_view<Expr> type;
|
Chris@16
|
172 };
|
Chris@16
|
173
|
Chris@16
|
174 template<typename Expr>
|
Chris@16
|
175 proto::detail::flat_view<Expr> const
|
Chris@16
|
176 operator ()(Expr &e) const
|
Chris@16
|
177 {
|
Chris@16
|
178 return proto::detail::flat_view<Expr>(e);
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 template<typename Expr>
|
Chris@16
|
182 proto::detail::flat_view<Expr const> const
|
Chris@16
|
183 operator ()(Expr const &e) const
|
Chris@16
|
184 {
|
Chris@16
|
185 return proto::detail::flat_view<Expr const>(e);
|
Chris@16
|
186 }
|
Chris@16
|
187 };
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 /// \brief A function that returns a "flattened"
|
Chris@16
|
191 /// view of a Proto expression tree.
|
Chris@16
|
192 ///
|
Chris@16
|
193 /// For a tree with a top-most node
|
Chris@16
|
194 /// tag of type \c T, the elements of the flattened sequence are
|
Chris@16
|
195 /// determined by recursing into each child node with the same
|
Chris@16
|
196 /// tag type and returning those nodes of different type. So for
|
Chris@16
|
197 /// instance, the Proto expression tree corresponding to the
|
Chris@16
|
198 /// expression <tt>a | b | c</tt> has a flattened view with elements
|
Chris@16
|
199 /// [a, b, c], even though the tree is grouped as
|
Chris@16
|
200 /// <tt>((a | b) | c)</tt>.
|
Chris@16
|
201 template<typename Expr>
|
Chris@16
|
202 proto::detail::flat_view<Expr> const
|
Chris@16
|
203 flatten(Expr &e)
|
Chris@16
|
204 {
|
Chris@16
|
205 return proto::detail::flat_view<Expr>(e);
|
Chris@16
|
206 }
|
Chris@16
|
207
|
Chris@16
|
208 /// \overload
|
Chris@16
|
209 ///
|
Chris@16
|
210 template<typename Expr>
|
Chris@16
|
211 proto::detail::flat_view<Expr const> const
|
Chris@16
|
212 flatten(Expr const &e)
|
Chris@16
|
213 {
|
Chris@16
|
214 return proto::detail::flat_view<Expr const>(e);
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 /// INTERNAL ONLY
|
Chris@16
|
218 ///
|
Chris@16
|
219 template<typename Context>
|
Chris@16
|
220 struct eval_fun
|
Chris@16
|
221 : proto::callable
|
Chris@16
|
222 {
|
Chris@16
|
223 explicit eval_fun(Context &ctx)
|
Chris@16
|
224 : ctx_(ctx)
|
Chris@16
|
225 {}
|
Chris@16
|
226
|
Chris@16
|
227 template<typename Sig>
|
Chris@16
|
228 struct result;
|
Chris@16
|
229
|
Chris@16
|
230 template<typename This, typename Expr>
|
Chris@16
|
231 struct result<This(Expr)>
|
Chris@16
|
232 : result<This(Expr const &)>
|
Chris@16
|
233 {};
|
Chris@16
|
234
|
Chris@16
|
235 template<typename This, typename Expr>
|
Chris@16
|
236 struct result<This(Expr &)>
|
Chris@16
|
237 : proto::result_of::eval<Expr, Context>
|
Chris@16
|
238 {};
|
Chris@16
|
239
|
Chris@16
|
240 template<typename Expr>
|
Chris@16
|
241 typename proto::result_of::eval<Expr, Context>::type
|
Chris@16
|
242 operator ()(Expr &e) const
|
Chris@16
|
243 {
|
Chris@16
|
244 return proto::eval(e, this->ctx_);
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247 template<typename Expr>
|
Chris@16
|
248 typename proto::result_of::eval<Expr const, Context>::type
|
Chris@16
|
249 operator ()(Expr const &e) const
|
Chris@16
|
250 {
|
Chris@16
|
251 return proto::eval(e, this->ctx_);
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 private:
|
Chris@16
|
255 Context &ctx_;
|
Chris@16
|
256 };
|
Chris@16
|
257
|
Chris@16
|
258 /// INTERNAL ONLY
|
Chris@16
|
259 ///
|
Chris@16
|
260 template<typename Context>
|
Chris@16
|
261 struct is_callable<eval_fun<Context> >
|
Chris@16
|
262 : mpl::true_
|
Chris@16
|
263 {};
|
Chris@16
|
264 }}
|
Chris@16
|
265
|
Chris@16
|
266 namespace boost { namespace fusion
|
Chris@16
|
267 {
|
Chris@16
|
268 namespace extension
|
Chris@16
|
269 {
|
Chris@16
|
270 template<typename Tag>
|
Chris@16
|
271 struct is_sequence_impl;
|
Chris@16
|
272
|
Chris@16
|
273 template<typename Tag, typename Domain>
|
Chris@16
|
274 struct is_sequence_impl<proto::tag::proto_flat_view<Tag, Domain> >
|
Chris@16
|
275 {
|
Chris@16
|
276 template<typename Sequence>
|
Chris@16
|
277 struct apply
|
Chris@16
|
278 : mpl::true_
|
Chris@16
|
279 {};
|
Chris@16
|
280 };
|
Chris@16
|
281
|
Chris@16
|
282 template<typename Tag, typename Domain>
|
Chris@16
|
283 struct is_sequence_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
284 {
|
Chris@16
|
285 template<typename Sequence>
|
Chris@16
|
286 struct apply
|
Chris@16
|
287 : mpl::true_
|
Chris@16
|
288 {};
|
Chris@16
|
289 };
|
Chris@16
|
290
|
Chris@16
|
291 template<typename Tag>
|
Chris@16
|
292 struct is_view_impl;
|
Chris@16
|
293
|
Chris@16
|
294 template<typename Tag, typename Domain>
|
Chris@16
|
295 struct is_view_impl<proto::tag::proto_flat_view<Tag, Domain> >
|
Chris@16
|
296 {
|
Chris@16
|
297 template<typename Sequence>
|
Chris@16
|
298 struct apply
|
Chris@16
|
299 : mpl::true_
|
Chris@16
|
300 {};
|
Chris@16
|
301 };
|
Chris@16
|
302
|
Chris@16
|
303 template<typename Tag, typename Domain>
|
Chris@16
|
304 struct is_view_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
305 {
|
Chris@16
|
306 template<typename Sequence>
|
Chris@16
|
307 struct apply
|
Chris@16
|
308 : mpl::false_
|
Chris@16
|
309 {};
|
Chris@16
|
310 };
|
Chris@16
|
311
|
Chris@16
|
312 template<typename Tag>
|
Chris@16
|
313 struct value_of_impl;
|
Chris@16
|
314
|
Chris@16
|
315 template<typename Tag, typename Domain>
|
Chris@16
|
316 struct value_of_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
|
Chris@16
|
317 {
|
Chris@16
|
318 template<
|
Chris@16
|
319 typename Iterator
|
Chris@16
|
320 , long Arity = proto::arity_of<typename Iterator::expr_type>::value
|
Chris@16
|
321 >
|
Chris@16
|
322 struct apply
|
Chris@16
|
323 {
|
Chris@16
|
324 typedef
|
Chris@16
|
325 typename proto::result_of::child_c<
|
Chris@16
|
326 typename Iterator::expr_type
|
Chris@16
|
327 , Iterator::index
|
Chris@16
|
328 >::value_type
|
Chris@16
|
329 type;
|
Chris@16
|
330 };
|
Chris@16
|
331
|
Chris@16
|
332 template<typename Iterator>
|
Chris@16
|
333 struct apply<Iterator, 0>
|
Chris@16
|
334 {
|
Chris@16
|
335 typedef
|
Chris@16
|
336 typename proto::result_of::value<
|
Chris@16
|
337 typename Iterator::expr_type
|
Chris@16
|
338 >::value_type
|
Chris@16
|
339 type;
|
Chris@16
|
340 };
|
Chris@16
|
341 };
|
Chris@16
|
342
|
Chris@16
|
343 template<typename Tag>
|
Chris@16
|
344 struct deref_impl;
|
Chris@16
|
345
|
Chris@16
|
346 template<typename Tag, typename Domain>
|
Chris@16
|
347 struct deref_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
|
Chris@16
|
348 {
|
Chris@16
|
349 template<
|
Chris@16
|
350 typename Iterator
|
Chris@16
|
351 , long Arity = proto::arity_of<typename Iterator::expr_type>::value
|
Chris@16
|
352 >
|
Chris@16
|
353 struct apply
|
Chris@16
|
354 {
|
Chris@16
|
355 typedef
|
Chris@16
|
356 typename proto::result_of::child_c<
|
Chris@16
|
357 typename Iterator::expr_type &
|
Chris@16
|
358 , Iterator::index
|
Chris@16
|
359 >::type
|
Chris@16
|
360 type;
|
Chris@16
|
361
|
Chris@16
|
362 static type call(Iterator const &iter)
|
Chris@16
|
363 {
|
Chris@16
|
364 return proto::child_c<Iterator::index>(iter.expr);
|
Chris@16
|
365 }
|
Chris@16
|
366 };
|
Chris@16
|
367
|
Chris@16
|
368 template<typename Iterator>
|
Chris@16
|
369 struct apply<Iterator, 0>
|
Chris@16
|
370 {
|
Chris@16
|
371 typedef
|
Chris@16
|
372 typename proto::result_of::value<
|
Chris@16
|
373 typename Iterator::expr_type &
|
Chris@16
|
374 >::type
|
Chris@16
|
375 type;
|
Chris@16
|
376
|
Chris@16
|
377 static type call(Iterator const &iter)
|
Chris@16
|
378 {
|
Chris@16
|
379 return proto::value(iter.expr);
|
Chris@16
|
380 }
|
Chris@16
|
381 };
|
Chris@16
|
382 };
|
Chris@16
|
383
|
Chris@16
|
384 template<typename Tag>
|
Chris@16
|
385 struct advance_impl;
|
Chris@16
|
386
|
Chris@16
|
387 template<typename Tag, typename Domain>
|
Chris@16
|
388 struct advance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
|
Chris@16
|
389 {
|
Chris@16
|
390 template<typename Iterator, typename N>
|
Chris@16
|
391 struct apply
|
Chris@16
|
392 {
|
Chris@16
|
393 typedef
|
Chris@16
|
394 proto::detail::expr_iterator<
|
Chris@16
|
395 typename Iterator::expr_type
|
Chris@16
|
396 , Iterator::index + N::value
|
Chris@16
|
397 >
|
Chris@16
|
398 type;
|
Chris@16
|
399
|
Chris@16
|
400 static type call(Iterator const &iter)
|
Chris@16
|
401 {
|
Chris@16
|
402 return type(iter.expr);
|
Chris@16
|
403 }
|
Chris@16
|
404 };
|
Chris@16
|
405 };
|
Chris@16
|
406
|
Chris@16
|
407 template<typename Tag>
|
Chris@16
|
408 struct distance_impl;
|
Chris@16
|
409
|
Chris@16
|
410 template<typename Tag, typename Domain>
|
Chris@16
|
411 struct distance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
|
Chris@16
|
412 {
|
Chris@16
|
413 template<typename IteratorFrom, typename IteratorTo>
|
Chris@16
|
414 struct apply
|
Chris@16
|
415 : mpl::long_<IteratorTo::index - IteratorFrom::index>
|
Chris@16
|
416 {};
|
Chris@16
|
417 };
|
Chris@16
|
418
|
Chris@16
|
419 template<typename Tag>
|
Chris@16
|
420 struct next_impl;
|
Chris@16
|
421
|
Chris@16
|
422 template<typename Tag, typename Domain>
|
Chris@16
|
423 struct next_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
|
Chris@16
|
424 {
|
Chris@16
|
425 template<typename Iterator>
|
Chris@16
|
426 struct apply
|
Chris@16
|
427 : advance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >::template apply<Iterator, mpl::long_<1> >
|
Chris@16
|
428 {};
|
Chris@16
|
429 };
|
Chris@16
|
430
|
Chris@16
|
431 template<typename Tag>
|
Chris@16
|
432 struct prior_impl;
|
Chris@16
|
433
|
Chris@16
|
434 template<typename Tag, typename Domain>
|
Chris@16
|
435 struct prior_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
|
Chris@16
|
436 {
|
Chris@16
|
437 template<typename Iterator>
|
Chris@16
|
438 struct apply
|
Chris@16
|
439 : advance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >::template apply<Iterator, mpl::long_<-1> >
|
Chris@16
|
440 {};
|
Chris@16
|
441 };
|
Chris@16
|
442
|
Chris@16
|
443 template<typename Tag>
|
Chris@16
|
444 struct category_of_impl;
|
Chris@16
|
445
|
Chris@16
|
446 template<typename Tag, typename Domain>
|
Chris@16
|
447 struct category_of_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
448 {
|
Chris@16
|
449 template<typename Sequence>
|
Chris@16
|
450 struct apply
|
Chris@16
|
451 {
|
Chris@16
|
452 typedef random_access_traversal_tag type;
|
Chris@16
|
453 };
|
Chris@16
|
454 };
|
Chris@16
|
455
|
Chris@16
|
456 template<typename Tag>
|
Chris@16
|
457 struct size_impl;
|
Chris@16
|
458
|
Chris@16
|
459 template<typename Tag, typename Domain>
|
Chris@16
|
460 struct size_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
461 {
|
Chris@16
|
462 template<typename Sequence>
|
Chris@16
|
463 struct apply
|
Chris@16
|
464 : mpl::long_<0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c>
|
Chris@16
|
465 {};
|
Chris@16
|
466 };
|
Chris@16
|
467
|
Chris@16
|
468 template<typename Tag>
|
Chris@16
|
469 struct begin_impl;
|
Chris@16
|
470
|
Chris@16
|
471 template<typename Tag, typename Domain>
|
Chris@16
|
472 struct begin_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
473 {
|
Chris@16
|
474 template<typename Sequence>
|
Chris@16
|
475 struct apply
|
Chris@16
|
476 {
|
Chris@16
|
477 typedef proto::detail::expr_iterator<Sequence, 0> type;
|
Chris@16
|
478
|
Chris@16
|
479 static type call(Sequence &seq)
|
Chris@16
|
480 {
|
Chris@16
|
481 return type(seq);
|
Chris@16
|
482 }
|
Chris@16
|
483 };
|
Chris@16
|
484 };
|
Chris@16
|
485
|
Chris@16
|
486 template<typename Tag>
|
Chris@16
|
487 struct end_impl;
|
Chris@16
|
488
|
Chris@16
|
489 template<typename Tag, typename Domain>
|
Chris@16
|
490 struct end_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
491 {
|
Chris@16
|
492 template<typename Sequence>
|
Chris@16
|
493 struct apply
|
Chris@16
|
494 {
|
Chris@16
|
495 typedef
|
Chris@16
|
496 proto::detail::expr_iterator<
|
Chris@16
|
497 Sequence
|
Chris@16
|
498 , 0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c
|
Chris@16
|
499 >
|
Chris@16
|
500 type;
|
Chris@16
|
501
|
Chris@16
|
502 static type call(Sequence &seq)
|
Chris@16
|
503 {
|
Chris@16
|
504 return type(seq);
|
Chris@16
|
505 }
|
Chris@16
|
506 };
|
Chris@16
|
507 };
|
Chris@16
|
508
|
Chris@16
|
509 template<typename Tag>
|
Chris@16
|
510 struct value_at_impl;
|
Chris@16
|
511
|
Chris@16
|
512 template<typename Tag, typename Domain>
|
Chris@16
|
513 struct value_at_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
514 {
|
Chris@16
|
515 template<
|
Chris@16
|
516 typename Sequence
|
Chris@16
|
517 , typename Index
|
Chris@16
|
518 , long Arity = proto::arity_of<Sequence>::value
|
Chris@16
|
519 >
|
Chris@16
|
520 struct apply
|
Chris@16
|
521 {
|
Chris@16
|
522 typedef
|
Chris@16
|
523 typename proto::result_of::child_c<
|
Chris@16
|
524 Sequence
|
Chris@16
|
525 , Index::value
|
Chris@16
|
526 >::value_type
|
Chris@16
|
527 type;
|
Chris@16
|
528 };
|
Chris@16
|
529
|
Chris@16
|
530 template<typename Sequence, typename Index>
|
Chris@16
|
531 struct apply<Sequence, Index, 0>
|
Chris@16
|
532 {
|
Chris@16
|
533 typedef
|
Chris@16
|
534 typename proto::result_of::value<
|
Chris@16
|
535 Sequence
|
Chris@16
|
536 >::value_type
|
Chris@16
|
537 type;
|
Chris@16
|
538 };
|
Chris@16
|
539 };
|
Chris@16
|
540
|
Chris@16
|
541 template<typename Tag>
|
Chris@16
|
542 struct at_impl;
|
Chris@16
|
543
|
Chris@16
|
544 template<typename Tag, typename Domain>
|
Chris@16
|
545 struct at_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
546 {
|
Chris@16
|
547 template<
|
Chris@16
|
548 typename Sequence
|
Chris@16
|
549 , typename Index
|
Chris@16
|
550 , long Arity = proto::arity_of<Sequence>::value
|
Chris@16
|
551 >
|
Chris@16
|
552 struct apply
|
Chris@16
|
553 {
|
Chris@16
|
554 typedef
|
Chris@16
|
555 typename proto::result_of::child_c<
|
Chris@16
|
556 Sequence &
|
Chris@16
|
557 , Index::value
|
Chris@16
|
558 >::type
|
Chris@16
|
559 type;
|
Chris@16
|
560
|
Chris@16
|
561 static type call(Sequence &seq)
|
Chris@16
|
562 {
|
Chris@16
|
563 return proto::child_c<Index::value>(seq);
|
Chris@16
|
564 }
|
Chris@16
|
565 };
|
Chris@16
|
566
|
Chris@16
|
567 template<typename Sequence, typename Index>
|
Chris@16
|
568 struct apply<Sequence, Index, 0>
|
Chris@16
|
569 {
|
Chris@16
|
570 typedef
|
Chris@16
|
571 typename proto::result_of::value<
|
Chris@16
|
572 Sequence &
|
Chris@16
|
573 >::type
|
Chris@16
|
574 type;
|
Chris@16
|
575
|
Chris@16
|
576 static type call(Sequence &seq)
|
Chris@16
|
577 {
|
Chris@16
|
578 return proto::value(seq);
|
Chris@16
|
579 }
|
Chris@16
|
580 };
|
Chris@16
|
581 };
|
Chris@16
|
582
|
Chris@16
|
583 template<typename Tag>
|
Chris@16
|
584 struct convert_impl;
|
Chris@16
|
585
|
Chris@16
|
586 template<typename Tag, typename Domain>
|
Chris@16
|
587 struct convert_impl<proto::tag::proto_expr<Tag, Domain> >
|
Chris@16
|
588 {
|
Chris@16
|
589 template<typename Sequence>
|
Chris@16
|
590 struct apply
|
Chris@16
|
591 {
|
Chris@16
|
592 typedef
|
Chris@16
|
593 typename proto::result_of::unpack_expr<
|
Chris@16
|
594 Tag
|
Chris@16
|
595 , Domain
|
Chris@16
|
596 , Sequence
|
Chris@16
|
597 >::type
|
Chris@16
|
598 type;
|
Chris@16
|
599
|
Chris@16
|
600 static type call(Sequence& seq)
|
Chris@16
|
601 {
|
Chris@16
|
602 return proto::unpack_expr<Tag, Domain>(seq);
|
Chris@16
|
603 }
|
Chris@16
|
604 };
|
Chris@16
|
605 };
|
Chris@16
|
606
|
Chris@16
|
607 template<typename Tag, typename Domain>
|
Chris@16
|
608 struct convert_impl<proto::tag::proto_flat_view<Tag, Domain> >
|
Chris@16
|
609 {
|
Chris@16
|
610 template<typename Sequence>
|
Chris@16
|
611 struct apply
|
Chris@16
|
612 {
|
Chris@16
|
613 typedef
|
Chris@16
|
614 typename proto::result_of::unpack_expr<
|
Chris@16
|
615 Tag
|
Chris@16
|
616 , Domain
|
Chris@16
|
617 , Sequence
|
Chris@16
|
618 >::type
|
Chris@16
|
619 type;
|
Chris@16
|
620
|
Chris@16
|
621 static type call(Sequence& seq)
|
Chris@16
|
622 {
|
Chris@16
|
623 return proto::unpack_expr<Tag, Domain>(seq);
|
Chris@16
|
624 }
|
Chris@16
|
625 };
|
Chris@16
|
626 };
|
Chris@16
|
627
|
Chris@16
|
628 template<typename Tag>
|
Chris@16
|
629 struct is_segmented_impl;
|
Chris@16
|
630
|
Chris@16
|
631 template<typename Tag, typename Domain>
|
Chris@16
|
632 struct is_segmented_impl<proto::tag::proto_flat_view<Tag, Domain> >
|
Chris@16
|
633 {
|
Chris@16
|
634 template<typename Iterator>
|
Chris@16
|
635 struct apply
|
Chris@16
|
636 : mpl::true_
|
Chris@16
|
637 {};
|
Chris@16
|
638 };
|
Chris@16
|
639
|
Chris@16
|
640 template<typename Tag>
|
Chris@16
|
641 struct segments_impl;
|
Chris@16
|
642
|
Chris@16
|
643 template<typename Tag, typename Domain>
|
Chris@16
|
644 struct segments_impl<proto::tag::proto_flat_view<Tag, Domain> >
|
Chris@16
|
645 {
|
Chris@16
|
646 template<typename Sequence>
|
Chris@16
|
647 struct apply
|
Chris@16
|
648 {
|
Chris@16
|
649 typedef typename Sequence::segments_type const &type;
|
Chris@16
|
650
|
Chris@16
|
651 static type call(Sequence &sequence)
|
Chris@16
|
652 {
|
Chris@16
|
653 return sequence.segs_;
|
Chris@16
|
654 }
|
Chris@16
|
655 };
|
Chris@16
|
656 };
|
Chris@16
|
657
|
Chris@16
|
658 template<typename Tag, typename Domain>
|
Chris@16
|
659 struct category_of_impl<proto::tag::proto_flat_view<Tag, Domain> >
|
Chris@16
|
660 {
|
Chris@16
|
661 template<typename Sequence>
|
Chris@16
|
662 struct apply
|
Chris@16
|
663 {
|
Chris@16
|
664 typedef forward_traversal_tag type;
|
Chris@16
|
665 };
|
Chris@16
|
666 };
|
Chris@16
|
667 }
|
Chris@16
|
668
|
Chris@16
|
669 namespace traits
|
Chris@16
|
670 {
|
Chris@16
|
671 template<typename Seq1, typename Seq2>
|
Chris@16
|
672 struct enable_equality<
|
Chris@16
|
673 Seq1
|
Chris@16
|
674 , Seq2
|
Chris@16
|
675 , typename enable_if_c<
|
Chris@16
|
676 mpl::or_<
|
Chris@16
|
677 proto::is_expr<Seq1>
|
Chris@16
|
678 , proto::is_expr<Seq2>
|
Chris@16
|
679 >::value
|
Chris@16
|
680 >::type
|
Chris@16
|
681 >
|
Chris@16
|
682 : mpl::false_
|
Chris@16
|
683 {};
|
Chris@16
|
684
|
Chris@16
|
685 template<typename Seq1, typename Seq2>
|
Chris@16
|
686 struct enable_comparison<
|
Chris@16
|
687 Seq1
|
Chris@16
|
688 , Seq2
|
Chris@16
|
689 , typename enable_if_c<
|
Chris@16
|
690 mpl::or_<
|
Chris@16
|
691 proto::is_expr<Seq1>
|
Chris@16
|
692 , proto::is_expr<Seq2>
|
Chris@16
|
693 >::value
|
Chris@16
|
694 >::type
|
Chris@16
|
695 >
|
Chris@16
|
696 : mpl::false_
|
Chris@16
|
697 {};
|
Chris@16
|
698 }
|
Chris@16
|
699 }}
|
Chris@16
|
700
|
Chris@16
|
701 namespace boost { namespace mpl
|
Chris@16
|
702 {
|
Chris@16
|
703 template<typename Tag, typename Args, long Arity>
|
Chris@16
|
704 struct sequence_tag< proto::expr<Tag, Args, Arity> >
|
Chris@16
|
705 {
|
Chris@16
|
706 typedef fusion::fusion_sequence_tag type;
|
Chris@16
|
707 };
|
Chris@16
|
708
|
Chris@16
|
709 template<typename Tag, typename Args, long Arity>
|
Chris@16
|
710 struct sequence_tag< proto::basic_expr<Tag, Args, Arity> >
|
Chris@16
|
711 {
|
Chris@16
|
712 typedef fusion::fusion_sequence_tag type;
|
Chris@16
|
713 };
|
Chris@16
|
714 }}
|
Chris@16
|
715
|
Chris@16
|
716 #ifdef BOOST_MSVC
|
Chris@16
|
717 #pragma warning(pop)
|
Chris@16
|
718 #endif
|
Chris@16
|
719
|
Chris@16
|
720 #endif
|