fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <array>
  4. #include <boost/spirit/include/qi.hpp>
  5. #include <boost/fusion/adapted/struct/adapt_struct.hpp>
  6. #include <boost/fusion/include/adapt_struct.hpp>
  7.  
  8. namespace qi = boost::spirit::qi;
  9. namespace ascii = boost::spirit::ascii;
  10.  
  11.  
  12. // ...code from http://w...content-available-to-author-only...t.org/doc/libs/1_60_0/libs/spirit/example/qi/boost_array.cpp here
  13. ////////////////////////////////////////////////////////////////////////////////////////////////
  14.  
  15. namespace detail
  16. {
  17. template <typename T>
  18. struct adapt_array;
  19.  
  20. template <typename T, std::size_t N>
  21. struct adapt_array<std::array<T, N> >
  22. {
  23. typedef std::array<T, N> array_type;
  24.  
  25. adapt_array(array_type& arr)
  26. : arr_(arr), current_(0) {}
  27.  
  28. // expose a push_back function compatible with std containers
  29. bool push_back(typename array_type::value_type const& val)
  30. {
  31. // if the array is full, we need to bail out
  32. // returning false will fail the parse
  33. if (current_ >= N)
  34. return false;
  35.  
  36. arr_[current_++] = val;
  37. return true;
  38. }
  39.  
  40. array_type& arr_;
  41. std::size_t current_;
  42. };
  43. }
  44.  
  45. namespace result_of
  46. {
  47. template <typename T>
  48. struct adapt_array;
  49.  
  50. template <typename T, std::size_t N>
  51. struct adapt_array<std::array<T, N> >
  52. {
  53. typedef detail::adapt_array<std::array<T, N> > type;
  54. };
  55. }
  56.  
  57. template <typename T, std::size_t N>
  58. inline detail::adapt_array<std::array<T, N> >
  59. adapt_array(std::array<T, N>& arr)
  60. {
  61. return detail::adapt_array<std::array<T, N> >(arr);
  62. }
  63.  
  64.  
  65. // specialize Spirit's container specific customization points for our adaptor
  66. namespace boost { namespace spirit { namespace traits
  67. {
  68. template <typename T, std::size_t N>
  69. struct is_container<::detail::adapt_array<std::array<T, N> > >
  70. : boost::mpl::true_
  71. {};
  72.  
  73. template <typename T, std::size_t N>
  74. struct container_value<::detail::adapt_array<std::array<T, N> > >
  75. {
  76. typedef T type; // value type of container
  77. };
  78.  
  79. template <typename T, std::size_t N>
  80. struct push_back_container<
  81. ::detail::adapt_array<std::array<T, N> >, T>
  82. {
  83. static bool call(::detail::adapt_array<std::array<T, N> >& c
  84. , T const& val)
  85. {
  86. return c.push_back(val);
  87. }
  88. };
  89. }}}
  90.  
  91.  
  92. // test
  93.  
  94. typedef result_of::adapt_array<std::array<double, 6> >::type AdaptedArrayType;
  95.  
  96. struct StructWithArray
  97. {
  98. StructWithArray()
  99. : adaptedAry_(ary_)
  100. {}
  101.  
  102. double dummy_; // see http://stackoverflow.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct
  103. std::array<double, 6> ary_;
  104. AdaptedArrayType adaptedAry_;
  105. };
  106.  
  107. BOOST_FUSION_ADAPT_STRUCT(
  108. StructWithArray
  109. ,
  110. (double, dummy_)
  111. (AdaptedArrayType, adaptedAry_)
  112. )
  113.  
  114. template <typename Iterator, typename Skipper>
  115. struct StructWithArrayParser
  116. : qi::grammar<Iterator, StructWithArray(), Skipper>
  117. {
  118. StructWithArrayParser() : StructWithArrayParser::base_type(start)
  119. {
  120. using qi::double_;
  121.  
  122. arrayLine %= double_ > double_ > double_ > double_ > double_ > double_;
  123. start %= double_ > arrayLine;
  124. }
  125.  
  126. qi::rule<Iterator, AdaptedArrayType(), Skipper> arrayLine;
  127. qi::rule<Iterator, StructWithArray(), Skipper> start;
  128. };
  129.  
  130. int main() {
  131. std::string arrayStr = "0 1 2 3 4 5 6";
  132. std::string::const_iterator it = arrayStr.begin();
  133. std::string::const_iterator endIt = arrayStr.end();
  134. StructWithArrayParser<std::string::const_iterator, ascii::space_type> grammar;
  135. StructWithArray structWithArray;
  136. bool ret = phrase_parse(it, endIt, grammar, ascii::space, structWithArray);
  137. std::cout << ret << " " << structWithArray.ary_[0] << " " << structWithArray.ary_[5];
  138. return 0;
  139. }
  140.  
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
1 1 6