$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: eric_at_[hidden]
Date: 2008-01-30 17:10:14
Author: eric_niebler
Date: 2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
New Revision: 43023
URL: http://svn.boost.org/trac/boost/changeset/43023
Log:
finally, a make_expr() I can live with
Text files modified: 
   trunk/boost/xpressive/proto/domain.hpp        |    24 +++                                     
   trunk/boost/xpressive/proto/make_expr.hpp     |   309 ++++++++++++++++++--------------------- 
   trunk/boost/xpressive/proto/operators.hpp     |    24 +-                                      
   trunk/boost/xpressive/proto/proto_fwd.hpp     |   114 ++-----------                           
   trunk/boost/xpressive/proto/transform/arg.hpp |    36 ++++                                    
   trunk/boost/xpressive/regex_primitives.hpp    |    98 +++++++++---                            
   trunk/libs/xpressive/proto/doc/preface.qbk    |    11 +                                       
   trunk/libs/xpressive/proto/example/mixed.cpp  |     5                                         
   trunk/libs/xpressive/proto/test/make_expr.cpp |   185 ++++++++++++++++++-----                 
   9 files changed, 461 insertions(+), 345 deletions(-)
Modified: trunk/boost/xpressive/proto/domain.hpp
==============================================================================
--- trunk/boost/xpressive/proto/domain.hpp	(original)
+++ trunk/boost/xpressive/proto/domain.hpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -142,6 +142,30 @@
         {
             typedef typename T::proto_domain type;
         };
+
+        /// INTERNAL ONLY
+        ///
+        template<typename T>
+        struct domain_of<T &, void>
+        {
+            typedef typename domain_of<T>::type type;
+        };
+
+        /// INTERNAL ONLY
+        ///
+        template<typename T>
+        struct domain_of<boost::reference_wrapper<T>, void>
+        {
+            typedef typename domain_of<T>::type type;
+        };
+
+        /// INTERNAL ONLY
+        ///
+        template<typename T>
+        struct domain_of<boost::reference_wrapper<T> const, void>
+        {
+            typedef typename domain_of<T>::type type;
+        };
     }
 }}
 
Modified: trunk/boost/xpressive/proto/make_expr.hpp
==============================================================================
--- trunk/boost/xpressive/proto/make_expr.hpp	(original)
+++ trunk/boost/xpressive/proto/make_expr.hpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -47,6 +47,8 @@
     #include <boost/preprocessor/seq/push_front.hpp>
     #include <boost/preprocessor/list/for_each_i.hpp>
     #include <boost/ref.hpp>
+    #include <boost/mpl/if.hpp>
+    #include <boost/mpl/eval_if.hpp>
     #include <boost/mpl/apply_wrap.hpp>
     #include <boost/utility/enable_if.hpp>
     #include <boost/type_traits/is_same.hpp>
@@ -79,29 +81,28 @@
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG_TYPE(Z, N, DATA)                                                     \
-        typename boost::proto::result_of::as_arg<                                                   \
-            BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, DATA), N)                                        \
-          , BOOST_PP_TUPLE_ELEM(2, 1, DATA)                                                         \
+        typename boost::proto::detail::protoify_<                                                   \
+            BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N)                                        \
+          , BOOST_PP_TUPLE_ELEM(3, 2, DATA)                                                         \
         >::type                                                                                     \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG(Z, N, DATA)                                                          \
-        boost::proto::as_arg<BOOST_PP_TUPLE_ELEM(2, 1, DATA) >(                                     \
-            BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, DATA), N)                                        \
-        )                                                                                           \
+        boost::proto::detail::protoify_<                                                            \
+            BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N)                                        \
+          , BOOST_PP_TUPLE_ELEM(3, 2, DATA)                                                         \
+        >::call(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N))                                   \
         /**/
 
     /// INTERNAL ONLY
     ///
     # define BOOST_PROTO_AT_TYPE(Z, N, DATA)                                                        \
-        typename remove_reference<                                                                  \
-            typename add_const<                                                                     \
-                typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c<                          \
-                    BOOST_PP_TUPLE_ELEM(2, 0, DATA)                                                 \
-                  , N                                                                               \
-                >::type                                                                             \
+        typename add_const<                                                                         \
+            typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c<                              \
+                BOOST_PP_TUPLE_ELEM(3, 0, DATA)                                                     \
+              , N                                                                                   \
             >::type                                                                                 \
         >::type                                                                                     \
         /**/
@@ -109,24 +110,25 @@
     /// INTERNAL ONLY
     ///
     # define BOOST_PROTO_AT(Z, N, DATA)                                                             \
-        fusion::BOOST_PROTO_FUSION_AT_C(N, BOOST_PP_TUPLE_ELEM(2, 0, DATA))                         \
+        fusion::BOOST_PROTO_FUSION_AT_C(N, BOOST_PP_TUPLE_ELEM(3, 1, DATA))                         \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG_AT_TYPE(Z, N, DATA)                                                  \
-        typename boost::proto::result_of::as_arg<                                                   \
+        typename boost::proto::detail::protoify_<                                                   \
             BOOST_PROTO_AT_TYPE(Z, N, DATA)                                                         \
-          , BOOST_PP_TUPLE_ELEM(2, 1, DATA)                                                         \
+          , BOOST_PP_TUPLE_ELEM(3, 2, DATA)                                                         \
         >::type                                                                                     \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG_AT(Z, N, DATA)                                                       \
-        boost::proto::as_arg<BOOST_PP_TUPLE_ELEM(2, 1, DATA) >(                                     \
-            BOOST_PROTO_AT(Z, N, DATA)                                                              \
-        )                                                                                           \
+        boost::proto::detail::protoify_<                                                            \
+            BOOST_PROTO_AT_TYPE(Z, N, DATA)                                                         \
+          , BOOST_PP_TUPLE_ELEM(3, 2, DATA)                                                         \
+        >::call(BOOST_PROTO_AT(Z, N, DATA))                                                         \
         /**/
 
     /// INTERNAL ONLY
@@ -210,14 +212,14 @@
     #define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM)                                           \
         BOOST_PP_EXPR_IF(                                                                           \
             BOOST_PP_GREATER(I, 1)                                                                  \
-          , ((boost::proto::utility::static_<                                                       \
+          , ((                                                                                      \
                 BOOST_PP_SEQ_HEAD(ELEM)                                                             \
                 BOOST_PP_IF(                                                                        \
                     BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM))                                           \
                   , BOOST_PROTO_TEMPLATE_PARAMS_YES_                                                \
                   , BOOST_PROTO_TEMPLATE_PARAMS_NO_                                                 \
-                )(R, DATA, I, ELEM)                                                                 \
-            >::value))                                                                              \
+                )(R, DATA, I, ELEM)()                                                               \
+            ))                                                                                      \
         )                                                                                           \
         /**/
 
@@ -268,13 +270,9 @@
                   , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                                 \
                 )                                                                                   \
             )                                                                                       \
-            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(                                                   \
-                N                                                                                   \
-              , typename boost::proto::utility::remref<const A                                      \
-              , >::type BOOST_PP_INTERCEPT                                                          \
-            )                                                                                       \
+            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT)             \
         >::type const                                                                               \
-        BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, const A, &a))           \
+        BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a))           \
         {                                                                                           \
             return boost::proto::detail::make_expr_<                                                \
                 BOOST_PP_SEQ_FOR_EACH_I(                                                            \
@@ -287,11 +285,7 @@
                       , BOOST_PP_TUPLE_ELEM(4, 1, DATA)                                             \
                     )                                                                               \
                 )                                                                                   \
-                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(                                               \
-                    N                                                                               \
-                  , typename boost::proto::utility::remref<const A                                  \
-                  , >::type BOOST_PP_INTERCEPT                                                      \
-                )                                                                                   \
+                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT)         \
             >::call(                                                                                \
                 BOOST_PP_SEQ_ENUM(                                                                  \
                     BOOST_PP_SEQ_FOR_EACH_I(                                                        \
@@ -347,49 +341,56 @@
         namespace utility
         {
             template<typename T>
-            struct addref
+            struct static_
             {
-                typedef 
-                    typename boost::unwrap_reference<T>::type &
-                type;
+                static T const value;
             };
 
             template<typename T>
-            struct addref<T &>
-            {
-                typedef 
-                    typename boost::unwrap_reference<T>::type &
-                type;
-            };
+            T const static_<T>::value = T();
+        }
 
-            template<typename T>
-            struct remref
+        namespace detail
+        {
+            template<typename T, typename Domain>
+            struct protoify_
             {
                 typedef
-                    typename boost::unwrap_reference<T>::type
+                    typename mpl::eval_if<
+                        boost::is_reference_wrapper<T>
+                      , proto::result_of::as_arg<typename boost::unwrap_reference<T>::type, Domain>
+                      , proto::result_of::as_expr<T, Domain>
+                    >::type
                 type;
+
+                static type call(T &t)
+                {
+                    return typename mpl::if_<
+                        is_reference_wrapper<T>
+                      , functional::as_arg<Domain>
+                      , functional::as_expr<Domain>
+                    >::type()(static_cast<typename boost::unwrap_reference<T>::type &>(t));
+                }
             };
 
-            template<typename T>
-            struct remref<T &>
+            template<typename T, typename Domain>
+            struct protoify_<T &, Domain>
             {
                 typedef
-                    typename boost::unwrap_reference<T>::type
+                    typename proto::result_of::as_arg<
+                        typename boost::unwrap_reference<T>::type
+                      , Domain
+                    >::type
                 type;
-            };
 
-            template<typename T>
-            struct static_
-            {
-                static T const value;
+                static type call(T &t)
+                {
+                    return functional::as_arg<Domain>()(
+                        static_cast<typename boost::unwrap_reference<T>::type &>(t)
+                    );
+                }
             };
 
-            template<typename T>
-            T const static_<T>::value = T();
-        }
-
-        namespace detail
-        {
             template<
                 typename Domain
                 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
@@ -427,26 +428,25 @@
             template<typename Domain, typename Sequence>
             struct unpack_expr_<tag::terminal, Domain, Sequence, 1u>
             {
-                typedef proto::expr<
-                    tag::terminal
-                  , args0<
-                        typename add_reference<
-                            typename add_const<
-                                typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c<
-                                    Sequence
-                                  , 0
-                                >::type
-                            >::type
+                typedef
+                    typename add_const<
+                        typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c<
+                            Sequence
+                          , 0
                         >::type
-                    >
-                > expr_type;
+                    >::type
+                terminal_type;
 
-                typedef typename Domain::template apply<expr_type>::type type;
+                typedef
+                    typename proto::detail::protoify_<
+                        terminal_type
+                      , Domain
+                    >::type
+                type;
 
                 static type const call(Sequence const &sequence)
                 {
-                    expr_type that = {fusion::BOOST_PROTO_FUSION_AT_C(0, sequence)};
-                    return Domain::make(that);
+                    return proto::detail::protoify_<terminal_type, Domain>::call(fusion::BOOST_PROTO_FUSION_AT_C(0, sequence));
                 }
             };
 
@@ -472,14 +472,11 @@
             struct make_expr_<tag::terminal, Domain, A
                 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
             {
-                typedef typename utility::addref<A>::type reference;
-                typedef proto::expr<tag::terminal, args0<reference> > expr_type;
-                typedef typename Domain::template apply<expr_type>::type type;
+                typedef typename proto::detail::protoify_<A, Domain>::type type;
 
-                static type const call(reference a)
+                static type const call(typename add_reference<A>::type a)
                 {
-                    expr_type that = {a};
-                    return Domain::make(that);
+                    return proto::detail::protoify_<A, Domain>::call(a);
                 }
             };
 
@@ -579,14 +576,14 @@
                 typename result_of::make_expr<
                     Tag
                   , Domain
-                  , typename utility::remref<A0>::type
+                  , A0
                 >::type const
                 operator ()(A0 &a0 BOOST_PROTO_DISABLE_IF_IS_CONST(A0)) const
                 {
                     return proto::detail::make_expr_<
                         Tag
                       , Domain
-                      , typename utility::remref<A0>::type
+                      , A0
                     >::call(a0);
                 }
 
@@ -596,16 +593,16 @@
                 typename result_of::make_expr<
                     Tag
                   , Domain
-                  , typename utility::remref<A0>::type
-                  , typename utility::remref<A1>::type
+                  , A0
+                  , A1
                 >::type const
                 operator ()(A0 &a0, A1 &a1 BOOST_PROTO_DISABLE_IF_IS_CONST(A0) BOOST_PROTO_DISABLE_IF_IS_CONST(A1)) const
                 {
                     return proto::detail::make_expr_<
                         Tag
                       , Domain
-                      , typename utility::remref<A0>::type
-                      , typename utility::remref<A1>::type
+                      , A0
+                      , A1
                     >::call(a0, a1);
                 }
 
@@ -615,16 +612,16 @@
                 typename result_of::make_expr<
                     Tag
                   , Domain
-                  , typename utility::remref<A0>::type
-                  , typename utility::remref<A1 const>::type
+                  , A0
+                  , A1 const
                 >::type const
                 operator ()(A0 &a0, A1 const &a1 BOOST_PROTO_DISABLE_IF_IS_CONST(A0)) const
                 {
                     return proto::detail::make_expr_<
                         Tag
                       , Domain
-                      , typename utility::remref<A0>::type
-                      , typename utility::remref<A1 const>::type
+                      , A0
+                      , A1 const
                     >::call(a0, a1);
                 }
 
@@ -634,16 +631,16 @@
                 typename result_of::make_expr<
                     Tag
                   , Domain
-                  , typename utility::remref<A0 const>::type
-                  , typename utility::remref<A1>::type
+                  , A0 const
+                  , A1
                 >::type const
                 operator ()(A0 const &a0, A1 &a1 BOOST_PROTO_DISABLE_IF_IS_CONST(A1)) const
                 {
                     return proto::detail::make_expr_<
                         Tag
                       , Domain
-                      , typename utility::remref<A0 const>::type
-                      , typename utility::remref<A1>::type
+                      , A0 const
+                      , A1
                     >::call(a0, a1);
                 }
 
@@ -670,7 +667,7 @@
                         typename result_of::make_expr<
                             tag::terminal
                           , Domain
-                          , typename utility::remref<A>::type
+                          , typename remove_reference<A>::type
                         >::type
                     type;
                 };
@@ -679,14 +676,14 @@
                 typename result_of::make_expr<
                     tag::terminal
                   , Domain
-                  , typename utility::remref<A>::type
+                  , A
                 >::type const
                 operator ()(A &a BOOST_PROTO_DISABLE_IF_IS_CONST(A)) const
                 {
                     return proto::detail::make_expr_<
                         tag::terminal
                       , Domain
-                      , typename utility::remref<A>::type
+                      , A
                     >::call(a);
                 }
 
@@ -694,14 +691,14 @@
                 typename result_of::make_expr<
                     tag::terminal
                   , Domain
-                  , typename utility::remref<A const>::type
+                  , A const
                 >::type const
                 operator ()(A const &a) const
                 {
                     return proto::detail::make_expr_<
                         tag::terminal
                       , Domain
-                      , typename utility::remref<A const>::type
+                      , A const
                     >::call(a);
                 }
             };
@@ -874,7 +871,7 @@
             is_domain<A0>
           , result_of::make_expr<
                 Tag
-              , typename utility::remref<A0>::type
+              , A0
             >
         >::type const
         make_expr(A0 &a0 BOOST_PROTO_DISABLE_IF_IS_CONST(A0))
@@ -882,19 +879,19 @@
             return proto::detail::make_expr_<
                 Tag
               , deduce_domain 
-              , typename utility::remref<A0>::type
+              , A0
             >::call(a0);
         }
 
-        /// \ovoerload
+        /// \overload
         ///
         template<typename Tag, typename A0, typename A1>
         typename lazy_disable_if<
             is_domain<A0>
           , result_of::make_expr<
                 Tag
-              , typename utility::remref<A0>::type
-              , typename utility::remref<A1>::type
+              , A0
+              , A1
             >
         >::type const
         make_expr(A0 &a0, A1 &a1 BOOST_PROTO_DISABLE_IF_IS_CONST(A0) BOOST_PROTO_DISABLE_IF_IS_CONST(A1))
@@ -902,20 +899,20 @@
             return proto::detail::make_expr_<
                 Tag
               , deduce_domain 
-              , typename utility::remref<A0>::type
-              , typename utility::remref<A1>::type
+              , A0
+              , A1
             >::call(a0, a1);
         }
 
-        /// \ovoerload
+        /// \overload
         ///
         template<typename Tag, typename A0, typename A1>
         typename lazy_disable_if<
             is_domain<A0>
           , result_of::make_expr<
                 Tag
-              , typename utility::remref<A0>::type
-              , typename utility::remref<A1 const>::type
+              , A0
+              , A1 const
             >
         >::type const
         make_expr(A0 &a0, A1 const &a1 BOOST_PROTO_DISABLE_IF_IS_CONST(A0))
@@ -923,20 +920,20 @@
             return proto::detail::make_expr_<
                 Tag
               , deduce_domain 
-              , typename utility::remref<A0>::type
-              , typename utility::remref<A1 const>::type
+              , A0
+              , A1 const
             >::call(a0, a1);
         }
 
-        /// \ovoerload
+        /// \overload
         ///
         template<typename Tag, typename A0, typename A1>
         typename lazy_disable_if<
             is_domain<A0>
           , result_of::make_expr<
                 Tag
-              , typename utility::remref<A0 const>::type
-              , typename utility::remref<A1>::type
+              , A0 const
+              , A1
             >
         >::type const
         make_expr(A0 const &a0, A1 &a1 BOOST_PROTO_DISABLE_IF_IS_CONST(A1))
@@ -944,8 +941,8 @@
             return proto::detail::make_expr_<
                 Tag
               , deduce_domain 
-              , typename utility::remref<A0 const>::type
-              , typename utility::remref<A1>::type
+              , A0 const
+              , A1
             >::call(a0, a1);
         }
 
@@ -955,14 +952,14 @@
         typename result_of::make_expr<
             Tag
           , Domain
-          , typename utility::remref<B0>::type
+          , B0
         >::type const
         make_expr(B0 &b0 BOOST_PROTO_DISABLE_IF_IS_CONST(B0))
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-              , typename utility::remref<B0>::type
+              , B0
             >::call(b0);
         }
 
@@ -972,16 +969,16 @@
         typename result_of::make_expr<
             Tag
           , Domain
-          , typename utility::remref<B0>::type
-          , typename utility::remref<B1>::type
+          , B0
+          , B1
         >::type const
         make_expr(B0 &b0, B1 &b1 BOOST_PROTO_DISABLE_IF_IS_CONST(B0) BOOST_PROTO_DISABLE_IF_IS_CONST(B1))
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-              , typename utility::remref<B0>::type
-              , typename utility::remref<B1>::type
+              , B0
+              , B1
             >::call(b0, b1);
         }
 
@@ -991,16 +988,16 @@
         typename result_of::make_expr<
             Tag
           , Domain
-          , typename utility::remref<B0>::type
-          , typename utility::remref<B1 const>::type
+          , B0
+          , B1 const
         >::type const
         make_expr(B0 &b0, B1 const &b1 BOOST_PROTO_DISABLE_IF_IS_CONST(B0))
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-              , typename utility::remref<B0>::type
-              , typename utility::remref<B1 const>::type
+              , B0
+              , B1 const
             >::call(b0, b1);
         }
 
@@ -1010,16 +1007,16 @@
         typename result_of::make_expr<
             Tag
           , Domain
-          , typename utility::remref<B0 const>::type
-          , typename utility::remref<B1>::type
+          , B0 const
+          , B1
         >::type const
         make_expr(B0 const &b0, B1 &b1 BOOST_PROTO_DISABLE_IF_IS_CONST(B1))
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-              , typename utility::remref<B0 const>::type
-              , typename utility::remref<B1>::type
+              , B0 const
+              , B1
             >::call(b0, b1);
         }
 
@@ -1064,15 +1061,15 @@
         {
             typedef proto::expr<
                 Tag
-              , BOOST_PP_CAT(args, N)<BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_TYPE, (A, Domain)) >
+              , BOOST_PP_CAT(args, N)<BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_TYPE, (A, ~, Domain)) >
             > expr_type;
 
             typedef typename Domain::template apply<expr_type>::type type;
 
-            static type const call(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a))
+            static type const call(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference<A, >::type a))
             {
                 expr_type that = {
-                    BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG, (a, Domain))
+                    BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG, (A, a, Domain))
                 };
                 return Domain::make(that);
             }
@@ -1100,7 +1097,7 @@
             typedef proto::expr<
                 Tag
               , BOOST_PP_CAT(args, N)<
-                    BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT_TYPE, (Sequence, Domain))
+                    BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT_TYPE, (Sequence const, ~, Domain))
                 >
             > expr_type;
 
@@ -1109,7 +1106,7 @@
             static type const call(Sequence const &sequence)
             {
                 expr_type that = {
-                    BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT, (sequence, Domain))
+                    BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT, (Sequence const, sequence, Domain))
                 };
                 return Domain::make(that);
             }
@@ -1121,10 +1118,10 @@
                 Tag
               , typename detail::deduce_domain_<
                     typename domain_of<
-                        BOOST_PROTO_AT_TYPE(~, 0, (Sequence const, ~))
+                        BOOST_PROTO_AT_TYPE(~, 0, (Sequence const, ~, ~))
                     >::type
                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(N))
-                    BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_AT_TYPE, (Sequence const, ~))
+                    BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_AT_TYPE, (Sequence const, ~, ~))
                 >::type
               , Sequence
               , N
@@ -1147,7 +1144,7 @@
                   , Domain
                     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
                         N
-                      , typename utility::remref<A
+                      , typename remove_reference<A
                       , >::type BOOST_PP_INTERCEPT
                     )
                 >::type
@@ -1160,22 +1157,14 @@
         typename result_of::make_expr<
             Tag
           , Domain
-            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
-                N
-              , typename utility::remref<const A
-              , >::type BOOST_PP_INTERCEPT
-            )
+            BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
         >::type const
         operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a)) const
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
-                    N
-                  , typename utility::remref<const A
-                  , >::type BOOST_PP_INTERCEPT
-                )
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
             >::call(BOOST_PP_ENUM_PARAMS(N, a));
         }
 
@@ -1192,11 +1181,7 @@
             is_domain<A0>
           , result_of::make_expr<
                 Tag
-                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
-                    N
-                  , typename utility::remref<const A
-                  , >::type BOOST_PP_INTERCEPT
-                )
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
             >
         >::type const
         make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a))
@@ -1204,11 +1189,7 @@
             return proto::detail::make_expr_<
                 Tag
               , deduce_domain 
-                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
-                    N
-                  , typename utility::remref<const A
-                  , >::type BOOST_PP_INTERCEPT
-                )
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
             >::call(BOOST_PP_ENUM_PARAMS(N, a));
         }
 
@@ -1218,22 +1199,14 @@
         typename result_of::make_expr<
             Tag
           , Domain
-            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
-                N
-              , typename utility::remref<const B
-              , >::type BOOST_PP_INTERCEPT
-            )
+            BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
         >::type const
         make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const B, &b))
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-                BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
-                    N
-                  , typename utility::remref<const B
-                  , >::type BOOST_PP_INTERCEPT
-                )
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
             >::call(BOOST_PP_ENUM_PARAMS(N, b));
         }
 
Modified: trunk/boost/xpressive/proto/operators.hpp
==============================================================================
--- trunk/boost/xpressive/proto/operators.hpp	(original)
+++ trunk/boost/xpressive/proto/operators.hpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -291,54 +291,54 @@
 #define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, TRAIT, DOMAIN, POST)                             \
     template<typename Arg>                                                                          \
     typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg                             \
-        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg>::type                       \
+        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg &>::type                     \
     >::type const                                                                                   \
     operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST)                                  \
     {                                                                                               \
-        return boost::proto::make_expr<TAG, DOMAIN>(arg);                                           \
+        return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg));                               \
     }                                                                                               \
     template<typename Arg>                                                                          \
     typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg                             \
-        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const>::type                 \
+        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const &>::type               \
     >::type const                                                                                   \
     operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST)                            \
     {                                                                                               \
-        return boost::proto::make_expr<TAG, DOMAIN>(arg);                                           \
+        return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg));                               \
     }                                                                                               \
     /**/
 
 #define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG, TRAIT, DOMAIN)                                  \
     template<typename Left, typename Right>                                                         \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right>::type               \
+        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right &>::type           \
     >::type const                                                                                   \
     operator OP(Left &left, Right &right)                                                           \
     {                                                                                               \
-        return boost::proto::make_expr<TAG, DOMAIN>(left, right);                                   \
+        return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right));           \
     }                                                                                               \
     template<typename Left, typename Right>                                                         \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right const>::type         \
+        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right const &>::type     \
     >::type const                                                                                   \
     operator OP(Left &left, Right const &right)                                                     \
     {                                                                                               \
-        return boost::proto::make_expr<TAG, DOMAIN>(left, right);                                   \
+        return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right));           \
     }                                                                                               \
     template<typename Left, typename Right>                                                         \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right>::type         \
+        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right &>::type     \
     >::type const                                                                                   \
     operator OP(Left const &left, Right &right)                                                     \
     {                                                                                               \
-        return boost::proto::make_expr<TAG, DOMAIN>(left, right);                                   \
+        return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right));           \
     }                                                                                               \
     template<typename Left, typename Right>                                                         \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right const>::type   \
+        , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right const &>::type\
     >::type const                                                                                   \
     operator OP(Left const &left, Right const &right)                                               \
     {                                                                                               \
-        return boost::proto::make_expr<TAG, DOMAIN>(left, right);                                   \
+        return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right));           \
     }                                                                                               \
     /**/
 
Modified: trunk/boost/xpressive/proto/proto_fwd.hpp
==============================================================================
--- trunk/boost/xpressive/proto/proto_fwd.hpp	(original)
+++ trunk/boost/xpressive/proto/proto_fwd.hpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -61,6 +61,24 @@
 
 #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
 
+#ifdef BOOST_PROTO_DOXYGEN_INVOKED
+// HACKHACK so Doxygen shows inheritance from mpl::true_ and mpl::false_
+namespace boost
+{
+    /// INTERNAL ONLY
+    ///
+    namespace mpl
+    {
+        /// INTERNAL ONLY
+        ///
+        struct true_ {};
+        /// INTERNAL ONLY
+        ///
+        struct false_ {};
+    }
+}
+#endif
+
 namespace boost { namespace proto
 {
     namespace detail
@@ -498,52 +516,6 @@
         typedef make_expr<tag::if_else_>            make_if_else;
         typedef make_expr<tag::function>            make_function;
 
-        //typedef make_expr_ref<tag::terminal>            make_terminal_ref;
-        //typedef make_expr_ref<tag::posit>               make_posit_ref;
-        //typedef make_expr_ref<tag::negate>              make_negate_ref;
-        //typedef make_expr_ref<tag::dereference>         make_dereference_ref;
-        //typedef make_expr_ref<tag::complement>          make_complement_ref;
-        //typedef make_expr_ref<tag::address_of>          make_address_of_ref;
-        //typedef make_expr_ref<tag::logical_not>         make_logical_not_ref;
-        //typedef make_expr_ref<tag::pre_inc>             make_pre_inc_ref;
-        //typedef make_expr_ref<tag::pre_dec>             make_pre_dec_ref;
-        //typedef make_expr_ref<tag::post_inc>            make_post_inc_ref;
-        //typedef make_expr_ref<tag::post_dec>            make_post_dec_ref;
-        //typedef make_expr_ref<tag::shift_left>          make_shift_left_ref;
-        //typedef make_expr_ref<tag::shift_right>         make_shift_right_ref;
-        //typedef make_expr_ref<tag::multiplies>          make_multiplies_ref;
-        //typedef make_expr_ref<tag::divides>             make_divides_ref;
-        //typedef make_expr_ref<tag::modulus>             make_modulus_ref;
-        //typedef make_expr_ref<tag::plus>                make_plus_ref;
-        //typedef make_expr_ref<tag::minus>               make_minus_ref;
-        //typedef make_expr_ref<tag::less>                make_less_ref;
-        //typedef make_expr_ref<tag::greater>             make_greater_ref;
-        //typedef make_expr_ref<tag::less_equal>          make_less_equal_ref;
-        //typedef make_expr_ref<tag::greater_equal>       make_greater_equal_ref;
-        //typedef make_expr_ref<tag::equal_to>            make_equal_to_ref;
-        //typedef make_expr_ref<tag::not_equal_to>        make_not_equal_to_ref;
-        //typedef make_expr_ref<tag::logical_or>          make_logical_or_ref;
-        //typedef make_expr_ref<tag::logical_and>         make_logical_and_ref;
-        //typedef make_expr_ref<tag::bitwise_and>         make_bitwise_and_ref;
-        //typedef make_expr_ref<tag::bitwise_or>          make_bitwise_or_ref;
-        //typedef make_expr_ref<tag::bitwise_xor>         make_bitwise_xor_ref;
-        //typedef make_expr_ref<tag::comma>               make_comma_ref;
-        //typedef make_expr_ref<tag::mem_ptr>             make_mem_ptr_ref;
-        //typedef make_expr_ref<tag::assign>              make_assign_ref;
-        //typedef make_expr_ref<tag::shift_left_assign>   make_shift_left_assign_ref;
-        //typedef make_expr_ref<tag::shift_right_assign>  make_shift_right_assign_ref;
-        //typedef make_expr_ref<tag::multiplies_assign>   make_multiplies_assign_ref;
-        //typedef make_expr_ref<tag::divides_assign>      make_divides_assign_ref;
-        //typedef make_expr_ref<tag::modulus_assign>      make_modulus_assign_ref;
-        //typedef make_expr_ref<tag::plus_assign>         make_plus_assign_ref;
-        //typedef make_expr_ref<tag::minus_assign>        make_minus_assign_ref;
-        //typedef make_expr_ref<tag::bitwise_and_assign>  make_bitwise_and_assign_ref;
-        //typedef make_expr_ref<tag::bitwise_or_assign>   make_bitwise_or_assign_ref;
-        //typedef make_expr_ref<tag::bitwise_xor_assign>  make_bitwise_xor_assign_ref;
-        //typedef make_expr_ref<tag::subscript>           make_subscript_ref;
-        //typedef make_expr_ref<tag::if_else_>            make_if_else_ref;
-        //typedef make_expr_ref<tag::function>            make_function_ref;
-
         struct flatten;
         struct pop_front;
         struct reverse;
@@ -595,52 +567,6 @@
     typedef functional::make_if_else                _make_if_else;
     typedef functional::make_function               _make_function;
 
-    //typedef functional::make_terminal_ref               _make_terminal_ref;
-    //typedef functional::make_posit_ref                  _make_posit_ref;
-    //typedef functional::make_negate_ref                 _make_negate_ref;
-    //typedef functional::make_dereference_ref            _make_dereference_ref;
-    //typedef functional::make_complement_ref             _make_complement_ref;
-    //typedef functional::make_address_of_ref             _make_address_of_ref;
-    //typedef functional::make_logical_not_ref            _make_logical_not_ref;
-    //typedef functional::make_pre_inc_ref                _make_pre_inc_ref;
-    //typedef functional::make_pre_dec_ref                _make_pre_dec_ref;
-    //typedef functional::make_post_inc_ref               _make_post_inc_ref;
-    //typedef functional::make_post_dec_ref               _make_post_dec_ref;
-    //typedef functional::make_shift_left_ref             _make_shift_left_ref;
-    //typedef functional::make_shift_right_ref            _make_shift_right_ref;
-    //typedef functional::make_multiplies_ref             _make_multiplies_ref;
-    //typedef functional::make_divides_ref                _make_divides_ref;
-    //typedef functional::make_modulus_ref                _make_modulus_ref;
-    //typedef functional::make_plus_ref                   _make_plus_ref;
-    //typedef functional::make_minus_ref                  _make_minus_ref;
-    //typedef functional::make_less_ref                   _make_less_ref;
-    //typedef functional::make_greater_ref                _make_greater_ref;
-    //typedef functional::make_less_equal_ref             _make_less_equal_ref;
-    //typedef functional::make_greater_equal_ref          _make_greater_equal_ref;
-    //typedef functional::make_equal_to_ref               _make_equal_to_ref;
-    //typedef functional::make_not_equal_to_ref           _make_not_equal_to_ref;
-    //typedef functional::make_logical_or_ref             _make_logical_or_ref;
-    //typedef functional::make_logical_and_ref            _make_logical_and_ref;
-    //typedef functional::make_bitwise_and_ref            _make_bitwise_and_ref;
-    //typedef functional::make_bitwise_or_ref             _make_bitwise_or_ref;
-    //typedef functional::make_bitwise_xor_ref            _make_bitwise_xor_ref;
-    //typedef functional::make_comma_ref                  _make_comma_ref;
-    //typedef functional::make_mem_ptr_ref                _make_mem_ptr_ref;
-    //typedef functional::make_assign_ref                 _make_assign_ref;
-    //typedef functional::make_shift_left_assign_ref      _make_shift_left_assign_ref;
-    //typedef functional::make_shift_right_assign_ref     _make_shift_right_assign_ref;
-    //typedef functional::make_multiplies_assign_ref      _make_multiplies_assign_ref;
-    //typedef functional::make_divides_assign_ref         _make_divides_assign_ref;
-    //typedef functional::make_modulus_assign_ref         _make_modulus_assign_ref;
-    //typedef functional::make_plus_assign_ref            _make_plus_assign_ref;
-    //typedef functional::make_minus_assign_ref           _make_minus_assign_ref;
-    //typedef functional::make_bitwise_and_assign_ref     _make_bitwise_and_assign_ref;
-    //typedef functional::make_bitwise_or_assign_ref      _make_bitwise_or_assign_ref;
-    //typedef functional::make_bitwise_xor_assign_ref     _make_bitwise_xor_assign_ref;
-    //typedef functional::make_subscript_ref              _make_subscript_ref;
-    //typedef functional::make_if_else_ref                _make_if_else_ref;
-    //typedef functional::make_function_ref               _make_function_ref;
-
     typedef functional::flatten     _flatten;
     typedef functional::pop_front   _pop_front;
     typedef functional::reverse     _reverse;
@@ -715,6 +641,8 @@
         typedef arg0 arg;
         typedef arg0 left;
         typedef arg1 right;
+
+        struct _ref;
     }
 
     using transform::when;
@@ -749,6 +677,8 @@
     template<int I>
     struct _arg_c;
 
+    using transform::_ref;
+
     template<typename T>
     struct is_extension;
 
Modified: trunk/boost/xpressive/proto/transform/arg.hpp
==============================================================================
--- trunk/boost/xpressive/proto/transform/arg.hpp	(original)
+++ trunk/boost/xpressive/proto/transform/arg.hpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -92,6 +92,37 @@
                 return proto::arg_c<I>(expr);
             }
         };
+
+        struct _ref : proto::callable
+        {
+            template<typename Sig> struct result {};
+
+            template<typename This, typename T>
+            struct result<This(T)>
+            {
+                typedef boost::reference_wrapper<T const> type;
+            };
+
+            template<typename This, typename T>
+            struct result<This(T &)>
+            {
+                typedef boost::reference_wrapper<T> type;
+            };
+
+            template<typename T>
+            boost::reference_wrapper<T>
+            operator ()(T &t) const
+            {
+                return boost::reference_wrapper<T>(t);
+            }
+
+            template<typename T>
+            boost::reference_wrapper<T const>
+            operator ()(T const &t) const
+            {
+                return boost::reference_wrapper<T const>(t);
+            }
+        };
     }
 
     template<int I>
@@ -124,6 +155,11 @@
       : mpl::true_
     {};
 
+    template<>
+    struct is_callable<transform::_ref>
+      : mpl::true_
+    {};
+
 }}
 
 #endif
Modified: trunk/boost/xpressive/regex_primitives.hpp
==============================================================================
--- trunk/boost/xpressive/regex_primitives.hpp	(original)
+++ trunk/boost/xpressive/regex_primitives.hpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -608,11 +608,19 @@
 /// \brief Make a sub-expression optional. Equivalent to !as_xpr(expr).
 ///
 /// \param expr The sub-expression to make optional.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified optional(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<proto::tag::logical_not, proto::default_domain> const optional = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+    proto::tag::logical_not
+  , proto::default_domain
+  , Expr const &
+>::type const
+optional(Expr const &expr)
+{
+    return proto::make_expr<
+        proto::tag::logical_not
+      , proto::default_domain
+    >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Repeat a sub-expression multiple times.
@@ -626,19 +634,33 @@
 ///
 /// \param expr The sub-expression to repeat.
 template<unsigned int Min, unsigned int Max, typename Expr>
-typename proto::result_of::make_expr<detail::generic_quant_tag<Min, Max>, proto::default_domain, Expr const>::type const
+typename proto::result_of::make_expr<
+    detail::generic_quant_tag<Min, Max>
+  , proto::default_domain
+  , Expr const &
+>::type const
 repeat(Expr const &expr)
 {
-    return proto::make_expr<detail::generic_quant_tag<Min, Max>, proto::default_domain>(expr);
+    return proto::make_expr<
+        detail::generic_quant_tag<Min, Max>
+      , proto::default_domain
+    >(boost::ref(expr));
 }
 
 /// \overload
 ///
 template<unsigned int Count, typename Expr2>
-typename proto::result_of::make_expr<detail::generic_quant_tag<Count, Count>, proto::default_domain, Expr2 const>::type const
+typename proto::result_of::make_expr<
+    detail::generic_quant_tag<Count, Count>
+  , proto::default_domain
+  , Expr2 const &
+>::type const
 repeat(Expr2 const &expr2)
 {
-    return proto::make_expr<detail::generic_quant_tag<Count, Count>, proto::default_domain>(expr2);
+    return proto::make_expr<
+        detail::generic_quant_tag<Count, Count>
+      , proto::default_domain
+    >(boost::ref(expr2));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -651,11 +673,19 @@
 /// \attention keep(expr) is equivalent to the perl (?>...) extension.
 ///
 /// \param expr The sub-expression to modify.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified keep(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<detail::keeper_tag, proto::default_domain> const keep = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+    detail::keeper_tag
+  , proto::default_domain
+  , Expr const &
+>::type const
+keep(Expr const &expr)
+{
+    return proto::make_expr<
+        detail::keeper_tag
+      , proto::default_domain
+    >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Look-ahead assertion.
@@ -670,11 +700,19 @@
 /// perl (?!...) extension.
 ///
 /// \param expr The sub-expression to put in the look-ahead assertion.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified before(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<detail::lookahead_tag, proto::default_domain> const before = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+    detail::lookahead_tag
+  , proto::default_domain
+  , Expr const &
+>::type const
+before(Expr const &expr)
+{
+    return proto::make_expr<
+        detail::lookahead_tag
+      , proto::default_domain
+    >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Look-behind assertion.
@@ -691,11 +729,19 @@
 /// \param expr The sub-expression to put in the look-ahead assertion.
 ///
 /// \pre expr cannot match a variable number of characters.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified after(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<detail::lookbehind_tag, proto::default_domain> const after = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+    detail::lookbehind_tag
+  , proto::default_domain
+  , Expr const &
+>::type const
+after(Expr const &expr)
+{
+    return proto::make_expr<
+        detail::lookbehind_tag
+      , proto::default_domain
+    >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Specify a regex traits or a std::locale.
@@ -815,10 +861,6 @@
         ignore_unused(a8);
         ignore_unused(a9);
         ignore_unused(as_xpr);
-        ignore_unused(optional);
-        ignore_unused(before);
-        ignore_unused(after);
-        ignore_unused(keep);
     }
 }
 
Modified: trunk/libs/xpressive/proto/doc/preface.qbk
==============================================================================
--- trunk/libs/xpressive/proto/doc/preface.qbk	(original)
+++ trunk/libs/xpressive/proto/doc/preface.qbk	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -7,8 +7,8 @@
 
 [section Preface]
 
-[:Something witty.]
-[:[*['-- Someone Famous]]]
+[:["There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.]]
+[:[*['-- William Shakespear]]]
 
 [heading Description]
 
@@ -64,4 +64,11 @@
 by MPL's lambda expressions, and by Aleksey Gurtovoy's 
 [@http://listarchives.boost.org/Archives/boost/2002/11/39718.php "round" lambda] notation.
 
+[heading Further Reading]
+
+A technical paper about an earlier version of Proto was accepted into the 
+[@http://lcsd.cs.tamu.edu/2007/ ACM SIGPLAN Symposium on Library-Centric Software Design LCSD'07],
+and can be found at [@http://lcsd.cs.tamu.edu/2007/final/1/1_Paper.pdf]. The
+tree transforms described in that paper differ from what exists today.
+
 [endsect]
Modified: trunk/libs/xpressive/proto/example/mixed.cpp
==============================================================================
--- trunk/libs/xpressive/proto/example/mixed.cpp	(original)
+++ trunk/libs/xpressive/proto/example/mixed.cpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -246,11 +246,10 @@
         proto::tag::function
       , MixedDomain
       , sin_ const
-      , A const
+      , A const &
     >::type sin(A const &a)
     {
-        static sin_ const s = {};
-        return proto::make_expr<proto::tag::function, MixedDomain>(s, a);
+        return proto::make_expr<proto::tag::function, MixedDomain>(sin_(), boost::ref(a));
     }
 
     template<typename FwdIter, typename Expr, typename Op>
Modified: trunk/libs/xpressive/proto/test/make_expr.cpp
==============================================================================
--- trunk/libs/xpressive/proto/test/make_expr.cpp	(original)
+++ trunk/libs/xpressive/proto/test/make_expr.cpp	2008-01-30 17:10:13 EST (Wed, 30 Jan 2008)
@@ -7,7 +7,8 @@
 
 #include <sstream>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/fusion/include/vector.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+#include <boost/fusion/tuple.hpp>
 #include <boost/test/unit_test.hpp>
 
 using namespace boost;
@@ -30,85 +31,186 @@
 void test_make_expr()
 {
     int i = 42;
-    terminal<int const &>::type t1 = make_expr<tag::terminal>(1);
-    terminal<int &>::type t2 = make_expr<tag::terminal>(i);
-    posit<terminal<int const &>::type>::type p1 = make_expr<tag::posit>(1);
-    posit<terminal<int &>::type>::type p2 = make_expr<tag::posit>(i);
+    terminal<int>::type t1 = make_expr<tag::terminal>(1);
+    terminal<int>::type t2 = make_expr<tag::terminal>(i);
+    posit<terminal<int>::type>::type p1 = make_expr<tag::posit>(1);
+    posit<terminal<int>::type>::type p2 = make_expr<tag::posit>(i);
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
 
-    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = make_expr<tag::posit, mydomain>(i);
+    ewrap<posit<ewrap<terminal<int>::type> >::type> p3 = make_expr<tag::posit, mydomain>(i);
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
 
     ewrap<plus<
-        proto::ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
-      , ewrap<terminal<int const &>::type>
+        ewrap<posit<ewrap<terminal<int>::type> >::type>
+      , ewrap<terminal<int>::type>
     >::type> p4 = make_expr<tag::plus>(p3, 0);
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
 }
 
-void test_make_expr2()
+void test_make_expr_ref()
 {
     int i = 42;
-    terminal<int const &>::type t1 = functional::make_expr<tag::terminal>()(1);
-    terminal<int &>::type t2 = functional::make_expr<tag::terminal>()(i);
-    posit<terminal<int const &>::type>::type p1 = functional::make_expr<tag::posit>()(1);
-    posit<terminal<int &>::type>::type p2 = functional::make_expr<tag::posit>()(i);
+    terminal<int const &>::type t1 = make_expr<tag::terminal>(boost::cref(1)); // DANGEROUS
+    terminal<int &>::type t2 = make_expr<tag::terminal>(boost::ref(i));
+    BOOST_CHECK_EQUAL(&i, &proto::arg(t2));
+    posit<terminal<int const &>::type>::type p1 = make_expr<tag::posit>(boost::cref(1)); // DANGEROUS
+    posit<terminal<int &>::type>::type p2 = make_expr<tag::posit>(boost::ref(i));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
 
-    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = functional::make_expr<tag::posit, mydomain>()(i);
+    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = make_expr<tag::posit, mydomain>(boost::ref(i));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
 
     ewrap<plus<
         proto::ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
-      , ewrap<terminal<int const &>::type>
+      , ewrap<terminal<int>::type>
+    >::type> p4 = make_expr<tag::plus>(boost::ref(p3), 0);
+    BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_make_expr_functional()
+{
+    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(proto::arg(proto::arg(p2)), 42);
+
+    ewrap<posit<ewrap<terminal<int>::type> >::type> p3 = functional::make_expr<tag::posit, mydomain>()(i);
+    BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+    ewrap<plus<
+        ewrap<posit<ewrap<terminal<int>::type> >::type>
+      , ewrap<terminal<int>::type>
     >::type> p4 = functional::make_expr<tag::plus, mydomain>()(p3, 0);
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
 }
 
-void test_unpack_expr()
+void test_make_expr_functional_ref()
 {
     int i = 42;
-    fusion::vector<int> v1(1);
-    fusion::vector<int&> v2(i);
-    terminal<int const &>::type t1 = unpack_expr<tag::terminal>(v1);
-    terminal<int &>::type t2 = unpack_expr<tag::terminal>(v2);
-    posit<terminal<int const &>::type>::type p1 = unpack_expr<tag::posit>(v1);
-    posit<terminal<int &>::type>::type p2 = unpack_expr<tag::posit>(v2);
+    terminal<int const &>::type t1 = functional::make_expr<tag::terminal>()(boost::cref(1)); // DANGEROUS
+    terminal<int &>::type t2 = functional::make_expr<tag::terminal>()(boost::ref(i));
+    BOOST_CHECK_EQUAL(&i, &proto::arg(t2));
+    posit<terminal<int const &>::type>::type p1 = functional::make_expr<tag::posit>()(boost::cref(1)); // DANGEROUS
+    posit<terminal<int &>::type>::type p2 = functional::make_expr<tag::posit>()(boost::ref(i));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
 
-    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = unpack_expr<tag::posit, mydomain>(v2);
+    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = functional::make_expr<tag::posit, mydomain>()(boost::ref(i));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
 
-    fusion::vector<ewrap<posit<ewrap<terminal<int &>::type> >::type> &, int> v3(p3, 0);
     ewrap<plus<
         proto::ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
-      , ewrap<terminal<int const &>::type>
-    >::type> p4 = unpack_expr<tag::plus>(v3);
+      , ewrap<terminal<int>::type>
+    >::type> p4 = functional::make_expr<tag::plus, mydomain>()(boost::ref(p3), 0);
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
 }
 
-void test_unpack_expr2()
+void test_unpack_expr()
 {
     int i = 42;
-    fusion::vector<int> v1(1);
-    fusion::vector<int&> v2(i);
-    terminal<int const &>::type t1 = functional::unpack_expr<tag::terminal>()(v1);
-    terminal<int &>::type t2 = functional::unpack_expr<tag::terminal>()(v2);
-    posit<terminal<int const &>::type>::type p1 = functional::unpack_expr<tag::posit>()(v1);
-    posit<terminal<int &>::type>::type p2 = functional::unpack_expr<tag::posit>()(v2);
+    terminal<int>::type t1 = unpack_expr<tag::terminal>(fusion::make_tuple(1));
+    terminal<int &>::type t2 = unpack_expr<tag::terminal>(fusion::make_tuple(boost::ref(i)));
+    posit<terminal<int>::type>::type p1 = unpack_expr<tag::posit>(fusion::make_tuple(1));
+    posit<terminal<int &>::type>::type p2 = unpack_expr<tag::posit>(fusion::make_tuple(boost::ref(i)));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
 
-    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = functional::unpack_expr<tag::posit, mydomain>()(v2);
+    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = unpack_expr<tag::posit, mydomain>(fusion::make_tuple(boost::ref(i)));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
 
-    fusion::vector<ewrap<posit<ewrap<terminal<int &>::type> >::type> &, int> v3(p3, 0);
     ewrap<plus<
-        proto::ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
-      , ewrap<terminal<int const &>::type>
-    >::type> p4 = functional::unpack_expr<tag::plus>()(v3);
+        ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
+      , ewrap<terminal<int>::type>
+    >::type> p4 = unpack_expr<tag::plus>(fusion::make_tuple(boost::ref(p3), 0));
+    BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_unpack_expr_functional()
+{
+    int i = 42;
+    terminal<int>::type t1 = functional::unpack_expr<tag::terminal>()(fusion::make_tuple(1));
+    terminal<int &>::type t2 = functional::unpack_expr<tag::terminal>()(fusion::make_tuple(boost::ref(i)));
+    posit<terminal<int>::type>::type p1 = functional::unpack_expr<tag::posit>()(fusion::make_tuple(1));
+    posit<terminal<int &>::type>::type p2 = functional::unpack_expr<tag::posit>()(fusion::make_tuple(boost::ref(i)));
+    BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+    ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = functional::unpack_expr<tag::posit, mydomain>()(fusion::make_tuple(boost::ref(i)));
+    BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+    ewrap<plus<
+        ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
+      , ewrap<terminal<int>::type>
+    >::type> p4 = functional::unpack_expr<tag::plus>()(fusion::make_tuple(boost::ref(p3), 0));
     BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
 }
 
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#define _ref(x) call<_ref(x)>
+#define Minus(x) call<Minus(x)>
+#endif
+
+// Turn all terminals held by reference into ones held by value
+struct ByVal
+  : or_<
+        when<terminal<_>, _make_terminal(_arg)>
+      , when<nary_expr<_, vararg<ByVal> > >
+    >
+{};
+
+// Turn all terminals held by value into ones held by reference (not safe in general)
+struct ByRef
+  : or_<
+        when<terminal<_>, _make_terminal(_ref(_arg))>
+      , when<nary_expr<_, vararg<ByRef> > >
+    >
+{};
+
+// turn all plus noded to minus nodes:
+struct Minus
+  : or_<
+        when<terminal<_> >
+      , when<plus<Minus, Minus>, _make_minus(Minus(_left), Minus(_right)) >
+    >
+{};
+
+struct Square
+  : or_<
+        // Not creating new terminal nodes here,
+        // so hold the existing terminals by reference:
+        when<terminal<_>, _make_multiplies(_ref(_), _ref(_))>
+      , when<plus<Square, Square> >
+    >
+{};
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#undef _ref
+#undef Minus
+#endif
+
+void test_make_expr_transform()
+{
+    int x = 0;
+    plus< 
+        terminal<int>::type
+      , terminal<int>::type
+    >::type t1 = ByVal()(as_expr(1) + 1, x, x);
+
+    plus< 
+        terminal<int const &>::type
+      , terminal<int const &>::type
+    >::type t2 = ByRef()(as_expr(1) + 1, x, x);
+
+    minus<
+        terminal<int>::type
+      , terminal<int const &>::type
+    >::type t3 = Minus()(as_expr(1) + 1, x, x);
+
+    plus<
+        multiplies<ref_<terminal<int>::type const>, ref_<terminal<int>::type const> >::type
+      , multiplies<ref_<terminal<int const &>::type const>, ref_<terminal<int const &>::type const> >::type
+    >::type t4 = Square()(as_expr(1) + 1, x, x);
+}
+
 using namespace unit_test;
 ///////////////////////////////////////////////////////////////////////////////
 // init_unit_test_suite
@@ -118,9 +220,12 @@
     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_make_expr_ref));
+    test->add(BOOST_TEST_CASE(&test_make_expr_functional));
+    test->add(BOOST_TEST_CASE(&test_make_expr_functional_ref));
     test->add(BOOST_TEST_CASE(&test_unpack_expr));
-    test->add(BOOST_TEST_CASE(&test_unpack_expr2));
+    test->add(BOOST_TEST_CASE(&test_unpack_expr_functional));
+    test->add(BOOST_TEST_CASE(&test_make_expr_transform));
 
     return test;
 }