optional.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  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. =============================================================================*/
  6. #include <boost/detail/lightweight_test.hpp>
  7. #include <boost/spirit/include/qi_char.hpp>
  8. #include <boost/spirit/include/qi_numeric.hpp>
  9. #include <boost/spirit/include/qi_operator.hpp>
  10. #include <boost/spirit/include/qi_action.hpp>
  11. #include <boost/spirit/include/qi_directive.hpp>
  12. #include <boost/spirit/include/support_argument.hpp>
  13. #include <boost/spirit/include/phoenix_core.hpp>
  14. #include <boost/spirit/include/phoenix_operator.hpp>
  15. #include <boost/fusion/adapted/struct.hpp>
  16. #include <iostream>
  17. #include "test.hpp"
  18. struct adata
  19. {
  20. int a;
  21. boost::optional<int> b;
  22. };
  23. BOOST_FUSION_ADAPT_STRUCT(
  24. adata,
  25. (int, a)
  26. (boost::optional<int>, b)
  27. )
  28. struct test_attribute_type
  29. {
  30. template <typename Attribute, typename Context>
  31. void operator()(Attribute&, Context&, bool&) const
  32. {
  33. BOOST_TEST(typeid(Attribute).name() == typeid(boost::optional<int>).name());
  34. }
  35. };
  36. int
  37. main()
  38. {
  39. using spirit_test::test;
  40. using spirit_test::test_attr;
  41. using boost::spirit::qi::_1;
  42. using boost::spirit::qi::int_;
  43. using boost::spirit::qi::omit;
  44. using boost::spirit::ascii::char_;
  45. {
  46. BOOST_TEST((test("1234", -int_)));
  47. BOOST_TEST((test("abcd", -int_, false)));
  48. }
  49. { // test propagation of unused
  50. using boost::fusion::at_c;
  51. using boost::fusion::vector;
  52. vector<char, char> v;
  53. BOOST_TEST((test_attr("a1234c", char_ >> -omit[int_] >> char_, v)));
  54. BOOST_TEST((at_c<0>(v) == 'a'));
  55. BOOST_TEST((at_c<1>(v) == 'c'));
  56. v = boost::fusion::vector<char, char>();
  57. BOOST_TEST((test_attr("a1234c", char_ >> omit[-int_] >> char_, v)));
  58. BOOST_TEST((at_c<0>(v) == 'a'));
  59. BOOST_TEST((at_c<1>(v) == 'c'));
  60. char ch;
  61. BOOST_TEST((test_attr(",c", -(',' >> char_), ch)));
  62. BOOST_TEST((ch == 'c'));
  63. }
  64. { // test action
  65. boost::optional<int> n = 0;
  66. BOOST_TEST((test_attr("1234", (-int_)[test_attribute_type()], n)));
  67. BOOST_TEST((n.get() == 1234));
  68. }
  69. {
  70. std::string s;
  71. BOOST_TEST((test_attr("abc", char_ >> -(char_ >> char_), s)));
  72. BOOST_TEST(s == "abc");
  73. }
  74. {
  75. namespace phx = boost::phoenix;
  76. boost::optional<int> n = 0;
  77. BOOST_TEST((test("1234", (-int_)[phx::ref(n) = _1])));
  78. BOOST_TEST(n.get() == 1234);
  79. n = boost::optional<int>();
  80. BOOST_TEST((test("abcd", (-int_)[phx::ref(n) = _1], false)));
  81. BOOST_TEST(!n);
  82. }
  83. {
  84. std::vector<adata> v;
  85. BOOST_TEST((test_attr("a 1 2 a 2", *("a" >> int_ >> -int_), v
  86. , char_(' '))));
  87. BOOST_TEST(2 == v.size() &&
  88. 1 == v[0].a && v[0].b && 2 == *(v[0].b) &&
  89. 2 == v[1].a && !v[1].b);
  90. }
  91. return boost::report_errors();
  92. }