|
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