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)
6 #include <boost/parameter/preprocessor.hpp>
7 #include <boost/parameter/binding.hpp>
8 #include <boost/parameter/config.hpp>
11 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
12 #include <type_traits>
14 #include <boost/mpl/bool.hpp>
15 #include <boost/mpl/if.hpp>
16 #include <boost/type_traits/is_same.hpp>
21 BOOST_PARAMETER_BASIC_FUNCTION((int), f
, test::tag
,
32 typedef typename
boost::parameter::binding
<
33 Args
,test::tag::index
,int&
36 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
38 std::is_same
<index_type
,int&>::value
39 , "index_type == int&"
43 typename
boost::mpl::if_
<
44 boost::is_same
<index_type
,int&>
53 , args
[test::_value
| 1.f
]
54 , args
[test::_index
| 2]
61 #include <boost/parameter/value_type.hpp>
63 #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
64 #include <boost/type_traits/remove_const.hpp>
69 BOOST_PARAMETER_BASIC_FUNCTION((int), g
, test::tag
,
80 typedef typename
boost::parameter::value_type
<
81 Args
,test::tag::index
,int
84 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
87 typename
std::remove_const
<index_type
>::type
90 , "remove_const<index_type>::type == int"
94 typename
boost::mpl::if_
<
96 typename
boost::remove_const
<index_type
>::type
107 , args
[test::_value
| 1.f
]
108 , args
[test::_index
| 2]
115 #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
116 #include <boost/type_traits/remove_reference.hpp>
121 BOOST_PARAMETER_FUNCTION((int), h
, test::tag
,
132 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
135 typename
std::remove_const
<
136 typename
std::remove_reference
<index_type
>::type
140 , "remove_cref<index_type>::type == int"
142 #elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \
143 !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
145 typename
boost::mpl::if_
<
147 typename
boost::remove_const
<
148 typename
boost::remove_reference
<index_type
>::type
156 #endif // BOOST_PARAMETER_CAN_USE_MP11 || Borland/MSVC workarounds not needed
158 tester(name
, value
, index
);
163 BOOST_PARAMETER_FUNCTION((int), h2
, test::tag
,
170 (index
, (int), static_cast<int>(value
* 2))
174 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
177 typename
std::remove_const
<
178 typename
std::remove_reference
<index_type
>::type
182 , "remove_cref<index_type>::type == int"
184 #elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \
185 !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
187 typename
boost::mpl::if_
<
189 typename
boost::remove_const
<
190 typename
boost::remove_reference
<index_type
>::type
198 #endif // BOOST_PARAMETER_CAN_USE_MP11 || Borland/MSVC workarounds not needed
200 tester(name
, value
, index
);
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>
224 template <typename 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
>
234 >::type
* = BOOST_PARAMETER_AUX_PP_NULLPTR
235 #endif // BOOST_NO_SFINAE
236 ) : f(args
[test::_value
| 1.f
]), i(args
[test::_index
| 2])
241 struct class_0
: test::base_0
243 BOOST_PARAMETER_CONSTRUCTOR(class_0
, (test::base_0
), test::tag
,
250 BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((int), test::tag
,
257 this->f
= args
[test::_value
| 2.f
];
258 this->i
= args
[test::_index
| 1];
265 template <typename 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
>
273 typename
boost::mpl::if_
<
274 boost::is_base_of
<base_1
,Args
>
279 >::type
* = BOOST_PARAMETER_AUX_PP_NULLPTR
280 #endif // BOOST_NO_SFINAE
285 , args
[test::_value
| 1.f
]
286 , args
[test::_index
| 2]
291 struct class_1
: test::base_1
293 BOOST_PARAMETER_CONSTRUCTOR(class_1
, (test::base_1
), test::tag
,
304 BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f
, test::tag
,
317 , args
[test::_value
| 1.f
]
318 , args
[test::_index
| 2]
324 BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f
, test::tag
,
337 , args
[test::_value
| 1.f
]
338 , args
[test::_index
| 2]
344 BOOST_PARAMETER_MEMBER_FUNCTION((int), f2
, test::tag
,
355 tester(name
, value
, index
);
359 BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2
, test::tag
,
370 tester(name
, value
, index
);
374 BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static
, test::tag
,
385 tester(name
, value
, index
);
389 BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((int), test::tag
,
400 tester(name
, value
, index
);
404 BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((int), test::tag
,
415 tester(name
, value
, index
);
420 BOOST_PARAMETER_FUNCTION((int), sfinae
, test::tag
,
422 (name
, (std::string
))
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)
440 typename
boost::mpl::if_
<
441 boost::is_same
<int,A0
>
452 #endif // BOOST_NO_SFINAE
456 template <typename T
, typename Args
>
457 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
458 using fn
= std::is_convertible
<T
,std::string
>;
462 boost::is_convertible
<T
,std::string
>
470 BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), test::tag
,
477 return args
[test::_value
] < args
[test::_index
];
481 BOOST_PARAMETER_FUNCTION((int), sfinae1
, test::tag
,
483 (name
, *(test::predicate
))
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)
501 typename
boost::mpl::if_
<
502 boost::is_same
<int,A0
>
509 sfinae1(A0
const& a0
)
513 #endif // BOOST_NO_SFINAE
517 udt(int foo_
, int bar_
) : foo(foo_
), bar(bar_
)
525 BOOST_PARAMETER_FUNCTION((int), lazy_defaults
, test::tag
,
539 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
540 #include <boost/parameter/aux_/as_lvalue.hpp>
543 #include <boost/core/lightweight_test.hpp>
548 test::values(std::string("foo"), 1.f
, 2)
552 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
553 , test::_name
= std::string("foo")
556 int index_lvalue
= 2;
559 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
560 , test::_name
= std::string("foo")
562 , test::_index
= index_lvalue
566 test::values(std::string("foo"), 1.f
, 2)
573 test::values(std::string("foo"), 1.f
, 2)
576 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
577 , boost::parameter::aux::as_lvalue(2)
584 test::values(std::string("foo"), 1.f
, 2)
587 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
588 , boost::parameter::aux::as_lvalue(2)
595 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
596 , test::_name
= std::string("foo")
602 BOOST_TEST(2 == u
.i
);
603 BOOST_TEST(1.f
== u
.f
);
607 BOOST_TEST(1 == u
.i
);
608 BOOST_TEST(2.f
== u
.f
);
611 test::values(std::string("foo"), 1.f
, 2)
616 x
.f(test::values(std::string("foo"), 1.f
, 2), std::string("foo"));
618 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
619 , test::_name
= std::string("foo")
621 x
.f2(test::values(std::string("foo"), 1.f
, 2), std::string("foo"));
623 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
624 , test::_name
= std::string("foo")
626 x(test::values(std::string("foo"), 1.f
, 2), std::string("foo"));
628 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
629 , test::_name
= std::string("foo")
632 test::class_1
const& x_const
= x
;
634 x_const
.f(test::values(std::string("foo"), 1.f
, 2), std::string("foo"));
636 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
637 , test::_name
= std::string("foo")
639 x_const
.f2(test::values(std::string("foo"), 1.f
, 2), std::string("foo"));
641 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
642 , test::_name
= std::string("foo")
644 test::class_1::f_static(
645 test::values(std::string("foo"), 1.f
, 2)
648 test::class_1::f_static(
649 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
650 , test::_name
= std::string("foo")
652 x_const(test::values(std::string("foo"), 1.f
, 2), std::string("foo"));
654 test::_tester
= test::values(std::string("foo"), 1.f
, 2)
655 , test::_name
= std::string("foo")
659 test::predicate
const& p_const
= p
;
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));
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);
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);
681 BOOST_TEST(test::sfinae1(1) == 0);
684 test::lazy_defaults(test::_name
= test::udt(0, 1));
685 test::lazy_defaults(test::_name
= 0, test::_value
= 1, test::_index
= 2);
687 return boost::report_errors();