|
Boost-Commit : |
From: eric_at_[hidden]
Date: 2007-08-08 17:49:47
Author: eric_niebler
Date: 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
New Revision: 38544
URL: http://svn.boost.org/trac/boost/changeset/38544
Log:
in-development proto v3 with new transforms
Added:
branches/proto/v3/boost/xpressive/proto/transform2/
branches/proto/v3/boost/xpressive/proto/transform2.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/apply.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/arg.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/branch.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/compose.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/construct.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/fold.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/fold_tree.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/function.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/list.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto/transform2/pass_through.hpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto/test/examples2.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto/test/lambda2.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto/test/toy_spirit3.cpp (contents, props changed)
Text files modified:
branches/proto/v3/boost/xpressive/proto/context/callable.hpp | 10 +-
branches/proto/v3/boost/xpressive/proto/context/default.hpp | 14 +-
branches/proto/v3/boost/xpressive/proto/debug.hpp | 2
branches/proto/v3/boost/xpressive/proto/deep_copy.hpp | 8 +-
branches/proto/v3/boost/xpressive/proto/domain.hpp | 4
branches/proto/v3/boost/xpressive/proto/expr.hpp | 12 +-
branches/proto/v3/boost/xpressive/proto/fusion.hpp | 10 +-
branches/proto/v3/boost/xpressive/proto/generate.hpp | 8 +-
branches/proto/v3/boost/xpressive/proto/make_expr.hpp | 28 +++---
branches/proto/v3/boost/xpressive/proto/matches.hpp | 21 +++--
branches/proto/v3/boost/xpressive/proto/operators.hpp | 36 ++++----
branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp | 152 +++++++++++++++++++++++++++++++++++++--
branches/proto/v3/boost/xpressive/proto/ref.hpp | 2
branches/proto/v3/boost/xpressive/proto/traits.hpp | 67 +++++++++++-----
branches/proto/v3/boost/xpressive/proto/transform/apply.hpp | 2
branches/proto/v3/boost/xpressive/proto/transform/construct.hpp | 28 +++---
branches/proto/v3/boost/xpressive/proto/transform/fold.hpp | 6
branches/proto/v3/boost/xpressive/proto/transform/fold_tree.hpp | 6
branches/proto/v3/boost/xpressive/proto/transform/pass_through.hpp | 8 +-
branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2 | 3
branches/proto/v3/libs/xpressive/proto/test/examples.cpp | 2
21 files changed, 297 insertions(+), 132 deletions(-)
Modified: branches/proto/v3/boost/xpressive/proto/context/callable.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/context/callable.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/context/callable.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -33,7 +33,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
struct private_type_
{
@@ -70,7 +70,7 @@
template<typename Expr, typename ThisContext = Context>
struct eval
: mpl::if_<
- detail::is_expr_handled<Expr, Context>
+ detail_::is_expr_handled<Expr, Context>
, callable_eval<Expr, ThisContext>
, typename DefaultCtx::template eval<Expr, Context>
>::type
@@ -104,7 +104,7 @@
#define N BOOST_PP_ITERATION()
#define ARG_COUNT BOOST_PP_MAX(1, N)
- namespace detail
+ namespace detail_
{
#if N > 0
template<typename Context>
@@ -112,7 +112,7 @@
: remove_cv<Context>::type
{
callable_context_wrapper();
- typedef private_type_ const &(*pointer_to_function)(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(ARG_COUNT), detail::dont_care BOOST_PP_INTERCEPT));
+ typedef private_type_ const &(*pointer_to_function)(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(ARG_COUNT), detail_::dont_care BOOST_PP_INTERCEPT));
operator pointer_to_function() const;
};
#endif
@@ -127,7 +127,7 @@
(
sizeof(yes_type) ==
sizeof(
- detail::check_is_expr_handled(
+ detail_::check_is_expr_handled(
(sctx_(
typename Expr::proto_tag()
BOOST_PP_ENUM_TRAILING(ARG_COUNT, BOOST_PROTO_ARG_N, sexpr_)
Modified: branches/proto/v3/boost/xpressive/proto/context/default.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/context/default.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/context/default.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -41,7 +41,7 @@
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, Nested), Expr)\
struct Nested\
: mpl::if_c<\
- 1==sizeof(detail::check_reference(Expr))\
+ 1==sizeof(detail_::check_reference(Expr))\
, typename BOOST_PP_CAT(nested_and_hidden_, Nested)::type &\
, typename BOOST_PP_CAT(nested_and_hidden_, Nested)::type\
>\
@@ -57,12 +57,12 @@
/// INTERNAL ONLY
///
#define BOOST_PROTO_DECLTYPE_(Expr, Type)\
- typedef detail::unspecified Type;
+ typedef detail_::unspecified Type;
#endif
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
template<typename T> T make();
@@ -75,7 +75,7 @@
template<typename A0, typename A1>
struct comma_result
{
- BOOST_PROTO_DECLTYPE_((detail::make<A0>(), detail::make<A1>()), type)
+ BOOST_PROTO_DECLTYPE_((detail_::make<A0>(), detail_::make<A1>()), type)
};
template<typename A0>
@@ -130,7 +130,7 @@
#if BOOST_WORKAROUND(BOOST_MSVC, == 1400)
template<typename T> T &make_ref_(T &t);
template<typename T> T const &make_ref_(T const &t);
- #define BOOST_PROTO_REF(x) detail::make_ref_(x)
+ #define BOOST_PROTO_REF(x) detail_::make_ref_(x)
#else
#define BOOST_PROTO_REF(x) x
#endif
@@ -309,7 +309,7 @@
{
typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 0>::type, Context>::type proto_arg0;
typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 1>::type, Context>::type proto_arg1;
- typedef typename detail::comma_result<proto_arg0, proto_arg1>::type result_type;
+ typedef typename detail_::comma_result<proto_arg0, proto_arg1>::type result_type;
result_type operator()(Expr &expr, Context &ctx) const
{
return proto::eval(proto::arg_c<0>(expr), ctx), proto::eval(proto::arg_c<1>(expr), ctx);
@@ -361,7 +361,7 @@
struct default_eval<Expr, Context, proto::tag::function, N>
{
typedef
- typename detail::result_of_fixup<
+ typename detail_::result_of_fixup<
BOOST_PROTO_EVAL_N_TYPE(1, 0, (Expr, Context))
>::type
function_type;
Modified: branches/proto/v3/boost/xpressive/proto/debug.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/debug.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/debug.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -32,7 +32,7 @@
namespace hidden_detail_
{
typedef char (¬_ostream)[sizeof(std::ostream)+1];
- not_ostream operator<<(std::ostream &, detail::dont_care);
+ not_ostream operator<<(std::ostream &, detail_::dont_care);
template<typename Tag, std::size_t S>
struct printable_tag_
Modified: branches/proto/v3/boost/xpressive/proto/deep_copy.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/deep_copy.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/deep_copy.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -22,7 +22,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
template<typename Expr, long Arity = Expr::proto_arity::value>
struct deep_copy_impl;
@@ -45,7 +45,7 @@
{
template<typename Expr>
struct deep_copy
- : detail::deep_copy_impl<Expr>
+ : detail_::deep_copy_impl<Expr>
{};
}
@@ -58,7 +58,7 @@
template<typename This, typename Expr>
struct result<This(Expr)>
- : result_of::deep_copy<typename detail::remove_cv_ref<Expr>::type>
+ : result_of::deep_copy<typename detail_::remove_cv_ref<Expr>::type>
{};
template<typename Expr>
@@ -72,7 +72,7 @@
functional::deep_copy const deep_copy = {};
- namespace detail
+ namespace detail_
{
#define BOOST_PROTO_DEFINE_DEEP_COPY_TYPE(z, n, data)\
typename deep_copy_impl<typename Expr::BOOST_PP_CAT(proto_arg, n)>::type
Modified: branches/proto/v3/boost/xpressive/proto/domain.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/domain.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/domain.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -19,7 +19,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
struct not_a_generator
{};
@@ -46,7 +46,7 @@
{};
struct deduce_domain
- : domain<detail::not_a_generator, detail::not_a_grammar>
+ : domain<detail_::not_a_generator, detail_::not_a_grammar>
{};
}
Modified: branches/proto/v3/boost/xpressive/proto/expr.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/expr.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/expr.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -65,7 +65,7 @@
proto::unref(this->BOOST_PP_CAT(arg, n))\
/**/
- namespace detail
+ namespace detail_
{
template<typename Tag, typename Arg>
struct address_of_hack
@@ -203,20 +203,20 @@
/// \overload
///
template<typename A0, std::size_t N>
- static expr make(A0 (&a0)[N], typename detail::if_is_array<proto_arg0, N>::type = 0)
+ static expr make(A0 (&a0)[N], typename detail_::if_is_array<proto_arg0, N>::type = 0)
{
expr that;
- detail::checked_copy(a0, that.arg0);
+ detail_::checked_copy(a0, that.arg0);
return that;
}
/// \overload
///
template<typename A0, std::size_t N>
- static expr make(A0 const (&a0)[N], typename detail::if_is_array<proto_arg0, N>::type = 0)
+ static expr make(A0 const (&a0)[N], typename detail_::if_is_array<proto_arg0, N>::type = 0)
{
expr that;
- detail::checked_copy(a0, that.arg0);
+ detail_::checked_copy(a0, that.arg0);
return that;
}
#endif
@@ -225,7 +225,7 @@
/// If \c Tag is \c boost::proto::tag::address_of and \c proto_arg0 is
/// \c proto::ref_\<T\>, then \c address_of_hack_type_ is <tt>T*</tt>.
/// Otherwise, it is some undefined type.
- typedef typename detail::address_of_hack<Tag, proto_arg0>::type address_of_hack_type_;
+ typedef typename detail_::address_of_hack<Tag, proto_arg0>::type address_of_hack_type_;
/// \return The address of <tt>this->arg0</tt> if \c Tag is
/// \c boost::proto::tag::address_of. Otherwise, this function will
Modified: branches/proto/v3/boost/xpressive/proto/fusion.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/fusion.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/fusion.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -40,7 +40,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
template<typename Expr, int Pos>
struct ref_iterator
@@ -48,7 +48,7 @@
{
typedef Expr expr_type;
typedef mpl::long_<Pos> index;
- typedef fusion::forward_traversal_tag category;
+ typedef fusion::random_access_traversal_tag category;
typedef tag::proto_ref_iterator fusion_tag;
ref_iterator(Expr const &expr)
@@ -171,7 +171,7 @@
template<typename Iterator, typename N>
struct apply
{
- typedef typename proto::detail::ref_iterator<
+ typedef typename proto::detail_::ref_iterator<
typename Iterator::expr_type
, Iterator::index::value + N::value
> type;
@@ -253,7 +253,7 @@
template<typename Sequence>
struct apply
{
- typedef proto::detail::ref_iterator<Sequence const, 0> type;
+ typedef proto::detail_::ref_iterator<Sequence const, 0> type;
static type call(Sequence& seq)
{
@@ -271,7 +271,7 @@
template<typename Sequence>
struct apply
{
- typedef proto::detail::ref_iterator<Sequence const, Sequence::proto_arity::value> type;
+ typedef proto::detail_::ref_iterator<Sequence const, Sequence::proto_arity::value> type;
static type call(Sequence& seq)
{
Modified: branches/proto/v3/boost/xpressive/proto/generate.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/generate.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/generate.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -24,7 +24,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
template<typename Domain, typename Expr>
struct generate_if
@@ -67,7 +67,7 @@
typedef Args type;
};
- template<typename Expr, long Arity = detail::arity_<Expr>::value>
+ template<typename Expr, long Arity = detail_::arity_<Expr>::value>
struct by_value_generator_;
#define BOOST_PROTO_DEFINE_BY_VALUE_TYPE(Z, N, Expr)\
@@ -140,14 +140,14 @@
template<typename Expr>
struct apply
: Generator::template apply<
- typename detail::by_value_generator_<Expr>::type
+ typename detail_::by_value_generator_<Expr>::type
>
{};
template<typename Expr>
static typename apply<Expr>::type make(Expr const &expr)
{
- return Generator::make(detail::by_value_generator_<Expr>::make(expr));
+ return Generator::make(detail_::by_value_generator_<Expr>::make(expr));
}
};
}
Modified: branches/proto/v3/boost/xpressive/proto/make_expr.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/make_expr.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/make_expr.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -55,7 +55,7 @@
# include <boost/fusion/sequence/intrinsic/at.hpp>
# include <boost/fusion/sequence/intrinsic/value_at.hpp>
# include <boost/fusion/sequence/intrinsic/size.hpp>
- namespace boost { namespace proto { namespace detail
+ namespace boost { namespace proto { namespace detail_
{
namespace fusion_ = fusion;
}}}
@@ -63,7 +63,7 @@
# include <boost/spirit/fusion/sequence/at.hpp>
# include <boost/spirit/fusion/sequence/value_at.hpp>
# include <boost/spirit/fusion/sequence/size.hpp>
- namespace boost { namespace proto { namespace detail { namespace fusion_
+ namespace boost { namespace proto { namespace detail_ { namespace fusion_
{
namespace result_of = fusion::meta;
template<int N, typename Seq>
@@ -95,14 +95,14 @@
///
# define BOOST_PROTO_AT_TYPE(Z, N, DATA) \
typename remove_reference< \
- typename detail::fusion_::result_of::value_at_c<BOOST_PP_TUPLE_ELEM(2, 0, DATA), N >::type \
+ typename detail_::fusion_::result_of::value_at_c<BOOST_PP_TUPLE_ELEM(2, 0, DATA), N >::type \
>::type \
/**/
/// INTERNAL ONLY
///
# define BOOST_PROTO_AT(Z, N, DATA) \
- detail::fusion_::at_c<N >(BOOST_PP_TUPLE_ELEM(2, 0, DATA)) \
+ detail_::fusion_::at_c<N >(BOOST_PP_TUPLE_ELEM(2, 0, DATA)) \
/**/
/// INTERNAL ONLY
@@ -337,7 +337,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
template<
typename Domain
@@ -434,21 +434,21 @@
{
template<typename Tag, typename Sequence, typename, typename>
struct unpack_expr
- : detail::unpack_expr_<
+ : detail_::unpack_expr_<
Tag
, deduce_domain
, Sequence
- , detail::fusion_::result_of::size<Sequence>::type::value
+ , detail_::fusion_::result_of::size<Sequence>::type::value
>
{};
template<typename Tag, typename Domain, typename Sequence>
struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
- : detail::unpack_expr_<
+ : detail_::unpack_expr_<
Tag
, Domain
, Sequence
- , detail::fusion_::result_of::size<Sequence>::type::value
+ , detail_::fusion_::result_of::size<Sequence>::type::value
>
{};
@@ -477,7 +477,7 @@
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
, typename Domain::proto_is_domain_
>
- : detail::make_expr_<
+ : detail_::make_expr_<
Tag
, Domain
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
@@ -494,9 +494,9 @@
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
, void
>
- : detail::make_expr_<
+ : detail_::make_expr_<
Tag
- , typename detail::deduce_domain_<
+ , typename detail_::deduce_domain_<
typename domain_of<A0>::type
, BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PROTO_MAX_ARITY, A)
>::type
@@ -567,7 +567,7 @@
: result_of::unpack_expr<
Tag
, Domain
- , typename detail::remove_cv_ref<Sequence>::type
+ , typename detail_::remove_cv_ref<Sequence>::type
>
{};
@@ -707,7 +707,7 @@
struct unpack_expr_<Tag, deduce_domain, Sequence, N>
: unpack_expr_<
Tag
- , typename detail::deduce_domain_<
+ , typename detail_::deduce_domain_<
typename domain_of<
BOOST_PROTO_AT_TYPE(~, 0, (Sequence const, ~))
>::type
Modified: branches/proto/v3/boost/xpressive/proto/matches.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/matches.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/matches.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -52,7 +52,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
struct _;
@@ -348,7 +348,7 @@
{
template<typename Expr, typename Grammar>
struct matches
- : detail::matches_impl<typename Expr::proto_base_expr, typename Grammar::proto_base_expr>
+ : detail_::matches_impl<typename Expr::proto_base_expr, typename Grammar::proto_base_expr>
{};
}
@@ -362,7 +362,7 @@
};
template<typename T>
- transform::detail::yes_type is_wildcard_expression_fun(T const *);
+ transform::detail_::yes_type is_wildcard_expression_fun(T const *);
}
namespace control
@@ -371,6 +371,7 @@
template<typename Grammar>
struct not_
: has_identity_transform
+ , transform_base
{
typedef not_ proto_base_expr;
};
@@ -392,6 +393,7 @@
template<typename Condition>
struct if_<Condition, void, void>
: has_identity_transform
+ , transform_base
{
typedef if_ proto_base_expr;
};
@@ -399,13 +401,14 @@
// or_
template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
struct or_
+ : transform_base
{
typedef or_ proto_base_expr;
template<typename Expr, typename State, typename Visitor>
struct apply
{
- typedef typename detail::matches_impl<Expr, or_>::which which;
+ typedef typename detail_::matches_impl<Expr, or_>::which which;
typedef typename which::template apply<Expr, State, Visitor>::type type;
};
@@ -413,7 +416,7 @@
static typename apply<Expr, State, Visitor>::type
call(Expr const &expr, State const &state, Visitor &visitor)
{
- typedef typename detail::matches_impl<Expr, or_>::which which;
+ typedef typename detail_::matches_impl<Expr, or_>::which which;
return which::call(expr, state, visitor);
}
};
@@ -421,13 +424,14 @@
// and_
template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
struct and_
+ : transform_base
{
typedef and_ proto_base_expr;
template<typename Expr, typename State, typename Visitor>
struct apply
{
- typedef typename detail::last<and_>::type which;
+ typedef typename detail_::last<and_>::type which;
typedef typename which::template apply<Expr, State, Visitor>::type type;
};
@@ -435,7 +439,7 @@
static typename apply<Expr, State, Visitor>::type
call(Expr const &expr, State const &state, Visitor &visitor)
{
- typedef typename detail::last<and_>::type which;
+ typedef typename detail_::last<and_>::type which;
return which::call(expr, state, visitor);
}
};
@@ -443,6 +447,7 @@
// switch_
template<typename Cases>
struct switch_
+ : transform_base
{
typedef switch_ proto_base_expr;
@@ -529,7 +534,7 @@
// handle proto::and_
template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
struct matches_impl<Expr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
- : detail::BOOST_PP_CAT(and, N)<
+ : detail_::BOOST_PP_CAT(and, N)<
BOOST_PROTO_DEFINE_MATCHES(~, 0, ~)::value,
BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_MATCHES, ~)
>
Modified: branches/proto/v3/boost/xpressive/proto/operators.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/operators.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/operators.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -24,7 +24,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
struct as_expr_if2
@@ -169,14 +169,14 @@
>
{};
- } // detail
+ } // detail_
#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_0
#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_1 , int
#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, POST) \
template<typename Arg> \
- typename detail::generate_if< \
+ typename detail_::generate_if< \
typename Arg::proto_domain \
, expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > \
>::type const \
@@ -187,7 +187,7 @@
return Arg::proto_domain::make(that); \
} \
template<typename Arg> \
- typename detail::generate_if< \
+ typename detail_::generate_if< \
typename Arg::proto_domain \
, expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > \
>::type const \
@@ -201,28 +201,28 @@
#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG) \
template<typename Left, typename Right> \
- inline typename detail::as_expr_if<TAG, Left, Right>::type const \
+ inline typename detail_::as_expr_if<TAG, Left, Right>::type const \
operator OP(Left &left, Right &right) \
{ \
- return detail::as_expr_if<TAG, Left, Right>::make(left, right); \
+ return detail_::as_expr_if<TAG, Left, Right>::make(left, right); \
} \
template<typename Left, typename Right> \
- inline typename detail::as_expr_if<TAG, Left, Right const>::type const \
+ inline typename detail_::as_expr_if<TAG, Left, Right const>::type const \
operator OP(Left &left, Right const &right) \
{ \
- return detail::as_expr_if<TAG, Left, Right const>::make(left, right); \
+ return detail_::as_expr_if<TAG, Left, Right const>::make(left, right); \
} \
template<typename Left, typename Right> \
- inline typename detail::as_expr_if<TAG, Left const, Right>::type const \
+ inline typename detail_::as_expr_if<TAG, Left const, Right>::type const \
operator OP(Left const &left, Right &right) \
{ \
- return detail::as_expr_if<TAG, Left const, Right>::make(left, right); \
+ return detail_::as_expr_if<TAG, Left const, Right>::make(left, right); \
} \
template<typename Left, typename Right> \
- inline typename detail::as_expr_if<TAG, Left const, Right const>::type const \
+ inline typename detail_::as_expr_if<TAG, Left const, Right const>::type const \
operator OP(Left const &left, Right const &right) \
{ \
- return detail::as_expr_if<TAG, Left const, Right const>::make(left, right); \
+ return detail_::as_expr_if<TAG, Left const, Right const>::make(left, right); \
} \
/**/
@@ -289,7 +289,7 @@
#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, TRAIT, DOMAIN, POST) \
template<typename Arg> \
- typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
+ typename boost::proto::detail_::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg>::type \
>::type const \
operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
@@ -297,7 +297,7 @@
return boost::proto::result_of::make_expr<TAG, DOMAIN, Arg>::call(arg); \
} \
template<typename Arg> \
- typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
+ typename boost::proto::detail_::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const>::type \
>::type const \
operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
@@ -308,7 +308,7 @@
#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG, TRAIT, DOMAIN) \
template<typename Left, typename Right> \
- typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ typename boost::proto::detail_::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right>::type \
>::type const \
operator OP(Left &left, Right &right) \
@@ -317,7 +317,7 @@
::call(left, right); \
} \
template<typename Left, typename Right> \
- typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ typename boost::proto::detail_::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right const>::type \
>::type const \
operator OP(Left &left, Right const &right) \
@@ -326,7 +326,7 @@
::call(left, right); \
} \
template<typename Left, typename Right> \
- typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ typename boost::proto::detail_::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right>::type \
>::type const \
operator OP(Left const &left, Right &right) \
@@ -335,7 +335,7 @@
::call(left, right); \
} \
template<typename Left, typename Right> \
- typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ typename boost::proto::detail_::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
, typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right const>::type \
>::type const \
operator OP(Left const &left, Right const &right) \
Modified: branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -19,6 +19,7 @@
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
#include <boost/mpl/long.hpp>
#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#ifndef BOOST_PROTO_MAX_ARITY
@@ -47,7 +48,7 @@
namespace boost { namespace proto
{
- namespace detail
+ namespace detail_
{
typedef char yes_type;
typedef char (&no_type)[2];
@@ -408,7 +409,54 @@
struct function;
}
- using namespace op;
+ using op::unary_expr;
+ using op::binary_expr;
+ using op::nary_expr;
+ using op::terminal;
+ using op::posit;
+ using op::negate;
+ using op::dereference;
+ using op::complement;
+ using op::address_of;
+ using op::logical_not;
+ using op::pre_inc;
+ using op::pre_dec;
+ using op::post_inc;
+ using op::post_dec;
+ using op::shift_left;
+ using op::shift_right;
+ using op::multiplies;
+ using op::divides;
+ using op::modulus;
+ using op::plus;
+ using op::minus;
+ using op::less;
+ using op::greater;
+ using op::less_equal;
+ using op::greater_equal;
+ using op::equal_to;
+ using op::not_equal_to;
+ using op::logical_or;
+ using op::logical_and;
+ using op::bitwise_and;
+ using op::bitwise_or;
+ using op::bitwise_xor;
+ using op::comma;
+ using op::mem_ptr;
+ using op::assign;
+ using op::shift_left_assign;
+ using op::shift_right_assign;
+ using op::multiplies_assign;
+ using op::divides_assign;
+ using op::modulus_assign;
+ using op::plus_assign;
+ using op::minus_assign;
+ using op::bitwise_and_assign;
+ using op::bitwise_or_assign;
+ using op::bitwise_xor_assign;
+ using op::subscript;
+ using op::if_else_;
+ using op::function;
namespace functional
{
@@ -457,10 +505,10 @@
namespace transform
{
- namespace detail
+ namespace detail_
{
- using proto::detail::yes_type;
- using proto::detail::no_type;
+ using proto::detail_::yes_type;
+ using proto::detail_::no_type;
struct default_factory;
@@ -491,16 +539,16 @@
template<typename Grammar>
struct identity;
- template<typename Grammar, typename Always, typename Factory = detail::default_factory>
+ template<typename Grammar, typename Always, typename Factory = detail_::default_factory>
struct always;
- template<typename Grammar, typename Lambda, typename Factory = detail::default_factory>
+ template<typename Grammar, typename Lambda, typename Factory = detail_::default_factory>
struct apply1;
- template<typename Grammar, typename Lambda, typename Factory = detail::default_factory>
+ template<typename Grammar, typename Lambda, typename Factory = detail_::default_factory>
struct apply2;
- template<typename Grammar, typename Lambda, typename Factory = detail::default_factory>
+ template<typename Grammar, typename Lambda, typename Factory = detail_::default_factory>
struct apply3;
template<typename Grammar, typename State>
@@ -543,6 +591,83 @@
struct pod_construct;
}
+ namespace transform2
+ {
+ namespace detail_
+ {
+ using proto::transform::detail_::no_type;
+ using proto::transform::detail_::yes_type;
+
+ template<typename Transform, typename EnableIf = void>
+ struct as_transform;
+ }
+
+ template<typename Grammar, typename Transform = _>
+ struct case_;
+
+ template<typename Transform = _>
+ struct default_;
+
+ template<typename N = mpl::long_<0>, typename Transform = _>
+ struct arg;
+
+ template<long N, typename Transform = _>
+ struct arg_c;
+
+ template<long N, typename Transform = _>
+ struct _arg_c;
+
+ template<typename Transform = _>
+ struct left;
+
+ template<typename Transform = _>
+ struct right;
+
+ typedef _ _expr;
+ struct _state;
+ struct _visitor;
+ struct _children;
+
+ template<typename Transform, typename Expr = _expr, typename State = _state, typename Visitor = _visitor>
+ struct apply_;
+
+ template<typename Sequence, typename State, typename Fun>
+ struct fold;
+
+ template<typename Sequence, typename State, typename Fun>
+ struct reverse_fold;
+
+ template<typename Sequence>
+ struct pop_front;
+
+ template<typename Grammar, typename State, typename Fun>
+ struct fold_tree;
+
+ template<typename Grammar, typename State, typename Fun>
+ struct reverse_fold_tree;
+
+ //template<typename Grammar, typename Function1>
+ //struct function1;
+
+ //template<typename Grammar, typename Function2>
+ //struct function2;
+
+ //template<typename Grammar, typename Function3>
+ //struct function3;
+
+ //template<typename Grammar>
+ //struct list;
+
+ //template<typename Grammar>
+ //struct tail;
+
+ //template<typename Grammar>
+ //struct pass_through;
+
+ template<typename Grammar, typename ConstructorFun>
+ struct construct;
+ }
+
namespace has_transformns_
{
template<typename Grammar>
@@ -557,6 +682,15 @@
using has_transformns_::has_identity_transform;
using has_transformns_::has_pass_through_transform;
+ namespace transform_basens_
+ {
+ struct transform_base { typedef void proto_is_transform; };
+ struct transform_tag {};
+ }
+
+ using transform_basens_::transform_base;
+ using transform_basens_::transform_tag;
+
template<typename T>
struct is_transform;
Modified: branches/proto/v3/boost/xpressive/proto/ref.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/ref.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/ref.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -134,7 +134,7 @@
template<typename This, typename T>
struct result<This(T)>
- : result_of::unref<typename detail::remove_cv_ref<T>::type>
+ : result_of::unref<typename detail_::remove_cv_ref<T>::type>
{};
template<typename T>
Modified: branches/proto/v3/boost/xpressive/proto/traits.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/traits.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/traits.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -29,6 +29,8 @@
#include <boost/mpl/or.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/eval_if.hpp>
+ #include <boost/mpl/aux_/template_arity.hpp>
+ #include <boost/mpl/aux_/lambda_arity_param.hpp>
#include <boost/static_assert.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/is_array.hpp>
@@ -36,6 +38,7 @@
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/add_reference.hpp>
+ #include <boost/type_traits/is_base_of.hpp>
#include <boost/xpressive/proto/proto_fwd.hpp>
#include <boost/xpressive/proto/ref.hpp>
#include <boost/xpressive/proto/args.hpp>
@@ -56,9 +59,27 @@
namespace boost { namespace proto
{
+ namespace detail_
+ {
+ template<typename T, typename EnableIf = void>
+ struct if_vararg
+ {};
+
+ template<typename T>
+ struct if_vararg<T, typename T::proto_is_vararg_>
+ : T
+ {};
+
+ template<typename T
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<T>::value)>
+ struct is_transform_
+ : is_base_of<transform_base, T>
+ {};
+ }
+
template<typename T>
struct is_transform
- : mpl::false_
+ : detail_::is_transform_<T>
{};
template<>
@@ -66,6 +87,12 @@
: mpl::true_
{};
+ // Work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct is_transform<proto::expr<Tag, Args, N> >
+ : mpl::false_
+ {};
+
namespace result_of
{
// is_ref
@@ -184,18 +211,6 @@
{};
}
- namespace detail
- {
- template<typename T, typename EnableIf = void>
- struct if_vararg
- {};
-
- template<typename T>
- struct if_vararg<T, typename T::proto_is_vararg_>
- : T
- {};
- }
-
namespace op
{
// terminal
@@ -419,7 +434,7 @@
template<typename This, typename Expr>
struct result<This(Expr)>
- : result_of::arg_c<typename detail::remove_cv_ref<Expr>::type, N>
+ : result_of::arg_c<typename detail_::remove_cv_ref<Expr>::type, N>
{};
template<typename Expr>
@@ -443,7 +458,7 @@
template<typename This, typename Expr>
struct result<This(Expr)>
- : result_of::arg<typename detail::remove_cv_ref<Expr>::type, N>
+ : result_of::arg<typename detail_::remove_cv_ref<Expr>::type, N>
{};
template<typename Expr>
@@ -466,7 +481,7 @@
template<typename This, typename Expr>
struct result<This(Expr)>
- : result_of::left<typename detail::remove_cv_ref<Expr>::type>
+ : result_of::left<typename detail_::remove_cv_ref<Expr>::type>
{};
template<typename Expr>
@@ -489,7 +504,7 @@
template<typename This, typename Expr>
struct result<This(Expr)>
- : result_of::right<typename detail::remove_cv_ref<Expr>::type>
+ : result_of::right<typename detail_::remove_cv_ref<Expr>::type>
{};
template<typename Expr>
@@ -665,7 +680,7 @@
typedef type proto_base_expr;
typedef proto::tag::function proto_tag;
BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, A)
- BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT)
+ BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, detail_::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT)
};
template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
@@ -686,11 +701,11 @@
typedef type proto_base_expr;
typedef Tag proto_tag;
BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, A)
- BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT)
+ BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, detail_::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT)
};
} // namespace op
- namespace detail
+ namespace detail_
{
template<BOOST_PP_ENUM_PARAMS(N, typename A)>
struct BOOST_PP_CAT(implicit_expr_, N)
@@ -704,13 +719,21 @@
return that;
}
};
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ >
+ struct is_transform_<T<BOOST_PP_ENUM_PARAMS(N, A)> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)>
+ : is_same<transform_tag, BOOST_PP_CAT(A, BOOST_PP_DEC(N))>
+ {};
}
template<BOOST_PP_ENUM_PARAMS(N, typename A)>
- detail::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)>
+ detail_::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)>
implicit_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a))
{
- detail::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)> that
+ detail_::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)> that
= {BOOST_PP_ENUM_PARAMS(N, a)};
return that;
}
Modified: branches/proto/v3/boost/xpressive/proto/transform/apply.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/transform/apply.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/transform/apply.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -15,7 +15,7 @@
namespace boost { namespace proto { namespace transform
{
- namespace detail
+ namespace detail_
{
struct any
{
Modified: branches/proto/v3/boost/xpressive/proto/transform/construct.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/transform/construct.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/transform/construct.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -27,7 +27,7 @@
namespace boost { namespace proto { namespace transform
{
- namespace detail
+ namespace detail_
{
template<typename T>
struct is_aggregate
@@ -175,7 +175,7 @@
#define N BOOST_PP_ITERATION()
#if N > 0
- namespace detail
+ namespace detail_
{
template<
template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
@@ -197,7 +197,7 @@
{
template<typename Expr, typename State, typename Visitor>
struct apply
- : detail::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
+ : detail_::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
{};
template<typename Expr, typename State, typename Visitor>
@@ -205,7 +205,7 @@
call(Expr const &expr, State const &state, Visitor &visitor)
{
typedef typename apply<Expr, State, Visitor>::type result_type;
- return construct::call_(expr, state, visitor, detail::is_aggregate<result_type>());
+ return construct::call_(expr, state, visitor, detail_::is_aggregate<result_type>());
}
private:
@@ -215,11 +215,11 @@
static typename apply<Expr, State, Visitor>::type
call_(Expr const &expr, State const &state, Visitor &visitor, mpl::true_)
{
- typename Grammar::template apply<Expr, State, Visitor>::type const &expr2
+ typename Grammar::template apply<Expr, State, Visitor>::type expr2
= Grammar::call(expr, state, visitor);
- detail::ignore_unused(expr2);
+ detail_::ignore_unused(expr2);
typename apply<Expr, State, Visitor>::type that = {
- BOOST_PP_ENUM_BINARY_PARAMS(N, detail::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
+ BOOST_PP_ENUM_BINARY_PARAMS(N, detail_::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
};
return that;
}
@@ -230,11 +230,11 @@
static typename apply<Expr, State, Visitor>::type
call_(Expr const &expr, State const &state, Visitor &visitor, mpl::false_)
{
- typename Grammar::template apply<Expr, State, Visitor>::type const &expr2
+ typename Grammar::template apply<Expr, State, Visitor>::type expr2
= Grammar::call(expr, state, visitor);
- detail::ignore_unused(expr2);
+ detail_::ignore_unused(expr2);
return typename apply<Expr, State, Visitor>::type(
- BOOST_PP_ENUM_BINARY_PARAMS(N, detail::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
+ BOOST_PP_ENUM_BINARY_PARAMS(N, detail_::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
);
}
};
@@ -245,18 +245,18 @@
{
template<typename Expr, typename State, typename Visitor>
struct apply
- : detail::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
+ : detail_::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
{};
template<typename Expr, typename State, typename Visitor>
static typename apply<Expr, State, Visitor>::type
call(Expr const &expr, State const &state, Visitor &visitor)
{
- typename Grammar::template apply<Expr, State, Visitor>::type const &expr2
+ typename Grammar::template apply<Expr, State, Visitor>::type expr2
= Grammar::call(expr, state, visitor);
- detail::ignore_unused(expr2);
+ detail_::ignore_unused(expr2);
typename apply<Expr, State, Visitor>::type that = {
- BOOST_PP_ENUM_BINARY_PARAMS(N, detail::as_pod_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
+ BOOST_PP_ENUM_BINARY_PARAMS(N, detail_::as_pod_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
};
return that;
}
Modified: branches/proto/v3/boost/xpressive/proto/transform/fold.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/transform/fold.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/transform/fold.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -26,7 +26,7 @@
namespace boost { namespace proto { namespace transform
{
- namespace detail
+ namespace detail_
{
template<typename Grammar, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
struct fold_impl
@@ -82,7 +82,7 @@
template<typename Expr, typename State, typename Visitor>
struct apply
- : detail::fold_impl<Grammar, Expr, State, Visitor>
+ : detail_::fold_impl<Grammar, Expr, State, Visitor>
{};
template<typename Expr, typename State, typename Visitor>
@@ -103,7 +103,7 @@
template<typename Expr, typename State, typename Visitor>
struct apply
- : detail::reverse_fold_impl<Grammar, Expr, State, Visitor>
+ : detail_::reverse_fold_impl<Grammar, Expr, State, Visitor>
{};
template<typename Expr, typename State, typename Visitor>
Modified: branches/proto/v3/boost/xpressive/proto/transform/fold_tree.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/transform/fold_tree.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/transform/fold_tree.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -17,7 +17,7 @@
namespace boost { namespace proto { namespace transform
{
- namespace detail
+ namespace detail_
{
template<typename Tag, typename Grammar>
struct fold_tree_
@@ -45,7 +45,7 @@
template<typename Tag, typename Grammar, typename State>
struct fold_tree
: transform::fold<
- nary_expr<Tag, vararg<detail::fold_tree_<Tag, Grammar> > >
+ nary_expr<Tag, vararg<detail_::fold_tree_<Tag, Grammar> > >
, State
>
{};
@@ -55,7 +55,7 @@
template<typename Tag, typename Grammar, typename State>
struct reverse_fold_tree
: transform::reverse_fold<
- nary_expr<Tag, vararg<detail::reverse_fold_tree_<Tag, Grammar> > >
+ nary_expr<Tag, vararg<detail_::reverse_fold_tree_<Tag, Grammar> > >
, State
>
{};
Modified: branches/proto/v3/boost/xpressive/proto/transform/pass_through.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/transform/pass_through.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto/transform/pass_through.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -21,7 +21,7 @@
namespace boost { namespace proto { namespace transform
{
- namespace detail
+ namespace detail_
{
template<typename Grammar, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
struct pass_through_impl {};
@@ -52,7 +52,7 @@
return expr;
}
};
- } // namespace detail
+ } // namespace detail_
template<typename Grammar>
struct pass_through
@@ -62,7 +62,7 @@
template<typename Expr, typename State, typename Visitor>
struct apply
- : detail::pass_through_impl<
+ : detail_::pass_through_impl<
Grammar
, typename Expr::proto_base_expr
, State
@@ -94,7 +94,7 @@
template<typename Expr, typename State, typename Visitor>
struct apply
- : transform::detail::pass_through_impl<
+ : transform::detail_::pass_through_impl<
Grammar
, typename Expr::proto_base_expr
, State
Added: branches/proto/v3/boost/xpressive/proto/transform2.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file transform2.hpp
+/// Includes all the transforms in the transform2/ sub-directory.
+//
+// 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_TRANSFORM2_HPP_EAN_06_23_2007
+#define BOOST_PROTO_TRANSFORM2_HPP_EAN_06_23_2007
+
+#include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
+#include <boost/xpressive/proto/transform2/apply.hpp>
+#include <boost/xpressive/proto/transform2/arg.hpp>
+//#include <boost/xpressive/proto/transform2/branch.hpp>
+#include <boost/xpressive/proto/transform2/compose.hpp>
+#include <boost/xpressive/proto/transform2/construct.hpp>
+#include <boost/xpressive/proto/transform2/fold.hpp>
+#include <boost/xpressive/proto/transform2/fold_tree.hpp>
+#include <boost/xpressive/proto/transform2/function.hpp>
+//#include <boost/xpressive/proto/transform2/list.hpp>
+//#include <boost/xpressive/proto/transform2/pass_through.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
+
+namespace boost { namespace proto
+{
+ using transform2::case_;
+ using transform2::default_;
+ using transform2::_expr;
+ using transform2::_state;
+ using transform2::_visitor;
+ using transform2::_arg_c;
+ using transform2::apply_;
+ using transform2::always;
+ using transform2::compose;
+ using transform2::fold;
+ using transform2::reverse_fold;
+ using transform2::fold_tree;
+ using transform2::reverse_fold_tree;
+ using transform2::_children;
+ using transform2::pop_front;
+
+ typedef _arg_c<0> _arg0;
+ typedef _arg_c<1> _arg1;
+ typedef _arg_c<2> _arg2;
+ typedef _arg_c<3> _arg3;
+ typedef _arg0 _arg;
+ typedef _arg0 _left;
+ typedef _arg1 _right;
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/apply.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/apply.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file apply.hpp
+/// Proto transforms for applying other Proto transforms.
+//
+// Copyright 2004 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_TRANSFORM2_APPLY_HPP_EAN_06_23_2007
+#define BOOST_PROTO_TRANSFORM2_APPLY_HPP_EAN_06_23_2007
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+ namespace detail_
+ {
+ template<typename T>
+ T &as_lvalue(T &t)
+ {
+ return t;
+ }
+
+ template<typename T>
+ T const &as_lvalue(T const &t)
+ {
+ return t;
+ }
+ }
+
+ template<typename Transform, typename Expr, typename State, typename Visitor>
+ struct apply_
+ : transform_base
+ {
+ typedef typename detail_::as_transform<Transform>::type transform_type;
+ typedef typename detail_::as_transform<Expr>::type expr_type;
+ typedef typename detail_::as_transform<State>::type state_type;
+ typedef typename detail_::as_transform<Visitor>::type visitor_type;
+
+ template<typename E, typename S, typename V>
+ struct apply
+ : transform_type::template apply<
+ typename expr_type::template apply<E, S, V>::type
+ , typename state_type::template apply<E, S, V>::type
+ , typename visitor_type::template apply<E, S, V>::type
+ >
+ {};
+
+ template<typename E, typename S, typename V>
+ static typename apply<E, S, V>::type
+ call(E const &e, S const &s, V &v)
+ {
+ typedef typename visitor_type::template apply<E, S, V>::type visitor;
+ return transform_type::call(
+ expr_type::call(e, s, v)
+ , state_type::call(e, s, v)
+ , const_cast<visitor &>(detail_::as_lvalue(visitor_type::call(e, s, v)))
+ );
+ }
+ };
+
+ struct ignore { template<typename T> ignore(T const &) {} };
+
+ template<typename T>
+ struct always : proto::transform_base
+ {
+ template<class,class,class> struct apply { typedef T type; };
+ static T call(ignore,ignore,ignore) { return T(); }
+ };
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename Transform, typename Expr, typename State, typename Visitor>
+ struct is_transform<transform2::apply_<Transform, Expr, State, Visitor> >
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct is_transform<transform2::always<T> >
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/arg.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/arg.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,176 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file arg.hpp
+/// Proto transforms for extracting arguments from expressions.
+//
+// Copyright 2004 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_TRANSFORM2_ARG_HPP_EAN_12_16_2006
+#define BOOST_PROTO_TRANSFORM2_ARG_HPP_EAN_12_16_2006
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/traits.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+ // A transform that simply extracts the arg from an expression
+ template<typename N, typename Transform>
+ struct arg
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : proto::result_of::arg<typename Transform::template apply<Expr, State, Visitor>::type, N>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ // NOTE Grammar::call could return a temporary!
+ // Don't return a dangling reference
+ return proto::arg<N>(Transform::call(expr, state, visitor));
+ }
+ };
+
+ // A transform that simply extracts the arg from an expression
+ template<long N, typename Transform>
+ struct arg_c
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : proto::result_of::arg_c<typename Transform::template apply<Expr, State, Visitor>::type, N>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return proto::arg_c<N>(Transform::call(expr, state, visitor));
+ }
+ };
+
+ // A transform that simply extracts the arg from an expression
+ template<long N, typename Transform>
+ struct _arg_c
+ : arg_c<N, Transform>
+ {};
+
+ // A transform that simply extracts the left arg from an expression
+ template<typename Transform>
+ struct left
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : proto::result_of::left<typename Transform::template apply<Expr, State, Visitor>::type>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return proto::left(Transform::call(expr, state, visitor));
+ }
+ };
+
+ // A transform that simply extracts the right arg from an expression
+ template<typename Transform>
+ struct right
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : proto::result_of::right<typename Transform::template apply<Expr, State, Visitor>::type>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return proto::right(Transform::call(expr, state, visitor));
+ }
+ };
+
+ // Just return the state
+ struct _state
+ : transform_base
+ {
+ template<typename, typename State, typename>
+ struct apply
+ {
+ typedef State type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static State const &
+ call(Expr const &, State const &state, Visitor &)
+ {
+ return state;
+ }
+ };
+
+ // Just return the visitor
+ struct _visitor
+ : transform_base
+ {
+ template<typename, typename, typename Visitor>
+ struct apply
+ {
+// BOOST_MPL_ASSERT_RELATION(0,==,sizeof(Visitor));
+ typedef Visitor type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static Visitor &
+ call(Expr const &, State const &, Visitor &visitor)
+ {
+ return visitor;
+ }
+ };
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename N, typename Transform>
+ struct is_transform<transform2::arg<N, Transform> >
+ : mpl::true_
+ {};
+
+ template<long N, typename Transform>
+ struct is_transform<transform2::arg_c<N, Transform> >
+ : mpl::true_
+ {};
+
+ template<long N, typename Transform>
+ struct is_transform<transform2::_arg_c<N, Transform> >
+ : mpl::true_
+ {};
+
+ template<typename Transform>
+ struct is_transform<transform2::left<Transform> >
+ : mpl::true_
+ {};
+
+ template<typename Transform>
+ struct is_transform<transform2::right<Transform> >
+ : mpl::true_
+ {};
+
+ template<>
+ struct is_transform<transform2::_state>
+ : mpl::true_
+ {};
+
+ template<>
+ struct is_transform<transform2::_visitor>
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/branch.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/branch.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file branch.hpp
+/// A special-purpose proto transform for transforming one branch of the expression
+/// tree separately from the rest. Given an expression and a new state, it
+/// transforms the expression using the new state.
+//
+// Copyright 2004 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_TRANSFORM2_BRANCH_HPP_EAN_12_16_2006
+#define BOOST_PROTO_TRANSFORM2_BRANCH_HPP_EAN_12_16_2006
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+
+ // A branch compiler, for compiling a sub-tree with a specified state
+ template<typename Grammar, typename BranchState>
+ struct branch
+ : Grammar, virtual transform_base
+ {
+ branch() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : Grammar::template apply<Expr, BranchState, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &, Visitor &visitor)
+ {
+ return Grammar::call(expr, BranchState(), visitor);
+ }
+ };
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename Grammar, typename BranchState>
+ struct is_transform<transform2::branch<Grammar, BranchState> >
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/compose.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/compose.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file compose.hpp
+/// A special-purpose proto transform for composing two transfomations. Given
+/// two Transforms, expressions are transformed according to the first transform,
+/// and the result is forwarded to the second for further transformation.
+//
+// Copyright 2004 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_TRANSFORM2_COMPOSE_HPP_EAN_04_01_2007
+#define BOOST_PROTO_TRANSFORM2_COMPOSE_HPP_EAN_04_01_2007
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+
+ // Composes two transforms
+ template<typename Transform1, typename Transform2>
+ struct compose
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef typename Transform2::template apply<
+ typename Transform1::template apply<Expr, State, Visitor>::type
+ , State
+ , Visitor
+ >::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Transform2::call(Transform1::call(expr, state, visitor), state, visitor);
+ }
+ };
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename Transform1, typename Transform2>
+ struct is_transform<transform2::compose<Transform1, Transform2> >
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/construct.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/construct.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,301 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file construct.hpp
+ /// For constructing an arbitrary type from a bunch of transforms.
+ //
+ // Copyright 2004 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_TRANSFORM2_CONSTRUCT_HPP_EAN_12_26_2006
+ #define BOOST_PROTO_TRANSFORM2_CONSTRUCT_HPP_EAN_12_26_2006
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/iterate.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/mpl/bool.hpp>
+ #include <boost/type_traits/is_pod.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto { namespace transform2
+ {
+ namespace detail_
+ {
+ template<typename T>
+ struct is_aggregate
+ : is_pod<T>
+ {};
+
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<expr<Tag, Args, N> >
+ : mpl::true_
+ {};
+
+ template<typename T, bool HasType = mpl::aux::has_type<T>::value>
+ struct nested_type
+ {
+ typedef typename T::type type;
+ };
+
+ template<typename T>
+ struct nested_type<T, false>
+ {
+ typedef T type;
+ };
+
+ template<
+ typename OriginalT, typename Expr, typename State, typename Visitor, typename AppliedT
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PROTO_MAX_ARITY, typename A, = no_type BOOST_PP_INTERCEPT)
+ , typename EnableIf = void
+ >
+ struct nested_type_if
+ : nested_type<AppliedT>
+ {
+ typedef yes_type proto_transform_applied;
+ };
+
+ template<
+ typename OriginalT, typename Expr, typename State, typename Visitor, typename AppliedT
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
+ >
+ struct nested_type_if<
+ OriginalT, Expr, State, Visitor, AppliedT
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ , typename AppliedT::proto_is_transform
+ >
+ : OriginalT::template apply<Expr, State, Visitor>
+ {
+ typedef yes_type proto_transform_applied;
+ };
+
+ template<typename OriginalT, typename Expr, typename State, typename Visitor, typename AppliedT>
+ struct nested_type_if<
+ OriginalT, Expr, State, Visitor, AppliedT
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, no_type BOOST_PP_INTERCEPT)
+ , void
+ >
+ {
+ typedef AppliedT type;
+ typedef no_type proto_transform_applied;
+ };
+
+ template<typename Transform, typename EnableIf>
+ struct as_transform
+ {
+ typedef case_<_, typename remove_pointer<Transform>::type> type;
+ };
+
+ template<typename Transform>
+ struct as_transform<Transform, typename Transform::proto_is_transform>
+ {
+ typedef Transform type;
+ };
+
+ template<typename R, typename Expr, typename State, typename Visitor
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)>
+ struct apply_aux_
+ {
+ typedef R type;
+ typedef no_type proto_transform_applied;
+ };
+
+ template<typename R, typename Expr, typename State, typename Visitor, bool IsTransform = is_transform<R>::value>
+ struct apply_
+ : apply_aux_<R, Expr, State, Visitor>
+ {};
+
+ template<typename R, typename Expr, typename State, typename Visitor>
+ struct apply_<R, Expr, State, Visitor, true>
+ : nested_type<typename R::template apply<Expr, State, Visitor>::type>
+ {
+ typedef yes_type proto_transform_applied;
+ };
+
+ // work around GCC bug
+ template<typename Tag, typename Args, long N, typename Expr, typename State, typename Visitor>
+ struct apply_<expr<Tag, Args, N>, Expr, State, Visitor, false>
+ {
+ typedef expr<Tag, Args, N> type;
+ typedef no_type proto_transform_applied;
+ };
+
+ template<typename T>
+ void ignore_unused(T const &)
+ {}
+ }
+
+ template<typename Grammar, typename ConstructorFun>
+ struct construct
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : ConstructorFun::template apply<typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return ConstructorFun::call(Grammar::call(expr, state, visitor), state, visitor);
+ }
+ };
+
+ template<typename Grammar, typename Transform>
+ struct case_
+ : transform_base
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : construct<_, Transform>::template apply<Expr, State, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return construct<_, Transform>::call(expr, state, visitor);
+ }
+ };
+
+ template<typename Grammar, typename Transform>
+ struct case_<Grammar ***, Transform>
+ : transform_base
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : construct<Grammar, Transform>::template apply<Expr, State, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return construct<Grammar, Transform>::call(expr, state, visitor);
+ }
+ };
+
+ template<typename Transform>
+ struct default_
+ : case_<_, Transform>
+ {};
+
+ #define BOOST_PROTO_APPLY_(Z, N, DATA) \
+ typename apply_<BOOST_PP_CAT(DATA, N), Expr, State, Visitor>::type \
+ /**/
+
+ #define BOOST_PROTO_IS_APPLIED_(Z, N, DATA) \
+ typename apply_<BOOST_PP_CAT(DATA, N), Expr, State, Visitor>::proto_transform_applied \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform2/construct.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_APPLY_
+ #undef BOOST_PROTO_IS_APPLIED_
+
+ }}}
+
+ namespace boost { namespace proto
+ {
+ template<typename Grammar, typename ConstructorFun>
+ struct is_transform<transform2::construct<Grammar, ConstructorFun> >
+ : mpl::true_
+ {};
+
+ template<typename Grammar, typename Transform>
+ struct is_transform<transform2::case_<Grammar, Transform> >
+ : mpl::true_
+ {};
+
+ template<typename Transform>
+ struct is_transform<transform2::default_<Transform> >
+ : mpl::true_
+ {};
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ #if N > 0
+ namespace detail_
+ {
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G),
+ typename Expr, typename State, typename Visitor
+ >
+ struct apply_aux_<T<BOOST_PP_ENUM_PARAMS(N, G)>, Expr, State, Visitor BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)>
+ : nested_type_if<
+ T<BOOST_PP_ENUM_PARAMS(N, G)>, Expr, State, Visitor
+ , T<BOOST_PP_ENUM(N, BOOST_PROTO_APPLY_, G)>
+ BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_IS_APPLIED_, G)
+ >
+ {};
+ }
+ #endif
+
+ template<typename Grammar, typename Result BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg)>
+ struct construct<Grammar, Result(BOOST_PP_ENUM_PARAMS(N, Arg))>
+ : transform_base
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : detail_::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ typedef typename apply<Expr, State, Visitor>::type result_type;
+ return construct::call_(expr, state, visitor, detail_::is_aggregate<result_type>());
+ }
+
+ private:
+ /// INTERNAL ONLY
+ ///
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call_(Expr const &expr, State const &state, Visitor &visitor, mpl::true_)
+ {
+ typename Grammar::template apply<Expr, State, Visitor>::type expr2
+ = Grammar::call(expr, state, visitor);
+ detail_::ignore_unused(expr2);
+ typename apply<Expr, State, Visitor>::type that = {
+ BOOST_PP_ENUM_BINARY_PARAMS(N, detail_::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
+ };
+ return that;
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call_(Expr const &expr, State const &state, Visitor &visitor, mpl::false_)
+ {
+ typename Grammar::template apply<Expr, State, Visitor>::type expr2
+ = Grammar::call(expr, state, visitor);
+ detail_::ignore_unused(expr2);
+ return typename apply<Expr, State, Visitor>::type(
+ BOOST_PP_ENUM_BINARY_PARAMS(N, detail_::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
+ );
+ }
+ };
+
+ #undef N
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/fold.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/fold.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,341 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file fold.hpp
+ /// A special-purpose proto transform for merging sequences of binary operations.
+ /// It transforms the right operand and passes the result as state while transforming
+ /// the left. Or, it might do the left first, if you choose.
+ //
+ // Copyright 2004 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_TRANSFORM2_FOLD_HPP_EAN_12_16_2006
+ #define BOOST_PROTO_TRANSFORM2_FOLD_HPP_EAN_12_16_2006
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/preprocessor/arithmetic/sub.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/traits.hpp>
+ #include <boost/xpressive/proto/transform2/branch.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ // BUGBUG
+ #include <boost/xpressive/proto/fusion.hpp>
+ #include <boost/fusion/algorithm/iteration/fold.hpp>
+ #include <boost/fusion/algorithm/transformation/pop_front.hpp>
+ #include <boost/fusion/sequence/view/reverse_view.hpp>
+
+ namespace boost { namespace proto { namespace transform2
+ {
+
+ namespace detail_
+ {
+ template<typename T>
+ struct uncvref
+ : remove_cv<typename remove_reference<T>::type>
+ {};
+
+ template<typename Transform, typename Visitor>
+ struct as_callable
+ {
+ as_callable(Visitor &v)
+ : v_(v)
+ {}
+
+ typedef typename detail_::as_transform<Transform>::type Tfx;
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State>
+ struct result<This(Expr, State)>
+ {
+ typedef typename Tfx::template apply<
+ typename uncvref<Expr>::type
+ , typename uncvref<State>::type
+ , Visitor
+ >::type type;
+ };
+
+ template<typename Expr, typename State>
+ typename Tfx::template apply<Expr, State, Visitor>::type
+ operator()(Expr const &expr, State const &state) const
+ {
+ return Tfx::call(expr, state, this->v_);
+ }
+
+ private:
+ Visitor &v_;
+ };
+
+ template<typename Transform, typename Expr, typename State, typename Visitor,
+ long Arity = Expr::proto_arity::value>
+ struct fold_impl
+ {};
+
+ template<typename Transform, typename Expr, typename State, typename Visitor,
+ long Arity = Expr::proto_arity::value>
+ struct reverse_fold_impl
+ {};
+
+ #define BOOST_PROTO_ARG_N_TYPE(n)\
+ BOOST_PP_CAT(proto_arg, n)\
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE_TYPE(z, n, data) \
+ typedef typename Transform::template \
+ apply< \
+ typename Expr::BOOST_PROTO_ARG_N_TYPE(n)::proto_base_expr \
+ , BOOST_PP_CAT(state, n) \
+ , Visitor \
+ >::type \
+ BOOST_PP_CAT(state, BOOST_PP_INC(n)); \
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE(z, n, data) \
+ BOOST_PP_CAT(state, BOOST_PP_INC(n)) const & \
+ BOOST_PP_CAT(s, BOOST_PP_INC(n)) = Transform::call( \
+ expr.BOOST_PP_CAT(arg, n).proto_base() \
+ , BOOST_PP_CAT(s, n) \
+ , visitor \
+ ); \
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(z, n, data) \
+ typedef typename Transform::template \
+ apply< \
+ typename Expr::BOOST_PROTO_ARG_N_TYPE( \
+ BOOST_PP_SUB(data, BOOST_PP_INC(n)))::proto_base_expr \
+ , BOOST_PP_CAT(state, BOOST_PP_SUB(data, n)) \
+ , Visitor \
+ >::type \
+ BOOST_PP_CAT(state, BOOST_PP_SUB(data, BOOST_PP_INC(n))); \
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE(z, n, data) \
+ BOOST_PP_CAT(state, BOOST_PP_SUB(data, BOOST_PP_INC(n))) const & \
+ BOOST_PP_CAT(s, BOOST_PP_SUB(data, BOOST_PP_INC(n))) = Transform::call( \
+ expr.BOOST_PP_CAT(arg, BOOST_PP_SUB(data, BOOST_PP_INC(n))).proto_base() \
+ , BOOST_PP_CAT(s, BOOST_PP_SUB(data, n)) \
+ , visitor \
+ ); \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform2/fold.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_FOLD_STATE
+ #undef BOOST_PROTO_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_ARG_N_TYPE
+ }
+
+ template<typename Sequence, typename State, typename Fun>
+ struct fold
+ : transform_base
+ {
+ typedef typename detail_::as_transform<Sequence>::type MakeSequence;
+ typedef typename detail_::as_transform<State>::type MakeState;
+
+ template<typename E, typename S, typename V>
+ struct apply
+ : fusion::result_of::fold<
+ typename MakeSequence::template apply<E, S, V>::type
+ , typename MakeState::template apply<E, S, V>::type
+ , detail_::as_callable<Fun, V>
+ >
+ {};
+
+ template<typename E, typename S, typename V>
+ static typename apply<E, S, V>::type
+ call(E const &e, S const &s, V &v)
+ {
+ detail_::as_callable<Fun, V> fun(v);
+ return fusion::fold(
+ MakeSequence::call(e, s, v)
+ , MakeState::call(e, s, v)
+ , fun
+ );
+ }
+ };
+
+ // Compile-time optimization:
+ template<typename State, typename Fun>
+ struct fold<_children, State, Fun>
+ : transform_base
+ {
+ typedef typename detail_::as_transform<State>::type make_state;
+ typedef typename detail_::as_transform<Fun>::type transform_type;
+
+ template<typename E, typename S, typename V>
+ struct apply
+ : detail_::reverse_fold_impl<
+ transform_type
+ , E
+ , typename make_state::template apply<E, S, V>::type
+ , V
+ >
+ {};
+
+ template<typename E, typename S, typename V>
+ static typename apply<E, S, V>::type
+ call(E const &e, S const &s, V &v)
+ {
+ return apply<E, S, V>::call(e, make_state::call(e, s, v), v);
+ }
+ };
+
+ template<typename Sequence, typename State, typename Fun>
+ struct reverse_fold
+ : transform_base
+ {
+ typedef typename detail_::as_transform<Sequence>::type MakeSequence;
+ typedef typename detail_::as_transform<State>::type MakeState;
+
+ template<typename E, typename S, typename V>
+ struct apply
+ : fusion::result_of::fold<
+ fusion::reverse_view<typename MakeSequence::template apply<E, S, V>::type>
+ , typename MakeState::template apply<E, S, V>::type
+ , detail_::as_callable<Fun, V>
+ >
+ {};
+
+ template<typename E, typename S, typename V>
+ static typename apply<E, S, V>::type
+ call(E const &e, S const &s, V &v)
+ {
+ detail_::as_callable<Fun, V> fun(v);
+ typedef typename MakeSequence::template apply<E, S, V>::type Seq;
+ Seq seq = MakeSequence::call(e, s, v);
+ return fusion::fold(
+ fusion::reverse_view<Seq>(seq)
+ , MakeState::call(e, s, v)
+ , fun
+ );
+ }
+ };
+
+ template<typename State, typename Fun>
+ struct reverse_fold<_children, State, Fun>
+ : transform_base
+ {
+ typedef typename detail_::as_transform<State>::type make_state;
+ typedef typename detail_::as_transform<Fun>::type transform_type;
+
+ template<typename E, typename S, typename V>
+ struct apply
+ : detail_::reverse_fold_impl<
+ transform_type
+ , E
+ , typename make_state::template apply<E, S, V>::type
+ , V
+ >
+ {};
+
+ template<typename E, typename S, typename V>
+ static typename apply<E, S, V>::type
+ call(E const &e, S const &s, V &v)
+ {
+ return apply<E, S, V>::call(e, make_state::call(e, s, v), v);
+ }
+ };
+
+ struct _children
+ : transform_base
+ {
+ template<typename E, typename, typename>
+ struct apply
+ {
+ typedef proto::children<E const> type;
+ };
+
+ template<typename E, typename S, typename V>
+ static proto::children<E const> call(E const &e, S const &, V &)
+ {
+ return proto::children_of(e);
+ };
+ };
+
+ template<typename Sequence>
+ struct pop_front
+ : transform_base
+ {
+ template<typename E, typename S, typename V>
+ struct apply
+ : fusion::result_of::pop_front<typename Sequence::template apply<E, S, V>::type const>
+ {};
+
+ template<typename E, typename S, typename V>
+ static typename apply<E, S, V>::type
+ call(E const &e, S const &s, V &v)
+ {
+ return fusion::pop_front(Sequence::call(e, s, v));
+ };
+ };
+
+ }}}
+
+ namespace boost { namespace proto
+ {
+ template<typename Sequence, typename State, typename Fun>
+ struct is_transform<transform2::fold<Sequence, State, Fun> >
+ : mpl::true_
+ {};
+
+ template<typename Sequence, typename State, typename Fun>
+ struct is_transform<transform2::reverse_fold<Sequence, State, Fun> >
+ : mpl::true_
+ {};
+
+ template<>
+ struct is_transform<transform2::_children>
+ : mpl::true_
+ {};
+
+ template<typename Sequence>
+ struct is_transform<transform2::pop_front<Sequence> >
+ : mpl::true_
+ {};
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Transform, typename Expr, typename state0, typename Visitor>
+ struct fold_impl<Transform, Expr, state0, Visitor, N>
+ {
+ BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE_TYPE, N)
+ typedef BOOST_PP_CAT(state, N) type;
+
+ static type call(Expr const &expr, state0 const &s0, Visitor &visitor)
+ {
+ BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE, N)
+ return BOOST_PP_CAT(s, N);
+ }
+ };
+
+ template<typename Transform, typename Expr, typename BOOST_PP_CAT(state, N), typename Visitor>
+ struct reverse_fold_impl<Transform, Expr, BOOST_PP_CAT(state, N), Visitor, N>
+ {
+ BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE_TYPE, N)
+ typedef state0 type;
+
+ static type call(Expr const &expr, BOOST_PP_CAT(state, N) const &BOOST_PP_CAT(s, N), Visitor &visitor)
+ {
+ BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE, N)
+ return s0;
+ }
+ };
+
+ #undef N
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/fold_tree.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/fold_tree.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,64 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fold_tree.hpp
+/// A higher-level transform that uses the fold, and branch transforms
+/// to recursively fold a tree.
+//
+// Copyright 2004 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_TRANSFORM2_FOLD_TREE_HPP_EAN_06_18_2007
+#define BOOST_PROTO_TRANSFORM2_FOLD_TREE_HPP_EAN_06_18_2007
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/xpressive/proto/transform2/construct.hpp>
+#include <boost/xpressive/proto/transform2/fold.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+ namespace detail_
+ {
+ template<typename Grammar, typename Fun>
+ struct fold_tree_
+ : or_<
+ case_< Grammar, fold<_children, _state, fold_tree_<Grammar, Fun> > >
+ , typename as_transform<Fun>::type
+ >
+ {};
+
+ template<typename Grammar, typename Fun>
+ struct reverse_fold_tree_
+ : or_<
+ case_< Grammar, reverse_fold<_children, _state, reverse_fold_tree_<Grammar, Fun> > >
+ , typename as_transform<Fun>::type
+ >
+ {};
+ }
+
+ template<typename Grammar, typename State, typename Fun>
+ struct fold_tree
+ : case_< Grammar, fold<_children, State, detail_::fold_tree_<Grammar, Fun> > >
+ {};
+
+ template<typename Grammar, typename State, typename Fun>
+ struct reverse_fold_tree
+ : case_< Grammar, reverse_fold<_children, State, detail_::reverse_fold_tree_<Grammar, Fun> > >
+ {};
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename Grammar, typename State, typename Fun>
+ struct is_transform<transform2::fold_tree<Grammar, Fun, State> >
+ : mpl::true_
+ {};
+
+ template<typename Grammar, typename State, typename Fun>
+ struct is_transform<transform2::reverse_fold_tree<Grammar, Fun, State> >
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/function.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/function.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,115 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file function.hpp
+/// Proto transforms for applying a function object.
+//
+// Copyright 2004 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_TRANSFORM2_FUNCTION_HPP_EAN_06_23_2007
+#define BOOST_PROTO_TRANSFORM2_FUNCTION_HPP_EAN_06_23_2007
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+
+ // Apply a function object, passing just Expr
+ template<typename Grammar, typename Function1>
+ struct function1
+ : Grammar, virtual transform_base
+ {
+ function1() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : boost::result_of<
+ Function1(
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ )
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Function1()(Grammar::call(expr, state, visitor));
+ }
+ };
+
+ // Apply a function object, passing Expr and State
+ template<typename Grammar, typename Function2>
+ struct function2
+ : Grammar, virtual transform_base
+ {
+ function2() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : boost::result_of<
+ Function2(
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ , State const &
+ )
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Function2()(Grammar::call(expr, state, visitor), state);
+ }
+ };
+
+ // Apply a function object, passing Expr, State and Visitor
+ template<typename Grammar, typename Function3>
+ struct function3
+ : Grammar, virtual transform_base
+ {
+ function3() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : boost::result_of<
+ Function3(
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ , State const &
+ , Visitor &
+ )
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Function3()(Grammar::call(expr, state, visitor), state, visitor);
+ }
+ };
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename Grammar, typename Function1>
+ struct is_transform<transform2::function1<Grammar, Function1> >
+ : mpl::true_
+ {};
+
+ template<typename Grammar, typename Function2>
+ struct is_transform<transform2::function2<Grammar, Function2> >
+ : mpl::true_
+ {};
+
+ template<typename Grammar, typename Function3>
+ struct is_transform<transform2::function3<Grammar, Function3> >
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/list.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/list.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file list.hpp
+/// A special-purpose proto transform for putting things into a
+/// fusion::cons<> list.
+//
+// Copyright 2004 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_TRANSFORM2_LIST_HPP_EAN_12_16_2006
+#define BOOST_PROTO_TRANSFORM2_LIST_HPP_EAN_12_16_2006
+
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/version.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/cons.hpp>
+#else
+# include <boost/fusion/sequence/container/list/cons.hpp>
+#endif
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace transform2
+{
+
+ // A list transform, that puts elements into a fusion cons-list
+ template<typename Grammar>
+ struct list
+ : Grammar, virtual transform_base
+ {
+ list() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef fusion::cons<
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ , State
+ > type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return typename apply<Expr, State, Visitor>::type
+ (Grammar::call(expr, state, visitor), state);
+ }
+ };
+
+ // A tail transform, that returns the tail of a fusion cons-list
+ template<typename Grammar>
+ struct tail
+ : Grammar, virtual transform_base
+ {
+ tail() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef typename Grammar::template apply<Expr, State, Visitor>::type::cdr_type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Grammar::call(expr, state, visitor).cdr;
+ }
+ };
+
+}}}
+
+namespace boost { namespace proto
+{
+ template<typename Grammar>
+ struct is_transform<transform2::list<Grammar> >
+ : mpl::true_
+ {};
+
+ template<typename Grammar>
+ struct is_transform<transform2::tail<Grammar> >
+ : mpl::true_
+ {};
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/transform2/pass_through.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/transform2/pass_through.hpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,156 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file pass_through.hpp
+ /// TODO
+ //
+ // Copyright 2004 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_TRANSFORM2_PASS_THROUGH_HPP_EAN_12_26_2006
+ #define BOOST_PROTO_TRANSFORM2_PASS_THROUGH_HPP_EAN_12_26_2006
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/enum.hpp>
+ #include <boost/preprocessor/iterate.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/args.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto { namespace transform2
+ {
+ namespace detail_
+ {
+ template<typename Grammar, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
+ struct pass_through_impl {};
+
+ #define BOOST_PROTO_DEFINE_TRANSFORM2_TYPE(z, n, data)\
+ typename Grammar::BOOST_PP_CAT(proto_arg, n)\
+ ::template apply<typename Expr::BOOST_PP_CAT(proto_arg, n)::proto_base_expr, State, Visitor>\
+ ::type
+
+ #define BOOST_PROTO_DEFINE_TRANSFORM(z, n, data)\
+ Grammar::BOOST_PP_CAT(proto_arg, n)::call(\
+ expr.BOOST_PP_CAT(arg, n).proto_base(), state, visitor\
+ )
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform2/pass_through.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_DEFINE_TRANSFORM
+ #undef BOOST_PROTO_DEFINE_TRANSFORM2_TYPE
+
+ template<typename Grammar, typename Expr, typename State, typename Visitor>
+ struct pass_through_impl<Grammar, Expr, State, Visitor, 0>
+ {
+ typedef Expr type;
+
+ static Expr const &call(Expr const &expr, State const &, Visitor &)
+ {
+ return expr;
+ }
+ };
+ } // namespace detail_
+
+ template<typename Grammar>
+ struct pass_through
+ : Grammar, virtual transform_base
+ {
+ pass_through() {}
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : detail_::pass_through_impl<
+ Grammar
+ , typename Expr::proto_base_expr
+ , State
+ , Visitor
+ , Expr::proto_arity::value
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
+ }
+ };
+ } // namespace transform2
+
+ template<typename Grammar>
+ struct is_transform<transform2::pass_through<Grammar> >
+ : mpl::true_
+ {};
+
+ //namespace has_transformns_
+ //{
+ // template<typename Grammar>
+ // struct has_pass_through_transform
+ // {
+ // has_pass_through_transform() {}
+
+ // template<typename Expr, typename State, typename Visitor>
+ // struct apply
+ // : transform2::detail_::pass_through_impl<
+ // Grammar
+ // , typename Expr::proto_base_expr
+ // , State
+ // , Visitor
+ // , Expr::proto_arity::value
+ // >
+ // {};
+
+ // template<typename Expr, typename State, typename Visitor>
+ // static typename apply<Expr, State, Visitor>::type
+ // call(Expr const &expr, State const &state, Visitor &visitor)
+ // {
+ // return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
+ // }
+ // };
+
+ //} // namespace has_transformns_
+
+ }} // namespace boost::proto
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Grammar, typename Expr, typename State, typename Visitor>
+ struct pass_through_impl<Grammar, Expr, State, Visitor, N>
+ {
+ typedef expr<
+ typename Expr::proto_tag
+ , BOOST_PP_CAT(args, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM2_TYPE, ~)
+ >
+ > type;
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ template<typename Expr2, typename State2, typename Visitor2>
+ static type call(Expr2 const &expr, State2 const &state, Visitor2 &visitor)
+ #else
+ static type call(Expr const &expr, State const &state, Visitor &visitor)
+ #endif
+ {
+ type that = {
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM, ~)
+ };
+ #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
+ // Without this, MSVC complains that "that" is uninitialized,
+ // and it actually triggers a runtime check in debug mode when
+ // built with VC8.
+ &that;
+ #endif
+ return that;
+ }
+ };
+
+ #undef N
+
+#endif
Modified: branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2
==============================================================================
--- branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2 (original)
+++ branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -22,9 +22,12 @@
[ run proto_fusion_s.cpp ]
[ run toy_spirit.cpp ]
[ run toy_spirit2.cpp ]
+ [ run toy_spirit3.cpp ]
[ run calculator.cpp ]
[ run lambda.cpp ]
+ [ run lambda2.cpp ]
[ run matches.cpp ]
[ run examples.cpp ]
+ [ run examples2.cpp ]
;
Modified: branches/proto/v3/libs/xpressive/proto/test/examples.cpp
==============================================================================
--- branches/proto/v3/libs/xpressive/proto/test/examples.cpp (original)
+++ branches/proto/v3/libs/xpressive/proto/test/examples.cpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
-// matches.hpp
+// examples.hpp
//
// Copyright 2006 Eric Niebler. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
Added: branches/proto/v3/libs/xpressive/proto/test/examples2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto/test/examples2.cpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,317 @@
+///////////////////////////////////////////////////////////////////////////////
+// examples2.hpp
+//
+// Copyright 2006 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)
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform2.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::proto;
+namespace mpl = boost::mpl;
+namespace fusion = boost::fusion;
+
+struct placeholder1 {};
+struct placeholder2 {};
+
+namespace test1
+{
+//[ CalculatorGrammar
+ using namespace boost::proto;
+
+ /*<< A Calculator expression is ... >>*/
+ struct CalculatorGrammar
+ : or_<
+ /*<< placeholder1, or ... >>*/
+ terminal< placeholder1 >
+ /*<< placeholder2, or ... >>*/
+ , terminal< placeholder2 >
+ /*<< some other terminal, or ... >>*/
+ , terminal< _ >
+ /*<< a unary expression where the operand is a calculator expression, or ... >>*/
+ , unary_expr< _, CalculatorGrammar >
+ /*<< a binary expression where the operands are calculator expressions, or ... >>*/
+ , binary_expr< _, CalculatorGrammar, CalculatorGrammar >
+ >
+ {};
+//]
+}
+
+//[ binary_arity
+/*<< The `CalculatorArity` is a transform for calculating
+the arity of a calculator expression. It will be define in
+terms of `binary_arity`, which is defined in terms of
+`CalculatorArity`; hence, the definition is recursive.>>*/
+struct CalculatorArity;
+
+// A custom transform that returns the arity of a unary
+// calculator expression by finding the arity of the
+// child expression.
+struct unary_arity
+ /*<< All custom transforms should inherit from
+ transform_base. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_transform<> trait. >>*/
+ : transform_base
+{
+ template<typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `apply<>` for calculating their return type. >>*/
+ struct apply
+ {
+ /*<< Get the child. >>*/
+ typedef typename result_of::arg<Expr>::type child_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the child. >>*/
+ typedef typename mpl::apply_wrap3<CalculatorArity, child_expr, State, Visitor>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ /*<< Transforms have a nested `call()` member function. >>*/
+ call(Expr const &, State const &, Visitor &)
+ {
+ /*<< The `unary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ return typename apply<Expr, State, Visitor>::type();
+ }
+};
+
+// A custom transform that returns the arity of a binary
+// calculator expression by finding the maximum of the
+// arities of the two children expressions.
+struct binary_arity
+ /*<< All custom transforms should inherit from
+ transform_base. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_transform<> trait. >>*/
+ : transform_base
+{
+ template<typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `apply<>` for calculating their return type. >>*/
+ struct apply
+ {
+ /*<< Get the left and right children. >>*/
+ typedef typename result_of::left<Expr>::type left_expr;
+ typedef typename result_of::right<Expr>::type right_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the left and right children. >>*/
+ typedef typename mpl::apply_wrap3<CalculatorArity, left_expr, State, Visitor>::type left_arity;
+ typedef typename mpl::apply_wrap3<CalculatorArity, right_expr, State, Visitor>::type right_arity;
+
+ /*<< The return type is the maximum of the children's arities. >>*/
+ typedef typename mpl::max<left_arity, right_arity>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ /*<< Transforms have a nested `call()` member function. >>*/
+ call(Expr const &, State const &, Visitor &)
+ {
+ /*<< The `binary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ return typename apply<Expr, State, Visitor>::type();
+ }
+};
+//]
+
+terminal< placeholder1 >::type const _1 = {{}};
+terminal< placeholder2 >::type const _2 = {{}};
+
+//[ CalculatorArityGrammar
+struct CalculatorArity
+ : or_<
+ case_< terminal< placeholder1 >, mpl::int_<1>() >
+ , case_< terminal< placeholder2 >, mpl::int_<2>() >
+ , case_< terminal<_>, mpl::int_<0>() >
+ , case_< unary_expr<_, _>, unary_arity >
+ , case_< binary_expr<_, _, _>, binary_arity >
+ >
+{};
+//]
+
+//[ CalculatorArityGrammar2
+struct CalcArity2
+ : or_<
+ case_< terminal< placeholder1 >, mpl::int_<1>() >
+ , case_< terminal< placeholder2 >, mpl::int_<2>() >
+ , case_< terminal<_>, mpl::int_<0>() >
+ , case_< unary_expr<_, CalcArity2> ***, _arg >
+ , case_< binary_expr<_, CalcArity2, CalcArity2> ***, mpl::max<_left, _right>() >
+ >
+{};
+//]
+
+//[ AsArgList
+// This transform matches function invocations such as foo(1,'a',"b")
+// and transforms them into Fusion cons lists of their arguments. In this
+// case, the result would be cons(1, cons('a', cons("b", nil()))).
+struct ArgsAsList
+ : case_<
+ function<vararg<terminal<_> > >
+ /*<< Use a `reverse_fold<>` transform to iterate over the children
+ of this node in reverse order, building a fusion list from back to
+ front. >>*/
+ , reverse_fold<
+ /*<< The first child expression of a `function<>` node is the
+ function being invoked. We don't want that in our list, so use
+ the `pop_front<>` transform to remove it. >>*/
+ pop_front<_children>
+ /*<< `nil` is the initial state used by the `reverse_fold<>`
+ transform. >>*/
+ , fusion::nil()
+ /*<< Put the rest of the function arguments in a fusion cons
+ list. >>*/
+ , fusion::cons<_arg,_state>(_arg,_state)
+ >
+ >
+{};
+//]
+
+//[ FoldTreeToList
+// This grammar describes what counts as the terminals in expressions
+// of the form (_1=1,'a',"b"), which will be flattened using
+// reverse_fold_tree<> below.
+struct Terminals
+ : or_<
+ case_<assign<_, terminal<_> >, _arg_c<0, _right> >
+ , case_<terminal<_>, _arg >
+ >
+{};
+
+// This transform matches expressions of the form (_1=1,'a',"b")
+// (note the use of the comma operator) and transforms it into a
+// Fusion cons list of their arguments. In this case, the result
+// would be cons(1, cons('a', cons("b", nil()))).
+struct FoldTreeToList
+ /*<< Fold all terminals that are separated by commas into a Fusion cons list. >>*/
+ : reverse_fold_tree<tag::comma, fusion::cons<Terminals,_state>(Terminals,_state), fusion::nil()>
+{};
+//]
+
+//[ Promote
+// This transform finds all float terminals in an expression and promotes
+// them to doubles.
+struct Promote
+ : or_<
+ /*<< Match a `terminal<float>`, then construct a
+ `terminal<double>::type` with the `float`. >>*/
+ case_<terminal<float>, terminal<double>::type(_arg) >
+ , case_<terminal<_> >
+ /*<< `nary_expr<>` has a pass-through transform which
+ will transform each child sub-expression using the
+ `Promote` transform. >>*/
+ , case_<nary_expr<_, vararg<Promote> > ***>
+ >
+{};
+//]
+
+//[ LazyMakePair
+struct make_pair_tag {};
+terminal<make_pair_tag>::type const make_pair_ = {{}};
+
+// This transform matches lazy function invocations like
+// `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
+// from the arguments.
+struct MakePair
+ : case_<
+ /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
+ function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
+ /*<< Return `std::pair<F,S>(f,s)` where `f` and `s` are the
+ first and second arguments to the lazy `make_pair_()` function >>*/
+ , std::pair<_arg_c<0, _arg1>, _arg_c<0, _arg2> >
+ (_arg_c<0, _arg1>, _arg_c<0, _arg2>)
+ >
+{};
+//]
+
+//[ NegateInt
+struct NegateInt
+ : case_<terminal<int>, negate<_>(_)>
+{};
+//]
+
+#ifndef BOOST_MSVC
+//[ SquareAndPromoteInt
+struct SquareAndPromoteInt
+ : case_<
+ terminal<int>
+ , multiplies<terminal<long>::type, terminal<long>::type>::type
+ (terminal<long>::type(_arg), terminal<long>::type(_arg))
+ >
+{};
+//]
+#endif
+
+void test_examples()
+{
+ //[ CalculatorArityTest
+ int i = 0; // not used, dummy state and visitor parameter
+
+ std::cout << CalculatorArity::call( lit(100) * 200, i, i) << '\n';
+ std::cout << CalculatorArity::call( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalculatorArity::call( (_2 - _1) / _2 * 100, i, i) << '\n';
+ //]
+
+ BOOST_CHECK_EQUAL(0, CalculatorArity::call( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalculatorArity::call( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalculatorArity::call( (_2 - _1) / _2 * 100, i, i));
+
+ BOOST_CHECK_EQUAL(0, CalcArity2::call( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalcArity2::call( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalcArity2::call( (_2 - _1) / _2 * 100, i, i));
+
+ using boost::fusion::cons;
+ using boost::fusion::nil;
+ cons<int, cons<char, cons<char const (&)[2]> > > args(ArgsAsList::call( _1(1, 'a', "b"), i, i ));
+ BOOST_CHECK_EQUAL(args.car, 1);
+ BOOST_CHECK_EQUAL(args.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(args.cdr.cdr.car, std::string("b"));
+
+ cons<int, cons<char, cons<char const (&)[2]> > > lst(FoldTreeToList::call( (_1 = 1, 'a', "b"), i, i ));
+ BOOST_CHECK_EQUAL(lst.car, 1);
+ BOOST_CHECK_EQUAL(lst.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(lst.cdr.cdr.car, std::string("b"));
+
+ plus<
+ terminal<double>::type
+ , terminal<double>::type
+ >::type p = Promote::call( lit(1.f) + 2.f, i, i );
+
+ //[ LazyMakePairTest
+ int j = 0; // not used, dummy state and visitor parameter
+
+ std::pair<int, double> p2 = MakePair::call( make_pair_(1, 3.14), j, j );
+
+ std::cout << p2.first << std::endl;
+ std::cout << p2.second << std::endl;
+ //]
+
+ BOOST_CHECK_EQUAL(p2.first, 1);
+ BOOST_CHECK_EQUAL(p2.second, 3.14);
+
+ NegateInt::call(lit(1), i, i);
+#ifndef BOOST_MSVC
+ SquareAndPromoteInt::call(lit(1), i, i);
+#endif
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test examples from the documentation");
+
+ test->add(BOOST_TEST_CASE(&test_examples));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto/test/lambda2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto/test/lambda2.cpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,203 @@
+///////////////////////////////////////////////////////////////////////////////
+// lambda.hpp
+//
+// Copyright 2006 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)
+
+#include <sstream>
+#include <boost/version.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/next_prior.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/at.hpp>
+# include <boost/spirit/fusion/sequence/tuple.hpp>
+namespace boost { namespace fusion { namespace result_of { using namespace meta; }}}
+#else
+# include <boost/fusion/tuple.hpp>
+#endif
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/sstream.hpp>
+#include <boost/typeof/std/ostream.hpp>
+#include <boost/typeof/std/iostream.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+#include <boost/xpressive/proto/transform2.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+
+using namespace boost;
+
+// Forward declaration of the lambda expression wrapper
+template<typename T>
+struct lambda;
+
+struct lambda_domain
+ : proto::domain<proto::pod_generator<lambda> >
+{};
+
+template<typename I>
+struct placeholder
+{
+ typedef I arity;
+};
+
+template<typename T>
+struct placeholder_arity
+{
+ typedef typename T::arity type;
+};
+
+namespace grammar
+{
+ using namespace proto;
+
+ // The lambda grammar, with the transforms for calculating the max arity
+ struct Lambda
+ : or_<
+ case_< terminal< placeholder<_> >, mpl::next<placeholder_arity<_arg> >() >
+ , case_< terminal<_>, mpl::int_<0>() >
+ , case_< nary_expr<_, vararg<_> >, fold<_children, mpl::int_<0>(), mpl::max<Lambda,_state>()> >
+ >
+ {};
+}
+
+// simple wrapper for calculating a lambda expression's arity.
+template<typename Expr>
+struct lambda_arity
+ : grammar::Lambda::apply<Expr, mpl::void_, mpl::void_>
+{};
+
+// The lambda context is the same as the default context
+// with the addition of special handling for lambda placeholders
+template<typename Tuple>
+struct lambda_context
+ : proto::callable_context<lambda_context<Tuple> const>
+{
+ lambda_context(Tuple const &args)
+ : args_(args)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename I>
+ struct result<This(proto::tag::terminal, placeholder<I> const &)>
+ : fusion::result_of::at<Tuple, I>
+ {};
+
+ template<typename I>
+ typename fusion::result_of::at<Tuple, I>::type
+ operator ()(proto::tag::terminal, placeholder<I> const &) const
+ {
+ #if BOOST_VERSION < 103500
+ return fusion::at<I::value>(this->args_);
+ #else
+ return fusion::at<I>(this->args_);
+ #endif
+ }
+
+ Tuple args_;
+};
+
+// The lambda<> expression wrapper makes expressions polymorphic
+// function objects
+template<typename T>
+struct lambda
+{
+ BOOST_PROTO_EXTENDS(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_ASSIGN(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_SUBSCRIPT(T, lambda<T>, lambda_domain)
+
+ // Careful not to evaluate the return type of the nullary function
+ // unless we have a nullary lambda!
+ typedef typename mpl::eval_if<
+ typename lambda_arity<T>::type
+ , mpl::identity<void>
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ >::type nullary_type;
+
+ // Define our operator() that evaluates the lambda expression.
+ nullary_type operator()() const
+ {
+ fusion::tuple<> args;
+ lambda_context<fusion::tuple<> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ operator()(A0 const &a0) const
+ {
+ fusion::tuple<A0 const &> args(a0);
+ lambda_context<fusion::tuple<A0 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0, typename A1>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ operator()(A0 const &a0, A1 const &a1) const
+ {
+ fusion::tuple<A0 const &, A1 const &> args(a0, a1);
+ lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define some lambda placeholders
+lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+
+template<typename T>
+lambda<typename proto::terminal<T>::type> const val(T const &t)
+{
+ lambda<typename proto::terminal<T>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+lambda<typename proto::terminal<T &>::type> const var(T &t)
+{
+ lambda<typename proto::terminal<T &>::type> that = {{t}};
+ return that;
+}
+
+void test_lambda()
+{
+ BOOST_CHECK_EQUAL(11, ( (_1 + 2) / 4 )(42));
+ BOOST_CHECK_EQUAL(-11, ( (-(_1 + 2)) / 4 )(42));
+ BOOST_CHECK_CLOSE(2.58, ( (4 - _2) * 3 )(42, 3.14), 0.1);
+
+ // check non-const ref terminals
+ std::stringstream sout;
+ (sout << _1 << " -- " << _2)(42, "Life, the Universe and Everything!");
+ BOOST_CHECK_EQUAL("42 -- Life, the Universe and Everything!", sout.str());
+
+ // check nullary lambdas
+ BOOST_CHECK_EQUAL(3, (val(1) + val(2))());
+
+ // check array indexing for kicks
+ int integers[5] = {0};
+ (var(integers)[2] = 2)();
+ (var(integers)[_1] = _1)(3);
+ BOOST_CHECK_EQUAL(2, integers[2]);
+ BOOST_CHECK_EQUAL(3, integers[3]);
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test expression template domains");
+
+ test->add(BOOST_TEST_CASE(&test_lambda));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto/test/toy_spirit3.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto/test/toy_spirit3.cpp 2007-08-08 17:49:42 EDT (Wed, 08 Aug 2007)
@@ -0,0 +1,472 @@
+///////////////////////////////////////////////////////////////////////////////
+// toy_spirit3.cpp
+//
+// Copyright 2006 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)
+
+#include <cctype>
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform2.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/algorithm/for_each.hpp>
+# include <boost/spirit/fusion/algorithm/fold.hpp>
+# include <boost/spirit/fusion/algorithm/any.hpp>
+#else
+#include <boost/fusion/algorithm/iteration/for_each.hpp>
+#include <boost/fusion/algorithm/iteration/fold.hpp>
+#include <boost/fusion/algorithm/query/any.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+ // global tags
+ struct char_tag {};
+ struct space_tag {};
+
+ // global primitives
+ proto::terminal<char_tag>::type const char_ = {{}};
+ proto::terminal<space_tag>::type const space = {{}};
+
+ using proto::lit;
+ using proto::literal;
+}
+
+namespace boost { namespace spirit2
+{
+ namespace utility
+ {
+ inline bool char_icmp(char ch, char lo, char hi)
+ {
+ return ch == lo || ch == hi;
+ }
+
+ template<typename FwdIter>
+ inline bool string_cmp(char const *sz, FwdIter &begin, FwdIter end)
+ {
+ FwdIter tmp = begin;
+ for(; *sz; ++tmp, ++sz)
+ if(tmp == end || *tmp != *sz)
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ template<typename FwdIter>
+ inline bool string_icmp(std::string const &str, FwdIter &begin, FwdIter end)
+ {
+ BOOST_ASSERT(0 == str.size() % 2);
+ FwdIter tmp = begin;
+ std::string::const_iterator istr = str.begin(), estr = str.end();
+ for(; istr != estr; ++tmp, istr += 2)
+ if(tmp == end || *tmp != *istr && *tmp != *(istr+1))
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ inline bool in_range(char ch, char lo, char hi)
+ {
+ return ch >= lo && ch <= hi;
+ }
+
+ inline bool in_irange(char ch, char lo, char hi)
+ {
+ return in_range(ch, lo, hi)
+ || in_range(std::tolower(ch), lo, hi)
+ || in_range(std::toupper(ch), lo, hi);
+ }
+
+ inline std::string to_istr(char const *sz)
+ {
+ std::string res;
+ res.reserve(std::strlen(sz) * 2);
+ for(; *sz; ++sz)
+ {
+ res.push_back(std::tolower(*sz));
+ res.push_back(std::toupper(*sz));
+ }
+ return res;
+ }
+ } // namespace utility
+
+ template<typename List>
+ struct alternate
+ {
+ explicit alternate(List const &list)
+ : elems(list)
+ {}
+ List elems;
+ };
+
+ template<typename List>
+ struct sequence
+ {
+ explicit sequence(List const &list)
+ : elems(list)
+ {}
+ List elems;
+ };
+
+ struct char_range
+ : std::pair<char, char>
+ {
+ char_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ struct ichar
+ {
+ ichar(char ch)
+ : lo_(std::tolower(ch))
+ , hi_(std::toupper(ch))
+ {}
+
+ char lo_, hi_;
+ };
+
+ struct istr
+ {
+ istr(char const *sz)
+ : str_(utility::to_istr(sz))
+ {}
+
+ std::string str_;
+ };
+
+ struct ichar_range
+ : std::pair<char, char>
+ {
+ ichar_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ // The no-case directive
+ struct no_case_tag {};
+
+ // remove_case specializations for stripping case-sensitivity from parsers
+ template<typename T, typename CaseSensitive>
+ struct remove_case;
+
+ template<typename T>
+ struct remove_case<T, mpl::false_>
+ {
+ typedef T type;
+ };
+
+ template<>
+ struct remove_case<char, mpl::true_>
+ {
+ typedef ichar type;
+ };
+
+ template<>
+ struct remove_case<char const *, mpl::true_>
+ {
+ typedef istr type;
+ };
+
+ template<>
+ struct remove_case<char_range, mpl::true_>
+ {
+ typedef ichar_range type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// Begin Spirit grammar here
+ ///////////////////////////////////////////////////////////////////////////////
+ namespace grammar
+ {
+ using namespace proto;
+ using namespace fusion;
+
+ struct SpiritExpr;
+
+ struct AnyChar
+ : terminal<char_tag>
+ {};
+
+ struct CharLiteral
+ : terminal<char>
+ {};
+
+ struct NTBSLiteral
+ : terminal<char const *>
+ {};
+
+ struct CharParser
+ : function<AnyChar, CharLiteral>
+ {};
+
+ struct CharRangeParser
+ : function<AnyChar, CharLiteral, CharLiteral>
+ {};
+
+ struct NoCase
+ : terminal<no_case_tag>
+ {};
+
+ // Extract the arg from terminals
+ struct SpiritTerminal
+ : or_<
+ case_< AnyChar, _arg >
+ , case_< CharLiteral, remove_case<char, _visitor>(_arg) >
+ , case_< CharParser, remove_case<char, _visitor>(_arg_c<0, _arg1>)> // char_('a')
+ , case_< NTBSLiteral, remove_case<char const *, _visitor>(_arg) >
+ , case_< CharRangeParser, remove_case<char_range, _visitor>(_arg_c<0, _arg1>, _arg_c<0, _arg2>)> // char_('a','z')
+ >
+ {};
+
+ template<typename Grammar>
+ struct FoldToList
+ : reverse_fold_tree<Grammar, nil(), cons<SpiritExpr, _state>(SpiritExpr, _state)>
+ {};
+
+ struct AltList : FoldToList< bitwise_or<_, _> > {};
+ struct SeqList : FoldToList< shift_right<_, _> > {};
+
+ // sequence rule folds all >>'s together into a list
+ // and wraps the result in a sequence<> wrapper
+ struct SpiritSequence
+ : case_< shift_right<SpiritExpr, SpiritExpr>, sequence<SeqList>(SeqList) >
+ {};
+
+ // alternate rule folds all |'s together into a list
+ // and wraps the result in a alternate<> wrapper
+ struct SpiritAlternate
+ : case_< bitwise_or<SpiritExpr, SpiritExpr>, alternate<AltList>(AltList) >
+ {};
+
+ // Directives such as no_case are handled here
+ struct SpiritDirective
+ : case_< subscript<NoCase, SpiritExpr>, apply_<SpiritExpr, _right, _state, mpl::true_()> >
+ {};
+
+ // A SpiritExpr is an alternate, a sequence, a directive or a terminal
+ struct SpiritExpr
+ : or_<
+ SpiritSequence
+ , SpiritAlternate
+ , SpiritDirective
+ , SpiritTerminal
+ >
+ {};
+
+ } // namespace grammar
+
+ using grammar::SpiritExpr;
+ using grammar::NoCase;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// End SpiritExpr
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Globals
+ NoCase::type const no_case = {{}};
+
+ // Parser
+ template<typename Iterator, typename Derived>
+ struct with_reset
+ {
+ with_reset(Iterator begin, Iterator end)
+ : first(begin), second(end)
+ {}
+
+ template<typename T>
+ bool operator()(T const &t) const
+ {
+ Iterator tmp = this->first;
+ if((*static_cast<Derived const *>(this))(t))
+ return true;
+ this->first = tmp;
+ return false;
+ }
+
+ bool done() const
+ {
+ return this->first == this->second;
+ }
+
+ mutable Iterator first;
+ Iterator second;
+ };
+
+ template<typename Iterator>
+ struct parser
+ : with_reset<Iterator, parser<Iterator> >
+ {
+ typedef with_reset<Iterator, parser<Iterator> > with_reset;
+
+ parser(Iterator begin, Iterator end)
+ : with_reset(begin, end)
+ {}
+
+ #if BOOST_VERSION < 103500
+ template<typename, typename> // used by fusion::fold
+ struct apply
+ {
+ typedef bool type;
+ };
+ #else
+ typedef bool result_type; // used by fusion::fold
+ #endif
+
+ template<typename T>
+ bool operator()(T const &t, bool success) const // used by fusion::fold
+ {
+ return success && (*this)(t);
+ }
+
+ template<typename List>
+ bool operator()(alternate<List> const &alternates) const
+ {
+ return fusion::any(alternates.elems, *static_cast<with_reset const *>(this));
+ }
+
+ template<typename List>
+ bool operator()(sequence<List> const &sequence) const
+ {
+ return fusion::fold(sequence.elems, true, *this);
+ }
+
+ bool operator()(char_tag ch) const
+ {
+ if(this->done())
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(char ch) const
+ {
+ if(this->done() || ch != *this->first)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(ichar ich) const
+ {
+ if(this->done() || !utility::char_icmp(*this->first, ich.lo_, ich.hi_))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(char const *sz) const
+ {
+ return utility::string_cmp(sz, this->first, this->second);
+ }
+
+ bool operator()(istr const &s) const
+ {
+ return utility::string_icmp(s.str_, this->first, this->second);
+ }
+
+ bool operator()(char_range rng) const
+ {
+ if(this->done() || !utility::in_range(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(ichar_range rng) const
+ {
+ if(this->done() || !utility::in_irange(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+ };
+
+ template<typename Rule, typename Iterator>
+ typename enable_if<proto::matches< Rule, SpiritExpr >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ mpl::false_ is_case_sensitive;
+ parser<Iterator> parse_fun(begin, end);
+ return parse_fun(SpiritExpr::call(rule, 0, is_case_sensitive));
+ }
+
+ // 2nd overload provides a short error message for invalid rules
+ template<typename Rule, typename Iterator>
+ typename disable_if<proto::matches< Rule, SpiritExpr >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritExpr>));
+ return false;
+ }
+
+ // parse() converts rule literals to proto expressions if necessary
+ // and dispatches to parse_impl
+ template<typename Rule, typename Iterator>
+ bool parse(Rule const &rule, Iterator begin, Iterator end)
+ {
+ return parse_impl(proto::as_expr(rule), begin, end);
+ }
+
+}}
+
+void test_toy_spirit3()
+{
+ using boost::spirit2::no_case;
+ using boost::char_;
+ std::string hello("abcd");
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ "abcd"
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> char_
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ !boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'D'
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'e'
+ | char_ >> no_case[char_('B') >> "C" >> char_('D','Z')]
+ , hello.begin()
+ , hello.end()
+ )
+ );
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto, grammars and tree transforms");
+
+ test->add(BOOST_TEST_CASE(&test_toy_spirit3));
+
+ return test;
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk