fork(1) download
  1. #include <boost/spirit/include/qi.hpp>
  2. #include <boost/fusion/include/define_struct.hpp>
  3.  
  4. #include <string>
  5.  
  6. namespace yak { namespace spirit {
  7.  
  8. // Dummy type for csv separator
  9. // Using to make use of original meta_create_sequence implementation
  10. struct csv_separator {};
  11.  
  12. namespace detail {
  13.  
  14. // extracted from boost/spirit/home/support/auto/meta_create.hpp (v1.46)
  15. template <typename T>
  16. struct is_fusion_sequence_but_not_proto_expr
  17. : boost::mpl::and_<
  18. boost::fusion::traits::is_sequence<T>
  19. , boost::mpl::not_<boost::proto::is_expr<T> > >
  20. {};
  21. }
  22.  
  23. }}
  24.  
  25. namespace boost { namespace spirit { namespace traits {
  26.  
  27. // deep_copy may be unnecessary...
  28.  
  29. // specialization for csv_separator
  30. template<>
  31. struct create_parser<yak::spirit::csv_separator>
  32. {
  33. typedef proto::result_of::deep_copy<
  34. BOOST_TYPEOF(qi::lit(','))
  35. >::type type;
  36.  
  37. static type call()
  38. {
  39. return proto::deep_copy(qi::lit(','));
  40. }
  41. };
  42.  
  43. // specialization for std::string
  44. template<>
  45. struct create_parser<std::string>
  46. {
  47. typedef proto::result_of::deep_copy<
  48. BOOST_TYPEOF(*(qi::char_ - qi::lit(',')))
  49. >::type type;
  50.  
  51. static type call()
  52. {
  53. return proto::deep_copy(*(qi::char_ - qi::lit(',')));
  54. }
  55. };
  56.  
  57. // specialization for Fusion Sequence
  58. // meta_create_sequence with slight modification
  59. template <typename Sequence>
  60. struct create_parser<Sequence, typename boost::enable_if<
  61. yak::spirit::detail::is_fusion_sequence_but_not_proto_expr<Sequence>
  62. >::type>
  63. {
  64.  
  65. // create a mpl sequence from the given fusion sequence
  66. typedef typename mpl::fold<
  67. typename fusion::result_of::as_vector<Sequence>::type
  68. , mpl::vector<>, mpl::push_back<mpl::push_back<mpl::_1, mpl::_2>, yak::spirit::csv_separator>
  69. >::type sequence_type_;
  70. typedef typename mpl::if_<mpl::empty<sequence_type_>, sequence_type_, typename mpl::pop_back<sequence_type_>::type>::type sequence_type;
  71.  
  72. typedef make_nary_proto_expr<
  73. sequence_type, proto::tag::shift_right, qi::domain
  74. > make_proto_expr;
  75.  
  76. typedef typename make_proto_expr::type type;
  77.  
  78. static type call()
  79. {
  80. return make_proto_expr::call();
  81. }
  82. };
  83.  
  84.  
  85. }}}
  86.  
  87. // BOOST_FUSION_DEFINE_STRUCT has the same effect as struct definition and BOOST_FUSION_ADAPT_STRUCT.
  88. BOOST_FUSION_DEFINE_STRUCT(
  89. (), // places global namespace
  90. data,
  91. (std::string, namae)
  92. (int, wanryoku)
  93. (int, kiyosa)
  94. (int, subayasa)
  95. (int, tairyoku)
  96. (int, maryoku)
  97. (int, seishin)
  98. (int, miryoku)
  99. )
  100.  
  101. BOOST_FUSION_DEFINE_STRUCT(
  102. (), // places global namespace
  103. data2,
  104. (std::string, namae)
  105. (std::string, namae2)
  106. (int, wanryoku)
  107. (int, kiyosa)
  108. (int, subayasa)
  109. (int, tairyoku)
  110. (int, maryoku)
  111. (int, seishin)
  112. (int, miryoku)
  113. )
  114.  
  115. template<typename Attr>
  116. void test_parse(const std::string &s, Attr &attr)
  117. {
  118. namespace qi = boost::spirit::qi;
  119.  
  120. typedef std::string::const_iterator Iterator;
  121. Iterator first = s.begin(), last = s.end();
  122.  
  123. qi::phrase_parse(first, last, qi::auto_, qi::space, attr);
  124. boost::fusion::out(std::cout, attr); // output as fusion sequence
  125. std::cout << std::endl;
  126. }
  127.  
  128. int main()
  129. {
  130. data d;
  131. test_parse("Name1, 21, 12, 20, 17, 15, 19, 20", d);
  132.  
  133. data2 d2;
  134. test_parse("Name1, Name2, 21, 12, 20, 17, 15, 19, 20", d2);
  135.  
  136. return 0;
  137. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty