• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2012 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #include <boost/config.hpp>
8 
9 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
10 #error "Valid only on compilers that support rvalues"
11 #endif
12 
13 #include <boost/detail/lightweight_test.hpp>
14 #include <boost/static_assert.hpp>
15 #include <boost/assert.hpp>
16 #include <vector>
17 
18 
19 namespace test_detail
20 {
21     int copies = 0;
22 
incr_copy()23     void incr_copy()
24     {
25         copies++;
26     }
27 
28     struct x
29     {
30         int i;
xtest_detail::x31         x() : i(123) {}
32 
xtest_detail::x33         x(x&& rhs) : i(rhs.i) {}
34 
operator =test_detail::x35         x& operator=(x&& rhs)
36         {
37             i = rhs.i;
38             return *this;
39         }
40 
xtest_detail::x41         x(x const& /*rhs*/)
42         {
43             incr_copy();
44         }
45 
operator =test_detail::x46         x& operator=(x const& /*rhs*/)
47         {
48             incr_copy();
49             return *this;
50         }
51     };
52 
53     typedef std::vector<x> vector_type;
54     extern bool disable_rvo; // to disable RVO
55 
56     vector_type
generate_vec()57     generate_vec()
58     {
59         vector_type v;
60         v.push_back(x());
61         if (disable_rvo)
62             return v;
63         return vector_type();
64    }
65 
66 
67     template <typename T>
move_me(T && val)68     T move_me(T && val)
69     {
70         T r(std::move(val));
71         if (disable_rvo)
72             return r;
73         return T();
74     }
75 
76     typedef FUSION_SEQUENCE return_type;
77 
78     return_type
generate()79     generate()
80     {
81         return_type r(generate_vec());
82         if (disable_rvo)
83             return r;
84         return return_type();
85     }
86 
87     typedef FUSION_SEQUENCE2 return_type2;
88 
89     return_type2
generate2()90     generate2()
91     {
92         return_type2 r(generate_vec(), x());
93         if (disable_rvo)
94             return r;
95         return return_type2();
96     }
97 }
98 
test()99 void test()
100 {
101     using namespace boost::fusion;
102     using namespace test_detail;
103 
104     return_type v = move_me(generate());
105     BOOST_TEST(copies == 0);
106 
107     return_type2 v2 = move_me(generate2());
108     BOOST_TEST(copies == 0);
109 
110     v2 = move_me(generate2());
111     BOOST_TEST(copies == 0);
112 
113     std::cout << "Copies: " << copies << std::endl;
114 }
115 
116 namespace test_detail
117 {
118    bool disable_rvo = true;
119 }
120 
121