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