$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r49930 - in trunk: boost/proto boost/proto/detail libs/proto/example libs/proto/test
From: eric_at_[hidden]
Date: 2008-11-25 11:00:41
Author: eric_niebler
Date: 2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
New Revision: 49930
URL: http://svn.boost.org/trac/boost/changeset/49930
Log:
deprecate old BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE macro, replace with more flexible and useful BOOST_PROTO_REPEAT and BOOST_PROTO_LOCAL_ITERATE
Added:
   trunk/boost/proto/detail/deprecated.hpp   (contents, props changed)
   trunk/boost/proto/detail/local.hpp   (contents, props changed)
   trunk/boost/proto/repeat.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/proto/core.hpp                  |     1                                         
   trunk/boost/proto/make_expr.hpp             |   225 --------------------------------------- 
   trunk/libs/proto/example/mini_lambda.cpp    |    95 +++++++++++-----                        
   trunk/libs/proto/example/virtual_member.cpp |    70 ++++-------                             
   trunk/libs/proto/test/lambda.cpp            |    30 ++---                                   
   5 files changed, 105 insertions(+), 316 deletions(-)
Modified: trunk/boost/proto/core.hpp
==============================================================================
--- trunk/boost/proto/core.hpp	(original)
+++ trunk/boost/proto/core.hpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -16,6 +16,7 @@
 #include <boost/proto/tags.hpp>
 #include <boost/proto/eval.hpp>
 #include <boost/proto/expr.hpp>
+#include <boost/proto/repeat.hpp>
 #include <boost/proto/traits.hpp>
 #include <boost/proto/domain.hpp>
 #include <boost/proto/fusion.hpp>
Added: trunk/boost/proto/detail/deprecated.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/deprecated.hpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -0,0 +1,249 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file deprecated.hpp
+/// Definition of the deprecated BOOST_PROTO_DEFINE_FUCTION_TEMPLATE and
+/// BOOST_PROTO_DEFINE_VARARG_FUCTION_TEMPLATE macros
+//
+//  Copyright 2008 Eric Niebler. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_DETAIL_DEPRECATED_HPP_EAN_11_25_2008
+#define BOOST_PROTO_DETAIL_DEPRECATED_HPP_EAN_11_25_2008
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/control/expr_if.hpp>
+#include <boost/preprocessor/comparison/greater.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/preprocessor/tuple/to_list.hpp>
+#include <boost/preprocessor/logical/and.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/preprocessor/seq/seq.hpp>
+#include <boost/preprocessor/seq/to_tuple.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/pop_back.hpp>
+#include <boost/preprocessor/seq/push_back.hpp>
+#include <boost/preprocessor/seq/push_front.hpp>
+#include <boost/preprocessor/list/for_each_i.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_TEMPLATE_AUX_(R, DATA, I, ELEM)                                      \
+    (ELEM BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I)))                              \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_TEMPLATE_YES_(R, DATA, I, ELEM)                                      \
+    BOOST_PP_LIST_FOR_EACH_I_R(                                                                 \
+        R                                                                                       \
+      , BOOST_PROTO_VARARG_TEMPLATE_AUX_                                                        \
+      , I                                                                                       \
+      , BOOST_PP_TUPLE_TO_LIST(                                                                 \
+            BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                               \
+          , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM))                                      \
+        )                                                                                       \
+    )                                                                                           \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_TEMPLATE_NO_(R, DATA, I, ELEM)                                       \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_TEMPLATE_(R, DATA, I, ELEM)                                          \
+    BOOST_PP_IF(                                                                                \
+        BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                                   \
+      , BOOST_PROTO_VARARG_TEMPLATE_YES_                                                        \
+      , BOOST_PROTO_VARARG_TEMPLATE_NO_                                                         \
+    )(R, DATA, I, ELEM)                                                                         \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_TYPE_AUX_(R, DATA, I, ELEM)                                          \
+    (BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I)))                                   \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_TEMPLATE_PARAMS_YES_(R, DATA, I, ELEM)                                      \
+    <                                                                                           \
+        BOOST_PP_SEQ_ENUM(                                                                      \
+            BOOST_PP_LIST_FOR_EACH_I_R(                                                         \
+                R                                                                               \
+              , BOOST_PROTO_VARARG_TYPE_AUX_                                                    \
+              , I                                                                               \
+              , BOOST_PP_TUPLE_TO_LIST(                                                         \
+                    BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                       \
+                  , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM))                              \
+                )                                                                               \
+            )                                                                                   \
+        )                                                                                       \
+    >                                                                                           \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_TEMPLATE_PARAMS_NO_(R, DATA, I, ELEM)                                       \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_TYPE_(R, DATA, I, ELEM)                                              \
+    BOOST_PP_COMMA_IF(I)                                                                        \
+    BOOST_PP_SEQ_HEAD(ELEM)                                                                     \
+    BOOST_PP_IF(                                                                                \
+        BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                                   \
+      , BOOST_PROTO_TEMPLATE_PARAMS_YES_                                                        \
+      , BOOST_PROTO_TEMPLATE_PARAMS_NO_                                                         \
+    )(R, DATA, I, ELEM) BOOST_PP_EXPR_IF(BOOST_PP_GREATER(I, 1), const)                         \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM)                                           \
+    BOOST_PP_EXPR_IF(                                                                           \
+        BOOST_PP_GREATER(I, 1)                                                                  \
+      , ((                                                                                      \
+            BOOST_PP_SEQ_HEAD(ELEM)                                                             \
+            BOOST_PP_IF(                                                                        \
+                BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                           \
+              , BOOST_PROTO_TEMPLATE_PARAMS_YES_                                                \
+              , BOOST_PROTO_TEMPLATE_PARAMS_NO_                                                 \
+            )(R, DATA, I, ELEM)()                                                               \
+        ))                                                                                      \
+    )                                                                                           \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_AS_CHILD_(Z, N, DATA)                                                \
+    (BOOST_PP_CAT(DATA, N))                                                                     \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_SEQ_PUSH_FRONT(SEQ, ELEM)                                                   \
+    BOOST_PP_SEQ_POP_BACK(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_BACK(SEQ, _dummy_), ELEM))  \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_AS_PARAM_(Z, N, DATA)                                                \
+    (BOOST_PP_CAT(DATA, N))                                                                     \
+    /**/
+
+/// INTERNAL ONLY
+///
+#define BOOST_PROTO_VARARG_FUN_(Z, N, DATA)                                                     \
+    template<                                                                                   \
+        BOOST_PP_SEQ_ENUM(                                                                      \
+            BOOST_PP_SEQ_FOR_EACH_I(                                                            \
+                BOOST_PROTO_VARARG_TEMPLATE_, ~                                                 \
+              , BOOST_PP_SEQ_PUSH_FRONT(                                                        \
+                    BOOST_PROTO_SEQ_PUSH_FRONT(                                                 \
+                        BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                         \
+                      , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                       \
+                    )                                                                           \
+                  , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                             \
+                )                                                                               \
+            )                                                                                   \
+            BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_PARAM_, typename A)                  \
+        )                                                                                       \
+    >                                                                                           \
+    typename boost::proto::result_of::make_expr<                                                \
+        BOOST_PP_SEQ_FOR_EACH_I(                                                                \
+            BOOST_PROTO_VARARG_TYPE_, ~                                                         \
+          , BOOST_PP_SEQ_PUSH_FRONT(                                                            \
+                BOOST_PROTO_SEQ_PUSH_FRONT(                                                     \
+                    BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                             \
+                  , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                           \
+                )                                                                               \
+              , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                                 \
+            )                                                                                   \
+        )                                                                                       \
+        BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT)             \
+    >::type const                                                                               \
+    BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a))           \
+    {                                                                                           \
+        return boost::proto::detail::make_expr_<                                                \
+            BOOST_PP_SEQ_FOR_EACH_I(                                                            \
+                BOOST_PROTO_VARARG_TYPE_, ~                                                     \
+              , BOOST_PP_SEQ_PUSH_FRONT(                                                        \
+                    BOOST_PROTO_SEQ_PUSH_FRONT(                                                 \
+                        BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                         \
+                      , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                       \
+                    )                                                                           \
+                  , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                             \
+                )                                                                               \
+            )                                                                                   \
+            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT)         \
+        >()(                                                                                    \
+            BOOST_PP_SEQ_ENUM(                                                                  \
+                BOOST_PP_SEQ_FOR_EACH_I(                                                        \
+                    BOOST_PROTO_VARARG_AS_EXPR_, ~                                              \
+                  , BOOST_PP_SEQ_PUSH_FRONT(                                                    \
+                        BOOST_PROTO_SEQ_PUSH_FRONT(                                             \
+                            BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                     \
+                          , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                   \
+                        )                                                                       \
+                      , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                         \
+                    )                                                                           \
+                )                                                                               \
+                BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_CHILD_, a)                       \
+            )                                                                                   \
+        );                                                                                      \
+    }                                                                                           \
+    /**/
+
+/// \code
+/// BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
+///     1
+///   , construct
+///   , boost::proto::default_domain
+///   , (boost::proto::tag::function)
+///   , ((op::construct)(typename)(int))
+/// )
+/// \endcode
+#define BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(ARGCOUNT, NAME, DOMAIN, TAG, BOUNDARGS)            \
+    BOOST_PP_REPEAT_FROM_TO(                                                                    \
+        ARGCOUNT                                                                                \
+      , BOOST_PP_INC(ARGCOUNT)                                                                  \
+      , BOOST_PROTO_VARARG_FUN_                                                                 \
+      , (NAME, TAG, BOUNDARGS, DOMAIN)                                                          \
+    )\
+    /**/
+
+/// \code
+/// BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
+///     construct
+///   , boost::proto::default_domain
+///   , (boost::proto::tag::function)
+///   , ((op::construct)(typename)(int))
+/// )
+/// \endcode
+#define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(NAME, DOMAIN, TAG, BOUNDARGS)               \
+    BOOST_PP_REPEAT(                                                                            \
+        BOOST_PP_SUB(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PP_SEQ_SIZE(BOUNDARGS))         \
+      , BOOST_PROTO_VARARG_FUN_                                                                 \
+      , (NAME, TAG, BOUNDARGS, DOMAIN)                                                          \
+    )                                                                                           \
+    /**/
+
+#endif
Added: trunk/boost/proto/detail/local.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/local.hpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file local.hpp
+/// Contains macros to ease the generation of repetitious code constructs
+//
+//  Copyright 2008 Eric Niebler. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_LOCAL_MACRO
+# error "local iteration target macro is not defined"
+#endif
+
+#ifndef BOOST_PROTO_LOCAL_LIMITS
+# define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PROTO_MAX_ARITY)
+#endif
+
+#ifndef BOOST_PROTO_LOCAL_typename_A
+# define BOOST_PROTO_LOCAL_typename_A BOOST_PROTO_typename_A
+#endif
+
+#ifndef BOOST_PROTO_LOCAL_A
+# define BOOST_PROTO_LOCAL_A BOOST_PROTO_A_const_ref
+#endif
+
+#ifndef BOOST_PROTO_LOCAL_A_a
+# define BOOST_PROTO_LOCAL_A_a BOOST_PROTO_A_const_ref_a
+#endif
+
+#ifndef BOOST_PROTO_LOCAL_a
+# define BOOST_PROTO_LOCAL_a BOOST_PROTO_ref_a
+#endif
+
+#define BOOST_PP_LOCAL_LIMITS BOOST_PROTO_LOCAL_LIMITS
+
+#define BOOST_PP_LOCAL_MACRO(N)       \
+  BOOST_PROTO_LOCAL_MACRO(            \
+      N                               \
+    , BOOST_PROTO_LOCAL_typename_A    \
+    , BOOST_PROTO_LOCAL_A             \
+    , BOOST_PROTO_LOCAL_A_a           \
+    , BOOST_PROTO_LOCAL_a             \
+  )                                   \
+  /**/
+
+#include BOOST_PP_LOCAL_ITERATE()
+
+#undef BOOST_PROTO_LOCAL_MACRO
+#undef BOOST_PROTO_LOCAL_LIMITS
+#undef BOOST_PROTO_LOCAL_typename_A
+#undef BOOST_PROTO_LOCAL_A
+#undef BOOST_PROTO_LOCAL_A_a
+#undef BOOST_PROTO_LOCAL_a
Modified: trunk/boost/proto/make_expr.hpp
==============================================================================
--- trunk/boost/proto/make_expr.hpp	(original)
+++ trunk/boost/proto/make_expr.hpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -17,37 +17,20 @@
     #include <boost/config.hpp>
     #include <boost/detail/workaround.hpp>
     #include <boost/preprocessor/cat.hpp>
-    #include <boost/preprocessor/control/if.hpp>
-    #include <boost/preprocessor/control/expr_if.hpp>
     #include <boost/preprocessor/arithmetic/inc.hpp>
     #include <boost/preprocessor/arithmetic/dec.hpp>
     #include <boost/preprocessor/arithmetic/sub.hpp>
     #include <boost/preprocessor/punctuation/comma_if.hpp>
     #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/facilities/intercept.hpp>
-    #include <boost/preprocessor/comparison/greater.hpp>
-    #include <boost/preprocessor/tuple/elem.hpp>
-    #include <boost/preprocessor/tuple/to_list.hpp>
-    #include <boost/preprocessor/logical/and.hpp>
     #include <boost/preprocessor/repetition/enum.hpp>
     #include <boost/preprocessor/repetition/enum_params.hpp>
-    #include <boost/preprocessor/repetition/enum_trailing.hpp>
     #include <boost/preprocessor/repetition/enum_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
     #include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
-    #include <boost/preprocessor/repetition/repeat_from_to.hpp>
-    #include <boost/preprocessor/seq/size.hpp>
-    #include <boost/preprocessor/seq/enum.hpp>
-    #include <boost/preprocessor/seq/seq.hpp>
-    #include <boost/preprocessor/seq/to_tuple.hpp>
-    #include <boost/preprocessor/seq/for_each_i.hpp>
-    #include <boost/preprocessor/seq/pop_back.hpp>
-    #include <boost/preprocessor/seq/push_back.hpp>
-    #include <boost/preprocessor/seq/push_front.hpp>
-    #include <boost/preprocessor/list/for_each_i.hpp>
     #include <boost/ref.hpp>
     #include <boost/mpl/if.hpp>
     #include <boost/mpl/assert.hpp>
@@ -73,6 +56,7 @@
     # include <boost/spirit/fusion/sequence/size.hpp>
     #endif
     #include <boost/proto/detail/poly_function.hpp>
+    #include <boost/proto/detail/deprecated.hpp>
     #include <boost/proto/detail/suffix.hpp>
 
     #ifdef _MSC_VER
@@ -148,213 +132,6 @@
         >::call(BOOST_PROTO_AT(Z, N, DATA))                                                         \
         /**/
 
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_TEMPLATE_AUX_(R, DATA, I, ELEM)                                      \
-        (ELEM BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I)))                              \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_TEMPLATE_YES_(R, DATA, I, ELEM)                                      \
-        BOOST_PP_LIST_FOR_EACH_I_R(                                                                 \
-            R                                                                                       \
-          , BOOST_PROTO_VARARG_TEMPLATE_AUX_                                                        \
-          , I                                                                                       \
-          , BOOST_PP_TUPLE_TO_LIST(                                                                 \
-                BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                               \
-              , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM))                                      \
-            )                                                                                       \
-        )                                                                                           \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_TEMPLATE_NO_(R, DATA, I, ELEM)                                       \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_TEMPLATE_(R, DATA, I, ELEM)                                          \
-        BOOST_PP_IF(                                                                                \
-            BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                                   \
-          , BOOST_PROTO_VARARG_TEMPLATE_YES_                                                        \
-          , BOOST_PROTO_VARARG_TEMPLATE_NO_                                                         \
-        )(R, DATA, I, ELEM)                                                                         \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_TYPE_AUX_(R, DATA, I, ELEM)                                          \
-        (BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I)))                                   \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_TEMPLATE_PARAMS_YES_(R, DATA, I, ELEM)                                      \
-        <                                                                                           \
-            BOOST_PP_SEQ_ENUM(                                                                      \
-                BOOST_PP_LIST_FOR_EACH_I_R(                                                         \
-                    R                                                                               \
-                  , BOOST_PROTO_VARARG_TYPE_AUX_                                                    \
-                  , I                                                                               \
-                  , BOOST_PP_TUPLE_TO_LIST(                                                         \
-                        BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                       \
-                      , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM))                              \
-                    )                                                                               \
-                )                                                                                   \
-            )                                                                                       \
-        >                                                                                           \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_TEMPLATE_PARAMS_NO_(R, DATA, I, ELEM)                                       \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_TYPE_(R, DATA, I, ELEM)                                              \
-        BOOST_PP_COMMA_IF(I)                                                                        \
-        BOOST_PP_SEQ_HEAD(ELEM)                                                                     \
-        BOOST_PP_IF(                                                                                \
-            BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                                   \
-          , BOOST_PROTO_TEMPLATE_PARAMS_YES_                                                        \
-          , BOOST_PROTO_TEMPLATE_PARAMS_NO_                                                         \
-        )(R, DATA, I, ELEM) BOOST_PP_EXPR_IF(BOOST_PP_GREATER(I, 1), const)                         \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM)                                           \
-        BOOST_PP_EXPR_IF(                                                                           \
-            BOOST_PP_GREATER(I, 1)                                                                  \
-          , ((                                                                                      \
-                BOOST_PP_SEQ_HEAD(ELEM)                                                             \
-                BOOST_PP_IF(                                                                        \
-                    BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                           \
-                  , BOOST_PROTO_TEMPLATE_PARAMS_YES_                                                \
-                  , BOOST_PROTO_TEMPLATE_PARAMS_NO_                                                 \
-                )(R, DATA, I, ELEM)()                                                               \
-            ))                                                                                      \
-        )                                                                                           \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_AS_CHILD_(Z, N, DATA)                                                \
-        (BOOST_PP_CAT(DATA, N))                                                                     \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_SEQ_PUSH_FRONT(SEQ, ELEM)                                                   \
-        BOOST_PP_SEQ_POP_BACK(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_BACK(SEQ, _dummy_), ELEM))  \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_AS_PARAM_(Z, N, DATA)                                                \
-        (BOOST_PP_CAT(DATA, N))                                                                     \
-        /**/
-
-    /// INTERNAL ONLY
-    ///
-    #define BOOST_PROTO_VARARG_FUN_(Z, N, DATA)                                                     \
-        template<                                                                                   \
-            BOOST_PP_SEQ_ENUM(                                                                      \
-                BOOST_PP_SEQ_FOR_EACH_I(                                                            \
-                    BOOST_PROTO_VARARG_TEMPLATE_, ~                                                 \
-                  , BOOST_PP_SEQ_PUSH_FRONT(                                                        \
-                        BOOST_PROTO_SEQ_PUSH_FRONT(                                                 \
-                            BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                         \
-                          , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                       \
-                        )                                                                           \
-                      , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                             \
-                    )                                                                               \
-                )                                                                                   \
-                BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_PARAM_, typename A)                  \
-            )                                                                                       \
-        >                                                                                           \
-        typename boost::proto::result_of::make_expr<                                                \
-            BOOST_PP_SEQ_FOR_EACH_I(                                                                \
-                BOOST_PROTO_VARARG_TYPE_, ~                                                         \
-              , BOOST_PP_SEQ_PUSH_FRONT(                                                            \
-                    BOOST_PROTO_SEQ_PUSH_FRONT(                                                     \
-                        BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                             \
-                      , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                           \
-                    )                                                                               \
-                  , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                                 \
-                )                                                                                   \
-            )                                                                                       \
-            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT)             \
-        >::type const                                                                               \
-        BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a))           \
-        {                                                                                           \
-            return boost::proto::detail::make_expr_<                                                \
-                BOOST_PP_SEQ_FOR_EACH_I(                                                            \
-                    BOOST_PROTO_VARARG_TYPE_, ~                                                     \
-                  , BOOST_PP_SEQ_PUSH_FRONT(                                                        \
-                        BOOST_PROTO_SEQ_PUSH_FRONT(                                                 \
-                            BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                         \
-                          , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                       \
-                        )                                                                           \
-                      , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                             \
-                    )                                                                               \
-                )                                                                                   \
-                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT)         \
-            >()(                                                                                    \
-                BOOST_PP_SEQ_ENUM(                                                                  \
-                    BOOST_PP_SEQ_FOR_EACH_I(                                                        \
-                        BOOST_PROTO_VARARG_AS_EXPR_, ~                                              \
-                      , BOOST_PP_SEQ_PUSH_FRONT(                                                    \
-                            BOOST_PROTO_SEQ_PUSH_FRONT(                                             \
-                                BOOST_PP_TUPLE_ELEM(4, 2, DATA)                                     \
-                              , (BOOST_PP_TUPLE_ELEM(4, 3, DATA))                                   \
-                            )                                                                       \
-                          , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                         \
-                        )                                                                           \
-                    )                                                                               \
-                    BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_CHILD_, a)                       \
-                )                                                                                   \
-            );                                                                                      \
-        }                                                                                           \
-        /**/
-
-    /// \code
-    /// BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
-    ///     1
-    ///   , construct
-    ///   , boost::proto::default_domain
-    ///   , (boost::proto::tag::function)
-    ///   , ((op::construct)(typename)(int))
-    /// )
-    /// \endcode
-    #define BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(ARGCOUNT, NAME, DOMAIN, TAG, BOUNDARGS)            \
-        BOOST_PP_REPEAT_FROM_TO(                                                                    \
-            ARGCOUNT                                                                                \
-          , BOOST_PP_INC(ARGCOUNT)                                                                  \
-          , BOOST_PROTO_VARARG_FUN_                                                                 \
-          , (NAME, TAG, BOUNDARGS, DOMAIN)                                                          \
-        )\
-        /**/
-
-    /// \code
-    /// BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
-    ///     construct
-    ///   , boost::proto::default_domain
-    ///   , (boost::proto::tag::function)
-    ///   , ((op::construct)(typename)(int))
-    /// )
-    /// \endcode
-    #define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(NAME, DOMAIN, TAG, BOUNDARGS)               \
-        BOOST_PP_REPEAT(                                                                            \
-            BOOST_PP_SUB(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PP_SEQ_SIZE(BOUNDARGS))         \
-          , BOOST_PROTO_VARARG_FUN_                                                                 \
-          , (NAME, TAG, BOUNDARGS, DOMAIN)                                                          \
-        )                                                                                           \
-        /**/
-
         namespace detail
         {
             template<typename T, typename Domain>
Added: trunk/boost/proto/repeat.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/repeat.hpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file repeat.hpp
+/// Contains macros to ease the generation of repetitious code constructs
+//
+//  Copyright 2008 Eric Niebler. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_REPEAT_HPP_EAN_11_24_2008
+#define BOOST_PROTO_REPEAT_HPP_EAN_11_24_2008
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/proto/proto_fwd.hpp> // for BOOST_PROTO_MAX_ARITY
+#include <boost/proto/detail/suffix.hpp>
+
+////////////////////////////////////////////
+/// INTERNAL ONLY
+#define BOOST_PROTO_ref_a_aux(Z, N, DATA)\
+  boost::ref(BOOST_PP_CAT(proto_a, N))
+
+/// \brief Generates a sequence like <tt>typename A0, typename A1, ...</tt>
+///
+#define BOOST_PROTO_typename_A(N)\
+  BOOST_PP_ENUM_PARAMS(N, typename proto_A)
+
+/// \brief Generates a sequence like <tt>A0 const &, A1 const &, ...</tt>
+///
+#define BOOST_PROTO_A_const_ref(N)\
+  BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const & BOOST_PP_INTERCEPT)
+
+/// \brief Generates a sequence like <tt>A0 &, A1 &, ...</tt>
+///
+#define BOOST_PROTO_A_ref(N)\
+  BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, & BOOST_PP_INTERCEPT)
+
+/// \brief Generates a sequence like <tt>A0, A1, ...</tt>
+///
+#define BOOST_PROTO_A(N)\
+  BOOST_PP_ENUM_PARAMS(N, proto_A)
+
+/// \brief Generates a sequence like <tt>A0 const, A1 const, ...</tt>
+///
+#define BOOST_PROTO_A_const(N)\
+  BOOST_PP_ENUM_PARAMS(N, const proto_A)
+
+/// \brief Generates a sequence like <tt>A0 const &a0, A1 const &a0, ...</tt>
+///
+#define BOOST_PROTO_A_const_ref_a(N)\
+  BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const &proto_a)
+
+/// \brief Generates a sequence like <tt>A0 &a0, A1 &a0, ...</tt>
+///
+#define BOOST_PROTO_A_ref_a(N)\
+  BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, &proto_a)
+
+/// \brief Generates a sequence like <tt>boost::ref(a0), boost::ref(a1), ...</tt>
+///
+#define BOOST_PROTO_ref_a(N)\
+  BOOST_PP_ENUM(N, BOOST_PROTO_ref_a_aux, ~)
+
+/// \brief Generates a sequence like <tt>a0, a1, ...</tt>
+///
+#define BOOST_PROTO_a(N)\
+  BOOST_PP_ENUM_PARAMS(N, proto_a)
+
+////////////////////////////////////////////
+/// INTERNAL ONLY
+#define BOOST_PROTO_invoke(Z, N, DATA)\
+  BOOST_PP_TUPLE_ELEM(5,0,DATA)(N, BOOST_PP_TUPLE_ELEM(5,1,DATA), BOOST_PP_TUPLE_ELEM(5,2,DATA), BOOST_PP_TUPLE_ELEM(5,3,DATA), BOOST_PP_TUPLE_ELEM(5,4,DATA))
+
+#define BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a)\
+  BOOST_PP_REPEAT_FROM_TO(FROM, TO, BOOST_PROTO_invoke, (MACRO, typename_A, A, A_a, a))
+
+#define BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO)\
+  BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+
+#define BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a)\
+  BOOST_PROTO_REPEAT_FROM_TO_EX(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+
+#define BOOST_PROTO_REPEAT(MACRO)\
+  BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO)
+
+#define BOOST_PROTO_LOCAL_ITERATE() <boost/proto/detail/local.hpp>
+
+#endif
Modified: trunk/libs/proto/example/mini_lambda.cpp
==============================================================================
--- trunk/libs/proto/example/mini_lambda.cpp	(original)
+++ trunk/libs/proto/example/mini_lambda.cpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -46,7 +46,7 @@
 };
 
 // The lambda grammar, with the transforms for calculating the max arity
-struct Lambda
+struct lambda_arity
   : proto::or_<
         proto::when<
             proto::terminal< placeholder<_> >
@@ -57,17 +57,11 @@
         >
       , proto::when<
             proto::nary_expr<_, proto::vararg<_> >
-          , proto::fold<_, mpl::int_<0>(), mpl::max<Lambda,proto::_state>()>
+          , proto::fold<_, mpl::int_<0>(), mpl::max<lambda_arity, proto::_state>()>
         >
     >
 {};
 
-// simple wrapper for calculating a lambda expression's arity.
-template<typename Expr>
-struct lambda_arity
-  : boost::result_of<Lambda(Expr, mpl::void_, mpl::void_)>
-{};
-
 // The lambda context is the same as the default context
 // with the addition of special handling for lambda placeholders
 template<typename Tuple>
@@ -105,16 +99,38 @@
     BOOST_PROTO_EXTENDS_ASSIGN()
     BOOST_PROTO_EXTENDS_SUBSCRIPT()
 
-    // Careful not to evaluate the return type of the nullary function
-    // unless we have a nullary lambda!
-    typedef typename mpl::eval_if<
-        typename lambda_arity<T>::type
-      , mpl::identity<void>
-      , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
-    >::type nullary_type;
+    // Calculate the arity of this lambda expression
+    static int const arity = boost::result_of<lambda_arity(T)>::type::value;
+
+    template<typename Sig>
+    struct result;
+
+    // Define nested result<> specializations to calculate the return
+    // type of this lambda expression. But be careful not to evaluate
+    // the return type of the nullary function unless we have a nullary
+    // lambda!
+    template<typename This>
+    struct result<This()>
+      : mpl::eval_if_c<
+            0 == arity
+          , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+          , mpl::identity<void>
+        >
+    {};
+
+    template<typename This, typename A0>
+    struct result<This(A0)>
+      : proto::result_of::eval<T const, lambda_context<fusion::tuple<A0> > >
+    {};
+
+    template<typename This, typename A0, typename A1>
+    struct result<This(A0, A1)>
+      : proto::result_of::eval<T const, lambda_context<fusion::tuple<A0, A1> > >
+    {};
 
     // Define our operator () that evaluates the lambda expression.
-    nullary_type operator ()() const
+    typename result<lambda()>::type
+    operator ()() const
     {
         fusion::tuple<> args;
         lambda_context<fusion::tuple<> > ctx(args);
@@ -122,7 +138,7 @@
     }
 
     template<typename A0>
-    typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+    typename result<lambda(A0 const &)>::type
     operator ()(A0 const &a0) const
     {
         fusion::tuple<A0 const &> args(a0);
@@ -131,7 +147,7 @@
     }
 
     template<typename A0, typename A1>
-    typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+    typename result<lambda(A0 const &, A1 const &)>::type
     operator ()(A0 const &a0, A1 const &a1) const
     {
         fusion::tuple<A0 const &, A1 const &> args(a0, a1);
@@ -166,23 +182,38 @@
     T operator()() const
     { return T(); }
 
-    template<typename A0>
-    T operator()(A0 const &a0) const
-    { return T(a0); }
-
-    template<typename A0, typename A1>
-    T operator()(A0 const &a0, A1 const &a1) const
-    { return T(a0, a1); }
+    // Generate BOOST_PROTO_MAX_ARITY overloads of the
+    // followig function call operator.
+#define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a)\
+    template<typename_A(N)>                                       \
+    T operator()(A_const_ref_a(N)) const                          \
+    { return T(a(N)); }
+#define BOOST_PROTO_LOCAL_a BOOST_PROTO_a
+#include BOOST_PROTO_LOCAL_ITERATE()
 };
 
 // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
-// construct function template like the one defined above.
-BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(            \
-    construct                                           \
-  , lambda_domain                                       \
-  , (proto::tag::function)                              \
-  , ((construct_helper)(typename))                      \
-)
+// following construct() function template.
+#define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a)      \
+template<typename T, typename_A(N)>                               \
+typename proto::result_of::make_expr<                             \
+    proto::tag::function                                          \
+  , lambda_domain                                                 \
+  , construct_helper<T>                                           \
+  , A_const_ref(N)                                                \
+>::type const                                                     \
+construct(A_const_ref_a(N))                                       \
+{                                                                 \
+    return proto::make_expr<                                      \
+        proto::tag::function                                      \
+      , lambda_domain                                             \
+    >(                                                            \
+        construct_helper<T>()                                     \
+      , ref_a(N)                                                  \
+    );                                                            \
+}
+BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0)
+#undef M0
 
 struct S
 {
Modified: trunk/libs/proto/example/virtual_member.cpp
==============================================================================
--- trunk/libs/proto/example/virtual_member.cpp	(original)
+++ trunk/libs/proto/example/virtual_member.cpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -202,9 +202,8 @@
             ((keyword::catch_,  catch_))
         )
 
-        BOOST_STATIC_CONSTANT(
-            int, arity = boost::result_of<arity_of(E)>::type::value
-        );
+        // Calculate the arity of this lambda expression
+        static int const arity = boost::result_of<arity_of(E)>::type::value;
 
         // Define overloads of operator() that evaluate the lambda
         // expression for up to 3 arguments.
@@ -214,53 +213,38 @@
         typename mpl::eval_if_c<
             0 != arity
           , mpl::identity<void>
-          , boost::result_of<grammar(E const &, int const &, fusion::vector0 &)>
+          , boost::result_of<grammar(
+                E const &
+              , int const &
+              , fusion::vector<> &
+            )>
         >::type
         operator()() const
         {
             BOOST_MPL_ASSERT_RELATION(arity, ==, 0);
-            fusion::vector0 args;
+            fusion::vector<> args;
             return grammar()(proto_base(), 0, args);            
         }
 
-        template<typename A0>
-        typename boost::result_of<grammar(
-            E const &
-          , int const &
-          , fusion::vector1<A0 const &> &
-        )>::type
-        operator ()(A0 const &a0) const
-        {
-            BOOST_MPL_ASSERT_RELATION(arity, <=, 1);
-            fusion::vector1<A0 const &> args(a0);
-            return grammar()(proto_base(), 0, args);
-        }
-
-        template<typename A0, typename A1>
-        typename boost::result_of<grammar(
-            E const &
-          , int const &
-          , fusion::vector2<A0 const &, A1 const &> &
-        )>::type
-        operator ()(A0 const &a0, A1 const &a1) const
-        {
-            BOOST_MPL_ASSERT_RELATION(arity, <=, 2);
-            fusion::vector2<A0 const &, A1 const &> args(a0, a1);
-            return grammar()(proto_base(), 0, args);
-        }
-
-        template<typename A0, typename A1, typename A2>
-        typename boost::result_of<grammar(
-            E const &
-          , int const &
-          , fusion::vector3<A0 const &, A1 const &, A2 const &> &
-        )>::type
-        operator ()(A0 const &a0, A1 const &a1, A2 const &a2) const
-        {
-            BOOST_MPL_ASSERT_RELATION(arity, <=, 3);
-            fusion::vector3<A0 const &, A1 const &, A2 const &> args(a0, a1, a2);
-            return grammar()(proto_base(), 0, args);
-        }
+        #define LAMBDA_EVAL(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
+        template<typename_A(N)>                                               \
+        typename boost::result_of<grammar(                                    \
+            E const &                                                         \
+          , int const &                                                       \
+          , fusion::vector<A_const_ref(N)> &                                  \
+        )>::type                                                              \
+        operator ()(A_const_ref_a(N)) const                                   \
+        {                                                                     \
+            BOOST_MPL_ASSERT_RELATION(arity, <=, N);                          \
+            fusion::vector<A_const_ref(N)> args(ref_a(N));                    \
+            return grammar()(proto_base(), 0, args);                          \
+        }                                                                     \
+        /**/
+
+        // Repeats LAMBDA_EVAL macro for N=1 to 3 inclusive (because
+        // there are only 3 placeholders)
+        BOOST_PROTO_REPEAT_FROM_TO(1, 4, LAMBDA_EVAL)
+        #undef LAMBDA_EVAL
     };
 
     namespace placeholders
Modified: trunk/libs/proto/test/lambda.cpp
==============================================================================
--- trunk/libs/proto/test/lambda.cpp	(original)
+++ trunk/libs/proto/test/lambda.cpp	2008-11-25 11:00:40 EST (Tue, 25 Nov 2008)
@@ -130,28 +130,24 @@
         return proto::eval(*this, ctx);
     }
 
-    template<typename A0>
-    typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
-    operator ()(A0 const &a0) const
-    {
-        fusion::tuple<A0 const &> args(a0);
-        lambda_context<fusion::tuple<A0 const &> > ctx(args);
-        return proto::eval(*this, ctx);
-    }
-
-    template<typename A0, typename A1>
-    typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
-    operator ()(A0 const &a0, A1 const &a1) const
-    {
-        fusion::tuple<A0 const &, A1 const &> args(a0, a1);
-        lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
-        return proto::eval(*this, ctx);
-    }
+    #define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a)                                    \
+    template<typename_A(N)>                                                                         \
+    typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A_const_ref(N)> > >::type \
+    operator ()(A_const_ref_a(N)) const                                                             \
+    {                                                                                               \
+        fusion::tuple<A_const_ref(N)> args(ref_a(N));                                               \
+        lambda_context<fusion::tuple<A_const_ref(N)> > ctx(args);                                   \
+        return proto::eval(*this, ctx);                                                             \
+    }                                                                                               \
+    /**/
+    BOOST_PROTO_REPEAT_FROM_TO(1, 4, M0)
+    #undef M0
 };
 
 // Define some lambda placeholders
 lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
 lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<3> > >::type> const _3 = {{}};
 
 template<typename T>
 lambda<typename proto::terminal<T>::type> const val(T const &t)