$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: eric_at_[hidden]
Date: 2007-12-18 03:05:38
Author: eric_niebler
Date: 2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
New Revision: 42137
URL: http://svn.boost.org/trac/boost/changeset/42137
Log:
port make_expr, make_arg and friends
Added:
   branches/proto/v3/boost/xpressive/proto/detail/make_.hpp   (contents, props changed)
   branches/proto/v3/boost/xpressive/proto/detail/make_arg_expr_.hpp   (contents, props changed)
   branches/proto/v3/boost/xpressive/proto/detail/make_expr_ex.hpp   (contents, props changed)
Text files modified: 
   branches/proto/v3/boost/xpressive/proto/args.hpp          |    21 --                                      
   branches/proto/v3/boost/xpressive/proto/expr.hpp          |    22 --                                      
   branches/proto/v3/boost/xpressive/proto/extends.hpp       |    13 +                                       
   branches/proto/v3/boost/xpressive/proto/make_expr.hpp     |   297 ++++++++++++++++++++++++++------------- 
   branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp     |     4                                         
   branches/proto/v3/boost/xpressive/proto/traits.hpp        |    20 +-                                      
   branches/proto/v3/libs/xpressive/proto/test/make_expr.cpp |    43 +++++                                   
   7 files changed, 271 insertions(+), 149 deletions(-)
Modified: branches/proto/v3/boost/xpressive/proto/args.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/args.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/args.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -99,27 +99,6 @@
         #undef CAR
         #undef CDR
 
-            struct make_cons_fun
-            {
-                template<typename Sig>
-                struct result;
-
-                template<typename This, typename... Args>
-                struct result<This(Args...)>
-                {
-                    typedef cons<UNCV(Args)...> type;
-                };
-
-                template<typename... Args>
-                cons<UNCV(Args)...> operator()(Args &&... args) const
-                {
-                    typedef cons<UNCV(Args)...> cons_type;
-                    return argsns_::make_cons_<cons_type>(args...);
-                }
-            };
-
-            make_cons_fun const make_cons = {};
-
         }
 
     }}
Added: branches/proto/v3/boost/xpressive/proto/detail/make_.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/detail/make_.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -0,0 +1,64 @@
+#ifndef BOOST_PP_IS_ITERATING
+    ///////////////////////////////////////////////////////////////////////////////
+    /// \file make_.hpp
+    /// Definintion of the make_ helper
+    //
+    //  Copyright 2007 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)
+
+    template<
+        typename Tag
+      , typename Domain
+      , template<typename> class AsExpr
+      , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)
+      , typename Dummy = void
+    >
+    struct make_;
+
+    template<typename Domain, template<typename> class AsExpr, typename A>
+    struct make_<tag::terminal, Domain, AsExpr, A>
+    {
+        typedef typename boost::result_of<AsExpr<Domain>(A)>::type type;
+
+        static type call(CVREF(A) a)
+        {
+            return AsExpr<Domain>()(a);
+        }
+    };
+
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/detail/make_.hpp>))
+#include BOOST_PP_ITERATE()
+
+#else
+
+    template<
+        typename Tag
+      , typename Domain
+      , template<typename> class AsExpr
+        BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A)
+    >
+    struct make_<Tag, Domain, AsExpr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), A)>
+    {
+        #define TMP(Z, N, DATA) typename boost::result_of<AsExpr<Domain>(A##N)>::type
+        typedef
+            expr<
+                Tag
+              , args<BOOST_PP_ENUM(BOOST_PP_ITERATION(), TMP, ~)>
+            >
+        expr_type;
+        #undef TMP
+
+        typedef typename Domain::template apply<expr_type>::type type;
+
+        #define TMP0(Z, N, DATA) CVREF(A##N) a##N
+        #define TMP1(Z, N, DATA) AsExpr<Domain>()(a##N)
+        static type call(BOOST_PP_ENUM(BOOST_PP_ITERATION(), TMP0, ~))
+        {
+            return Domain::make(expr_type::make(BOOST_PP_ENUM(BOOST_PP_ITERATION(), TMP1, ~)));
+        }
+        #undef TMP0
+        #undef TMP1
+    };
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/detail/make_arg_expr_.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/detail/make_arg_expr_.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -0,0 +1,83 @@
+#ifndef BOOST_PP_IS_ITERATING
+    ///////////////////////////////////////////////////////////////////////////////
+    /// \file make_arg_expr_.hpp
+    /// Definintion of the result_of::make_arg and result_of::make_expr
+    //
+    //  Copyright 2007 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)
+
+    template<typename Tag, typename A0>
+    struct make_arg<Tag, A0>
+      : proto::detail::make_<Tag, typename domain_of<A0>::type, functional::as_arg, A0>
+    {};
+
+    template<typename Tag, typename A0>
+    struct make_arg<Tag, deduce_domain, A0>
+      : proto::detail::make_<Tag, typename domain_of<A0>::type, functional::as_arg, A0>
+    {};
+
+    template<typename Tag, typename A0>
+    struct make_expr<Tag, A0>
+      : proto::detail::make_<Tag, typename domain_of<A0>::type, functional::as_expr, A0>
+    {};
+
+    template<typename Tag, typename A0>
+    struct make_expr<Tag, deduce_domain, A0>
+      : proto::detail::make_<Tag, typename domain_of<A0>::type, functional::as_expr, A0>
+    {};
+
+    #define BOOST_PP_ITERATION_PARAMS_1 (3, (2, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/detail/make_arg_expr_.hpp>))
+    #include BOOST_PP_ITERATE()
+
+#else
+
+    #define N BOOST_PP_ITERATION()
+
+    template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+    struct make_arg<Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, A)>
+      : mpl::if_<
+            is_domain<A0>
+          , proto::detail::make_<Tag, A0, functional::as_arg, BOOST_PP_ENUM_SHIFTED_PARAMS(N, A)>
+          , make_arg<Tag, deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)>
+        >::type
+    {};
+
+    template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+    struct make_arg<Tag, deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)>
+      : proto::detail::make_<
+            Tag
+          , typename proto::detail::deduce_domain_<
+                typename domain_of<A0>::type
+              , BOOST_PP_ENUM_SHIFTED_PARAMS(N, A)
+            >::type
+          , functional::as_arg
+            BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+        >
+    {};
+
+    template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+    struct make_expr<Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, A)>
+      : mpl::if_<
+            is_domain<A0>
+          , proto::detail::make_<Tag, A0, functional::as_expr, BOOST_PP_ENUM_SHIFTED_PARAMS(N, A)>
+          , make_expr<Tag, deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)>
+        >::type
+    {};
+
+    template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+    struct make_expr<Tag, deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)>
+      : proto::detail::make_<
+            Tag
+          , typename proto::detail::deduce_domain_<
+                typename domain_of<A0>::type
+              , BOOST_PP_ENUM_SHIFTED_PARAMS(N, A)
+            >::type
+          , functional::as_expr
+            BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+        >
+    {};
+
+    #undef N
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/detail/make_expr_ex.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/detail/make_expr_ex.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -0,0 +1,83 @@
+#ifndef BOOST_PP_IS_ITERATING
+    ///////////////////////////////////////////////////////////////////////////////
+    /// \file make_expr_ex.hpp
+    /// Exploded instances of the make_expr and make_arg functions
+    //
+    //  Copyright 2007 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)
+
+	#define M1(Z, N, _) ((0)(1))
+
+	#define M2(R, PRODUCT) M3(R, BOOST_PP_SEQ_SIZE(PRODUCT), PRODUCT)
+
+    #define M3(R, SIZE, PRODUCT)                                                                    \
+        template<typename Tag, BOOST_PP_ENUM_PARAMS(SIZE, typename A)>                              \
+        typename lazy_disable_if<                                                                   \
+            is_domain<A0>                                                                           \
+          , result_of::make_arg<Tag, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>                  \
+        >::type                                                                                     \
+        make_arg(BOOST_PP_SEQ_FOR_EACH_I_R(R, M4, ~, PRODUCT))                                      \
+        {                                                                                           \
+            return result_of::make_arg<Tag, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>           \
+                ::call(BOOST_PP_ENUM_PARAMS(SIZE, a));                                              \
+        }                                                                                           \
+                                                                                                    \
+        template<typename Tag, typename Domain, BOOST_PP_ENUM_PARAMS(SIZE, typename A)>             \
+        typename result_of::make_arg<Tag, Domain, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>::type\
+        make_arg(BOOST_PP_SEQ_FOR_EACH_I_R(R, M4, ~, PRODUCT))                                      \
+        {                                                                                           \
+            return result_of::make_arg<Tag, Domain, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>   \
+                ::call(BOOST_PP_ENUM_PARAMS(SIZE, a));                                              \
+        }                                                                                           \
+                                                                                                    \
+        template<typename Tag, BOOST_PP_ENUM_PARAMS(SIZE, typename A)>                              \
+        typename lazy_disable_if<                                                                   \
+            is_domain<A0>                                                                           \
+          , result_of::make_expr<Tag, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>                 \
+        >::type                                                                                     \
+        make_expr(BOOST_PP_SEQ_FOR_EACH_I_R(R, M4, ~, PRODUCT))                                     \
+        {                                                                                           \
+            return result_of::make_expr<Tag, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>          \
+                ::call(BOOST_PP_ENUM_PARAMS(SIZE, a));                                              \
+        }                                                                                           \
+                                                                                                    \
+        template<typename Tag, typename Domain, BOOST_PP_ENUM_PARAMS(SIZE, typename A)>             \
+        typename result_of::make_expr<Tag, Domain, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>::type\
+        make_expr(BOOST_PP_SEQ_FOR_EACH_I_R(R, M4, ~, PRODUCT))                                     \
+        {                                                                                           \
+            return result_of::make_expr<Tag, Domain, BOOST_PP_SEQ_FOR_EACH_I_R(R, M5, ~, PRODUCT)>  \
+                ::call(BOOST_PP_ENUM_PARAMS(SIZE, a));                                              \
+        }                                                                                           \
+        /**/
+
+	#define M4(R, _, I, ELEM)                                                                       \
+		BOOST_PP_COMMA_IF(I) BOOST_PP_CAT(A, I) BOOST_PP_CAT(C, ELEM) &BOOST_PP_CAT(a, I)           \
+		/**/
+
+	#define M5(R, _, I, ELEM)                                                                       \
+		BOOST_PP_COMMA_IF(I) BOOST_PP_CAT(A, I) BOOST_PP_CAT(C, ELEM)&                              \
+        /**/
+
+	#define C0
+
+	#define C1 const
+
+	#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/detail/make_expr_ex.hpp>))
+	#include BOOST_PP_ITERATE()
+
+	#undef C0
+	#undef C1
+	#undef M1
+	#undef M2
+	#undef M3
+	#undef M4
+
+#else
+
+	BOOST_PP_SEQ_FOR_EACH_PRODUCT(
+		M2,
+		BOOST_PP_REPEAT(BOOST_PP_ITERATION(), M1, ~)
+	)
+
+#endif
Modified: branches/proto/v3/boost/xpressive/proto/expr.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/expr.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/expr.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -118,9 +118,7 @@
             operator=(A &&a)
             {
                 expr<tag::assign, args<expr &, typename result_of::as_arg<A>::type> > that =
-                    //{{*this, {proto::as_arg(std::forward<A>(a))}}};
                     {{*this, {result_of::as_arg<A>::call(a)}}};
-                    //{{*this, {a}}};
                 return that;
             }
 
@@ -129,9 +127,7 @@
             operator=(A &&a) const
             {
                 expr<tag::assign, args<expr const &, typename result_of::as_arg<A>::type> > that =
-                    //{{*this, {proto::as_arg(std::forward<A>(a))}}};
                     {{*this, {result_of::as_arg<A>::call(a)}}};
-                    //{{*this, {a}}};
                 return that;
             }
 
@@ -140,9 +136,7 @@
             operator[](A &&a)
             {
                 expr<tag::subscript, args<expr &, typename result_of::as_arg<A>::type> > that =
-                    //{{*this, {proto::as_arg(std::forward<A>(a))}}};
                     {{*this, {result_of::as_arg<A>::call(a)}}};
-                    //{{*this, {a}}};
                 return that;
             }
 
@@ -151,9 +145,7 @@
             operator[](A &&a) const
             {
                 expr<tag::subscript, args<expr const &, typename result_of::as_arg<A>::type> > that =
-                    //{{*this, {proto::as_arg(std::forward<A>(a))}}};
                     {{*this, {result_of::as_arg<A>::call(a)}}};
-                    //{{*this, {a}}};
                 return that;
             }
 
@@ -161,10 +153,9 @@
             expr<tag::function, args<expr &, typename result_of::as_arg<A>::type...> >
             operator()(A &&... a)
             {
-                expr<tag::function, args<expr &, typename result_of::as_arg<A>::type...> > that =
-                    //{argsns_::make_cons(*this, proto::as_arg(std::forward<A>(a))...)};
-                    {argsns_::make_cons(*this, result_of::as_arg<A>::call(a)...)};
-                    //{{*this, a...}};
+                typedef args<expr &, typename result_of::as_arg<A>::type...> args_type;
+                expr<tag::function, args_type> that =
+                    {argsns_::make_cons_<typename args_type::cons_type>(*this, result_of::as_arg<A>::call(a)...)};
                 return that;
             }
 
@@ -172,10 +163,9 @@
             expr<tag::function, args<expr const &, typename result_of::as_arg<A>::type...> >
             operator()(A &&... a) const
             {
-                expr<tag::function, args<expr const &, typename result_of::as_arg<A>::type...> > that =
-                    //{argsns_::make_cons(*this, proto::as_arg(std::forward<A>(a))...)};
-                    {argsns_::make_cons(*this, result_of::as_arg<A>::call(a)...)};
-                    //{{*this, a...}};
+                typedef args<expr const &, typename result_of::as_arg<A>::type...> args_type;
+                expr<tag::function, args_type> that =
+                    {argsns_::make_cons_<typename args_type::cons_type>(*this, result_of::as_arg<A>::call(a)...)};
                 return that;
             }
         };
Modified: branches/proto/v3/boost/xpressive/proto/extends.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/extends.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/extends.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -160,17 +160,20 @@
         >::type                                                                                     \
         operator ()(A &&... a) BOOST_PROTO_CONST ## Const                                           \
         {                                                                                           \
+           typedef                                                                                  \
+                boost::proto::args<                                                                 \
+                    Derived BOOST_PROTO_CONST ## Const &                                            \
+                  , typename boost::proto::result_of::as_arg<A, Domain>::type...                    \
+                >                                                                                   \
+            args_type;                                                                              \
             typedef                                                                                 \
                 boost::proto::expr<                                                                 \
                     boost::proto::tag::function                                                     \
-                  , boost::proto::args<                                                             \
-                        Derived BOOST_PROTO_CONST ## Const &                                        \
-                      , typename boost::proto::result_of::as_arg<A, Domain>::type...                \
-                    >                                                                               \
+                  , args_type                                                                       \
                 >                                                                                   \
             that_type;                                                                              \
             that_type that = {                                                                      \
-                boost::proto::argsns_::make_cons(                                                   \
+                boost::proto::argsns_::make_cons_<typename args_type::cons_type>(                   \
                     *static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)                        \
                   , boost::proto::result_of::as_arg<A, Domain>::call(a)...                          \
                 )                                                                                   \
Modified: branches/proto/v3/boost/xpressive/proto/make_expr.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/make_expr.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/make_expr.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -28,6 +28,7 @@
 #include <boost/fusion/include/front.hpp>
 #include <boost/fusion/include/transform_view.hpp>
 #include <boost/fusion/include/invoke_function_object.hpp>
+#include <boost/fusion/include/unfused_generic.hpp>
 #include <boost/xpressive/proto/detail/define.hpp>
 
 /// INTERNAL ONLY
@@ -237,16 +238,11 @@
     )                                                                                           \
     /**/
 
-namespace boost { namespace fusion
-{
-    template<typename Function>
-    class unfused_generic;
-}}
-
 namespace boost { namespace proto
 {
     namespace detail
     {
+    #ifdef BOOST_HAS_VARIADIC_TMPL
         template<typename Domain, typename... Rest>
         struct deduce_domain_
         {
@@ -257,6 +253,24 @@
         struct deduce_domain_<default_domain, Head, Tail...>
           : deduce_domain_<typename domain_of<Head>::type, Tail...>
         {};
+    #else
+        template<typename Domain, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
+        struct deduce_domain_
+        {
+            typedef Domain type;
+        };
+
+        template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)>
+        struct deduce_domain_<default_domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)>
+          : deduce_domain_<typename domain_of<A0>::type, BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PROTO_MAX_ARITY, A)>
+        {};
+
+        template<>
+        struct deduce_domain_<default_domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
+        {
+            typedef default_domain type;
+        };
+    #endif
 
         struct fold_domain_
         {
@@ -292,11 +306,58 @@
             struct result
             {};
 
+        #ifdef BOOST_HAS_VARIADIC_TMPL
             template<typename This, typename... Args>
             struct result<This(Args...)>
             {
                 typedef args<UNCV(Args)...> type;
             };
+        #else
+            #define TMP0(Z, N, DATA) UNCV(A##N)
+            #define TMP1(Z, N, DATA)                                                                \
+            template<typename This BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename A)>               \
+            struct result<This(BOOST_PP_ENUM_PARAMS_Z(Z, N, A))>                                    \
+            {                                                                                       \
+                typedef args<BOOST_PP_ENUM_ ## Z(N, TMP0, ~)> type;                                 \
+            };
+            BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP1, ~)
+            #undef TMP0
+            #undef TMP1
+        #endif
+        };
+
+        template<typename Cons>
+        struct make_cons_fun
+        {
+            typedef Cons result_type;
+
+        #ifdef BOOST_HAS_VARIADIC_TMPL
+            template<typename... Args>
+            Cons operator()(Args &... args) const
+            {
+                return argsns_::make_cons_<Cons>(args...);
+            }
+        #else
+            #define TMP(Z, N, DATA)                                                                 \
+            template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)>                                      \
+            Cons operator()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const                       \
+            {                                                                                       \
+                return argsns_::make_cons_<Cons>(BOOST_PP_ENUM_PARAMS_Z(Z, N, a));                  \
+            }
+            BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
+            #undef TMP
+        #endif
+        };
+
+        // HACKHACK
+        template<typename Fun>
+        struct constify : Fun
+        {
+            template<typename Sig>
+            struct result
+            {
+                typedef typename Fun::template result<Sig>::type const type;
+            };
         };
 
         template<
@@ -308,24 +369,22 @@
         >
         struct unpack_
         {
-            typedef expr<
-                Tag
-              , typename fusion::result_of::invoke_function_object<
+            typedef 
+                typename fusion::result_of::invoke_function_object<
                     make_args_fun
                   , fusion::transform_view<Sequence const, AsExpr<Domain> >
                 >::type
-            > expr_type;
+            args_type;
 
+            typedef expr<Tag, args_type> expr_type;
             typedef typename Domain::template apply<expr_type>::type type;
 
             static type call(CVREF(Sequence) sequence)
             {
-                fusion::transform_view<Sequence const, AsExpr<Domain> > seq(sequence, AsExpr<Domain>());
-
-                expr_type that = {
-                    fusion::invoke_function_object(argsns_::make_cons_fun(), seq)
-                };
-
+                constify<AsExpr<Domain> > as_expr;
+                make_cons_fun<typename args_type::cons_type> make_cons;
+                fusion::transform_view<Sequence const, constify<AsExpr<Domain> > > seq(sequence, as_expr);
+                expr_type that = {fusion::invoke_function_object(make_cons, seq)};
                 return Domain::make(that);
             }
         };
@@ -379,7 +438,7 @@
           : unpack_<tag::terminal, default_domain, AsExpr, Sequence, 1u>
         {};
 
-
+    #ifdef BOOST_HAS_VARIADIC_TMPL
         template<typename Tag, typename Domain, template<typename> class AsExpr, typename... Args>
         struct make_
         {
@@ -408,6 +467,9 @@
                 return AsExpr<Domain>()(a);
             }
         };
+    #else
+    #include <boost/xpressive/proto/detail/make_.hpp>
+    #endif
 
     }
 
@@ -435,6 +497,29 @@
             >
         {};
 
+        template<typename Tag, typename Sequence, typename, typename>
+        struct unpack_expr
+          : proto::detail::unpack_<
+                Tag
+              , deduce_domain
+              , functional::as_expr
+              , Sequence
+              , fusion::result_of::size<Sequence>::type::value
+            >
+        {};
+
+        template<typename Tag, typename Domain, typename Sequence>
+        struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
+          : proto::detail::unpack_<
+                Tag
+              , Domain
+              , functional::as_expr
+              , Sequence
+              , fusion::result_of::size<Sequence>::type::value
+            >
+        {};
+
+    #ifdef BOOST_HAS_VARIADIC_TMPL
         template<typename Tag, typename Head, typename... Tail>
         struct make_arg<Tag, Head, Tail...>
           : mpl::if_<
@@ -458,28 +543,6 @@
             >
         {};
 
-        template<typename Tag, typename Sequence, typename, typename>
-        struct unpack_expr
-          : proto::detail::unpack_<
-                Tag
-              , deduce_domain
-              , functional::as_expr
-              , Sequence
-              , fusion::result_of::size<Sequence>::type::value
-            >
-        {};
-
-        template<typename Tag, typename Domain, typename Sequence>
-        struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
-          : proto::detail::unpack_<
-                Tag
-              , Domain
-              , functional::as_expr
-              , Sequence
-              , fusion::result_of::size<Sequence>::type::value
-            >
-        {};
-
         template<typename Tag, typename Head, typename... Tail>
         struct make_expr<Tag, Head, Tail...>
           : mpl::if_<
@@ -502,12 +565,16 @@
               , Tail...
             >
         {};
+    #else
+    #include <boost/xpressive/proto/detail/make_arg_expr_.hpp>
+    #endif
+
     }
 
     namespace functional
     {
         template<typename Tag, typename Domain>
-        struct make_arg
+        struct unpack_arg
         {
             BOOST_PROTO_CALLABLE()
 
@@ -515,21 +582,27 @@
             struct result
             {};
 
-            template<typename This, typename... A>
-            struct result<This(A...)>
-              : result_of::make_arg<Tag, Domain, A...>
+            template<typename This, typename Sequence>
+            struct result<This(Sequence)>
+              : result_of::unpack_arg<Tag, Domain, UNCVREF(Sequence)>
             {};
 
-            template<typename... A>
-            typename result_of::make_arg<Tag, Domain, A...>::type
-            operator ()(A &&...a) const
+            template<typename This>
+            struct result<This(fusion::vector0 &)>
             {
-                return result_of::make_arg<Tag, Domain, A...>::call(a...);
+                typedef void type;
+            };
+
+            template<typename Sequence>
+            typename result_of::unpack_arg<Tag, Domain, Sequence>::type
+            operator ()(Sequence const &sequence) const
+            {
+                return result_of::unpack_arg<Tag, Domain, Sequence>::call(sequence);
             }
         };
 
         template<typename Tag, typename Domain>
-        struct unpack_arg
+        struct unpack_expr
         {
             BOOST_PROTO_CALLABLE()
 
@@ -539,43 +612,47 @@
 
             template<typename This, typename Sequence>
             struct result<This(Sequence)>
-              : result_of::unpack_arg<Tag, Domain, UNCVREF(Sequence)>
+              : result_of::unpack_expr<Tag, Domain, UNCVREF(Sequence)>
             {};
 
+            template<typename This>
+            struct result<This(fusion::vector0 &)>
+            {
+                typedef void type;
+            };
+
             template<typename Sequence>
-            typename result_of::unpack_arg<Tag, Domain, Sequence>::type
+            typename result_of::unpack_expr<Tag, Domain, Sequence>::type
             operator ()(Sequence const &sequence) const
             {
-                return result_of::unpack_arg<Tag, Domain, Sequence>::call(sequence);
+                return result_of::unpack_expr<Tag, Domain, Sequence>::call(sequence);
             }
         };
 
+    #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
         template<typename Tag, typename Domain>
-        struct unfused_arg_fun
+        struct make_arg
         {
             BOOST_PROTO_CALLABLE()
 
-            template<typename Sequence>
+            template<typename Sig>
             struct result
-              : result_of::unpack_arg<Tag, Domain, Sequence>
             {};
 
-            template<typename Sequence>
-            typename proto::result_of::unpack_arg<Tag, Domain, Sequence>::type
-            operator ()(Sequence const &sequence) const
+            template<typename This, typename... A>
+            struct result<This(A...)>
+              : result_of::make_arg<Tag, Domain, A...>
+            {};
+
+            template<typename... A>
+            typename result_of::make_arg<Tag, Domain, A...>::type
+            operator ()(A &&...a) const
             {
-                return result_of::unpack_arg<Tag, Domain, Sequence>::call(sequence);
+                return result_of::make_arg<Tag, Domain, A...>::call(a...);
             }
         };
 
         template<typename Tag, typename Domain>
-        struct unfused_arg
-          : fusion::unfused_generic<unfused_arg_fun<Tag, Domain> >
-        {
-            BOOST_PROTO_CALLABLE()
-        };
-
-        template<typename Tag, typename Domain>
         struct make_expr
         {
             BOOST_PROTO_CALLABLE()
@@ -596,39 +673,60 @@
                 return result_of::make_expr<Tag, Domain, A...>::call(a...);
             }
         };
-
+    #else
         template<typename Tag, typename Domain>
-        struct unpack_expr
+        struct unfused_arg_fun
         {
             BOOST_PROTO_CALLABLE()
 
             template<typename Sig>
-            struct result
-            {};
+            struct result;
 
             template<typename This, typename Sequence>
             struct result<This(Sequence)>
-              : result_of::unpack_expr<Tag, Domain, UNCVREF(Sequence)>
+              : result_of::unpack_arg<Tag, Domain, UNCVREF(Sequence)>
             {};
 
+            template<typename This>
+            struct result<This(fusion::vector0 &)>
+            {
+                typedef void type;
+            };
+
             template<typename Sequence>
-            typename result_of::unpack_expr<Tag, Domain, Sequence>::type
+            typename proto::result_of::unpack_arg<Tag, Domain, Sequence>::type
             operator ()(Sequence const &sequence) const
             {
-                return result_of::unpack_expr<Tag, Domain, Sequence>::call(sequence);
+                return result_of::unpack_arg<Tag, Domain, Sequence>::call(sequence);
             }
         };
 
         template<typename Tag, typename Domain>
+        struct make_arg
+          : fusion::unfused_generic<unfused_arg_fun<Tag, Domain> >
+        {
+            BOOST_PROTO_CALLABLE()
+        };
+
+        template<typename Tag, typename Domain>
         struct unfused_expr_fun
         {
             BOOST_PROTO_CALLABLE()
 
-            template<typename Sequence>
-            struct result
-              : result_of::unpack_expr<Tag, Domain, Sequence>
+            template<typename Sig>
+            struct result;
+
+            template<typename This, typename Sequence>
+            struct result<This(Sequence)>
+              : result_of::unpack_expr<Tag, Domain, UNCVREF(Sequence)>
             {};
 
+            template<typename This>
+            struct result<This(fusion::vector0 &)>
+            {
+                typedef void type;
+            };
+
             template<typename Sequence>
             typename proto::result_of::unpack_expr<Tag, Domain, Sequence>::type
             operator ()(Sequence const &sequence) const
@@ -638,11 +736,13 @@
         };
 
         template<typename Tag, typename Domain>
-        struct unfused_expr
+        struct make_expr
           : fusion::unfused_generic<unfused_expr_fun<Tag, Domain> >
         {
             BOOST_PROTO_CALLABLE()
         };
+    #endif
+
     }
 
     /// unpack_arg
@@ -666,46 +766,47 @@
         return result_of::unpack_arg<Tag, Domain, Sequence2>::call(sequence2);
     }
 
-    /// make_arg
+    /// unpack_expr
     ///
-    template<typename Tag, typename Head, typename... Tail>
+    template<typename Tag, typename Sequence>
     typename lazy_disable_if<
-        is_domain<Head>
-      , result_of::make_arg<Tag, Head, Tail...>
+        is_domain<Sequence>
+      , result_of::unpack_expr<Tag, Sequence>
     >::type
-    make_arg(Head &&head, Tail &&... tail)
+    unpack_expr(Sequence const &sequence)
     {
-        return result_of::make_arg<Tag, Head, Tail...>::call(head, tail...);
+        return result_of::unpack_expr<Tag, Sequence>::call(sequence);
     }
 
     /// \overload
     ///
-    template<typename Tag, typename Domain, typename Head, typename... Tail>
-    typename result_of::make_arg<Tag, Domain, Head, Tail...>::type
-    make_arg(Head &&head, Tail &&... tail)
+    template<typename Tag, typename Domain, typename Sequence2>
+    typename result_of::unpack_expr<Tag, Domain, Sequence2>::type
+    unpack_expr(Sequence2 const &sequence2)
     {
-        return result_of::make_arg<Tag, Domain, Head, Tail...>::call(head, tail...);
+        return result_of::unpack_expr<Tag, Domain, Sequence2>::call(sequence2);
     }
 
-    /// unpack_expr
+    #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    /// make_arg
     ///
-    template<typename Tag, typename Sequence>
+    template<typename Tag, typename Head, typename... Tail>
     typename lazy_disable_if<
-        is_domain<Sequence>
-      , result_of::unpack_expr<Tag, Sequence>
+        is_domain<Head>
+      , result_of::make_arg<Tag, Head, Tail...>
     >::type
-    unpack_expr(Sequence const &sequence)
+    make_arg(Head &&head, Tail &&... tail)
     {
-        return result_of::unpack_expr<Tag, Sequence>::call(sequence);
+        return result_of::make_arg<Tag, Head, Tail...>::call(head, tail...);
     }
 
     /// \overload
     ///
-    template<typename Tag, typename Domain, typename Sequence2>
-    typename result_of::unpack_expr<Tag, Domain, Sequence2>::type
-    unpack_expr(Sequence2 const &sequence2)
+    template<typename Tag, typename Domain, typename Head, typename... Tail>
+    typename result_of::make_arg<Tag, Domain, Head, Tail...>::type
+    make_arg(Head &&head, Tail &&... tail)
     {
-        return result_of::unpack_expr<Tag, Domain, Sequence2>::call(sequence2);
+        return result_of::make_arg<Tag, Domain, Head, Tail...>::call(head, tail...);
     }
 
     /// make_expr
@@ -729,6 +830,9 @@
         return result_of::make_expr<Tag, Domain, Head, Tail...>::call(head, tail...);
     }
 
+    #else
+    #include <boost/xpressive/proto/detail/make_expr_ex.hpp>
+    #endif
 
     template<typename Tag, typename Domain>
     struct is_callable<functional::make_arg<Tag, Domain> >
@@ -760,7 +864,6 @@
       : mpl::true_
     {};
 
-
 }}
 
 #include <boost/xpressive/proto/detail/undef.hpp>
Modified: branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -231,21 +231,25 @@
         #else
         template<
             typename Tag
+          , typename DomainOrArg
             BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
                 BOOST_PROTO_MAX_ARITY
               , typename A
               , = void BOOST_PP_INTERCEPT
             )
+          , typename Dummy = void
         >
         struct make_arg;
 
         template<
             typename Tag
+          , typename DomainOrArg
             BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
                 BOOST_PROTO_MAX_ARITY
               , typename A
               , = void BOOST_PP_INTERCEPT
             )
+          , typename Dummy = void
         >
         struct make_expr;
         #endif
Modified: branches/proto/v3/boost/xpressive/proto/traits.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/traits.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/traits.hpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -299,7 +299,7 @@
             typedef expr<tag::terminal, term<value_type> > expr_type;
             typedef typename Domain::template apply<expr_type>::type type;
 
-            static type call(CVREF(T) t)
+            static type const call(CVREF(T) t)
             {
                 return Domain::make(expr_type::make(t));
             }
@@ -310,7 +310,7 @@
         {
             typedef typename T::proto_derived_expr type;  // strips the cv-qualification
 
-            static type call(T const &t)
+            static type const call(T const &t)
             {
                 return t;
             }
@@ -321,7 +321,7 @@
         {
             typedef typename T::proto_derived_expr type; // strips the cv-qualification
 
-            static type call(T &t)
+            static type const call(T &t)
             {
                 return t;
             }
@@ -333,7 +333,7 @@
             typedef expr<tag::terminal, term<CVREF(T) > > expr_type;
             typedef typename Domain::template apply<expr_type>::type type;
 
-            static type call(CVREF(T) t)
+            static type const call(CVREF(T) t)
             {
                 return Domain::make(expr_type::make(t));
             }
@@ -394,21 +394,21 @@
 
         #ifdef BOOST_HAS_RVALUE_REFS
             template<typename T>
-            typename result_of::as_arg<T, Domain>::type
+            typename result_of::as_arg<T, Domain>::type const
             operator ()(T &&t) const
             {
                 return result_of::as_arg<T, Domain>::call(t);
             }
         #else
             template<typename T>
-            typename result_of::as_arg<T &, Domain>::type
+            typename result_of::as_arg<T &, Domain>::type const
             operator ()(T &t) const
             {
                 return result_of::as_arg<T &, Domain>::call(t);
             }
 
             template<typename T>
-            typename result_of::as_arg<T const &, Domain>::type
+            typename result_of::as_arg<T const &, Domain>::type const
             operator ()(T const &t) const
             {
                 return result_of::as_arg<T const &, Domain>::call(t);
@@ -429,21 +429,21 @@
 
         #ifdef BOOST_HAS_RVALUE_REFS
             template<typename T>
-            typename result_of::as_expr<T, Domain>::type
+            typename result_of::as_expr<T, Domain>::type const
             operator ()(T &&t) const
             {
                 return result_of::as_expr<T, Domain>::call(t);
             }
         #else
             template<typename T>
-            typename result_of::as_expr<T &, Domain>::type
+            typename result_of::as_expr<T &, Domain>::type const
             operator ()(T &t) const
             {
                 return result_of::as_expr<T &, Domain>::call(t);
             }
 
             template<typename T>
-            typename result_of::as_expr<T const &, Domain>::type
+            typename result_of::as_expr<T const &, Domain>::type const
             operator ()(T const &t) const
             {
                 return result_of::as_expr<T const &, Domain>::call(t);
Modified: branches/proto/v3/libs/xpressive/proto/test/make_expr.cpp
==============================================================================
--- branches/proto/v3/libs/xpressive/proto/test/make_expr.cpp	(original)
+++ branches/proto/v3/libs/xpressive/proto/test/make_expr.cpp	2007-12-18 03:05:36 EST (Tue, 18 Dec 2007)
@@ -46,6 +46,25 @@
     BOOST_CHECK_EQUAL(arg(arg(left(p4))), 42);
 }
 
+void test_make_expr2()
+{
+    int i = 42;
+    terminal<int>::type t1 = functional::make_expr<tag::terminal>()(1);
+    terminal<int>::type t2 = functional::make_expr<tag::terminal>()(i);
+    posit<terminal<int>::type>::type p1 = functional::make_expr<tag::posit>()(1);
+    posit<terminal<int>::type>::type p2 = functional::make_expr<tag::posit>()(i);
+    BOOST_CHECK_EQUAL(arg(arg(p2)), 42);
+
+    ewrap<posit<ewrap<terminal<int>::type> >::type> p3 = functional::make_expr<tag::posit, mydomain>()(i);
+    BOOST_CHECK_EQUAL(arg(arg(p3)), 42);
+
+    ewrap<plus<
+        ewrap<posit<ewrap<terminal<int>::type> >::type>
+      , ewrap<terminal<int>::type>
+    >::type> p4 = functional::make_expr<tag::plus>()(p3, 0);
+    BOOST_CHECK_EQUAL(arg(arg(left(p4))), 42);
+}
+
 void test_unpack_expr()
 {
     int i = 42;
@@ -68,6 +87,28 @@
     BOOST_CHECK_EQUAL(arg(arg(left(p4))), 42);
 }
 
+void test_unpack_expr2()
+{
+    int i = 42;
+    fusion::vector<int> v1(1);
+    fusion::vector<int&> v2(i);
+    terminal<int>::type t1 = functional::unpack_expr<tag::terminal>()(v1);
+    terminal<int>::type t2 = functional::unpack_expr<tag::terminal>()(v2);
+    posit<terminal<int>::type>::type p1 = functional::unpack_expr<tag::posit>()(v1);
+    posit<terminal<int>::type>::type p2 = functional::unpack_expr<tag::posit>()(v2);
+    BOOST_CHECK_EQUAL(arg(arg(p2)), 42);
+
+    ewrap<posit<ewrap<terminal<int>::type> >::type> p3 = functional::unpack_expr<tag::posit, mydomain>()(v2);
+    BOOST_CHECK_EQUAL(arg(arg(p3)), 42);
+
+    fusion::vector<ewrap<posit<ewrap<terminal<int>::type> >::type>, int> v3(p3, 0);
+    ewrap<plus<
+        ewrap<posit<ewrap<terminal<int>::type> >::type>
+      , ewrap<terminal<int>::type>
+    >::type> p4 = functional::unpack_expr<tag::plus>()(v3);
+    BOOST_CHECK_EQUAL(arg(arg(left(p4))), 42);
+}
+
 using namespace unit_test;
 ///////////////////////////////////////////////////////////////////////////////
 // init_unit_test_suite
@@ -77,7 +118,9 @@
     test_suite *test = BOOST_TEST_SUITE("test make_expr, unpack_expr and friends");
 
     test->add(BOOST_TEST_CASE(&test_make_expr));
+    test->add(BOOST_TEST_CASE(&test_make_expr2));
     test->add(BOOST_TEST_CASE(&test_unpack_expr));
+    test->add(BOOST_TEST_CASE(&test_unpack_expr2));
 
     return test;
 }