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) |
5 | |
6 | #include <boost/parameter/preprocessor.hpp> |
7 | #include <boost/parameter/binding.hpp> |
8 | #include <boost/parameter/config.hpp> |
9 | #include "basics.hpp" |
10 | |
11 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
12 | #include <type_traits> |
13 | #else |
14 | #include <boost/mpl/bool.hpp> |
15 | #include <boost/mpl/if.hpp> |
16 | #include <boost/type_traits/is_same.hpp> |
17 | #endif |
18 | |
19 | namespace test { |
20 | |
21 | BOOST_PARAMETER_BASIC_FUNCTION((int), f, test::tag, |
22 | (required |
23 | (tester, *) |
24 | (name, *) |
25 | ) |
26 | (optional |
27 | (value, *) |
28 | (index, (int)) |
29 | ) |
30 | ) |
31 | { |
32 | typedef typename boost::parameter::binding< |
33 | Args,test::tag::index,int& |
34 | >::type index_type; |
35 | |
36 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
37 | static_assert( |
38 | std::is_same<index_type,int&>::value |
39 | , "index_type == int&" |
40 | ); |
41 | #else |
42 | BOOST_MPL_ASSERT(( |
43 | typename boost::mpl::if_< |
44 | boost::is_same<index_type,int&> |
45 | , boost::mpl::true_ |
46 | , boost::mpl::false_ |
47 | >::type |
48 | )); |
49 | #endif |
50 | |
51 | args[test::_tester]( |
52 | args[test::_name] |
53 | , args[test::_value | 1.f] |
54 | , args[test::_index | 2] |
55 | ); |
56 | |
57 | return 1; |
58 | } |
59 | } // namespace test |
60 | |
61 | #include <boost/parameter/value_type.hpp> |
62 | |
63 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) |
64 | #include <boost/type_traits/remove_const.hpp> |
65 | #endif |
66 | |
67 | namespace test { |
68 | |
69 | BOOST_PARAMETER_BASIC_FUNCTION((int), g, test::tag, |
70 | (required |
71 | (tester, *) |
72 | (name, *) |
73 | ) |
74 | (optional |
75 | (value, *) |
76 | (index, (int)) |
77 | ) |
78 | ) |
79 | { |
80 | typedef typename boost::parameter::value_type< |
81 | Args,test::tag::index,int |
82 | >::type index_type; |
83 | |
84 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
85 | static_assert( |
86 | std::is_same< |
87 | typename std::remove_const<index_type>::type |
88 | , int |
89 | >::value |
90 | , "remove_const<index_type>::type == int" |
91 | ); |
92 | #else |
93 | BOOST_MPL_ASSERT(( |
94 | typename boost::mpl::if_< |
95 | boost::is_same< |
96 | typename boost::remove_const<index_type>::type |
97 | , int |
98 | > |
99 | , boost::mpl::true_ |
100 | , boost::mpl::false_ |
101 | >::type |
102 | )); |
103 | #endif |
104 | |
105 | args[test::_tester]( |
106 | args[test::_name] |
107 | , args[test::_value | 1.f] |
108 | , args[test::_index | 2] |
109 | ); |
110 | |
111 | return 1; |
112 | } |
113 | } // namespace test |
114 | |
115 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) |
116 | #include <boost/type_traits/remove_reference.hpp> |
117 | #endif |
118 | |
119 | namespace test { |
120 | |
121 | BOOST_PARAMETER_FUNCTION((int), h, test::tag, |
122 | (required |
123 | (tester, *) |
124 | (name, *) |
125 | ) |
126 | (optional |
127 | (value, *, 1.f) |
128 | (index, (int), 2) |
129 | ) |
130 | ) |
131 | { |
132 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
133 | static_assert( |
134 | std::is_same< |
135 | typename std::remove_const< |
136 | typename std::remove_reference<index_type>::type |
137 | >::type |
138 | , int |
139 | >::value |
140 | , "remove_cref<index_type>::type == int" |
141 | ); |
142 | #elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ |
143 | !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) |
144 | BOOST_MPL_ASSERT(( |
145 | typename boost::mpl::if_< |
146 | boost::is_same< |
147 | typename boost::remove_const< |
148 | typename boost::remove_reference<index_type>::type |
149 | >::type |
150 | , int |
151 | > |
152 | , boost::mpl::true_ |
153 | , boost::mpl::false_ |
154 | >::type |
155 | )); |
156 | #endif // BOOST_PARAMETER_CAN_USE_MP11 || Borland/MSVC workarounds not needed |
157 | |
158 | tester(name, value, index); |
159 | |
160 | return 1; |
161 | } |
162 | |
163 | BOOST_PARAMETER_FUNCTION((int), h2, test::tag, |
164 | (required |
165 | (tester, *) |
166 | (name, *) |
167 | ) |
168 | (optional |
169 | (value, *, 1.f) |
170 | (index, (int), static_cast<int>(value * 2)) |
171 | ) |
172 | ) |
173 | { |
174 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
175 | static_assert( |
176 | std::is_same< |
177 | typename std::remove_const< |
178 | typename std::remove_reference<index_type>::type |
179 | >::type |
180 | , int |
181 | >::value |
182 | , "remove_cref<index_type>::type == int" |
183 | ); |
184 | #elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ |
185 | !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) |
186 | BOOST_MPL_ASSERT(( |
187 | typename boost::mpl::if_< |
188 | boost::is_same< |
189 | typename boost::remove_const< |
190 | typename boost::remove_reference<index_type>::type |
191 | >::type |
192 | , int |
193 | > |
194 | , boost::mpl::true_ |
195 | , boost::mpl::false_ |
196 | >::type |
197 | )); |
198 | #endif // BOOST_PARAMETER_CAN_USE_MP11 || Borland/MSVC workarounds not needed |
199 | |
200 | tester(name, value, index); |
201 | |
202 | return 1; |
203 | } |
204 | } // namespace test |
205 | |
206 | #include <string> |
207 | |
208 | #if !defined(BOOST_NO_SFINAE) |
209 | #include <boost/parameter/aux_/preprocessor/nullptr.hpp> |
210 | #include <boost/core/enable_if.hpp> |
211 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) |
212 | #include <boost/type_traits/is_base_of.hpp> |
213 | #include <boost/type_traits/is_convertible.hpp> |
214 | #endif |
215 | #endif |
216 | |
217 | namespace test { |
218 | |
219 | struct base_0 |
220 | { |
221 | float f; |
222 | int i; |
223 | |
224 | template <typename Args> |
225 | explicit base_0( |
226 | Args const& args |
227 | #if !defined(BOOST_NO_SFINAE) |
228 | , typename boost::disable_if< |
229 | typename boost::mpl::if_< |
230 | boost::is_base_of<base_0,Args> |
231 | , boost::mpl::true_ |
232 | , boost::mpl::false_ |
233 | >::type |
234 | >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR |
235 | #endif // BOOST_NO_SFINAE |
236 | ) : f(args[test::_value | 1.f]), i(args[test::_index | 2]) |
237 | { |
238 | } |
239 | }; |
240 | |
241 | struct class_0 : test::base_0 |
242 | { |
243 | BOOST_PARAMETER_CONSTRUCTOR(class_0, (test::base_0), test::tag, |
244 | (optional |
245 | (value, *) |
246 | (index, *) |
247 | ) |
248 | ) |
249 | |
250 | BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((int), test::tag, |
251 | (optional |
252 | (value, *) |
253 | (index, *) |
254 | ) |
255 | ) |
256 | { |
257 | this->f = args[test::_value | 2.f]; |
258 | this->i = args[test::_index | 1]; |
259 | return 1; |
260 | } |
261 | }; |
262 | |
263 | struct base_1 |
264 | { |
265 | template <typename Args> |
266 | explicit base_1( |
267 | Args const& args |
268 | #if !defined(BOOST_NO_SFINAE) |
269 | , typename boost::disable_if< |
270 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
271 | std::is_base_of<base_1,Args> |
272 | #else |
273 | typename boost::mpl::if_< |
274 | boost::is_base_of<base_1,Args> |
275 | , boost::mpl::true_ |
276 | , boost::mpl::false_ |
277 | >::type |
278 | #endif |
279 | >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR |
280 | #endif // BOOST_NO_SFINAE |
281 | ) |
282 | { |
283 | args[test::_tester]( |
284 | args[test::_name] |
285 | , args[test::_value | 1.f] |
286 | , args[test::_index | 2] |
287 | ); |
288 | } |
289 | }; |
290 | |
291 | struct class_1 : test::base_1 |
292 | { |
293 | BOOST_PARAMETER_CONSTRUCTOR(class_1, (test::base_1), test::tag, |
294 | (required |
295 | (tester, *) |
296 | (name, *) |
297 | ) |
298 | (optional |
299 | (value, *) |
300 | (index, *) |
301 | ) |
302 | ) |
303 | |
304 | BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, test::tag, |
305 | (required |
306 | (tester, *) |
307 | (name, *) |
308 | ) |
309 | (optional |
310 | (value, *) |
311 | (index, *) |
312 | ) |
313 | ) |
314 | { |
315 | args[test::_tester]( |
316 | args[test::_name] |
317 | , args[test::_value | 1.f] |
318 | , args[test::_index | 2] |
319 | ); |
320 | |
321 | return 1; |
322 | } |
323 | |
324 | BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, test::tag, |
325 | (required |
326 | (tester, *) |
327 | (name, *) |
328 | ) |
329 | (optional |
330 | (value, *) |
331 | (index, *) |
332 | ) |
333 | ) |
334 | { |
335 | args[test::_tester]( |
336 | args[test::_name] |
337 | , args[test::_value | 1.f] |
338 | , args[test::_index | 2] |
339 | ); |
340 | |
341 | return 1; |
342 | } |
343 | |
344 | BOOST_PARAMETER_MEMBER_FUNCTION((int), f2, test::tag, |
345 | (required |
346 | (tester, *) |
347 | (name, *) |
348 | ) |
349 | (optional |
350 | (value, *, 1.f) |
351 | (index, *, 2) |
352 | ) |
353 | ) |
354 | { |
355 | tester(name, value, index); |
356 | return 1; |
357 | } |
358 | |
359 | BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2, test::tag, |
360 | (required |
361 | (tester, *) |
362 | (name, *) |
363 | ) |
364 | (optional |
365 | (value, *, 1.f) |
366 | (index, *, 2) |
367 | ) |
368 | ) |
369 | { |
370 | tester(name, value, index); |
371 | return 1; |
372 | } |
373 | |
374 | BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static, test::tag, |
375 | (required |
376 | (tester, *) |
377 | (name, *) |
378 | ) |
379 | (optional |
380 | (value, *, 1.f) |
381 | (index, *, 2) |
382 | ) |
383 | ) |
384 | { |
385 | tester(name, value, index); |
386 | return 1; |
387 | } |
388 | |
389 | BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((int), test::tag, |
390 | (required |
391 | (tester, *) |
392 | (name, *) |
393 | ) |
394 | (optional |
395 | (value, *, 1.f) |
396 | (index, *, 2) |
397 | ) |
398 | ) |
399 | { |
400 | tester(name, value, index); |
401 | return 1; |
402 | } |
403 | |
404 | BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((int), test::tag, |
405 | (required |
406 | (tester, *) |
407 | (name, *) |
408 | ) |
409 | (optional |
410 | (value, *, 1.f) |
411 | (index, *, 2) |
412 | ) |
413 | ) |
414 | { |
415 | tester(name, value, index); |
416 | return 1; |
417 | } |
418 | }; |
419 | |
420 | BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, |
421 | (required |
422 | (name, (std::string)) |
423 | ) |
424 | ) |
425 | { |
426 | return 1; |
427 | } |
428 | |
429 | #if !defined(BOOST_NO_SFINAE) |
430 | // On compilers that actually support SFINAE, add another overload |
431 | // that is an equally good match and can only be in the overload set |
432 | // when the others are not. This tests that the SFINAE is actually |
433 | // working. On all other compilers we're just checking that everything |
434 | // about SFINAE-enabled code will work, except of course the SFINAE. |
435 | template <typename A0> |
436 | typename boost::enable_if< |
437 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
438 | std::is_same<int,A0> |
439 | #else |
440 | typename boost::mpl::if_< |
441 | boost::is_same<int,A0> |
442 | , boost::mpl::true_ |
443 | , boost::mpl::false_ |
444 | >::type |
445 | #endif |
446 | , int |
447 | >::type |
448 | sfinae(A0 const& a0) |
449 | { |
450 | return 0; |
451 | } |
452 | #endif // BOOST_NO_SFINAE |
453 | |
454 | struct predicate |
455 | { |
456 | template <typename T, typename Args> |
457 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
458 | using fn = std::is_convertible<T,std::string>; |
459 | #else |
460 | struct apply |
461 | : boost::mpl::if_< |
462 | boost::is_convertible<T,std::string> |
463 | , boost::mpl::true_ |
464 | , boost::mpl::false_ |
465 | > |
466 | { |
467 | }; |
468 | #endif |
469 | |
470 | BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), test::tag, |
471 | (required |
472 | (value, *) |
473 | (index, *) |
474 | ) |
475 | ) |
476 | { |
477 | return args[test::_value] < args[test::_index]; |
478 | } |
479 | }; |
480 | |
481 | BOOST_PARAMETER_FUNCTION((int), sfinae1, test::tag, |
482 | (required |
483 | (name, *(test::predicate)) |
484 | ) |
485 | ) |
486 | { |
487 | return 1; |
488 | } |
489 | |
490 | #if !defined(BOOST_NO_SFINAE) |
491 | // On compilers that actually support SFINAE, add another overload |
492 | // that is an equally good match and can only be in the overload set |
493 | // when the others are not. This tests that the SFINAE is actually |
494 | // working. On all other compilers we're just checking that everything |
495 | // about SFINAE-enabled code will work, except of course the SFINAE. |
496 | template <typename A0> |
497 | typename boost::enable_if< |
498 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
499 | std::is_same<int,A0> |
500 | #else |
501 | typename boost::mpl::if_< |
502 | boost::is_same<int,A0> |
503 | , boost::mpl::true_ |
504 | , boost::mpl::false_ |
505 | >::type |
506 | #endif |
507 | , int |
508 | >::type |
509 | sfinae1(A0 const& a0) |
510 | { |
511 | return 0; |
512 | } |
513 | #endif // BOOST_NO_SFINAE |
514 | |
515 | struct udt |
516 | { |
517 | udt(int foo_, int bar_) : foo(foo_), bar(bar_) |
518 | { |
519 | } |
520 | |
521 | int foo; |
522 | int bar; |
523 | }; |
524 | |
525 | BOOST_PARAMETER_FUNCTION((int), lazy_defaults, test::tag, |
526 | (required |
527 | (name, *) |
528 | ) |
529 | (optional |
530 | (value, *, name.foo) |
531 | (index, *, name.bar) |
532 | ) |
533 | ) |
534 | { |
535 | return 0; |
536 | } |
537 | } // namespace test |
538 | |
539 | #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) |
540 | #include <boost/parameter/aux_/as_lvalue.hpp> |
541 | #endif |
542 | |
543 | #include <boost/core/lightweight_test.hpp> |
544 | |
545 | int main() |
546 | { |
547 | test::f( |
548 | a0: test::values(n: std::string("foo" ), v: 1.f, i: 2) |
549 | , a1: std::string("foo" ) |
550 | ); |
551 | test::f( |
552 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
553 | , a1: test::_name = std::string("foo" ) |
554 | ); |
555 | |
556 | int index_lvalue = 2; |
557 | |
558 | test::f( |
559 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
560 | , a1: test::_name = std::string("foo" ) |
561 | , a2: test::_value = 1.f |
562 | , a3: test::_index = index_lvalue |
563 | ); |
564 | |
565 | test::f( |
566 | a0: test::values(n: std::string("foo" ), v: 1.f, i: 2) |
567 | , a1: std::string("foo" ) |
568 | , a2: 1.f |
569 | , a3&: index_lvalue |
570 | ); |
571 | |
572 | test::g( |
573 | a0: test::values(n: std::string("foo" ), v: 1.f, i: 2) |
574 | , a1: std::string("foo" ) |
575 | , a2: 1.f |
576 | #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) |
577 | , boost::parameter::aux::as_lvalue(2) |
578 | #else |
579 | , a3: 2 |
580 | #endif |
581 | ); |
582 | |
583 | test::h( |
584 | a0: test::values(n: std::string("foo" ), v: 1.f, i: 2) |
585 | , a1: std::string("foo" ) |
586 | , a2: 1.f |
587 | #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) |
588 | , boost::parameter::aux::as_lvalue(2) |
589 | #else |
590 | , a3: 2 |
591 | #endif |
592 | ); |
593 | |
594 | test::h2( |
595 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
596 | , a1: test::_name = std::string("foo" ) |
597 | , a2: test::_value = 1.f |
598 | ); |
599 | |
600 | test::class_0 u; |
601 | |
602 | BOOST_TEST(2 == u.i); |
603 | BOOST_TEST(1.f == u.f); |
604 | |
605 | u(); |
606 | |
607 | BOOST_TEST(1 == u.i); |
608 | BOOST_TEST(2.f == u.f); |
609 | |
610 | test::class_1 x( |
611 | test::values(n: std::string("foo" ), v: 1.f, i: 2) |
612 | , std::string("foo" ) |
613 | , test::_index = 2 |
614 | ); |
615 | |
616 | x.f(a0: test::values(n: std::string("foo" ), v: 1.f, i: 2), a1: std::string("foo" )); |
617 | x.f( |
618 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
619 | , a1: test::_name = std::string("foo" ) |
620 | ); |
621 | x.f2(a0: test::values(n: std::string("foo" ), v: 1.f, i: 2), a1: std::string("foo" )); |
622 | x.f2( |
623 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
624 | , a1: test::_name = std::string("foo" ) |
625 | ); |
626 | x(test::values(n: std::string("foo" ), v: 1.f, i: 2), std::string("foo" )); |
627 | x( |
628 | test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
629 | , test::_name = std::string("foo" ) |
630 | ); |
631 | |
632 | test::class_1 const& x_const = x; |
633 | |
634 | x_const.f(a0: test::values(n: std::string("foo" ), v: 1.f, i: 2), a1: std::string("foo" )); |
635 | x_const.f( |
636 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
637 | , a1: test::_name = std::string("foo" ) |
638 | ); |
639 | x_const.f2(a0: test::values(n: std::string("foo" ), v: 1.f, i: 2), a1: std::string("foo" )); |
640 | x_const.f2( |
641 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
642 | , a1: test::_name = std::string("foo" ) |
643 | ); |
644 | test::class_1::f_static( |
645 | a0: test::values(n: std::string("foo" ), v: 1.f, i: 2) |
646 | , a1: std::string("foo" ) |
647 | ); |
648 | test::class_1::f_static( |
649 | a0: test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
650 | , a1: test::_name = std::string("foo" ) |
651 | ); |
652 | x_const(test::values(n: std::string("foo" ), v: 1.f, i: 2), std::string("foo" )); |
653 | x_const( |
654 | test::_tester = test::values(n: std::string("foo" ), v: 1.f, i: 2) |
655 | , test::_name = std::string("foo" ) |
656 | ); |
657 | |
658 | test::predicate p; |
659 | test::predicate const& p_const = p; |
660 | |
661 | BOOST_TEST(p_const(3, 4)); |
662 | BOOST_TEST(!p_const(4, 3)); |
663 | BOOST_TEST(!p_const(test::_index = 3, test::_value = 4)); |
664 | |
665 | #if !defined(BOOST_NO_SFINAE) && \ |
666 | !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) |
667 | // GCC 3- tries to bind string literals |
668 | // to non-const references to char const*. |
669 | // BOOST_TEST(test::sfinae("foo") == 1); |
670 | char const* foo_str = "foo" ; |
671 | BOOST_TEST(test::sfinae(foo_str) == 1); |
672 | BOOST_TEST(test::sfinae(1) == 0); |
673 | |
674 | #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) |
675 | // Sun actually eliminates the desired overload for some reason. |
676 | // Disabling this part of the test because SFINAE abilities are |
677 | // not the point of this test. |
678 | BOOST_TEST(test::sfinae1(foo_str) == 1); |
679 | #endif |
680 | |
681 | BOOST_TEST(test::sfinae1(1) == 0); |
682 | #endif |
683 | |
684 | test::lazy_defaults(a0: test::_name = test::udt(0, 1)); |
685 | test::lazy_defaults(a0: test::_name = 0, a1: test::_value = 1, a2: test::_index = 2); |
686 | |
687 | return boost::report_errors(); |
688 | } |
689 | |
690 | |