]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/proto/test/matches.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / proto / test / matches.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // matches.hpp
3 //
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
5 // Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #include <string>
9 #include <iostream>
10 #include <boost/config.hpp>
11 #include <boost/detail/workaround.hpp>
12 #include <boost/mpl/assert.hpp>
13 #include <boost/mpl/placeholders.hpp>
14 #include <boost/type_traits/is_same.hpp>
15 #include <boost/proto/core.hpp>
16 #include <boost/proto/debug.hpp>
17 #include <boost/proto/transform/arg.hpp>
18 #include <boost/test/unit_test.hpp>
19
20 namespace mpl = boost::mpl;
21 namespace proto = boost::proto;
22 namespace fusion = boost::fusion;
23
24 struct int_convertible
25 {
26 int_convertible() {}
27 operator int() const { return 0; }
28 };
29
30 struct Input
31 : proto::or_<
32 proto::shift_right< proto::terminal< std::istream & >, proto::_ >
33 , proto::shift_right< Input, proto::_ >
34 >
35 {};
36
37 struct Output
38 : proto::or_<
39 proto::shift_left< proto::terminal< std::ostream & >, proto::_ >
40 , proto::shift_left< Output, proto::_ >
41 >
42 {};
43
44 proto::terminal< std::istream & >::type const cin_ = {std::cin};
45 proto::terminal< std::ostream & >::type const cout_ = {std::cout};
46
47 struct Anything
48 : proto::or_<
49 proto::terminal<proto::_>
50 , proto::nary_expr<proto::_, proto::vararg<Anything> >
51 >
52 {};
53
54 void a_function() {}
55
56 struct MyCases
57 {
58 template<typename Tag>
59 struct case_
60 : proto::not_<proto::_>
61 {};
62 };
63
64 template<>
65 struct MyCases::case_<proto::tag::shift_right>
66 : proto::_
67 {};
68
69 template<>
70 struct MyCases::case_<proto::tag::plus>
71 : proto::_
72 {};
73
74 enum binary_representation_enum
75 {
76 magnitude
77 , two_complement
78 };
79
80 typedef
81 mpl::integral_c<binary_representation_enum, magnitude>
82 magnitude_c;
83
84 typedef
85 mpl::integral_c<binary_representation_enum, two_complement>
86 two_complement_c;
87
88 template<typename Type, typename Representation>
89 struct number
90 {};
91
92 struct NumberGrammar
93 : proto::or_ <
94 proto::terminal<number<proto::_, two_complement_c> >
95 , proto::terminal<number<proto::_, magnitude_c> >
96 >
97 {};
98
99 struct my_terminal
100 {};
101
102 template<typename T>
103 struct a_template
104 {};
105
106 template<typename Expr>
107 struct my_expr;
108
109 struct my_domain
110 : proto::domain<proto::pod_generator<my_expr> >
111 {};
112
113 template<typename Expr>
114 struct my_expr
115 {
116 BOOST_PROTO_BASIC_EXTENDS(Expr, my_expr, my_domain)
117 };
118
119 void test_matches()
120 {
121 proto::assert_matches< proto::_ >( proto::lit(1) );
122 proto::assert_matches< proto::_ >( proto::as_child(1) );
123 proto::assert_matches< proto::_ >( proto::as_expr(1) );
124
125 proto::assert_matches< proto::terminal<int> >( proto::lit(1) );
126 proto::assert_matches< proto::terminal<int> >( proto::as_child(1) );
127 proto::assert_matches< proto::terminal<int> >( proto::as_expr(1) );
128
129 proto::assert_matches_not< proto::terminal<int> >( proto::lit('a') );
130 proto::assert_matches_not< proto::terminal<int> >( proto::as_child('a') );
131 proto::assert_matches_not< proto::terminal<int> >( proto::as_expr('a') );
132
133 proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::lit('a') );
134 proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_child('a') );
135 proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_expr('a') );
136
137 proto::assert_matches_not< proto::terminal<int> >( proto::lit((int_convertible())) );
138 proto::assert_matches_not< proto::terminal<int> >( proto::as_child((int_convertible())) );
139 proto::assert_matches_not< proto::terminal<int> >( proto::as_expr((int_convertible())) );
140
141 proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::lit((int_convertible())) );
142 proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_child((int_convertible())) );
143 proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_expr((int_convertible())) );
144
145 proto::assert_matches< proto::if_<boost::is_same<proto::_value, int>() > >( proto::lit(1) );
146 proto::assert_matches_not< proto::if_<boost::is_same<proto::_value, int>() > >( proto::lit('a') );
147
148 proto::assert_matches<
149 proto::and_<
150 proto::terminal<proto::_>
151 , proto::if_<boost::is_same<proto::_value, int>() >
152 >
153 >( proto::lit(1) );
154
155 proto::assert_matches_not<
156 proto::and_<
157 proto::terminal<proto::_>
158 , proto::if_<boost::is_same<proto::_value, int>() >
159 >
160 >( proto::lit('a') );
161
162 proto::assert_matches< proto::terminal<char const *> >( proto::lit("hello") );
163 proto::assert_matches< proto::terminal<char const *> >( proto::as_child("hello") );
164 proto::assert_matches< proto::terminal<char const *> >( proto::as_expr("hello") );
165
166 proto::assert_matches< proto::terminal<char const[6]> >( proto::lit("hello") );
167 proto::assert_matches< proto::terminal<char const (&)[6]> >( proto::as_child("hello") );
168 proto::assert_matches< proto::terminal<char const[6]> >( proto::as_expr("hello") );
169
170 proto::assert_matches< proto::terminal<char [6]> >( proto::lit("hello") );
171 proto::assert_matches< proto::terminal<char [6]> >( proto::as_child("hello") );
172 proto::assert_matches< proto::terminal<char [6]> >( proto::as_expr("hello") );
173
174 proto::assert_matches< proto::terminal<char const[proto::N]> >( proto::lit("hello") );
175 proto::assert_matches< proto::terminal<char const (&)[proto::N]> >( proto::as_child("hello") );
176 proto::assert_matches< proto::terminal<char const[proto::N]> >( proto::as_expr("hello") );
177
178 proto::assert_matches< proto::terminal<char [proto::N]> >( proto::lit("hello") );
179 proto::assert_matches< proto::terminal<char [proto::N]> >( proto::as_child("hello") );
180 proto::assert_matches< proto::terminal<char [proto::N]> >( proto::as_expr("hello") );
181
182 proto::assert_matches< proto::terminal<wchar_t const[proto::N]> >( proto::lit(L"hello") );
183 proto::assert_matches< proto::terminal<wchar_t const (&)[proto::N]> >( proto::as_child(L"hello") );
184 proto::assert_matches< proto::terminal<wchar_t const[proto::N]> >( proto::as_expr(L"hello") );
185
186 proto::assert_matches< proto::terminal<wchar_t [proto::N]> >( proto::lit(L"hello") );
187 proto::assert_matches< proto::terminal<wchar_t [proto::N]> >( proto::as_child(L"hello") );
188 proto::assert_matches< proto::terminal<wchar_t [proto::N]> >( proto::as_expr(L"hello") );
189
190 proto::assert_matches_not< proto::if_<boost::is_same<proto::_value, int>()> >( proto::lit("hello") );
191
192 proto::assert_matches< proto::terminal<std::string> >( proto::lit(std::string("hello")) );
193 proto::assert_matches< proto::terminal<std::string> >( proto::as_child(std::string("hello")) );
194 proto::assert_matches< proto::terminal<std::string> >( proto::as_expr(std::string("hello")) );
195
196 proto::assert_matches< proto::terminal<std::basic_string<proto::_> > >( proto::lit(std::string("hello")) );
197 proto::assert_matches< proto::terminal<std::basic_string<proto::_> > >( proto::as_child(std::string("hello")) );
198 proto::assert_matches< proto::terminal<std::basic_string<proto::_> > >( proto::as_expr(std::string("hello")) );
199
200 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> > >( proto::lit(1) );
201 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> > >( proto::as_child(1) );
202 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> > >( proto::as_expr(1) );
203
204 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_,proto::_,proto::_> > >( proto::lit(1) );
205 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_,proto::_,proto::_> > >( proto::as_child(1) );
206 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_,proto::_,proto::_> > >( proto::as_expr(1) );
207
208 #if BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(61700))
209 typedef std::string const const_string;
210 #else
211 typedef std::string const_string;
212 #endif
213
214 proto::assert_matches< proto::terminal<std::basic_string<proto::_> const & > >( proto::lit(const_string("hello")) );
215 proto::assert_matches< proto::terminal<std::basic_string<proto::_> const & > >( proto::as_child(const_string("hello")) );
216 proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> const & > >( proto::as_expr(const_string("hello")) );
217
218 proto::assert_matches< proto::terminal< void(&)() > >( proto::lit(a_function) );
219 proto::assert_matches< proto::terminal< void(&)() > >( proto::as_child(a_function) );
220 proto::assert_matches< proto::terminal< void(&)() > >( proto::as_expr(a_function) );
221
222 proto::assert_matches_not< proto::terminal< void(*)() > >( proto::lit(a_function) );
223 proto::assert_matches_not< proto::terminal< void(*)() > >( proto::as_child(a_function) );
224 proto::assert_matches_not< proto::terminal< void(*)() > >( proto::as_expr(a_function) );
225
226 proto::assert_matches< proto::terminal< proto::convertible_to<void(*)()> > >( proto::lit(a_function) );
227 proto::assert_matches< proto::terminal< proto::convertible_to<void(*)()> > >( proto::as_child(a_function) );
228 proto::assert_matches< proto::terminal< proto::convertible_to<void(*)()> > >( proto::as_expr(a_function) );
229
230 proto::assert_matches< proto::terminal< void(*)() > >( proto::lit(&a_function) );
231 proto::assert_matches< proto::terminal< void(*)() > >( proto::as_child(&a_function) );
232 proto::assert_matches< proto::terminal< void(*)() > >( proto::as_expr(&a_function) );
233
234 proto::assert_matches< proto::terminal< void(* const &)() > >( proto::lit(&a_function) );
235 proto::assert_matches< proto::terminal< void(* const &)() > >( proto::as_child(&a_function) );
236 proto::assert_matches_not< proto::terminal< void(* const &)() > >( proto::as_expr(&a_function) );
237
238 proto::assert_matches<
239 proto::or_<
240 proto::if_<boost::is_same<proto::_value, char>() >
241 , proto::if_<boost::is_same<proto::_value, int>() >
242 >
243 >( proto::lit(1) );
244
245 proto::assert_matches_not<
246 proto::or_<
247 proto::if_<boost::is_same<proto::_value, char>() >
248 , proto::if_<boost::is_same<proto::_value, int>() >
249 >
250 >( proto::lit(1u) );
251
252 proto::assert_matches< Input >( cin_ >> 1 >> 2 >> 3 );
253 proto::assert_matches_not< Output >( cin_ >> 1 >> 2 >> 3 );
254
255 proto::assert_matches< Output >( cout_ << 1 << 2 << 3 );
256 proto::assert_matches_not< Input >( cout_ << 1 << 2 << 3 );
257
258 proto::assert_matches< proto::function< proto::terminal<int>, proto::vararg< proto::terminal<char> > > >( proto::lit(1)('a','b','c','d') );
259 proto::assert_matches_not< proto::function< proto::terminal<int>, proto::vararg< proto::terminal<char> > > >( proto::lit(1)('a','b','c',"d") );
260
261 proto::assert_matches< Anything >( cout_ << 1 << +proto::lit('a') << proto::lit(1)('a','b','c',"d") );
262
263 proto::assert_matches< proto::switch_<MyCases> >( proto::lit(1) >> 'a' );
264 proto::assert_matches< proto::switch_<MyCases> >( proto::lit(1) + 'a' );
265 proto::assert_matches_not< proto::switch_<MyCases> >( proto::lit(1) << 'a' );
266
267 number<int, two_complement_c> num;
268 proto::assert_matches<NumberGrammar>(proto::as_expr(num));
269
270 // check custom terminal types
271 {
272 proto::nullary_expr<my_terminal, int>::type i = {0};
273
274 proto::assert_matches<proto::nullary_expr<my_terminal, proto::_> >( i );
275 proto::assert_matches_not<proto::terminal<proto::_> >( i );
276
277 proto::terminal<int>::type j = {0};
278 proto::assert_matches<proto::terminal<proto::_> >( j );
279 proto::assert_matches_not<proto::nullary_expr<my_terminal, proto::_> >( j );
280
281 proto::assert_matches<proto::nullary_expr<proto::_, proto::_> >( i );
282 }
283
284 // check 0 and 1 arg forms or or_ and and_
285 {
286 proto::assert_matches< proto::and_<> >( proto::lit(1) );
287 proto::assert_matches_not< proto::or_<> >( proto::lit(1) );
288
289 proto::assert_matches< proto::and_<proto::terminal<int> > >( proto::lit(1) );
290 proto::assert_matches< proto::or_<proto::terminal<int> > >( proto::lit(1) );
291 }
292
293 // Test lambda matches with arrays, a corner case that had
294 // a bug that was reported by Antoine de Maricourt on boost@lists.boost.org
295 {
296 a_template<int[3]> a;
297 proto::assert_matches< proto::terminal< a_template<proto::_> > >( proto::lit(a) );
298 }
299
300 // Test that the actual derived expression type makes it through to proto::if_
301 {
302 my_expr<proto::terminal<int>::type> e = {{1}};
303 proto::assert_matches< proto::if_<boost::is_same<proto::domain_of<proto::_>, my_domain>()> >( e );
304 }
305 }
306
307 using namespace boost::unit_test;
308 ///////////////////////////////////////////////////////////////////////////////
309 // init_unit_test_suite
310 //
311 test_suite* init_unit_test_suite( int argc, char* argv[] )
312 {
313 test_suite *test = BOOST_TEST_SUITE("test proto::matches<>");
314
315 test->add(BOOST_TEST_CASE(&test_matches));
316
317 return test;
318 }
319