attribute2.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Hartmut Kaiser
  3. Copyright (c) 2001-2011 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #include <boost/config/warning_disable.hpp>
  8. #include <boost/detail/lightweight_test.hpp>
  9. #include <boost/spirit/include/phoenix_limits.hpp>
  10. #include <boost/fusion/include/struct.hpp>
  11. #include <boost/fusion/include/nview.hpp>
  12. #include <boost/spirit/include/qi_char.hpp>
  13. #include <boost/spirit/include/qi_string.hpp>
  14. #include <boost/spirit/include/qi_numeric.hpp>
  15. #include <boost/spirit/include/qi_operator.hpp>
  16. #include <boost/spirit/include/qi_nonterminal.hpp>
  17. #include <boost/spirit/include/qi_auxiliary.hpp>
  18. #include <iostream>
  19. #include <vector>
  20. #include <string>
  21. #include "test.hpp"
  22. ///////////////////////////////////////////////////////////////////////////////
  23. struct test_data
  24. {
  25. std::string s1;
  26. std::string s2;
  27. int i1;
  28. double d1;
  29. std::string s3;
  30. };
  31. BOOST_FUSION_ADAPT_STRUCT(
  32. test_data,
  33. (int, i1)
  34. (std::string, s1)
  35. (std::string, s2)
  36. (std::string, s3)
  37. (double, d1)
  38. )
  39. ///////////////////////////////////////////////////////////////////////////////
  40. struct test_int_data1
  41. {
  42. int i;
  43. };
  44. // we provide a custom attribute transformation taking copy of the actual
  45. // attribute value, simulating more complex type transformations
  46. namespace boost { namespace spirit { namespace traits
  47. {
  48. template <>
  49. struct transform_attribute<test_int_data1, int, qi::domain>
  50. {
  51. typedef int type;
  52. static int pre(test_int_data1& d) { return d.i; }
  53. static void post(test_int_data1& d, int i) { d.i = i; }
  54. static void fail(test_int_data1&) {}
  55. };
  56. }}}
  57. ///////////////////////////////////////////////////////////////////////////////
  58. struct test_int_data2
  59. {
  60. int i;
  61. };
  62. // we provide a simple custom attribute transformation utilizing passing the
  63. // actual attribute by reference
  64. namespace boost { namespace spirit { namespace traits
  65. {
  66. template <>
  67. struct transform_attribute<test_int_data2, int, qi::domain>
  68. {
  69. typedef int& type;
  70. static int& pre(test_int_data2& d) { return d.i; }
  71. static void post(test_int_data2&, int const&) {}
  72. static void fail(test_int_data2&) {}
  73. };
  74. }}}
  75. ///////////////////////////////////////////////////////////////////////////////
  76. int
  77. main()
  78. {
  79. using spirit_test::test_attr;
  80. namespace qi = boost::spirit::qi;
  81. namespace fusion = boost::fusion;
  82. {
  83. std::vector<test_int_data1> v;
  84. qi::rule<char const*, int()> r = qi::int_;
  85. BOOST_TEST(test_attr("1,2", r % ',', v));
  86. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  87. }
  88. {
  89. std::vector<double> v;
  90. qi::rule<char const*, int()> r = qi::int_;
  91. BOOST_TEST(test_attr("1,2", r % ',', v));
  92. BOOST_TEST(v.size() == 2 && v[0] == 1.0 && v[1] == 2.0);
  93. }
  94. {
  95. std::vector<test_int_data1> v;
  96. // this won't compile as there is no defined transformation for
  97. // test_int_data1 and double
  98. // BOOST_TEST(test_attr("1.0,2.2", qi::attr_cast(qi::double_) % ',', v));
  99. // BOOST_TEST(test_attr("1.0,2.2"
  100. // , qi::attr_cast<test_int_data1>(qi::double_) % ',', v));
  101. BOOST_TEST(test_attr("1.0,2.2"
  102. , qi::attr_cast<test_int_data1, int>(qi::double_) % ',', v));
  103. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  104. qi::rule<char const*, int()> r = qi::double_;
  105. v.clear();
  106. BOOST_TEST(test_attr("1.0,2.0", r % ',', v));
  107. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  108. }
  109. // testing explicit transformation if attribute is taken by reference
  110. {
  111. test_int_data2 d = { 0 };
  112. BOOST_TEST(test_attr("1", qi::attr_cast(qi::int_), d));
  113. BOOST_TEST(d.i == 1);
  114. BOOST_TEST(test_attr("2", qi::attr_cast<test_int_data2>(qi::int_), d));
  115. BOOST_TEST(d.i == 2);
  116. BOOST_TEST(test_attr("3", qi::attr_cast<test_int_data2, int>(qi::int_), d));
  117. BOOST_TEST(d.i == 3);
  118. }
  119. {
  120. std::vector<test_int_data2> v;
  121. BOOST_TEST(test_attr("1,2", qi::attr_cast(qi::int_) % ',', v));
  122. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  123. v.clear();
  124. BOOST_TEST(test_attr("1,2"
  125. , qi::attr_cast<test_int_data2>(qi::int_) % ',', v));
  126. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  127. v.clear();
  128. BOOST_TEST(test_attr("1,2"
  129. , qi::attr_cast<test_int_data2, int>(qi::int_) % ',', v));
  130. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  131. }
  132. {
  133. std::vector<test_int_data2> v;
  134. qi::rule<char const*, int()> r = qi::int_;
  135. BOOST_TEST(test_attr("1,2", r % ',', v));
  136. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  137. }
  138. {
  139. std::vector<test_int_data2> v;
  140. // this won't compile as there is no defined transformation for
  141. // test_int_data2 and double
  142. // BOOST_TEST(test_attr("1.0,2.2", qi::attr_cast(qi::double_) % ',', v));
  143. // BOOST_TEST(test_attr("1.0,2.2"
  144. // , qi::attr_cast<test_int_data2>(qi::double_) % ',', v));
  145. BOOST_TEST(test_attr("1.0,2.2"
  146. , qi::attr_cast<test_int_data2, int>(qi::double_) % ',', v));
  147. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  148. qi::rule<char const*, int()> r = qi::double_;
  149. v.clear();
  150. BOOST_TEST(test_attr("1.0,2.0", r % ',', v));
  151. BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
  152. }
  153. return boost::report_errors();
  154. }