Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79526 - in branches/release: . boost boost/proto boost/proto/detail boost/proto/transform boost/proto/transform/detail boost/proto/transform/detail/preprocessed libs libs/proto/doc libs/proto/doc/reference libs/proto/doc/reference/transform libs/proto/preprocess libs/proto/test
From: eric_at_[hidden]
Date: 2012-07-15 00:40:43


Author: eric_niebler
Date: 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
New Revision: 79526
URL: http://svn.boost.org/trac/boost/changeset/79526

Log:
merge [79461], [79465], and [79485] from trunk
Added:
   branches/release/boost/proto/transform/detail/expand_pack.hpp
      - copied unchanged from r79461, /trunk/boost/proto/transform/detail/expand_pack.hpp
   branches/release/boost/proto/transform/detail/pack.hpp
      - copied, changed from r79461, /trunk/boost/proto/transform/detail/pack.hpp
   branches/release/boost/proto/transform/detail/pack_impl.hpp
      - copied, changed from r79461, /trunk/boost/proto/transform/detail/pack_impl.hpp
   branches/release/boost/proto/transform/detail/preprocessed/expand_pack.hpp
      - copied unchanged from r79461, /trunk/boost/proto/transform/detail/preprocessed/expand_pack.hpp
   branches/release/boost/proto/transform/detail/preprocessed/pack_impl.hpp
      - copied, changed from r79461, /trunk/boost/proto/transform/detail/preprocessed/pack_impl.hpp
   branches/release/libs/proto/test/pack_expansion.cpp
      - copied, changed from r79461, /trunk/libs/proto/test/pack_expansion.cpp
Properties modified:
   branches/release/ (props changed)
   branches/release/boost/ (props changed)
   branches/release/libs/ (props changed)
Text files modified:
   branches/release/boost/proto/detail/deduce_domain.hpp | 1
   branches/release/boost/proto/fusion.hpp | 21
   branches/release/boost/proto/proto_fwd.hpp | 2
   branches/release/boost/proto/transform/call.hpp | 24 +
   branches/release/boost/proto/transform/detail/call.hpp | 29 +
   branches/release/boost/proto/transform/detail/lazy.hpp | 21 +
   branches/release/boost/proto/transform/detail/make.hpp | 24 +
   branches/release/boost/proto/transform/detail/pack.hpp | 7
   branches/release/boost/proto/transform/detail/pack_impl.hpp | 2
   branches/release/boost/proto/transform/detail/preprocessed/call.hpp | 200 ++++++++++
   branches/release/boost/proto/transform/detail/preprocessed/lazy.hpp | 180 +++++++++
   branches/release/boost/proto/transform/detail/preprocessed/make.hpp | 220 +++++++++++
   branches/release/boost/proto/transform/detail/preprocessed/pack_impl.hpp | 20
   branches/release/boost/proto/transform/detail/preprocessed/when.hpp | 762 ++++++++++++++++-----------------------
   branches/release/boost/proto/transform/detail/when.hpp | 77 +--
   branches/release/boost/proto/transform/lazy.hpp | 7
   branches/release/boost/proto/transform/make.hpp | 7
   branches/release/boost/proto/transform/when.hpp | 50 ++
   branches/release/libs/proto/doc/back_end.qbk | 96 +++++
   branches/release/libs/proto/doc/proto.qbk | 2
   branches/release/libs/proto/doc/reference.xml | 5
   branches/release/libs/proto/doc/reference/repeat.xml | 36
   branches/release/libs/proto/doc/reference/transform/call.xml | 28 +
   branches/release/libs/proto/doc/reference/transform/impl.xml | 118 ++++++
   branches/release/libs/proto/doc/reference/transform/lazy.xml | 24 +
   branches/release/libs/proto/doc/reference/transform/make.xml | 40 +
   branches/release/libs/proto/doc/reference/transform/when.xml | 108 +++++
   branches/release/libs/proto/preprocess/Jamfile.v2 | 2
   branches/release/libs/proto/preprocess/wave.cfg | 3
   branches/release/libs/proto/test/Jamfile.v2 | 3
   branches/release/libs/proto/test/pack_expansion.cpp | 63 +-
   31 files changed, 1606 insertions(+), 576 deletions(-)

Modified: branches/release/boost/proto/detail/deduce_domain.hpp
==============================================================================
--- branches/release/boost/proto/detail/deduce_domain.hpp (original)
+++ branches/release/boost/proto/detail/deduce_domain.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -19,6 +19,7 @@
 #include <boost/preprocessor/cat.hpp>
 #include <boost/preprocessor/facilities/intercept.hpp>
 #include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>

Modified: branches/release/boost/proto/fusion.hpp
==============================================================================
--- branches/release/boost/proto/fusion.hpp (original)
+++ branches/release/boost/proto/fusion.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -44,12 +44,11 @@
           : fusion::iterator_base<expr_iterator<Expr, Pos> >
         {
             typedef Expr expr_type;
- typedef typename Expr::proto_tag proto_tag;
             static const long index = Pos;
             typedef fusion::random_access_traversal_tag category;
             typedef tag::proto_expr_iterator fusion_tag;
 
- expr_iterator(Expr &e)
+ explicit expr_iterator(Expr &e)
               : expr(e)
             {}
 
@@ -60,7 +59,6 @@
         struct flat_view
         {
             typedef Expr expr_type;
- typedef typename Expr::proto_tag proto_tag;
             typedef fusion::forward_traversal_tag category;
             typedef tag::proto_flat_view fusion_tag;
 
@@ -373,7 +371,7 @@
             struct apply
             {
                 typedef
- typename proto::detail::expr_iterator<
+ proto::detail::expr_iterator<
                         typename Iterator::expr_type
                       , Iterator::index + N::value
>
@@ -583,12 +581,14 @@
             template<typename Sequence>
             struct apply
             {
- typedef typename Sequence::proto_tag proto_tag;
+ typedef typename Sequence::expr_type::proto_tag proto_tag;
 
- typedef fusion::transform_view<
- typename Sequence::expr_type
- , proto::detail::as_element<proto_tag>
- > type;
+ typedef
+ fusion::transform_view<
+ typename Sequence::expr_type
+ , proto::detail::as_element<proto_tag>
+ >
+ type;
 
                 static type call(Sequence &sequence)
                 {
@@ -639,7 +639,6 @@
           : mpl::false_
         {};
     }
-
 }}
 
 namespace boost { namespace mpl
@@ -655,7 +654,7 @@
     {
         typedef fusion::fusion_sequence_tag type;
     };
-}}
+}}
 
 #ifdef BOOST_MSVC
 #pragma warning(pop)

Modified: branches/release/boost/proto/proto_fwd.hpp
==============================================================================
--- branches/release/boost/proto/proto_fwd.hpp (original)
+++ branches/release/boost/proto/proto_fwd.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -404,6 +404,8 @@
     template<typename Grammar>
     struct vararg;
 
+ struct pack;
+
     // Boost bug https://svn.boost.org/trac/boost/ticket/4602
     //int const N = INT_MAX;
     int const N = (INT_MAX >> 10);

Modified: branches/release/boost/proto/transform/call.hpp
==============================================================================
--- branches/release/boost/proto/transform/call.hpp (original)
+++ branches/release/boost/proto/transform/call.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -29,6 +29,7 @@
 #include <boost/proto/transform/impl.hpp>
 #include <boost/proto/detail/as_lvalue.hpp>
 #include <boost/proto/detail/poly_function.hpp>
+#include <boost/proto/transform/detail/pack.hpp>
 
 namespace boost { namespace proto
 {
@@ -84,6 +85,29 @@
       : PrimitiveTransform
     {};
 
+ /// \brief A specialization that treats function pointer Transforms as
+ /// if they were function type Transforms.
+ ///
+ /// This specialization requires that \c Fun is actually a function type.
+ ///
+ /// This specialization is required for nested transforms such as
+ /// <tt>call\<T0(T1(_))\></tt>. In C++, functions that are used as
+ /// parameters to other functions automatically decay to funtion
+ /// pointer types. In other words, the type <tt>T0(T1(_))</tt> is
+ /// indistinguishable from <tt>T0(T1(*)(_))</tt>. This specialization
+ /// is required to handle these nested function pointer type transforms
+ /// properly.
+ template<typename Fun>
+ struct call<Fun *>
+ : call<Fun>
+ {};
+
+ /// INTERNAL ONLY
+ template<typename Fun>
+ struct call<detail::msvc_fun_workaround<Fun> >
+ : call<Fun>
+ {};
+
     /// \brief Either call the PolymorphicFunctionObject with 0
     /// arguments, or invoke the PrimitiveTransform with 3
     /// arguments.

Modified: branches/release/boost/proto/transform/detail/call.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/call.hpp (original)
+++ branches/release/boost/proto/transform/detail/call.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -31,11 +31,9 @@
         #pragma wave option(preserve: 1)
     #endif
 
- #if BOOST_PROTO_MAX_ARITY > 3
     #define BOOST_PP_ITERATION_PARAMS_1 \
- (3, (4, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/detail/call.hpp>))
+ (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/detail/call.hpp>))
     #include BOOST_PP_ITERATE()
- #endif
 
     #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
         #pragma wave option(output: null)
@@ -48,6 +46,7 @@
 
     #define N BOOST_PP_ITERATION()
 
+ #if N > 3
     /// \brief Call the PolymorphicFunctionObject \c Fun with the
     /// current expression, state and data, transformed according
     /// to \c A0 through \c AN.
@@ -81,6 +80,30 @@
             }
         };
     };
+ #endif
+
+ #if N > 0
+ /// \brief Call the PolymorphicFunctionObject \c Fun with the
+ /// current expression, state and data, transformed according
+ /// to \c A0 through \c AN.
+ template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct call<Fun(BOOST_PP_ENUM_PARAMS(N, A)...)> : transform<call<Fun(BOOST_PP_ENUM_PARAMS(N, A)...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value // BUGBUG this isn't right. Could be pack(_child), should use arity of child!
+ , BOOST_PP_CAT(A, BOOST_PP_DEC(N))
+ , detail::BOOST_PP_CAT(expand_pattern_rest_, BOOST_PP_DEC(N))<
+ Fun
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_DEC(N), A)
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+ #endif
 
     #undef N
 

Modified: branches/release/boost/proto/transform/detail/lazy.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/lazy.hpp (original)
+++ branches/release/boost/proto/transform/detail/lazy.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -53,6 +53,27 @@
         {};
     };
 
+ #if N > 0
+ template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct lazy<Object(BOOST_PP_ENUM_PARAMS(N, A)...)>
+ : transform<lazy<Object(BOOST_PP_ENUM_PARAMS(N, A)...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , BOOST_PP_CAT(A, BOOST_PP_DEC(N))
+ , detail::BOOST_PP_CAT(expand_pattern_rest_, BOOST_PP_DEC(N))<
+ Object
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_DEC(N), A)
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+ #endif
+
     #undef N
 
 #endif

Modified: branches/release/boost/proto/transform/detail/make.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/make.hpp (original)
+++ branches/release/boost/proto/transform/detail/make.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -173,6 +173,30 @@
         };
     };
 
+ #if N > 0
+ /// \brief A PrimitiveTransform which computes a type by evaluating any
+ /// nested transforms and then constructs an object of that type with the
+ /// current expression, state and data, transformed according
+ /// to \c A0 through \c AN.
+ template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make<Object(BOOST_PP_ENUM_PARAMS(N, A)...)>
+ : transform<make<Object(BOOST_PP_ENUM_PARAMS(N, A)...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , BOOST_PP_CAT(A, BOOST_PP_DEC(N))
+ , detail::BOOST_PP_CAT(expand_pattern_rest_, BOOST_PP_DEC(N))<
+ Object
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_DEC(N), A)
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+ #endif
     #undef N
 
 #endif

Copied: branches/release/boost/proto/transform/detail/pack.hpp (from r79461, /trunk/boost/proto/transform/detail/pack.hpp)
==============================================================================
--- /trunk/boost/proto/transform/detail/pack.hpp (original)
+++ branches/release/boost/proto/transform/detail/pack.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -23,6 +23,7 @@
 #include <boost/preprocessor/iteration/iterate.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
 #include <boost/proto/proto_fwd.hpp>
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -52,6 +53,12 @@
         template<typename Tfx, typename T>
         struct expand_pattern_helper<Tfx, pack(T)>
         {
+ // BUGBUG fix me. See comment in transform/detail/call.hpp
+ BOOST_MPL_ASSERT_MSG(
+ (is_same<T, _>::value)
+ , PACK_EXPANSIONS_OF_EXPRESSIONS_OTHER_THAN_THE_CURRENT_NOT_YET_SUPPORTED
+ , (T)
+ );
             typedef Tfx type(T);
             typedef mpl::true_ applied;
         };

Copied: branches/release/boost/proto/transform/detail/pack_impl.hpp (from r79461, /trunk/boost/proto/transform/detail/pack_impl.hpp)
==============================================================================
--- /trunk/boost/proto/transform/detail/pack_impl.hpp (original)
+++ branches/release/boost/proto/transform/detail/pack_impl.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -40,7 +40,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };

Modified: branches/release/boost/proto/transform/detail/preprocessed/call.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/preprocessed/call.hpp (original)
+++ branches/release/boost/proto/transform/detail/preprocessed/call.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -8,6 +8,66 @@
     
     
     
+ template<typename Fun , typename A0>
+ struct call<Fun(A0...)> : transform<call<Fun(A0...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A0
+ , detail::expand_pattern_rest_0<
+ Fun
+
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
+ template<typename Fun , typename A0 , typename A1>
+ struct call<Fun(A0 , A1...)> : transform<call<Fun(A0 , A1...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A1
+ , detail::expand_pattern_rest_1<
+ Fun
+ , A0
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
+ template<typename Fun , typename A0 , typename A1 , typename A2>
+ struct call<Fun(A0 , A1 , A2...)> : transform<call<Fun(A0 , A1 , A2...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A2
+ , detail::expand_pattern_rest_2<
+ Fun
+ , A0 , A1
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3>
     struct call<Fun(A0 , A1 , A2 , A3)> : transform<call<Fun(A0 , A1 , A2 , A3)> >
     {
@@ -39,6 +99,26 @@
     
     
     
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3>
+ struct call<Fun(A0 , A1 , A2 , A3...)> : transform<call<Fun(A0 , A1 , A2 , A3...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A3
+ , detail::expand_pattern_rest_3<
+ Fun
+ , A0 , A1 , A2
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
     struct call<Fun(A0 , A1 , A2 , A3 , A4)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4)> >
     {
@@ -70,6 +150,26 @@
     
     
     
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
+ struct call<Fun(A0 , A1 , A2 , A3 , A4...)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A4
+ , detail::expand_pattern_rest_4<
+ Fun
+ , A0 , A1 , A2 , A3
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
     struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5)> >
     {
@@ -101,6 +201,26 @@
     
     
     
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
+ struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5...)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A5
+ , detail::expand_pattern_rest_5<
+ Fun
+ , A0 , A1 , A2 , A3 , A4
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
     struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6)> >
     {
@@ -132,6 +252,26 @@
     
     
     
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
+ struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6...)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A6
+ , detail::expand_pattern_rest_6<
+ Fun
+ , A0 , A1 , A2 , A3 , A4 , A5
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
     struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)> >
     {
@@ -163,6 +303,26 @@
     
     
     
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
+ struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A7
+ , detail::expand_pattern_rest_7<
+ Fun
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
     struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)> >
     {
@@ -194,6 +354,26 @@
     
     
     
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
+ struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A8
+ , detail::expand_pattern_rest_8<
+ Fun
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+
+
     template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
     struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)> >
     {
@@ -222,3 +402,23 @@
             }
         };
     };
+
+
+
+ template<typename Fun , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
+ struct call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)> : transform<call<Fun(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A9
+ , detail::expand_pattern_rest_9<
+ Fun
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };

Modified: branches/release/boost/proto/transform/detail/preprocessed/lazy.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/preprocessed/lazy.hpp (original)
+++ branches/release/boost/proto/transform/detail/preprocessed/lazy.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -45,6 +45,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0>
+ struct lazy<Object(A0...)>
+ : transform<lazy<Object(A0...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A0
+ , detail::expand_pattern_rest_0<
+ Object
+
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -65,6 +83,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1>
+ struct lazy<Object(A0 , A1...)>
+ : transform<lazy<Object(A0 , A1...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A1
+ , detail::expand_pattern_rest_1<
+ Object
+ , A0
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -85,6 +121,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2>
+ struct lazy<Object(A0 , A1 , A2...)>
+ : transform<lazy<Object(A0 , A1 , A2...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A2
+ , detail::expand_pattern_rest_2<
+ Object
+ , A0 , A1
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -105,6 +159,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3>
+ struct lazy<Object(A0 , A1 , A2 , A3...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A3
+ , detail::expand_pattern_rest_3<
+ Object
+ , A0 , A1 , A2
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -125,6 +197,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
+ struct lazy<Object(A0 , A1 , A2 , A3 , A4...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3 , A4...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A4
+ , detail::expand_pattern_rest_4<
+ Object
+ , A0 , A1 , A2 , A3
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -145,6 +235,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
+ struct lazy<Object(A0 , A1 , A2 , A3 , A4 , A5...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3 , A4 , A5...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A5
+ , detail::expand_pattern_rest_5<
+ Object
+ , A0 , A1 , A2 , A3 , A4
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -165,6 +273,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
+ struct lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A6
+ , detail::expand_pattern_rest_6<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -185,6 +311,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
+ struct lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A7
+ , detail::expand_pattern_rest_7<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -205,6 +349,24 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
+ struct lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A8
+ , detail::expand_pattern_rest_8<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     
     
     
@@ -225,3 +387,21 @@
>::template impl<Expr, State, Data>
         {};
     };
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
+ struct lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)>
+ : transform<lazy<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : lazy<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A9
+ , detail::expand_pattern_rest_9<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };

Modified: branches/release/boost/proto/transform/detail/preprocessed/make.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/preprocessed/make.hpp (original)
+++ branches/release/boost/proto/transform/detail/preprocessed/make.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -180,6 +180,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0>
+ struct make<Object(A0...)>
+ : transform<make<Object(A0...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A0
+ , detail::expand_pattern_rest_0<
+ Object
+
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -282,6 +304,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1>
+ struct make<Object(A0 , A1...)>
+ : transform<make<Object(A0 , A1...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A1
+ , detail::expand_pattern_rest_1<
+ Object
+ , A0
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -384,6 +428,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2>
+ struct make<Object(A0 , A1 , A2...)>
+ : transform<make<Object(A0 , A1 , A2...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A2
+ , detail::expand_pattern_rest_2<
+ Object
+ , A0 , A1
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -486,6 +552,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3>
+ struct make<Object(A0 , A1 , A2 , A3...)>
+ : transform<make<Object(A0 , A1 , A2 , A3...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A3
+ , detail::expand_pattern_rest_3<
+ Object
+ , A0 , A1 , A2
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -588,6 +676,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
+ struct make<Object(A0 , A1 , A2 , A3 , A4...)>
+ : transform<make<Object(A0 , A1 , A2 , A3 , A4...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A4
+ , detail::expand_pattern_rest_4<
+ Object
+ , A0 , A1 , A2 , A3
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -690,6 +800,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
+ struct make<Object(A0 , A1 , A2 , A3 , A4 , A5...)>
+ : transform<make<Object(A0 , A1 , A2 , A3 , A4 , A5...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A5
+ , detail::expand_pattern_rest_5<
+ Object
+ , A0 , A1 , A2 , A3 , A4
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -792,6 +924,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
+ struct make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6...)>
+ : transform<make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A6
+ , detail::expand_pattern_rest_6<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -894,6 +1048,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
+ struct make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)>
+ : transform<make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A7
+ , detail::expand_pattern_rest_7<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -996,6 +1172,28 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
+ struct make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)>
+ : transform<make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A8
+ , detail::expand_pattern_rest_8<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
     namespace detail
     {
         template<
@@ -1098,3 +1296,25 @@
             }
         };
     };
+
+
+
+
+ template<typename Object , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
+ struct make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)>
+ : transform<make<Object(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : make<
+ typename detail::expand_pattern<
+ proto::arity_of<Expr>::value
+ , A9
+ , detail::expand_pattern_rest_9<
+ Object
+ , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
+ >
+ >::type
+ >::template impl<Expr, State, Data>
+ {};
+ };

Copied: branches/release/boost/proto/transform/detail/preprocessed/pack_impl.hpp (from r79461, /trunk/boost/proto/transform/detail/preprocessed/pack_impl.hpp)
==============================================================================
--- /trunk/boost/proto/transform/detail/preprocessed/pack_impl.hpp (original)
+++ branches/release/boost/proto/transform/detail/preprocessed/pack_impl.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -11,7 +11,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -77,7 +77,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -138,7 +138,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -194,7 +194,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -245,7 +245,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -291,7 +291,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -332,7 +332,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -368,7 +368,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -399,7 +399,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };
@@ -425,7 +425,7 @@
         {
             BOOST_MPL_ASSERT_MSG(
                 (expand_pattern_helper<proto::_child_c<0>, Fun>::applied::value)
- , NO_PACK_EXPRESSION_FOUND_IN_PACK_EXPANSION
+ , NO_PACK_EXPRESSION_FOUND_IN_UNPACKING_PATTERN
               , (Fun)
             );
         };

Modified: branches/release/boost/proto/transform/detail/preprocessed/when.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/preprocessed/when.hpp (original)
+++ branches/release/boost/proto/transform/detail/preprocessed/when.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -33,46 +33,8 @@
     
     template<typename Grammar, typename R >
     struct when<Grammar, R()>
- : transform<when<Grammar, R()> >
- {
- typedef Grammar first;
- typedef R second();
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R()>
- , make<R()>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R()>
+ {};
     
     
     
@@ -101,46 +63,38 @@
     
     template<typename Grammar, typename R , typename A0>
     struct when<Grammar, R(A0)>
- : transform<when<Grammar, R(A0)> >
- {
- typedef Grammar first;
- typedef R second(A0);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0)>
- , make<R(A0)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0>
+ struct when<Grammar, R(A0...)>
+ : detail::when_impl<Grammar, R, R(A0...)>
+ {};
     
     
     
@@ -169,46 +123,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1>
     struct when<Grammar, R(A0 , A1)>
- : transform<when<Grammar, R(A0 , A1)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1)>
- , make<R(A0 , A1)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1>
+ struct when<Grammar, R(A0 , A1...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1...)>
+ {};
     
     
     
@@ -237,46 +183,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2>
     struct when<Grammar, R(A0 , A1 , A2)>
- : transform<when<Grammar, R(A0 , A1 , A2)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2)>
- , make<R(A0 , A1 , A2)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2>
+ struct when<Grammar, R(A0 , A1 , A2...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2...)>
+ {};
     
     
     
@@ -305,46 +243,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3>
     struct when<Grammar, R(A0 , A1 , A2 , A3)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3)>
- , make<R(A0 , A1 , A2 , A3)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3>
+ struct when<Grammar, R(A0 , A1 , A2 , A3...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3...)>
+ {};
     
     
     
@@ -373,46 +303,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
     struct when<Grammar, R(A0 , A1 , A2 , A3 , A4)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3 , A4)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3 , A4);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3 , A4)>
- , make<R(A0 , A1 , A2 , A3 , A4)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
+ struct when<Grammar, R(A0 , A1 , A2 , A3 , A4...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4...)>
+ {};
     
     
     
@@ -441,46 +363,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
     struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3 , A4 , A5);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3 , A4 , A5)>
- , make<R(A0 , A1 , A2 , A3 , A4 , A5)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
+ struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5...)>
+ {};
     
     
     
@@ -509,46 +423,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
     struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3 , A4 , A5 , A6);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3 , A4 , A5 , A6)>
- , make<R(A0 , A1 , A2 , A3 , A4 , A5 , A6)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
+ struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6...)>
+ {};
     
     
     
@@ -577,46 +483,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
     struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)>
- , make<R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
+ struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7...)>
+ {};
     
     
     
@@ -645,46 +543,38 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
     struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)>
- , make<R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
+ struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8...)>
+ {};
     
     
     
@@ -713,43 +603,35 @@
     
     template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
     struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)>
- : transform<when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)> >
- {
- typedef Grammar first;
- typedef R second(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9);
- typedef typename Grammar::proto_grammar proto_grammar;
-
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
-
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)>
- , make<R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)>
- >::type
- which;
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
-
-
-
-
-
-
-
-
-
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9)>
+ {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template<typename Grammar, typename R , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
+ struct when<Grammar, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)>
+ : detail::when_impl<Grammar, R, R(A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9...)>
+ {};

Modified: branches/release/boost/proto/transform/detail/when.hpp
==============================================================================
--- branches/release/boost/proto/transform/detail/when.hpp (original)
+++ branches/release/boost/proto/transform/detail/when.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -60,50 +60,41 @@
     /// ObjectTransforms.
     template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
     struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))>
- : transform<when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))> >
- {
- typedef Grammar first;
- typedef R second(BOOST_PP_ENUM_PARAMS(N, A));
- typedef typename Grammar::proto_grammar proto_grammar;
+ : detail::when_impl<Grammar, R, R(BOOST_PP_ENUM_PARAMS(N, A))>
+ {};
 
- // Note: do not evaluate is_callable<R> in this scope.
- // R may be an incomplete type at this point.
-
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
- // OK to evaluate is_callable<R> here. R should be compete by now.
- typedef
- typename mpl::if_c<
- is_callable<R>::value
- , call<R(BOOST_PP_ENUM_PARAMS(N, A))> // "R" is a function to call
- , make<R(BOOST_PP_ENUM_PARAMS(N, A))> // "R" is an object to construct
- >::type
- which;
-
- typedef typename which::template impl<Expr, State, Data>::result_type result_type;
-
- /// 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
- /// \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
- /// \return <tt>which()(e, s, d)</tt>
- BOOST_FORCEINLINE
- result_type operator ()(
- typename impl::expr_param e
- , typename impl::state_param s
- , typename impl::data_param d
- ) const
- {
- return typename which::template impl<Expr, State, Data>()(e, s, d);
- }
- };
- };
+ #if N > 0
+ /// \brief A grammar element and a PrimitiveTransform that associates
+ /// a transform with the grammar.
+ ///
+ /// Use <tt>when\<\></tt> to override a grammar's default transform
+ /// with a custom transform. It is for used when composing larger
+ /// transforms by associating smaller transforms with individual
+ /// rules in your grammar, as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// 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
+ /// distinguish between the two, and uses <tt>call\<\></tt> to
+ /// evaluate CallableTransforms and <tt>make\<\></tt> to evaluate
+ /// ObjectTransforms.
+ template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A)...)>
+ : detail::when_impl<Grammar, R, R(BOOST_PP_ENUM_PARAMS(N, A)...)>
+ {};
+ #endif
 
     #undef N
 

Modified: branches/release/boost/proto/transform/lazy.hpp
==============================================================================
--- branches/release/boost/proto/transform/lazy.hpp (original)
+++ branches/release/boost/proto/transform/lazy.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -16,6 +16,7 @@
 #include <boost/proto/transform/make.hpp>
 #include <boost/proto/transform/call.hpp>
 #include <boost/proto/transform/impl.hpp>
+#include <boost/proto/transform/detail/pack.hpp>
 
 namespace boost { namespace proto
 {
@@ -38,6 +39,12 @@
         {};
     };
 
+ /// INTERNAL ONLY
+ template<typename Fun>
+ struct lazy<detail::msvc_fun_workaround<Fun> >
+ : lazy<Fun>
+ {};
+
     #include <boost/proto/transform/detail/lazy.hpp>
 
     /// INTERNAL ONLY

Modified: branches/release/boost/proto/transform/make.hpp
==============================================================================
--- branches/release/boost/proto/transform/make.hpp (original)
+++ branches/release/boost/proto/transform/make.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -29,6 +29,7 @@
 #include <boost/proto/traits.hpp>
 #include <boost/proto/args.hpp>
 #include <boost/proto/transform/impl.hpp>
+#include <boost/proto/transform/detail/pack.hpp>
 #include <boost/proto/detail/as_lvalue.hpp>
 #include <boost/proto/detail/ignore_unused.hpp>
 
@@ -250,6 +251,12 @@
         };
     };
 
+ /// INTERNAL ONLY
+ template<typename Fun>
+ struct make<detail::msvc_fun_workaround<Fun> >
+ : make<Fun>
+ {};
+
     // Other specializations generated by the preprocessor.
     #include <boost/proto/transform/detail/make.hpp>
     #include <boost/proto/transform/detail/make_gcc_workaround.hpp>

Modified: branches/release/boost/proto/transform/when.hpp
==============================================================================
--- branches/release/boost/proto/transform/when.hpp (original)
+++ branches/release/boost/proto/transform/when.hpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -29,6 +29,56 @@
 
 namespace boost { namespace proto
 {
+ namespace detail
+ {
+ template<typename Grammar, typename R, typename Fun>
+ struct when_impl
+ : transform<when<Grammar, Fun> >
+ {
+ typedef Grammar first;
+ typedef Fun second;
+ typedef typename Grammar::proto_grammar proto_grammar;
+
+ // Note: do not evaluate is_callable<R> in this scope.
+ // R may be an incomplete type at this point.
+
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ // OK to evaluate is_callable<R> here. R should be compete by now.
+ typedef
+ typename mpl::if_c<
+ is_callable<R>::value
+ , proto::call<Fun> // "R" is a function to call
+ , proto::make<Fun> // "R" is an object to construct
+ >::type
+ which;
+
+ typedef typename which::template impl<Expr, State, Data>::result_type result_type;
+
+ /// 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
+ /// \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
+ /// \return <tt>which()(e, s, d)</tt>
+ BOOST_FORCEINLINE
+ result_type operator ()(
+ typename impl::expr_param e
+ , typename impl::state_param s
+ , typename impl::data_param d
+ ) const
+ {
+ return typename which::template impl<Expr, State, Data>()(e, s, d);
+ }
+ };
+ };
+ }
+
     /// \brief A grammar element and a PrimitiveTransform that associates
     /// a transform with the grammar.
     ///

Modified: branches/release/libs/proto/doc/back_end.qbk
==============================================================================
--- branches/release/libs/proto/doc/back_end.qbk (original)
+++ branches/release/libs/proto/doc/back_end.qbk 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -1158,6 +1158,102 @@
 
 [endsect]
 
+[/==================================================]
+[section:unpacking_expressions Unpacking Expressions]
+[/==================================================]
+
+Processing expressions with an arbitrary number of children can be a pain. What if you want to do something to each child, then pass the results as arguments to some other function? Can you do it just once without worrying about how many children an expression has? Yes. This is where Proto's /unpacking expressions/ come in handy. Unpacking expressions give you a way to write callable and object transforms that handle ['n]-ary expressions.
+
+[note *Inspired by C++11 Variadic Templates*
+
+Proto's unpacking expressions take inspiration from the C++11 feature of the same name. If you are familiar with variadic functions, and in particular how to expand a function parameter pack, this discussion should seem very familiar. However, this feature doesn't actually use any C++11 features, so the code describe here will work with any compliant C++98 compiler.]
+
+[heading Example: A C++ Expression Evaluator]
+
+Proto has the built-in _default_pt_ transform for evaluating Proto expressions in a C++-ish way. But if it didn't, it wouldn't be too hard to implement one from scratch using Proto's unpacking patterns. The transform `eval` below does just that.
+
+
+ template<typename T> T declval();
+
+ // A callable polymorphic function object that takes an unpacked expression
+ // and a tag, and evaluates the expression. A plus tag and two operands adds
+ // them with operator +, for instance.
+ struct do_eval : proto::callable
+ {
+ typedef double result_type;
+
+ #define UNARY_OP(TAG, OP) \
+ template<typename Arg> \
+ double operator()(proto::tag::TAG, Arg arg) const \
+ { \
+ return OP arg; \
+ } \
+ /**/
+
+ #define BINARY_OP(TAG, OP) \
+ template<typename Left, typename Right> \
+ double operator()(proto::tag::TAG, Left left, Right right) const \
+ { \
+ return left OP right; \
+ } \
+ /**/
+
+ UNARY_OP(negate, -)
+ BINARY_OP(plus, +)
+ BINARY_OP(minus, -)
+ BINARY_OP(multiplies, *)
+ BINARY_OP(divides, /)
+ /*... others ...*/
+ };
+
+ struct eval
+ : proto::or_<
+ // Evaluate terminals by simply returning their value
+ proto::when<proto::terminal<_>, proto::_value>
+
+ // Non-terminals are handled by unpacking the expression,
+ // recursively calling eval on each child, and passing
+ // the results along with the expression's tag to do_eval
+ // defined above.
+ , proto::otherwise<do_eval(proto::tag_of<_>(), eval(proto::pack(_))...)>
+ // UNPACKING PATTERN HERE -------------------^^^^^^^^^^^^^^^^^^^^^^^^
+ >
+ {};
+
+The bulk of the above code is devoted to the `do_eval` function object that maps tag types to behaviors, but the interesting bit is the definition of the `eval` algorithm at the bottom. Terminals are handled quite simply, but non-terminals could be unary, binary, ternary, even ['n]-ary if we consider function call expressions. The `eval` algorithm handles this uniformly with the help of an unpacking pattern.
+
+Non-terminals are evaluated with this callable transform:
+
+ do_eval(proto::tag_of<_>(), eval(proto::pack(_))...)
+
+You can read this as: call the `do_eval` function object with the tag of the current expression and all its children after they have each been evaluated with `eval`. The unpacking pattern is the bit just before the ellipsis: `eval(proto::pack(_))`.
+
+What's going on here is this. The unpacking expression gets repeated once for each child in the expression currently being evaluated. In each repetition, the type `proto::pack(_)` gets replaced with [^proto::_child_c<['N]>]. So, if a unary expression is passed to `eval`, it actually gets evaluated like this:
+
+ // After the unpacking pattern is expanded for a unary expression
+ do_eval(proto::tag_of<_>(), eval(proto::_child_c<0>))
+
+And when passed a binary expression, the unpacking pattern expands like this:
+
+ // After the unpacking pattern is expanded for a binary expression
+ do_eval(proto::tag_of<_>(), eval(proto::_child_c<0>), eval(proto::_child_c<1>))
+
+Although it can't happen in our example, when passed a terminal, the unpacking pattern expands such that it extracts the value from the terminal instead of the children. So it gets handled like this:
+
+ // If a terminal were passed to this transform, Proto would try
+ // to evaluate it like this, which would fail:
+ do_eval(proto::tag_of<_>(), eval(proto::_value))
+
+That doesn't make sense. `proto::_value` would return something that isn't a Proto expression, and `eval` wouldn't be able to evaluate it. Proto algorithms don't work unless you pass them Proto expressions.
+
+[note *Kickin' It Old School*
+
+You may be thinking, my compiler doesn't support C++11 variadic templates! How can this possibly work? The answer is simple: The `...` above isn't a C++11 pack expansion. It's actually an old-school C-style vararg. Remember that callable and object transforms are /function types/. A transform with one of these pseudo-pack expansions is really just the type of a boring, old vararg function. Proto just interprets it differently.]
+
+Unpacking patterns are very expressive. Any callable or object transform can be used as an unpacking pattern, so long as `proto::pack(_)` appears exactly once somewhere within it. This gives you a lot of flexibility in how you want to process the children of an expression before passing them on to some function object or object constructor.
+
+[endsect]
+
 [/=============================================================]
 [section:external_transforms Separating Grammars And Transforms]
 [/=============================================================]

Modified: branches/release/libs/proto/doc/proto.qbk
==============================================================================
--- branches/release/libs/proto/doc/proto.qbk (original)
+++ branches/release/libs/proto/doc/proto.qbk 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -179,6 +179,8 @@
   [classref boost::proto::deduce_domain `proto::deduce_domain`]]
 [def _lazy_pt_
   [classref boost::proto::lazy `proto::lazy<>`]]
+[def _pack_
+ [classref boost::proto::pack `proto::pack`]]
 [def _SYB_
   [link boost_proto.users_guide.resources.SYB ["Scrap Your Boilerplate]]]
 [def _result_of_value_

Modified: branches/release/libs/proto/doc/reference.xml
==============================================================================
--- branches/release/libs/proto/doc/reference.xml (original)
+++ branches/release/libs/proto/doc/reference.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -609,6 +609,11 @@
       </listitem>
       <listitem>
         <computeroutput>
+ <classname alt="boost::proto::pack">proto::pack</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
           <classname alt="boost::proto::pass_through">proto::pass_through</classname>
         </computeroutput>
       </listitem>

Modified: branches/release/libs/proto/doc/reference/repeat.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/repeat.xml (original)
+++ branches/release/libs/proto/doc/reference/repeat.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -305,7 +305,7 @@
       Generates sequences like
       <computeroutput>
         typename A<subscript>0</subscript>,
- typename A<subscript>1</subscript>, ...
+ typename A<subscript>1</subscript>, …
         typename A<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -318,7 +318,7 @@
         <computeroutput>BOOST_PROTO_typename_A(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>typename A<subscript>0</subscript>, typename A<subscript>1</subscript>, ... typename A<subscript>N-1</subscript></programlisting>
+ <programlisting>typename A<subscript>0</subscript>, typename A<subscript>1</subscript>, … typename A<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -329,7 +329,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> const &amp;,
- A<subscript>1</subscript> const &amp;, ...
+ A<subscript>1</subscript> const &amp;, …
         A<subscript>N-1</subscript> const &amp;
       </computeroutput>.
     </purpose>
@@ -342,7 +342,7 @@
         <computeroutput>BOOST_PROTO_A_const_ref(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>A<subscript>0</subscript> const &amp;, A<subscript>1</subscript> const &amp;, ... A<subscript>N-1</subscript> const &amp;</programlisting>
+ <programlisting>A<subscript>0</subscript> const &amp;, A<subscript>1</subscript> const &amp;, … A<subscript>N-1</subscript> const &amp;</programlisting>
       </para>
     </description>
   </macro>
@@ -353,7 +353,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> &amp;,
- A<subscript>1</subscript> &amp;, ...
+ A<subscript>1</subscript> &amp;, …
         A<subscript>N-1</subscript> &amp;
       </computeroutput>.
     </purpose>
@@ -366,7 +366,7 @@
         <computeroutput>BOOST_PROTO_A_ref(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>A<subscript>0</subscript> &amp;, A<subscript>1</subscript> &amp;, ... A<subscript>N-1</subscript> &amp;</programlisting>
+ <programlisting>A<subscript>0</subscript> &amp;, A<subscript>1</subscript> &amp;, … A<subscript>N-1</subscript> &amp;</programlisting>
       </para>
     </description>
   </macro>
@@ -377,7 +377,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript>,
- A<subscript>1</subscript>, ...
+ A<subscript>1</subscript>, …
         A<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -390,7 +390,7 @@
         <computeroutput>BOOST_PROTO_A(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>A<subscript>0</subscript>, A<subscript>1</subscript>, ... A<subscript>N-1</subscript></programlisting>
+ <programlisting>A<subscript>0</subscript>, A<subscript>1</subscript>, … A<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -401,7 +401,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> const,
- A<subscript>1</subscript> const, ...
+ A<subscript>1</subscript> const, …
         A<subscript>N-1</subscript> const
       </computeroutput>.
     </purpose>
@@ -414,7 +414,7 @@
         <computeroutput>BOOST_PROTO_A_const(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>A<subscript>0</subscript> const, A<subscript>1</subscript> const, ... A<subscript>N-1</subscript> const</programlisting>
+ <programlisting>A<subscript>0</subscript> const, A<subscript>1</subscript> const, … A<subscript>N-1</subscript> const</programlisting>
       </para>
     </description>
   </macro>
@@ -425,7 +425,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> const &amp; a<subscript>0</subscript>,
- A<subscript>1</subscript> const &amp; a<subscript>1</subscript>, ...
+ A<subscript>1</subscript> const &amp; a<subscript>1</subscript>, …
         A<subscript>N-1</subscript> const &amp; a<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -438,7 +438,7 @@
         <computeroutput>BOOST_PROTO_A_const_ref_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>A<subscript>0</subscript> const &amp; a<subscript>0</subscript>, A<subscript>1</subscript> const &amp; a<subscript>1</subscript>, ... A<subscript>N-1</subscript> const &amp; a<subscript>N-1</subscript></programlisting>
+ <programlisting>A<subscript>0</subscript> const &amp; a<subscript>0</subscript>, A<subscript>1</subscript> const &amp; a<subscript>1</subscript>, … A<subscript>N-1</subscript> const &amp; a<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -449,7 +449,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> &amp; a<subscript>0</subscript>,
- A<subscript>1</subscript> &amp; a<subscript>1</subscript>, ...
+ A<subscript>1</subscript> &amp; a<subscript>1</subscript>, …
         A<subscript>N-1</subscript> &amp; a<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -462,7 +462,7 @@
         <computeroutput>BOOST_PROTO_A_ref_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>A<subscript>0</subscript> &amp; a<subscript>0</subscript>, A<subscript>1</subscript> &amp; a<subscript>1</subscript>, ... A<subscript>N-1</subscript> &amp; a<subscript>N-1</subscript></programlisting>
+ <programlisting>A<subscript>0</subscript> &amp; a<subscript>0</subscript>, A<subscript>1</subscript> &amp; a<subscript>1</subscript>, … A<subscript>N-1</subscript> &amp; a<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -473,7 +473,7 @@
       Generates sequences like
       <computeroutput>
         boost::ref(a<subscript>0</subscript>),
- boost::ref(a<subscript>1</subscript>), ...
+ boost::ref(a<subscript>1</subscript>), …
         boost::ref(a<subscript>N-1</subscript>)
       </computeroutput>.
     </purpose>
@@ -486,7 +486,7 @@
         <computeroutput>BOOST_PROTO_ref_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>boost::ref(a<subscript>0</subscript>), boost::ref(a<subscript>1</subscript>), ... boost::ref(a<subscript>N-1</subscript>)</programlisting>
+ <programlisting>boost::ref(a<subscript>0</subscript>), boost::ref(a<subscript>1</subscript>), … boost::ref(a<subscript>N-1</subscript>)</programlisting>
       </para>
     </description>
   </macro>
@@ -497,7 +497,7 @@
       Generates sequences like
       <computeroutput>
         a<subscript>0</subscript>,
- a<subscript>1</subscript>, ...
+ a<subscript>1</subscript>, …
         a<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -510,7 +510,7 @@
         <computeroutput>BOOST_PROTO_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
- <programlisting>a<subscript>0</subscript>, a<subscript>1</subscript>, ... a<subscript>N-1</subscript></programlisting>
+ <programlisting>a<subscript>0</subscript>, a<subscript>1</subscript>, … a<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>

Modified: branches/release/libs/proto/doc/reference/transform/call.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/call.xml (original)
+++ branches/release/libs/proto/doc/reference/transform/call.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -105,15 +105,26 @@
                   <listitem>
                     <para>
                       If <computeroutput>T</computeroutput> is of the form
- <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then
+ <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then
                       <computeroutput>result_type</computeroutput> is:
                       <programlisting>typename boost::result_of&lt;PolymorphicFunctionObject(
   typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;(Expr, State, Data)&gt;::type,
- ...
+ …
   typename boost::result_of&lt;<classname>when</classname>&lt;<classname>_</classname>,A<subscript>n</subscript>&gt;(Expr, State, Data)&gt;::type
 &gt;::type</programlisting>
                     </para>
                   </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> is of the form
+ <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then
+ let <computeroutput>T&apos;</computeroutput> be <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
+ where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
+ as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>.
+ Then, <computeroutput>result_type</computeroutput> is:
+ <programlisting><computeroutput>typename <classname>proto::call</classname>&lt;T&apos;&gt;::impl&lt;Expr,State,Data&gt;::result_type</computeroutput></programlisting>
+ </para>
+ </listitem>
                 </itemizedlist>
               </para>
             </description>
@@ -188,7 +199,7 @@
                     <listitem>
                       <para>
                         If <computeroutput>T</computeroutput> is of the form
- <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then
+ <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then
                         return:
                         <programlisting>PolymorphicFunctionObject()(
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
@@ -197,6 +208,17 @@
 )</programlisting>
                       </para>
                     </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> is of the form
+ <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then
+ let <computeroutput>T&apos;</computeroutput> be <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
+ where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
+ as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>.
+ Then, return:
+ <programlisting><computeroutput><classname>proto::call</classname>&lt;T&apos;&gt;()(expr, state, data)</computeroutput></programlisting>
+ </para>
+ </listitem>
                   </itemizedlist>
                 </para>
               </description>

Modified: branches/release/libs/proto/doc/reference/transform/impl.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/impl.xml (original)
+++ branches/release/libs/proto/doc/reference/transform/impl.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -183,6 +183,124 @@
           <type>typename boost::add_reference&lt;Data const&gt;::type</type>
         </typedef>
       </struct>
+
+ <!-- proto::pack -->
+ <struct name="pack">
+ <purpose>To turn an expression into a pseudo-parameter pack containing the
+ expression's children, for the purpose of expanding the pack expression within
+ a <conceptname>CallableTransform</conceptname> or
+ <conceptname>ObjectTransform</conceptname>.</purpose>
+ <description>
+ <para>
+ <computeroutput>proto::pack</computeroutput> is useful within
+ <conceptname>CallableTransform</conceptname>s and
+ <conceptname>ObjectTransform</conceptname>s when one wishes to unpack an expression
+ into a function call or an object constructor. <computeroutput>proto::pack</computeroutput>
+ turns a Proto expression into a pseudo-parameter pack, which may appear in an unpacking
+ pattern to be expanded with the "<computeroutput>...</computeroutput>" syntax.
+ </para>
+
+ <para>
+ <emphasis role="bold">Example:</emphasis>
+ </para>
+
+ <para>
+ <programlisting>// The following demonstrates how to use a pseudo-pack expansion
+// to unpack an expression into a function call.
+
+struct do_sum : <classname alt="boost::proto::callable">proto::callable</classname>
+{
+ typedef int result_type;
+
+ int operator()(int i) const { return i; }
+ int operator()(int i, int j) const { return i + j; }
+ int operator()(int i, int j, int k) const { return i + j + k; }
+};
+
+// Take any n-ary expression where the children are all int terminals and sum all the ints
+struct sum
+ : <classname alt="boost::proto::when">proto::when</classname>&lt;
+
+ // Match any nary expression where the children are all int terminals
+ <classname alt="boost::proto::nary_expr">proto::nary_expr</classname>&lt;<classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::vararg">proto::vararg</classname>&lt;<classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt; &gt; &gt;
+
+ // Turn the current expression into a pseudo-parameter pack, then expand it,
+ // extracting the value from each child in turn.
+ , do_sum(<classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))...)
+ &gt;
+{};
+
+int main()
+{
+ <classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt;::type i = {42};
+ int result = sum()( i(3,5) ); // Creates a ternary functional-call expression
+ std::cout &lt;&lt; "Sum of 42, 3, and 5 : " &lt;&lt; result &lt;&lt; std::endl;
+}</programlisting>
+ </para>
+
+ <para>
+ The above program displays:
+ </para>
+
+ <para>
+ <computeroutput>Sum of 42, 3, and 5 : 50</computeroutput>
+ </para>
+
+ <para>
+ In the above example, the type
+ <computeroutput>
+ <classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))
+ </computeroutput>
+ is a so-called <emphasis>unpacking pattern</emphasis>, described below.
+ </para>
+
+ <para>
+ <emphasis role="bold">Unpacking Patterns:</emphasis>
+ </para>
+
+ <para>
+ Composite transforms (either <conceptname>CallableTransform</conceptname>s or
+ <conceptname>ObjectTransform</conceptname>s) usually have the form
+ <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>.
+ However, when the argument list in a composite transform is terminated with a C-style
+ vararg ellipsis as in <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
+ the final argument <computeroutput>A<subscript>n</subscript></computeroutput> is treated
+ as an <emphasis>unpacking pattern</emphasis>.
+ </para>
+
+ <para>
+ An unpacking pattern must itself be a composite transform; that is, it must be a
+ function type representing either a <conceptname>CallableTransform</conceptname> or
+ an <conceptname>ObjectTransform</conceptname>. The type <computeroutput>proto::pack(_)</computeroutput>
+ must appear exactly once in the unpacking pattern. This type will receive a substitution
+ when the unpacking pattern is expanded.
+ </para>
+
+ <para>
+ A composite transform like <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
+ when evaluated against a given expression <replaceable>E</replaceable>, state and data, is evaluated as if it were
+ <computeroutput>X(A<subscript>0</subscript>,…A<subscript>n-1</subscript>,<replaceable>S</replaceable>)</computeroutput>
+ where <replaceable>S</replaceable> is a type sequence computed as follows:
+ </para>
+ <para>
+ Let <computeroutput><replaceable>SUB</replaceable>(A,B)</computeroutput> be a type function that replaces every occurence of
+ <computeroutput>proto::pack(_)</computeroutput> within <computeroutput>A</computeroutput> with <computeroutput>B</computeroutput>.
+ <itemizedlist>
+ <listitem>
+ If the expression <replaceable>E</replaceable> is a terminal (i.e. it has arity 0), <replaceable>S</replaceable>
+ is the one-element sequence containing <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_value">proto::_value</classname>)</computeroutput>.
+ </listitem>
+ <listitem>
+ If the expression <replaceable>E</replaceable> is a non-terminal, <replaceable>S</replaceable> is the sequence
+ <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname>&lt;0&gt;),…
+ <replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname>&lt;<replaceable>M</replaceable>-1&gt;)</computeroutput>, where
+ <replaceable>M</replaceable> is the arity of the expression <replaceable>E</replaceable>.
+ </listitem>
+ </itemizedlist>
+ </para>
+ </description>
+ </struct>
+
     </namespace>
   </namespace>
 </header>

Modified: branches/release/libs/proto/doc/reference/transform/lazy.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/lazy.xml (original)
+++ branches/release/libs/proto/doc/reference/transform/lazy.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -64,9 +64,17 @@
                   <listitem>
                     <para>
                       If <computeroutput>T</computeroutput> if of the form
- <computeroutput>O(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
+ <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
                       be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
- and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>.
+ and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> if of the form
+ <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then let <computeroutput>O'</computeroutput>
+ be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
+ and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>.
                     </para>
                   </listitem>
                   <listitem>
@@ -104,9 +112,17 @@
                     <listitem>
                       <para>
                         If <computeroutput>T</computeroutput> if of the form
- <computeroutput>O(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
+ <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
+ be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
+ and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> if of the form
+ <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>, then let <computeroutput>O'</computeroutput>
                         be <computeroutput>boost::result_of&lt;<classname>proto::make</classname>&lt;O&gt;(Expr, State, Data)&gt;::type</computeroutput>
- and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>.
+ and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>.
                       </para>
                     </listitem>
                     <listitem>

Modified: branches/release/libs/proto/doc/reference/transform/make.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/make.xml (original)
+++ branches/release/libs/proto/doc/reference/transform/make.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -149,9 +149,7 @@
           <para>
             The purpose of <computeroutput>proto::make&lt;&gt;</computeroutput> is to annotate a transform as
             an <conceptname>ObjectTransform</conceptname> so that
- <computeroutput>
- <classname alt="proto::when">proto::when&lt;&gt;</classname>
- </computeroutput> knows
+ <computeroutput><classname alt="proto::when">proto::when&lt;&gt;</classname></computeroutput> knows
             how to apply it.
           </para>
 
@@ -180,7 +178,8 @@
               </para>
               <para>
                 If <computeroutput>T</computeroutput> is an <conceptname>ObjectTransform</conceptname> of the form
- <computeroutput>Object(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>,
+ <computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput> or
+ <computeroutput>Object(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
                 then let <computeroutput>O</computeroutput> be the return type
                 <computeroutput>Object</computeroutput>. Otherwise, let <computeroutput>O</computeroutput>
                 be <computeroutput>T</computeroutput>. The <computeroutput>result_type</computeroutput> typedef is
@@ -200,7 +199,7 @@
                   </listitem>
                   <listitem>
                     If <computeroutput>O</computeroutput> is a template like
- <computeroutput><classname>proto::noinvoke</classname>&lt;S&lt;X<subscript>0</subscript>,...X<subscript>n</subscript>&gt; &gt;</computeroutput>,
+ <computeroutput><classname>proto::noinvoke</classname>&lt;S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt; &gt;</computeroutput>,
                     then the result type is calculated as follows:
                     <itemizedlist>
                       <listitem>
@@ -222,7 +221,7 @@
                         <para>
                           The result type is
                           <computeroutput>
- S&lt;X<subscript>0</subscript>',...X<subscript>n</subscript>'&gt;
+ S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
                           </computeroutput>.
                         </para>
                       </listitem>
@@ -230,7 +229,7 @@
                   </listitem>
                   <listitem>
                     If <computeroutput>O</computeroutput> is a template like
- <computeroutput>S&lt;X<subscript>0</subscript>,...X<subscript>n</subscript>&gt;</computeroutput>,
+ <computeroutput>S&lt;X<subscript>0</subscript>,…X<subscript>n</subscript>&gt;</computeroutput>,
                     then the result type is calculated as follows:
                     <itemizedlist>
                       <listitem>
@@ -250,11 +249,11 @@
                         <para>
                           If any substitutions took place in the above step and
                           <computeroutput>
- S&lt;X<subscript>0</subscript>',...X<subscript>n</subscript>'&gt;
+ S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
                           </computeroutput> has a nested
                           <computeroutput>type</computeroutput> typedef, the result type is
                           <computeroutput>
- S&lt;X<subscript>0</subscript>',...X<subscript>n</subscript>'&gt;::type
+ S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;::type
                           </computeroutput>.
                         </para>
                       </listitem>
@@ -262,7 +261,7 @@
                         <para>
                           Otherwise, the result type is
                           <computeroutput>
- S&lt;X<subscript>0</subscript>',...X<subscript>n</subscript>'&gt;
+ S&lt;X<subscript>0</subscript>',…X<subscript>n</subscript>'&gt;
                           </computeroutput>.
                         </para>
                       </listitem>
@@ -306,7 +305,7 @@
                     <listitem>
                       <para>
                         If <computeroutput>T</computeroutput> is of the form
- <computeroutput>O(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then:
+ <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript>)</computeroutput>, then:
                       </para>
                       <itemizedlist>
                         <listitem>
@@ -317,7 +316,7 @@
                             and return an object <computeroutput>that</computeroutput> as follows:
                             <programlisting>result_type that = {
   <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
- ...
+ …
   <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
 };</programlisting>
                           </para>
@@ -328,7 +327,7 @@
                             and return an object <computeroutput>that</computeroutput> as follows:
                             <programlisting>result_type that(
   <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>0</subscript>&gt;()(expr, state, data),
- ...
+ …
   <classname>proto::when</classname>&lt;<classname>_</classname>, A<subscript>n</subscript>&gt;()(expr, state, data)
 );</programlisting>
                           </para>
@@ -337,9 +336,18 @@
                     </listitem>
                     <listitem>
                       <para>
- Otherwise, construct
- and return an object <computeroutput>that</computeroutput> as follows:
- <programlisting>result_type that = result_type();</programlisting>
+ If <computeroutput>T</computeroutput> is of the form
+ <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n</subscript> ...)</computeroutput>,
+ then let <computeroutput>T&apos;</computeroutput> be <computeroutput>O(A<subscript>0</subscript>,…A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
+ where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
+ as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>. Then, return:
+ <programlisting>proto::make&lt;T&apos;&gt;()(expr, state, data)</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, construct and return an object <computeroutput>that</computeroutput>
+ as follows: <programlisting>result_type that = result_type();</programlisting>
                       </para>
                     </listitem>
                   </itemizedlist>

Modified: branches/release/libs/proto/doc/reference/transform/when.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/when.xml (original)
+++ branches/release/libs/proto/doc/reference/transform/when.xml 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -199,6 +199,114 @@
       <struct-specialization name="when">
         <template>
           <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="A" pack="1"/>
+ </template>
+ <specialization>
+ <template-arg>Grammar</template-arg>
+ <template-arg>R(A..., ...)</template-arg>
+ </specialization>
+ <inherit><type><classname>proto::transform</classname>&lt; when&lt;Grammar, R(A..., ...)&gt; &gt;</type></inherit>
+ <purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a
+ transform with the grammar. </purpose>
+ <description>
+ <para>
+ Use <computeroutput>proto::when&lt;&gt;</computeroutput> to override a grammar's default
+ transform with a custom transform. It is for use when composing larger transforms by associating
+ smaller transforms with individual rules in your grammar.
+ </para>
+ <para>
+ The <computeroutput>when&lt;G, R(A..., ...)&gt;</computeroutput> form accepts either a
+ <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its
+ second parameter. <computeroutput>proto::when&lt;&gt;</computeroutput> uses
+ <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput> to
+ distinguish between the two, and uses
+ <computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> to evaluate
+ <conceptname>CallableTransform</conceptname>s and
+ <computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> to evaluate
+ <conceptname>ObjectTransform</conceptname>s.
+ </para>
+ <para>
+ <emphasis role="bold">Note:</emphasis> In the specialization
+ <computeroutput>when&lt;G, R(A..., ...)&gt;</computeroutput>, the first ellipsis denotes a
+ C++11-style variadic template (which is emulated for C++98 compilers). The second ellipsis
+ is a C-style vararg.
+ </para>
+ </description>
+ <struct name="impl">
+ <template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template>
+ <inherit><type><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</type></inherit>
+ <typedef name="call_">
+ <purpose>For exposition only</purpose>
+ <type><classname>proto::call</classname>&lt;R(A..., ...)&gt;</type>
+ </typedef>
+ <typedef name="make_">
+ <purpose>For exposition only</purpose>
+ <type><classname>proto::make</classname>&lt;R(A..., ...)&gt;</type>
+ </typedef>
+ <typedef name="which">
+ <purpose>For exposition only</purpose>
+ <type>typename mpl::if_&lt;<classname>proto::is_callable</classname>&lt;R&gt;,call_,make_&gt;::type</type>
+ </typedef>
+ <typedef name="result_type">
+ <type>typename boost::result_of&lt;which(Expr, State, Data)&gt;::type</type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="operator()" cv="const">
+ <type>result_type</type>
+ <parameter name="expr">
+ <paramtype>typename impl::expr_param</paramtype>
+ <description>
+ <para>The current expression </para>
+ </description>
+ </parameter>
+ <parameter name="state">
+ <paramtype>typename impl::state_param</paramtype>
+ <description>
+ <para>The current state </para>
+ </description>
+ </parameter>
+ <parameter name="data">
+ <paramtype>typename impl::data_param</paramtype>
+ <description>
+ <para>An arbitrary data </para>
+ </description>
+ </parameter>
+ <description>
+ <para>
+ Evaluate <computeroutput>R(A..., ...)</computeroutput> as a transform either with
+ <computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> or with
+ <computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> depending
+ on whether <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput>
+ is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.
+ </para>
+ </description>
+ <requires>
+ <para>
+ <computeroutput><classname>proto::matches</classname>&lt;Expr, Grammar&gt;::value</computeroutput>
+ is <computeroutput>true</computeroutput>.
+ </para>
+ </requires>
+ <returns>
+ <para>
+ <computeroutput>which()(expr, state, data)</computeroutput>
+ </para>
+ </returns>
+ </method>
+ </method-group>
+ </struct>
+ <typedef name="proto_grammar">
+ <type>typename Grammar::proto_grammar</type>
+ </typedef>
+ </struct-specialization>
+
+ <struct-specialization name="when">
+ <template>
+ <template-type-parameter name="Grammar"/>
         </template>
         <specialization>
           <template-arg>Grammar</template-arg>

Modified: branches/release/libs/proto/preprocess/Jamfile.v2
==============================================================================
--- branches/release/libs/proto/preprocess/Jamfile.v2 (original)
+++ branches/release/libs/proto/preprocess/Jamfile.v2 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -6,7 +6,7 @@
 
 actions wave
 {
- $(>[2]) -o- -DBOOST_PROTO_MAX_ARITY=5 --config-file wave.cfg $(>[1])
+ $(>[2]) -o- -DBOOST_PROTO_MAX_ARITY=10 --config-file wave.cfg $(>[1])
 }
 
 W = ../../../tools/wave/build//wave ;

Modified: branches/release/libs/proto/preprocess/wave.cfg
==============================================================================
--- branches/release/libs/proto/preprocess/wave.cfg (original)
+++ branches/release/libs/proto/preprocess/wave.cfg 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -8,6 +8,9 @@
 -DBOOST_PROTO_CREATE_PREPROCESSED_FILES
 -D_WIN32
 -NBOOST_FORCEINLINE
+-NBOOST_MPL_ASSERT
+-NBOOST_MPL_ASSERT_MSG
+-NBOOST_MPL_ASSERT_RELATION
 -S../../..
 -S"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include"
 -S.

Modified: branches/release/libs/proto/test/Jamfile.v2
==============================================================================
--- branches/release/libs/proto/test/Jamfile.v2 (original)
+++ branches/release/libs/proto/test/Jamfile.v2 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -35,8 +35,9 @@
         [ run toy_spirit.cpp ]
         [ run toy_spirit2.cpp ]
         [ run make.cpp ]
- [ run noinvoke.cpp ]
         [ run mem_ptr.cpp : : : <toolset>msvc:<cxxflags>/wd4355 ]
+ [ run noinvoke.cpp ]
+ [ run pack_expansion.cpp ]
         [ compile bug2407.cpp ]
     ;
 

Copied: branches/release/libs/proto/test/pack_expansion.cpp (from r79461, /trunk/libs/proto/test/pack_expansion.cpp)
==============================================================================
--- /trunk/libs/proto/test/pack_expansion.cpp (original)
+++ branches/release/libs/proto/test/pack_expansion.cpp 2012-07-15 00:40:39 EDT (Sun, 15 Jul 2012)
@@ -20,31 +20,44 @@
     template<typename Sig>
     struct result;
 
- template<typename This, typename Left, typename Right>
- struct result<This(proto::tag::plus, Left, Right)>
- {
- typedef BOOST_TYPEOF_TPL(declval<Left>() + declval<Right>()) type;
- };
-
- template<typename This, typename Left, typename Right>
- struct result<This(proto::tag::multiplies, Left, Right)>
- {
- typedef BOOST_TYPEOF_TPL(declval<Left>() * declval<Right>()) type;
- };
-
- template<typename Left, typename Right>
- typename result<eval_(proto::tag::plus, Left, Right)>::type
- operator()(proto::tag::plus, Left left, Right right) const
- {
- return left + right;
- }
-
- template<typename Left, typename Right>
- typename result<eval_(proto::tag::multiplies, Left, Right)>::type
- operator()(proto::tag::multiplies, Left left, Right right) const
- {
- return left * right;
- }
+#define UNARY_OP(TAG, OP) \
+ template<typename This, typename Arg> \
+ struct result<This(proto::tag::TAG, Arg)> \
+ { \
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (OP declval<Arg>())) \
+ typedef typename nested::type type; \
+ }; \
+ \
+ template<typename Arg> \
+ typename result<eval_(proto::tag::TAG, Arg)>::type \
+ operator()(proto::tag::TAG, Arg arg) const \
+ { \
+ return OP arg; \
+ } \
+ /**/
+
+#define BINARY_OP(TAG, OP) \
+ template<typename This, typename Left, typename Right> \
+ struct result<This(proto::tag::TAG, Left, Right)> \
+ { \
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, (declval<Left>() OP declval<Right>())) \
+ typedef typename nested::type type; \
+ }; \
+ \
+ template<typename Left, typename Right> \
+ typename result<eval_(proto::tag::TAG, Left, Right)>::type \
+ operator()(proto::tag::TAG, Left left, Right right) const \
+ { \
+ return left OP right; \
+ } \
+ /**/
+
+ UNARY_OP(negate, -)
+ BINARY_OP(plus, +)
+ BINARY_OP(minus, -)
+ BINARY_OP(multiplies, *)
+ BINARY_OP(divides, /)
+ /*... others ...*/
 };
 
 struct eval1


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