/////////////////////////////////////////////////////////////////////////////// /// \file fusion.hpp /// Make any Proto parse tree a valid Fusion sequence // // Copyright 2007 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_04_29_2006 #define BOOST_PROTO_FUSION_HPP_EAN_04_29_2006 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define UNREF(x) typename remove_reference::type #define UNCVREF(x) typename remove_cv::type>::type namespace boost { namespace proto { namespace detail { template struct ref_iterator : fusion::iterator_base > { typedef Expr expr_type; typedef mpl::long_ index; typedef fusion::forward_traversal_tag category; typedef tag::proto_ref_iterator fusion_tag; ref_iterator(Expr const &expr) : expr_(expr) {} Expr expr_; }; } template struct children : proto::ref_ { children(Expr &expr) : proto::ref_(proto::ref_::make(expr)) {} }; template children children_of(Expr &expr) { return children(expr); } template struct eval_fun { eval_fun(Context &ctx) : ctx_(ctx) {} template struct result {}; template struct result : proto::result_of::eval {}; template typename proto::result_of::eval::type operator()(Expr &expr) const { return proto::eval(expr, this->ctx_); } private: Context &ctx_; }; }} namespace boost { namespace fusion { namespace extension { template struct is_view_impl; template<> struct is_view_impl { template struct apply : mpl::true_ {}; }; template<> struct is_view_impl { template struct apply : mpl::false_ {}; }; template struct value_of_impl; template<> struct value_of_impl { template struct apply : proto::result_of::arg {}; }; template struct deref_impl; template<> struct deref_impl { template struct apply { typedef typename proto::result_of::arg< typename Iterator::expr_type , typename Iterator::index >::type const &type; static type call(Iterator const &iter) { return proto::arg(iter.expr_); } }; }; template struct advance_impl; template<> struct advance_impl { template struct apply { typedef typename proto::detail::ref_iterator< typename Iterator::expr_type , Iterator::index::value + N::value > type; static type call(Iterator const &iter) { return type(iter.expr_); } }; }; template struct distance_impl; template<> struct distance_impl { template struct apply : mpl::long_ {}; }; template struct next_impl; template<> struct next_impl { template struct apply : advance_impl::template apply > {}; }; template struct prior_impl; template<> struct prior_impl { template struct apply : advance_impl::template apply > {}; }; template struct category_of_impl; template<> struct category_of_impl { template struct apply { typedef random_access_traversal_tag type; }; }; template struct size_impl; template<> struct size_impl { template struct apply : Sequence::proto_arity {}; }; template struct begin_impl; template<> struct begin_impl { template struct apply { typedef proto::detail::ref_iterator type; static type call(Sequence& seq) { return type(seq); } }; }; template struct end_impl; template<> struct end_impl { template struct apply { typedef proto::detail::ref_iterator type; static type call(Sequence& seq) { return type(seq); } }; }; template struct value_at_impl; template<> struct value_at_impl { template struct apply { typedef typename proto::result_of::arg::type type; }; }; template struct at_impl; template<> struct at_impl { template struct apply { typedef typename proto::result_of::arg::type const &type; static type call(Sequence &seq) { return proto::arg_c(seq); } }; }; template struct is_segmented_impl; template<> struct is_segmented_impl { template struct apply : mpl::true_ {}; }; template struct as_element { template struct result {}; template struct result : mpl::if_< is_same , UNCVREF(Expr) const & , fusion::single_view > {}; template typename result::type operator()(Expr &expr) const { return typename result::type(expr); } }; template struct segments_impl; template<> struct segments_impl { template struct apply { typedef typename Sequence::proto_tag proto_tag; typedef fusion::transform_view< proto::ref_ , as_element > type; static type call(Sequence &sequence) { proto::ref_ r = {sequence}; return type(r, as_element()); } }; }; template<> struct category_of_impl { template struct apply { typedef forward_traversal_tag type; }; }; template<> struct begin_impl { template struct apply : fusion::segmented_begin {}; }; template<> struct end_impl { template struct apply : fusion::segmented_end {}; }; template<> struct size_impl { template struct apply : fusion::segmented_size {}; }; } }} //namespace boost { namespace mpl //{ //template<> //struct begin_impl //{ // template // struct apply // : begin_impl::type> // ::template apply // {}; //}; //template<> //struct end_impl //{ // template // struct apply // : end_impl::type> // ::template apply // {}; //}; //template<> //struct size_impl //{ // template // struct apply // { // typedef typename Sequence::proto_arity type; // }; //}; //template<> //struct at_impl //{ // template // struct apply // : at_impl::type> // ::template apply // {}; //}; //template<> //struct begin_impl //{ // template // struct apply // : begin_impl::type> // ::template apply // {}; //}; //template<> //struct end_impl //{ // template // struct apply // : end_impl::type> // ::template apply // {}; //}; //template<> //struct size_impl //{ // template // struct apply // { // typedef typename Sequence::proto_arity type; // }; //}; //template<> //struct at_impl //{ // template // struct apply // : at_impl::type> // ::template apply // {}; //}; //}} // namespace boost::mpl //namespace boost { namespace mpl //{ // template // struct sequence_tag > // { // typedef proto::tag::proto_expr type; // }; // // template // struct sequence_tag > // { // typedef proto::tag::proto_expr type; // }; // // template<> // struct begin_impl // { // template // struct apply // : begin_impl::type> // ::template apply // {}; // }; // // template<> // struct end_impl // { // template // struct apply // : end_impl::type> // ::template apply // {}; // }; // // template<> // struct size_impl // { // template // struct apply // { // typedef typename Sequence::proto_arity type; // }; // }; // // template<> // struct at_impl // { // template // struct apply // : at_impl::type> // ::template apply // {}; // }; // //}} // namespace boost::mpl #undef UNREF #undef UNCVREF #endif