]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/test/x3/rule4.cpp
cfbfe515c19558ef6978cd9bfd0a5b96626892d9
[ceph.git] / ceph / src / boost / libs / spirit / test / x3 / rule4.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
3
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
8 // this file deliberately contains non-ascii characters
9 // boostinspect:noascii
10
11 #include <boost/detail/lightweight_test.hpp>
12 #include <boost/spirit/home/x3.hpp>
13 #include <boost/fusion/include/vector.hpp>
14 #include <boost/fusion/include/at.hpp>
15
16 #include <string>
17 #include <cstring>
18 #include <iostream>
19 #include "test.hpp"
20
21 namespace x3 = boost::spirit::x3;
22
23 int got_it = 0;
24
25 struct my_rule_class
26 {
27 template <typename Iterator, typename Exception, typename Context>
28 x3::error_handler_result
29 on_error(Iterator&, Iterator const& last, Exception const& x, Context const& context)
30 {
31 std::cout
32 << "Error! Expecting: "
33 << x.which()
34 << ", got: \""
35 << std::string(x.where(), last)
36 << "\""
37 << std::endl
38 ;
39 return x3::error_handler_result::fail;
40 }
41
42 template <typename Iterator, typename Attribute, typename Context>
43 inline void
44 on_success(Iterator const&, Iterator const&, Attribute&, Context const&)
45 {
46 ++got_it;
47 }
48 };
49
50 int
51 main()
52 {
53 using spirit_test::test_attr;
54 using spirit_test::test;
55
56 using namespace boost::spirit::x3::ascii;
57 using boost::spirit::x3::rule;
58 using boost::spirit::x3::int_;
59 using boost::spirit::x3::lit;
60
61 { // show that ra = rb and ra %= rb works as expected
62 rule<class a, int> ra;
63 rule<class b, int> rb;
64 int attr;
65
66 auto ra_def = (ra %= int_);
67 BOOST_TEST(test_attr("123", ra_def, attr));
68 BOOST_TEST(attr == 123);
69
70 auto rb_def = (rb %= ra_def);
71 BOOST_TEST(test_attr("123", rb_def, attr));
72 BOOST_TEST(attr == 123);
73
74 auto rb_def2 = (rb = ra_def);
75 BOOST_TEST(test_attr("123", rb_def2, attr));
76 BOOST_TEST(attr == 123);
77 }
78
79 { // show that ra %= rb works as expected with semantic actions
80 rule<class a, int> ra;
81 rule<class b, int> rb;
82 int attr;
83
84 auto f = [](auto c){};
85 auto ra_def = (ra %= int_[f]);
86 BOOST_TEST(test_attr("123", ra_def, attr));
87 BOOST_TEST(attr == 123);
88
89 auto ra_def2 = (rb = (ra %= int_[f]));
90 BOOST_TEST(test_attr("123", ra_def2, attr));
91 BOOST_TEST(attr == 123);
92 }
93
94
95 { // std::string as container attribute with auto rules
96
97 std::string attr;
98
99 // test deduced auto rule behavior
100
101 auto text = rule<class text, std::string>()
102 = +(!char_(')') >> !char_('>') >> char_);
103
104 attr.clear();
105 BOOST_TEST(test_attr("x", text, attr));
106 BOOST_TEST(attr == "x");
107 }
108
109 { // error handling
110
111 auto r = rule<my_rule_class, char const*>()
112 = '(' > int_ > ',' > int_ > ')';
113
114 BOOST_TEST(test("(123,456)", r));
115 BOOST_TEST(!test("(abc,def)", r));
116 BOOST_TEST(!test("(123,456]", r));
117 BOOST_TEST(!test("(123;456)", r));
118 BOOST_TEST(!test("[123,456]", r));
119
120 BOOST_TEST(got_it == 1);
121 }
122
123 {
124 typedef boost::variant<double, int> v_type;
125 auto r1 = rule<class r1, v_type>()
126 = int_;
127 v_type v;
128 BOOST_TEST(test_attr("1", r1, v) && v.which() == 1 &&
129 boost::get<int>(v) == 1);
130
131 typedef boost::optional<int> ov_type;
132 auto r2 = rule<class r2, ov_type>()
133 = int_;
134 ov_type ov;
135 BOOST_TEST(test_attr("1", r2, ov) && ov && boost::get<int>(ov) == 1);
136 }
137
138 // test handling of single element fusion sequences
139 {
140 using boost::fusion::vector;
141 using boost::fusion::at_c;
142 auto r = rule<class r, vector<int>>()
143 = int_;
144
145 vector<int> v(0);
146 BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1);
147 }
148
149 { // attribute compatibility test
150 using boost::spirit::x3::rule;
151 using boost::spirit::x3::int_;
152
153 auto const expr = int_;
154
155 short i;
156 BOOST_TEST(test_attr("1", expr, i) && i == 1); // ok
157
158 const rule< class int_rule, int > int_rule( "int_rule" );
159 auto const int_rule_def = int_;
160 auto const start = int_rule = int_rule_def;
161
162 short j;
163 BOOST_TEST(test_attr("1", start, j) && j == 1); // error
164 }
165
166 return boost::report_errors();
167 }