I took the liberty to peruse this design to redesign nt2 computation evaluation. As nt2 provides a lot of functions on its various DSL terminal, we're seeking some solution that scale - as havign 200+ case<Tag> specialization is a bit unpractical.

Soooo, despite ppl telling me dispacthing on tag cause loss of hairs and other
bad stuff, I came to the conclusion that I could use both part :
- dispatch on tag for most things
- dispatch on rules for local, AST based optimisation (turnign a*b+c into madd, or similar stuff)


Using thomas code and my own functor class , i designed a new computation transform but it fails to dispatch. Before goign further, recall that nt2::functors::functor ae generalized polymorphic function object follwoing the result_of protocol. For a given tag, functor<Tag> perform the proper operation on its arguments by forwarding the call to a call<Tag,Category> class, Category being something
discriminating the various type i want to differentiate.

So here's the transform (reuing algorithm etc from previosu post)

template<class Rule, class Actions, class Dispatch = Rule>
struct bind
: boost::proto::when< Rule
, typename Actions::template action<Dispatch>
>
{};

template<class Actions>
struct compiler : boost::proto::switch_<Actions> {};

//////////////////////////////////////////////////////////////////////////////
// computation action
//////////////////////////////////////////////////////////////////////////////
template<class Locality>
struct compute
{
template<class Tag>
struct case_
: bind< boost::proto::_
, compute
, boost::proto::tag_of<boost::proto::_>()
>
{};

//////////////////////////////////////////////////////////////////////////////
// Primary case captures any tag into appropriate functor and call it
// recursively using unpack
//////////////////////////////////////////////////////////////////////////////
template<class Case,class Dummy=void>
struct action
: boost::proto::
unpack< boost::proto::
call<functors::functor<Case,Locality>(compiler<compute>)>
>
{};
};

//////////////////////////////////////////////////////////////////////////////
// Captures terminal and forward their value, state and data to the functor
//////////////////////////////////////////////////////////////////////////////
template<class Locality> template<class Dummy>
struct compute<Locality>::action<functors::terminal_,Dummy>
: boost::proto::
call<functors::functor< functors::terminal_
, Locality
> ( boost::proto::_value
, boost::proto::_state
, boost::proto::_data
)
>
{};
} }

namespace boost { namespace proto
{
template<class Actions>
struct is_callable<nt2::dsl::compiler<Actions> > : boost::mpl::true_ {};
} }


Alas, the compiler is not happy and complain about an incompelte proto::apply_transform type:

/usr/local/include/boost-1_44/boost/proto/transform/impl.hpp:96: error: invalid use of incomplete type ‘struct boost::proto::detail::apply_transform<boost::proto::call<nt2::functors::functor<boost::proto::tag_of<boost::proto::_>(), nt2::simd::native<float, nt2::tag::sse_> >(nt2::dsl::compiler<nt2::dsl::compute<nt2::simd::native<float, nt2::tag::sse_> > >)>(nt2::simd::pack<float, 4u, boost::proto::exprns_::is_proto_expr>&, const nt2::simd::expression<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const int&>, 0l>, float, mpl_::size_t<4u>, boost::proto::exprns_::is_proto_expr>&, int, int)>’

/usr/local/include/boost-1_44/boost/proto/transform/impl.hpp:75: error: declaration of ‘struct boost::proto::detail::apply_transform<boost::proto::call<nt2::functors::functor<boost::proto::tag_of<boost::proto::_>(), nt2::simd::native<float, nt2::tag::sse_> >(nt2::dsl::compiler<nt2::dsl::compute<nt2::simd::native<float, nt2::tag::sse_> > >)>(nt2::simd::pack<float, 4u, boost::proto::exprns_::is_proto_expr>&, const nt2::simd::expression<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const int&>, 0l>, float, mpl_::size_t<4u>, boost::proto::exprns_::is_proto_expr>&, int, int)>’

Thomas and me tried to fix it but not to avail ...

Before bashing me, I strongly push the fact that tag dispatching is a valid use-case, unless anyone can provide me with such a scalable solution without ressorting to this.

As for a small reproductible example, it's currently a bit hard. You can look at the code
int he nT2 github repository (github.com/jfalcou/nt2).
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to