1//We need to declare:
2//
3//2 conversions: rv<T> & and const rv<T> &
4//1 rv<T> & constructor: move constructor
5//1 const rv<T> & constructor: copy constructor
6//1 T & constructor: copy constructor
7//
8//Optimization:
9//Since RVO is better than move-construction,
10//avoid copy constructor overloading.
11
12#include <boost/move/utility_core.hpp>
13#include <iostream>
14
15bool moved = false;
16
17class obj
18{
19 BOOST_COPYABLE_AND_MOVABLE(obj)
20 public:
21
22 obj()
23 {
24 std::cout << "constructing obj" << "\n";
25 }
26
27 ~obj()
28 {}
29
30 obj(const obj &)
31 {
32 std::cout << "copy construct from const obj" << "\n";
33 }
34
35 // copy construct from movable object (non-const rvalue, explicitly moved lvalue)
36 obj(BOOST_RV_REF(obj))
37 {
38 std::cout << "move construct from movable rvalue" << "\n";
39 }
40
41 obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
42 {
43 std::cout << "copy assign from const obj" << "\n";
44 return *this;
45 }
46
47 obj& operator =(BOOST_RV_REF(obj))
48 {
49 std::cout << "move assign from movable rvalue" << "\n";
50 return *this;
51 }
52};
53
54
55obj rvalue_func() { return obj(); }
56const obj const_rvalue_func() { return obj(); }
57obj& lvalue_func() { static obj o; return o; }
58const obj& const_lvalue_func() { static obj o; return o; }
59
60obj produce() { return obj(); }
61
62void consume(obj){}
63
64int main()
65{
66 { consume(produce()); }
67 { obj o = produce(); }
68 { obj o(produce()); }
69 {
70 obj o1(rvalue_func());
71 obj o2 = const_rvalue_func();
72 obj o3 = lvalue_func();
73 obj o4 = const_lvalue_func();
74 // can't explicitly move temporaries
75 //obj o5 = boost::move(rvalue_func());
76 obj o5;
77 //Maybe missed optimization: copied
78 o5 = rvalue_func();
79 //Explicit forward works OK and optimized
80 o5 = boost::forward<obj>(t: rvalue_func());
81
82 obj o7 = boost::move(t&: lvalue_func());
83 obj o8 = boost::move(t: const_lvalue_func());
84
85 obj o;
86 o = rvalue_func();
87 o = const_rvalue_func();
88 o = lvalue_func();
89 o = const_lvalue_func();
90 // can't explicitly move temporaries
91 //o = boost::move(rvalue_func());
92 o = boost::forward<obj>(t: rvalue_func());
93 o = boost::move(t: const_rvalue_func());
94 o = boost::move(t&: lvalue_func());
95 o = boost::move(t: const_lvalue_func());
96 }
97 return 0;
98}
99
100//We need to declare:
101//
102//2 conversions: rv<T> & and const rv<T> &
103//1 rv<T> & constructor: move constructor
104//1 const rv<T> & constructor: copy constructor
105//1 T & constructor: copy constructor
106

source code of boost/libs/move/test/copy_move_optimization.cpp