Boost logo

Boost-Commit :

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


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