optional.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*=============================================================================
  2. Copyright (c) 2001-2015 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/home/x3.hpp>
  8. #include <boost/fusion/adapted/struct.hpp>
  9. #include <boost/fusion/include/vector.hpp>
  10. #include <iostream>
  11. #include "test.hpp"
  12. #include "utils.hpp"
  13. struct adata
  14. {
  15. int a;
  16. boost::optional<int> b;
  17. };
  18. BOOST_FUSION_ADAPT_STRUCT(adata,
  19. a, b
  20. )
  21. struct test_attribute_type
  22. {
  23. template <typename Context>
  24. void operator()(Context& ctx) const
  25. {
  26. BOOST_TEST(typeid(decltype(_attr(ctx))).name() == typeid(boost::optional<int>).name());
  27. }
  28. };
  29. int
  30. main()
  31. {
  32. using boost::spirit::x3::traits::is_optional;
  33. static_assert(is_optional<boost::optional<int>>(), "is_optional problem");
  34. using spirit_test::test;
  35. using spirit_test::test_attr;
  36. using boost::spirit::x3::int_;
  37. using boost::spirit::x3::omit;
  38. using boost::spirit::x3::ascii::char_;
  39. {
  40. BOOST_TEST((test("1234", -int_)));
  41. BOOST_TEST((test("abcd", -int_, false)));
  42. }
  43. { // test propagation of unused
  44. using boost::fusion::at_c;
  45. using boost::fusion::vector;
  46. vector<char, char> v;
  47. BOOST_TEST((test_attr("a1234c", char_ >> -omit[int_] >> char_, v)));
  48. BOOST_TEST((at_c<0>(v) == 'a'));
  49. BOOST_TEST((at_c<1>(v) == 'c'));
  50. v = boost::fusion::vector<char, char>();
  51. BOOST_TEST((test_attr("a1234c", char_ >> omit[-int_] >> char_, v)));
  52. BOOST_TEST((at_c<0>(v) == 'a'));
  53. BOOST_TEST((at_c<1>(v) == 'c'));
  54. char ch;
  55. BOOST_TEST((test_attr(",c", -(',' >> char_), ch)));
  56. BOOST_TEST((ch == 'c'));
  57. }
  58. { // test action
  59. boost::optional<int> n = 0;
  60. BOOST_TEST((test_attr("1234", (-int_)[test_attribute_type()], n)));
  61. BOOST_TEST((n.get() == 1234));
  62. }
  63. {
  64. std::string s;
  65. BOOST_TEST((test_attr("abc", char_ >> -(char_ >> char_), s)));
  66. BOOST_TEST(s == "abc");
  67. }
  68. {
  69. boost::optional<int> n = 0;
  70. auto f = [&](auto& ctx){ n = _attr(ctx); };
  71. BOOST_TEST((test("1234", (-int_)[f])));
  72. BOOST_TEST(n.get() == 1234);
  73. n = boost::optional<int>();
  74. BOOST_TEST((test("abcd", (-int_)[f], false)));
  75. BOOST_TEST(!n);
  76. }
  77. {
  78. std::vector<adata> v;
  79. BOOST_TEST((test_attr("a 1 2 a 2", *('a' >> int_ >> -int_), v
  80. , char_(' '))));
  81. BOOST_TEST(2 == v.size() &&
  82. 1 == v[0].a && v[0].b && 2 == *(v[0].b) &&
  83. 2 == v[1].a && !v[1].b);
  84. }
  85. { // test move only types
  86. boost::optional<move_only> o;
  87. BOOST_TEST(test_attr("s", -synth_move_only, o));
  88. BOOST_TEST(o);
  89. }
  90. return boost::report_errors();
  91. }