]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/test/qi/alternative.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 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/mpl/print.hpp>
10 #include <boost/spirit/include/qi_operator.hpp>
11 #include <boost/spirit/include/qi_char.hpp>
12 #include <boost/spirit/include/qi_string.hpp>
13 #include <boost/spirit/include/qi_numeric.hpp>
14 #include <boost/spirit/include/qi_directive.hpp>
15 #include <boost/spirit/include/qi_action.hpp>
16 #include <boost/spirit/include/qi_nonterminal.hpp>
17 #include <boost/spirit/include/qi_auxiliary.hpp>
18 #include <boost/spirit/include/qi_rule.hpp>
19 #include <boost/spirit/include/support_argument.hpp>
20 #include <boost/spirit/include/phoenix_core.hpp>
21 #include <boost/spirit/include/phoenix_operator.hpp>
22 #include <boost/fusion/include/adapt_struct.hpp>
23 #include <boost/variant.hpp>
24 #include <boost/assert.hpp>
33 test_action(char last
)
36 template<typename Context
>
37 void operator()(std::vector
<char> const& v
, Context
const&, bool&) const
39 BOOST_TEST(v
.size() == 4 &&
40 v
[0] == 'a' && v
[1] == 'b' && v
[2] == '1' && v
[3] == last_
);
48 typedef std::vector
<boost::optional
<char> > result_type
;
50 template<typename Context
>
51 void operator()(result_type
const& v
, Context
const&, bool&) const
53 BOOST_TEST(v
.size() == 5 &&
54 !v
[0] && v
[1] == 'a' && v
[2] == 'b' && v
[3] == '1' && v
[4] == '2');
68 BOOST_FUSION_ADAPT_STRUCT(
73 BOOST_FUSION_ADAPT_STRUCT(
75 (std::string
, FileName
)
81 using spirit_test::test
;
82 using spirit_test::test_attr
;
84 using boost::spirit::ascii::char_
;
85 using boost::spirit::qi::int_
;
86 using boost::spirit::qi::lit
;
87 using boost::spirit::qi::unused_type
;
88 using boost::spirit::qi::_1
;
89 using boost::spirit::qi::omit
;
92 BOOST_TEST((test("a", char_
| char_
)));
93 BOOST_TEST((test("x", lit('x') | lit('i'))));
94 BOOST_TEST((test("i", lit('x') | lit('i'))));
95 BOOST_TEST((!test("z", lit('x') | lit('o'))));
96 BOOST_TEST((test("rock", lit("rock") | lit("roll"))));
97 BOOST_TEST((test("roll", lit("rock") | lit("roll"))));
98 BOOST_TEST((test("rock", lit("rock") | int_
)));
99 BOOST_TEST((test("12345", lit("rock") | int_
)));
103 boost::variant
<unused_type
, int, char> v
;
105 BOOST_TEST((test_attr("12345", lit("rock") | int_
| char_
, v
)));
106 BOOST_TEST(boost::get
<int>(v
) == 12345);
108 BOOST_TEST((test_attr("rock", lit("rock") | int_
| char_
, v
)));
109 BOOST_TEST(v
.which() == 1);
111 BOOST_TEST((test_attr("x", lit("rock") | int_
| char_
, v
)));
112 BOOST_TEST(boost::get
<char>(v
) == 'x');
115 { // Make sure that we are using the actual supplied attribute types
116 // from the variant and not the expected type.
117 // $$$ Fixed: <2/19/2011> JDG $$$
118 boost::variant
<int, std::string
> v
;
119 BOOST_TEST((test_attr("12345", int_
| +char_
, v
)));
120 BOOST_TEST(boost::get
<int>(v
) == 12345);
122 BOOST_TEST((test_attr("abc", int_
| +char_
, v
)));
123 BOOST_TEST(boost::get
<std::string
>(v
) == "abc");
125 BOOST_TEST((test_attr("12345", +char_
| int_
, v
)));
126 BOOST_TEST(boost::get
<std::string
>(v
) == "12345");
131 namespace phx
= boost::phoenix
;
132 boost::optional
<boost::variant
<int, char> > v
;
134 BOOST_TEST((test("12345", (lit("rock") | int_
| char_
)[phx::ref(v
) = _1
])));
135 BOOST_TEST(boost::get
<int>(boost::get(v
)) == 12345);
136 BOOST_TEST((test("rock", (lit("rock") | int_
| char_
)[phx::ref(v
) = _1
])));
142 BOOST_TEST((test_attr("rock", lit("rock") | lit('x'), x
)));
146 // test if alternatives with all components having unused
147 // attributes have an unused attribute
149 using boost::fusion::vector
;
150 using boost::fusion::at_c
;
152 vector
<char, char> v
;
153 BOOST_TEST((test_attr("abc",
154 char_
>> (omit
[char_
] | omit
[char_
]) >> char_
, v
)));
155 BOOST_TEST((at_c
<0>(v
) == 'a'));
156 BOOST_TEST((at_c
<1>(v
) == 'c'));
160 // Test that we can still pass a "compatible" attribute to
161 // an alternate even if its "expected" attribute is unused type.
164 BOOST_TEST((test_attr("...", *(char_('.') | char_(',')), s
)));
165 BOOST_TEST(s
== "...");
168 { // make sure collapsing eps works as expected
169 // (compile check only)
171 using boost::spirit::qi::rule
;
172 using boost::spirit::qi::_val
;
173 using boost::spirit::qi::_1
;
174 using boost::spirit::eps
;
175 rule
<const wchar_t*, wchar_t()> r1
, r2
, r3
;
177 r3
= ((eps
>> r1
))[_val
+= _1
];
178 r3
= ((r1
) | r2
)[_val
+= _1
];
180 r3
%= ((eps
>> r1
) | r2
);
181 r3
= ((eps
>> r1
) | r2
)[_val
+= _1
];
184 // make sure the attribute of an alternative gets properly collapsed
186 using boost::spirit::qi::lexeme
;
187 using boost::spirit::ascii::alnum
;
188 using boost::spirit::ascii::alpha
;
189 using boost::spirit::ascii::digit
;
190 using boost::spirit::ascii::string
;
191 namespace phx
= boost::phoenix
;
194 BOOST_TEST( (test("ab1_", (*(alnum
| char_('_')))[test_action('_')])) );
195 BOOST_TEST( (test("ab12", (*(alpha
| digit
))[test_action('2')])) );
197 BOOST_TEST( (test("abcab12", (*("abc" | alnum
))[test_action_2()])) );
199 std::vector
<boost::optional
<char> > v
;
200 BOOST_TEST( (test("x,y,z", (*(',' | char_
))[phx::ref(v
) = _1
])) );
201 BOOST_ASSERT(v
[0] == 'x');
203 BOOST_ASSERT(v
[2] == 'y');
205 BOOST_ASSERT(v
[4] == 'z');
209 using boost::spirit::qi::eps
;
211 // testing a sequence taking a container as attribute
213 BOOST_TEST( (test_attr("abc,a,b,c",
214 char_
>> char_
>> (char_
% ','), s
)) );
215 BOOST_TEST(s
== "abcabc");
217 // test having an optional<container> inside a sequence
219 BOOST_TEST( (test_attr("ab",
220 char_
>> char_
>> -(char_
% ','), s
)) );
221 BOOST_TEST(s
== "ab");
223 // test having a variant<container, ...> inside a sequence
225 BOOST_TEST( (test_attr("ab",
226 char_
>> char_
>> ((char_
% ',') | eps
), s
)) );
227 BOOST_TEST(s
== "ab");
229 BOOST_TEST( (test_attr("abc",
230 char_
>> char_
>> ((char_
% ',') | eps
), s
)) );
231 BOOST_TEST(s
== "abc");
235 using boost::spirit::qi::int_
;
238 BOOST_TEST( (test_attr("10", int_(5) | int_(10), i
)) );
243 #ifdef SPIRIT_NO_COMPILE_CHECK
244 //compile test only (bug_march_10_2011_8_35_am)
245 // TODO: does not work as intended with std <= c++03
246 typedef boost::variant
<double, std::string
> value_type
;
248 using boost::spirit::qi::rule
;
249 using boost::spirit::qi::eps
;
250 rule
<std::string::const_iterator
, value_type()> r1
= r1
| eps
;
255 using boost::spirit::qi::rule
;
256 typedef boost::variant
<DIgnore
, DInclude
> DLine
;
258 rule
<char*, DIgnore()> ignore
;
259 rule
<char*, DInclude()> include
;
260 rule
<char*, DLine()> line
= include
| ignore
;
263 return boost::report_errors();