Boost logo

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&lt;&gt;</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&lt;&gt;</classname></computeroutput> and
+ <computeroutput><classname alt="proto::basic_expr">proto::basic_expr&lt;&gt;</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&lt;&gt;</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&lt;&gt;</classname></computeroutput> and
+ <computeroutput><classname alt="proto::basic_expr">proto::basic_expr&lt;&gt;</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&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc.,
- are type sequences for use as the 2<superscript>nd</superscript> parameter to the <computeroutput>
- <classname>proto::expr&lt;&gt;</classname></computeroutput> class template.</purpose>
+ are type sequences for use as the 2<superscript>nd</superscript> parameter to the
+ <computeroutput><classname>proto::expr&lt;&gt;</classname></computeroutput> or
+ <computeroutput><classname>proto::basic_expr&lt;&gt;</classname></computeroutput> class templates.</purpose>
         <description>
           <para>
- Type sequences, for use as the 2<superscript>nd</superscript> parameter to the <computeroutput>
- <classname>proto::expr&lt;&gt;</classname></computeroutput> class template. The
+ Type sequences, for use as the 2<superscript>nd</superscript> parameter to the
+ <computeroutput><classname>proto::expr&lt;&gt;</classname></computeroutput> or
+ <computeroutput><classname>proto::basic_expr&lt;&gt;</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&lt;&gt;</code></classname>
+ <classname alt="boost::proto::expr"><code>proto::expr&lt;&gt;</code></classname> or
+ <classname alt="boost::proto::basic_expr"><code>proto::basic_expr&lt;&gt;</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&lt;&gt;</code></classname>
+ <classname alt="boost::proto::expr"><code>proto::expr&lt;&gt;</code></classname> or
+ <classname alt="boost::proto::basic_expr"><code>proto::basic_expr&lt;&gt;</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>&lt;&gt;</computeroutput> rather than
+ <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
+ <computeroutput>use_basic_expr&lt; Domain &gt;</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>&lt;&gt;</computeroutput> rather than
+ <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
+ </para>
+ </description>
+ <inherit>
+ <type>mpl::bool_&lt; <replaceable>true-or-false</replaceable> &gt;</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>&lt;&gt;</computeroutput> or
+ <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
+ </para>
+ </description>
+ <typedef name="A">
+ <purpose>For exposition only</purpose>
+ <type><classname>proto::basic_expr</classname>&lt; Tag, Args &gt;</type>
+ </typedef>
+ <typedef name="B">
+ <purpose>For exposition only</purpose>
+ <type><classname>proto::expr</classname>&lt; Tag, Args &gt;</type>
+ </typedef>
+ <typedef name="type">
+ <type>typename mpl::if_&lt;<classname>proto::wants_basic_expr</classname>&lt; Domain &gt;, A, B&gt;::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&lt;&gt;</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&lt;&gt;</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&lt;&gt;</classname></computeroutput>,
+ <computeroutput><classname alt="proto::listN">proto::list2&lt;&gt;</classname></computeroutput>,
+ etc. The child types
+ must all themselves be either <computeroutput>proto::expr&lt;&gt;</computeroutput>
+ or <computeroutput>proto::basic_expr&lt;&gt;&amp;</computeroutput> (or extensions thereof via
+ <computeroutput><classname>proto::extends&lt;&gt;</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&lt;T&gt;</computeroutput>, where
+ <computeroutput>T</computeroutput> can be any type.
+ </para>
+ <para>
+ <computeroutput>proto::basic_expr&lt;&gt;</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_&lt; Arity &gt;</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 &amp;</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 &amp;</type>
+ <returns>
+ <para>
+ <computeroutput>*this</computeroutput>
+ </para>
+ </returns>
+ </method>
+
+ <method name="proto_base" cv="const">
+ <type>basic_expr const &amp;</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&lt;&gt;</classname></computeroutput>,
             etc. The child types
             must all themselves be either <computeroutput>proto::expr&lt;&gt;</computeroutput>
- or <computeroutput>proto::expr&lt;&gt;&amp;</computeroutput> (or extensions thereof via
+ or <computeroutput>proto::basic_expr&lt;&gt;&amp;</computeroutput> (or extensions thereof via
             <computeroutput><classname>proto::extends&lt;&gt;</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&lt;Domain(<classname>proto::expr</classname>&lt;
- <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;
- A<subscript>0</subscript> &gt; &gt;)&gt;::type</computeroutput>.
+ <computeroutput>boost::result_of&lt;Domain(typename <classname>proto::base_expr</classname>&lt;
+ Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;
+ A<subscript>0</subscript> &gt; &gt;::type)&gt;::type</computeroutput>.
               </para>
               <para>
                 Otherwise, <computeroutput>type</computeroutput> is a typedef for
- <computeroutput>boost::result_of&lt;Domain(<classname>proto::expr</classname>&lt;
- Tag, <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;
- typename <classname>proto::result_of::as_child</classname>&lt;A&gt;::type...&gt; &gt;)&gt;::type</computeroutput>
+ <computeroutput>boost::result_of&lt;Domain(typename <classname>proto::base_expr</classname>&lt;
+ Domain, Tag, <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;
+ typename <classname>proto::result_of::as_child</classname>&lt;A&gt;::type...&gt; &gt;::type)&gt;::type</computeroutput>
               </para>
             </description>
             <type><emphasis>see-below</emphasis></type>
@@ -352,7 +352,7 @@
               </listitem>
             </itemizedlist>
             Let <computeroutput><replaceable>MAKE</replaceable>&lt;Tag&gt;(a...)</computeroutput> be defined as
- <computeroutput><classname>proto::expr</classname>&lt;Tag,
+ <computeroutput><classname>proto::base_expr</classname>&lt;Domain, Tag,
             <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;A...&gt; &gt;::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>&lt;Tag&gt;(a...)</computeroutput> be defined as
- <computeroutput><classname>proto::expr</classname>&lt;Tag,
+ <computeroutput><classname>proto::base_expr</classname>&lt;Domain, Tag,
             <classname alt="proto::listN">proto::list<emphasis>N</emphasis></classname>&lt;A...&gt; &gt;::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>&lt;AT,
+ An expression type <computeroutput><classname>proto::basic_expr</classname>&lt;AT,
             <classname alt="proto::listN">proto::list<replaceable>N</replaceable></classname>&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>,U<subscript>0</subscript>,...U<subscript>m</subscript>&gt; &gt;</computeroutput>
- matches a grammar <computeroutput><classname>proto::expr</classname>&lt;BT,
+ matches a grammar <computeroutput><classname>proto::basic_expr</classname>&lt;BT,
             <classname alt="proto::listN">proto::list<replaceable>M</replaceable></classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>,proto::vararg&lt;V&gt; &gt; &gt;</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>&lt;AT,
+ <classname>proto::basic_expr</classname>&lt;AT,
                     <classname alt="proto::listN">
                       proto::list<replaceable>N</replaceable>
                     </classname>&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>&gt;
@@ -567,7 +567,7 @@
                   </computeroutput>
                   matches a grammar
                   <computeroutput>
- <classname>proto::expr</classname>&lt;BT,
+ <classname>proto::basic_expr</classname>&lt;BT,
                     <classname alt="proto::listN">
                       proto::list<replaceable>N</replaceable>
                     </classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>&gt;
@@ -588,14 +588,14 @@
                 <para>
                   An expression
                   <computeroutput>
- <classname>proto::expr</classname>&lt;AT,
+ <classname>proto::basic_expr</classname>&lt;AT,
                     <classname alt="proto::listN">
                       proto::list<replaceable>N</replaceable>
                     </classname>&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>,U<subscript>0</subscript>,...U<subscript>m</subscript>&gt;
                     &gt;
                   </computeroutput> matches a grammar
                   <computeroutput>
- <classname>proto::expr</classname>&lt;BT,
+ <classname>proto::basic_expr</classname>&lt;BT,
                     <classname alt="proto::listN">
                       proto::list<replaceable>M</replaceable>
                     </classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>,<classname>proto::vararg</classname>&lt;V&gt;
@@ -700,11 +700,11 @@
           <para>
             A terminal expression
             <computeroutput>
- <classname>proto::expr</classname>&lt;AT,
+ <classname>proto::basic_expr</classname>&lt;AT,
               <classname>proto::term</classname>&lt;A&gt; &gt;
             </computeroutput> matches a grammar
             <computeroutput>
- <classname>proto::expr</classname>&lt;BT, <classname>proto::term</classname>&lt;B&gt; &gt;
+ <classname>proto::basic_expr</classname>&lt;BT, <classname>proto::term</classname>&lt;B&gt; &gt;
             </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&lt;&gt;</classname> is an aggregate.</computeroutput>
+ Note: <computeroutput><classname>proto::expr&lt;&gt;</classname></computeroutput> and
+ <computeroutput><classname>proto::basic_expr&lt;&gt;</classname></computeroutput>are aggregates.
           </para>
         </description>
         <inherit><type>mpl::bool_&lt;<replaceable>true-or-false</replaceable>&gt;</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&lt;&gt;</classname></computeroutput> or is an extension
+ If <computeroutput>T</computeroutput> is an instantiation of
+ <computeroutput><classname alt="proto::expr">proto::expr&lt;&gt;</classname></computeroutput> or
+ <computeroutput><classname alt="proto::basic_expr">proto::basic_expr&lt;&gt;</classname></computeroutput> or is an extension
             (via <classname alt="proto::extends">proto::extends&lt;&gt;</classname> or
             <macroname>BOOST_PROTO_EXTENDS</macroname>()) of such an instantiation,
             <computeroutput><classname>proto::is_expr</classname>&lt;T&gt;::value</computeroutput>
@@ -2101,7 +2103,7 @@
               <computeroutput>A</computeroutput> be <computeroutput>T &amp;</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&lt;T, Domain&gt;::type</computeroutput>
- is <computeroutput>boost::result_of&lt;Domain(<classname>proto::expr</classname>&lt; <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;A&gt; &gt;)&gt;::type</computeroutput>.
+ is <computeroutput>boost::result_of&lt;Domain(typename <classname>proto::base_expr</classname>&lt;Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;A&gt; &gt;::type)&gt;::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&lt;T, Domain&gt;::type</computeroutput> is
- <computeroutput>boost::result_of&lt;Domain(<classname>proto::expr</classname>&lt; <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;T &amp;&gt; &gt;)&gt;::type</computeroutput>.
+ <computeroutput>boost::result_of&lt;Domain(typename <classname>proto::base_expr</classname>&lt;Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;T &amp;&gt; &gt;::type)&gt;::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>&lt;T, <classname>proto::listN</classname>&lt;R0,...RN&gt; &gt;</type>
+ <type>typename <classname>proto::base_expr</classname>&lt;D, T, <classname>proto::listN</classname>&lt;R0,...RN&gt; &gt;::type</type>
           </typedef>
           <typedef name="result_type">
             <type>typename boost::result_of&lt;D(expr_type)&gt;::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