Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67122 - in trunk: boost/proto libs/proto/test
From: eric_at_[hidden]
Date: 2010-12-08 23:08:42


Author: eric_niebler
Date: 2010-12-08 23:08:40 EST (Wed, 08 Dec 2010)
New Revision: 67122
URL: http://svn.boost.org/trac/boost/changeset/67122

Log:
proto::matches preserves domain-specific expression wrappers
Text files modified:
   trunk/boost/proto/domain.hpp | 22 ++++
   trunk/boost/proto/matches.hpp | 201 +++++++++++++++++++++------------------
   trunk/boost/proto/proto_fwd.hpp | 3
   trunk/libs/proto/test/matches.cpp | 19 +++
   4 files changed, 152 insertions(+), 93 deletions(-)

Modified: trunk/boost/proto/domain.hpp
==============================================================================
--- trunk/boost/proto/domain.hpp (original)
+++ trunk/boost/proto/domain.hpp 2010-12-08 23:08:40 EST (Wed, 08 Dec 2010)
@@ -292,6 +292,28 @@
         typedef typename domain_of<T>::type type;
     };
 
+ /// A metafunction that returns \c mpl::true_
+ /// if the type \c SubDomain is a sub-domain of
+ /// \c SuperDomain; \c mpl::false_ otherwise.
+ template<typename SubDomain, typename SuperDomain>
+ struct is_sub_domain_of
+ : is_sub_domain_of<typename SubDomain::proto_super_domain, SuperDomain>
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename SuperDomain>
+ struct is_sub_domain_of<proto::no_super_domain, SuperDomain>
+ : mpl::false_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename SuperDomain>
+ struct is_sub_domain_of<SuperDomain, SuperDomain>
+ : mpl::true_
+ {};
+
 }}
 
 #endif

Modified: trunk/boost/proto/matches.hpp
==============================================================================
--- trunk/boost/proto/matches.hpp (original)
+++ trunk/boost/proto/matches.hpp 2010-12-08 23:08:40 EST (Wed, 08 Dec 2010)
@@ -67,7 +67,7 @@
 
         namespace detail
         {
- template<typename Expr, typename Grammar>
+ template<typename Expr, typename BasicExpr, typename Grammar>
             struct matches_;
 
             template<bool B, typename Pred>
@@ -138,24 +138,26 @@
             struct vararg_matches_impl;
 
             // vararg_matches
- template<typename Args1, typename Args2, typename Back, bool Can, bool Zero, typename Void = void>
+ template<typename Expr, typename Args1, typename Args2, typename Back, bool Can, bool Zero, typename Void = void>
             struct vararg_matches
               : mpl::false_
             {};
 
- template<typename Args1, typename Args2, typename Back>
- struct vararg_matches<Args1, Args2, Back, true, true, typename Back::proto_is_vararg_>
+ template<typename Expr, typename Args1, typename Args2, typename Back>
+ struct vararg_matches<Expr, Args1, Args2, Back, true, true, typename Back::proto_is_vararg_>
               : matches_<
- proto::basic_expr<ignore, Args1, Args1::arity>
+ Expr
+ , proto::basic_expr<ignore, Args1, Args1::arity>
                   , proto::basic_expr<ignore, Args2, Args1::arity>
>
             {};
 
- template<typename Args1, typename Args2, typename Back>
- struct vararg_matches<Args1, Args2, Back, true, false, typename Back::proto_is_vararg_>
+ template<typename Expr, typename Args1, typename Args2, typename Back>
+ struct vararg_matches<Expr, Args1, Args2, Back, true, false, typename Back::proto_is_vararg_>
               : and_2<
                     matches_<
- proto::basic_expr<ignore, Args1, Args2::arity>
+ Expr
+ , proto::basic_expr<ignore, Args1, Args2::arity>
                       , proto::basic_expr<ignore, Args2, Args2::arity>
>::value
                   , vararg_matches_impl<Args1, typename Back::proto_grammar, Args2::arity + 1, Args1::arity>
@@ -297,66 +299,70 @@
             {};
 
             // matches_
- template<typename Expr, typename Grammar>
+ template<typename Expr, typename BasicExpr, typename Grammar>
             struct matches_
               : mpl::false_
             {};
 
- template<typename Expr>
- struct matches_< Expr, proto::_ >
+ template<typename Expr, typename BasicExpr>
+ struct matches_< Expr, BasicExpr, proto::_ >
               : mpl::true_
             {};
 
- template<typename Tag, typename Args1, long N1, typename Args2, long N2>
- struct matches_< proto::basic_expr<Tag, Args1, N1>, proto::basic_expr<Tag, Args2, N2> >
- : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
+ template<typename Expr, typename Tag, typename Args1, long N1, typename Args2, long N2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, N1>, proto::basic_expr<Tag, Args2, N2> >
+ : vararg_matches< Expr, Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
             {};
 
- template<typename Tag, typename Args1, long N1, typename Args2, long N2>
- struct matches_< proto::basic_expr<Tag, Args1, N1>, proto::basic_expr<proto::_, Args2, N2> >
- : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
+ template<typename Expr, typename Tag, typename Args1, long N1, typename Args2, long N2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, N1>, proto::basic_expr<proto::_, Args2, N2> >
+ : vararg_matches< Expr, Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
             {};
 
- template<typename Tag, typename Args1, typename Args2>
- struct matches_< proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<Tag, Args2, 0> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<Tag, Args2, 0> >
               : terminal_matches<typename Args1::child0, typename Args2::child0>
             {};
 
- template<typename Tag, typename Args1, typename Args2, long N2>
- struct matches_< proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<proto::_, Args2, N2> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2, long N2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<proto::_, Args2, N2> >
               : mpl::false_
             {};
 
- template<typename Tag, typename Args1, typename Args2>
- struct matches_< proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<proto::_, Args2, 0> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 0>, proto::basic_expr<proto::_, Args2, 0> >
               : terminal_matches<typename Args1::child0, typename Args2::child0>
             {};
 
- template<typename Tag, typename Args1, typename Args2>
- struct matches_< proto::basic_expr<Tag, Args1, 1>, proto::basic_expr<Tag, Args2, 1> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 1>, proto::basic_expr<Tag, Args2, 1> >
               : matches_<
- typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar
- , typename Args2::child0::proto_grammar
- >
+ typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar
+ , typename Args2::child0::proto_grammar
+ >
             {};
 
- template<typename Tag, typename Args1, typename Args2>
- struct matches_< proto::basic_expr<Tag, Args1, 1>, proto::basic_expr<proto::_, Args2, 1> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 1>, proto::basic_expr<proto::_, Args2, 1> >
               : matches_<
- typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar
- , typename Args2::child0::proto_grammar
- >
+ typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar
+ , typename Args2::child0::proto_grammar
+ >
             {};
 
         #define BOOST_PROTO_MATCHES_N_FUN(Z, N, DATA) \
             matches_< \
- typename detail::expr_traits<typename Args1::BOOST_PP_CAT(child, N)>::value_type::proto_grammar\
+ typename detail::expr_traits<typename Args1::BOOST_PP_CAT(child, N)>::value_type::proto_derived_expr \
+ , typename detail::expr_traits<typename Args1::BOOST_PP_CAT(child, N)>::value_type::proto_grammar \
               , typename Args2::BOOST_PP_CAT(child, N)::proto_grammar \
>
 
         #define BOOST_PROTO_DEFINE_MATCHES(Z, N, DATA) \
             matches_< \
                 Expr \
+ , BasicExpr \
               , typename BOOST_PP_CAT(G, N)::proto_grammar \
>
 
@@ -381,22 +387,20 @@
         #undef BOOST_PROTO_DEFINE_LAMBDA_MATCHES
 
             // handle proto::if_
- template<typename Tag, typename Args, long Arity, typename If, typename Then, typename Else>
- struct matches_<proto::basic_expr<Tag, Args, Arity>, proto::if_<If, Then, Else> >
+ template<typename Expr, typename Tag, typename Args, long Arity, typename If, typename Then, typename Else>
+ struct matches_<Expr, proto::basic_expr<Tag, Args, Arity>, proto::if_<If, Then, Else> >
               : mpl::eval_if_c<
                     remove_reference<
- typename when<_, If>::
- template impl<proto::expr<Tag, Args, Arity>, int, int>::result_type
+ typename when<_, If>::template impl<Expr, int, int>::result_type
>::type::value
- , matches_<proto::basic_expr<Tag, Args, Arity>, typename Then::proto_grammar>
- , matches_<proto::basic_expr<Tag, Args, Arity>, typename Else::proto_grammar>
+ , matches_<Expr, proto::basic_expr<Tag, Args, Arity>, typename Then::proto_grammar>
+ , matches_<Expr, proto::basic_expr<Tag, Args, Arity>, typename Else::proto_grammar>
>::type
             {
                 typedef
                     typename mpl::if_c<
                         remove_reference<
- typename when<_, If>::
- template impl<proto::expr<Tag, Args, Arity>, int, int>::result_type
+ typename when<_, If>::template impl<Expr, int, int>::result_type
>::type::value
                       , Then
                       , Else
@@ -405,42 +409,43 @@
             };
 
             // handle degenerate cases of proto::or_
- template<typename Expr>
- struct matches_<Expr, or_<> >
+ template<typename Expr, typename BasicExpr>
+ struct matches_<Expr, BasicExpr, or_<> >
               : mpl::false_
             {
                 typedef not_<_> which;
             };
 
- template<typename Expr, typename G0>
- struct matches_<Expr, or_<G0> >
- : matches_<Expr, typename G0::proto_grammar>
+ template<typename Expr, typename BasicExpr, typename G0>
+ struct matches_<Expr, BasicExpr, or_<G0> >
+ : matches_<Expr, BasicExpr, typename G0::proto_grammar>
             {
                 typedef G0 which;
             };
 
             // handle degenerate cases of proto::and_
- template<typename Expr>
- struct matches_<Expr, and_<> >
+ template<typename Expr, typename BasicExpr>
+ struct matches_<Expr, BasicExpr, and_<> >
               : mpl::true_
             {};
 
- template<typename Expr, typename G0>
- struct matches_<Expr, and_<G0> >
- : matches_<Expr, typename G0::proto_grammar>
+ template<typename Expr, typename BasicExpr, typename G0>
+ struct matches_<Expr, BasicExpr, and_<G0> >
+ : matches_<Expr, BasicExpr, typename G0::proto_grammar>
             {};
 
             // handle proto::not_
- template<typename Expr, typename Grammar>
- struct matches_<Expr, not_<Grammar> >
- : mpl::not_<matches_<Expr, typename Grammar::proto_grammar> >
+ template<typename Expr, typename BasicExpr, typename Grammar>
+ struct matches_<Expr, BasicExpr, not_<Grammar> >
+ : mpl::not_<matches_<Expr, BasicExpr, typename Grammar::proto_grammar> >
             {};
 
             // handle proto::switch_
- template<typename Tag, typename Args, long Arity, typename Cases>
- struct matches_<proto::basic_expr<Tag, Args, Arity>, switch_<Cases> >
+ template<typename Expr, typename Tag, typename Args, long Arity, typename Cases>
+ struct matches_<Expr, proto::basic_expr<Tag, Args, Arity>, switch_<Cases> >
               : matches_<
- proto::basic_expr<Tag, Args, Arity>
+ Expr
+ , proto::basic_expr<Tag, Args, Arity>
                   , typename Cases::template case_<Tag>::proto_grammar
>
             {
@@ -513,7 +518,8 @@
         template<typename Expr, typename Grammar>
         struct matches
           : detail::matches_<
- typename Expr::proto_grammar
+ typename Expr::proto_derived_expr
+ , typename Expr::proto_grammar
               , typename Grammar::proto_grammar
>
         {};
@@ -523,7 +529,8 @@
         template<typename Expr, typename Grammar>
         struct matches<Expr &, Grammar>
           : detail::matches_<
- typename Expr::proto_grammar
+ typename Expr::proto_derived_expr
+ , typename Expr::proto_grammar
               , typename Grammar::proto_grammar
>
         {};
@@ -762,14 +769,20 @@
 
             template<typename Expr, typename State, typename Data>
             struct impl
- : detail::matches_<typename Expr::proto_grammar, or_>
- ::which::template impl<Expr, State, Data>
+ : detail::matches_<
+ typename Expr::proto_derived_expr
+ , typename Expr::proto_grammar
+ , or_
+ >::which::template impl<Expr, State, Data>
             {};
 
             template<typename Expr, typename State, typename Data>
             struct impl<Expr &, State, Data>
- : detail::matches_<typename Expr::proto_grammar, or_>
- ::which::template impl<Expr &, State, Data>
+ : detail::matches_<
+ typename Expr::proto_derived_expr
+ , typename Expr::proto_grammar
+ , or_
+ >::which::template impl<Expr &, State, Data>
             {};
         };
 
@@ -790,7 +803,7 @@
 
             template<typename Expr, typename State, typename Data>
             struct impl
- : detail::_and_impl<and_, Expr, State, Data>
+ : detail::_and_impl<and_, Expr, State, Data>
             {};
         };
 
@@ -824,12 +837,12 @@
 
             template<typename Expr, typename State, typename Data>
             struct impl
- : Cases::template case_<typename Expr::proto_tag>::template impl<Expr, State, Data>
+ : Cases::template case_<typename Expr::proto_tag>::template impl<Expr, State, Data>
             {};
 
             template<typename Expr, typename State, typename Data>
             struct impl<Expr &, State, Data>
- : Cases::template case_<typename Expr::proto_tag>::template impl<Expr &, State, Data>
+ : Cases::template case_<typename Expr::proto_tag>::template impl<Expr &, State, Data>
             {};
         };
 
@@ -993,40 +1006,40 @@
                 #undef M0
             };
 
- template<bool B, typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ template<bool B, typename Expr, typename BasicExpr, BOOST_PP_ENUM_PARAMS(N, typename G)>
             struct BOOST_PP_CAT(or_, N)
             #if 2 == N
- : mpl::bool_<matches_<Expr, typename G1::proto_grammar>::value>
+ : mpl::bool_<matches_<Expr, BasicExpr, typename G1::proto_grammar>::value>
             {
                 typedef G1 which;
             };
             #else
               : BOOST_PP_CAT(or_, BOOST_PP_DEC(N))<
- matches_<Expr, typename G1::proto_grammar>::value
- , Expr, BOOST_PP_ENUM_SHIFTED_PARAMS(N, G)
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, BOOST_PP_ENUM_SHIFTED_PARAMS(N, G)
>
             {};
             #endif
 
- template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G)>
- struct BOOST_PP_CAT(or_, N)<true, Expr, BOOST_PP_ENUM_PARAMS(N, G)>
+ template<typename Expr, typename BasicExpr BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G)>
+ struct BOOST_PP_CAT(or_, N)<true, Expr, BasicExpr, BOOST_PP_ENUM_PARAMS(N, G)>
               : mpl::true_
             {
                 typedef G0 which;
             };
 
             // handle proto::or_
- template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
- struct matches_<Expr, proto::or_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ template<typename Expr, typename BasicExpr BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G)>
+ struct matches_<Expr, BasicExpr, proto::or_<BOOST_PP_ENUM_PARAMS(N, G)> >
               : BOOST_PP_CAT(or_, N)<
- matches_<Expr, typename G0::proto_grammar>::value,
- Expr, BOOST_PP_ENUM_PARAMS(N, G)
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr BOOST_PP_ENUM_TRAILING_PARAMS(N, G)
>
             {};
 
             // handle proto::and_
- template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
- struct matches_<Expr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ template<typename Expr, typename BasicExpr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct matches_<Expr, BasicExpr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
               : detail::BOOST_PP_CAT(and_, N)<
                     BOOST_PROTO_DEFINE_MATCHES(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_MATCHES, ~)
@@ -1044,9 +1057,10 @@
             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_grammar
- , Back
- >::value
+ typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_grammar
+ , Back
+ >::value
                   , vararg_matches_impl<Args, Back, N + 1, To>
>
             {};
@@ -1054,9 +1068,10 @@
             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_grammar
- , Back
- >
+ typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_grammar
+ , Back
+ >
             {};
 
             template<
@@ -1065,26 +1080,26 @@
                 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)
- >
+ 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, ~)
>
             {};
 
- template<typename Tag, typename Args1, typename Args2>
- struct matches_< proto::basic_expr<Tag, Args1, N>, proto::basic_expr<Tag, Args2, N> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, N>, proto::basic_expr<Tag, Args2, N> >
               : BOOST_PP_CAT(and_, N)<
                     BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)
>
             {};
 
- template<typename Tag, typename Args1, typename Args2>
- struct matches_< proto::basic_expr<Tag, Args1, N>, proto::basic_expr<proto::_, Args2, N> >
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, N>, proto::basic_expr<proto::_, Args2, N> >
               : BOOST_PP_CAT(and_, N)<
                     BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)

Modified: trunk/boost/proto/proto_fwd.hpp
==============================================================================
--- trunk/boost/proto/proto_fwd.hpp (original)
+++ trunk/boost/proto/proto_fwd.hpp 2010-12-08 23:08:40 EST (Wed, 08 Dec 2010)
@@ -424,6 +424,9 @@
     template<typename T, typename Void = void>
     struct is_domain;
 
+ template<typename SubDomain, typename SuperDomain>
+ struct is_sub_domain_of;
+
     template<typename Expr>
     struct tag_of;
 

Modified: trunk/libs/proto/test/matches.cpp
==============================================================================
--- trunk/libs/proto/test/matches.cpp (original)
+++ trunk/libs/proto/test/matches.cpp 2010-12-08 23:08:40 EST (Wed, 08 Dec 2010)
@@ -102,6 +102,19 @@
 struct a_template
 {};
 
+template<typename Expr>
+struct my_expr;
+
+struct my_domain
+ : proto::domain<proto::pod_generator<my_expr> >
+{};
+
+template<typename Expr>
+struct my_expr
+{
+ BOOST_PROTO_BASIC_EXTENDS(Expr, my_expr, my_domain)
+};
+
 void test_matches()
 {
     assert_matches< _ >( lit(1) );
@@ -282,6 +295,12 @@
         a_template<int[3]> a;
         assert_matches< proto::terminal< a_template<_> > >( lit(a) );
     }
+
+ // Test that the actual derived expression type makes it through to proto::if_
+ {
+ my_expr<proto::terminal<int>::type> e = {{1}};
+ assert_matches< proto::if_<boost::is_same<domain_of<_>, my_domain>()> >( e );
+ }
 }
 
 using namespace unit_test;


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