I'm using boost::spirit to parse text into a struct containing a fixed size array. While following the example in
and trying to use it for parsing into a struct containing a std::array (or a boost::array) i recognised that because of how BOOST_FUSION_ADAPT_STRUCT works i have to place the helper result_of::adapt_array< some_array_type >::type in the struct as well.
I think it should be possible to create a wrapper using BOOST_FUSION_ADAPT_ADT but it seems overkill just to get rid of the little adapter overhead in the struct. As i don't have many instances of it, i can live with it from a memory point of view, but it also introduces some noise.
I also think it could be possible to create an adapter which derives from the array type rather than encapsulating it to hide some of the noise but it would force me to alter all existing structs and it would leak parser overhead to the outside which is not a nice solution.
Is there something obvious I'm approaching wrong or do exist new helpers which route the overhead in the background so that they can be encapsulated in the parser?
I'm aware of Using std::array as Attribute for boost::spirit::x3 .
Here's my current code:
#include <string>
#include <array>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
// ...code from http://www.boost.org/doc/libs/1_60_0/libs/spirit/example/qi/boost_array.cpp here
typedef result_of::adapt_array<std::array<double, 6> >::type AdaptedArrayType;
struct StructWithArray
{
StructWithArray()
: adaptedAry_(ary_)
{}
double dummy_; // see https://stackguides.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct
std::array<double, 6> ary_;
AdaptedArrayType adaptedAry_;
};
BOOST_FUSION_ADAPT_STRUCT(
StructWithArray
,
(double, dummy_)
(AdaptedArrayType, adaptedAry_)
)
template <typename Iterator, typename Skipper>
struct StructWithArrayParser
: qi::grammar<Iterator, StructWithArray(), Skipper>
{
StructWithArrayParser() : StructWithArrayParser::base_type(start)
{
using qi::double_;
arrayLine %= double_ > double_ > double_ > double_ > double_ > double_;
start %= double_ > arrayLine;
}
qi::rule<Iterator, AdaptedArrayType(), Skipper> arrayLine;
qi::rule<Iterator, StructWithArray(), Skipper> start;
};
int main() {
std::string arrayStr = "0 1 2 3 4 5 6";
std::string::const_iterator it = arrayStr.begin();
std::string::const_iterator endIt = arrayStr.end();
StructWithArrayParser<std::string::const_iterator, ascii::space_type> grammar;
StructWithArray structWithArray;
bool ret = phrase_parse(it, endIt, grammar, ascii::space, structWithArray);
return 0;
}