$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r62479 - in trunk/boost/proto: . context detail transform
From: eric_at_[hidden]
Date: 2010-06-06 09:40:46
Author: eric_niebler
Date: 2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
New Revision: 62479
URL: http://svn.boost.org/trac/boost/changeset/62479
Log:
major simplification of proto/operators.hpp
Text files modified: 
   trunk/boost/proto/context/default.hpp   |    12                                         
   trunk/boost/proto/detail/decltype.hpp   |     7                                         
   trunk/boost/proto/make_expr.hpp         |     2                                         
   trunk/boost/proto/matches.hpp           |    30 ++                                      
   trunk/boost/proto/operators.hpp         |   462 +++++++++++---------------------------- 
   trunk/boost/proto/proto_fwd.hpp         |    27 ++                                      
   trunk/boost/proto/traits.hpp            |     1                                         
   trunk/boost/proto/transform/default.hpp |    14                                         
   trunk/boost/proto/transform/make.hpp    |    24 -                                       
   9 files changed, 203 insertions(+), 376 deletions(-)
Modified: trunk/boost/proto/context/default.hpp
==============================================================================
--- trunk/boost/proto/context/default.hpp	(original)
+++ trunk/boost/proto/context/default.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -152,14 +152,12 @@
             template<typename Expr, typename Context>
             struct is_member_function_eval
               : is_member_function_pointer<
-                    typename remove_const<
-                        typename remove_reference<
-                            typename proto::result_of::eval<
-                                typename remove_reference<
-                                    typename proto::result_of::child_c<Expr, 1>::type
-                                >::type
-                              , Context
+                    typename detail::uncvref<
+                        typename proto::result_of::eval<
+                            typename remove_reference<
+                                typename proto::result_of::child_c<Expr, 1>::type
                             >::type
+                          , Context
                         >::type
                     >::type
                 >
Modified: trunk/boost/proto/detail/decltype.hpp
==============================================================================
--- trunk/boost/proto/detail/decltype.hpp	(original)
+++ trunk/boost/proto/detail/decltype.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -22,7 +22,6 @@
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/type_traits/is_class.hpp>
-#include <boost/type_traits/remove_cv.hpp>
 #include <boost/type_traits/remove_reference.hpp>
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/is_function.hpp>
@@ -391,9 +390,7 @@
             {
                 typedef
                     typename classtypeof<
-                        typename remove_const<
-                            typename remove_reference<U>::type
-                        >::type
+                        typename uncvref<U>::type
                     >::type
                 V;
 
@@ -487,7 +484,7 @@
         template<typename T, typename PMF>
         struct memfun
         {
-            typedef typename remove_const<typename remove_reference<PMF>::type>::type pmf_type;
+            typedef typename uncvref<PMF>::type pmf_type;
             typedef typename classtypeof<pmf_type>::type V;
             typedef typename boost::tr1_result_of<pmf_type(T)>::type result_type;
 
Modified: trunk/boost/proto/make_expr.hpp
==============================================================================
--- trunk/boost/proto/make_expr.hpp	(original)
+++ trunk/boost/proto/make_expr.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -37,8 +37,6 @@
     #include <boost/type_traits/add_const.hpp>
     #include <boost/type_traits/add_reference.hpp>
     #include <boost/type_traits/remove_cv.hpp>
-    #include <boost/type_traits/remove_const.hpp>
-    #include <boost/type_traits/remove_reference.hpp>
     #include <boost/proto/proto_fwd.hpp>
     #include <boost/proto/traits.hpp>
     #include <boost/proto/domain.hpp>
Modified: trunk/boost/proto/matches.hpp
==============================================================================
--- trunk/boost/proto/matches.hpp	(original)
+++ trunk/boost/proto/matches.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -323,12 +323,18 @@
 
             template<typename Tag, typename Args1, typename Args2>
             struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<Tag, Args2, 1> >
-              : matches_<typename detail::expr_traits<typename Args1::child0>::value_type::proto_base_expr, typename Args2::child0::proto_base_expr>
+              : matches_<
+					typename detail::expr_traits<typename Args1::child0>::value_type::proto_base_expr
+				  , typename Args2::child0::proto_base_expr
+				>
             {};
 
             template<typename Tag, typename Args1, typename Args2>
             struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<proto::_, Args2, 1> >
-              : matches_<typename detail::expr_traits<typename Args1::child0>::value_type::proto_base_expr, typename Args2::child0::proto_base_expr>
+              : matches_<
+					typename detail::expr_traits<typename Args1::child0>::value_type::proto_base_expr
+				  , typename Args2::child0::proto_base_expr
+				>
             {};
 
         #define BOOST_PROTO_MATCHES_N_FUN(Z, N, DATA)                                               \
@@ -377,7 +383,9 @@
 
             template<typename Expr, typename If>
             struct matches_<Expr, proto::if_<If> >
-              : detail::uncvref<typename when<_, If>::template impl<Expr, int, int>::result_type>::type
+              : detail::uncvref<
+					typename when<_, If>::template impl<Expr, int, int>::result_type
+				>::type
             {};
 
             // handle degenerate cases of proto::or_
@@ -1020,14 +1028,20 @@
             template<typename Args, typename Back, long To>
             struct vararg_matches_impl<Args, Back, N, To>
               : and_2<
-                    matches_<typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_base_expr, Back>::value
+                    matches_<
+						typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_base_expr
+					  , Back
+					>::value
                   , vararg_matches_impl<Args, Back, N + 1, To>
                 >
             {};
 
             template<typename Args, typename Back>
             struct vararg_matches_impl<Args, Back, N, N>
-              : matches_<typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_base_expr, Back>
+              : matches_<
+					typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_base_expr
+				  , Back
+				>
             {};
 
             template<
@@ -1035,7 +1049,11 @@
                 BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Expr)
                 BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Grammar)
             >
-            struct lambda_matches<T<BOOST_PP_ENUM_PARAMS(N, Expr)>, T<BOOST_PP_ENUM_PARAMS(N, Grammar)> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N) >
+            struct lambda_matches<
+				T<BOOST_PP_ENUM_PARAMS(N, Expr)>
+			  , T<BOOST_PP_ENUM_PARAMS(N, Grammar)>
+			    BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
+			>
               : BOOST_PP_CAT(and_, N)<
                     BOOST_PROTO_DEFINE_LAMBDA_MATCHES(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_LAMBDA_MATCHES, ~)
Modified: trunk/boost/proto/operators.hpp
==============================================================================
--- trunk/boost/proto/operators.hpp	(original)
+++ trunk/boost/proto/operators.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -11,10 +11,8 @@
 #define BOOST_PROTO_OPERATORS_HPP_EAN_04_01_2005
 
 #include <boost/preprocessor/punctuation/comma.hpp>
-#include <boost/preprocessor/seq/seq.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/mpl/assert.hpp>
-#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/utility/enable_if.hpp>
 #include <boost/proto/proto_fwd.hpp>
 #include <boost/proto/tags.hpp>
 #include <boost/proto/expr.hpp>
@@ -27,213 +25,65 @@
 {
     namespace detail
     {
-        template<typename Domain, typename Expr, typename EnableIf = void>
-        struct generate_if
-          : lazy_enable_if_c<
-                matches<Expr, typename Domain::proto_grammar>::value
-              , typename Domain::proto_generator::template result<typename Domain::proto_generator(Expr)>
-            >
-        {};
-
-        // Optimization, generate fewer templates...
-        template<typename Expr>
-        struct generate_if<proto::default_domain, Expr, void>
-        {
-            typedef Expr type;
-        };
-
-        template<typename Domain, typename Tag, typename Left, typename Right>
-        struct generate_if_left
-          : lazy_enable_if_c<
-                matches<proto::expr<Tag, proto::list2<Left &, Right>, 2>, typename Domain::proto_grammar>::value
-              , typename Domain::proto_generator::template result<typename Domain::proto_generator(
-                    proto::expr<Tag, proto::list2<Left &, typename Domain::proto_generator::template result<Domain(Right)>::type>, 2>
-                )>
-            >
-        {};
-
-        // Optimization, generate fewer templates...
-        template<typename Tag, typename Left, typename Right>
-        struct generate_if_left<proto::default_domain, Tag, Left, Right>
-        {
-            typedef proto::expr<Tag, proto::list2<Left &, Right>, 2> type;
-        };
-
-        template<typename Domain, typename Tag, typename Left, typename Right>
-        struct generate_if_right
-          : lazy_enable_if_c<
-                matches<proto::expr<Tag, proto::list2<Left, Right &>, 2>, typename Domain::proto_grammar>::value
-              , typename Domain::proto_generator::template result<typename Domain::proto_generator(
-                    proto::expr<Tag, proto::list2<typename Domain::proto_generator::template result<Domain(Left)>::type, Right &>, 2>
-                )>
-            >
-        {};
-
-        // Optimization, generate fewer templates...
-        template<typename Tag, typename Left, typename Right>
-        struct generate_if_right<proto::default_domain, Tag, Left, Right>
-        {
-            typedef proto::expr<Tag, proto::list2<Left, Right &>, 2> type;
-        };
-
-        template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
-        struct as_expr_if2
+        template<typename MakeExpr, typename Grammar>
+        struct lazy_matches
+          : proto::matches<typename MakeExpr::type, Grammar>
         {};
 
-        template<typename Tag, typename Left, typename Right>
-        struct as_expr_if2<Tag, Left, Right, typename Left::proto_is_expr_, void>
-          : generate_if_left<
-                typename Left::proto_domain
-              , Tag
-              , Left
-              , proto::expr<tag::terminal, term<Right &>, 0>
-            >
-        {
-            typedef proto::expr<tag::terminal, term<Right &>, 0> term_type;
-            typedef typename Left::proto_generator proto_generator;
-            typedef
-                proto::expr<
-                    Tag
-                  , list2<
-                        Left &
-                      , typename proto_generator::template result<proto_generator(term_type)>::type
-                    >
-                  , 2
-                >
-            expr_type;
-
-            static typename proto_generator::template result<proto_generator(expr_type)>::type
-            make(Left &left, Right &right)
-            {
-                term_type const term = {right};
-                expr_type const that = {left, proto_generator()(term)};
-                return proto_generator()(that);
-            }
-        };
-
-        template<typename Tag, typename Left, typename Right>
-        struct as_expr_if2<Tag, Left, Right, void, typename Right::proto_is_expr_>
-          : generate_if_right<
-                typename Right::proto_domain
-              , Tag
-              , proto::expr<tag::terminal, term<Left &>, 0>
-              , Right
-            >
-        {
-            typedef proto::expr<tag::terminal, term<Left &>, 0> term_type;
-            typedef typename Right::proto_generator proto_generator;
-            typedef
-                proto::expr<
-                    Tag
-                  , list2<
-                        typename proto_generator::template result<proto_generator(term_type)>::type
-                      , Right &
-                    >
-                  , 2
-                >
-            expr_type;
-
-            static typename proto_generator::template result<proto_generator(expr_type)>::type
-            make(Left &left, Right &right)
-            {
-                term_type const term = {left};
-                expr_type const that = {proto_generator()(term), right};
-                return proto_generator()(that);
-            }
-        };
-
-        template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
-        struct as_expr_if
-          : as_expr_if2<Tag, Left, Right>
-        {};
-
-        template<typename Tag, typename Left, typename Right>
-        struct as_expr_if<Tag, Left, Right, typename Left::proto_is_expr_, typename Right::proto_is_expr_>
-          : generate_if<
-                typename common_domain2<typename Left::proto_domain, typename Right::proto_domain>::type
-              , proto::expr<Tag, list2<Left &, Right &>, 2>
-            >
-        {
-            typedef proto::expr<Tag, list2<Left &, Right &>, 2> expr_type;
-            typedef
-                typename common_domain2<
-                    typename Left::proto_domain
-                  , typename Right::proto_domain
-                >::type
-            proto_domain;
-            typedef typename proto_domain::proto_generator proto_generator;
-
-            static typename proto_generator::template result<proto_generator(expr_type)>::type
-            make(Left &left, Right &right)
-            {
-                expr_type const that = {left, right};
-                return proto_generator()(that);
-            }
-        };
-
-        template<typename Arg, typename Trait, typename Enable = void>
-        struct arg_weight
-        {
-            BOOST_STATIC_CONSTANT(int, value = 1 + Trait::value);
-        };
-
-        template<typename Arg, typename Trait>
-        struct arg_weight<Arg, Trait, typename Arg::proto_is_expr_>
-        {
-            BOOST_STATIC_CONSTANT(int, value = 0);
-        };
-
-        template<typename Domain, typename Trait, typename Arg, typename Expr>
+        template<typename Domain, typename Grammar, typename Trait, typename Tag, typename Arg>
         struct enable_unary
-          : boost::enable_if_c<
-                boost::mpl::and_<Trait, boost::proto::matches<Expr, typename Domain::proto_grammar> >::value
-              , Expr
-            >
-        {};
-
-        template<typename Trait, typename Arg, typename Expr>
-        struct enable_unary<deduce_domain, Trait, Arg, Expr>
-          : boost::enable_if_c<
+          : boost::lazy_enable_if_c<
                 boost::mpl::and_<
                     Trait
-                  , boost::proto::matches<Expr, typename domain_of<Arg>::type::proto_grammar>
+                  , lazy_matches<result_of::make_expr<Tag, Domain, Arg &>, Grammar>
                 >::value
-              , Expr
+              , result_of::make_expr<Tag, Domain, Arg &>
             >
         {};
 
-        template<typename Trait, typename Arg, typename Expr>
-        struct enable_unary<default_domain, Trait, Arg, Expr>
-          : boost::enable_if_c<Trait::value, Expr>
+        template<typename Domain, typename Trait, typename Tag, typename Arg>
+        struct enable_unary<Domain, proto::_, Trait, Tag, Arg>
+          : boost::lazy_enable_if_c<Trait::value, result_of::make_expr<Tag, Domain, Arg &> >
         {};
 
-        template<typename Domain, typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
-        struct enable_binary
-          : boost::enable_if_c<
-                boost::mpl::and_<
-                    mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
-                  , boost::proto::matches<Expr, typename Domain::proto_grammar>
-                >::value
-              , Expr
+        template<typename Trait, typename Tag, typename Arg>
+        struct enable_unary<deduce_domain, not_a_grammar, Trait, Tag, Arg>
+          : enable_unary<
+                typename domain_of<Arg>::type
+              , typename domain_of<Arg>::type::proto_grammar
+              , Trait
+              , Tag
+              , Arg
             >
         {};
 
-        template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
-        struct enable_binary<deduce_domain, Trait1, Arg1, Trait2, Arg2, Expr>
-          : boost::enable_if_c<
+        template<typename Domain, typename Grammar, typename Trait, typename Tag, typename Left, typename Right>
+        struct enable_binary
+          : boost::lazy_enable_if_c<
                 boost::mpl::and_<
-                    mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
-                  , boost::proto::matches<Expr, typename deduce_domain2<Arg1, Arg2>::type::proto_grammar>
+                    Trait
+                  , lazy_matches<proto::result_of::as_child<Left>, Grammar>
+                  , lazy_matches<proto::result_of::as_child<Right>, Grammar>
+                  , lazy_matches<result_of::make_expr<Tag, Domain, Left &, Right &>, Grammar>
                 >::value
-              , Expr
+              , result_of::make_expr<Tag, Domain, Left &, Right &>
             >
         {};
 
-        template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
-        struct enable_binary<default_domain, Trait1, Arg1, Trait2, Arg2, Expr>
-          : boost::enable_if_c<
-                (3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))
-              , Expr
+        template<typename Domain, typename Trait, typename Tag, typename Left, typename Right>
+        struct enable_binary<Domain, proto::_, Trait, Tag, Left, Right>
+          : boost::lazy_enable_if_c<Trait::value, result_of::make_expr<Tag, Domain, Left &, Right &> >
+        {};
+
+        template<typename Trait, typename Tag, typename Left, typename Right>
+        struct enable_binary<deduce_domain, not_a_grammar, Trait, Tag, Left, Right>
+          : enable_binary<
+                typename deduce_domain2<Left, Right>::type
+              , typename deduce_domain2<Left, Right>::type::proto_grammar
+              , Trait
+              , Tag
+              , Left
+              , Right
             >
         {};
 
@@ -242,133 +92,27 @@
 #define BOOST_PROTO_UNARY_OP_IS_POSTFIX_0
 #define BOOST_PROTO_UNARY_OP_IS_POSTFIX_1 , int
 
-#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, POST)                                            \
-    template<typename Arg>                                                                          \
-    typename detail::generate_if<                                                                   \
-        typename Arg::proto_domain                                                                  \
-      , proto::expr<TAG, list1<Arg &>, 1>                                                           \
-      , typename Arg::proto_is_expr_                                                                \
-    >::type const                                                                                   \
-    operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST)                                  \
-    {                                                                                               \
-        typedef proto::expr<TAG, list1<Arg &>, 1> that_type;                                        \
-        that_type const that = {arg};                                                               \
-        return typename Arg::proto_generator()(that);                                               \
-    }                                                                                               \
-    template<typename Arg>                                                                          \
-    typename detail::generate_if<                                                                   \
-        typename Arg::proto_domain                                                                  \
-      , proto::expr<TAG, list1<Arg const &>, 1>                                                     \
-      , typename Arg::proto_is_expr_                                                                \
-    >::type const                                                                                   \
-    operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST)                            \
-    {                                                                                               \
-        typedef proto::expr<TAG, list1<Arg const &>, 1> that_type;                                  \
-        that_type const that = {arg};                                                               \
-        return typename Arg::proto_generator()(that);                                               \
-    }                                                                                               \
-    /**/
-
-#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG)                                                 \
-    template<typename Left, typename Right>                                                         \
-    inline typename detail::as_expr_if<TAG, Left, Right>::type const                                \
-    operator OP(Left &left, Right &right)                                                           \
-    {                                                                                               \
-        return detail::as_expr_if<TAG, Left, Right>::make(left, right);                             \
-    }                                                                                               \
-    template<typename Left, typename Right>                                                         \
-    inline typename detail::as_expr_if<TAG, Left, Right const>::type const                          \
-    operator OP(Left &left, Right const &right)                                                     \
-    {                                                                                               \
-        return detail::as_expr_if<TAG, Left, Right const>::make(left, right);                       \
-    }                                                                                               \
-    template<typename Left, typename Right>                                                         \
-    inline typename detail::as_expr_if<TAG, Left const, Right>::type const                          \
-    operator OP(Left const &left, Right &right)                                                     \
-    {                                                                                               \
-        return detail::as_expr_if<TAG, Left const, Right>::make(left, right);                       \
-    }                                                                                               \
-    template<typename Left, typename Right>                                                         \
-    inline typename detail::as_expr_if<TAG, Left const, Right const>::type const                    \
-    operator OP(Left const &left, Right const &right)                                               \
-    {                                                                                               \
-        return detail::as_expr_if<TAG, Left const, Right const>::make(left, right);                 \
-    }                                                                                               \
-    /**/
-
-    namespace exprns_
-    {
-
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(+, tag::unary_plus, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(-, tag::negate, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(*, tag::dereference, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(~, tag::complement, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(&, tag::address_of, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(!, tag::logical_not, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, tag::pre_inc, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, tag::pre_dec, 0)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, tag::post_inc, 1)
-        BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, tag::post_dec, 1)
-
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<, tag::shift_left)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>, tag::shift_right)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(*, tag::multiplies)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(/, tag::divides)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(%, tag::modulus)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(+, tag::plus)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(-, tag::minus)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(<, tag::less)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(>, tag::greater)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(<=, tag::less_equal)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(>=, tag::greater_equal)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(==, tag::equal_to)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(!=, tag::not_equal_to)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(||, tag::logical_or)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(&&, tag::logical_and)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(&, tag::bitwise_and)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(|, tag::bitwise_or)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(^, tag::bitwise_xor)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(BOOST_PP_COMMA(), tag::comma)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(->*, tag::mem_ptr)
-
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<=, tag::shift_left_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>=, tag::shift_right_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(*=, tag::multiplies_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(/=, tag::divides_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(%=, tag::modulus_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(+=, tag::plus_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(-=, tag::minus_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(&=, tag::bitwise_and_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(|=, tag::bitwise_or_assign)
-        BOOST_PROTO_DEFINE_BINARY_OPERATOR(^=, tag::bitwise_xor_assign)
-
-        /// if_else
-        ///
-        template<typename A0, typename A1, typename A2>
-        typename functional::make_expr<tag::if_else_>::impl<A0 const &, A1 const &, A2 const &>::result_type const
-        if_else(A0 const &a0, A1 const &a1, A2 const &a2)
-        {
-            return functional::make_expr<tag::if_else_>::impl<A0 const &, A1 const &, A2 const &>()(a0, a1, a2);
-        }
-    }
-
-    using exprns_::if_else;
-
-#undef BOOST_PROTO_DEFINE_UNARY_OPERATOR
-#undef BOOST_PROTO_DEFINE_BINARY_OPERATOR
-
 #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::functional::make_expr<TAG, DOMAIN>::impl<Arg &>::result_type       \
+    typename boost::proto::detail::enable_unary<                                                    \
+        DOMAIN                                                                                      \
+      , DOMAIN::proto_grammar                                                                       \
+      , BOOST_PROTO_APPLY_UNARY_(TRAIT, Arg)                                                        \
+      , TAG                                                                                         \
+      , Arg                                                                                         \
     >::type const                                                                                   \
     operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST)                                  \
     {                                                                                               \
         return boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Arg &>()(arg);                \
     }                                                                                               \
+                                                                                                    \
     template<typename Arg>                                                                          \
-    typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg                             \
-        , typename boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Arg const &>::result_type \
+    typename boost::proto::detail::enable_unary<                                                    \
+        DOMAIN                                                                                      \
+      , DOMAIN::proto_grammar                                                                       \
+      , BOOST_PROTO_APPLY_UNARY_(TRAIT, Arg)                                                        \
+      , TAG                                                                                         \
+      , Arg const                                                                                   \
     >::type const                                                                                   \
     operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST)                            \
     {                                                                                               \
@@ -378,36 +122,63 @@
 
 #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::functional::make_expr<TAG, DOMAIN>::impl<Left &, Right &>::result_type\
+    typename boost::proto::detail::enable_binary<                                                   \
+        DOMAIN                                                                                      \
+      , DOMAIN::proto_grammar                                                                       \
+      , BOOST_PROTO_APPLY_BINARY_(TRAIT, Left, Right)                                               \
+      , TAG                                                                                         \
+      , Left                                                                                        \
+      , Right                                                                                       \
     >::type const                                                                                   \
     operator OP(Left &left, Right &right)                                                           \
     {                                                                                               \
-        return boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left &, Right &>()(left, right);\
+        return boost::proto::functional::make_expr<TAG, DOMAIN>::                                   \
+            impl<Left &, Right &>()(left, right);                                                   \
     }                                                                                               \
+                                                                                                    \
     template<typename Left, typename Right>                                                         \
-    typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left &, Right const &>::result_type\
+    typename boost::proto::detail::enable_binary<                                                   \
+        DOMAIN                                                                                      \
+      , DOMAIN::proto_grammar                                                                       \
+      , BOOST_PROTO_APPLY_BINARY_(TRAIT, Left, Right)                                               \
+      , TAG                                                                                         \
+      , Left                                                                                        \
+      , Right const                                                                                 \
     >::type const                                                                                   \
     operator OP(Left &left, Right const &right)                                                     \
     {                                                                                               \
-        return boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left &, Right const &>()(left, right);\
+        return boost::proto::functional::make_expr<TAG, DOMAIN>::                                   \
+            impl<Left &, Right const &>()(left, right);                                             \
     }                                                                                               \
+                                                                                                    \
     template<typename Left, typename Right>                                                         \
-    typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left const &, Right &>::result_type\
+    typename boost::proto::detail::enable_binary<                                                   \
+        DOMAIN                                                                                      \
+      , DOMAIN::proto_grammar                                                                       \
+      , BOOST_PROTO_APPLY_BINARY_(TRAIT, Left, Right)                                               \
+      , TAG                                                                                         \
+      , Left const                                                                                  \
+      , Right                                                                                       \
     >::type const                                                                                   \
     operator OP(Left const &left, Right &right)                                                     \
     {                                                                                               \
-        return boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left const &, Right &>()(left, right);\
+        return boost::proto::functional::make_expr<TAG, DOMAIN>::                                   \
+            impl<Left const &, Right &>()(left, right);                                             \
     }                                                                                               \
+                                                                                                    \
     template<typename Left, typename Right>                                                         \
-    typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right     \
-        , typename boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left const &, Right const &>::result_type\
+    typename boost::proto::detail::enable_binary<                                                   \
+        DOMAIN                                                                                      \
+      , DOMAIN::proto_grammar                                                                       \
+      , BOOST_PROTO_APPLY_BINARY_(TRAIT, Left, Right)                                               \
+      , TAG                                                                                         \
+      , Left const                                                                                  \
+      , Right const                                                                                 \
     >::type const                                                                                   \
     operator OP(Left const &left, Right const &right)                                               \
     {                                                                                               \
-        return boost::proto::functional::make_expr<TAG, DOMAIN>::impl<Left const &, Right const &>()(left, right);\
+        return boost::proto::functional::make_expr<TAG, DOMAIN>::                                   \
+            impl<Left const &, Right const &>()(left, right);                                       \
     }                                                                                               \
     /**/
 
@@ -454,17 +225,54 @@
     BOOST_PROTO_DEFINE_BINARY_OPERATOR(^=, boost::proto::tag::bitwise_xor_assign, TRAIT, DOMAIN)    \
     /**/
 
+    // Extensions are a superset of Proto expressions
     template<typename T>
     struct is_extension
-      : mpl::false_
+      : is_expr<T>
     {};
 
-    namespace exops
+    #define BOOST_PROTO_APPLY_UNARY_(TRAIT, ARG) TRAIT<ARG>
+    #define BOOST_PROTO_APPLY_BINARY_(TRAIT, LEFT, RIGHT) boost::mpl::or_<TRAIT<LEFT>, TRAIT<RIGHT> >
+
+    namespace exprns_
     {
-        BOOST_PROTO_DEFINE_OPERATORS(is_extension, default_domain)
-        using proto::if_else;
+        // This defines all of Proto's built-in free operator overloads
+        BOOST_PROTO_DEFINE_OPERATORS(is_extension, deduce_domain)
+
+        // if_else, for the non-overloadable ternary conditional operator ?:
+        template<typename A0, typename A1, typename A2>
+        typename result_of::make_expr<tag::if_else_, deduce_domain, A0 const &, A1 const &, A2 const &>::type const
+        if_else(A0 const &a0, A1 const &a1, A2 const &a2)
+        {
+            return functional::make_expr<tag::if_else_>::impl<A0 const &, A1 const &, A2 const &>()(a0, a1, a2);
+        }
     }
 
+    using exprns_::if_else;
+
+    #undef BOOST_PROTO_APPLY_UNARY_
+    #undef BOOST_PROTO_APPLY_BINARY_
+
+    // Redefine BOOST_PROTO_APPLY_UNARY_ and BOOST_PROTO_APPLY_BINARY_ so that end users
+    // can use BOOST_PROTO_DEFINE_OPERATORS to define Proto operator overloads that work
+    // with their own terminal types.
+
+    #define BOOST_PROTO_APPLY_UNARY_(TRAIT, ARG)                                                    \
+        boost::mpl::and_<TRAIT<ARG>, boost::mpl::not_<boost::proto::is_extension<ARG> > >           \
+        /**/
+
+    #define BOOST_PROTO_APPLY_BINARY_(TRAIT, LEFT, RIGHT)                                           \
+        boost::mpl::and_<                                                                           \
+            boost::mpl::or_<TRAIT<LEFT>, TRAIT<RIGHT> >                                             \
+          , boost::mpl::not_<                                                                       \
+                boost::mpl::or_<                                                                    \
+                    boost::proto::is_extension<LEFT>                                                \
+                  , boost::proto::is_extension<RIGHT>                                               \
+                >                                                                                   \
+            >                                                                                       \
+        >                                                                                           \
+        /**/
+
 }}
 
 #endif
Modified: trunk/boost/proto/proto_fwd.hpp
==============================================================================
--- trunk/boost/proto/proto_fwd.hpp	(original)
+++ trunk/boost/proto/proto_fwd.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -122,6 +122,24 @@
             typedef T type;
         };
 
+        template<typename T, std::size_t N>
+        struct uncvref<T const[N]>
+        {
+            typedef T type[N];
+        };
+
+        template<typename T, std::size_t N>
+        struct uncvref<T (&)[N]>
+        {
+            typedef T type[N];
+        };
+
+        template<typename T, std::size_t N>
+        struct uncvref<T const (&)[N]>
+        {
+            typedef T type[N];
+        };
+
         struct ignore
         {
             ignore()
@@ -135,7 +153,8 @@
         /// INTERNAL ONLY
         ///
         #define BOOST_PROTO_UNCVREF(X)                                                              \
-            typename boost::remove_const<typename boost::remove_reference<X>::type>::type
+			typename boost::proto::detail::uncvref<X>::type											\
+			/**/
 
         struct _default;
 
@@ -752,8 +771,10 @@
     template<typename T>
     struct is_extension;
 
-    namespace exops
-    {}
+    //namespace exops
+    //{}
+
+	namespace exops = exprns_;
 
 }} // namespace boost::proto
 
Modified: trunk/boost/proto/traits.hpp
==============================================================================
--- trunk/boost/proto/traits.hpp	(original)
+++ trunk/boost/proto/traits.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -37,7 +37,6 @@
     #include <boost/type_traits/is_same.hpp>
     #include <boost/type_traits/is_function.hpp>
     #include <boost/type_traits/remove_cv.hpp>
-    #include <boost/type_traits/remove_const.hpp>
     #include <boost/type_traits/add_reference.hpp>
     #include <boost/proto/proto_fwd.hpp>
     #include <boost/proto/args.hpp>
Modified: trunk/boost/proto/transform/default.hpp
==============================================================================
--- trunk/boost/proto/transform/default.hpp	(original)
+++ trunk/boost/proto/transform/default.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -171,14 +171,12 @@
             template<typename Grammar, typename Expr, typename State, typename Data>
             struct is_member_function_invocation
               : is_member_function_pointer<
-                    typename remove_const<
-                        typename remove_reference<
-                            typename Grammar::template impl<
-                                typename result_of::child_c<Expr, 1>::type
-                              , State
-                              , Data
-                            >::result_type
-                        >::type
+                    typename uncvref<
+                        typename Grammar::template impl<
+                            typename result_of::child_c<Expr, 1>::type
+                            , State
+                            , Data
+                        >::result_type
                     >::type
                 >
             {};
Modified: trunk/boost/proto/transform/make.hpp
==============================================================================
--- trunk/boost/proto/transform/make.hpp	(original)
+++ trunk/boost/proto/transform/make.hpp	2010-06-06 09:40:44 EDT (Sun, 06 Jun 2010)
@@ -26,8 +26,6 @@
     #include <boost/mpl/aux_/template_arity.hpp>
     #include <boost/mpl/aux_/lambda_arity_param.hpp>
     #include <boost/utility/result_of.hpp>
-    #include <boost/type_traits/remove_const.hpp>
-    #include <boost/type_traits/remove_reference.hpp>
     #include <boost/proto/proto_fwd.hpp>
     #include <boost/proto/traits.hpp>
     #include <boost/proto/args.hpp>
@@ -96,11 +94,7 @@
             // TODO could optimize this if R is a transform
             template<typename R, typename Expr, typename State, typename Data>
             struct make_if_<R, Expr, State, Data, true>
-              : remove_const<
-                    typename remove_reference<
-                        typename R::template impl<Expr, State, Data>::result_type
-                    >::type
-                >
+              : uncvref<typename R::template impl<Expr, State, Data>::result_type>
             {};
 
             template<typename Type, bool IsAggregate = is_aggregate<Type>::value>
@@ -335,11 +329,9 @@
             struct make_if_<R(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
             {
                 typedef
-                    typename remove_const<
-                        typename remove_reference<
-                            typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
-                                ::template impl<Expr, State, Data>::result_type
-                        >::type
+                    typename uncvref<
+                        typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
+                            ::template impl<Expr, State, Data>::result_type
                     >::type
                 type;
             };
@@ -352,11 +344,9 @@
             struct make_if_<R(*)(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
             {
                 typedef
-                    typename remove_const<
-                        typename remove_reference<
-                            typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
-                                ::template impl<Expr, State, Data>::result_type
-                        >::type
+                    typename uncvref<
+                        typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
+                            ::template impl<Expr, State, Data>::result_type
                     >::type
                 type;
             };