]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/test/x3/alternative.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/spirit/home/x3.hpp>
10 #include <boost/fusion/include/adapt_struct.hpp>
11 #include <boost/variant.hpp>
12 #include <boost/fusion/include/vector.hpp>
13 #include <boost/fusion/include/at.hpp>
30 BOOST_FUSION_ADAPT_STRUCT(di_ignore
,
34 BOOST_FUSION_ADAPT_STRUCT(di_include
,
41 struct stationary
: boost::noncopyable
43 explicit stationary(int i
) : val
{i
} {}
44 stationary
& operator=(int i
) { val
= i
; return *this; }
53 using spirit_test::test
;
54 using spirit_test::test_attr
;
56 using boost::spirit::x3::attr
;
57 using boost::spirit::x3::char_
;
58 using boost::spirit::x3::int_
;
59 using boost::spirit::x3::lit
;
60 using boost::spirit::x3::unused_type
;
61 using boost::spirit::x3::unused
;
62 using boost::spirit::x3::omit
;
63 using boost::spirit::x3::eps
;
65 BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_
| char_
);
68 BOOST_TEST((test("a", char_
| char_
)));
69 BOOST_TEST((test("x", lit('x') | lit('i'))));
70 BOOST_TEST((test("i", lit('x') | lit('i'))));
71 BOOST_TEST((!test("z", lit('x') | lit('o'))));
72 BOOST_TEST((test("rock", lit("rock") | lit("roll"))));
73 BOOST_TEST((test("roll", lit("rock") | lit("roll"))));
74 BOOST_TEST((test("rock", lit("rock") | int_
)));
75 BOOST_TEST((test("12345", lit("rock") | int_
)));
79 typedef boost::variant
<undefined
, int, char> attr_type
;
82 BOOST_TEST((test_attr("12345", int_
| char_
, v
)));
83 BOOST_TEST(boost::get
<int>(v
) == 12345);
85 BOOST_TEST((test_attr("12345", lit("rock") | int_
| char_
, v
)));
86 BOOST_TEST(boost::get
<int>(v
) == 12345);
89 BOOST_TEST((test_attr("rock", lit("rock") | int_
| char_
, v
)));
90 BOOST_TEST(v
.which() == 0);
92 BOOST_TEST((test_attr("x", lit("rock") | int_
| char_
, v
)));
93 BOOST_TEST(boost::get
<char>(v
) == 'x');
96 { // Make sure that we are using the actual supplied attribute types
97 // from the variant and not the expected type.
98 boost::variant
<int, std::string
> v
;
99 BOOST_TEST((test_attr("12345", int_
| +char_
, v
)));
100 BOOST_TEST(boost::get
<int>(v
) == 12345);
102 BOOST_TEST((test_attr("abc", int_
| +char_
, v
)));
103 BOOST_TEST(boost::get
<std::string
>(v
) == "abc");
105 BOOST_TEST((test_attr("12345", +char_
| int_
, v
)));
106 BOOST_TEST(boost::get
<std::string
>(v
) == "12345");
111 BOOST_TEST((test_attr("rock", lit("rock") | lit('x'), x
)));
115 // test if alternatives with all components having unused
116 // attributes have an unused attribute
118 using boost::fusion::vector
;
119 using boost::fusion::at_c
;
121 vector
<char, char> v
;
122 BOOST_TEST((test_attr("abc",
123 char_
>> (omit
[char_
] | omit
[char_
]) >> char_
, v
)));
124 BOOST_TEST((at_c
<0>(v
) == 'a'));
125 BOOST_TEST((at_c
<1>(v
) == 'c'));
129 // Test that we can still pass a "compatible" attribute to
130 // an alternate even if its "expected" attribute is unused type.
133 BOOST_TEST((test_attr("...", *(char_('.') | char_(',')), s
)));
134 BOOST_TEST(s
== "...");
137 { // make sure collapsing eps works as expected
138 // (compile check only)
140 using boost::spirit::x3::rule
;
141 using boost::spirit::x3::eps
;
142 using boost::spirit::x3::_attr
;
143 using boost::spirit::x3::_val
;
145 rule
<class r1
, wchar_t> r1
;
146 rule
<class r2
, wchar_t> r2
;
147 rule
<class r3
, wchar_t> r3
;
149 auto f
= [&](auto& ctx
){ _val(ctx
) = _attr(ctx
); };
151 r3
= ((eps
>> r1
))[f
];
153 r3
= ((eps
>> r1
) | r2
);
158 using boost::spirit::x3::eps
;
160 // test having a variant<container, ...>
161 BOOST_TEST( (test_attr("a,b", (char_
% ',') | eps
, s
)) );
162 BOOST_TEST(s
== "ab");
166 using boost::spirit::x3::eps
;
168 // testing a sequence taking a container as attribute
170 BOOST_TEST( (test_attr("abc,a,b,c",
171 char_
>> char_
>> (char_
% ','), s
)) );
172 BOOST_TEST(s
== "abcabc");
174 // test having an optional<container> inside a sequence
176 BOOST_TEST( (test_attr("ab",
177 char_
>> char_
>> -(char_
% ','), s
)) );
178 BOOST_TEST(s
== "ab");
180 // test having a variant<container, ...> inside a sequence
182 BOOST_TEST( (test_attr("ab",
183 char_
>> char_
>> ((char_
% ',') | eps
), s
)) );
184 BOOST_TEST(s
== "ab");
186 BOOST_TEST( (test_attr("abc",
187 char_
>> char_
>> ((char_
% ',') | eps
), s
)) );
188 BOOST_TEST(s
== "abc");
192 //compile test only (bug_march_10_2011_8_35_am)
193 typedef boost::variant
<double, std::string
> value_type
;
195 using boost::spirit::x3::rule
;
196 using boost::spirit::x3::eps
;
198 rule
<class r1
, value_type
> r1
;
199 auto r1_
= r1
= r1
| eps
; // left recursive!
201 unused
= r1_
; // silence unused local warning
205 using boost::spirit::x3::rule
;
206 typedef boost::variant
<di_ignore
, di_include
> d_line
;
208 rule
<class ignore
, di_ignore
> ignore
;
209 rule
<class include
, di_include
> include
;
210 rule
<class line
, d_line
> line
;
213 line
= include
| ignore
;
215 unused
= start
; // silence unused local warning
218 // single-element fusion vector tests
220 boost::fusion::vector
<boost::variant
<int, std::string
>> fv
;
221 BOOST_TEST((test_attr("12345", int_
| +char_
, fv
)));
222 BOOST_TEST(boost::get
<int>(boost::fusion::at_c
<0>(fv
)) == 12345);
224 boost::fusion::vector
<boost::variant
<int, std::string
>> fvi
;
225 BOOST_TEST((test_attr("12345", int_
| int_
, fvi
)));
226 BOOST_TEST(boost::get
<int>(boost::fusion::at_c
<0>(fvi
)) == 12345);
229 // alternative over single element sequences as part of another sequence
231 auto key1
= lit("long") >> attr(long());
232 auto key2
= lit("char") >> attr(char());
233 auto keys
= key1
| key2
;
234 auto pair
= keys
>> lit("=") >> +char_
;
236 boost::fusion::deque
<boost::variant
<long, char>, std::string
> attr_
;
238 BOOST_TEST(test_attr("long=ABC", pair
, attr_
));
239 BOOST_TEST(boost::get
<long>(&boost::fusion::front(attr_
)) != nullptr);
240 BOOST_TEST(boost::get
<char>(&boost::fusion::front(attr_
)) == nullptr);
243 { // ensure no unneeded synthesization, copying and moving occurred
244 auto p
= '{' >> int_
>> '}';
247 BOOST_TEST(test_attr("{42}", p
| eps
| p
, st
));
248 BOOST_TEST_EQ(st
.val
, 42);
251 { // attributeless parsers must not insert values
253 BOOST_TEST(test_attr("1 2 3 - 5 - - 7 -", (int_
| '-') % ' ', v
));
254 BOOST_TEST_EQ(v
.size(), 5)
255 && BOOST_TEST_EQ(v
[0], 1)
256 && BOOST_TEST_EQ(v
[1], 2)
257 && BOOST_TEST_EQ(v
[2], 3)
258 && BOOST_TEST_EQ(v
[3], 5)
259 && BOOST_TEST_EQ(v
[4], 7)
263 { // regressing test for #603
264 using boost::spirit::x3::attr
;
266 std::vector
<boost::variant
<std::string
, int, X
>> v
;
267 BOOST_TEST(test_attr("xx42x9y", *(int_
| +char_('x') | 'y' >> attr(X
{})), v
));
268 BOOST_TEST_EQ(v
.size(), 5);
271 { // sequence parser in alternative into container
273 BOOST_TEST(test_attr("abcbbcd",
274 *(char_('a') >> *(*char_('b') >> char_('c')) | char_('d')), s
));
275 BOOST_TEST_EQ(s
, "abcbbcd");
278 return boost::report_errors();