Opened 10 years ago
Closed 10 years ago
#7254 closed Bugs (fixed)
Proto expressions are not MPL sequences
Reported by: | Mathias Gaunard | Owned by: | Eric Niebler |
---|---|---|---|
Milestone: | To Be Determined | Component: | proto |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: |
Description
Proto expressions are not MPL sequences. It is arguably possible to get a MPL sequence by using boost::fusion::result_of::as_vector, but this may have undesirable overhead.
Change History (7)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
I don't mind adding the tag in my expressions myself.
But
typedef boost::fusion::fusion_sequence_tag tag;
doesn't work.
It says there is no convert_impl
for the proto expression tag.
comment:3 by , 10 years ago
The following works just fine for me:
#include <iostream> #include <typeinfo> #include <boost/proto/proto.hpp> #include <boost/fusion/mpl.hpp> #include <boost/mpl/for_each.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/type_traits/remove_reference.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; namespace fusion = boost::fusion; template<class E> struct my_expr; struct my_domain : proto::domain<proto::generator<my_expr> > {}; template<class E> struct my_expr : proto::extends<E, my_expr<E>, my_domain> { my_expr(E const &e = E()) : proto::extends<E, my_expr<E>, my_domain>(e) {} typedef fusion::fusion_sequence_tag tag; }; struct noop { typedef void result_type; template<typename T> void operator()(T const &) const { std::cout << typeid(T).name() << std::endl; } }; int main() { my_expr<proto::terminal<int>::type> i; mpl::for_each<decltype(i + i), boost::remove_reference<mpl::_1> >(noop()); }
comment:4 by , 10 years ago
Try calling mpl::pop_back
on that type, I get the following error:
invalid use of incomplete type `struct boost::fusion::extension::convert_impl<boost::proto::tagns_::tag::proto_expr>'
comment:5 by , 10 years ago
Interesting. Looks like an undocumented Fusion customization point. I can guess what it's supposed to do, but I'm following up on the boost list about it. At the very least, it's a bug in Fusion's docs. Let's wait and see what Joel says.
comment:7 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I've wanted to do this, but there's a snag. MPL sequences use tag dispatching. You can get the tag of an MPL sequence either by specializing
mpl::sequence_tag
or by having a nestedtag
typedef in your sequence type. Neither is satisfactory for Proto.Specializing
mpl::sequence_tag
is a non-starter because any type that usesproto::extends
orBOOST_PROTO_EXTENDS
can be a Proto expression. This is an open set.Having a nested
tag
type is a non-starter because expressions are part of end-users' APIs, and Proto shouldn't be claiming such a common identifier for itself. Someone might wante.tag
to mean something in their DSL.BTW, Fusion doesn't have this problem because it uses
fusion_tag
instead of simplytag
.I'm open to suggestions.