Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / move / test / copy_move_optimization.cpp
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 #include <boost/move/detail/config_begin.hpp>
12 #include <boost/move/utility_core.hpp>
13 #include <iostream>
14
15 bool moved = false;
16
17 class 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
55 obj        rvalue_func()       { return obj(); }
56 const obj  const_rvalue_func() { return obj();  }
57 obj&       lvalue_func()       { static obj o;  return o; }
58 const obj& const_lvalue_func() { static obj o; return o; }
59
60 obj produce()     { return obj(); }
61
62 void consume(obj){}
63
64 int 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>(rvalue_func());
81
82    obj o7 = boost::move(lvalue_func());
83    obj o8 = boost::move(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>(rvalue_func());
93    o = boost::move(const_rvalue_func());
94    o = boost::move(lvalue_func());
95    o = boost::move(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
107 #include <boost/move/detail/config_end.hpp>