move.hpp 2.3 KB

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