私は boost::spirit を使用して、テキストを固定サイズの配列を含む構造体に解析しています。の例に従いながら
std::array (またはboost::array) を含む構造体に解析するためにそれを使用しようとすると、BOOST_FUSION_ADAPT_STRUCTがどのように機能するかのために、ヘルパーresult_of::adapt_array< some_array_type >::typeを構造体も。
BOOST_FUSION_ADAPT_ADTを使用してラッパーを作成することは可能だと思いますが、構造体の小さなアダプター オーバーヘッドを取り除くだけではやり過ぎのようです。私はそれの多くのインスタンスを持っていないので、メモリの観点からそれと一緒に暮らすことができますが、ノイズも発生します.
また、ノイズの一部を隠すために配列型をカプセル化するのではなく、配列型から派生するアダプターを作成することも可能だと思いますが、既存のすべての構造体を変更する必要があり、パーサーのオーバーヘッドが外部に漏れます。いい解決策。
私が間違っていることは明らかですか、それともパーサーにカプセル化できるようにバックグラウンドでオーバーヘッドをルーティングする新しいヘルパーが存在しますか?
Boost::spirit::x3 の属性として std::array を使用することを認識して います。
これが私の現在のコードです:
#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://stackoverflow.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;
}