rvalues_test.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2014 Antony Polukhin.
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. // For more information, see http://www.boost.org
  7. #include <boost/function.hpp>
  8. #include <boost/move/move.hpp>
  9. #include <boost/core/lightweight_test.hpp>
  10. #include <iostream>
  11. #include <cstdlib>
  12. #define BOOST_CHECK BOOST_TEST
  13. class only_movable {
  14. private:
  15. BOOST_MOVABLE_BUT_NOT_COPYABLE(only_movable)
  16. int value_;
  17. bool moved_;
  18. public:
  19. only_movable(BOOST_RV_REF(only_movable) x)
  20. : value_(x.value_)
  21. , moved_(false)
  22. {
  23. x.moved_ = true;
  24. }
  25. only_movable& operator=(BOOST_RV_REF(only_movable) x) {
  26. value_ = x.value_;
  27. x.moved_ = true;
  28. moved_ = false;
  29. return *this;
  30. }
  31. explicit only_movable(int value = 0) : value_(value), moved_(false) {}
  32. int get_value() const { return value_; }
  33. bool is_moved() const { return moved_; }
  34. };
  35. int one(BOOST_RV_REF(only_movable) v) { return v.get_value(); }
  36. only_movable two(BOOST_RV_REF(only_movable) t) {
  37. only_movable t1 = boost::move(t);
  38. return BOOST_MOVE_RET(only_movable, t1);
  39. }
  40. only_movable two_sum(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) {
  41. only_movable ret(t1.get_value() + t2.get_value());
  42. return BOOST_MOVE_RET(only_movable, ret);
  43. }
  44. struct sum_struct {
  45. only_movable operator()(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) const {
  46. only_movable ret(t1.get_value() + t2.get_value());
  47. return BOOST_MOVE_RET(only_movable, ret);
  48. }
  49. };
  50. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  51. int three(std::string&&) { return 1; }
  52. std::string&& four(std::string&& s) { return boost::move(s); }
  53. #endif
  54. int main()
  55. {
  56. using boost::function;
  57. function <int(BOOST_RV_REF(only_movable))> f1 = one;
  58. only_movable om1(1);
  59. BOOST_CHECK(f1(boost::move(om1)) == 1);
  60. function <only_movable(BOOST_RV_REF(only_movable))> f2 = two;
  61. only_movable om2(2);
  62. only_movable om2_2 = f2(boost::move(om2));
  63. BOOST_CHECK(om2_2.get_value() == 2);
  64. BOOST_CHECK(om2.is_moved());
  65. {
  66. function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = two_sum;
  67. only_movable om1_sum(1), om2_sum(2);
  68. only_movable om2_sum_2 = f2_sum(boost::move(om1_sum), boost::move(om2_sum));
  69. BOOST_CHECK(om2_sum_2.get_value() == 3);
  70. }
  71. {
  72. sum_struct s;
  73. function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = s;
  74. only_movable om1_sum(1), om2_sum(2);
  75. only_movable om2_sum_2 = f2_sum(boost::move(om1_sum), boost::move(om2_sum));
  76. BOOST_CHECK(om2_sum_2.get_value() == 3);
  77. }
  78. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  79. function <int(std::string&&)> f3 = three;
  80. function <std::string&& (std::string&& s)> f4 = four;
  81. f3(std::string("Hello"));
  82. BOOST_CHECK(f4(std::string("world")) == "world");
  83. #endif
  84. return boost::report_errors();
  85. }