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
7// For more information, see http://www.boost.org
8
9#include <boost/function.hpp>
10#include <boost/move/move.hpp>
11#include <boost/core/lightweight_test.hpp>
12#include <iostream>
13#include <cstdlib>
14
15#define BOOST_CHECK BOOST_TEST
16
17class only_movable {
18private:
19 BOOST_MOVABLE_BUT_NOT_COPYABLE(only_movable)
20 int value_;
21 bool moved_;
22
23public:
24 only_movable(BOOST_RV_REF(only_movable) x)
25 : value_(x.value_)
26 , moved_(false)
27 {
28 x.moved_ = true;
29 }
30
31 only_movable& operator=(BOOST_RV_REF(only_movable) x) {
32 value_ = x.value_;
33 x.moved_ = true;
34 moved_ = false;
35 return *this;
36 }
37
38 explicit only_movable(int value = 0) : value_(value), moved_(false) {}
39 int get_value() const { return value_; }
40 bool is_moved() const { return moved_; }
41};
42
43
44int one(BOOST_RV_REF(only_movable) v) { return v.get_value(); }
45only_movable two(BOOST_RV_REF(only_movable) t) {
46 only_movable t1 = boost::move(t);
47 return BOOST_MOVE_RET(only_movable, t1);
48}
49
50only_movable two_sum(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) {
51 only_movable ret(t1.get_value() + t2.get_value());
52 return BOOST_MOVE_RET(only_movable, ret);
53}
54
55struct sum_struct {
56 only_movable operator()(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) const {
57 only_movable ret(t1.get_value() + t2.get_value());
58 return BOOST_MOVE_RET(only_movable, ret);
59 }
60};
61
62int three(std::string&&) { return 1; }
63std::string&& four(std::string&& s) { return boost::move(t&: s); }
64
65int main()
66{
67 using boost::function;
68
69 function <int(BOOST_RV_REF(only_movable))> f1 = one;
70
71 only_movable om1(1);
72 BOOST_CHECK(f1(boost::move(om1)) == 1);
73
74 function <only_movable(BOOST_RV_REF(only_movable))> f2 = two;
75
76 only_movable om2(2);
77 only_movable om2_2 = f2(boost::move(t&: om2));
78 BOOST_CHECK(om2_2.get_value() == 2);
79 BOOST_CHECK(om2.is_moved());
80
81 {
82 function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = two_sum;
83 only_movable om1_sum(1), om2_sum(2);
84 only_movable om2_sum_2 = f2_sum(boost::move(t&: om1_sum), boost::move(t&: om2_sum));
85 BOOST_CHECK(om2_sum_2.get_value() == 3);
86 }
87
88 {
89 sum_struct s;
90 function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = s;
91 only_movable om1_sum(1), om2_sum(2);
92 only_movable om2_sum_2 = f2_sum(boost::move(t&: om1_sum), boost::move(t&: om2_sum));
93 BOOST_CHECK(om2_sum_2.get_value() == 3);
94 }
95
96 function <int(std::string&&)> f3 = three;
97 function <std::string&& (std::string&& s)> f4 = four;
98
99 f3(std::string("Hello"));
100 BOOST_CHECK(f4(std::string("world")) == "world");
101
102 return boost::report_errors();
103}
104

source code of boost/libs/function/test/rvalues_test.cpp