]>
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 // TODO: fix unneeded self move in alternative
45 stationary
& operator=(stationary
&&) { std::abort(); }
46 stationary
& operator=(int i
) { val
= i
; return *this; }
55 using spirit_test::test
;
56 using spirit_test::test_attr
;
58 using boost::spirit::x3::attr
;
59 using boost::spirit::x3::char_
;
60 using boost::spirit::x3::int_
;
61 using boost::spirit::x3::lit
;
62 using boost::spirit::x3::unused_type
;
63 using boost::spirit::x3::unused
;
64 using boost::spirit::x3::omit
;
65 using boost::spirit::x3::eps
;
69 BOOST_TEST((test("a", char_
| char_
)));
70 BOOST_TEST((test("x", lit('x') | lit('i'))));
71 BOOST_TEST((test("i", lit('x') | lit('i'))));
72 BOOST_TEST((!test("z", lit('x') | lit('o'))));
73 BOOST_TEST((test("rock", lit("rock") | lit("roll"))));
74 BOOST_TEST((test("roll", lit("rock") | lit("roll"))));
75 BOOST_TEST((test("rock", lit("rock") | int_
)));
76 BOOST_TEST((test("12345", lit("rock") | int_
)));
80 typedef boost::variant
<undefined
, int, char> attr_type
;
83 BOOST_TEST((test_attr("12345", int_
| char_
, v
)));
84 BOOST_TEST(boost::get
<int>(v
) == 12345);
86 BOOST_TEST((test_attr("12345", lit("rock") | int_
| char_
, v
)));
87 BOOST_TEST(boost::get
<int>(v
) == 12345);
90 BOOST_TEST((test_attr("rock", lit("rock") | int_
| char_
, v
)));
91 BOOST_TEST(v
.which() == 0);
93 BOOST_TEST((test_attr("x", lit("rock") | int_
| char_
, v
)));
94 BOOST_TEST(boost::get
<char>(v
) == 'x');
97 { // Make sure that we are using the actual supplied attribute types
98 // from the variant and not the expected type.
99 boost::variant
<int, std::string
> v
;
100 BOOST_TEST((test_attr("12345", int_
| +char_
, v
)));
101 BOOST_TEST(boost::get
<int>(v
) == 12345);
103 BOOST_TEST((test_attr("abc", int_
| +char_
, v
)));
104 BOOST_TEST(boost::get
<std::string
>(v
) == "abc");
106 BOOST_TEST((test_attr("12345", +char_
| int_
, v
)));
107 BOOST_TEST(boost::get
<std::string
>(v
) == "12345");
112 BOOST_TEST((test_attr("rock", lit("rock") | lit('x'), x
)));
116 // test if alternatives with all components having unused
117 // attributes have an unused attribute
119 using boost::fusion::vector
;
120 using boost::fusion::at_c
;
122 vector
<char, char> v
;
123 BOOST_TEST((test_attr("abc",
124 char_
>> (omit
[char_
] | omit
[char_
]) >> char_
, v
)));
125 BOOST_TEST((at_c
<0>(v
) == 'a'));
126 BOOST_TEST((at_c
<1>(v
) == 'c'));
130 // Test that we can still pass a "compatible" attribute to
131 // an alternate even if its "expected" attribute is unused type.
134 BOOST_TEST((test_attr("...", *(char_('.') | char_(',')), s
)));
135 BOOST_TEST(s
== "...");
138 { // make sure collapsing eps works as expected
139 // (compile check only)
141 using boost::spirit::x3::rule
;
142 using boost::spirit::x3::eps
;
143 using boost::spirit::x3::_attr
;
144 using boost::spirit::x3::_val
;
146 rule
<class r1
, wchar_t> r1
;
147 rule
<class r2
, wchar_t> r2
;
148 rule
<class r3
, wchar_t> r3
;
150 auto f
= [&](auto& ctx
){ _val(ctx
) = _attr(ctx
); };
152 r3
= ((eps
>> r1
))[f
];
154 r3
= ((eps
>> r1
) | r2
);
159 using boost::spirit::x3::eps
;
161 // test having a variant<container, ...>
162 BOOST_TEST( (test_attr("a,b", (char_
% ',') | eps
, s
)) );
163 BOOST_TEST(s
== "ab");
167 using boost::spirit::x3::eps
;
169 // testing a sequence taking a container as attribute
171 BOOST_TEST( (test_attr("abc,a,b,c",
172 char_
>> char_
>> (char_
% ','), s
)) );
173 BOOST_TEST(s
== "abcabc");
175 // test having an optional<container> inside a sequence
177 BOOST_TEST( (test_attr("ab",
178 char_
>> char_
>> -(char_
% ','), s
)) );
179 BOOST_TEST(s
== "ab");
181 // test having a variant<container, ...> inside a sequence
183 BOOST_TEST( (test_attr("ab",
184 char_
>> char_
>> ((char_
% ',') | eps
), s
)) );
185 BOOST_TEST(s
== "ab");
187 BOOST_TEST( (test_attr("abc",
188 char_
>> char_
>> ((char_
% ',') | eps
), s
)) );
189 BOOST_TEST(s
== "abc");
193 //compile test only (bug_march_10_2011_8_35_am)
194 typedef boost::variant
<double, std::string
> value_type
;
196 using boost::spirit::x3::rule
;
197 using boost::spirit::x3::eps
;
199 rule
<class r1
, value_type
> r1
;
200 auto r1_
= r1
= r1
| eps
; // left recursive!
202 unused
= r1_
; // silence unused local warning
206 using boost::spirit::x3::rule
;
207 typedef boost::variant
<di_ignore
, di_include
> d_line
;
209 rule
<class ignore
, di_ignore
> ignore
;
210 rule
<class include
, di_include
> include
;
211 rule
<class line
, d_line
> line
;
214 line
= include
| ignore
;
216 unused
= start
; // silence unused local warning
219 // single-element fusion vector tests
221 boost::fusion::vector
<boost::variant
<int, std::string
>> fv
;
222 BOOST_TEST((test_attr("12345", int_
| +char_
, fv
)));
223 BOOST_TEST(boost::get
<int>(boost::fusion::at_c
<0>(fv
)) == 12345);
225 boost::fusion::vector
<boost::variant
<int, std::string
>> fvi
;
226 BOOST_TEST((test_attr("12345", int_
| int_
, fvi
)));
227 BOOST_TEST(boost::get
<int>(boost::fusion::at_c
<0>(fvi
)) == 12345);
230 // alternative over single element sequences as part of another sequence
232 auto key1
= lit("long") >> attr(long());
233 auto key2
= lit("char") >> attr(char());
234 auto keys
= key1
| key2
;
235 auto pair
= keys
>> lit("=") >> +char_
;
237 boost::fusion::deque
<boost::variant
<long, char>, std::string
> attr_
;
239 BOOST_TEST(test_attr("long=ABC", pair
, attr_
));
240 BOOST_TEST(boost::get
<long>(&boost::fusion::front(attr_
)) != nullptr);
241 BOOST_TEST(boost::get
<char>(&boost::fusion::front(attr_
)) == nullptr);
244 { // ensure no unneded synthesization, copying and moving occured
245 auto p
= '{' >> int_
>> '}';
248 BOOST_TEST(test_attr("{42}", p
| eps
| p
, st
));
249 BOOST_TEST_EQ(st
.val
, 42);
252 return boost::report_errors();