]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/proto/include/boost/proto/fusion.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / proto / include / boost / proto / fusion.hpp
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