without Karma: Live On Wandbox:
#include <boost/fusion/adapted/struct.hpp>
struct MyStruct { int a, b, c; };
BOOST_FUSION_ADAPT_STRUCT(MyStruct, c, b, a)
#include <iostream>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/as_vector.hpp>
using boost::fusion::as_vector;
int main() {
MyStruct ms { 3, 2, 1 };
std::cout << as_vector(ms) << "\n";
std::cout
<< boost::fusion::tuple_open("<")
<< boost::fusion::tuple_delimiter(",")
<< boost::fusion::tuple_close(">");
std::cout << as_vector(ms) << "\n";
}
Prints
(1 2 3)
<1,2,3>
Named adaptations: you can adapt different orders at the same time by using the *_NAMED
macros. Here's a demo that shows it both using Fusion IO and the Karma generator.
Note I slightly modified the struct so it's easier to track which field is 'a'
, 'b'
or 'c'
.
See it Live On Wandbox:
#include <boost/fusion/adapted/struct.hpp>
struct MyStruct { char a, b, c; };
BOOST_FUSION_ADAPT_STRUCT_NAMED(MyStruct, AsABC, a, b, c)
BOOST_FUSION_ADAPT_STRUCT_NAMED(MyStruct, AsBCA, b, c, a)
BOOST_FUSION_ADAPT_STRUCT_NAMED(MyStruct, AsCBA, c, b, a)
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/qi.hpp>
namespace bsk = boost::spirit::karma;
template <typename Attr, typename It = boost::spirit::ostream_iterator>
struct MyGen : bsk::grammar<It, Attr()> {
MyGen() : MyGen::base_type(start_) {
using namespace bsk;
start_ = '<' << auto_ << ',' << auto_ << ',' << auto_ << '>';
}
private:
bsk::rule<It, Attr()> start_;
};
#include <iostream>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/as_vector.hpp>
using boost::fusion::as_vector;
template <typename Attr>
void do_tests(Attr const& ms) {
std::cout << as_vector(ms) << "\n";
std::cout << format(MyGen<Attr>{}, ms) << "\n";
}
int main() {
std::cout << boost::fusion::tuple_open("<") << boost::fusion::tuple_delimiter(",") << boost::fusion::tuple_close(">");
MyStruct ms { 'a', 'b', 'c' };
using namespace boost::fusion::adapted;
do_tests(AsABC{ms});
do_tests(AsCBA{ms});
do_tests(AsBCA{ms});
}
Prints
<a,b,c>
<a,b,c>
<c,b,a>
<c,b,a>
<b,c,a>
<b,c,a>
Yes you can do without adapting (don't though):
Live On Wandbox (commenting parts because of compiletime limitations)
struct MyStruct { char a, b, c; };
namespace bsk = boost::spirit::karma;
namespace phx = boost::phoenix;
template <typename It = boost::spirit::ostream_iterator>
struct MyGen : bsk::grammar<It, MyStruct()> {
MyGen() : MyGen::base_type(start_) {
using boost::proto::deep_copy;
using namespace bsk;
auto A = deep_copy(char_[ _1 = phx::bind(&MyStruct::a, _val) ]);
auto B = deep_copy(char_[ _1 = phx::bind(&MyStruct::b, _val) ]);
auto C = deep_copy(char_[ _1 = phx::bind(&MyStruct::c, _val) ]);
start_ =
'<' << A << ',' << B << ',' << C << '>' << eol <<
'<' << A << ',' << C << ',' << B << '>' << eol <<
'<' << B << ',' << A << ',' << C << '>' << eol <<
'<' << C << ',' << A << ',' << B << '>' << eol <<
'<' << B << ',' << C << ',' << A << '>' << eol <<
'<' << C << ',' << B << ',' << A << '>' << eol
;
}
private:
bsk::rule<It, MyStruct()> start_;
};
int main() {
std::cout << format(MyGen<>{}, MyStruct { 'a', 'b', 'c' });
}
Prints
<a,b,c>
<a,c,b>
<b,a,c>
<c,a,b>
<b,c,a>
<c,b,a>