auto.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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/fusion/include/std_pair.hpp>
  8. #include <boost/algorithm/string/predicate.hpp>
  9. #include <boost/spirit/include/qi_bool.hpp>
  10. #include <boost/spirit/include/qi_char.hpp>
  11. #include <boost/spirit/include/qi_numeric.hpp>
  12. #include <boost/spirit/include/qi_string.hpp>
  13. #include <boost/spirit/include/qi_nonterminal.hpp>
  14. #include <boost/spirit/include/qi_operator.hpp>
  15. #include <boost/spirit/include/qi_directive.hpp>
  16. #include <boost/spirit/include/qi_auto.hpp>
  17. #include "test.hpp"
  18. namespace qi = boost::spirit::qi;
  19. namespace traits = boost::spirit::traits;
  20. ///////////////////////////////////////////////////////////////////////////////
  21. template <typename Char, typename T>
  22. bool test_create_parser(Char const *in, T& t)
  23. {
  24. Char const* last = in;
  25. while (*last)
  26. last++;
  27. BOOST_TEST((traits::meta_create_exists<qi::domain, T>::value));
  28. return qi::phrase_parse(in, last, qi::create_parser<T>(), qi::space, t);
  29. }
  30. template <typename Char, typename T>
  31. bool test_create_parser_auto(Char const *in, T& t)
  32. {
  33. Char const* last = in;
  34. while (*last)
  35. last++;
  36. BOOST_TEST((traits::meta_create_exists<qi::domain, T>::value));
  37. return qi::phrase_parse(in, last, t, qi::space);
  38. }
  39. template <typename Char, typename Attribute>
  40. bool test_rule(Char const* in, Attribute const& expected)
  41. {
  42. BOOST_TEST((traits::meta_create_exists<qi::domain, Attribute>::value));
  43. Attribute attr = Attribute();
  44. qi::rule<Char const*, Attribute()> r = qi::create_parser<Attribute>();
  45. return spirit_test::test_attr(in, r, attr) && attr == expected;
  46. }
  47. template <typename Char, typename Attribute, typename Skipper>
  48. bool test_rule(Char const* in, Attribute const& expected, Skipper const& skipper)
  49. {
  50. BOOST_TEST((traits::meta_create_exists<qi::domain, Attribute>::value));
  51. Attribute attr = Attribute();
  52. qi::rule<Char const*, Attribute(), Skipper> r = qi::create_parser<Attribute>();
  53. return spirit_test::test_attr(in, r, attr, skipper) && attr == expected;
  54. }
  55. struct my_type {};
  56. ///////////////////////////////////////////////////////////////////////////////
  57. int main()
  58. {
  59. {
  60. BOOST_TEST((!traits::meta_create_exists<qi::domain, my_type>::value));
  61. }
  62. {
  63. // test primitive types
  64. bool b = false;
  65. BOOST_TEST(test_create_parser("true", b) && b == true);
  66. int i = 0;
  67. BOOST_TEST(test_create_parser("1", i) && i == 1);
  68. double d = 0;
  69. BOOST_TEST(test_create_parser("1.1", d) && d == 1.1);
  70. char c = '\0';
  71. BOOST_TEST(test_create_parser("a", c) && c == 'a');
  72. wchar_t wc = L'\0';
  73. BOOST_TEST(test_create_parser(L"a", wc) && wc == L'a');
  74. // test containers
  75. std::vector<int> v;
  76. BOOST_TEST(test_create_parser("0 1 2", v) && v.size() == 3 &&
  77. v[0] == 0 && v[1] == 1 && v[2] == 2);
  78. std::list<int> l;
  79. BOOST_TEST(test_create_parser("0 1 2", l) && l.size() == 3 &&
  80. *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
  81. // test optional
  82. boost::optional<int> o;
  83. BOOST_TEST(test_create_parser("", o) && !o);
  84. BOOST_TEST(test_create_parser("1", o) && !!o && boost::get<int>(o) == 1);
  85. // test alternative
  86. boost::variant<double, bool, std::vector<char> > vv;
  87. BOOST_TEST(test_create_parser("true", vv) && vv.which() == 1 &&
  88. boost::get<bool>(vv) == true);
  89. BOOST_TEST(test_create_parser("1.0", vv) && vv.which() == 0 &&
  90. boost::get<double>(vv) == 1.0);
  91. BOOST_TEST(test_create_parser("some_string", vv) && vv.which() == 2 &&
  92. boost::equals(boost::get<std::vector<char> >(vv), "some_string"));
  93. // test fusion sequence
  94. std::pair<int, double> p;
  95. BOOST_TEST(test_create_parser("1 2.0", p) &&
  96. p.first == 1 && p.second == 2.0);
  97. }
  98. {
  99. // test containers
  100. std::vector<int> v;
  101. BOOST_TEST(test_create_parser_auto("0 1 2", v) && v.size() == 3 &&
  102. v[0] == 0 && v[1] == 1 && v[2] == 2);
  103. std::list<int> l;
  104. BOOST_TEST(test_create_parser_auto("0 1 2", l) && l.size() == 3 &&
  105. *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
  106. // test optional
  107. boost::optional<int> o;
  108. BOOST_TEST(test_create_parser_auto("", o) && !o);
  109. BOOST_TEST(test_create_parser_auto("1", o) && !!o && boost::get<int>(o) == 1);
  110. // test alternative
  111. boost::variant<double, bool, std::vector<char> > vv;
  112. BOOST_TEST(test_create_parser_auto("true", vv) && vv.which() == 1 &&
  113. boost::get<bool>(vv) == true);
  114. BOOST_TEST(test_create_parser_auto("1.0", vv) && vv.which() == 0 &&
  115. boost::get<double>(vv) == 1.0);
  116. BOOST_TEST(test_create_parser_auto("some_string", vv) && vv.which() == 2 &&
  117. boost::equals(boost::get<std::vector<char> >(vv), "some_string"));
  118. // test fusion sequence
  119. std::pair<int, double> p;
  120. BOOST_TEST(test_create_parser_auto("1 2.0", p) &&
  121. p.first == 1 && p.second == 2.0);
  122. }
  123. {
  124. using qi::auto_;
  125. using qi::no_case;
  126. using spirit_test::test_attr;
  127. // test primitive types
  128. bool b = false;
  129. BOOST_TEST(test_attr("true", auto_, b) && b == true);
  130. int i = 0;
  131. BOOST_TEST(test_attr("1", auto_, i) && i == 1);
  132. double d = 0;
  133. BOOST_TEST(test_attr("1.1", auto_, d) && d == 1.1);
  134. char c = '\0';
  135. BOOST_TEST(test_attr("a", auto_, c) && c == 'a');
  136. wchar_t wc = L'\0';
  137. BOOST_TEST(test_attr(L"a", auto_, wc) && wc == L'a');
  138. b = false;
  139. BOOST_TEST(test_attr("TRUE", no_case[auto_], b) && b == true);
  140. // test containers
  141. std::vector<int> v;
  142. BOOST_TEST(test_attr("0 1 2", auto_, v, qi::space) && v.size() == 3 &&
  143. v[0] == 0 && v[1] == 1 && v[2] == 2);
  144. v.clear();
  145. BOOST_TEST(test_attr("0,1,2", auto_ % ',', v) && v.size() == 3 &&
  146. v[0] == 0 && v[1] == 1 && v[2] == 2);
  147. std::list<int> l;
  148. BOOST_TEST(test_attr("0 1 2", auto_, l, qi::space) && l.size() == 3 &&
  149. *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
  150. l.clear();
  151. BOOST_TEST(test_attr("0,1,2", auto_ % ',', l) && l.size() == 3 &&
  152. *l.begin() == 0 && *(++l.begin()) == 1 && *(++ ++l.begin()) == 2);
  153. // test optional
  154. boost::optional<int> o;
  155. BOOST_TEST(test_attr("", auto_, o) && !o);
  156. BOOST_TEST(test_attr("1", auto_, o) && !!o && boost::get<int>(o) == 1);
  157. // test alternative
  158. boost::variant<double, bool, std::vector<char> > vv;
  159. BOOST_TEST(test_attr("true", auto_, vv) && vv.which() == 1 &&
  160. boost::get<bool>(vv) == true);
  161. BOOST_TEST(test_attr("1.0", auto_, vv) && vv.which() == 0 &&
  162. boost::get<double>(vv) == 1.0);
  163. BOOST_TEST(test_create_parser("some_string", vv) && vv.which() == 2 &&
  164. boost::equals(boost::get<std::vector<char> >(vv), "some_string"));
  165. // test fusion sequence
  166. std::pair<int, double> p;
  167. BOOST_TEST(test_attr("1 2.0", auto_, p, qi::space) &&
  168. p.first == 1 && p.second == 2.0);
  169. }
  170. {
  171. // test primitive types
  172. BOOST_TEST(test_rule("true", true));
  173. BOOST_TEST(test_rule("1", 1));
  174. BOOST_TEST(test_rule("1.1", 1.1));
  175. // test containers
  176. std::vector<int> v;
  177. v.push_back(0);
  178. v.push_back(1);
  179. v.push_back(2);
  180. BOOST_TEST(test_rule("0 1 2", v, qi::space));
  181. std::list<int> l;
  182. l.push_back(0);
  183. l.push_back(1);
  184. l.push_back(2);
  185. BOOST_TEST(test_rule("0 1 2", l, qi::space));
  186. // test optional
  187. boost::optional<int> o;
  188. BOOST_TEST(test_rule("", o));
  189. o = 1;
  190. BOOST_TEST(test_rule("1", o));
  191. // test alternative
  192. // boost::variant<int, double, float, std::string> vv;
  193. // vv = 1;
  194. // BOOST_TEST(test_rule("1", vv));
  195. // vv = 1.0;
  196. // BOOST_TEST(test_rule("1.0", vv));
  197. // vv = 1.0f;
  198. // BOOST_TEST(test_rule("1.0", vv));
  199. // vv = "some string";
  200. // BOOST_TEST(test_rule("some string", vv));
  201. // test fusion sequence
  202. std::pair<int, double> p (1, 2.0);
  203. BOOST_TEST(test_rule("1 2.0", p, qi::space));
  204. }
  205. return boost::report_errors();
  206. }