Say I have a struct like so:
struct MyStruct
{
int a;
int b;
int c;
}
BOOST_FUSION_ADAPT_STRUCT
(
MyStruct,
(int, a)
(int, b)
(int, c)
)
And then if I have a simple generator:
struct MyStructGenerator
: boost::spirit::karma::grammar<boost::spirit::ostream_iterator, MyStruct()>
{
MyStructGenerator() : MyStructGenerator::base_type(start_)
{
namespace bsk = boost::spirit::karma;
start_ = '<'
<< bsk::int_
<< ','
<< bsk::int_
<< ','
<< bsk::int_
<< '>';
}
~MyStructGenerator() = default;
boost::spirit::karma::rule<boost::spirit::ostream_iterator, MyStruct()> start_;
};
And I run the following:
int main()
{
MyStruct ms = { 3, 2, 1 };
std::cout << boost::spirit::karma::format(MyStructGenerator(), ms) << std::endl;
}
I, of course, expect to see <3, 2, 1>
. What I cannot figure out is how to change the order within the rule? What if I wanted to see <1, 2, 3>
or even if I wanted to see <2, 1, 3>
?
Also, is there anyway I could do this without BOOST_FUSION_ADAPT_STRUCT
?
You could simply use phoenix and bind to access the member values. So for your example to swap the member it would be like this:
#include <iostream>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/phoenix/bind/bind_member_variable.hpp>
using namespace std;
struct MyStruct {
int a;
int b;
int c;
};
struct MyStructGenerator : boost::spirit::karma::grammar<boost::spirit::ostream_iterator, MyStruct()>
{
MyStructGenerator() : MyStructGenerator::base_type(start_)
{
namespace bsk = boost::spirit::karma;
start_ = '<'
<< bsk::int_[bsk::_1 = boost::phoenix::bind(&MyStruct::c, bsk::_val)]
<< ','
<< bsk::int_[bsk::_1 = boost::phoenix::bind(&MyStruct::b, bsk::_val)]
<< ','
<< bsk::int_[bsk::_1 = boost::phoenix::bind(&MyStruct::a, bsk::_val)]
<< '>';
}
~MyStructGenerator() = default;
boost::spirit::karma::rule<boost::spirit::ostream_iterator, MyStruct()> start_;
};
int main() {
MyStruct ms = { 3, 2, 1 };
std::cout << boost::spirit::karma::format(MyStructGenerator(), ms) << std::endl;
}