diff --git a/include/boost/bind/apply.hpp b/include/boost/bind/apply.hpp index 6a43a89..5c315ac 100644 --- a/include/boost/bind/apply.hpp +++ b/include/boost/bind/apply.hpp @@ -11,6 +11,8 @@ // http://www.boost.org/LICENSE_1_0.txt) // +#include + namespace boost { @@ -18,6 +20,15 @@ template struct apply { typedef R result_type; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template result_type operator()( F&& f, A&&... a ) const + { + return static_cast( f )( static_cast( a )... ); + } + +#else + template result_type operator()(F & f) const { return f(); @@ -67,6 +78,8 @@ template struct apply { return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); } + +#endif }; } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9b62451..d8551bf 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -81,3 +81,4 @@ run bind_noexcept_mf2_test.cpp ; run std_placeholders_test.cpp ; run apply_test.cpp ; run apply_test2.cpp ; +run apply_rv_test.cpp ; diff --git a/test/apply_rv_test.cpp b/test/apply_rv_test.cpp new file mode 100644 index 0000000..50d0ca6 --- /dev/null +++ b/test/apply_rv_test.cpp @@ -0,0 +1,77 @@ +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_RVALUE_REFERENCES is defined") +int main() {} + +#elif defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined") +int main() {} + +#else + +struct F +{ +public: + + int operator()( int & x ) const + { + return x; + } + + int operator()( int && x ) const + { + return -x; + } +}; + +int& get_lvalue_arg() +{ + static int a = 1; + return a; +} + +int get_prvalue_arg() +{ + return 2; +} + +F& get_lvalue_f() +{ + static F f; + return f; +} + +F get_prvalue_f() +{ + return F(); +} + +int main() +{ + using namespace boost::placeholders; + + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(get_lvalue_f), boost::bind(get_lvalue_arg))(), 1 ); + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(get_lvalue_f), boost::bind(get_prvalue_arg))(), -2 ); + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(get_prvalue_f), boost::bind(get_lvalue_arg))(), 1 ); + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(get_prvalue_f), boost::bind(get_prvalue_arg))(), -2 ); + + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(boost::apply(), _1), boost::bind(boost::apply(), _2))(get_lvalue_f, get_lvalue_arg), 1 ); + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(boost::apply(), _1), boost::bind(boost::apply(), _2))(get_lvalue_f, get_prvalue_arg), -2 ); + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(boost::apply(), _1), boost::bind(boost::apply(), _2))(get_prvalue_f, get_lvalue_arg), 1 ); + BOOST_TEST_EQ( boost::bind(boost::apply(), boost::bind(boost::apply(), _1), boost::bind(boost::apply(), _2))(get_prvalue_f, get_prvalue_arg), -2 ); + + return boost::report_errors(); +} + +#endif