diff options
Diffstat (limited to '3rdParty/Boost/src/boost/proto/fusion.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/proto/fusion.hpp | 694 |
1 files changed, 694 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/proto/fusion.hpp b/3rdParty/Boost/src/boost/proto/fusion.hpp new file mode 100644 index 0000000..cf50038 --- /dev/null +++ b/3rdParty/Boost/src/boost/proto/fusion.hpp @@ -0,0 +1,694 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file fusion.hpp +/// Make any Proto expression a valid Fusion sequence +// +// Copyright 2008 Eric Niebler. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROTO_FUSION_HPP_EAN_11_04_2006 +#define BOOST_PROTO_FUSION_HPP_EAN_11_04_2006 + +#include <boost/config.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/long.hpp> +#include <boost/mpl/sequence_tag_fwd.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/fusion/include/is_view.hpp> +#include <boost/fusion/include/tag_of_fwd.hpp> +#include <boost/fusion/include/category_of.hpp> +#include <boost/fusion/include/iterator_base.hpp> +#include <boost/fusion/include/intrinsic.hpp> +#include <boost/fusion/include/single_view.hpp> +#include <boost/fusion/include/transform_view.hpp> +#include <boost/fusion/support/ext_/is_segmented.hpp> +#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp> +#include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp> +#include <boost/fusion/sequence/comparison/enable_comparison.hpp> +#include <boost/fusion/view/ext_/segmented_iterator.hpp> +#include <boost/proto/proto_fwd.hpp> +#include <boost/proto/traits.hpp> +#include <boost/proto/eval.hpp> + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable : 4510) // default constructor could not be generated +#pragma warning(disable : 4512) // assignment operator could not be generated +#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required +#endif + +namespace boost { namespace proto +{ + namespace detail + { + template<typename Expr, long Pos> + struct expr_iterator + : fusion::iterator_base<expr_iterator<Expr, Pos> > + { + typedef Expr expr_type; + typedef typename Expr::proto_tag proto_tag; + BOOST_STATIC_CONSTANT(long, index = Pos); + typedef fusion::random_access_traversal_tag category; + typedef tag::proto_expr_iterator fusion_tag; + + expr_iterator(Expr &e) + : expr(e) + {} + + Expr &expr; + }; + + template<typename Expr> + struct flat_view + { + typedef Expr expr_type; + typedef typename Expr::proto_tag proto_tag; + typedef fusion::forward_traversal_tag category; + typedef tag::proto_flat_view fusion_tag; + + explicit flat_view(Expr &e) + : expr_(e) + {} + + Expr &expr_; + }; + + template<typename Tag> + struct as_element + { + template<typename Sig> + struct result; + + template<typename This, typename Expr> + struct result<This(Expr)> + : result<This(Expr const &)> + {}; + + template<typename This, typename Expr> + struct result<This(Expr &)> + : mpl::if_c< + is_same<Tag, typename Expr::proto_tag>::value + , flat_view<Expr> + , fusion::single_view<Expr &> + > + {}; + + template<typename Expr> + typename result<as_element(Expr &)>::type const + operator ()(Expr &e) const + { + return typename result<as_element(Expr &)>::type(e); + } + + template<typename Expr> + typename result<as_element(Expr const &)>::type const + operator ()(Expr const &e) const + { + return typename result<as_element(Expr const &)>::type(e); + } + }; + } + + namespace result_of + { + template<typename Expr> + struct flatten + : flatten<Expr const &> + {}; + + template<typename Expr> + struct flatten<Expr &> + { + typedef detail::flat_view<Expr> type; + }; + } + + namespace functional + { + /// \brief A PolymorphicFunctionObject type that returns a "flattened" + /// view of a Proto expression tree. + /// + /// A PolymorphicFunctionObject type that returns a "flattened" + /// view of a Proto expression tree. For a tree with a top-most node + /// tag of type \c T, the elements of the flattened sequence are + /// determined by recursing into each child node with the same + /// tag type and returning those nodes of different type. So for + /// instance, the Proto expression tree corresponding to the + /// expression <tt>a | b | c</tt> has a flattened view with elements + /// [a, b, c], even though the tree is grouped as + /// <tt>((a | b) | c)</tt>. + struct flatten + { + BOOST_PROTO_CALLABLE() + + template<typename Sig> + struct result; + + template<typename This, typename Expr> + struct result<This(Expr)> + : result<This(Expr const &)> + {}; + + template<typename This, typename Expr> + struct result<This(Expr &)> + { + typedef proto::detail::flat_view<Expr> type; + }; + + template<typename Expr> + proto::detail::flat_view<Expr> const + operator ()(Expr &e) const + { + return proto::detail::flat_view<Expr>(e); + } + + template<typename Expr> + proto::detail::flat_view<Expr const> const + operator ()(Expr const &e) const + { + return proto::detail::flat_view<Expr const>(e); + } + }; + } + + /// \brief A function that returns a "flattened" + /// view of a Proto expression tree. + /// + /// For a tree with a top-most node + /// tag of type \c T, the elements of the flattened sequence are + /// determined by recursing into each child node with the same + /// tag type and returning those nodes of different type. So for + /// instance, the Proto expression tree corresponding to the + /// expression <tt>a | b | c</tt> has a flattened view with elements + /// [a, b, c], even though the tree is grouped as + /// <tt>((a | b) | c)</tt>. + template<typename Expr> + proto::detail::flat_view<Expr> const + flatten(Expr &e) + { + return proto::detail::flat_view<Expr>(e); + } + + /// \overload + /// + template<typename Expr> + proto::detail::flat_view<Expr const> const + flatten(Expr const &e) + { + return proto::detail::flat_view<Expr const>(e); + } + + /// INTERNAL ONLY + /// + template<typename Context> + struct eval_fun + : proto::callable + { + explicit eval_fun(Context &ctx) + : ctx_(ctx) + {} + + template<typename Sig> + struct result; + + template<typename This, typename Expr> + struct result<This(Expr)> + : result<This(Expr const &)> + {}; + + template<typename This, typename Expr> + struct result<This(Expr &)> + : proto::result_of::eval<Expr, Context> + {}; + + template<typename Expr> + typename proto::result_of::eval<Expr, Context>::type + operator ()(Expr &e) const + { + return proto::eval(e, this->ctx_); + } + + template<typename Expr> + typename proto::result_of::eval<Expr const, Context>::type + operator ()(Expr const &e) const + { + return proto::eval(e, this->ctx_); + } + + private: + Context &ctx_; + }; + + /// INTERNAL ONLY + /// + template<typename Context> + struct is_callable<eval_fun<Context> > + : mpl::true_ + {}; +}} + +namespace boost { namespace fusion +{ + namespace extension + { + template<typename Tag> + struct is_sequence_impl; + + template<> + struct is_sequence_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + : mpl::true_ + {}; + }; + + template<> + struct is_sequence_impl<proto::tag::proto_expr> + { + template<typename Sequence> + struct apply + : mpl::true_ + {}; + }; + + template<typename Tag> + struct is_view_impl; + + template<> + struct is_view_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + : mpl::true_ + {}; + }; + + template<> + struct is_view_impl<proto::tag::proto_expr> + { + template<typename Sequence> + struct apply + : mpl::false_ + {}; + }; + + template<typename Tag> + struct value_of_impl; + + template<> + struct value_of_impl<proto::tag::proto_expr_iterator> + { + template< + typename Iterator + , long Arity = proto::arity_of<typename Iterator::expr_type>::value + > + struct apply + { + typedef + typename proto::result_of::child_c< + typename Iterator::expr_type + , Iterator::index + >::value_type + type; + }; + + template<typename Iterator> + struct apply<Iterator, 0> + { + typedef + typename proto::result_of::value< + typename Iterator::expr_type + >::value_type + type; + }; + }; + + template<typename Tag> + struct deref_impl; + + template<> + struct deref_impl<proto::tag::proto_expr_iterator> + { + template< + typename Iterator + , long Arity = proto::arity_of<typename Iterator::expr_type>::value + > + struct apply + { + typedef + typename proto::result_of::child_c< + typename Iterator::expr_type & + , Iterator::index + >::type + type; + + static type call(Iterator const &iter) + { + return proto::child_c<Iterator::index>(iter.expr); + } + }; + + template<typename Iterator> + struct apply<Iterator, 0> + { + typedef + typename proto::result_of::value< + typename Iterator::expr_type & + >::type + type; + + static type call(Iterator const &iter) + { + return proto::value(iter.expr); + } + }; + }; + + template<typename Tag> + struct advance_impl; + + template<> + struct advance_impl<proto::tag::proto_expr_iterator> + { + template<typename Iterator, typename N> + struct apply + { + typedef + typename proto::detail::expr_iterator< + typename Iterator::expr_type + , Iterator::index + N::value + > + type; + + static type call(Iterator const &iter) + { + return type(iter.expr); + } + }; + }; + + template<typename Tag> + struct distance_impl; + + template<> + struct distance_impl<proto::tag::proto_expr_iterator> + { + template<typename IteratorFrom, typename IteratorTo> + struct apply + : mpl::long_<IteratorTo::index - IteratorFrom::index> + {}; + }; + + template<typename Tag> + struct next_impl; + + template<> + struct next_impl<proto::tag::proto_expr_iterator> + { + template<typename Iterator> + struct apply + : advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<1> > + {}; + }; + + template<typename Tag> + struct prior_impl; + + template<> + struct prior_impl<proto::tag::proto_expr_iterator> + { + template<typename Iterator> + struct apply + : advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<-1> > + {}; + }; + + template<typename Tag> + struct category_of_impl; + + template<> + struct category_of_impl<proto::tag::proto_expr> + { + template<typename Sequence> + struct apply + { + typedef random_access_traversal_tag type; + }; + }; + + template<typename Tag> + struct size_impl; + + template<> + struct size_impl<proto::tag::proto_expr> + { + template<typename Sequence> + struct apply + : mpl::long_<0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c> + {}; + }; + + template<typename Tag> + struct begin_impl; + + template<> + struct begin_impl<proto::tag::proto_expr> + { + template<typename Sequence> + struct apply + { + typedef proto::detail::expr_iterator<Sequence, 0> type; + + static type call(Sequence &seq) + { + return type(seq); + } + }; + }; + + template<typename Tag> + struct end_impl; + + template<> + struct end_impl<proto::tag::proto_expr> + { + template<typename Sequence> + struct apply + { + typedef + proto::detail::expr_iterator< + Sequence + , 0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c + > + type; + + static type call(Sequence &seq) + { + return type(seq); + } + }; + }; + + template<typename Tag> + struct value_at_impl; + + template<> + struct value_at_impl<proto::tag::proto_expr> + { + template< + typename Sequence + , typename Index + , long Arity = proto::arity_of<Sequence>::value + > + struct apply + { + typedef + typename proto::result_of::child_c< + Sequence + , Index::value + >::value_type + type; + }; + + template<typename Sequence, typename Index> + struct apply<Sequence, Index, 0> + { + typedef + typename proto::result_of::value< + Sequence + >::value_type + type; + }; + }; + + template<typename Tag> + struct at_impl; + + template<> + struct at_impl<proto::tag::proto_expr> + { + template< + typename Sequence + , typename Index + , long Arity = proto::arity_of<Sequence>::value + > + struct apply + { + typedef + typename proto::result_of::child_c< + Sequence & + , Index::value + >::type + type; + + static type call(Sequence &seq) + { + return proto::child_c<Index::value>(seq); + } + }; + + template<typename Sequence, typename Index> + struct apply<Sequence, Index, 0> + { + typedef + typename proto::result_of::value< + Sequence & + >::type + type; + + static type call(Sequence &seq) + { + return proto::value(seq); + } + }; + }; + + template<typename Tag> + struct is_segmented_impl; + + template<> + struct is_segmented_impl<proto::tag::proto_flat_view> + { + template<typename Iterator> + struct apply + : mpl::true_ + {}; + }; + + template<typename Tag> + struct segments_impl; + + template<> + struct segments_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + { + typedef typename Sequence::proto_tag proto_tag; + + typedef fusion::transform_view< + typename Sequence::expr_type + , proto::detail::as_element<proto_tag> + > type; + + static type call(Sequence &sequence) + { + return type(sequence.expr_, proto::detail::as_element<proto_tag>()); + } + }; + }; + + template<> + struct category_of_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + { + typedef forward_traversal_tag type; + }; + }; + + template<> + struct begin_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + : fusion::segmented_begin<Sequence> + {}; + }; + + template<> + struct end_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + : fusion::segmented_end<Sequence> + {}; + }; + + template<> + struct size_impl<proto::tag::proto_flat_view> + { + template<typename Sequence> + struct apply + : fusion::segmented_size<Sequence> + {}; + }; + + } + + namespace traits + { + template<typename Seq1, typename Seq2> + struct enable_equality< + Seq1 + , Seq2 + , typename enable_if_c< + mpl::or_< + proto::is_expr<Seq1> + , proto::is_expr<Seq2> + >::value + >::type + > + : mpl::false_ + {}; + + template<typename Seq1, typename Seq2> + struct enable_comparison< + Seq1 + , Seq2 + , typename enable_if_c< + mpl::or_< + proto::is_expr<Seq1> + , proto::is_expr<Seq2> + >::value + >::type + > + : mpl::false_ + {}; + } + +}} + +namespace boost { namespace mpl +{ + template<typename Tag, typename Args, long Arity> + struct sequence_tag< proto::expr<Tag, Args, Arity> > + { + typedef fusion::fusion_sequence_tag type; + }; + + template<typename Tag, typename Args, long Arity> + struct sequence_tag< proto::basic_expr<Tag, Args, Arity> > + { + typedef fusion::fusion_sequence_tag type; + }; +}} + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif |