summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/move/test/copy_move_optimization.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/move/test/copy_move_optimization.cpp')
-rw-r--r--src/boost/libs/move/test/copy_move_optimization.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/boost/libs/move/test/copy_move_optimization.cpp b/src/boost/libs/move/test/copy_move_optimization.cpp
new file mode 100644
index 00000000..06d18475
--- /dev/null
+++ b/src/boost/libs/move/test/copy_move_optimization.cpp
@@ -0,0 +1,107 @@
+//We need to declare:
+//
+//2 conversions: rv<T> & and const rv<T> &
+//1 rv<T> & constructor: move constructor
+//1 const rv<T> & constructor: copy constructor
+//1 T & constructor: copy constructor
+//
+//Optimization:
+//Since RVO is better than move-construction,
+//avoid copy constructor overloading.
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+#include <iostream>
+
+bool moved = false;
+
+class obj
+{
+ BOOST_COPYABLE_AND_MOVABLE(obj)
+ public:
+
+ obj()
+ {
+ std::cout << "constructing obj" << "\n";
+ }
+
+ ~obj()
+ {}
+
+ obj(const obj &)
+ {
+ std::cout << "copy construct from const obj" << "\n";
+ }
+
+ // copy construct from movable object (non-const rvalue, explicitly moved lvalue)
+ obj(BOOST_RV_REF(obj))
+ {
+ std::cout << "move construct from movable rvalue" << "\n";
+ }
+
+ obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
+ {
+ std::cout << "copy assign from const obj" << "\n";
+ return *this;
+ }
+
+ obj& operator =(BOOST_RV_REF(obj))
+ {
+ std::cout << "move assign from movable rvalue" << "\n";
+ return *this;
+ }
+};
+
+
+obj rvalue_func() { return obj(); }
+const obj const_rvalue_func() { return obj(); }
+obj& lvalue_func() { static obj o; return o; }
+const obj& const_lvalue_func() { static obj o; return o; }
+
+obj produce() { return obj(); }
+
+void consume(obj){}
+
+int main()
+{
+ { consume(produce()); }
+ { obj o = produce(); }
+ { obj o(produce()); }
+ {
+ obj o1(rvalue_func());
+ obj o2 = const_rvalue_func();
+ obj o3 = lvalue_func();
+ obj o4 = const_lvalue_func();
+ // can't explicitly move temporaries
+ //obj o5 = boost::move(rvalue_func());
+ obj o5;
+ //Maybe missed optimization: copied
+ o5 = rvalue_func();
+ //Explicit forward works OK and optimized
+ o5 = boost::forward<obj>(rvalue_func());
+
+ obj o7 = boost::move(lvalue_func());
+ obj o8 = boost::move(const_lvalue_func());
+
+ obj o;
+ o = rvalue_func();
+ o = const_rvalue_func();
+ o = lvalue_func();
+ o = const_lvalue_func();
+ // can't explicitly move temporaries
+ //o = boost::move(rvalue_func());
+ o = boost::forward<obj>(rvalue_func());
+ o = boost::move(const_rvalue_func());
+ o = boost::move(lvalue_func());
+ o = boost::move(const_lvalue_func());
+ }
+ return 0;
+}
+
+//We need to declare:
+//
+//2 conversions: rv<T> & and const rv<T> &
+//1 rv<T> & constructor: move constructor
+//1 const rv<T> & constructor: copy constructor
+//1 T & constructor: copy constructor
+
+#include <boost/move/detail/config_end.hpp>