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_tagor by having a nestedtagtypedef in your sequence type. Neither is satisfactory for Proto.Specializing
mpl::sequence_tagis a non-starter because any type that usesproto::extendsorBOOST_PROTO_EXTENDScan be a Proto expression. This is an open set.Having a nested
tagtype 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.tagto mean something in their DSL.BTW, Fusion doesn't have this problem because it uses
fusion_taginstead of simplytag.I'm open to suggestions.