1 // Copyright 2021 Peter Dimov
2 // Distributed under the Boost Software License, Version 1.0.
3 // https://www.boost.org/LICENSE_1_0.txt
4 
5 #include<boost/bind/apply.hpp>
6 #include<boost/bind/bind.hpp>
7 #include <boost/core/lightweight_test.hpp>
8 #include <boost/config.hpp>
9 #include <boost/config/pragma_message.hpp>
10 
11 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
12 
13 BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_RVALUE_REFERENCES is defined")
main()14 int main() {}
15 
16 #elif defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
17 
18 BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined")
main()19 int main() {}
20 
21 #else
22 
23 struct F
24 {
25 public:
26 
operator ()F27     int operator()( int & x ) const
28     {
29         return x;
30     }
31 
operator ()F32     int operator()( int && x ) const
33     {
34         return -x;
35     }
36 };
37 
get_lvalue_arg()38 int& get_lvalue_arg()
39 {
40     static int a = 1;
41     return a;
42 }
43 
get_prvalue_arg()44 int get_prvalue_arg()
45 {
46     return 2;
47 }
48 
get_lvalue_f()49 F& get_lvalue_f()
50 {
51     static F f;
52     return f;
53 }
54 
get_prvalue_f()55 F get_prvalue_f()
56 {
57     return F();
58 }
59 
main()60 int main()
61 {
62     using namespace boost::placeholders;
63 
64     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_lvalue_f), boost::bind(get_lvalue_arg))(), 1 );
65     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_lvalue_f), boost::bind(get_prvalue_arg))(), -2 );
66     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_prvalue_f), boost::bind(get_lvalue_arg))(), 1 );
67     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_prvalue_f), boost::bind(get_prvalue_arg))(), -2 );
68 
69     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(boost::apply<F&>(), _1), boost::bind(boost::apply<int&>(), _2))(get_lvalue_f, get_lvalue_arg), 1 );
70     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(boost::apply<F&>(), _1), boost::bind(boost::apply<int>(), _2))(get_lvalue_f, get_prvalue_arg), -2 );
71     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(boost::apply<F>(), _1), boost::bind(boost::apply<int&>(), _2))(get_prvalue_f, get_lvalue_arg), 1 );
72     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(boost::apply<F>(), _1), boost::bind(boost::apply<int>(), _2))(get_prvalue_f, get_prvalue_arg), -2 );
73 
74     return boost::report_errors();
75 }
76 
77 #endif
78