File indexing completed on 2025-01-18 09:50:33
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
0010 #define BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
0011
0012 #include <boost/config.hpp>
0013 #include <boost/mpl/if.hpp>
0014 #include <boost/mpl/bool.hpp>
0015 #include <boost/mpl/long.hpp>
0016 #include <boost/mpl/sequence_tag_fwd.hpp>
0017 #include <boost/utility/enable_if.hpp>
0018 #include <boost/fusion/include/is_view.hpp>
0019 #include <boost/fusion/include/tag_of_fwd.hpp>
0020 #include <boost/fusion/include/category_of.hpp>
0021 #include <boost/fusion/include/iterator_base.hpp>
0022 #include <boost/fusion/include/intrinsic.hpp>
0023 #include <boost/fusion/include/single_view.hpp>
0024 #include <boost/fusion/include/transform.hpp>
0025 #include <boost/fusion/include/as_list.hpp>
0026 #include <boost/fusion/include/is_segmented.hpp>
0027 #include <boost/fusion/sequence/comparison/enable_comparison.hpp>
0028 #include <boost/proto/proto_fwd.hpp>
0029 #include <boost/proto/traits.hpp>
0030 #include <boost/proto/eval.hpp>
0031 #include <boost/proto/make_expr.hpp>
0032
0033 #ifdef BOOST_MSVC
0034 #pragma warning(push)
0035 #pragma warning(disable : 4510)
0036 #pragma warning(disable : 4512)
0037 #pragma warning(disable : 4610)
0038 #endif
0039
0040 namespace boost { namespace proto
0041 {
0042 namespace detail
0043 {
0044 template<typename Expr, long Pos>
0045 struct expr_iterator
0046 : fusion::iterator_base<expr_iterator<Expr, Pos> >
0047 {
0048 typedef Expr expr_type;
0049 static const long index = Pos;
0050 typedef fusion::random_access_traversal_tag category;
0051 typedef
0052 tag::proto_expr_iterator<
0053 typename Expr::proto_tag
0054 , typename Expr::proto_domain
0055 >
0056 fusion_tag;
0057
0058 explicit expr_iterator(Expr &e)
0059 : expr(e)
0060 {}
0061
0062 Expr &expr;
0063 };
0064
0065 template<typename Tag>
0066 struct as_element
0067 {
0068 template<typename Sig>
0069 struct result;
0070
0071 template<typename This, typename Expr>
0072 struct result<This(Expr)>
0073 : result<This(Expr const &)>
0074 {};
0075
0076 template<typename This, typename Expr>
0077 struct result<This(Expr &)>
0078 : mpl::if_c<
0079 is_same<Tag, typename Expr::proto_tag>::value
0080 , flat_view<Expr>
0081 , fusion::single_view<Expr &>
0082 >
0083 {};
0084
0085 template<typename Expr>
0086 typename result<as_element(Expr &)>::type const
0087 operator ()(Expr &e) const
0088 {
0089 return typename result<as_element(Expr &)>::type(e);
0090 }
0091
0092 template<typename Expr>
0093 typename result<as_element(Expr const &)>::type const
0094 operator ()(Expr const &e) const
0095 {
0096 return typename result<as_element(Expr const &)>::type(e);
0097 }
0098 };
0099
0100 template<typename Expr>
0101 struct flat_view
0102 : fusion::sequence_base<flat_view<Expr> >
0103 {
0104 typedef fusion::forward_traversal_tag category;
0105 typedef
0106 tag::proto_flat_view<
0107 typename Expr::proto_tag
0108 , typename Expr::proto_domain
0109 >
0110 fusion_tag;
0111 typedef
0112 typename fusion::result_of::as_list<
0113 typename fusion::result_of::transform<
0114 Expr
0115 , as_element<typename Expr::proto_tag>
0116 >::type
0117 >::type
0118 segments_type;
0119
0120 explicit flat_view(Expr &e)
0121 : segs_(fusion::as_list(fusion::transform(e, as_element<typename Expr::proto_tag>())))
0122 {}
0123
0124 segments_type segs_;
0125 };
0126 }
0127
0128 namespace result_of
0129 {
0130 template<typename Expr>
0131 struct flatten
0132 : flatten<Expr const &>
0133 {};
0134
0135 template<typename Expr>
0136 struct flatten<Expr &>
0137 {
0138 typedef detail::flat_view<Expr> type;
0139 };
0140 }
0141
0142 namespace functional
0143 {
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 struct flatten
0157 {
0158 BOOST_PROTO_CALLABLE()
0159
0160 template<typename Sig>
0161 struct result;
0162
0163 template<typename This, typename Expr>
0164 struct result<This(Expr)>
0165 : result<This(Expr const &)>
0166 {};
0167
0168 template<typename This, typename Expr>
0169 struct result<This(Expr &)>
0170 {
0171 typedef proto::detail::flat_view<Expr> type;
0172 };
0173
0174 template<typename Expr>
0175 proto::detail::flat_view<Expr> const
0176 operator ()(Expr &e) const
0177 {
0178 return proto::detail::flat_view<Expr>(e);
0179 }
0180
0181 template<typename Expr>
0182 proto::detail::flat_view<Expr const> const
0183 operator ()(Expr const &e) const
0184 {
0185 return proto::detail::flat_view<Expr const>(e);
0186 }
0187 };
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 template<typename Expr>
0202 proto::detail::flat_view<Expr> const
0203 flatten(Expr &e)
0204 {
0205 return proto::detail::flat_view<Expr>(e);
0206 }
0207
0208
0209
0210 template<typename Expr>
0211 proto::detail::flat_view<Expr const> const
0212 flatten(Expr const &e)
0213 {
0214 return proto::detail::flat_view<Expr const>(e);
0215 }
0216
0217
0218
0219 template<typename Context>
0220 struct eval_fun
0221 : proto::callable
0222 {
0223 explicit eval_fun(Context &ctx)
0224 : ctx_(ctx)
0225 {}
0226
0227 template<typename Sig>
0228 struct result;
0229
0230 template<typename This, typename Expr>
0231 struct result<This(Expr)>
0232 : result<This(Expr const &)>
0233 {};
0234
0235 template<typename This, typename Expr>
0236 struct result<This(Expr &)>
0237 : proto::result_of::eval<Expr, Context>
0238 {};
0239
0240 template<typename Expr>
0241 typename proto::result_of::eval<Expr, Context>::type
0242 operator ()(Expr &e) const
0243 {
0244 return proto::eval(e, this->ctx_);
0245 }
0246
0247 template<typename Expr>
0248 typename proto::result_of::eval<Expr const, Context>::type
0249 operator ()(Expr const &e) const
0250 {
0251 return proto::eval(e, this->ctx_);
0252 }
0253
0254 private:
0255 Context &ctx_;
0256 };
0257
0258
0259
0260 template<typename Context>
0261 struct is_callable<eval_fun<Context> >
0262 : mpl::true_
0263 {};
0264 }}
0265
0266 namespace boost { namespace fusion
0267 {
0268 namespace extension
0269 {
0270 template<typename Tag>
0271 struct is_sequence_impl;
0272
0273 template<typename Tag, typename Domain>
0274 struct is_sequence_impl<proto::tag::proto_flat_view<Tag, Domain> >
0275 {
0276 template<typename Sequence>
0277 struct apply
0278 : mpl::true_
0279 {};
0280 };
0281
0282 template<typename Tag, typename Domain>
0283 struct is_sequence_impl<proto::tag::proto_expr<Tag, Domain> >
0284 {
0285 template<typename Sequence>
0286 struct apply
0287 : mpl::true_
0288 {};
0289 };
0290
0291 template<typename Tag>
0292 struct is_view_impl;
0293
0294 template<typename Tag, typename Domain>
0295 struct is_view_impl<proto::tag::proto_flat_view<Tag, Domain> >
0296 {
0297 template<typename Sequence>
0298 struct apply
0299 : mpl::true_
0300 {};
0301 };
0302
0303 template<typename Tag, typename Domain>
0304 struct is_view_impl<proto::tag::proto_expr<Tag, Domain> >
0305 {
0306 template<typename Sequence>
0307 struct apply
0308 : mpl::false_
0309 {};
0310 };
0311
0312 template<typename Tag>
0313 struct value_of_impl;
0314
0315 template<typename Tag, typename Domain>
0316 struct value_of_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
0317 {
0318 template<
0319 typename Iterator
0320 , long Arity = proto::arity_of<typename Iterator::expr_type>::value
0321 >
0322 struct apply
0323 {
0324 typedef
0325 typename proto::result_of::child_c<
0326 typename Iterator::expr_type
0327 , Iterator::index
0328 >::value_type
0329 type;
0330 };
0331
0332 template<typename Iterator>
0333 struct apply<Iterator, 0>
0334 {
0335 typedef
0336 typename proto::result_of::value<
0337 typename Iterator::expr_type
0338 >::value_type
0339 type;
0340 };
0341 };
0342
0343 template<typename Tag>
0344 struct deref_impl;
0345
0346 template<typename Tag, typename Domain>
0347 struct deref_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
0348 {
0349 template<
0350 typename Iterator
0351 , long Arity = proto::arity_of<typename Iterator::expr_type>::value
0352 >
0353 struct apply
0354 {
0355 typedef
0356 typename proto::result_of::child_c<
0357 typename Iterator::expr_type &
0358 , Iterator::index
0359 >::type
0360 type;
0361
0362 static type call(Iterator const &iter)
0363 {
0364 return proto::child_c<Iterator::index>(iter.expr);
0365 }
0366 };
0367
0368 template<typename Iterator>
0369 struct apply<Iterator, 0>
0370 {
0371 typedef
0372 typename proto::result_of::value<
0373 typename Iterator::expr_type &
0374 >::type
0375 type;
0376
0377 static type call(Iterator const &iter)
0378 {
0379 return proto::value(iter.expr);
0380 }
0381 };
0382 };
0383
0384 template<typename Tag>
0385 struct advance_impl;
0386
0387 template<typename Tag, typename Domain>
0388 struct advance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
0389 {
0390 template<typename Iterator, typename N>
0391 struct apply
0392 {
0393 typedef
0394 proto::detail::expr_iterator<
0395 typename Iterator::expr_type
0396 , Iterator::index + N::value
0397 >
0398 type;
0399
0400 static type call(Iterator const &iter)
0401 {
0402 return type(iter.expr);
0403 }
0404 };
0405 };
0406
0407 template<typename Tag>
0408 struct distance_impl;
0409
0410 template<typename Tag, typename Domain>
0411 struct distance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
0412 {
0413 template<typename IteratorFrom, typename IteratorTo>
0414 struct apply
0415 : mpl::long_<IteratorTo::index - IteratorFrom::index>
0416 {};
0417 };
0418
0419 template<typename Tag>
0420 struct next_impl;
0421
0422 template<typename Tag, typename Domain>
0423 struct next_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
0424 {
0425 template<typename Iterator>
0426 struct apply
0427 : advance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >::template apply<Iterator, mpl::long_<1> >
0428 {};
0429 };
0430
0431 template<typename Tag>
0432 struct prior_impl;
0433
0434 template<typename Tag, typename Domain>
0435 struct prior_impl<proto::tag::proto_expr_iterator<Tag, Domain> >
0436 {
0437 template<typename Iterator>
0438 struct apply
0439 : advance_impl<proto::tag::proto_expr_iterator<Tag, Domain> >::template apply<Iterator, mpl::long_<-1> >
0440 {};
0441 };
0442
0443 template<typename Tag>
0444 struct category_of_impl;
0445
0446 template<typename Tag, typename Domain>
0447 struct category_of_impl<proto::tag::proto_expr<Tag, Domain> >
0448 {
0449 template<typename Sequence>
0450 struct apply
0451 {
0452 typedef random_access_traversal_tag type;
0453 };
0454 };
0455
0456 template<typename Tag>
0457 struct size_impl;
0458
0459 template<typename Tag, typename Domain>
0460 struct size_impl<proto::tag::proto_expr<Tag, Domain> >
0461 {
0462 template<typename Sequence>
0463 struct apply
0464 : mpl::long_<0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c>
0465 {};
0466 };
0467
0468 template<typename Tag>
0469 struct begin_impl;
0470
0471 template<typename Tag, typename Domain>
0472 struct begin_impl<proto::tag::proto_expr<Tag, Domain> >
0473 {
0474 template<typename Sequence>
0475 struct apply
0476 {
0477 typedef proto::detail::expr_iterator<Sequence, 0> type;
0478
0479 static type call(Sequence &seq)
0480 {
0481 return type(seq);
0482 }
0483 };
0484 };
0485
0486 template<typename Tag>
0487 struct end_impl;
0488
0489 template<typename Tag, typename Domain>
0490 struct end_impl<proto::tag::proto_expr<Tag, Domain> >
0491 {
0492 template<typename Sequence>
0493 struct apply
0494 {
0495 typedef
0496 proto::detail::expr_iterator<
0497 Sequence
0498 , 0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c
0499 >
0500 type;
0501
0502 static type call(Sequence &seq)
0503 {
0504 return type(seq);
0505 }
0506 };
0507 };
0508
0509 template<typename Tag>
0510 struct value_at_impl;
0511
0512 template<typename Tag, typename Domain>
0513 struct value_at_impl<proto::tag::proto_expr<Tag, Domain> >
0514 {
0515 template<
0516 typename Sequence
0517 , typename Index
0518 , long Arity = proto::arity_of<Sequence>::value
0519 >
0520 struct apply
0521 {
0522 typedef
0523 typename proto::result_of::child_c<
0524 Sequence
0525 , Index::value
0526 >::value_type
0527 type;
0528 };
0529
0530 template<typename Sequence, typename Index>
0531 struct apply<Sequence, Index, 0>
0532 {
0533 typedef
0534 typename proto::result_of::value<
0535 Sequence
0536 >::value_type
0537 type;
0538 };
0539 };
0540
0541 template<typename Tag>
0542 struct at_impl;
0543
0544 template<typename Tag, typename Domain>
0545 struct at_impl<proto::tag::proto_expr<Tag, Domain> >
0546 {
0547 template<
0548 typename Sequence
0549 , typename Index
0550 , long Arity = proto::arity_of<Sequence>::value
0551 >
0552 struct apply
0553 {
0554 typedef
0555 typename proto::result_of::child_c<
0556 Sequence &
0557 , Index::value
0558 >::type
0559 type;
0560
0561 static type call(Sequence &seq)
0562 {
0563 return proto::child_c<Index::value>(seq);
0564 }
0565 };
0566
0567 template<typename Sequence, typename Index>
0568 struct apply<Sequence, Index, 0>
0569 {
0570 typedef
0571 typename proto::result_of::value<
0572 Sequence &
0573 >::type
0574 type;
0575
0576 static type call(Sequence &seq)
0577 {
0578 return proto::value(seq);
0579 }
0580 };
0581 };
0582
0583 template<typename Tag>
0584 struct convert_impl;
0585
0586 template<typename Tag, typename Domain>
0587 struct convert_impl<proto::tag::proto_expr<Tag, Domain> >
0588 {
0589 template<typename Sequence>
0590 struct apply
0591 {
0592 typedef
0593 typename proto::result_of::unpack_expr<
0594 Tag
0595 , Domain
0596 , Sequence
0597 >::type
0598 type;
0599
0600 static type call(Sequence& seq)
0601 {
0602 return proto::unpack_expr<Tag, Domain>(seq);
0603 }
0604 };
0605 };
0606
0607 template<typename Tag, typename Domain>
0608 struct convert_impl<proto::tag::proto_flat_view<Tag, Domain> >
0609 {
0610 template<typename Sequence>
0611 struct apply
0612 {
0613 typedef
0614 typename proto::result_of::unpack_expr<
0615 Tag
0616 , Domain
0617 , Sequence
0618 >::type
0619 type;
0620
0621 static type call(Sequence& seq)
0622 {
0623 return proto::unpack_expr<Tag, Domain>(seq);
0624 }
0625 };
0626 };
0627
0628 template<typename Tag>
0629 struct is_segmented_impl;
0630
0631 template<typename Tag, typename Domain>
0632 struct is_segmented_impl<proto::tag::proto_flat_view<Tag, Domain> >
0633 {
0634 template<typename Iterator>
0635 struct apply
0636 : mpl::true_
0637 {};
0638 };
0639
0640 template<typename Tag>
0641 struct segments_impl;
0642
0643 template<typename Tag, typename Domain>
0644 struct segments_impl<proto::tag::proto_flat_view<Tag, Domain> >
0645 {
0646 template<typename Sequence>
0647 struct apply
0648 {
0649 typedef typename Sequence::segments_type const &type;
0650
0651 static type call(Sequence &sequence)
0652 {
0653 return sequence.segs_;
0654 }
0655 };
0656 };
0657
0658 template<typename Tag, typename Domain>
0659 struct category_of_impl<proto::tag::proto_flat_view<Tag, Domain> >
0660 {
0661 template<typename Sequence>
0662 struct apply
0663 {
0664 typedef forward_traversal_tag type;
0665 };
0666 };
0667 }
0668
0669 namespace traits
0670 {
0671 template<typename Seq1, typename Seq2>
0672 struct enable_equality<
0673 Seq1
0674 , Seq2
0675 , typename enable_if_c<
0676 mpl::or_<
0677 proto::is_expr<Seq1>
0678 , proto::is_expr<Seq2>
0679 >::value
0680 >::type
0681 >
0682 : mpl::false_
0683 {};
0684
0685 template<typename Seq1, typename Seq2>
0686 struct enable_comparison<
0687 Seq1
0688 , Seq2
0689 , typename enable_if_c<
0690 mpl::or_<
0691 proto::is_expr<Seq1>
0692 , proto::is_expr<Seq2>
0693 >::value
0694 >::type
0695 >
0696 : mpl::false_
0697 {};
0698 }
0699 }}
0700
0701 namespace boost { namespace mpl
0702 {
0703 template<typename Tag, typename Args, long Arity>
0704 struct sequence_tag< proto::expr<Tag, Args, Arity> >
0705 {
0706 typedef fusion::fusion_sequence_tag type;
0707 };
0708
0709 template<typename Tag, typename Args, long Arity>
0710 struct sequence_tag< proto::basic_expr<Tag, Args, Arity> >
0711 {
0712 typedef fusion::fusion_sequence_tag type;
0713 };
0714 }}
0715
0716 #ifdef BOOST_MSVC
0717 #pragma warning(pop)
0718 #endif
0719
0720 #endif