]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright Daniel Wallin 2006. |
2 | // Distributed under the Boost Software License, Version 1.0. | |
3 | // (See accompanying file LICENSE_1_0.txt or copy at | |
4 | // http://www.boost.org/LICENSE_1_0.txt) | |
7c673cae | 5 | |
92f5a8d4 | 6 | #include <boost/parameter/config.hpp> |
7c673cae FG |
7 | #include <boost/parameter/preprocessor.hpp> |
8 | #include <boost/parameter/name.hpp> | |
7c673cae | 9 | #include <boost/tuple/tuple.hpp> |
92f5a8d4 | 10 | #include <map> |
7c673cae FG |
11 | #include <string> |
12 | #include "basics.hpp" | |
13 | ||
92f5a8d4 TL |
14 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
15 | #include <boost/parameter/value_type.hpp> | |
16 | #include <boost/mp11/map.hpp> | |
17 | #include <boost/core/enable_if.hpp> | |
18 | #include <type_traits> | |
19 | #else | |
20 | #include <boost/mpl/bool.hpp> | |
21 | #include <boost/mpl/if.hpp> | |
22 | #include <boost/type_traits/is_convertible.hpp> | |
23 | #if !defined(BOOST_NO_SFINAE) | |
24 | #include <boost/parameter/value_type.hpp> | |
25 | #include <boost/mpl/has_key.hpp> | |
26 | #include <boost/core/enable_if.hpp> | |
27 | #include <boost/type_traits/is_same.hpp> | |
28 | #endif | |
7c673cae FG |
29 | #endif |
30 | ||
31 | namespace test { | |
32 | ||
92f5a8d4 TL |
33 | BOOST_PARAMETER_NAME(expected) |
34 | BOOST_PARAMETER_NAME(x) | |
35 | BOOST_PARAMETER_NAME(y) | |
36 | BOOST_PARAMETER_NAME(z) | |
37 | ||
38 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
39 | template <typename To> | |
40 | struct predicate | |
41 | { | |
42 | template <typename From, typename Args> | |
43 | using fn = std::is_convertible<From,To>; | |
44 | }; | |
45 | ||
46 | BOOST_PARAMETER_FUNCTION((int), f, test::tag, | |
47 | (required | |
48 | (expected, *) | |
49 | ) | |
50 | (deduced | |
51 | (required | |
52 | (x, *(test::predicate<int>)) | |
53 | (y, *(test::predicate<std::string>)) | |
54 | ) | |
55 | ) | |
56 | ) | |
57 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
58 | struct predicate_int | |
59 | { | |
60 | template <typename From, typename Args> | |
61 | struct apply | |
62 | : boost::mpl::if_< | |
63 | boost::is_convertible<From,int> | |
64 | , boost::mpl::true_ | |
65 | , boost::mpl::false_ | |
66 | > | |
67 | { | |
68 | }; | |
69 | }; | |
70 | ||
71 | struct predicate_string | |
72 | { | |
73 | template <typename From, typename Args> | |
74 | struct apply | |
75 | : boost::mpl::if_< | |
76 | boost::is_convertible<From,std::string> | |
77 | , boost::mpl::true_ | |
78 | , boost::mpl::false_ | |
79 | > | |
80 | { | |
81 | }; | |
82 | }; | |
83 | ||
84 | BOOST_PARAMETER_FUNCTION((int), f, test::tag, | |
85 | (required | |
86 | (expected, *) | |
87 | ) | |
88 | (deduced | |
89 | (required | |
90 | (x, *(test::predicate_int)) | |
91 | (y, *(test::predicate_string)) | |
92 | ) | |
93 | ) | |
94 | ) | |
95 | #endif // BOOST_PARAMETER_CAN_USE_MP11 | |
96 | { | |
97 | BOOST_TEST(test::equal(x, boost::tuples::get<0>(expected))); | |
98 | BOOST_TEST(test::equal(y, boost::tuples::get<1>(expected))); | |
99 | return 1; | |
100 | } | |
7c673cae | 101 | |
92f5a8d4 TL |
102 | struct X |
103 | { | |
104 | X(int x_ = -1) : x(x_) | |
105 | { | |
106 | } | |
7c673cae | 107 | |
92f5a8d4 TL |
108 | bool operator==(X const& other) const |
109 | { | |
110 | return this->x == other.x; | |
111 | } | |
7c673cae | 112 | |
92f5a8d4 TL |
113 | int x; |
114 | }; | |
7c673cae | 115 | |
92f5a8d4 TL |
116 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
117 | BOOST_PARAMETER_FUNCTION((int), g, test::tag, | |
118 | (required | |
119 | (expected, *) | |
120 | ) | |
121 | (deduced | |
122 | (required | |
123 | (x, *(test::predicate<int>)) | |
124 | (y, *(test::predicate<std::string>)) | |
125 | ) | |
126 | (optional | |
127 | (z, *(test::predicate<test::X>), test::X()) | |
128 | ) | |
129 | ) | |
130 | ) | |
131 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) | |
132 | struct predicate_X | |
133 | { | |
134 | template <typename From, typename Args> | |
135 | struct apply | |
136 | : boost::mpl::if_< | |
137 | boost::is_convertible<From,test::X> | |
138 | , boost::mpl::true_ | |
139 | , boost::mpl::false_ | |
140 | > | |
141 | { | |
142 | }; | |
143 | }; | |
7c673cae | 144 | |
92f5a8d4 TL |
145 | BOOST_PARAMETER_FUNCTION((int), g, tag, |
146 | (required | |
147 | (expected, *) | |
148 | ) | |
149 | (deduced | |
150 | (required | |
151 | (x, *(test::predicate_int)) | |
152 | (y, *(test::predicate_string)) | |
153 | ) | |
154 | (optional | |
155 | (z, *(test::predicate_X), test::X()) | |
156 | ) | |
157 | ) | |
7c673cae | 158 | ) |
92f5a8d4 TL |
159 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
160 | { | |
161 | BOOST_TEST(test::equal(x, boost::tuples::get<0>(expected))); | |
162 | BOOST_TEST(test::equal(y, boost::tuples::get<1>(expected))); | |
163 | BOOST_TEST(test::equal(z, boost::tuples::get<2>(expected))); | |
164 | return 1; | |
165 | } | |
166 | ||
167 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
168 | BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, | |
169 | (deduced | |
170 | (required | |
171 | (x, *(test::predicate<std::string>)) | |
172 | ) | |
173 | ) | |
7c673cae | 174 | ) |
7c673cae | 175 | #else |
92f5a8d4 TL |
176 | BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, |
177 | (deduced | |
178 | (required | |
179 | (x, *(test::predicate_string)) | |
180 | ) | |
181 | ) | |
7c673cae | 182 | ) |
92f5a8d4 TL |
183 | #endif |
184 | { | |
185 | return 1; | |
186 | } | |
7c673cae | 187 | |
92f5a8d4 TL |
188 | #if !defined(BOOST_NO_SFINAE) |
189 | // On compilers that actually support SFINAE, add another overload | |
190 | // that is an equally good match and can only be in the overload set | |
191 | // when the others are not. This tests that the SFINAE is actually | |
192 | // working. On all other compilers we're just checking that everything | |
193 | // about SFINAE-enabled code will work, except of course the SFINAE. | |
194 | template <typename A0> | |
195 | typename boost::enable_if< | |
196 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
197 | std::is_same<int,A0> | |
198 | #else | |
199 | typename boost::mpl::if_< | |
200 | boost::is_same<int,A0> | |
201 | , boost::mpl::true_ | |
202 | , boost::mpl::false_ | |
203 | >::type | |
204 | #endif | |
205 | , int | |
206 | >::type | |
207 | sfinae(A0 const& a0) | |
7c673cae | 208 | { |
92f5a8d4 | 209 | return 0; |
7c673cae | 210 | } |
7c673cae | 211 | |
92f5a8d4 TL |
212 | #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) || \ |
213 | !BOOST_WORKAROUND(BOOST_MSVC, < 1800) | |
214 | // Test support for two different Boost.Parameter-enabled | |
215 | // function call operator overloads. | |
216 | class char_read_base | |
217 | { | |
218 | int index; | |
219 | char const* key; | |
220 | ||
221 | public: | |
222 | template <typename Args> | |
223 | explicit char_read_base(Args const& args) | |
224 | : index(args[test::_y]), key(args[test::_z]) | |
225 | { | |
226 | } | |
227 | ||
228 | BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), test::tag, | |
229 | (deduced | |
230 | (required | |
231 | (y, (int)) | |
232 | (z, (char const*)) | |
233 | ) | |
234 | ) | |
235 | ) | |
236 | { | |
237 | this->index = y; | |
238 | this->key = z; | |
239 | } | |
240 | ||
241 | BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((char), test::tag, | |
242 | (deduced | |
243 | (required | |
244 | (y, (bool)) | |
245 | (z, (std::map<char const*,std::string>)) | |
246 | ) | |
247 | ) | |
248 | ) | |
249 | { | |
250 | return y ? ( | |
251 | (z.find(this->key)->second)[this->index] | |
252 | ) : this->key[this->index]; | |
253 | } | |
254 | }; | |
255 | ||
256 | struct char_reader : public char_read_base | |
257 | { | |
258 | BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), test::tag, | |
259 | (deduced | |
260 | (required | |
261 | (y, (int)) | |
262 | (z, (char const*)) | |
263 | ) | |
264 | ) | |
265 | ) | |
266 | }; | |
267 | #endif // MSVC-11.0- | |
7c673cae | 268 | |
92f5a8d4 TL |
269 | // Test Boost.Parameter-enabled functions |
270 | // with parameter-dependent return types. | |
271 | #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) | |
272 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) | |
273 | BOOST_PARAMETER_FUNCTION( | |
274 | ( | |
275 | boost::lazy_enable_if< | |
276 | boost::mp11::mp_map_contains<Args,test::tag::y> | |
277 | , boost::parameter::value_type<Args,test::tag::y> | |
278 | > | |
279 | ), return_y, test::tag, | |
280 | (deduced | |
281 | (required | |
282 | (x, (std::map<char const*,std::string>)) | |
283 | (y, (char const*)) | |
284 | ) | |
285 | (optional | |
286 | (z, (int), 4) | |
287 | ) | |
288 | ) | |
7c673cae | 289 | ) |
92f5a8d4 TL |
290 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
291 | BOOST_PARAMETER_FUNCTION( | |
292 | ( | |
293 | boost::lazy_enable_if< | |
294 | typename boost::mpl::has_key<Args,test::tag::y>::type | |
295 | , boost::parameter::value_type<Args,test::tag::y> | |
296 | > | |
297 | ), return_y, test::tag, | |
298 | (deduced | |
299 | (required | |
300 | (x, (std::map<char const*,std::string>)) | |
301 | (y, (char const*)) | |
302 | ) | |
303 | (optional | |
304 | (z, (int), 4) | |
305 | ) | |
306 | ) | |
7c673cae | 307 | ) |
92f5a8d4 TL |
308 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
309 | { | |
310 | return y; | |
311 | } | |
312 | #endif // LIBS_PARAMETER_TEST_COMPILE_FAILURE | |
313 | #endif // BOOST_NO_SFINAE | |
7c673cae | 314 | |
92f5a8d4 TL |
315 | #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) |
316 | BOOST_PARAMETER_FUNCTION( | |
317 | (typename boost::parameter::value_type<Args,test::tag::y>::type), | |
318 | return_y, test::tag, | |
319 | (deduced | |
320 | (required | |
321 | (x, (std::map<char const*,std::string>)) | |
322 | (y, (char const*)) | |
323 | ) | |
324 | (optional | |
325 | (z, (int), 4) | |
326 | ) | |
327 | ) | |
7c673cae | 328 | ) |
92f5a8d4 TL |
329 | { |
330 | return y; | |
331 | } | |
332 | #endif // defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) | |
7c673cae FG |
333 | } // namespace test |
334 | ||
92f5a8d4 | 335 | #include <boost/core/lightweight_test.hpp> |
7c673cae FG |
336 | |
337 | int main() | |
338 | { | |
92f5a8d4 TL |
339 | test::f( |
340 | boost::make_tuple(0, std::string("foo")) | |
341 | , test::_x = 0 | |
342 | , test::_y = std::string("foo") | |
343 | ); | |
344 | test::f( | |
345 | boost::make_tuple(0, std::string("foo")) | |
346 | , 0 | |
347 | , std::string("foo") | |
348 | ); | |
349 | test::f( | |
350 | boost::make_tuple(0, std::string("foo")) | |
351 | , std::string("foo") | |
352 | , 0 | |
353 | ); | |
354 | test::f( | |
355 | boost::make_tuple(0, std::string("foo")) | |
356 | , test::_y = std::string("foo") | |
357 | , 0 | |
358 | ); | |
359 | test::f( | |
360 | boost::make_tuple(0, std::string("foo")) | |
361 | , test::_x = 0 | |
362 | , std::string("foo") | |
363 | ); | |
364 | test::f( | |
365 | boost::make_tuple(0, std::string("foo")) | |
366 | , 0 | |
367 | , test::_y = std::string("foo") | |
368 | ); | |
369 | test::g( | |
370 | boost::make_tuple(0, std::string("foo"), test::X()) | |
371 | , test::_x = 0 | |
372 | , test::_y = std::string("foo") | |
373 | ); | |
374 | test::g( | |
375 | boost::make_tuple(0, std::string("foo"), test::X()) | |
376 | , 0 | |
377 | , std::string("foo") | |
378 | ); | |
379 | test::g( | |
380 | boost::make_tuple(0, std::string("foo"), test::X()) | |
381 | , std::string("foo") | |
382 | , 0 | |
383 | ); | |
384 | test::g( | |
385 | boost::make_tuple(0, std::string("foo"), test::X()) | |
386 | , test::_y = std::string("foo") | |
387 | , 0 | |
388 | ); | |
389 | test::g( | |
390 | boost::make_tuple(0, std::string("foo"), test::X()) | |
391 | , test::_x = 0 | |
392 | , std::string("foo") | |
393 | ); | |
394 | test::g( | |
395 | boost::make_tuple(0, std::string("foo"), test::X()) | |
396 | , 0 | |
397 | , test::_y = std::string("foo") | |
398 | ); | |
399 | test::g( | |
400 | boost::make_tuple(0, std::string("foo"), test::X(1)) | |
401 | , 0 | |
402 | , test::_y = std::string("foo") | |
403 | , test::X(1) | |
404 | ); | |
405 | test::g( | |
406 | boost::make_tuple(0, std::string("foo"), test::X(1)) | |
407 | , test::X(1) | |
408 | , 0 | |
409 | , test::_y = std::string("foo") | |
410 | ); | |
411 | ||
412 | std::map<char const*,std::string> k2s; | |
413 | #if !defined(BOOST_NO_SFINAE) | |
414 | char const* keys[] = {"foo", "bar", "baz"}; | |
415 | BOOST_TEST_EQ(1, test::sfinae(keys[0])); | |
416 | BOOST_TEST_EQ(0, test::sfinae(0)); | |
417 | #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) || \ | |
418 | !BOOST_WORKAROUND(BOOST_MSVC, < 1800) | |
419 | k2s[keys[0]] = std::string("qux"); | |
420 | k2s[keys[1]] = std::string("wmb"); | |
421 | k2s[keys[2]] = std::string("zxc"); | |
422 | test::char_reader r(keys[0], 0); | |
423 | BOOST_TEST_EQ('q', (r(k2s, true))); | |
424 | BOOST_TEST_EQ('f', (r(k2s, false))); | |
425 | r(keys[1], 1); | |
426 | BOOST_TEST_EQ('m', (r(k2s, true))); | |
427 | BOOST_TEST_EQ('a', (r(k2s, false))); | |
428 | r(keys[2], 2); | |
429 | BOOST_TEST_EQ('c', (r(k2s, true))); | |
430 | BOOST_TEST_EQ('z', (r(k2s, false))); | |
431 | #endif // MSVC-11.0- | |
432 | #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) | |
433 | BOOST_TEST_EQ(keys[1], test::return_y(2, k2s, keys[1])); | |
434 | #endif | |
435 | #endif // BOOST_NO_SFINAE | |
436 | ||
437 | #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) | |
438 | BOOST_TEST_EQ(keys[1], test::return_y(2, k2s, keys[1])); | |
7c673cae FG |
439 | #endif |
440 | ||
92f5a8d4 | 441 | return boost::report_errors(); |
7c673cae FG |
442 | } |
443 |