boost/xpressive/proto/fusion.hpp
///////////////////////////////////////////////////////////////////////////////
/// \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 <boost/xpressive/proto/detail/prefix.hpp>
#include <boost/xpressive/proto/proto.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/distance.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.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/mpl.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/view/ext_/segmented_iterator.hpp>
#include <boost/xpressive/proto/detail/suffix.hpp>
#define UNREF(x) typename remove_reference<x>::type
#define UNCVREF(x) typename remove_cv<typename remove_reference<x>::type>::type
namespace boost { namespace proto
{
namespace detail
{
template<typename Expr, int Pos>
struct ref_iterator
: fusion::iterator_base<ref_iterator<Expr, Pos> >
{
typedef Expr expr_type;
typedef mpl::long_<Pos> index;
typedef fusion::forward_traversal_tag category;
typedef tag::proto_ref_iterator fusion_tag;
ref_iterator(Expr const &expr)
: expr_(expr)
{}
Expr expr_;
};
}
template<typename Expr>
struct children
: proto::ref_<Expr>
{
children(Expr &expr)
: proto::ref_<Expr>(proto::ref_<Expr>::make(expr))
{}
};
template<typename Expr>
children<Expr> children_of(Expr &expr)
{
return children<Expr>(expr);
}
template<typename Context>
struct eval_fun
{
eval_fun(Context &ctx)
: ctx_(ctx)
{}
template<typename Sig>
struct result {};
template<typename This, typename Expr>
struct result<This(Expr)>
: proto::result_of::eval<UNREF(Expr), Context>
{};
template<typename Expr>
typename proto::result_of::eval<Expr, Context>::type
operator()(Expr &expr) const
{
return proto::eval(expr, this->ctx_);
}
private:
Context &ctx_;
};
}}
namespace boost { namespace fusion
{
namespace extension
{
template<typename Tag>
struct is_view_impl;
template<>
struct is_view_impl<proto::tag::proto_ref>
{
template<typename Iterator>
struct apply
: mpl::true_
{};
};
template<>
struct is_view_impl<proto::tag::proto_expr>
{
template<typename Iterator>
struct apply
: mpl::false_
{};
};
template<typename Tag>
struct value_of_impl;
template<>
struct value_of_impl<proto::tag::proto_ref_iterator>
{
template<typename Iterator>
struct apply
: proto::result_of::arg<typename Iterator::expr_type, typename Iterator::index>
{};
};
template<typename Tag>
struct deref_impl;
template<>
struct deref_impl<proto::tag::proto_ref_iterator>
{
template<typename Iterator>
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<typename Iterator::index>(iter.expr_);
}
};
};
template<typename Tag>
struct advance_impl;
template<>
struct advance_impl<proto::tag::proto_ref_iterator>
{
template<typename Iterator, typename N>
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<typename Tag>
struct distance_impl;
template<>
struct distance_impl<proto::tag::proto_ref_iterator>
{
template<typename IteratorFrom, typename IteratorTo>
struct apply
: mpl::long_<IteratorTo::index::value - IteratorFrom::index::value>
{};
};
template<typename Tag>
struct next_impl;
template<>
struct next_impl<proto::tag::proto_ref_iterator>
{
template<typename Iterator>
struct apply
: advance_impl<proto::tag::proto_ref_iterator>::template apply<Iterator, mpl::long_<1> >
{};
};
template<typename Tag>
struct prior_impl;
template<>
struct prior_impl<proto::tag::proto_ref_iterator>
{
template<typename Iterator>
struct apply
: advance_impl<proto::tag::proto_ref_iterator>::template apply<Iterator, mpl::long_<-1> >
{};
};
template<typename Tag>
struct category_of_impl;
template<>
struct category_of_impl<proto::tag::proto_ref>
{
template<typename Sequence>
struct apply
{
typedef random_access_traversal_tag type;
};
};
template<typename Tag>
struct size_impl;
template<>
struct size_impl<proto::tag::proto_ref>
{
template<typename Sequence>
struct apply
: Sequence::proto_arity
{};
};
template<typename Tag>
struct begin_impl;
template<>
struct begin_impl<proto::tag::proto_ref>
{
template<typename Sequence>
struct apply
{
typedef proto::detail::ref_iterator<Sequence const, 0> type;
static type call(Sequence& seq)
{
return type(seq);
}
};
};
template<typename Tag>
struct end_impl;
template<>
struct end_impl<proto::tag::proto_ref>
{
template<typename Sequence>
struct apply
{
typedef proto::detail::ref_iterator<Sequence const, Sequence::proto_arity::value> type;
static type call(Sequence& seq)
{
return type(seq);
}
};
};
template<typename Tag>
struct value_at_impl;
template<>
struct value_at_impl<proto::tag::proto_ref>
{
template<typename Sequence, typename N>
struct apply
{
typedef typename proto::result_of::arg<Sequence, N>::type type;
};
};
template<typename Tag>
struct at_impl;
template<>
struct at_impl<proto::tag::proto_ref>
{
template<typename Sequence, typename N>
struct apply
{
typedef typename proto::result_of::arg<Sequence, N>::type const &type;
static type call(Sequence &seq)
{
return proto::arg_c<N::value>(seq);
}
};
};
template<typename Tag>
struct is_segmented_impl;
template<>
struct is_segmented_impl<proto::tag::proto_expr>
{
template<typename Iterator>
struct apply
: mpl::true_
{};
};
template<typename Tag>
struct as_element
{
template<typename Sig>
struct result {};
template<typename This, typename Expr>
struct result<This(Expr)>
: mpl::if_<
is_same<Tag, UNREF(Expr)::proto_tag>
, UNCVREF(Expr) const &
, fusion::single_view<UNCVREF(Expr) const &>
>
{};
template<typename Expr>
typename result<as_element(Expr)>::type
operator()(Expr &expr) const
{
return typename result<as_element(Expr)>::type(expr);
}
};
template<typename Tag>
struct segments_impl;
template<>
struct segments_impl<proto::tag::proto_expr>
{
template<typename Sequence>
struct apply
{
typedef typename Sequence::proto_tag proto_tag;
typedef fusion::transform_view<
proto::ref_<Sequence>
, as_element<proto_tag>
> type;
static type call(Sequence &sequence)
{
proto::ref_<Sequence> r = {sequence};
return type(r, as_element<proto_tag>());
}
};
};
template<>
struct category_of_impl<proto::tag::proto_expr>
{
template<typename Sequence>
struct apply
{
typedef forward_traversal_tag type;
};
};
template<>
struct begin_impl<proto::tag::proto_expr>
{
template<typename Sequence>
struct apply
: fusion::segmented_begin<Sequence>
{};
};
template<>
struct end_impl<proto::tag::proto_expr>
{
template<typename Sequence>
struct apply
: fusion::segmented_end<Sequence>
{};
};
template<>
struct size_impl<proto::tag::proto_expr>
{
template<typename Sequence>
struct apply
: fusion::segmented_size<Sequence>
{};
};
}
}}
//namespace boost { namespace mpl
//{
//template<>
//struct begin_impl<proto::tag::proto_expr>
//{
// template<typename Sequence>
// struct apply
// : begin_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args>
// {};
//};
//template<>
//struct end_impl<proto::tag::proto_expr>
//{
// template<typename Sequence>
// struct apply
// : end_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args>
// {};
//};
//template<>
//struct size_impl<proto::tag::proto_expr>
//{
// template<typename Sequence>
// struct apply
// {
// typedef typename Sequence::proto_arity type;
// };
//};
//template<>
//struct at_impl<proto::tag::proto_expr>
//{
// template<typename Sequence, typename N>
// struct apply
// : at_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args, N>
// {};
//};
//template<>
//struct begin_impl<proto::tag::proto_ref>
//{
// template<typename Sequence>
// struct apply
// : begin_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args>
// {};
//};
//template<>
//struct end_impl<proto::tag::proto_ref>
//{
// template<typename Sequence>
// struct apply
// : end_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args>
// {};
//};
//template<>
//struct size_impl<proto::tag::proto_ref>
//{
// template<typename Sequence>
// struct apply
// {
// typedef typename Sequence::proto_arity type;
// };
//};
//template<>
//struct at_impl<proto::tag::proto_ref>
//{
// template<typename Sequence, typename N>
// struct apply
// : at_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args, N>
// {};
//};
//}} // namespace boost::mpl
//namespace boost { namespace mpl
//{
// template<typename Tag, typename Args, long Arity>
// struct sequence_tag<proto::expr<Tag, Args, Arity> >
// {
// typedef proto::tag::proto_expr type;
// };
//
// template<typename Expr>
// struct sequence_tag<proto::ref_<Expr> >
// {
// typedef proto::tag::proto_expr type;
// };
//
// template<>
// struct begin_impl<proto::tag::proto_expr>
// {
// template<typename Sequence>
// struct apply
// : begin_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args>
// {};
// };
//
// template<>
// struct end_impl<proto::tag::proto_expr>
// {
// template<typename Sequence>
// struct apply
// : end_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args>
// {};
// };
//
// template<>
// struct size_impl<proto::tag::proto_expr>
// {
// template<typename Sequence>
// struct apply
// {
// typedef typename Sequence::proto_arity type;
// };
// };
//
// template<>
// struct at_impl<proto::tag::proto_expr>
// {
// template<typename Sequence, typename N>
// struct apply
// : at_impl<typename sequence_tag<typename Sequence::proto_args>::type>
// ::template apply<typename Sequence::proto_args, N>
// {};
// };
//
//}} // namespace boost::mpl
#undef UNREF
#undef UNCVREF
#endif