Edit: /usr/include/boost/proto/fusion.hpp (20934B)
///////////////////////////////////////////////////////////////////////////////
/// \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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
struct expr_iterator
: fusion::iterator_base >
{
typedef Expr expr_type;
static const long index = Pos;
typedef fusion::random_access_traversal_tag category;
typedef
tag::proto_expr_iterator<
typename Expr::proto_tag
, typename Expr::proto_domain
>
fusion_tag;
explicit expr_iterator(Expr &e)
: expr(e)
{}
Expr &expr;
};
template
struct as_element
{
template
struct result;
template
struct result
: result
{};
template
struct result
: mpl::if_c<
is_same::value
, flat_view
, fusion::single_view
>
{};
template
typename result::type const
operator ()(Expr &e) const
{
return typename result::type(e);
}
template
typename result::type const
operator ()(Expr const &e) const
{
return typename result::type(e);
}
};
template
struct flat_view
: fusion::sequence_base >
{
typedef fusion::forward_traversal_tag category;
typedef
tag::proto_flat_view<
typename Expr::proto_tag
, typename Expr::proto_domain
>
fusion_tag;
typedef
typename fusion::result_of::as_list<
typename fusion::result_of::transform<
Expr
, as_element
>::type
>::type
segments_type;
explicit flat_view(Expr &e)
: segs_(fusion::as_list(fusion::transform(e, as_element())))
{}
segments_type segs_;
};
}
namespace result_of
{
template
struct flatten
: flatten
{};
template
struct flatten
{
typedef detail::flat_view 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 a | b | c has a flattened view with elements
/// [a, b, c], even though the tree is grouped as
/// ((a | b) | c).
struct flatten
{
BOOST_PROTO_CALLABLE()
template
struct result;
template
struct result
: result
{};
template
struct result
{
typedef proto::detail::flat_view type;
};
template
proto::detail::flat_view const
operator ()(Expr &e) const
{
return proto::detail::flat_view(e);
}
template
proto::detail::flat_view const
operator ()(Expr const &e) const
{
return proto::detail::flat_view(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 a | b | c has a flattened view with elements
/// [a, b, c], even though the tree is grouped as
/// ((a | b) | c).
template
proto::detail::flat_view const
flatten(Expr &e)
{
return proto::detail::flat_view(e);
}
/// \overload
///
template
proto::detail::flat_view const
flatten(Expr const &e)
{
return proto::detail::flat_view(e);
}
/// INTERNAL ONLY
///
template
struct eval_fun
: proto::callable
{
explicit eval_fun(Context &ctx)
: ctx_(ctx)
{}
template
struct result;
template
struct result
: result
{};
template
struct result
: proto::result_of::eval
{};
template
typename proto::result_of::eval::type
operator ()(Expr &e) const
{
return proto::eval(e, this->ctx_);
}
template
typename proto::result_of::eval::type
operator ()(Expr const &e) const
{
return proto::eval(e, this->ctx_);
}
private:
Context &ctx_;
};
/// INTERNAL ONLY
///
template
struct is_callable >
: mpl::true_
{};
}}
namespace boost { namespace fusion
{
namespace extension
{
template
struct is_sequence_impl;
template
struct is_sequence_impl >
{
template
struct apply
: mpl::true_
{};
};
template
struct is_sequence_impl >
{
template
struct apply
: mpl::true_
{};
};
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<
typename Iterator
, long Arity = proto::arity_of::value
>
struct apply
{
typedef
typename proto::result_of::child_c<
typename Iterator::expr_type
, Iterator::index
>::value_type
type;
};
template
struct apply
{
typedef
typename proto::result_of::value<
typename Iterator::expr_type
>::value_type
type;
};
};
template
struct deref_impl;
template
struct deref_impl >
{
template<
typename Iterator
, long Arity = proto::arity_of::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(iter.expr);
}
};
template
struct apply
{
typedef
typename proto::result_of::value<
typename Iterator::expr_type &
>::type
type;
static type call(Iterator const &iter)
{
return proto::value(iter.expr);
}
};
};
template
struct advance_impl;
template
struct advance_impl >
{
template
struct apply
{
typedef
proto::detail::expr_iterator<
typename Iterator::expr_type
, Iterator::index + 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
: mpl::long_<0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c>
{};
};
template
struct begin_impl;
template
struct begin_impl >
{
template
struct apply
{
typedef proto::detail::expr_iterator type;
static type call(Sequence &seq)
{
return type(seq);
}
};
};
template
struct end_impl;
template
struct end_impl >
{
template
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
struct value_at_impl;
template
struct value_at_impl >
{
template<
typename Sequence
, typename Index
, long Arity = proto::arity_of::value
>
struct apply
{
typedef
typename proto::result_of::child_c<
Sequence
, Index::value
>::value_type
type;
};
template
struct apply
{
typedef
typename proto::result_of::value<
Sequence
>::value_type
type;
};
};
template
struct at_impl;
template
struct at_impl >
{
template<
typename Sequence
, typename Index
, long Arity = proto::arity_of::value
>
struct apply
{
typedef
typename proto::result_of::child_c<
Sequence &
, Index::value
>::type
type;
static type call(Sequence &seq)
{
return proto::child_c(seq);
}
};
template
struct apply
{
typedef
typename proto::result_of::value<
Sequence &
>::type
type;
static type call(Sequence &seq)
{
return proto::value(seq);
}
};
};
template
struct convert_impl;
template
struct convert_impl >
{
template
struct apply
{
typedef
typename proto::result_of::unpack_expr<
Tag
, Domain
, Sequence
>::type
type;
static type call(Sequence& seq)
{
return proto::unpack_expr(seq);
}
};
};
template
struct convert_impl >
{
template
struct apply
{
typedef
typename proto::result_of::unpack_expr<
Tag
, Domain
, Sequence
>::type
type;
static type call(Sequence& seq)
{
return proto::unpack_expr(seq);
}
};
};
template
struct is_segmented_impl;
template
struct is_segmented_impl >
{
template
struct apply
: mpl::true_
{};
};
template
struct segments_impl;
template
struct segments_impl >
{
template
struct apply
{
typedef typename Sequence::segments_type const &type;
static type call(Sequence &sequence)
{
return sequence.segs_;
}
};
};
template
struct category_of_impl >
{
template
struct apply
{
typedef forward_traversal_tag type;
};
};
}
namespace traits
{
template
struct enable_equality<
Seq1
, Seq2
, typename enable_if_c<
mpl::or_<
proto::is_expr
, proto::is_expr
>::value
>::type
>
: mpl::false_
{};
template
struct enable_comparison<
Seq1
, Seq2
, typename enable_if_c<
mpl::or_<
proto::is_expr
, proto::is_expr
>::value
>::type
>
: mpl::false_
{};
}
}}
namespace boost { namespace mpl
{
template
struct sequence_tag< proto::expr >
{
typedef fusion::fusion_sequence_tag type;
};
template
struct sequence_tag< proto::basic_expr >
{
typedef fusion::fusion_sequence_tag type;
};
}}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#endif