Boost logo

Boost-Commit :

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;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk