Say if I have a simple struct like:
struct huh { char xxx; };
Without going to Boost Fusion adapted structs, I'd like to find a simpler proxy for operating on a member variable for in a Spirit rule's semantic action. Now this, of course, doesn't work:
_val.xxx = _1
but I'd like to get a little cleaner than binding with phoenix:
bind(&huh::xxx, _val) = _1
Here is a working example of the simple picture that compiles on a clang and a g++:
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/phoenix/bind/bind_member_variable.hpp>
struct huh { char xxx; };
int main() {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;
start = qi::char_[
phx::bind(&huh::xxx, qi::_val) = qi::_1
];
return 0;
}
Any ideas?
Binding with fusion is exactly the glue to make it "a little cleaner than binding with phoenix".
So, there's your solution. Alternatively, factor your expression templates, maybe:
auto _xxx = phx::bind(&huh::xxx, _val);
So you can write:
start = char_[ _xxx = _1 ];
Alternatively, use a function or a customization point:
Adding a trait
namespace boost { namespace spirit { namespace traits {
template <> struct assign_to_attribute_from_value<huh, char, void> {
static void call(char c, huh& attr) { attr.xxx = c; }
};
} } }
You can now simply write
qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;
start = qi::char_;
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
struct huh { char xxx; };
namespace boost { namespace spirit { namespace traits {
template <> struct assign_to_attribute_from_value<huh, char, void> {
static void call(char c, huh& attr) { attr.xxx = c; }
};
} } }
int main() {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
qi::rule<std::string::const_iterator, huh(), ascii::space_type> start;
start = qi::char_;
}