How can I obtain the types of the local variables used within a scoped Boost Phoenix statement? Using Phoenix and Proto I can extract numerous aspects of a Phoenix expression. For example, the following code exposes the arity (3); tag type (lambda_actor); and child-2 tag type (shift_left) of a Phoenix lambda expression:
#include <boost/proto/proto.hpp>
#include <boost/phoenix.hpp>
namespace proto = boost::proto;
namespace phoenix = boost::phoenix;
using namespace phoenix::local_names;
struct Foo { const char str[6] = " Ok.\n"; };
int main(int argc, char *argv[])
{
auto f = phoenix::lambda(_a = 17, _b = Foo()) [
std::cout << _a << phoenix::bind(&Foo::str,_b)
];
typedef typename proto::tag_of<decltype( f )>::type tag;
typedef typename proto::tag_of<decltype(proto::child_c<2>(f))>::type tagc;
static_assert(proto::arity_of<decltype(f)>::value==3,"");
static_assert(std::is_same<tag, phoenix::tag::lambda_actor>::value,"");
static_assert(std::is_same<tagc, proto::tag::shift_left>::value,"");
return 0;
}
How can I obtain the types of the local variables; in this example: _a and _b?
I'm assuming that the types you are interested in are
intandFoo, if this is not what you are after please disregard this answer. Looking over the documentation I haven't been able to find an easy way to get these types. But if you look at the type of the proto expression stored infyou can see thatintandFoocan be found in a vector of actors inside the first child. The steps you need to make to finally get to the interesting types can be seen in the output and following that you can easily create a metafunction that does what you want. In this simple caseget_local_typeuses an index to access the type in question. If you want to access it via name (using_a) you should be able to get the index associated with a name using the data inmap_local_index_to_tuplein the second child of the lambda expression. Usingphoenix::detail::get_indexthat is defined here implementingget_local_type_from_nameis also pretty easy. This metafunction expects the map mentioned above as its first argument and the type of the placeholder you want information from (more specifically it needsphoenix::detail::local<phoenix::local_names::_a_key>, and you can get that usingproto::result_of::valueon the type of the placeholder) as its second.