$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61750 - in trunk/boost/proto: context transform
From: eric_at_[hidden]
Date: 2010-05-03 21:19:55
Author: eric_niebler
Date: 2010-05-03 21:19:53 EDT (Mon, 03 May 2010)
New Revision: 61750
URL: http://svn.boost.org/trac/boost/changeset/61750
Log:
_default transform is also a grammar that matches the expressions the transform knows how to handle
Text files modified: 
   trunk/boost/proto/context/default.hpp   |   172 +++++----                               
   trunk/boost/proto/transform/default.hpp |   693 +++++++++++++++++++++++---------------- 
   2 files changed, 507 insertions(+), 358 deletions(-)
Modified: trunk/boost/proto/context/default.hpp
==============================================================================
--- trunk/boost/proto/context/default.hpp	(original)
+++ trunk/boost/proto/context/default.hpp	2010-05-03 21:19:53 EDT (Mon, 03 May 2010)
@@ -13,7 +13,10 @@
     #define BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
 
     #include <boost/config.hpp>
+    #include <boost/preprocessor/arithmetic/add.hpp>
+    #include <boost/preprocessor/arithmetic/sub.hpp>
     #include <boost/preprocessor/iteration/iterate.hpp>
+    #include <boost/preprocessor/repetition/enum.hpp>
     #include <boost/preprocessor/repetition/enum_shifted.hpp>
     #include <boost/utility/result_of.hpp>
     #include <boost/type_traits/is_const.hpp>
@@ -45,9 +48,22 @@
             struct default_eval
             {};
 
+            template<typename Expr, typename Context>
+            struct default_eval<Expr, Context, tag::terminal, 0>
+            {
+                typedef
+                    typename proto::result_of::value<Expr &>::type
+                result_type;
+
+                result_type operator ()(Expr &expr, Context &) const
+                {
+                    return proto::value(expr);
+                }
+            };
+
             /// INTERNAL ONLY
             ///
-        #define BOOST_PROTO_UNARY_OP_RESULT(OP, TAG, MAKE)                                          \
+        #define BOOST_PROTO_UNARY_DEFAULT_EVAL(OP, TAG, MAKE)                                       \
             template<typename Expr, typename Context>                                               \
             struct default_eval<Expr, Context, TAG, 1>                                              \
             {                                                                                       \
@@ -65,7 +81,7 @@
 
             /// INTERNAL ONLY
             ///
-        #define BOOST_PROTO_BINARY_OP_RESULT(OP, TAG, LMAKE, RMAKE)                                 \
+        #define BOOST_PROTO_BINARY_DEFAULT_EVAL(OP, TAG, LMAKE, RMAKE)                              \
             template<typename Expr, typename Context>                                               \
             struct default_eval<Expr, Context, TAG, 2>                                              \
             {                                                                                       \
@@ -89,48 +105,48 @@
             };                                                                                      \
             /**/
 
-            BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::unary_plus, make)
-            BOOST_PROTO_UNARY_OP_RESULT(-, proto::tag::negate, make)
-            BOOST_PROTO_UNARY_OP_RESULT(*, proto::tag::dereference, make)
-            BOOST_PROTO_UNARY_OP_RESULT(~, proto::tag::complement, make)
-            BOOST_PROTO_UNARY_OP_RESULT(&, proto::tag::address_of, make)
-            BOOST_PROTO_UNARY_OP_RESULT(!, proto::tag::logical_not, make)
-            BOOST_PROTO_UNARY_OP_RESULT(++, proto::tag::pre_inc, make_mutable)
-            BOOST_PROTO_UNARY_OP_RESULT(--, proto::tag::pre_dec, make_mutable)
-
-            BOOST_PROTO_BINARY_OP_RESULT(<<, proto::tag::shift_left, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>>, proto::tag::shift_right, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(*, proto::tag::multiplies, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(/, proto::tag::divides, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(%, proto::tag::modulus, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(+, proto::tag::plus, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(-, proto::tag::minus, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(<, proto::tag::less, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>, proto::tag::greater, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(<=, proto::tag::less_equal, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>=, proto::tag::greater_equal, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(==, proto::tag::equal_to, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(!=, proto::tag::not_equal_to, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(||, proto::tag::logical_or, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(&&, proto::tag::logical_and, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(&, proto::tag::bitwise_and, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(|, proto::tag::bitwise_or, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(^, proto::tag::bitwise_xor, make, make)
-
-            BOOST_PROTO_BINARY_OP_RESULT(=, proto::tag::assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(<<=, proto::tag::shift_left_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>>=, proto::tag::shift_right_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(*=, proto::tag::multiplies_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(/=, proto::tag::divides_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(%=, proto::tag::modulus_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(+=, proto::tag::plus_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(-=, proto::tag::minus_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(&=, proto::tag::bitwise_and_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(|=, proto::tag::bitwise_or_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(^=, proto::tag::bitwise_xor_assign, make_mutable, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(+, proto::tag::unary_plus, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(-, proto::tag::negate, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(*, proto::tag::dereference, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(~, proto::tag::complement, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(&, proto::tag::address_of, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(!, proto::tag::logical_not, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(++, proto::tag::pre_inc, make_mutable)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(--, proto::tag::pre_dec, make_mutable)
+
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<<, proto::tag::shift_left, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>>, proto::tag::shift_right, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(*, proto::tag::multiplies, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(/, proto::tag::divides, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(%, proto::tag::modulus, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(+, proto::tag::plus, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(-, proto::tag::minus, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<, proto::tag::less, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>, proto::tag::greater, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<=, proto::tag::less_equal, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>=, proto::tag::greater_equal, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(==, proto::tag::equal_to, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(!=, proto::tag::not_equal_to, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(||, proto::tag::logical_or, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(&&, proto::tag::logical_and, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(&, proto::tag::bitwise_and, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(|, proto::tag::bitwise_or, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(^, proto::tag::bitwise_xor, make, make)
+
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(=, proto::tag::assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<<=, proto::tag::shift_left_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>>=, proto::tag::shift_right_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(*=, proto::tag::multiplies_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(/=, proto::tag::divides_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(%=, proto::tag::modulus_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(+=, proto::tag::plus_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(-=, proto::tag::minus_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(&=, proto::tag::bitwise_and_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(|=, proto::tag::bitwise_or_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(^=, proto::tag::bitwise_xor_assign, make_mutable, make)
 
-        #undef BOOST_PROTO_UNARY_OP_RESULT
-        #undef BOOST_PROTO_BINARY_OP_RESULT
+        #undef BOOST_PROTO_UNARY_DEFAULT_EVAL
+        #undef BOOST_PROTO_BINARY_DEFAULT_EVAL
 
             /// INTERNAL ONLY
             template<typename Expr, typename Context>
@@ -194,19 +210,6 @@
               : memfun_eval<Expr, Context, is_member_function_eval<Expr, Context>::value>
             {};
 
-            template<typename Expr, typename Context, typename Tag>
-            struct default_eval<Expr, Context, Tag, 0>
-            {
-                typedef
-                    typename proto::result_of::value<Expr &>::type
-                result_type;
-
-                result_type operator ()(Expr &expr, Context &) const
-                {
-                    return proto::value(expr);
-                }
-            };
-
             // Handle post-increment specially.
             template<typename Expr, typename Context>
             struct default_eval<Expr, Context, proto::tag::post_inc, 1>
@@ -298,7 +301,7 @@
             };
 
             // Handle function specially
-            #define EVAL_TYPE(Z, N, DATA)                                                           \
+            #define BOOST_PROTO_DEFAULT_EVAL_TYPE(Z, N, DATA)                                       \
                 typename proto::result_of::eval<                                                    \
                     typename remove_reference<                                                      \
                         typename proto::result_of::child_c<DATA, N>::type                           \
@@ -307,7 +310,7 @@
                 >::type                                                                             \
                 /**/
 
-            #define EVAL(Z, N, DATA)                                                                \
+            #define BOOST_PROTO_DEFAULT_EVAL(Z, N, DATA)                                            \
                 proto::eval(proto::child_c<N>(DATA), context)                                       \
                 /**/
 
@@ -315,7 +318,9 @@
             struct default_eval<Expr, Context, proto::tag::function, 1>
             {
                 typedef
-                    typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
+                    typename proto::detail::result_of_fixup<
+                        BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
+                    >::type
                 function_type;
 
                 typedef
@@ -324,7 +329,7 @@
 
                 result_type operator ()(Expr &expr, Context &context) const
                 {
-                    return EVAL(~, 0, expr)();
+                    return BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)();
                 }
             };
 
@@ -332,11 +337,15 @@
             struct default_eval<Expr, Context, proto::tag::function, 2>
             {
                 typedef
-                    typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
+                    typename proto::detail::result_of_fixup<
+                        BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
+                    >::type
                 function_type;
 
                 typedef
-                    typename detail::result_of_<function_type(EVAL_TYPE(~, 1, Expr))>::type
+                    typename detail::result_of_<
+                        function_type(BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 1, Expr))
+                    >::type
                 result_type;
 
                 result_type operator ()(Expr &expr, Context &context) const
@@ -352,29 +361,35 @@
             private:
                 result_type invoke(Expr &expr, Context &context, mpl::false_, mpl::false_) const
                 {
-                    return EVAL(~, 0, expr)(EVAL(~, 1, expr));
+                    return BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)(BOOST_PROTO_DEFAULT_EVAL(~, 1, expr));
                 }
 
                 result_type invoke(Expr &expr, Context &context, mpl::true_, mpl::false_) const
                 {
                     BOOST_PROTO_USE_GET_POINTER();
                     typedef typename detail::classtypeof<function_type>::type class_type;
-                    return (BOOST_PROTO_GET_POINTER(class_type, EVAL(~, 1, expr)) ->* EVAL(~, 0, expr))();
+                    return (
+                        BOOST_PROTO_GET_POINTER(class_type, BOOST_PROTO_DEFAULT_EVAL(~, 1, expr)) ->* 
+                        BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)
+                    )();
                 }
 
                 result_type invoke(Expr &expr, Context &context, mpl::false_, mpl::true_) const
                 {
                     BOOST_PROTO_USE_GET_POINTER();
                     typedef typename detail::classtypeof<function_type>::type class_type;
-                    return (BOOST_PROTO_GET_POINTER(class_type, EVAL(~, 1, expr)) ->* EVAL(~, 0, expr));
+                    return (
+                        BOOST_PROTO_GET_POINTER(class_type, BOOST_PROTO_DEFAULT_EVAL(~, 1, expr)) ->*
+                        BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)
+                    );
                 }
             };
 
             #define BOOST_PP_ITERATION_PARAMS_1 (3, (3, BOOST_PROTO_MAX_ARITY, <boost/proto/context/default.hpp>))
             #include BOOST_PP_ITERATE()
 
-            #undef EVAL_TYPE
-            #undef EVAL
+            #undef BOOST_PROTO_DEFAULT_EVAL_TYPE
+            #undef BOOST_PROTO_DEFAULT_EVAL
 
             /// default_context
             ///
@@ -404,12 +419,14 @@
         struct default_eval<Expr, Context, proto::tag::function, N>
         {
             typedef
-                typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
+                typename proto::detail::result_of_fixup<
+                    BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
+                >::type
             function_type;
 
             typedef
                 typename boost::result_of<
-                    function_type(BOOST_PP_ENUM_SHIFTED(N, EVAL_TYPE, Expr))
+                    function_type(BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFAULT_EVAL_TYPE, Expr))
                 >::type
             result_type;
 
@@ -421,17 +438,24 @@
         private:
             result_type invoke(Expr &expr, Context &context, mpl::false_) const
             {
-                return EVAL(~, 0, expr)(BOOST_PP_ENUM_SHIFTED(N, EVAL, expr));
+                return BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)(
+                    BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFAULT_EVAL, expr)
+                );
             }
 
             result_type invoke(Expr &expr, Context &context, mpl::true_) const
             {
-                #define M0(Z, M, expr) BOOST_PP_COMMA_IF(BOOST_PP_SUB(M, 2)) EVAL(Z, M, expr)
+                #define M0(Z, M, DATA)                                                              \
+                    BOOST_PROTO_DEFAULT_EVAL(Z, BOOST_PP_ADD(M, 2), DATA)                           \
+                    /**/
+
                 BOOST_PROTO_USE_GET_POINTER();
                 typedef typename detail::classtypeof<function_type>::type class_type;
-                return (BOOST_PROTO_GET_POINTER(class_type, EVAL(~, 1, expr)) ->* EVAL(~, 0, expr))(
-                    BOOST_PP_REPEAT_FROM_TO(2, N, M0, expr)
-                );
+                return (
+                    BOOST_PROTO_GET_POINTER(class_type, BOOST_PROTO_DEFAULT_EVAL(~, 1, expr)) ->*
+                    BOOST_PROTO_DEFAULT_EVAL(~, 0, expr)
+                )(BOOST_PP_ENUM(BOOST_PP_SUB(N, 2), M0, expr));
+
                 #undef M0
             }
         };
Modified: trunk/boost/proto/transform/default.hpp
==============================================================================
--- trunk/boost/proto/transform/default.hpp	(original)
+++ trunk/boost/proto/transform/default.hpp	2010-05-03 21:19:53 EDT (Mon, 03 May 2010)
@@ -13,6 +13,9 @@
 
     #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
+    #include <boost/preprocessor/arithmetic/add.hpp>
+    #include <boost/preprocessor/arithmetic/sub.hpp>
+    #include <boost/preprocessor/repetition/enum.hpp>
     #include <boost/preprocessor/repetition/enum_shifted.hpp>
     #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
     #include <boost/ref.hpp>
@@ -29,114 +32,143 @@
 
     namespace boost { namespace proto
     {
-        template<typename Grammar /*= detail::_default*/>
-        struct _default
-          : transform<_default<Grammar> >
+        namespace detail
         {
-            template<typename Expr, typename State, typename Data, typename Tag, long Arity>
-            struct impl2;
+            template<typename Grammar, typename Tag>
+            struct default_case
+              : not_<_>
+            {};
 
-            template<typename Expr, typename State, typename Data, typename Tag>
-            struct impl2<Expr, State, Data, Tag, 0>
-              : _value::impl<Expr, State, Data>
-            {};
-
-            #define BOOST_PROTO_UNARY_OP_RESULT(OP, TAG, MAKE)                                      \
-            template<typename Expr, typename State, typename Data>                                  \
-            struct impl2<Expr, State, Data, TAG, 1>                                                 \
-              : transform_impl<Expr, State, Data>                                                   \
-            {                                                                                       \
-            private:                                                                                \
-                typedef typename result_of::child_c<Expr, 0>::type e0;                              \
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;           \
-            public:                                                                                 \
-                BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type)                    \
-                result_type operator ()(                                                            \
-                    typename impl2::expr_param e                                                    \
-                  , typename impl2::state_param s                                                   \
-                  , typename impl2::data_param d                                                    \
-                ) const                                                                             \
-                {                                                                                   \
-                    typename Grammar::template impl<e0, State, Data> t0;                            \
-                    return OP t0(proto::child_c<0>(e), s, d);                                       \
-                }                                                                                   \
-            };                                                                                      \
+            template<typename Grammar>
+            struct default_case<Grammar, tag::terminal>
+              : when<terminal<_>, _value>
+            {};
+
+            template<typename Grammar>
+            struct default_cases
+            {
+                template<typename Tag>
+                struct case_
+                  : default_case<Grammar, Tag>
+                {};
+            };
+
+            #define BOOST_PROTO_UNARY_DEFAULT_EVAL(OP, TAG, MAKE)                                       \
+            template<typename Grammar>                                                                  \
+            struct BOOST_PP_CAT(default_, TAG)                                                          \
+              : transform<BOOST_PP_CAT(default_, TAG)<Grammar> >                                        \
+            {                                                                                           \
+                template<typename Expr, typename State, typename Data>                                  \
+                struct impl                                                                             \
+                  : transform_impl<Expr, State, Data>                                                   \
+                {                                                                                       \
+                private:                                                                                \
+                    typedef typename result_of::child_c<Expr, 0>::type e0;                              \
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;           \
+                public:                                                                                 \
+                    BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type)                    \
+                    result_type operator ()(                                                            \
+                        typename impl::expr_param e                                                     \
+                      , typename impl::state_param s                                                    \
+                      , typename impl::data_param d                                                     \
+                    ) const                                                                             \
+                    {                                                                                   \
+                        typename Grammar::template impl<e0, State, Data> t0;                            \
+                        return OP t0(proto::child_c<0>(e), s, d);                                       \
+                    }                                                                                   \
+                };                                                                                      \
+            };                                                                                          \
+                                                                                                        \
+            template<typename Grammar>                                                                  \
+            struct default_case<Grammar, tag::TAG>                                                      \
+            : when<unary_expr<tag::TAG, Grammar>, BOOST_PP_CAT(default_, TAG)<Grammar> >                \
+            {};                                                                                         \
             /**/
 
-            #define BOOST_PROTO_BINARY_OP_RESULT(OP, TAG, LMAKE, RMAKE)                             \
-            template<typename Expr, typename State, typename Data>                                  \
-            struct impl2<Expr, State, Data, TAG, 2>                                                 \
-              : transform_impl<Expr, State, Data>                                                   \
-            {                                                                                       \
-            private:                                                                                \
-                typedef typename result_of::child_c<Expr, 0>::type e0;                              \
-                typedef typename result_of::child_c<Expr, 1>::type e1;                              \
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;           \
-                typedef typename Grammar::template impl<e1, State, Data>::result_type r1;           \
-            public:                                                                                 \
-                BOOST_PROTO_DECLTYPE_(                                                              \
-                    proto::detail::LMAKE<r0>() OP proto::detail::RMAKE<r1>()                        \
-                  , result_type                                                                     \
-                )                                                                                   \
-                result_type operator ()(                                                            \
-                    typename impl2::expr_param e                                                    \
-                  , typename impl2::state_param s                                                   \
-                  , typename impl2::data_param d                                                    \
-                ) const                                                                             \
-                {                                                                                   \
-                    typename Grammar::template impl<e0, State, Data> t0;                            \
-                    typename Grammar::template impl<e1, State, Data> t1;                            \
-                    return t0(proto::child_c<0>(e), s, d)                                           \
-                        OP t1(proto::child_c<1>(e), s, d);                                          \
-                }                                                                                   \
-            };                                                                                      \
+            #define BOOST_PROTO_BINARY_DEFAULT_EVAL(OP, TAG, LMAKE, RMAKE)                              \
+            template<typename Grammar>                                                                  \
+            struct BOOST_PP_CAT(default_, TAG)                                                          \
+              : transform<BOOST_PP_CAT(default_, TAG)<Grammar> >                                        \
+            {                                                                                           \
+                template<typename Expr, typename State, typename Data>                                  \
+                struct impl                                                                             \
+                  : transform_impl<Expr, State, Data>                                                   \
+                {                                                                                       \
+                private:                                                                                \
+                    typedef typename result_of::child_c<Expr, 0>::type e0;                              \
+                    typedef typename result_of::child_c<Expr, 1>::type e1;                              \
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;           \
+                    typedef typename Grammar::template impl<e1, State, Data>::result_type r1;           \
+                public:                                                                                 \
+                    BOOST_PROTO_DECLTYPE_(                                                              \
+                        proto::detail::LMAKE<r0>() OP proto::detail::RMAKE<r1>()                        \
+                      , result_type                                                                     \
+                    )                                                                                   \
+                    result_type operator ()(                                                            \
+                        typename impl::expr_param e                                                     \
+                      , typename impl::state_param s                                                    \
+                      , typename impl::data_param d                                                     \
+                    ) const                                                                             \
+                    {                                                                                   \
+                        typename Grammar::template impl<e0, State, Data> t0;                            \
+                        typename Grammar::template impl<e1, State, Data> t1;                            \
+                        return t0(proto::child_c<0>(e), s, d)                                           \
+                            OP t1(proto::child_c<1>(e), s, d);                                          \
+                    }                                                                                   \
+                };                                                                                      \
+            };                                                                                          \
+                                                                                                        \
+            template<typename Grammar>                                                                  \
+            struct default_case<Grammar, tag::TAG>                                                      \
+              : when<binary_expr<tag::TAG, Grammar, Grammar>, BOOST_PP_CAT(default_, TAG)<Grammar> >    \
+            {};                                                                                         \
             /**/
 
-            BOOST_PROTO_UNARY_OP_RESULT(+, tag::unary_plus, make)
-            BOOST_PROTO_UNARY_OP_RESULT(-, tag::negate, make)
-            BOOST_PROTO_UNARY_OP_RESULT(*, tag::dereference, make)
-            BOOST_PROTO_UNARY_OP_RESULT(~, tag::complement, make)
-            BOOST_PROTO_UNARY_OP_RESULT(&, tag::address_of, make)
-            BOOST_PROTO_UNARY_OP_RESULT(!, tag::logical_not, make)
-            BOOST_PROTO_UNARY_OP_RESULT(++, tag::pre_inc, make_mutable)
-            BOOST_PROTO_UNARY_OP_RESULT(--, tag::pre_dec, make_mutable)
-
-            BOOST_PROTO_BINARY_OP_RESULT(<<, tag::shift_left, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>>, tag::shift_right, make_mutable, make_mutable)
-            BOOST_PROTO_BINARY_OP_RESULT(*, tag::multiplies, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(/, tag::divides, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(%, tag::modulus, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(+, tag::plus, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(-, tag::minus, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(<, tag::less, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>, tag::greater, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(<=, tag::less_equal, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>=, tag::greater_equal, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(==, tag::equal_to, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(!=, tag::not_equal_to, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(||, tag::logical_or, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(&&, tag::logical_and, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(&, tag::bitwise_and, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(|, tag::bitwise_or, make, make)
-            BOOST_PROTO_BINARY_OP_RESULT(^, tag::bitwise_xor, make, make)
-
-            BOOST_PROTO_BINARY_OP_RESULT(=, tag::assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(<<=, tag::shift_left_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(>>=, tag::shift_right_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(*=, tag::multiplies_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(/=, tag::divides_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(%=, tag::modulus_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(+=, tag::plus_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(-=, tag::minus_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(&=, tag::bitwise_and_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(|=, tag::bitwise_or_assign, make_mutable, make)
-            BOOST_PROTO_BINARY_OP_RESULT(^=, tag::bitwise_xor_assign, make_mutable, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(+, unary_plus, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(-, negate, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(*, dereference, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(~, complement, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(&, address_of, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(!, logical_not, make)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(++, pre_inc, make_mutable)
+            BOOST_PROTO_UNARY_DEFAULT_EVAL(--, pre_dec, make_mutable)
+
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<<, shift_left, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>>, shift_right, make_mutable, make_mutable)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(*, multiplies, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(/, divides, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(%, modulus, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(+, plus, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(-, minus, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<, less, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>, greater, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<=, less_equal, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>=, greater_equal, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(==, equal_to, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(!=, not_equal_to, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(||, logical_or, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(&&, logical_and, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(&, bitwise_and, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(|, bitwise_or, make, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(^, bitwise_xor, make, make)
+
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(=, assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(<<=, shift_left_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(>>=, shift_right_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(*=, multiplies_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(/=, divides_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(%=, modulus_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(+=, plus_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(-=, minus_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(&=, bitwise_and_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(|=, bitwise_or_assign, make_mutable, make)
+            BOOST_PROTO_BINARY_DEFAULT_EVAL(^=, bitwise_xor_assign, make_mutable, make)
 
-            #undef BOOST_PROTO_UNARY_OP_RESULT
-            #undef BOOST_PROTO_BINARY_OP_RESULT
+            #undef BOOST_PROTO_UNARY_DEFAULT_EVAL
+            #undef BOOST_PROTO_BINARY_DEFAULT_EVAL
 
             /// INTERNAL ONLY
-            template<typename Expr, typename State, typename Data>
+            template<typename Grammar, typename Expr, typename State, typename Data>
             struct is_member_function_invocation
               : is_member_function_pointer<
                     typename remove_const<
@@ -152,8 +184,8 @@
             {};
 
             /// INTERNAL ONLY
-            template<typename Expr, typename State, typename Data, bool IsMemFunCall>
-            struct memfun_impl
+            template<typename Grammar, typename Expr, typename State, typename Data, bool IsMemFunCall>
+            struct default_mem_ptr_impl
               : transform_impl<Expr, State, Data>
             {
             private:
@@ -164,9 +196,9 @@
             public:
                 typedef typename detail::mem_ptr_fun<r0, r1>::result_type result_type;
                 result_type operator ()(
-                    typename memfun_impl::expr_param e
-                  , typename memfun_impl::state_param s
-                  , typename memfun_impl::data_param d
+                    typename default_mem_ptr_impl::expr_param e
+                  , typename default_mem_ptr_impl::state_param s
+                  , typename default_mem_ptr_impl::data_param d
                 ) const
                 {
                     typename Grammar::template impl<e0, State, Data> t0;
@@ -179,8 +211,8 @@
             };
 
             /// INTERNAL ONLY
-            template<typename Expr, typename State, typename Data>
-            struct memfun_impl<Expr, State, Data, true>
+            template<typename Grammar, typename Expr, typename State, typename Data>
+            struct default_mem_ptr_impl<Grammar, Expr, State, Data, true>
               : transform_impl<Expr, State, Data>
             {
             private:
@@ -191,9 +223,9 @@
             public:
                 typedef detail::memfun<r0, r1> result_type;
                 result_type const operator ()(
-                    typename memfun_impl::expr_param e
-                  , typename memfun_impl::state_param s
-                  , typename memfun_impl::data_param d
+                    typename default_mem_ptr_impl::expr_param e
+                  , typename default_mem_ptr_impl::state_param s
+                  , typename default_mem_ptr_impl::data_param d
                 ) const
                 {
                     typename Grammar::template impl<e0, State, Data> t0;
@@ -205,155 +237,245 @@
                 }
             };
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::mem_ptr, 2>
-              : memfun_impl<Expr, State, Data, is_member_function_invocation<Expr, State, Data>::value>
+            template<typename Grammar>
+            struct default_mem_ptr
+              : transform<default_mem_ptr<Grammar> >
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : default_mem_ptr_impl<
+                        Grammar
+                      , Expr
+                      , State
+                      , Data
+                      , is_member_function_invocation<Grammar, Expr, State, Data>::value
+                    >
+                {};
+            };
+
+            template<typename Grammar>
+            struct default_case<Grammar, tag::mem_ptr>
+              : when<mem_ptr<Grammar, Grammar>, default_mem_ptr<Grammar> >
             {};
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::post_inc, 1>
-              : transform_impl<Expr, State, Data>
-            {
-            private:
-                typedef typename result_of::child_c<Expr, 0>::type e0;
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
-            public:
-                BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() ++, result_type)
-                result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
-                ) const
-                {
-                    typename Grammar::template impl<e0, State, Data> t0;
-                    return t0(proto::child_c<0>(e), s, d) ++;
-                }
+            template<typename Grammar>
+            struct default_post_inc
+              : transform<default_post_inc<Grammar> >
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : transform_impl<Expr, State, Data>
+                {
+                private:
+                    typedef typename result_of::child_c<Expr, 0>::type e0;
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+                public:
+                    BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() ++, result_type)
+                    result_type operator ()(
+                        typename impl::expr_param e
+                      , typename impl::state_param s
+                      , typename impl::data_param d
+                    ) const
+                    {
+                        typename Grammar::template impl<e0, State, Data> t0;
+                        return t0(proto::child_c<0>(e), s, d) ++;
+                    }
+                };
             };
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::post_dec, 1>
-              : transform_impl<Expr, State, Data>
-            {
-            private:
-                typedef typename result_of::child_c<Expr, 0>::type e0;
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
-            public:
-                BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() --, result_type)
-                result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
-                ) const
-                {
-                    typename Grammar::template impl<e0, State, Data> t0;
-                    return t0(proto::child_c<0>(e), s, d) --;
-                }
+            template<typename Grammar>
+            struct default_case<Grammar, tag::post_inc>
+              : when<post_inc<Grammar>, default_post_inc<Grammar> >
+            {};
+
+            template<typename Grammar>
+            struct default_post_dec
+              : transform<default_post_dec<Grammar> >
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : transform_impl<Expr, State, Data>
+                {
+                private:
+                    typedef typename result_of::child_c<Expr, 0>::type e0;
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+                public:
+                    BOOST_PROTO_DECLTYPE_(proto::detail::make_mutable<r0>() --, result_type)
+                    result_type operator ()(
+                        typename impl::expr_param e
+                      , typename impl::state_param s
+                      , typename impl::data_param d
+                    ) const
+                    {
+                        typename Grammar::template impl<e0, State, Data> t0;
+                        return t0(proto::child_c<0>(e), s, d) --;
+                    }
+                };
             };
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::subscript, 2>
-              : transform_impl<Expr, State, Data>
-            {
-            private:
-                typedef typename result_of::child_c<Expr, 0>::type e0;
-                typedef typename result_of::child_c<Expr, 1>::type e1;
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
-                typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
-            public:
-                BOOST_PROTO_DECLTYPE_(
-                    proto::detail::make_subscriptable<r0>() [ proto::detail::make<r1>() ]
-                  , result_type
-                )
-                result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
-                ) const
-                {
-                    typename Grammar::template impl<e0, State, Data> t0;
-                    typename Grammar::template impl<e1, State, Data> t1;
-                    return t0(proto::child_c<0>(e), s, d) [
-                           t1(proto::child_c<1>(e), s, d) ];
-                }
+            template<typename Grammar>
+            struct default_case<Grammar, tag::post_dec>
+              : when<post_dec<Grammar>, default_post_dec<Grammar> >
+            {};
+
+            template<typename Grammar>
+            struct default_subscript
+              : transform<default_subscript<Grammar> >
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : transform_impl<Expr, State, Data>
+                {
+                private:
+                    typedef typename result_of::child_c<Expr, 0>::type e0;
+                    typedef typename result_of::child_c<Expr, 1>::type e1;
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+                    typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+                public:
+                    BOOST_PROTO_DECLTYPE_(
+                        proto::detail::make_subscriptable<r0>() [ proto::detail::make<r1>() ]
+                      , result_type
+                    )
+                    result_type operator ()(
+                        typename impl::expr_param e
+                      , typename impl::state_param s
+                      , typename impl::data_param d
+                    ) const
+                    {
+                        typename Grammar::template impl<e0, State, Data> t0;
+                        typename Grammar::template impl<e1, State, Data> t1;
+                        return t0(proto::child_c<0>(e), s, d) [
+                               t1(proto::child_c<1>(e), s, d) ];
+                    }
+                };
             };
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::if_else_, 3>
-              : transform_impl<Expr, State, Data>
+            template<typename Grammar>
+            struct default_case<Grammar, tag::subscript>
+              : when<subscript<Grammar, Grammar>, default_subscript<Grammar> >
+            {};
+
+            template<typename Grammar>
+            struct default_if_else_
             {
-            private:
-                typedef typename result_of::child_c<Expr, 0>::type e0;
-                typedef typename result_of::child_c<Expr, 1>::type e1;
-                typedef typename result_of::child_c<Expr, 2>::type e2;
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
-                typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
-                typedef typename Grammar::template impl<e2, State, Data>::result_type r2;
-            public:
-                BOOST_PROTO_DECLTYPE_(
-                    proto::detail::make<r0>()
-                  ? proto::detail::make<r1>()
-                  : proto::detail::make<r2>()
-                  , result_type
-                )
-                result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
-                ) const
-                {
-                    typename Grammar::template impl<e0, State, Data> t0;
-                    typename Grammar::template impl<e1, State, Data> t1;
-                    typename Grammar::template impl<e2, State, Data> t2;
-                    return t0(proto::child_c<0>(e), s, d)
-                         ? t1(proto::child_c<1>(e), s, d)
-                         : t2(proto::child_c<2>(e), s, d);
-                }
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : transform_impl<Expr, State, Data>
+                {
+                private:
+                    typedef typename result_of::child_c<Expr, 0>::type e0;
+                    typedef typename result_of::child_c<Expr, 1>::type e1;
+                    typedef typename result_of::child_c<Expr, 2>::type e2;
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+                    typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+                    typedef typename Grammar::template impl<e2, State, Data>::result_type r2;
+                public:
+                    BOOST_PROTO_DECLTYPE_(
+                        proto::detail::make<r0>()
+                      ? proto::detail::make<r1>()
+                      : proto::detail::make<r2>()
+                      , result_type
+                    )
+                    result_type operator ()(
+                        typename impl::expr_param e
+                      , typename impl::state_param s
+                      , typename impl::data_param d
+                    ) const
+                    {
+                        typename Grammar::template impl<e0, State, Data> t0;
+                        typename Grammar::template impl<e1, State, Data> t1;
+                        typename Grammar::template impl<e2, State, Data> t2;
+                        return t0(proto::child_c<0>(e), s, d)
+                             ? t1(proto::child_c<1>(e), s, d)
+                             : t2(proto::child_c<2>(e), s, d);
+                    }
+                };
             };
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::comma, 2>
-              : transform_impl<Expr, State, Data>
-            {
-            private:
-                typedef typename result_of::child_c<Expr, 0>::type e0;
-                typedef typename result_of::child_c<Expr, 1>::type e1;
-                typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
-                typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
-            public:
-                typedef typename proto::detail::comma_result<r0, r1>::type result_type;
-                result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
-                ) const
-                {
-                    typename Grammar::template impl<e0, State, Data> t0;
-                    typename Grammar::template impl<e1, State, Data> t1;
-                    return t0(proto::child_c<0>(e), s, d)
-                         , t1(proto::child_c<1>(e), s, d);
-                }
+            template<typename Grammar>
+            struct default_case<Grammar, tag::if_else_>
+              : when<if_else_<Grammar, Grammar, Grammar>, default_if_else_<Grammar> >
+            {};
+
+            template<typename Grammar>
+            struct default_comma
+              : transform<default_comma<Grammar> >
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : transform_impl<Expr, State, Data>
+                {
+                private:
+                    typedef typename result_of::child_c<Expr, 0>::type e0;
+                    typedef typename result_of::child_c<Expr, 1>::type e1;
+                    typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+                    typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+                public:
+                    typedef typename proto::detail::comma_result<r0, r1>::type result_type;
+                    result_type operator ()(
+                        typename impl::expr_param e
+                      , typename impl::state_param s
+                      , typename impl::data_param d
+                    ) const
+                    {
+                        typename Grammar::template impl<e0, State, Data> t0;
+                        typename Grammar::template impl<e1, State, Data> t1;
+                        return t0(proto::child_c<0>(e), s, d)
+                             , t1(proto::child_c<1>(e), s, d);
+                    }
+                };
+            };
+
+            template<typename Grammar>
+            struct default_case<Grammar, tag::comma>
+              : when<comma<Grammar, Grammar>, default_comma<Grammar> >
+            {};
+
+            template<typename Grammar, typename Expr, typename State, typename Data, long Arity>
+            struct default_function_impl;
+
+            template<typename Grammar>
+            struct default_function
+              : transform<default_function<Grammar> >
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : default_function_impl<
+                        Grammar
+                      , Expr
+                      , State
+                      , Data
+                      , transform_impl<Expr, State, Data>::expr::proto_arity_c
+                    >
+                {};
             };
 
-            #define EVAL_TYPE(Z, N, DATA)                                                           \
+            template<typename Grammar>
+            struct default_case<Grammar, tag::function>
+              : when<function<Grammar, vararg<Grammar> >, default_function<Grammar> >
+            {};
+
+            #define BOOST_PROTO_DEFAULT_EVAL_TYPE(Z, N, DATA)                                       \
                 typedef                                                                             \
                     typename result_of::child_c<DATA, N>::type                                      \
                 BOOST_PP_CAT(e, N);                                                                 \
+                                                                                                    \
                 typedef                                                                             \
                     typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>::result_type   \
                 BOOST_PP_CAT(r, N);                                                                 \
                 /**/
 
-            #define EVAL(Z, N, DATA)                                                                \
+            #define BOOST_PROTO_DEFAULT_EVAL(Z, N, DATA)                                            \
                 typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>()(                 \
-                    proto::child_c<N>(DATA), s, d                                            \
+                    proto::child_c<N>(DATA), s, d                                                   \
                 )                                                                                   \
                 /**/
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::function, 1>
+            template<typename Grammar, typename Expr, typename State, typename Data>
+            struct default_function_impl<Grammar, Expr, State, Data, 1>
               : transform_impl<Expr, State, Data>
             {
-                EVAL_TYPE(~, 0, Expr)
+                BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
 
                 typedef
                     typename proto::detail::result_of_fixup<r0>::type
@@ -364,21 +486,21 @@
                 result_type;
 
                 result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
+                    typename default_function_impl::expr_param e
+                  , typename default_function_impl::state_param s
+                  , typename default_function_impl::data_param d
                 ) const
                 {
-                    return EVAL(~, 0, e)();
+                    return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)();
                 }
             };
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::function, 2>
+            template<typename Grammar, typename Expr, typename State, typename Data>
+            struct default_function_impl<Grammar, Expr, State, Data, 2>
               : transform_impl<Expr, State, Data>
             {
-                EVAL_TYPE(~, 0, Expr)
-                EVAL_TYPE(~, 1, Expr)
+                BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 0, Expr)
+                BOOST_PROTO_DEFAULT_EVAL_TYPE(~, 1, Expr)
 
                 typedef
                     typename proto::detail::result_of_fixup<r0>::type
@@ -389,9 +511,9 @@
                 result_type;
 
                 result_type operator ()(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
+                    typename default_function_impl::expr_param e
+                  , typename default_function_impl::state_param s
+                  , typename default_function_impl::data_param d
                 ) const
                 {
                     return this->invoke(
@@ -405,60 +527,60 @@
 
             private:
                 result_type invoke(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
+                    typename default_function_impl::expr_param e
+                  , typename default_function_impl::state_param s
+                  , typename default_function_impl::data_param d
                   , mpl::false_
                   , mpl::false_
                 ) const
                 {
-                    return EVAL(~, 0, e)(EVAL(~, 1, e));
+                    return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)(BOOST_PROTO_DEFAULT_EVAL(~, 1, e));
                 }
 
                 result_type invoke(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
+                    typename default_function_impl::expr_param e
+                  , typename default_function_impl::state_param s
+                  , typename default_function_impl::data_param d
                   , mpl::true_
                   , mpl::false_
                 ) const
                 {
                     BOOST_PROTO_USE_GET_POINTER();
                     typedef typename detail::classtypeof<function_type>::type class_type;
-                    return (BOOST_PROTO_GET_POINTER(class_type, EVAL(~, 1, e)) ->* EVAL(~, 0, e))();
+                    return (
+                        BOOST_PROTO_GET_POINTER(class_type, BOOST_PROTO_DEFAULT_EVAL(~, 1, e)) ->* 
+                        BOOST_PROTO_DEFAULT_EVAL(~, 0, e)
+                    )();
                 }
 
                 result_type invoke(
-                    typename impl2::expr_param e
-                  , typename impl2::state_param s
-                  , typename impl2::data_param d
+                    typename default_function_impl::expr_param e
+                  , typename default_function_impl::state_param s
+                  , typename default_function_impl::data_param d
                   , mpl::false_
                   , mpl::true_
                 ) const
                 {
                     BOOST_PROTO_USE_GET_POINTER();
                     typedef typename detail::classtypeof<function_type>::type class_type;
-                    return (BOOST_PROTO_GET_POINTER(class_type, EVAL(~, 1, e)) ->* EVAL(~, 0, e));
+                    return (
+                        BOOST_PROTO_GET_POINTER(class_type, BOOST_PROTO_DEFAULT_EVAL(~, 1, e)) ->*
+                        BOOST_PROTO_DEFAULT_EVAL(~, 0, e)
+                    );
                 }
             };
 
             #define BOOST_PP_ITERATION_PARAMS_1 (3, (3, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/default.hpp>))
             #include BOOST_PP_ITERATE()
 
-            #undef EVAL_TYPE
-            #undef EVAL
+            #undef BOOST_PROTO_DEFAULT_EVAL_TYPE
+            #undef BOOST_PROTO_DEFAULT_EVAL
+        }
 
-            template<typename Expr, typename State, typename Data>
-            struct impl
-              : impl2<
-                    Expr
-                  , State
-                  , Data
-                  , typename transform_impl<Expr, State, Data>::expr::proto_tag
-                  , transform_impl<Expr, State, Data>::expr::proto_arity_c
-                >
-            {};
-        };
+        template<typename Grammar /*= detail::_default*/>
+        struct _default
+          : switch_<detail::default_cases<Grammar> >
+        {};
 
         template<typename Grammar>
         struct is_callable<_default<Grammar> >
@@ -482,11 +604,11 @@
 
     #define N BOOST_PP_ITERATION()
 
-        template<typename Expr, typename State, typename Data>
-        struct impl2<Expr, State, Data, tag::function, N>
+        template<typename Grammar, typename Expr, typename State, typename Data>
+        struct default_function_impl<Grammar, Expr, State, Data, N>
           : transform_impl<Expr, State, Data>
         {
-            BOOST_PP_REPEAT(N, EVAL_TYPE, Expr)
+            BOOST_PP_REPEAT(N, BOOST_PROTO_DEFAULT_EVAL_TYPE, Expr)
 
             typedef
                 typename proto::detail::result_of_fixup<r0>::type
@@ -499,9 +621,9 @@
             result_type;
 
             result_type operator ()(
-                typename impl2::expr_param e
-              , typename impl2::state_param s
-              , typename impl2::data_param d
+                typename default_function_impl::expr_param e
+              , typename default_function_impl::state_param s
+              , typename default_function_impl::data_param d
             ) const
             {
                 return this->invoke(e, s, d, is_member_function_pointer<function_type>());
@@ -509,28 +631,31 @@
 
         private:
             result_type invoke(
-                typename impl2::expr_param e
-              , typename impl2::state_param s
-              , typename impl2::data_param d
+                typename default_function_impl::expr_param e
+              , typename default_function_impl::state_param s
+              , typename default_function_impl::data_param d
               , mpl::false_
             ) const
             {
-                return EVAL(~, 0, e)(BOOST_PP_ENUM_SHIFTED(N, EVAL, e));
+                return BOOST_PROTO_DEFAULT_EVAL(~, 0, e)(
+                    BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFAULT_EVAL, e)
+                );
             }
 
             result_type invoke(
-                typename impl2::expr_param e
-              , typename impl2::state_param s
-              , typename impl2::data_param d
+                typename default_function_impl::expr_param e
+              , typename default_function_impl::state_param s
+              , typename default_function_impl::data_param d
               , mpl::true_
             ) const
             {
-                #define M0(Z, M, e) BOOST_PP_COMMA_IF(BOOST_PP_SUB(M, 2)) EVAL(Z, M, e)
+                #define M0(Z, M, DATA) BOOST_PROTO_DEFAULT_EVAL(Z, BOOST_PP_ADD(M, 2), DATA)
                 BOOST_PROTO_USE_GET_POINTER();
                 typedef typename detail::classtypeof<function_type>::type class_type;
-                return (BOOST_PROTO_GET_POINTER(class_type, EVAL(~, 1, e)) ->* EVAL(~, 0, e))(
-                    BOOST_PP_REPEAT_FROM_TO(2, N, M0, e)
-                );
+                return (
+                    BOOST_PROTO_GET_POINTER(class_type, BOOST_PROTO_DEFAULT_EVAL(~, 1, e)) ->* 
+                    BOOST_PROTO_DEFAULT_EVAL(~, 0, e)
+                )(BOOST_PP_ENUM(BOOST_PP_SUB(N, 2), M0, e));
                 #undef M0
             }
         };