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
19namespace 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
67namespace 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
119namespace 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
217namespace 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
545int 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

source code of boost/libs/parameter/test/preprocessor.cpp