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 #elif defined(BOOST_NO_CXX11_REF_QUALIFIERS)
22 
23 BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_REF_QUALIFIERS is defined")
main()24 int main() {}
25 
26 #else
27 
28 struct F
29 {
30 public:
31 
operator ()F32     int operator()( int & x ) &
33     {
34         return x;
35     }
36 
operator ()F37     int operator()( int && x ) &
38     {
39         return -x;
40     }
41 
operator ()F42     int operator()( int & x ) &&
43     {
44         return x + 10;
45     }
46 
operator ()F47     int operator()( int && x ) &&
48     {
49         return -x - 10;
50     }
51 };
52 
get_lvalue_arg()53 int& get_lvalue_arg()
54 {
55     static int a = 1;
56     return a;
57 }
58 
get_prvalue_arg()59 int get_prvalue_arg()
60 {
61     return 2;
62 }
63 
get_lvalue_f()64 F& get_lvalue_f()
65 {
66     static F f;
67     return f;
68 }
69 
get_prvalue_f()70 F get_prvalue_f()
71 {
72     return F();
73 }
74 
main()75 int main()
76 {
77     using namespace boost::placeholders;
78 
79     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_lvalue_f), boost::bind(get_lvalue_arg))(), 1 );
80     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_lvalue_f), boost::bind(get_prvalue_arg))(), -2 );
81     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_prvalue_f), boost::bind(get_lvalue_arg))(), 11 );
82     BOOST_TEST_EQ( boost::bind(boost::apply<int>(), boost::bind(get_prvalue_f), boost::bind(get_prvalue_arg))(), -12 );
83 
84     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 );
85     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 );
86     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), 11 );
87     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), -12 );
88 
89     return boost::report_errors();
90 }
91 
92 #endif
93