// Copyright David Abrahams, Daniel Wallin 2003. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #if (BOOST_PARAMETER_MAX_ARITY < 2) #error Define BOOST_PARAMETER_MAX_ARITY as 2 or greater. #endif #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 3) #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ as 3 or greater. #endif #endif #include namespace test { BOOST_PARAMETER_NAME((name, keywords) in(name)) BOOST_PARAMETER_NAME((value, keywords) in(value)) } // namespace test #if defined(BOOST_PARAMETER_CAN_USE_MP11) #include #else #include #include #include #endif namespace test { template struct f_predicate { template #if defined(BOOST_PARAMETER_CAN_USE_MP11) using fn = std::is_convertible; #else struct apply : boost::mpl::if_< boost::is_convertible , boost::mpl::true_ , boost::mpl::false_ > { }; #endif }; } // namespace test #include #include #include namespace test { struct f_parameters : boost::parameter::parameters< boost::parameter::optional< test::keywords::name , test::f_predicate > , boost::parameter::optional< test::keywords::value , test::f_predicate > > { }; } // namespace test #include namespace test { // The use of assert_equal_string is just a nasty workaround for a // vc++ 6 ICE. void assert_equal_string(std::string x, std::string y) { BOOST_TEST(x == y); } template void f_impl(P const& p) { float v = p[test::value | 3.f]; BOOST_TEST_EQ(v, 3.f); test::assert_equal_string(p[test::name | "bar"], "foo"); } void f() { test::f_impl(f_parameters()()); } } // namespace test #include namespace test { template void f( A0 const& a0 , BOOST_PARAMETER_MATCH(f_parameters, (A0), args) ) { test::f_impl(args(a0)); } template void f( A0 const& a0 , A1 const& a1 , BOOST_PARAMETER_MATCH(f_parameters, (A0)(A1), args) ) { test::f_impl(args(a0, a1)); } } // namespace test #if !defined(BOOST_NO_SFINAE) && \ !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) #include #if !defined(BOOST_PARAMETER_CAN_USE_MP11) #include #endif namespace test { // On compilers that actually support SFINAE, add another overload that is // an equally good match and can only be in the overload set when the // others are not. This tests that the SFINAE is actually working. On // all other compilers we're just checking that everything about // SFINAE-enabled code will work, except of course the SFINAE. template typename boost::enable_if< #if defined(BOOST_PARAMETER_CAN_USE_MP11) std::is_same #else typename boost::mpl::if_< boost::is_same , boost::mpl::true_ , boost::mpl::false_ >::type #endif , int >::type f(A0 const& a0, A1 const& a1) { return 0; } } // namespace test #endif // SFINAE enabled, no Borland workarounds needed. int main() { test::f("foo"); test::f("foo", 3.f); test::f(test::value = 3.f, test::name = "foo"); #if !defined(BOOST_NO_SFINAE) && \ !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) BOOST_TEST_EQ(0, test::f(3, 4)); #endif return boost::report_errors(); }