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()99void 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