• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
obj()22    obj()
23    {
24       std::cout << "constructing obj" << "\n";
25    }
26 
~obj()27    ~obj()
28    {}
29 
obj(const obj &)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)
obj(BOOST_RV_REF (obj))36    obj(BOOST_RV_REF(obj))
37    {
38       std::cout << "move construct from movable rvalue" << "\n";
39    }
40 
operator =(BOOST_COPY_ASSIGN_REF (obj))41    obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
42    {
43       std::cout << "copy assign from const obj" << "\n";
44       return *this;
45    }
46 
operator =(BOOST_RV_REF (obj))47    obj& operator =(BOOST_RV_REF(obj))
48    {
49       std::cout << "move assign from movable rvalue" << "\n";
50       return *this;
51    }
52 };
53 
54 
rvalue_func()55 obj        rvalue_func()       { return obj(); }
const_rvalue_func()56 const obj  const_rvalue_func() { return obj();  }
lvalue_func()57 obj&       lvalue_func()       { static obj o;  return o; }
const_lvalue_func()58 const obj& const_lvalue_func() { static obj o; return o; }
59 
produce()60 obj produce()     { return obj(); }
61 
consume(obj)62 void consume(obj){}
63 
main()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>
108