Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2008-06-23 18:31:08


Author: danieljames
Date: 2008-06-23 18:31:07 EDT (Mon, 23 Jun 2008)
New Revision: 46631
URL: http://svn.boost.org/trac/boost/changeset/46631

Log:
Quirk and dirty attempt at implementing move for noncopyable types.

Doesn't seem to support passing rvalues by reference. Also needs more tests.

Added:
   sandbox/move/libs/move/test/noncopyable.cpp (contents, props changed)
   sandbox/move/libs/move/test/y.hpp (contents, props changed)
Text files modified:
   sandbox/move/boost/move.hpp | 5 ++++-
   sandbox/move/libs/move/test/Jamfile.v2 | 1 +
   2 files changed, 5 insertions(+), 1 deletions(-)

Modified: sandbox/move/boost/move.hpp
==============================================================================
--- sandbox/move/boost/move.hpp (original)
+++ sandbox/move/boost/move.hpp 2008-06-23 18:31:07 EDT (Mon, 23 Jun 2008)
@@ -117,7 +117,10 @@
 */
 template <typename T>
 struct is_movable : boost::mpl::and_<
- boost::is_convertible<move_from<T>, T>,
+ boost::mpl::or_<
+ boost::is_convertible<T, move_from<T> >,
+ boost::is_convertible<move_from<T>, T>
+ >,
                         move_detail::has_move_assign<T>,
                         boost::mpl::not_<boost::is_convertible<move_detail::test_can_convert_anything, T> >
> { };

Modified: sandbox/move/libs/move/test/Jamfile.v2
==============================================================================
--- sandbox/move/libs/move/test/Jamfile.v2 (original)
+++ sandbox/move/libs/move/test/Jamfile.v2 2008-06-23 18:31:07 EDT (Mon, 23 Jun 2008)
@@ -11,6 +11,7 @@
 test-suite "move-suite" :
     [ run main.cpp ]
     [ run move.cpp ]
+ [ run noncopyable.cpp ]
     [ run move_test.cpp ]
     [ run no_sfinae_test.cpp ]
 ;

Added: sandbox/move/libs/move/test/noncopyable.cpp
==============================================================================
--- (empty file)
+++ sandbox/move/libs/move/test/noncopyable.cpp 2008-06-23 18:31:07 EDT (Mon, 23 Jun 2008)
@@ -0,0 +1,158 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Copyright Daniel James 2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define DEBUG_MOVE
+#include <boost/move.hpp>
+#include <boost/static_assert.hpp>
+#include "say.hpp"
+#include "y.hpp"
+
+//
+// Some functions we can use to test the passing of Ys in and out of
+// functions.
+//
+Y source()
+{
+ return Y();
+}
+
+Y const csource()
+{
+ return Y();
+}
+
+void sink(Y)
+{
+ SAY("in rvalue sink");
+}
+
+void sink2(Y&)
+{
+ SAY("in non-const lvalue sink2");
+}
+
+void sink2(Y const&)
+{
+ SAY("in const lvalue sink2");
+}
+
+void sink3(Y&)
+{
+ SAY("in non-const lvalue sink3");
+}
+
+template <class T>
+void tsink(T)
+{
+ SAY("in templated rvalue sink");
+}
+
+int main()
+{
+ SAY(" ------ test 1, direct init from rvalue ------- ");
+ Y::expect_move();
+ Y z2(source());
+
+ SAY(" ------ test 2, copy init from rvalue ------- ");
+ Y::expect_move();
+ Y z4 = Y();
+
+ //SAY(" ------ test 3, copy init from lvalue ------- ");
+ //Y::expect_copy();
+ //Y z5 = z4;
+
+ //SAY(" ------ test 4, direct init from lvalue ------- ");
+ //Y::expect_copy();
+ //Y z6(z4);
+
+ SAY(" ------ test 5, construct const ------- ");
+ Y const z7;
+
+ //SAY(" ------ test 6, copy init from lvalue ------- ");
+ //Y::expect_copy();
+ //Y z8 = z7;
+ Y z8;
+
+ //SAY(" ------ test 7, direct init from lvalue ------- ");
+ //Y::expect_copy();
+ //Y z9(z7);
+ Y z9;
+
+ SAY(" ------ test 8, pass rvalue by-value ------- ");
+ Y::expect_move();
+ sink(source());
+
+ SAY(" ------ test 9, pass const rvalue by-value ------- ");
+ Y::expect_move();
+ sink(csource());
+
+ // TODO: Why do these fail?
+
+ //SAY(" ------ test 10, pass rvalue by overloaded reference ------- ");
+ //Y::expect_move();
+ //sink2(source());
+
+ //SAY(" ------ test 11, pass const rvalue by overloaded reference ------- ");
+ //Y::expect_move();
+ //sink2(csource());
+
+ //SAY(" ------ test 13, pass lvalue by-value ------- ");
+ //Y::expect_copy();
+ //sink(z5);
+
+ //SAY(" ------ test 14, pass const lvalue by-value ------- ");
+ //Y::expect_copy();
+ //sink(z7);
+
+ SAY(" ------ test 15, pass lvalue by-reference ------- ");
+ Y::expect_copy();
+ sink2(z4);
+
+ SAY(" ------ test 16, pass const lvalue by const reference ------- ");
+ Y::expect_copy();
+ sink2(z7);
+
+ SAY(" ------ test 17, pass rvalue by value to template param ------- ");
+ Y::expect_move();
+ tsink(source());
+
+ //SAY(" ------ test 18, direct initialize a const Y with an Y ------- ");
+ //Y::expect_move();
+ //typedef Y const YC;
+ //sink2(YC(Y()));
+
+ //SAY(" ------ test 19, assign from non-const lvalue ------- ");
+ //Y::expect_copy();
+ //z4 = z5;
+
+ //SAY(" ------ test 20, assign from const lvalue ------- ");
+ //Y::expect_copy();
+ //z4 = z7;
+
+ SAY(" ------ test 21, assign from rvalue ------- ");
+ Y::expect_move();
+ z4 = source();
+
+ SAY(" ------ test 22, explicit move direct init from movable lvalue ------- ");
+ BOOST_STATIC_ASSERT(boost::is_movable<Y>::value);
+ Y::expect_move();
+ Y z10(boost::move(z2));
+
+ SAY(" ------ test 23, explicit move copy init from movable lvalue ------- ");
+ Y::expect_move();
+ Y z11 = boost::move(z9);
+
+ SAY(" ------ test 24, move assign from movable lvalue ------- ");
+ Y::expect_move();
+ z10 = boost::move(z8);
+
+ SAY(" ------ test 25, request move construct from non-movable lvalue ------- ");
+ BOOST_STATIC_ASSERT(!boost::is_movable<std::string>::value);
+ std::string s1("hello");
+ std::string s2(boost::move(s1));
+
+ SAY("----- done, with " << Y::suboptimal_copies << " suboptimal copies -----");
+ return 0;
+}

Added: sandbox/move/libs/move/test/y.hpp
==============================================================================
--- (empty file)
+++ sandbox/move/libs/move/test/y.hpp 2008-06-23 18:31:07 EDT (Mon, 23 Jun 2008)
@@ -0,0 +1,113 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Copyright Daniel James 2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef Y_DWA2004410_HPP
+# define Y_DWA2004410_HPP
+
+# include <boost/move.hpp>
+# include <boost/assert.hpp>
+# include "say.hpp"
+
+//
+// A sample movable class.
+//
+class Y
+{
+ Y(Y& rhs);
+ public: // "Ordinary" stuff
+ Y() : resource(++cnt)
+ {
+ SAY("Y() #" << resource);
+ }
+
+ ~Y()
+ {
+ release();
+ }
+
+ public: // Move stuff
+ // move constructor
+ Y(boost::move_from<Y> rhs)
+ : resource(rhs.source.resource)
+ {
+ BOOST_ASSERT(rhs.source.resource <= cnt); // check for garbage
+ SAY("MOVE #" << resource);
+ BOOST_ASSERT(move_expected);
+ rhs.source.resource = 0;
+ BOOST_ASSERT(resource);
+ }
+
+ // move assignment
+ Y& operator=(Y rhs)
+ {
+ BOOST_ASSERT(rhs.resource <= cnt); // check for garbage
+ release();
+ resource = rhs.resource;
+ SAY("MOVE #" << resource);
+ BOOST_ASSERT(move_expected);
+ rhs.resource = 0;
+ BOOST_ASSERT(resource);
+ return *this;
+ }
+
+ //operator boost::move_from<Y>()
+ //{
+ // return boost::move_from<Y>(*this);
+ //}
+
+ // TODO: Is this case desirable?
+ operator boost::move_from<Y>() const
+ {
+ return boost::move_from<Y>(*const_cast<Y*>(this));
+
+ }
+
+ static int copies; // count the number of copies
+ static int suboptimal_copies; // count the number of copies that should've been avoidable
+
+ static void expect_copy() { copy_expected = true; move_expected = false; }
+ static void expect_move() { copy_expected = false; move_expected = true; }
+
+ private: // helper functions
+ void release()
+ {
+ BOOST_ASSERT(resource <= cnt); // check for garbage
+ if (!resource)
+ SAY("destroy empty");
+ else
+ SAY("destroy #" << resource);
+ resource = 0;
+ }
+
+ void copy(Y const& rhs)
+ {
+ BOOST_ASSERT(rhs.resource <= cnt); // check for garbage
+ SAY("copy #" << this->resource << " <- #" << rhs.resource);
+ if (!copy_expected)
+ {
+ SAY("***** SUBOPTIMAL COPY ******");
+ ++suboptimal_copies;
+ }
+ else
+ {
+ move_expected = true; // OK to move now
+ }
+ ++copies;
+ }
+
+ private: // Data members
+ int resource;
+
+ static int cnt; // count the number of resources
+ static bool copy_expected;
+ static bool move_expected;
+};
+
+int Y::cnt;
+int Y::copies;
+int Y::suboptimal_copies;
+bool Y::copy_expected;
+bool Y::move_expected;
+
+#endif // Y_DWA2004410_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk