|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r62616 - in trunk: boost/proto boost/proto/detail boost/proto/transform libs/proto/doc libs/proto/doc/reference libs/proto/doc/reference/concepts libs/proto/doc/reference/transform libs/proto/test
From: eric_at_[hidden]
Date: 2010-06-08 20:14:43
Author: eric_niebler
Date: 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
New Revision: 62616
URL: http://svn.boost.org/trac/boost/changeset/62616
Log:
use basic_expr instead of expr when possible for better compile times
Text files modified:
trunk/boost/proto/deep_copy.hpp | 29 ++++--
trunk/boost/proto/detail/expr0.hpp | 125 +++++++++++++++++++++++++++++
trunk/boost/proto/domain.hpp | 49 +++++++++++
trunk/boost/proto/expr.hpp | 18 ++--
trunk/boost/proto/extends.hpp | 80 ++++++++++--------
trunk/boost/proto/fusion.hpp | 6 +
trunk/boost/proto/generate.hpp | 112 +++++++++++++++++---------
trunk/boost/proto/literal.hpp | 2
trunk/boost/proto/make_expr.hpp | 108 ++++++++++--------------
trunk/boost/proto/matches.hpp | 26 +++---
trunk/boost/proto/proto_fwd.hpp | 12 ++
trunk/boost/proto/traits.hpp | 96 ++++++++++++---------
trunk/boost/proto/transform/arg.hpp | 4
trunk/boost/proto/transform/call.hpp | 12 +-
trunk/boost/proto/transform/make.hpp | 60 ++++++++++++-
trunk/boost/proto/transform/pass_through.hpp | 18 ++-
trunk/boost/proto/transform/when.hpp | 10 +-
trunk/libs/proto/doc/glossary.qbk | 6
trunk/libs/proto/doc/proto.qbk | 2
trunk/libs/proto/doc/reference.xml | 20 ++++
trunk/libs/proto/doc/reference/args.xml | 23 +++--
trunk/libs/proto/doc/reference/concepts/Expr.xml | 6
trunk/libs/proto/doc/reference/domain.xml | 63 ++++++++++++++
trunk/libs/proto/doc/reference/expr.xml | 122 ++++++++++++++++++++++++++++
trunk/libs/proto/doc/reference/make_expr.xml | 16 +-
trunk/libs/proto/doc/reference/matches.xml | 16 +-
trunk/libs/proto/doc/reference/traits.xml | 12 +-
trunk/libs/proto/doc/reference/transform/pass_through.xml | 2
trunk/libs/proto/test/make_expr.cpp | 169 ++++++++++++++++++++++++++++++++-------
trunk/libs/proto/test/proto_fusion_s.cpp | 18 ++++
30 files changed, 927 insertions(+), 315 deletions(-)
Modified: trunk/boost/proto/deep_copy.hpp
==============================================================================
--- trunk/boost/proto/deep_copy.hpp (original)
+++ trunk/boost/proto/deep_copy.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -40,14 +40,21 @@
>::type
actual_terminal_type;
- typedef typename terminal<actual_terminal_type>::type expr_type;
+ typedef
+ typename base_expr<
+ typename Expr::proto_domain
+ , tag::terminal
+ , term<actual_terminal_type>
+ >::type
+ expr_;
+
typedef typename Expr::proto_generator proto_generator;
- typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type;
+ typedef typename proto_generator::template result<proto_generator(expr_)>::type result_type;
template<typename Expr2, typename S, typename D>
result_type operator()(Expr2 const &e, S const &, D const &) const
{
- return proto_generator()(expr_type::make(e.proto_base().child0));
+ return proto_generator()(expr_::make(e.proto_base().child0));
}
};
}
@@ -161,7 +168,7 @@
#define BOOST_PROTO_DEFINE_DEEP_COPY_TYPE(Z, N, DATA) \
typename deep_copy_impl< \
typename remove_reference< \
- typename Expr::BOOST_PP_CAT(proto_child, N) \
+ typename Expr::BOOST_PP_CAT(proto_child, N) \
>::type::proto_derived_expr \
>::result_type \
/**/
@@ -189,22 +196,22 @@
struct deep_copy_impl<Expr, N>
{
typedef
- proto::expr<
- typename Expr::proto_tag
+ typename base_expr<
+ typename Expr::proto_domain
+ , typename Expr::proto_tag
, BOOST_PP_CAT(list, N)<
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
>
- , N
- >
- expr_type;
+ >::type
+ expr_;
typedef typename Expr::proto_generator proto_generator;
- typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type;
+ typedef typename proto_generator::template result<proto_generator(expr_)>::type result_type;
template<typename Expr2, typename S, typename D>
result_type operator()(Expr2 const &e, S const &, D const &) const
{
- expr_type const that = {
+ expr_ const that = {
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~)
};
Modified: trunk/boost/proto/detail/expr0.hpp
==============================================================================
--- trunk/boost/proto/detail/expr0.hpp (original)
+++ trunk/boost/proto/detail/expr0.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -12,6 +12,127 @@
#define ARG_COUNT BOOST_PP_MAX(1, BOOST_PP_ITERATION())
+ /// \brief Simplified representation of a node in an expression tree.
+ ///
+ /// \c proto::basic_expr\<\> is a node in an expression template tree. It
+ /// is a container for its child sub-trees. It also serves as
+ /// the terminal nodes of the tree.
+ ///
+ /// \c Tag is type that represents the operation encoded by
+ /// this expression. It is typically one of the structs
+ /// in the \c boost::proto::tag namespace, but it doesn't
+ /// have to be.
+ ///
+ /// \c Args is a type list representing the type of the children
+ /// of this expression. It is an instantiation of one
+ /// of \c proto::list1\<\>, \c proto::list2\<\>, etc. The
+ /// child types must all themselves be either \c expr\<\>
+ /// or <tt>proto::expr\<\>&</tt>. If \c Args is an
+ /// instantiation of \c proto::term\<\> then this
+ /// \c expr\<\> type represents a terminal expression;
+ /// the parameter to the \c proto::term\<\> template
+ /// represents the terminal's value type.
+ ///
+ /// \c Arity is an integral constant representing the number of child
+ /// nodes this node contains. If \c Arity is 0, then this
+ /// node is a terminal.
+ ///
+ /// \c proto::basic_expr\<\> is a valid Fusion random-access sequence, where
+ /// the elements of the sequence are the child expressions.
+ #ifdef BOOST_PROTO_DEFINE_TERMINAL
+ template<typename Tag, typename Arg0>
+ struct basic_expr<Tag, term<Arg0>, 0>
+ #else
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(ARG_COUNT, typename Arg)>
+ struct basic_expr<Tag, BOOST_PP_CAT(list, BOOST_PP_ITERATION())<BOOST_PP_ENUM_PARAMS(ARG_COUNT, Arg)>, BOOST_PP_ITERATION() >
+ #endif
+ {
+ typedef Tag proto_tag;
+ BOOST_STATIC_CONSTANT(long, proto_arity_c = BOOST_PP_ITERATION());
+ typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
+ typedef basic_expr proto_base_expr;
+ #ifdef BOOST_PROTO_DEFINE_TERMINAL
+ typedef term<Arg0> proto_args;
+ #else
+ typedef BOOST_PP_CAT(list, BOOST_PP_ITERATION())<BOOST_PP_ENUM_PARAMS(ARG_COUNT, Arg)> proto_args;
+ #endif
+ typedef basic_expr proto_grammar;
+ typedef default_domain proto_domain;
+ typedef default_generator proto_generator;
+ typedef proto::tag::proto_expr fusion_tag;
+ typedef basic_expr proto_derived_expr;
+ typedef void proto_is_expr_; /**< INTERNAL ONLY */
+
+ BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_CHILD, ~)
+ BOOST_PP_REPEAT_FROM_TO(ARG_COUNT, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_VOID, ~)
+
+ /// \return *this
+ ///
+ basic_expr const &proto_base() const
+ {
+ return *this;
+ }
+
+ /// \overload
+ ///
+ basic_expr &proto_base()
+ {
+ return *this;
+ }
+
+ #ifdef BOOST_PROTO_DEFINE_TERMINAL
+ /// \return A new \c expr\<\> object initialized with the specified
+ /// arguments.
+ ///
+ template<typename A0>
+ static basic_expr const make(A0 &a0)
+ {
+ return detail::make_terminal(a0, static_cast<basic_expr *>(0), static_cast<proto_args *>(0));
+ }
+
+ /// \overload
+ ///
+ template<typename A0>
+ static basic_expr const make(A0 const &a0)
+ {
+ return detail::make_terminal(a0, static_cast<basic_expr *>(0), static_cast<proto_args *>(0));
+ }
+ #else
+ /// \return A new \c expr\<\> object initialized with the specified
+ /// arguments.
+ ///
+ template<BOOST_PP_ENUM_PARAMS(ARG_COUNT, typename A)>
+ static basic_expr const make(BOOST_PP_ENUM_BINARY_PARAMS(ARG_COUNT, A, const &a))
+ {
+ basic_expr that = {BOOST_PP_ENUM_PARAMS(ARG_COUNT, a)};
+ return that;
+ }
+ #endif
+
+ #if 1 == BOOST_PP_ITERATION()
+ /// If \c Tag is \c boost::proto::tag::address_of and \c proto_child0 is
+ /// <tt>T&</tt>, then \c address_of_hack_type_ is <tt>T*</tt>.
+ /// Otherwise, it is some undefined type.
+ typedef typename detail::address_of_hack<Tag, proto_child0>::type address_of_hack_type_;
+
+ /// \return The address of <tt>this->child0</tt> if \c Tag is
+ /// \c boost::proto::tag::address_of. Otherwise, this function will
+ /// fail to compile.
+ ///
+ /// \attention Proto overloads <tt>operator&</tt>, which means that
+ /// proto-ified objects cannot have their addresses taken, unless we use
+ /// the following hack to make \c &x implicitly convertible to \c X*.
+ operator address_of_hack_type_() const
+ {
+ return boost::addressof(this->child0);
+ }
+ #else
+ /// INTERNAL ONLY
+ ///
+ typedef detail::not_a_valid_type address_of_hack_type_;
+ #endif
+ };
+
/// \brief Representation of a node in an expression tree.
///
/// \c proto::expr\<\> is a node in an expression template tree. It
@@ -87,7 +208,7 @@
template<typename A0>
static expr const make(A0 &a0)
{
- return detail::make_terminal(a0, static_cast<expr *>(0));
+ return detail::make_terminal(a0, static_cast<expr *>(0), static_cast<proto_args *>(0));
}
/// \overload
@@ -95,7 +216,7 @@
template<typename A0>
static expr const make(A0 const &a0)
{
- return detail::make_terminal(a0, static_cast<expr *>(0));
+ return detail::make_terminal(a0, static_cast<expr *>(0), static_cast<proto_args *>(0));
}
#else
/// \return A new \c expr\<\> object initialized with the specified
Modified: trunk/boost/proto/domain.hpp
==============================================================================
--- trunk/boost/proto/domain.hpp (original)
+++ trunk/boost/proto/domain.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -11,9 +11,8 @@
#ifndef BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
#define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
-#include <boost/config.hpp>
#include <boost/ref.hpp>
-#include <boost/proto/generate.hpp>
+#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/detail/deduce_domain.hpp>
namespace boost { namespace proto
@@ -173,6 +172,52 @@
{
typedef typename domain_of<T>::type type;
};
+
+ /// \brief Tests a domain to see whether its generator would prefer
+ /// to be passed instances of \c proto::basic_expr\<\> rather than
+ /// \c proto::expr\<\>.
+ ///
+ template<typename Domain, typename Void>
+ struct wants_basic_expr
+ : mpl::false_
+ {};
+
+ template<typename Domain>
+ struct wants_basic_expr<Domain, typename Domain::proto_use_basic_expr_>
+ : mpl::true_
+ {};
+
+ /// \brief Given a domain, a tag type and an argument list,
+ /// compute the type of the expression to generate. This is
+ /// either an instance of \c proto::expr\<\> or
+ /// \c proto::basic_expr\<\>.
+ ///
+ template<typename Domain, typename Tag, typename Args, typename Void>
+ struct base_expr
+ {
+ typedef proto::expr<Tag, Args, Args::arity> type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain, typename Tag, typename Args>
+ struct base_expr<Domain, Tag, Args, typename Domain::proto_use_basic_expr_>
+ {
+ typedef proto::basic_expr<Tag, Args, Args::arity> type;
+ };
+
+ /// \brief Annotate a domain to indicate that its generator would
+ /// prefer to be passed instances of \c proto::basic_expr\<\> rather
+ /// than \c proto::expr\<\>. <tt>use_basic_expr\<Domain\></tt> is
+ /// itself a domain.
+ ///
+ template<typename Domain>
+ struct use_basic_expr
+ : Domain
+ {
+ BOOST_PROTO_USE_BASIC_EXPR()
+ };
+
}}
#endif
Modified: trunk/boost/proto/expr.hpp
==============================================================================
--- trunk/boost/proto/expr.hpp (original)
+++ trunk/boost/proto/expr.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -69,17 +69,17 @@
typedef Expr *type;
};
- template<typename T, typename Tag, typename Arg0>
- proto::expr<Tag, proto::term<Arg0>, 0> make_terminal(T &t, proto::expr<Tag, proto::term<Arg0>, 0> *)
+ template<typename T, typename Expr, typename Arg0>
+ Expr make_terminal(T &t, Expr *, proto::term<Arg0> *)
{
- proto::expr<Tag, proto::term<Arg0>, 0> that = {t};
+ Expr that = {t};
return that;
}
- template<typename T, typename Tag, typename Arg0, std::size_t N>
- proto::expr<Tag, proto::term<Arg0[N]>, 0> make_terminal(T (&t)[N], proto::expr<Tag, proto::term<Arg0[N]>, 0> *)
+ template<typename T, typename Expr, typename Arg0, std::size_t N>
+ Expr make_terminal(T (&t)[N], Expr *, proto::term<Arg0[N]> *)
{
- expr<Tag, proto::term<Arg0[N]>, 0> that;
+ Expr that;
for(std::size_t i = 0; i < N; ++i)
{
that.child0[i] = t[i];
@@ -87,10 +87,10 @@
return that;
}
- template<typename T, typename Tag, typename Arg0, std::size_t N>
- proto::expr<Tag, proto::term<Arg0[N]>, 0> make_terminal(T const(&t)[N], proto::expr<Tag, proto::term<Arg0[N]>, 0> *)
+ template<typename T, typename Expr, typename Arg0, std::size_t N>
+ Expr make_terminal(T const(&t)[N], Expr *, proto::term<Arg0[N]> *)
{
- expr<Tag, proto::term<Arg0[N]>, 0> that;
+ Expr that;
for(std::size_t i = 0; i < N; ++i)
{
that.child0[i] = t[i];
Modified: trunk/boost/proto/extends.hpp
==============================================================================
--- trunk/boost/proto/extends.hpp (original)
+++ trunk/boost/proto/extends.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -204,31 +204,33 @@
BOOST_PROTO_DISABLE_MSVC_C4522 \
Typename() boost::tr1_result_of< \
Typename() This::proto_generator( \
- boost::proto::expr< \
- boost::proto::tag::assign \
+ Typename() boost::proto::base_expr< \
+ Typename() This::proto_domain \
+ , boost::proto::tag::assign \
, boost::proto::list2< \
This & \
, This Const() & \
> \
- , 2 \
- > \
+ >::type \
) \
>::type const \
operator =(This Const() &a) \
{ \
- typedef boost::proto::expr< \
- boost::proto::tag::assign \
- , boost::proto::list2< \
- This & \
- , This Const() & \
- > \
- , 2 \
- > that_type; \
+ typedef \
+ Typename() boost::proto::base_expr< \
+ Typename() This::proto_domain \
+ , boost::proto::tag::assign \
+ , boost::proto::list2< \
+ This & \
+ , This Const() & \
+ > \
+ >::type \
+ that_type; \
that_type const that = { \
*this \
, a \
}; \
- return Typename() This::proto_generator()(that); \
+ return Typename() This::proto_generator()(that); \
} \
/**/
@@ -251,26 +253,28 @@
template<typename A> \
typename boost::tr1_result_of< \
proto_generator( \
- boost::proto::expr< \
- boost::proto::tag::assign \
+ typename boost::proto::base_expr< \
+ proto_domain \
+ , boost::proto::tag::assign \
, boost::proto::list2< \
proto_derived_expr ThisConst() & \
, typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
> \
- , 2 \
- > \
+ >::type \
) \
>::type const \
operator =(A ThatConst() &a) ThisConst() \
{ \
- typedef boost::proto::expr< \
- boost::proto::tag::assign \
- , boost::proto::list2< \
- proto_derived_expr ThisConst() & \
- , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
- > \
- , 2 \
- > that_type; \
+ typedef \
+ typename boost::proto::base_expr< \
+ proto_domain \
+ , boost::proto::tag::assign \
+ , boost::proto::list2< \
+ proto_derived_expr ThisConst() & \
+ , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
+ > \
+ >::type \
+ that_type; \
that_type const that = { \
*static_cast<proto_derived_expr ThisConst() *>(this) \
, boost::proto::as_child<proto_domain>(a) \
@@ -315,26 +319,28 @@
template<typename A> \
typename boost::tr1_result_of< \
proto_generator( \
- boost::proto::expr< \
- boost::proto::tag::subscript \
+ typename boost::proto::base_expr< \
+ proto_domain \
+ , boost::proto::tag::subscript \
, boost::proto::list2< \
proto_derived_expr ThisConst() & \
, typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
> \
- , 2 \
- > \
+ >::type \
) \
>::type const \
operator [](A ThatConst() &a) ThisConst() \
{ \
- typedef boost::proto::expr< \
- boost::proto::tag::subscript \
- , boost::proto::list2< \
- proto_derived_expr ThisConst() & \
- , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
- > \
- , 2 \
- > that_type; \
+ typedef \
+ typename boost::proto::base_expr< \
+ proto_domain \
+ , boost::proto::tag::subscript \
+ , boost::proto::list2< \
+ proto_derived_expr ThisConst() & \
+ , typename boost::proto::result_of::as_child<A ThatConst(), proto_domain>::type \
+ > \
+ >::type \
+ that_type; \
that_type const that = { \
*static_cast<proto_derived_expr ThisConst() *>(this) \
, boost::proto::as_child<proto_domain>(a) \
Modified: trunk/boost/proto/fusion.hpp
==============================================================================
--- trunk/boost/proto/fusion.hpp (original)
+++ trunk/boost/proto/fusion.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -728,6 +728,12 @@
{
typedef fusion::fusion_sequence_tag type;
};
+
+ template<typename Tag, typename Args, long Arity>
+ struct sequence_tag< proto::basic_expr<Tag, Args, Arity> >
+ {
+ typedef fusion::fusion_sequence_tag type;
+ };
}}
#if BOOST_MSVC
Modified: trunk/boost/proto/generate.hpp
==============================================================================
--- trunk/boost/proto/generate.hpp (original)
+++ trunk/boost/proto/generate.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -12,11 +12,14 @@
#define BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
#include <boost/config.hpp>
- #include <boost/utility/result_of.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/utility/enable_if.hpp>
+ #include <boost/utility/result_of.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/args.hpp>
@@ -26,39 +29,38 @@
namespace detail
{
template<typename Expr>
- struct expr_params;
+ struct by_value_generator_;
- template<typename Tag, typename Args, long N>
- struct expr_params<proto::expr<Tag, Args, N> >
+ template<typename Tag, typename Arg>
+ struct by_value_generator_<proto::expr<Tag, term<Arg>, 0> >
{
- typedef Tag tag;
- typedef Args args;
- BOOST_STATIC_CONSTANT(long, arity = N);
- };
-
- template<typename Expr, long Arity = expr_params<Expr>::arity>
- struct by_value_generator_;
+ typedef
+ proto::expr<
+ Tag
+ , term<typename detail::term_traits<Arg>::value_type>
+ , 0
+ >
+ type;
- #define BOOST_PROTO_DEFINE_BY_VALUE_TYPE(Z, N, Expr) \
- typename uncvref<typename expr_params<Expr>::args::BOOST_PP_CAT(child, N)>::type \
- /**/
-
- #define BOOST_PROTO_DEFINE_BY_VALUE(Z, N, expr) \
- expr.BOOST_PP_CAT(child, N) \
- /**/
+ static type const call(proto::expr<Tag, term<Arg>, 0> const &e)
+ {
+ type that = {e.child0};
+ return that;
+ }
+ };
- template<typename Expr>
- struct by_value_generator_<Expr, 0>
+ template<typename Tag, typename Arg>
+ struct by_value_generator_<proto::basic_expr<Tag, term<Arg>, 0> >
{
typedef
- proto::expr<
- typename expr_params<Expr>::tag
- , term<typename detail::term_traits<typename expr_params<Expr>::args::child0>::value_type>
+ proto::basic_expr<
+ Tag
+ , term<typename detail::term_traits<Arg>::value_type>
, 0
>
type;
- static type const make(Expr const &e)
+ static type const call(proto::basic_expr<Tag, term<Arg>, 0> const &e)
{
type that = {e.child0};
return that;
@@ -120,6 +122,7 @@
struct generator
{
BOOST_PROTO_CALLABLE()
+ BOOST_PROTO_USE_BASIC_EXPR()
template<typename Sig>
struct result;
@@ -165,6 +168,7 @@
struct pod_generator
{
BOOST_PROTO_CALLABLE()
+ BOOST_PROTO_USE_BASIC_EXPR()
template<typename Sig>
struct result;
@@ -245,7 +249,7 @@
template<typename Expr>
typename result<by_value_generator(Expr)>::type operator ()(Expr const &e) const
{
- return detail::by_value_generator_<Expr>::make(e);
+ return detail::by_value_generator_<Expr>::call(e);
}
};
@@ -360,25 +364,55 @@
#define N BOOST_PP_ITERATION()
- template<typename Expr>
- struct by_value_generator_<Expr, N>
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg) >
+ struct by_value_generator_<
+ proto::expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>, N>
+ >
{
typedef
- proto::expr<
- typename expr_params<Expr>::tag
- , BOOST_PP_CAT(list, N)<
- // typename uncvref<typename expr_params<Expr>::args::child0>::type, ...
- BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_BY_VALUE_TYPE, Expr)
- >
- , N
+ BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>
+ src_args;
+
+ typedef
+ BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM_BINARY_PARAMS(N, typename uncvref<Arg, >::type BOOST_PP_INTERCEPT)
>
- type;
+ dst_args;
+
+ typedef proto::expr<Tag, src_args, N> src_type;
+ typedef proto::expr<Tag, dst_args, N> type;
+
+ static type const call(src_type const &e)
+ {
+ type that = {
+ BOOST_PP_ENUM_PARAMS(N, e.child)
+ };
+ return that;
+ }
+ };
+
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg) >
+ struct by_value_generator_<
+ proto::basic_expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>, N>
+ >
+ {
+ typedef
+ BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>
+ src_args;
+
+ typedef
+ BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM_BINARY_PARAMS(N, typename uncvref<Arg, >::type BOOST_PP_INTERCEPT)
+ >
+ dst_args;
+
+ typedef proto::basic_expr<Tag, src_args, N> src_type;
+ typedef proto::basic_expr<Tag, dst_args, N> type;
- static type const make(Expr const &e)
+ static type const call(src_type const &e)
{
type that = {
- // expr.child0, ...
- BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_BY_VALUE, e)
+ BOOST_PP_ENUM_PARAMS(N, e.child)
};
return that;
}
Modified: trunk/boost/proto/literal.hpp
==============================================================================
--- trunk/boost/proto/literal.hpp (original)
+++ trunk/boost/proto/literal.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -25,7 +25,7 @@
///
/// A simple wrapper for a terminal, provided for
/// ease of use. In all cases, <tt>literal\<X\> l(x);</tt>
- /// is equivalent to <tt>terminal\<X\>::::type l = {x};</tt>.
+ /// is equivalent to <tt>terminal\<X\>::type l = {x};</tt>.
///
/// The \c Domain template parameter defaults to
/// \c proto::default_domain.
Modified: trunk/boost/proto/make_expr.hpp
==============================================================================
--- trunk/boost/proto/make_expr.hpp (original)
+++ trunk/boost/proto/make_expr.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -155,41 +155,23 @@
{
template<typename T, typename Domain>
struct protoify_
- {
- typedef
- typename boost::unwrap_reference<T>::type
- unref_type;
-
- typedef
- typename mpl::eval_if_c<
- boost::is_reference_wrapper<T>::value
- , proto::result_of::as_child<unref_type, Domain>
- , proto::result_of::as_expr<unref_type, Domain>
- >::type
- type;
-
- static type call(T &t)
- {
- return typename mpl::if_c<
- is_reference_wrapper<T>::value
- , functional::as_child<Domain>
- , functional::as_expr<Domain>
- >::type()(static_cast<unref_type &>(t));
- }
- };
+ : result_of::as_expr<T, Domain>
+ {};
template<typename T, typename Domain>
struct protoify_<T &, Domain>
- {
- typedef
- typename proto::result_of::as_child<T, Domain>::type
- type;
+ : result_of::as_child<T, Domain>
+ {};
- static type call(T &t)
- {
- return functional::as_child<Domain>()(t);
- }
- };
+ template<typename T, typename Domain>
+ struct protoify_<boost::reference_wrapper<T>, Domain>
+ : result_of::as_child<T, Domain>
+ {};
+
+ template<typename T, typename Domain>
+ struct protoify_<boost::reference_wrapper<T> const, Domain>
+ : result_of::as_child<T, Domain>
+ {};
template<typename Tag, typename Domain, typename Sequence, std::size_t Size>
struct unpack_expr_
@@ -273,7 +255,7 @@
///
/// In this specialization, the domain is deduced from the
/// domains of the child types. (If
- /// <tt>is_domain\<A0\>::::value</tt> is \c true, then another
+ /// <tt>is_domain\<A0\>::value</tt> is \c true, then another
/// specialization is selected.)
template<
typename Tag
@@ -283,12 +265,12 @@
>
struct make_expr
{
- /// Same as <tt>result_of::make_expr\<Tag, D, A0, ... AN\>::::type</tt>
+ /// Same as <tt>result_of::make_expr\<Tag, D, A0, ... AN\>::type</tt>
/// where \c D is the deduced domain, which is calculated as follows:
///
/// For each \c x in <tt>[0,N)</tt> (proceeding in order beginning with
- /// <tt>x=0</tt>), if <tt>domain_of\<Ax\>::::type</tt> is not
- /// \c default_domain, then \c D is <tt>domain_of\<Ax\>::::type</tt>.
+ /// <tt>x=0</tt>), if <tt>domain_of\<Ax\>::type</tt> is not
+ /// \c default_domain, then \c D is <tt>domain_of\<Ax\>::type</tt>.
/// Otherwise, \c D is \c default_domain.
typedef
typename detail::make_expr_<
@@ -318,26 +300,26 @@
{
/// If \c Tag is <tt>tag::terminal</tt>, then \c type is a
/// typedef for <tt>boost::result_of\<Domain(expr\<tag::terminal,
- /// term\<A0\> \>)\>::::type</tt>.
+ /// term\<A0\> \>)\>::type</tt>.
///
/// Otherwise, \c type is a typedef for <tt>boost::result_of\<Domain(expr\<Tag,
- /// listN\< as_child\<A0\>::::type, ... as_child\<AN\>::::type\>)
- /// \>::::type</tt>, where \c N is the number of non-void template
- /// arguments, and <tt>as_child\<A\>::::type</tt> is evaluated as
+ /// listN\< as_child\<A0\>::type, ... as_child\<AN\>::type\>)
+ /// \>::type</tt>, where \c N is the number of non-void template
+ /// arguments, and <tt>as_child\<A\>::type</tt> is evaluated as
/// follows:
///
- /// \li If <tt>is_expr\<A\>::::value</tt> is \c true, then the
+ /// \li If <tt>is_expr\<A\>::value</tt> is \c true, then the
/// child type is \c A.
/// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
- /// and <tt>is_expr\<B\>::::value</tt> is \c true, then the
+ /// and <tt>is_expr\<B\>::value</tt> is \c true, then the
/// child type is <tt>B &</tt>.
- /// \li If <tt>is_expr\<A\>::::value</tt> is \c false, then the
+ /// \li If <tt>is_expr\<A\>::value</tt> is \c false, then the
/// child type is <tt>boost::result_of\<Domain(expr\<tag::terminal, term\<A\> \>
- /// )\>::::type</tt>.
+ /// )\>::type</tt>.
/// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
- /// and <tt>is_expr\<B\>::::value</tt> is \c false, then the
+ /// and <tt>is_expr\<B\>::value</tt> is \c false, then the
/// child type is <tt>boost::result_of\<Domain(expr\<tag::terminal, term\<B &\> \>
- /// )\>::::type</tt>.
+ /// )\>::type</tt>.
typedef
typename detail::make_expr_<
Tag
@@ -358,7 +340,7 @@
///
/// In this specialization, the domain is deduced from the
/// domains of the child types. (If
- /// <tt>is_domain\<Sequence>::::value</tt> is \c true, then another
+ /// <tt>is_domain\<Sequence>::value</tt> is \c true, then another
/// specialization is selected.)
template<
typename Tag
@@ -371,8 +353,8 @@
/// Let \c S be the type of a Fusion Random Access Sequence
/// equivalent to \c Sequence. Then \c type is the
/// same as <tt>result_of::make_expr\<Tag,
- /// fusion::result_of::value_at_c\<S, 0\>::::type, ...
- /// fusion::result_of::value_at_c\<S, N-1\>::::type\>::::type</tt>,
+ /// fusion::result_of::value_at_c\<S, 0\>::type, ...
+ /// fusion::result_of::value_at_c\<S, N-1\>::type\>::type</tt>,
/// where \c N is the size of \c S.
typedef
typename detail::unpack_expr_<
@@ -395,8 +377,8 @@
/// Let \c S be the type of a Fusion Random Access Sequence
/// equivalent to \c Sequence. Then \c type is the
/// same as <tt>result_of::make_expr\<Tag, Domain,
- /// fusion::result_of::value_at_c\<S, 0\>::::type, ...
- /// fusion::result_of::value_at_c\<S, N-1\>::::type\>::::type</tt>,
+ /// fusion::result_of::value_at_c\<S, 0\>::type, ...
+ /// fusion::result_of::value_at_c\<S, N-1\>::type\>::type</tt>,
/// where \c N is the size of \c S.
typedef
typename detail::unpack_expr_<
@@ -595,7 +577,7 @@
/// <tt>as_expr\<Domain\>(x)</tt>.
///
/// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
- /// <tt>expr\<Tag, listN\<C0,...CN\> \>::::make(c0,...cN)</tt>
+ /// <tt>expr\<Tag, listN\<C0,...CN\> \>::make(c0,...cN)</tt>
/// where \c Bx is the type of \c bx.
///
/// \return <tt>Domain()(make_\<Tag\>(wrap_(a0),...wrap_(aN)))</tt>.
@@ -655,14 +637,14 @@
/// Let \c s be a Fusion Random Access Sequence equivalent to \c sequence.
/// Let <tt>wrap_\<N\>(s)</tt>, where \c s has type \c S, be defined
/// such that:
- /// \li If <tt>fusion::result_of::value_at_c\<S,N\>::::type</tt> is a reference,
+ /// \li If <tt>fusion::result_of::value_at_c\<S,N\>::type</tt> is a reference,
/// <tt>wrap_\<N\>(s)</tt> is equivalent to
/// <tt>as_child\<Domain\>(fusion::at_c\<N\>(s))</tt>.
/// \li Otherwise, <tt>wrap_\<N\>(s)</tt> is equivalent to
/// <tt>as_expr\<Domain\>(fusion::at_c\<N\>(s))</tt>.
///
/// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
- /// <tt>expr\<Tag, listN\<B0,...BN\> \>::::make(b0,...bN)</tt>
+ /// <tt>expr\<Tag, listN\<B0,...BN\> \>::make(b0,...bN)</tt>
/// where \c Bx is the type of \c bx.
///
/// \param sequence a Fusion Forward Sequence.
@@ -744,12 +726,13 @@
struct make_expr_<Tag, Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
BOOST_PP_ENUM_TRAILING_PARAMS(M, void BOOST_PP_INTERCEPT), void>
{
- typedef proto::expr<
- Tag
- , BOOST_PP_CAT(list, N)<BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD_TYPE, (A, ~, Domain)) >
- , N
- > expr_type;
+ typedef
+ BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD_TYPE, (A, ~, Domain))
+ >
+ proto_args;
+ typedef typename base_expr<Domain, Tag, proto_args>::type expr_type;
typedef typename Domain::proto_generator proto_generator;
typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type;
@@ -777,14 +760,13 @@
{
BOOST_PROTO_FUSION_ITERATORS_TYPE(N)
- typedef proto::expr<
- Tag
- , BOOST_PP_CAT(list, N)<
+ typedef
+ BOOST_PP_CAT(list, N)<
BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE, ~)
>
- , N
- > expr_type;
+ proto_args;
+ typedef typename base_expr<Domain, Tag, proto_args>::type expr_type;
typedef typename Domain::proto_generator proto_generator;
typedef typename proto_generator::template result<proto_generator(expr_type)>::type type;
Modified: trunk/boost/proto/matches.hpp
==============================================================================
--- trunk/boost/proto/matches.hpp (original)
+++ trunk/boost/proto/matches.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -464,9 +464,9 @@
/// \li An expression \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
/// matches all \c Bx for \c x in <tt>[0,n)</tt>.
/// \li An expression \c E matches <tt>if_\<T,U,V\></tt> if
- /// <tt>boost::result_of\<when\<_,T\>(E,int,int)\>::::type::value</tt>
+ /// <tt>boost::result_of\<when\<_,T\>(E,int,int)\>::type::value</tt>
/// is \c true and \c E matches \c U; or, if
- /// <tt>boost::result_of\<when\<_,T\>(E,int,int)\>::::type::value</tt>
+ /// <tt>boost::result_of\<when\<_,T\>(E,int,int)\>::type::value</tt>
/// is \c false and \c E matches \c V. (Note: \c U defaults to \c _
/// and \c V defaults to \c not_\<_\>.)
/// \li An expression \c E matches <tt>not_\<T\></tt> if \c E does
@@ -484,7 +484,7 @@
/// \li \c A is <tt>B const &</tt>
/// \li \c B is <tt>exact\<A\></tt>
/// \li \c B is <tt>convertible_to\<X\></tt> and
- /// <tt>is_convertible\<A,X\>::::value</tt> is \c true.
+ /// <tt>is_convertible\<A,X\>::value</tt> is \c true.
/// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
/// \c B is <tt>X[proto::N]</tt>.
/// \li \c A is <tt>X(&)[M]</tt> and \c B is <tt>X(&)[proto::N]</tt>.
@@ -522,7 +522,7 @@
/// and a transform that returns the current expression unchanged.
///
/// The wildcard type, \c _, is a grammar element such that
- /// <tt>matches\<E,_\>::::value</tt> is \c true for any expression
+ /// <tt>matches\<E,_\>::value</tt> is \c true for any expression
/// type \c E.
///
/// The wildcard can also be used as a stand-in for a template
@@ -617,7 +617,7 @@
typedef Expr result_type;
/// \param e An expression
- /// \pre <tt>matches\<Expr,not_\>::::value</tt> is \c true.
+ /// \pre <tt>matches\<Expr,not_\>::value</tt> is \c true.
/// \return \c e
#ifdef BOOST_PROTO_STRICT_RESULT_OF
result_type
@@ -642,15 +642,15 @@
/// When <tt>if_\<If,Then,Else\></tt> is used as a grammar, \c If
/// must be a Proto transform and \c Then and \c Else must be grammars.
/// An expression type \c E matches <tt>if_\<If,Then,Else\></tt> if
- /// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::::type::value</tt>
+ /// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::type::value</tt>
/// is \c true and \c E matches \c U; or, if
- /// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::::type::value</tt>
+ /// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::type::value</tt>
/// is \c false and \c E matches \c V.
///
/// The template parameter \c Then defaults to \c _
/// and \c Else defaults to \c not\<_\>, so an expression type \c E
/// will match <tt>if_\<If\></tt> if and only if
- /// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::::type::value</tt>
+ /// <tt>boost::result_of\<when\<_,If\>(E,int,int)\>::type::value</tt>
/// is \c true.
///
/// \code
@@ -667,7 +667,7 @@
/// When <tt>if_\<If,Then,Else\></tt> is used as a transform, \c If,
/// \c Then and \c Else must be Proto transforms. When applying
/// the transform to an expression \c E, state \c S and data \c V,
- /// if <tt>boost::result_of\<when\<_,If\>(E,S,V)\>::::type::value</tt>
+ /// if <tt>boost::result_of\<when\<_,If\>(E,S,V)\>::type::value</tt>
/// is \c true then the \c Then transform is applied; otherwise
/// the \c Else transform is applied.
///
@@ -737,7 +737,7 @@
/// When applying <tt>or_\<B0,B1,...Bn\></tt> as a transform with an
/// expression \c e of type \c E, state \c s and data \c d, it is
/// equivalent to <tt>Bx()(e, s, d)</tt>, where \c x is the lowest
- /// number such that <tt>matches\<E,Bx\>::::value</tt> is \c true.
+ /// number such that <tt>matches\<E,Bx\>::value</tt> is \c true.
template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
struct or_ : transform<or_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
{
@@ -746,7 +746,7 @@
/// \param e An expression
/// \param s The current state
/// \param d A data of arbitrary type
- /// \pre <tt>matches\<Expr,or_\>::::value</tt> is \c true.
+ /// \pre <tt>matches\<Expr,or_\>::value</tt> is \c true.
/// \return <tt>which()(e, s, d)</tt>, where <tt>which</tt> is the
/// sub-grammar that matched <tt>Expr</tt>.
@@ -808,7 +808,7 @@
/// \param e An expression
/// \param s The current state
/// \param d A data of arbitrary type
- /// \pre <tt>matches\<Expr,switch_\>::::value</tt> is \c true.
+ /// \pre <tt>matches\<Expr,switch_\>::value</tt> is \c true.
/// \return <tt>which()(e, s, d)</tt>, where <tt>which</tt> is
/// <tt>Cases::case_<typename Expr::proto_tag></tt>
@@ -827,7 +827,7 @@
///
/// By default, matching terminals ignores references and
/// cv-qualifiers. For instance, a terminal expression of
- /// type <tt>terminal\<int const &\>::::type</tt> will match
+ /// type <tt>terminal\<int const &\>::type</tt> will match
/// the grammar <tt>terminal\<int\></tt>. If that is not
/// desired, you can force an exact match with
/// <tt>terminal\<exact\<int\> \></tt>. This will only
Modified: trunk/boost/proto/proto_fwd.hpp
==============================================================================
--- trunk/boost/proto/proto_fwd.hpp (original)
+++ trunk/boost/proto/proto_fwd.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -272,10 +272,19 @@
struct deduce_domain;
+ template<typename Domain, typename Void = void>
+ struct wants_basic_expr;
+
+ template<typename Domain, typename Tag, typename Args, typename Void = void>
+ struct base_expr;
+
+ template<typename Domain>
+ struct use_basic_expr;
+
////////////////////////////////////////////////////////////////////////////////////////////////
namespace exprns_
{
- template<typename Tag, typename Args, long Arity>
+ template<typename Tag, typename Args, long Arity = Args::arity>
struct basic_expr;
template<typename Tag, typename Args, long Arity = Args::arity>
@@ -646,6 +655,7 @@
#define BOOST_PROTO_UNEXPR() typedef int proto_is_expr_;
#define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
#define BOOST_PROTO_AGGREGATE() typedef void proto_is_aggregate_;
+ #define BOOST_PROTO_USE_BASIC_EXPR() typedef void proto_use_basic_expr_;
struct callable
{
Modified: trunk/boost/proto/traits.hpp
==============================================================================
--- trunk/boost/proto/traits.hpp (original)
+++ trunk/boost/proto/traits.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -41,6 +41,7 @@
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/args.hpp>
#include <boost/proto/tags.hpp>
+ #include <boost/proto/generate.hpp>
#include <boost/proto/transform/pass_through.hpp>
#if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
@@ -84,19 +85,19 @@
/// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
/// callable transform or an object transform. (The former are evaluated
/// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
- /// <tt>is_callable\<R\>::::value</tt> is \c true, the function type is
+ /// <tt>is_callable\<R\>::value</tt> is \c true, the function type is
/// a callable transform; otherwise, it is an object transform.
///
- /// Unless specialized for a type \c T, <tt>is_callable\<T\>::::value</tt>
+ /// Unless specialized for a type \c T, <tt>is_callable\<T\>::value</tt>
/// is computed as follows:
///
/// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
- /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::::value</tt>
- /// is <tt>is_same\<YN, proto::callable\>::::value</tt>.
+ /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::value</tt>
+ /// is <tt>is_same\<YN, proto::callable\>::value</tt>.
/// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
- /// for \c void, <tt>is_callable\<T\>::::value</tt> is \c true. (Note: this is
+ /// for \c void, <tt>is_callable\<T\>::value</tt> is \c true. (Note: this is
/// the case for any type that derives from \c proto::callable.)
- /// \li Otherwise, <tt>is_callable\<T\>::::value</tt> is \c false.
+ /// \li Otherwise, <tt>is_callable\<T\>::value</tt> is \c false.
template<typename T>
struct is_callable
: proto::detail::is_callable_<T>
@@ -122,6 +123,12 @@
struct is_callable<proto::expr<Tag, Args, N> >
: mpl::false_
{};
+
+ // work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct is_callable<proto::basic_expr<Tag, Args, N> >
+ : mpl::false_
+ {};
#endif
/// \brief A Boolean metafunction that indicates whether a type requires
@@ -130,7 +137,7 @@
/// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
/// to determine how to construct an object of some type \c T, given some
/// initialization arguments <tt>a0,a1,...aN</tt>.
- /// If <tt>is_aggregate\<T\>::::value</tt> is \c true, then an object of
+ /// If <tt>is_aggregate\<T\>::value</tt> is \c true, then an object of
/// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
/// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
template<typename T, typename Void>
@@ -145,6 +152,11 @@
: mpl::true_
{};
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<proto::basic_expr<Tag, Args, N>, void>
+ : mpl::true_
+ {};
+
/// INTERNAL ONLY
template<typename T>
struct is_aggregate<T, typename T::proto_is_aggregate_>
@@ -166,11 +178,11 @@
/// type \c T is a Proto expression type.
///
/// If \c T has a nested type \c proto_is_expr_ that is a typedef
- /// for \c void, <tt>is_expr\<T\>::::value</tt> is \c true. (Note, this
+ /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
/// is the case for <tt>proto::expr\<\></tt>, any type that is derived
/// from <tt>proto::extends\<\></tt> or that uses the
/// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
- /// <tt>is_expr\<T\>::::value</tt> is \c false.
+ /// <tt>is_expr\<T\>::value</tt> is \c false.
template<typename T, typename Void /* = void*/>
struct is_expr
: mpl::false_
@@ -180,11 +192,11 @@
/// type \c T is a Proto expression type.
///
/// If \c T has a nested type \c proto_is_expr_ that is a typedef
- /// for \c void, <tt>is_expr\<T\>::::value</tt> is \c true. (Note, this
+ /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
/// is the case for <tt>proto::expr\<\></tt>, any type that is derived
/// from <tt>proto::extends\<\></tt> or that uses the
/// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
- /// <tt>is_expr\<T\>::::value</tt> is \c false.
+ /// <tt>is_expr\<T\>::value</tt> is \c false.
template<typename T>
struct is_expr<T, typename T::proto_is_expr_>
: mpl::true_
@@ -235,8 +247,8 @@
///
/// If \c T is a function type, let \c A be <tt>T &</tt>.
/// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
- /// Then, the result type <tt>as_expr\<T, Domain\>::::type</tt> is
- /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<A\> \>)\>::::type</tt>.
+ /// Then, the result type <tt>as_expr\<T, Domain\>::type</tt> is
+ /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<A\> \>)\>::type</tt>.
template<
typename T
, typename Domain // = default_domain
@@ -254,7 +266,7 @@
, remove_cv<T>
>::type
arg0_;
- typedef proto::expr<proto::tag::terminal, term<arg0_>, 0> expr_;
+ typedef typename base_expr<Domain, proto::tag::terminal, term<arg0_> >::type expr_;
typedef typename Domain::proto_generator proto_generator;
typedef typename proto_generator::template result<Domain(expr_)>::type type;
typedef type const reference;
@@ -264,7 +276,7 @@
template<typename T2>
static reference call(T2 &t)
{
- return proto_generator()(expr_::make(t));
+ return proto_generator()(expr_::make(static_cast<T &>(t)));
}
};
@@ -276,7 +288,7 @@
/// possible. Types which are already Proto types are left alone.
///
/// This specialization is selected when the type is already a Proto type.
- /// The result type <tt>as_expr\<T, Domain\>::::type</tt> is \c T stripped
+ /// The result type <tt>as_expr\<T, Domain\>::type</tt> is \c T stripped
/// of cv-qualifiers.
template<typename T, typename Domain>
struct as_expr<
@@ -298,7 +310,7 @@
template<typename T2>
static reference call(T2 &t)
{
- return proto_generator()(t);
+ return proto_generator()(static_cast<T &>(t));
}
};
@@ -318,7 +330,7 @@
/// INTERNAL ONLY
///
template<typename T2>
- static T2 &call(T2 &t)
+ static reference call(T2 &t)
{
return t;
}
@@ -332,8 +344,8 @@
/// Types which are already Proto types are returned by reference.
///
/// This specialization is selected when the type is not yet a Proto type.
- /// The result type <tt>as_child\<T, Domain\>::::type</tt> is
- /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<T &\> \>)\>::::type</tt>.
+ /// The result type <tt>as_child\<T, Domain\>::type</tt> is
+ /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<T &\> \>)\>::type</tt>.
template<
typename T
, typename Domain // = default_domain
@@ -344,7 +356,7 @@
>
struct as_child
{
- typedef proto::expr<proto::tag::terminal, term<T &>, 0> expr_;
+ typedef typename base_expr<Domain, proto::tag::terminal, term<T &> >::type expr_;
typedef typename Domain::proto_generator proto_generator;
typedef typename proto_generator::template result<proto_generator(expr_)>::type type;
@@ -353,7 +365,7 @@
template<typename T2>
static type call(T2 &t)
{
- return proto_generator()(expr_::make(t));
+ return proto_generator()(expr_::make(static_cast<T &>(t)));
}
};
@@ -365,7 +377,7 @@
/// Types which are already Proto types are returned by reference.
///
/// This specialization is selected when the type is already a Proto type.
- /// The result type <tt>as_child\<T, Domain\>::::type</tt> is
+ /// The result type <tt>as_child\<T, Domain\>::type</tt> is
/// <tt>T &</tt>.
template<typename T, typename Domain>
struct as_child<
@@ -397,7 +409,7 @@
template<typename T2>
static type call(T2 &t)
{
- return proto_generator()(t);
+ return proto_generator()(static_cast<T &>(t));
}
};
@@ -409,7 +421,7 @@
/// Types which are already Proto types are returned by reference.
///
/// This specialization is selected when the type is already a Proto type.
- /// The result type <tt>as_child\<T, Domain\>::::type</tt> is
+ /// The result type <tt>as_child\<T, Domain\>::type</tt> is
/// <tt>T &</tt>.
template<typename T>
struct as_child<
@@ -426,9 +438,9 @@
/// INTERNAL ONLY
///
template<typename T2>
- static T2 &call(T2 &t)
+ static type call(T2 &t)
{
- return t;
+ return static_cast<T &>(t);
}
};
@@ -544,7 +556,7 @@
typedef Expr result_type;
/// \param e The current expression
- /// \pre <tt>matches\<Expr, terminal\<T\> \>::::value</tt> is \c true.
+ /// \pre <tt>matches\<Expr, terminal\<T\> \>::value</tt> is \c true.
/// \return \c e
/// \throw nothrow
#ifdef BOOST_PROTO_STRICT_RESULT_OF
@@ -614,7 +626,7 @@
typedef Expr result_type;
/// \param e The current expression
- /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::::value</tt> is \c true.
+ /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::value</tt> is \c true.
/// \return \c e
/// \throw nothrow
#ifdef BOOST_PROTO_STRICT_RESULT_OF
@@ -906,7 +918,7 @@
/// \brief Return the Nth child of the given expression.
/// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
/// \pre <tt>N \< Expr::proto_arity::value</tt>
/// \return <tt>proto::child_c\<N\>(expr)</tt>
/// \throw nothrow
@@ -949,7 +961,7 @@
/// \brief Return the Nth child of the given expression.
/// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
/// \pre <tt>N::value \< Expr::proto_arity::value</tt>
/// \return <tt>proto::child\<N\>(expr)</tt>
/// \throw nothrow
@@ -987,7 +999,7 @@
/// \brief Return the value of the given terminal expression.
/// \param expr The terminal expression node.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
/// \pre <tt>0 == Expr::proto_arity::value</tt>
/// \return <tt>proto::value(expr)</tt>
/// \throw nothrow
@@ -1025,7 +1037,7 @@
/// \brief Return the left child of the given binary expression.
/// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
/// \pre <tt>2 == Expr::proto_arity::value</tt>
/// \return <tt>proto::left(expr)</tt>
/// \throw nothrow
@@ -1063,7 +1075,7 @@
/// \brief Return the right child of the given binary expression.
/// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
/// \pre <tt>2 == Expr::proto_arity::value</tt>
/// \return <tt>proto::right(expr)</tt>
/// \throw nothrow
@@ -1097,12 +1109,12 @@
/// without (i.e., <tt>as_expr(t)</tt>). If no domain is
/// specified, \c default_domain is assumed.
///
- /// If <tt>is_expr\<T\>::::value</tt> is \c true, then the argument is
+ /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
/// returned unmodified, by reference. Otherwise, the argument is wrapped
/// in a Proto terminal expression node according to the following rules.
/// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let
/// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr()
- /// returns <tt>Domain()(terminal\<A\>::::type::make(t))</tt>.
+ /// returns <tt>Domain()(terminal\<A\>::type::make(t))</tt>.
///
/// \param t The object to wrap.
template<typename T>
@@ -1153,9 +1165,9 @@
/// without (i.e., <tt>as_child(t)</tt>). If no domain is
/// specified, \c default_domain is assumed.
///
- /// If <tt>is_expr\<T\>::::value</tt> is \c true, then the argument is
+ /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
/// returned as-is. Otherwise, \c as_child() returns
- /// <tt>Domain()(terminal\<T &\>::::type::make(t))</tt>.
+ /// <tt>Domain()(terminal\<T &\>::type::make(t))</tt>.
///
/// \param t The object to wrap.
template<typename T>
@@ -1200,7 +1212,7 @@
/// reference.
///
/// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
/// \pre \c N is an MPL Integral Constant.
/// \pre <tt>N::value \< Expr::proto_arity::value</tt>
/// \throw nothrow
@@ -1245,7 +1257,7 @@
/// is returned by reference.
///
/// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
/// \pre <tt>N \< Expr::proto_arity::value</tt>
/// \throw nothrow
/// \return A reference to the Nth child
@@ -1299,7 +1311,7 @@
/// child is returned by reference.
///
/// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
/// \pre <tt>2 == Expr::proto_arity::value</tt>
/// \throw nothrow
/// \return A reference to the left child
@@ -1326,7 +1338,7 @@
/// child is returned by reference.
///
/// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
/// \pre <tt>2 == Expr::proto_arity::value</tt>
/// \throw nothrow
/// \return A reference to the right child
Modified: trunk/boost/proto/transform/arg.hpp
==============================================================================
--- trunk/boost/proto/transform/arg.hpp (original)
+++ trunk/boost/proto/transform/arg.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -150,7 +150,7 @@
result_type;
/// Returns the N-th child of \c e
- /// \pre <tt>arity_of\<Expr\>::::value \> N</tt>
+ /// \pre <tt>arity_of\<Expr\>::value \> N</tt>
/// \param e The current expression.
/// \return <tt>proto::child_c\<N\>(e)</tt>
/// \throw nothrow
@@ -190,7 +190,7 @@
result_type;
/// Returns the value of the specified terminal expression.
- /// \pre <tt>arity_of\<Expr\>::::value == 0</tt>.
+ /// \pre <tt>arity_of\<Expr\>::value == 0</tt>.
/// \param e The current expression.
/// \return <tt>proto::value(e)</tt>
/// \throw nothrow
Modified: trunk/boost/proto/transform/call.hpp
==============================================================================
--- trunk/boost/proto/transform/call.hpp (original)
+++ trunk/boost/proto/transform/call.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -121,8 +121,8 @@
/// \param d An arbitrary data
/// If \c Fun is a nullary PolymorphicFunctionObject, \c type is a typedef
- /// for <tt>boost::result_of\<Fun()\>::::type</tt>. Otherwise, it is
- /// a typedef for <tt>boost::result_of\<Fun(Expr, State, Data)\>::::type</tt>.
+ /// for <tt>boost::result_of\<Fun()\>::type</tt>. Otherwise, it is
+ /// a typedef for <tt>boost::result_of\<Fun(Expr, State, Data)\>::type</tt>.
template<typename Expr, typename State, typename Data>
struct impl
: impl2<Expr, State, Data, is_transform<Fun>::value>
@@ -175,8 +175,8 @@
/// Let \c x be <tt>when\<_, A0\>()(e, s, d)</tt> and \c X
/// be the type of \c x.
/// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
- /// then \c type is a typedef for <tt>boost::result_of\<Fun(X)\>::::type</tt>.
- /// Otherwise, it is a typedef for <tt>boost::result_of\<Fun(X, State, Data)\>::::type</tt>.
+ /// then \c type is a typedef for <tt>boost::result_of\<Fun(X)\>::type</tt>.
+ /// Otherwise, it is a typedef for <tt>boost::result_of\<Fun(X, State, Data)\>::type</tt>.
/// Either call the PolymorphicFunctionObject with 1 argument:
/// the result of applying the \c A0 transform; or
@@ -251,8 +251,8 @@
/// be the type of \c y.
/// If \c Fun is a binary PolymorphicFunction object that accepts \c x
/// and \c y, then \c type is a typedef for
- /// <tt>boost::result_of\<Fun(X, Y)\>::::type</tt>. Otherwise, it is
- /// a typedef for <tt>boost::result_of\<Fun(X, Y, Data)\>::::type</tt>.
+ /// <tt>boost::result_of\<Fun(X, Y)\>::type</tt>. Otherwise, it is
+ /// a typedef for <tt>boost::result_of\<Fun(X, Y, Data)\>::type</tt>.
/// Either call the PolymorphicFunctionObject with 2 arguments:
/// the result of applying the \c A0 transform, and the
Modified: trunk/boost/proto/transform/make.hpp
==============================================================================
--- trunk/boost/proto/transform/make.hpp (original)
+++ trunk/boost/proto/transform/make.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -89,6 +89,14 @@
typedef proto::expr<Tag, Args, N> type;
typedef void not_applied_;
};
+
+ // work around GCC bug
+ template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
+ struct make_if_<proto::basic_expr<Tag, Args, N>, Expr, State, Data, false>
+ {
+ typedef proto::basic_expr<Tag, Args, N> type;
+ typedef void not_applied_;
+ };
#endif
// TODO could optimize this if R is a transform
@@ -207,23 +215,23 @@
///
/// \li Function types
/// \li Function pointer types
- /// \li Types for which <tt>proto::is_callable\< type \>::::value</tt> is \c true
+ /// \li Types for which <tt>proto::is_callable\< type \>::value</tt> is \c true
///
- /// <tt>boost::result_of\<make\<T\<X0,X1,...\> \>(Expr, State, Data)\>::::type</tt>
+ /// <tt>boost::result_of\<make\<T\<X0,X1,...\> \>(Expr, State, Data)\>::type</tt>
/// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
///
/// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt>
- /// be <tt>boost::result_of\<make\<U\<Y0,Y1,...\> \>(Expr, State, Data)\>::::type</tt>
+ /// be <tt>boost::result_of\<make\<U\<Y0,Y1,...\> \>(Expr, State, Data)\>::type</tt>
/// (which evaluates this procedure recursively). Note whether any
/// substitutions took place during this operation.
/// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be
- /// <tt>boost::result_of\<when\<_, X\>(Expr, State, Data)\>::::type</tt>.
+ /// <tt>boost::result_of\<when\<_, X\>(Expr, State, Data)\>::type</tt>.
/// Note that a substitution took place.
/// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution
/// took place.
/// \li If any substitutions took place in any of the above steps and
/// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef,
- /// the result type is <tt>T\<X0',X1',...\>::::type</tt>.
+ /// the result type is <tt>T\<X0',X1',...\>::type</tt>.
/// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>.
///
/// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt>
@@ -362,6 +370,18 @@
return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a));
}
};
+
+ template<typename T, typename A>
+ struct construct_<proto::basic_expr<T, A, N>, true>
+ {
+ typedef proto::basic_expr<T, A, N> result_type;
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), typename A)>
+ result_type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_MAX(N, 1), A, &a)) const
+ {
+ return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a));
+ }
+ };
}
/// \brief A PrimitiveTransform which computes a type by evaluating any
@@ -375,7 +395,7 @@
template<typename Expr, typename State, typename Data>
struct impl : transform_impl<Expr, State, Data>
{
- /// \brief <tt>boost::result_of\<make\<Object\>(Expr, State, Data)\>::::type</tt>
+ /// \brief <tt>boost::result_of\<make\<Object\>(Expr, State, Data)\>::type</tt>
typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
//typedef typename detail::make_<Object, Expr, State, Data>::type result_type;
@@ -437,6 +457,34 @@
}
};
};
+
+ template<typename Tag, typename Args, long Arity BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make<proto::basic_expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))>
+ : transform<make<proto::basic_expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef proto::basic_expr<Tag, Args, Arity> result_type;
+
+ result_type operator ()(
+ typename impl::expr_param e
+ , typename impl::state_param s
+ , typename impl::data_param d
+ ) const
+ {
+ return proto::basic_expr<Tag, Args, Arity>::make(
+ #define TMP(Z, M, DATA) \
+ detail::as_lvalue( \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template impl<Expr, State, Data>()(e, s, d) \
+ )
+ BOOST_PP_ENUM(N, TMP, DATA)
+ #undef TMP
+ );
+ }
+ };
+ };
#endif
#undef N
Modified: trunk/boost/proto/transform/pass_through.hpp
==============================================================================
--- trunk/boost/proto/transform/pass_through.hpp (original)
+++ trunk/boost/proto/transform/pass_through.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -91,7 +91,7 @@
/// a Grammar.
///
/// Given a Grammar such as <tt>plus\<T0, T1\></tt>, an expression type
- /// that matches the grammar such as <tt>plus\<E0, E1\>::::type</tt>, a
+ /// that matches the grammar such as <tt>plus\<E0, E1\>::type</tt>, a
/// state \c S and a data \c V, the result of applying the
/// <tt>pass_through\<plus\<T0, T1\> \></tt> transform is:
///
@@ -167,13 +167,15 @@
{
typedef typename pass_through_impl::expr unref_expr;
- typedef proto::expr<
- typename unref_expr::proto_tag
- , BOOST_PP_CAT(list, N)<
- BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM_TYPE, ~)
- >
- , N
- > expr_type;
+ typedef
+ typename base_expr<
+ typename unref_expr::proto_domain
+ , typename unref_expr::proto_tag
+ , BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM_TYPE, ~)
+ >
+ >::type
+ expr_type;
typedef typename unref_expr::proto_generator proto_generator;
typedef typename boost::tr1_result_of<proto_generator(expr_type)>::type result_type;
Modified: trunk/boost/proto/transform/when.hpp
==============================================================================
--- trunk/boost/proto/transform/when.hpp (original)
+++ trunk/boost/proto/transform/when.hpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -46,8 +46,8 @@
/// In <tt>when\<G, T\></tt>, when \c T is a class type it is a
/// PrimitiveTransform and the following equivalencies hold:
///
- /// <tt>boost::result_of\<when\<G,T\>(E,S,V)\>::::type</tt> is the same as
- /// <tt>boost::result_of\<T(E,S,V)\>::::type</tt>.
+ /// <tt>boost::result_of\<when\<G,T\>(E,S,V)\>::type</tt> is the same as
+ /// <tt>boost::result_of\<T(E,S,V)\>::type</tt>.
///
/// <tt>when\<G,T\>()(e,s,d)</tt> is the same as
/// <tt>T()(e,s,d)</tt>.
@@ -130,7 +130,7 @@
///
/// The <tt>when\<G, R(A0,A1,...)\></tt> form accepts either a
/// CallableTransform or an ObjectTransform as its second parameter.
- /// <tt>when\<\></tt> uses <tt>is_callable\<R\>::::value</tt> to
+ /// <tt>when\<\></tt> uses <tt>is_callable\<R\>::value</tt> to
/// distinguish between the two, and uses <tt>call\<\></tt> to
/// evaluate CallableTransforms and <tt>make\<\></tt> to evaluate
/// ObjectTransforms.
@@ -159,13 +159,13 @@
/// Evaluate <tt>R(A0,A1,...)</tt> as a transform either with
/// <tt>call\<\></tt> or with <tt>make\<\></tt> depending on
- /// whether <tt>is_callable\<R\>::::value</tt> is \c true or
+ /// whether <tt>is_callable\<R\>::value</tt> is \c true or
/// \c false.
///
/// \param e The current expression
/// \param s The current state
/// \param d An arbitrary data
- /// \pre <tt>matches\<Expr, Grammar\>::::value</tt> is \c true
+ /// \pre <tt>matches\<Expr, Grammar\>::value</tt> is \c true
/// \return <tt>which()(e, s, d)</tt>
result_type operator ()(
typename impl::expr_param e
Modified: trunk/libs/proto/doc/glossary.qbk
==============================================================================
--- trunk/libs/proto/doc/glossary.qbk (original)
+++ trunk/libs/proto/doc/glossary.qbk 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -45,9 +45,9 @@
within that problem space.]]
[ [ [anchor expression] expression]
[In Proto, an /expression/ is a heterogeneous tree where each node is either
- an instantiation of `boost::proto::expr<>` or some type that is an extension
- (via `boost::proto::extends<>` or `BOOST_PROTO_EXTENDS()`) of such an
- instantiation.]]
+ an instantiation of `boost::proto::expr<>`, `boost::proto::basic_expr<>` or
+ some type that is an extension (via `boost::proto::extends<>` or
+ `BOOST_PROTO_EXTENDS()`) of such an instantiation.]]
[ [ [anchor expression_template] expression template]
[A C++ technique using templates and operator overloading to cause
expressions to build trees that represent the expression for lazy evaluation
Modified: trunk/libs/proto/doc/proto.qbk
==============================================================================
--- trunk/libs/proto/doc/proto.qbk (original)
+++ trunk/libs/proto/doc/proto.qbk 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -47,6 +47,8 @@
[@../../libs/typeof/index.html Boost.Typeof]]
[def _expr_
[classref boost::proto::expr `proto::expr<>`]]
+[def _basic_expr_
+ [classref boost::proto::basic_expr `proto::basic_expr<>`]]
[def _deep_copy_
[funcref boost::proto::deep_copy `proto::deep_copy()`]]
[def _domain_
Modified: trunk/libs/proto/doc/reference.xml
==============================================================================
--- trunk/libs/proto/doc/reference.xml (original)
+++ trunk/libs/proto/doc/reference.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -77,6 +77,16 @@
</listitem>
<listitem>
<computeroutput>
+ <classname alt="boost::proto::base_expr">proto::base_expr</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
+ <classname alt="boost::proto::basic_expr">proto::basic_expr</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
<classname alt="boost::proto::binary_expr">proto::binary_expr</classname>
</computeroutput>
</listitem>
@@ -912,6 +922,11 @@
</listitem>
<listitem>
<computeroutput>
+ <classname alt="boost::proto::use_basic_expr">proto::use_basic_expr</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
<classname alt="boost::proto::unexpr">proto::unexpr</classname>
</computeroutput>
</listitem>
@@ -922,6 +937,11 @@
</listitem>
<listitem>
<computeroutput>
+ <classname alt="boost::proto::wants_basic_expr">proto::wants_basic_expr</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
<classname alt="boost::proto::when">proto::when</classname>
</computeroutput>
</listitem>
Modified: trunk/libs/proto/doc/reference/args.xml
==============================================================================
--- trunk/libs/proto/doc/reference/args.xml (original)
+++ trunk/libs/proto/doc/reference/args.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -16,13 +16,16 @@
<template>
<template-type-parameter name="T"/>
</template>
- <purpose>A type sequence, for use as the 2<superscript>nd</superscript> parameter to the <computeroutput>
- <classname alt="proto::expr">proto::expr<></classname></computeroutput> class template.</purpose>
+ <purpose>A type sequence, for use as the 2<superscript>nd</superscript> parameter to the
+ <computeroutput><classname alt="proto::expr">proto::expr<></classname></computeroutput> and
+ <computeroutput><classname alt="proto::basic_expr">proto::basic_expr<></classname></computeroutput>
+ class templates.</purpose>
<description>
<para>
- A type sequence, for use as the 2<superscript>nd</superscript> parameter to the <computeroutput>
- <classname alt="proto::expr">proto::expr<></classname></computeroutput> class template. The
- types in the sequence correspond to the children of a node in an expression tree.
+ A type sequence with one element, for use as the 2<superscript>nd</superscript> parameter to the
+ <computeroutput><classname alt="proto::expr">proto::expr<></classname></computeroutput> and
+ <computeroutput><classname alt="proto::basic_expr">proto::basic_expr<></classname></computeroutput>
+ class templates. The sequence element represents the value of a terminal.
</para>
</description>
<data-member name="arity" specifiers="static">
@@ -40,12 +43,14 @@
<template-type-parameter name="Arg" pack="1"/>
</template>
<purpose><computeroutput>proto::list1<></computeroutput>, <computeroutput>proto::list2<></computeroutput>, etc.,
- are type sequences for use as the 2<superscript>nd</superscript> parameter to the <computeroutput>
- <classname>proto::expr<></classname></computeroutput> class template.</purpose>
+ are type sequences for use as the 2<superscript>nd</superscript> parameter to the
+ <computeroutput><classname>proto::expr<></classname></computeroutput> or
+ <computeroutput><classname>proto::basic_expr<></classname></computeroutput> class templates.</purpose>
<description>
<para>
- Type sequences, for use as the 2<superscript>nd</superscript> parameter to the <computeroutput>
- <classname>proto::expr<></classname></computeroutput> class template. The
+ Type sequences, for use as the 2<superscript>nd</superscript> parameter to the
+ <computeroutput><classname>proto::expr<></classname></computeroutput> or
+ <computeroutput><classname>proto::basic_expr<></classname></computeroutput> class template. The
types in the sequence correspond to the children of a node in an expression tree.
There is no type literally named "<computeroutput>listN</computeroutput>"; rather, there is
a set of types named
Modified: trunk/libs/proto/doc/reference/concepts/Expr.xml
==============================================================================
--- trunk/libs/proto/doc/reference/concepts/Expr.xml (original)
+++ trunk/libs/proto/doc/reference/concepts/Expr.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -95,7 +95,8 @@
<description>
<simpara>
A typedef for an instantiation of
- <classname alt="boost::proto::expr"><code>proto::expr<></code></classname>
+ <classname alt="boost::proto::expr"><code>proto::expr<></code></classname> or
+ <classname alt="boost::proto::basic_expr"><code>proto::basic_expr<></code></classname>
that is equivalent to Expr. Expression types are equivalent if they have the
same <code>proto_tag</code>, <code>proto_args</code>, and <code>proto_arity</code>.
</simpara>
@@ -180,7 +181,8 @@
</return-type>
<semantics>
Returns an object of type
- <classname alt="boost::proto::expr"><code>proto::expr<></code></classname>
+ <classname alt="boost::proto::expr"><code>proto::expr<></code></classname> or
+ <classname alt="boost::proto::basic_expr"><code>proto::basic_expr<></code></classname>
that is equivalent to <code>e</code>.
</semantics>
</valid-expression>
Modified: trunk/libs/proto/doc/reference/domain.xml
==============================================================================
--- trunk/libs/proto/doc/reference/domain.xml (original)
+++ trunk/libs/proto/doc/reference/domain.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -132,6 +132,69 @@
</typedef>
</struct>
+ <!-- proto::use_basic_expr -->
+ <struct name="use_basic_expr">
+ <template>
+ <template-type-parameter name="Domain"/>
+ </template>
+ <description>
+ <para>
+ Annotate a domain to indicate that its generator would
+ prefer to be passed instances of
+ <computeroutput><classname>proto::basic_expr</classname><></computeroutput> rather than
+ <computeroutput><classname>proto::expr</classname><></computeroutput>.
+ <computeroutput>use_basic_expr< Domain ></computeroutput> is itself a domain.
+ </para>
+ </description>
+ </struct>
+
+ <!-- proto::wants_basic_expr -->
+ <struct name="wants_basic_expr">
+ <template>
+ <template-type-parameter name="Domain"/>
+ </template>
+ <description>
+ <para>
+ A Boolean metafunction that tests a domain to see whether
+ its generator would prefer to be passed instances of
+ <computeroutput><classname>proto::basic_expr</classname><></computeroutput> rather than
+ <computeroutput><classname>proto::expr</classname><></computeroutput>.
+ </para>
+ </description>
+ <inherit>
+ <type>mpl::bool_< <replaceable>true-or-false</replaceable> ></type>
+ </inherit>
+ </struct>
+
+ <!-- proto::wants_basic_expr -->
+ <struct name="base_expr">
+ <template>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template>
+ <description>
+ <para>
+ Given a domain, a tag type and an argument list,
+ compute the type of the expression to generate. This is
+ either an instance of
+ <computeroutput><classname>proto::basic_expr</classname><></computeroutput> or
+ <computeroutput><classname>proto::expr</classname><></computeroutput>.
+ </para>
+ </description>
+ <typedef name="A">
+ <purpose>For exposition only</purpose>
+ <type><classname>proto::basic_expr</classname>< Tag, Args ></type>
+ </typedef>
+ <typedef name="B">
+ <purpose>For exposition only</purpose>
+ <type><classname>proto::expr</classname>< Tag, Args ></type>
+ </typedef>
+ <typedef name="type">
+ <type>typename mpl::if_<<classname>proto::wants_basic_expr</classname>< Domain >, A, B>::type</type>
+ </typedef>
+ </struct>
+
</namespace>
</namespace>
</header>
Modified: trunk/libs/proto/doc/reference/expr.xml
==============================================================================
--- trunk/libs/proto/doc/reference/expr.xml (original)
+++ trunk/libs/proto/doc/reference/expr.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -11,10 +11,130 @@
<template-type-parameter name="Args"/>
<template-nontype-parameter name="Arity">
<type>long</type>
+ <default>Args::arity</default>
</template-nontype-parameter>
</template>
<purpose>Simplified representation of a node in an expression tree.</purpose>
+
+ <description>
+ <para>
+ <computeroutput>proto::basic_expr<></computeroutput> is a node in an expression
+ template tree. It is a container for its child sub-trees. It also serves as the
+ terminal nodes of the tree.
+ </para>
+ <para>
+ <computeroutput>Tag</computeroutput> is type that represents the operation
+ encoded by this expression. It is typically one of the structs in the
+ <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't
+ have to be. If <computeroutput>Arity</computeroutput> is 0 then this
+ <computeroutput>expr<></computeroutput> type represents a leaf in the
+ expression tree.
+ </para>
+ <para>
+ <computeroutput>Args</computeroutput> is a list of types representing
+ the children of this expression. It is an instantiation of one of
+ <computeroutput><classname alt="proto::listN">proto::list1<></classname></computeroutput>,
+ <computeroutput><classname alt="proto::listN">proto::list2<></classname></computeroutput>,
+ etc. The child types
+ must all themselves be either <computeroutput>proto::expr<></computeroutput>
+ or <computeroutput>proto::basic_expr<>&</computeroutput> (or extensions thereof via
+ <computeroutput><classname>proto::extends<></classname></computeroutput> or
+ <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>), unless
+ <computeroutput>Arity</computeroutput> is 0, in which case
+ <computeroutput>Args</computeroutput> must be
+ <computeroutput>proto::term<T></computeroutput>, where
+ <computeroutput>T</computeroutput> can be any type.
+ </para>
+ <para>
+ <computeroutput>proto::basic_expr<></computeroutput> is a valid Fusion
+ random-access sequence, where the elements of the sequence are the child
+ expressions.
+ </para>
+ </description>
+
+ <!-- typedefs -->
+
+ <typedef name="proto_tag">
+ <type>Tag</type>
+ </typedef>
+
+ <typedef name="proto_args">
+ <type>Args</type>
+ </typedef>
+
+ <typedef name="proto_arity">
+ <type>mpl::long_< Arity ></type>
+ </typedef>
+
+ <typedef name="proto_domain">
+ <type><classname>proto::default_domain</classname></type>
+ </typedef>
+
+ <typedef name="proto_grammar">
+ <type>basic_expr</type>
+ </typedef>
+
+ <typedef name="proto_base_expr">
+ <type>basic_expr</type>
+ </typedef>
+
+ <typedef name="proto_derived_expr">
+ <type>basic_expr</type>
+ </typedef>
+
+ <typedef name="proto_childN">
+ <type>typename Args::child<replaceable>N</replaceable></type>
+ <purpose>For each <replaceable>N</replaceable> in <replaceable>[0,max(Arity,1))</replaceable>.</purpose>
+ </typedef>
+
+ <method-group name="public static functions">
+
+ <!-- make -->
+ <method name="make" specifiers="static">
+ <type>basic_expr const</type>
+ <template>
+ <template-type-parameter name="A" pack="1"/>
+ </template>
+ <parameter name="a" pack="1">
+ <paramtype>A const &</paramtype>
+ </parameter>
+ <requires>
+ <para>
+ The number of supplied arguments must be <computeroutput>max(Arity,1)</computeroutput>.
+ </para>
+ </requires>
+ <returns>
+ <para>
+ A new <computeroutput>basic_expr</computeroutput> object initialized with the specified arguments.
+ </para>
+ </returns>
+ </method>
+
+ </method-group>
+
+ <method-group name="public member functions">
+
+ <method name="proto_base">
+ <type>basic_expr &</type>
+ <returns>
+ <para>
+ <computeroutput>*this</computeroutput>
+ </para>
+ </returns>
+ </method>
+
+ <method name="proto_base" cv="const">
+ <type>basic_expr const &</type>
+ <description>
+ <para>
+ This is an overloaded member function, provided for convenience. It differs from
+ the above function only in what argument(s) it accepts.
+ </para>
+ </description>
+ </method>
+
+ </method-group>
</struct>
<!-- boost::proto::expr -->
@@ -52,7 +172,7 @@
<computeroutput><classname alt="proto::listN">proto::list2<></classname></computeroutput>,
etc. The child types
must all themselves be either <computeroutput>proto::expr<></computeroutput>
- or <computeroutput>proto::expr<>&</computeroutput> (or extensions thereof via
+ or <computeroutput>proto::basic_expr<>&</computeroutput> (or extensions thereof via
<computeroutput><classname>proto::extends<></classname></computeroutput> or
<computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>), unless
<computeroutput>Arity</computeroutput> is 0, in which case
Modified: trunk/libs/proto/doc/reference/make_expr.xml
==============================================================================
--- trunk/libs/proto/doc/reference/make_expr.xml (original)
+++ trunk/libs/proto/doc/reference/make_expr.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -209,15 +209,15 @@
If <computeroutput>Tag</computeroutput> is
<computeroutput><classname>proto::tag::terminal</classname></computeroutput>, then
<computeroutput>type</computeroutput> is a typedef for
- <computeroutput>boost::result_of<Domain(<classname>proto::expr</classname><
- <classname>proto::tag::terminal</classname>, <classname>proto::term</classname><
- A<subscript>0</subscript> > >)>::type</computeroutput>.
+ <computeroutput>boost::result_of<Domain(typename <classname>proto::base_expr</classname><
+ Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname><
+ A<subscript>0</subscript> > >::type)>::type</computeroutput>.
</para>
<para>
Otherwise, <computeroutput>type</computeroutput> is a typedef for
- <computeroutput>boost::result_of<Domain(<classname>proto::expr</classname><
- Tag, <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname><
- typename <classname>proto::result_of::as_child</classname><A>::type...> >)>::type</computeroutput>
+ <computeroutput>boost::result_of<Domain(typename <classname>proto::base_expr</classname><
+ Domain, Tag, <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname><
+ typename <classname>proto::result_of::as_child</classname><A>::type...> >::type)>::type</computeroutput>
</para>
</description>
<type><emphasis>see-below</emphasis></type>
@@ -352,7 +352,7 @@
</listitem>
</itemizedlist>
Let <computeroutput><replaceable>MAKE</replaceable><Tag>(a...)</computeroutput> be defined as
- <computeroutput><classname>proto::expr</classname><Tag,
+ <computeroutput><classname>proto::base_expr</classname><Domain, Tag,
<classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname><A...> >::make(a...)</computeroutput>
where
<computeroutput>A<subscript>x</subscript></computeroutput> is the type of
@@ -426,7 +426,7 @@
</listitem>
</itemizedlist>
Let <computeroutput><replaceable>MAKE</replaceable><Tag>(a...)</computeroutput> be defined as
- <computeroutput><classname>proto::expr</classname><Tag,
+ <computeroutput><classname>proto::base_expr</classname><Domain, Tag,
<classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname><A...> >::make(a...)</computeroutput>
where
<computeroutput>A<subscript>x</subscript></computeroutput> is the type of
Modified: trunk/libs/proto/doc/reference/matches.xml
==============================================================================
--- trunk/libs/proto/doc/reference/matches.xml (original)
+++ trunk/libs/proto/doc/reference/matches.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -503,9 +503,9 @@
<purpose>For matching a Grammar to a variable number of sub-expressions.</purpose>
<description>
<para>
- An expression type <computeroutput><classname>proto::expr</classname><AT,
+ An expression type <computeroutput><classname>proto::basic_expr</classname><AT,
<classname alt="proto::listN">proto::list<replaceable>N</replaceable></classname><A<subscript>0</subscript>,...A<subscript>n</subscript>,U<subscript>0</subscript>,...U<subscript>m</subscript>> ></computeroutput>
- matches a grammar <computeroutput><classname>proto::expr</classname><BT,
+ matches a grammar <computeroutput><classname>proto::basic_expr</classname><BT,
<classname alt="proto::listN">proto::list<replaceable>M</replaceable></classname><B<subscript>0</subscript>,...B<subscript>n</subscript>,proto::vararg<V> > ></computeroutput>
if <computeroutput>BT</computeroutput> is <computeroutput><classname>proto::_</classname></computeroutput>
or <computeroutput>AT</computeroutput>, and if
@@ -559,7 +559,7 @@
<para>
An expression
<computeroutput>
- <classname>proto::expr</classname><AT,
+ <classname>proto::basic_expr</classname><AT,
<classname alt="proto::listN">
proto::list<replaceable>N</replaceable>
</classname><A<subscript>0</subscript>,...A<subscript>n</subscript>>
@@ -567,7 +567,7 @@
</computeroutput>
matches a grammar
<computeroutput>
- <classname>proto::expr</classname><BT,
+ <classname>proto::basic_expr</classname><BT,
<classname alt="proto::listN">
proto::list<replaceable>N</replaceable>
</classname><B<subscript>0</subscript>,...B<subscript>n</subscript>>
@@ -588,14 +588,14 @@
<para>
An expression
<computeroutput>
- <classname>proto::expr</classname><AT,
+ <classname>proto::basic_expr</classname><AT,
<classname alt="proto::listN">
proto::list<replaceable>N</replaceable>
</classname><A<subscript>0</subscript>,...A<subscript>n</subscript>,U<subscript>0</subscript>,...U<subscript>m</subscript>>
>
</computeroutput> matches a grammar
<computeroutput>
- <classname>proto::expr</classname><BT,
+ <classname>proto::basic_expr</classname><BT,
<classname alt="proto::listN">
proto::list<replaceable>M</replaceable>
</classname><B<subscript>0</subscript>,...B<subscript>n</subscript>,<classname>proto::vararg</classname><V>
@@ -700,11 +700,11 @@
<para>
A terminal expression
<computeroutput>
- <classname>proto::expr</classname><AT,
+ <classname>proto::basic_expr</classname><AT,
<classname>proto::term</classname><A> >
</computeroutput> matches a grammar
<computeroutput>
- <classname>proto::expr</classname><BT, <classname>proto::term</classname><B> >
+ <classname>proto::basic_expr</classname><BT, <classname>proto::term</classname><B> >
</computeroutput>
if <computeroutput>BT</computeroutput> is <computeroutput><classname>proto::_</classname></computeroutput>
or <computeroutput>AT</computeroutput> and one of the following is true:
Modified: trunk/libs/proto/doc/reference/traits.xml
==============================================================================
--- trunk/libs/proto/doc/reference/traits.xml (original)
+++ trunk/libs/proto/doc/reference/traits.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -71,7 +71,8 @@
<computeroutput>T t(a<subscript>0</subscript>,...a<subscript>n</subscript>)</computeroutput>.
</para>
<para>
- Note: <computeroutput><classname>proto::expr<></classname> is an aggregate.</computeroutput>
+ Note: <computeroutput><classname>proto::expr<></classname></computeroutput> and
+ <computeroutput><classname>proto::basic_expr<></classname></computeroutput>are aggregates.
</para>
</description>
<inherit><type>mpl::bool_<<replaceable>true-or-false</replaceable>></type></inherit>
@@ -2046,8 +2047,9 @@
is a Proto expression type.</purpose>
<description>
<para>
- If <computeroutput>T</computeroutput> is an instantiation of <computeroutput>
- <classname alt="proto::expr">proto::expr<></classname></computeroutput> or is an extension
+ If <computeroutput>T</computeroutput> is an instantiation of
+ <computeroutput><classname alt="proto::expr">proto::expr<></classname></computeroutput> or
+ <computeroutput><classname alt="proto::basic_expr">proto::basic_expr<></classname></computeroutput> or is an extension
(via <classname alt="proto::extends">proto::extends<></classname> or
<macroname>BOOST_PROTO_EXTENDS</macroname>()) of such an instantiation,
<computeroutput><classname>proto::is_expr</classname><T>::value</computeroutput>
@@ -2101,7 +2103,7 @@
<computeroutput>A</computeroutput> be <computeroutput>T &</computeroutput>. Otherwise, let
<computeroutput>A</computeroutput> be the type <computeroutput>T</computeroutput> stripped of
cv-qualifiers. Then, the result type <computeroutput>proto::result_of::as_expr<T, Domain>::type</computeroutput>
- is <computeroutput>boost::result_of<Domain(<classname>proto::expr</classname>< <classname>proto::tag::terminal</classname>, <classname>proto::term</classname><A> >)>::type</computeroutput>.
+ is <computeroutput>boost::result_of<Domain(typename <classname>proto::base_expr</classname><Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname><A> >::type)>::type</computeroutput>.
</para>
</description>
<typedef name="type">
@@ -2127,7 +2129,7 @@
<para>
When <computeroutput>T</computeroutput> is not yet a Proto type,
the result type <computeroutput>proto::result_of::as_child<T, Domain>::type</computeroutput> is
- <computeroutput>boost::result_of<Domain(<classname>proto::expr</classname>< <classname>proto::tag::terminal</classname>, <classname>proto::term</classname><T &> >)>::type</computeroutput>.
+ <computeroutput>boost::result_of<Domain(typename <classname>proto::base_expr</classname><Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname><T &> >::type)>::type</computeroutput>.
</para>
<para>
When <computeroutput>T</computeroutput> is already a Proto type
Modified: trunk/libs/proto/doc/reference/transform/pass_through.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/pass_through.xml (original)
+++ trunk/libs/proto/doc/reference/transform/pass_through.xml 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -106,7 +106,7 @@
</typedef>
<typedef name="expr_type">
<purpose>For exposition only</purpose>
- <type><classname>proto::expr</classname><T, <classname>proto::listN</classname><R0,...RN> ></type>
+ <type>typename <classname>proto::base_expr</classname><D, T, <classname>proto::listN</classname><R0,...RN> >::type</type>
</typedef>
<typedef name="result_type">
<type>typename boost::result_of<D(expr_type)>::type</type>
Modified: trunk/libs/proto/test/make_expr.cpp
==============================================================================
--- trunk/libs/proto/test/make_expr.cpp (original)
+++ trunk/libs/proto/test/make_expr.cpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -38,13 +38,31 @@
unary_plus<terminal<int>::type>::type p2 = make_expr<tag::unary_plus>(i);
BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
- ewrap<unary_plus<ewrap<terminal<int>::type> >::type> p3 = make_expr<tag::unary_plus, mydomain>(i);
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::unary_plus
+ , proto::list1<
+ ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p3_type;
+ p3_type p3 = make_expr<tag::unary_plus, mydomain>(i);
BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
- ewrap<plus<
- ewrap<unary_plus<ewrap<terminal<int>::type> >::type>
- , ewrap<terminal<int>::type>
- >::type> p4 = make_expr<tag::plus>(p3, 0);
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::plus
+ , proto::list2<
+ p3_type
+ , ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p4_type;
+ p4_type p4 = make_expr<tag::plus>(p3, 0);
BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
}
@@ -58,13 +76,31 @@
unary_plus<terminal<int &>::type>::type p2 = make_expr<tag::unary_plus>(boost::ref(i));
BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = make_expr<tag::unary_plus, mydomain>(boost::ref(i));
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::unary_plus
+ , proto::list1<
+ ewrap<proto::basic_expr<tag::terminal, proto::term<int &> > >
+ >
+ >
+ >
+ p3_type;
+ p3_type p3 = make_expr<tag::unary_plus, mydomain>(boost::ref(i));
BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
- ewrap<plus<
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
- , ewrap<terminal<int>::type>
- >::type> p4 = make_expr<tag::plus>(boost::ref(p3), 0);
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::plus
+ , proto::list2<
+ p3_type &
+ , ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p4_type;
+ p4_type p4 = make_expr<tag::plus>(boost::ref(p3), 0);
BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
}
@@ -77,14 +113,31 @@
unary_plus<terminal<int>::type>::type p2 = functional::make_expr<tag::unary_plus>()(i);
BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
- ewrap<unary_plus<ewrap<terminal<int>::type> >::type> p3 = functional::make_expr<tag::unary_plus, mydomain>()(i);
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::unary_plus
+ , proto::list1<
+ ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p3_type;
+ p3_type p3 = functional::make_expr<tag::unary_plus, mydomain>()(i);
BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
- ewrap<plus<
- ewrap<unary_plus<ewrap<terminal<int>::type> >::type>
- , ewrap<terminal<int>::type>
- >::type> p4 = functional::make_expr<tag::plus, mydomain>()(p3, 0);
- BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::plus
+ , proto::list2<
+ p3_type
+ , ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p4_type;
+ p4_type p4 = functional::make_expr<tag::plus>()(p3, 0);
}
void test_make_expr_functional_ref()
@@ -97,13 +150,31 @@
unary_plus<terminal<int &>::type>::type p2 = functional::make_expr<tag::unary_plus>()(boost::ref(i));
BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = functional::make_expr<tag::unary_plus, mydomain>()(boost::ref(i));
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::unary_plus
+ , proto::list1<
+ ewrap<proto::basic_expr<tag::terminal, proto::term<int &> > >
+ >
+ >
+ >
+ p3_type;
+ p3_type p3 = functional::make_expr<tag::unary_plus, mydomain>()(boost::ref(i));
BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
- ewrap<plus<
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
- , ewrap<terminal<int>::type>
- >::type> p4 = functional::make_expr<tag::plus, mydomain>()(boost::ref(p3), 0);
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::plus
+ , proto::list2<
+ p3_type &
+ , ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p4_type;
+ p4_type p4 = functional::make_expr<tag::plus>()(boost::ref(p3), 0);
BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
}
@@ -116,13 +187,31 @@
unary_plus<terminal<int &>::type>::type p2 = unpack_expr<tag::unary_plus>(fusion::make_tuple(boost::ref(i)));
BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = unpack_expr<tag::unary_plus, mydomain>(fusion::make_tuple(boost::ref(i)));
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::unary_plus
+ , proto::list1<
+ ewrap<proto::basic_expr<tag::terminal, proto::term<int &> > >
+ >
+ >
+ >
+ p3_type;
+ p3_type p3 = unpack_expr<tag::unary_plus, mydomain>(fusion::make_tuple(boost::ref(i)));
BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
- ewrap<plus<
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
- , ewrap<terminal<int>::type>
- >::type> p4 = unpack_expr<tag::plus>(fusion::make_tuple(boost::ref(p3), 0));
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::plus
+ , proto::list2<
+ p3_type &
+ , ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p4_type;
+ p4_type p4 = unpack_expr<tag::plus>(fusion::make_tuple(boost::ref(p3), 0));
BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
}
@@ -135,13 +224,31 @@
unary_plus<terminal<int &>::type>::type p2 = functional::unpack_expr<tag::unary_plus>()(fusion::make_tuple(boost::ref(i)));
BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = functional::unpack_expr<tag::unary_plus, mydomain>()(fusion::make_tuple(boost::ref(i)));
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::unary_plus
+ , proto::list1<
+ ewrap<proto::basic_expr<tag::terminal, proto::term<int &> > >
+ >
+ >
+ >
+ p3_type;
+ p3_type p3 = functional::unpack_expr<tag::unary_plus, mydomain>()(fusion::make_tuple(boost::ref(i)));
BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
- ewrap<plus<
- ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
- , ewrap<terminal<int>::type>
- >::type> p4 = functional::unpack_expr<tag::plus>()(fusion::make_tuple(boost::ref(p3), 0));
+ typedef
+ ewrap<
+ proto::basic_expr<
+ tag::plus
+ , proto::list2<
+ p3_type &
+ , ewrap<proto::basic_expr<tag::terminal, proto::term<int> > >
+ >
+ >
+ >
+ p4_type;
+ p4_type p4 = functional::unpack_expr<tag::plus>()(fusion::make_tuple(boost::ref(p3), 0));
BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
}
Modified: trunk/libs/proto/test/proto_fusion_s.cpp
==============================================================================
--- trunk/libs/proto/test/proto_fusion_s.cpp (original)
+++ trunk/libs/proto/test/proto_fusion_s.cpp 2010-06-08 20:14:39 EDT (Tue, 08 Jun 2010)
@@ -28,6 +28,12 @@
return sout << boost::proto::value(*op);
}
+template<typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::basic_expr<boost::proto::tag::terminal, Args, 0> const *op)
+{
+ return sout << boost::proto::value(*op);
+}
+
template<typename Tag, typename Args>
std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 1> const *op)
{
@@ -35,11 +41,23 @@
}
template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::basic_expr<Tag, Args, 1> const *op)
+{
+ return sout << Tag() << boost::addressof(boost::proto::child(*op).proto_base());
+}
+
+template<typename Tag, typename Args>
std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 2> const *op)
{
return sout << boost::addressof(boost::proto::left(*op).proto_base()) << Tag() << boost::addressof(boost::proto::right(*op).proto_base());
}
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::basic_expr<Tag, Args, 2> const *op)
+{
+ return sout << boost::addressof(boost::proto::left(*op).proto_base()) << Tag() << boost::addressof(boost::proto::right(*op).proto_base());
+}
+
///////////////////////////////////////////////////////////////////////////////
// to_string
//
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