// Copyright Rene Rivera 2006. // Copyright Cromwell D. Enage 2017. // 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 #include namespace param { BOOST_PARAMETER_NESTED_KEYWORD(tag, a0, a_zero) BOOST_PARAMETER_NESTED_KEYWORD(tag, a1, a_one) BOOST_PARAMETER_NAME(a2) BOOST_PARAMETER_NAME(a3) BOOST_PARAMETER_NAME(in(lrc)) BOOST_PARAMETER_NAME(out(lr)) #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) BOOST_PARAMETER_NAME(consume(rr)) #else BOOST_PARAMETER_NAME(rr) #endif } #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) #include #else #include #endif namespace test { struct A { int i; int j; template A(ArgPack const& args) : i(args[param::a0]), j(args[param::a1]) { BOOST_MPL_ASSERT((boost::parameter::is_argument_pack)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::a0 > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::a1 > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); } }; float F() { return 4.0f; } float E() { return 4.625f; } double D() { return 198.9; } struct C { struct result_type { double operator()() const { return 2.5; } }; result_type operator()() const { return result_type(); } }; struct B : A { #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) boost::function k; boost::function l; #else std::function k; std::function l; #endif template B(ArgPack const& args) : A((args, param::tag::a0::a_zero = 1)) , k(args[param::_a2 | E]) , l(args[param::_a3 || C()]) { } }; struct G { int i; int& j; int const& k; template G(ArgPack const& args) : i(args[param::_rr]) , j(args[param::_lr]) , k(args[param::_lrc]) { BOOST_MPL_ASSERT((boost::parameter::is_argument_pack)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::rr > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::lr > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::lrc > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); } }; } // namespace test #include namespace test { std::pair const& lvalue_const_pair() { static std::pair const clp = std::pair(7, 10); return clp; } struct H { std::pair i; std::pair& j; std::pair const& k; template H(ArgPack const& args) : i(args[param::_rr | test::lvalue_const_pair()]) , j(args[param::_lr]) , k(args[param::_lrc]) { BOOST_MPL_ASSERT((boost::parameter::is_argument_pack)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT((boost::mpl::has_key)); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( boost::mpl::equal_to< typename boost::mpl::count::type , boost::mpl::int_<1> > )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::lr > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::key_type::type , param::tag::lrc > , boost::mpl::true_ , boost::mpl::false_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); BOOST_MPL_ASSERT(( typename boost::mpl::if_< boost::is_same< typename boost::mpl ::order::type , boost::mpl::void_ > , boost::mpl::false_ , boost::mpl::true_ >::type )); } }; } // namespace test #include int main() { #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && \ BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \ BOOST_WORKAROUND(BOOST_MSVC, < 1800) // MSVC 11.0 on AppVeyor fails without this workaround. test::A a(( param::a0 = 1 , param::a1 = 13 , param::_a2 = std::function(test::D) )); #else test::A a((param::a0 = 1, param::a1 = 13, param::_a2 = test::D)); #endif BOOST_TEST_EQ(1, a.i); BOOST_TEST_EQ(13, a.j); #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && \ BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \ BOOST_WORKAROUND(BOOST_MSVC, < 1800) // MSVC 11.0 on AppVeyor fails without this workaround. test::B b0(( param::tag::a1::a_one = 13 , param::_a2 = std::function(test::F) )); #else test::B b0((param::tag::a1::a_one = 13, param::_a2 = test::F)); #endif BOOST_TEST_EQ(1, b0.i); BOOST_TEST_EQ(13, b0.j); BOOST_TEST_EQ(4.0f, b0.k()); BOOST_TEST_EQ(2.5, b0.l()); #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && \ BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \ BOOST_WORKAROUND(BOOST_MSVC, < 1800) // MSVC 11.0 on AppVeyor fails without this workaround. test::B b1(( param::_a3 = std::function(test::D) , param::a1 = 13 )); #else test::B b1((param::_a3 = test::D, param::a1 = 13)); #endif BOOST_TEST_EQ(1, b1.i); BOOST_TEST_EQ(13, b1.j); BOOST_TEST_EQ(4.625f, b1.k()); BOOST_TEST_EQ(198.9, b1.l()); int x = 23; int const y = 42; #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_0) test::G g((param::_lr = 15, param::_rr = 16, param::_lrc = y)); #else test::G g((param::_lr = x, param::_rr = 16, param::_lrc = y)); #endif BOOST_TEST_EQ(16, g.i); BOOST_TEST_EQ(23, g.j); BOOST_TEST_EQ(42, g.k); x = 1; BOOST_TEST_EQ(1, g.j); std::pair p1(8, 9); std::pair const p2(11, 12); test::H h0((param::_lr = p1, param::_lrc = p2)); #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_1) test::H h1(( param::_lr = p2 , param::_rr = std::make_pair(7, 10) , param::_lrc = p2 )); #else test::H h1(( param::_lr = p1 , param::_rr = std::make_pair(7, 10) , param::_lrc = p2 )); #endif BOOST_TEST_EQ(h0.i.first, h1.i.first); BOOST_TEST_EQ(h0.i.second, h1.i.second); BOOST_TEST_EQ(p1.first, h1.j.first); BOOST_TEST_EQ(p1.second, h1.j.second); BOOST_TEST_EQ(p2.first, h1.k.first); BOOST_TEST_EQ(p2.second, h1.k.second); p1.first = 1; BOOST_TEST_EQ(p1.first, h1.j.first); return boost::report_errors(); }