attribute.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/config/warning_disable.hpp>
  6. #include <boost/detail/lightweight_test.hpp>
  7. #include <boost/spirit/include/phoenix_limits.hpp>
  8. #include <boost/fusion/include/struct.hpp>
  9. #include <boost/fusion/include/nview.hpp>
  10. #include <boost/spirit/include/karma_char.hpp>
  11. #include <boost/spirit/include/karma_string.hpp>
  12. #include <boost/spirit/include/karma_numeric.hpp>
  13. #include <boost/spirit/include/karma_operator.hpp>
  14. #include <boost/spirit/include/karma_nonterminal.hpp>
  15. #include <boost/spirit/include/karma_auxiliary.hpp>
  16. #include "test.hpp"
  17. using namespace spirit_test;
  18. ///////////////////////////////////////////////////////////////////////////////
  19. struct test_data
  20. {
  21. std::string s1;
  22. std::string s2;
  23. int i1;
  24. double d1;
  25. std::string s3;
  26. };
  27. BOOST_FUSION_ADAPT_STRUCT(
  28. test_data,
  29. (int, i1)
  30. (std::string, s1)
  31. (std::string, s2)
  32. (std::string, s3)
  33. (double, d1)
  34. )
  35. ///////////////////////////////////////////////////////////////////////////////
  36. // this is just a test structure we need to use in place of an int
  37. struct test_int_data1
  38. {
  39. int i;
  40. };
  41. // so we provide a custom attribute transformation
  42. namespace boost { namespace spirit { namespace traits
  43. {
  44. template <>
  45. struct transform_attribute<test_int_data1 const, int, karma::domain>
  46. {
  47. typedef int type;
  48. static int pre(test_int_data1 const& d) { return d.i; }
  49. };
  50. }}}
  51. ///////////////////////////////////////////////////////////////////////////////
  52. // this is another test structure we need to use in place of an int, but this
  53. // time we use a reference to the embedded element
  54. struct test_int_data2
  55. {
  56. int i;
  57. };
  58. // so we provide a custom attribute transformation
  59. namespace boost { namespace spirit { namespace traits
  60. {
  61. template <>
  62. struct transform_attribute<test_int_data2 const, int, karma::domain>
  63. {
  64. typedef int const& type;
  65. static int const& pre(test_int_data2 const& d) { return d.i; }
  66. };
  67. }}}
  68. ///////////////////////////////////////////////////////////////////////////////
  69. int main()
  70. {
  71. namespace fusion = boost::fusion;
  72. namespace karma = boost::spirit::karma;
  73. test_data d1 = { "s11", "s12", 1, 2.5, "s13" };
  74. {
  75. BOOST_TEST(test("s121",
  76. karma::string << karma::int_,
  77. fusion::as_nview<2, 0>(d1)));
  78. BOOST_TEST(test_delimited("s12 1 ",
  79. karma::string << karma::int_,
  80. fusion::as_nview<2, 0>(d1), ' '));
  81. }
  82. {
  83. test_data d2 = { "s21", "s22", 2, 3.4, "s23" };
  84. typedef fusion::result_of::as_nview<test_data const, 1, 2, 4>::type
  85. test_view;
  86. std::vector<test_data> v;
  87. v.push_back(d1);
  88. v.push_back(d2);
  89. karma::rule<output_iterator<char>::type, test_view()> r =
  90. karma::string << karma::string << karma::double_;
  91. BOOST_TEST(test("s11s122.5\ns21s223.4", r % karma::eol, v));
  92. BOOST_TEST(test_delimited("s11s122.5 \n s21s223.4 ",
  93. r % karma::eol, v, ' '));
  94. }
  95. {
  96. test_int_data1 d = { 1 };
  97. BOOST_TEST(test("1", karma::attr_cast(karma::int_), d));
  98. BOOST_TEST(test("1", karma::attr_cast<test_int_data1>(karma::int_), d));
  99. BOOST_TEST(test("1", karma::attr_cast<test_int_data1, int>(karma::int_), d));
  100. }
  101. {
  102. test_int_data1 d[] = {{ 1 }, { 2 }};
  103. std::vector<test_int_data1> v;
  104. v.push_back(d[0]);
  105. v.push_back(d[1]);
  106. BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v));
  107. BOOST_TEST(test("1,2"
  108. , karma::attr_cast<test_int_data1>(karma::int_) % ',', v));
  109. BOOST_TEST(test("1,2"
  110. , karma::attr_cast<test_int_data1, int>(karma::int_) % ',', v));
  111. }
  112. {
  113. test_int_data1 d[] = {{ 1 }, { 2 }};
  114. std::vector<test_int_data1> v;
  115. v.push_back(d[0]);
  116. v.push_back(d[1]);
  117. karma::rule<output_iterator<char>::type, int()> r = karma::int_;
  118. BOOST_TEST(test("1,2", r % ',', v));
  119. }
  120. {
  121. test_int_data1 d[] = {{ 1 }, { 2 }};
  122. std::vector<test_int_data1> v;
  123. v.push_back(d[0]);
  124. v.push_back(d[1] );
  125. // this won't compile as there is no defined transformation for
  126. // test_int_data1 and double
  127. // BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v));
  128. // BOOST_TEST(test("1.0,2.0"
  129. // , karma::attr_cast<test_int_data1>(karma::double_) % ',', v));
  130. BOOST_TEST(test("1.0,2.0"
  131. , karma::attr_cast<test_int_data1, int>(karma::double_) % ',', v));
  132. karma::rule<output_iterator<char>::type, int()> r = karma::double_;
  133. BOOST_TEST(test("1.0,2.0", r % ',', v));
  134. }
  135. {
  136. test_int_data2 d = { 1 };
  137. BOOST_TEST(test("1", karma::attr_cast(karma::int_), d));
  138. BOOST_TEST(test("1", karma::attr_cast<test_int_data2>(karma::int_), d));
  139. BOOST_TEST(test("1", karma::attr_cast<test_int_data2, int>(karma::int_), d));
  140. }
  141. {
  142. test_int_data2 d[] = {{ 1 }, { 2 }};
  143. std::vector<test_int_data2> v;
  144. v.push_back(d[0]);
  145. v.push_back(d[1]);
  146. BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v));
  147. BOOST_TEST(test("1,2"
  148. , karma::attr_cast<test_int_data2>(karma::int_) % ',', v));
  149. BOOST_TEST(test("1,2"
  150. , karma::attr_cast<test_int_data2, int>(karma::int_) % ',', v));
  151. }
  152. {
  153. test_int_data2 d[] = {{ 1 }, { 2 }};
  154. std::vector<test_int_data2> v;
  155. v.push_back(d[0]);
  156. v.push_back(d[1]);
  157. karma::rule<output_iterator<char>::type, int()> r = karma::int_;
  158. BOOST_TEST(test("1,2", r % ',', v));
  159. }
  160. {
  161. test_int_data2 d[] = {{ 1 }, { 2 }};
  162. std::vector<test_int_data2> v;
  163. v.push_back(d[0]);
  164. v.push_back(d[1] );
  165. // this won't compile as there is no defined transformation for
  166. // test_int_data2 and double
  167. // BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v));
  168. // BOOST_TEST(test("1.0,2.0"
  169. // , karma::attr_cast<test_int_data2>(karma::double_) % ',', v));
  170. BOOST_TEST(test("1.0,2.0"
  171. , karma::attr_cast<test_int_data2, int>(karma::double_) % ',', v));
  172. karma::rule<output_iterator<char>::type, int()> r = karma::double_;
  173. BOOST_TEST(test("1.0,2.0", r % ',', v));
  174. }
  175. return boost::report_errors();
  176. }