|
Boost-Commit : |
From: daniel_james_at_[hidden]
Date: 2008-07-13 15:26:37
Author: danieljames
Date: 2008-07-13 15:26:36 EDT (Sun, 13 Jul 2008)
New Revision: 47397
URL: http://svn.boost.org/trac/boost/changeset/47397
Log:
Implement moving swappable types.
I had to rejig the terminology a little - so 'boost_movable' means movable using
boost::move_from, 'movable' means movable by any means.
Text files modified:
sandbox/move/boost/move.hpp | 85 +++++++++++++++++++++++++++++++++++----
sandbox/move/libs/move/test/Jamfile.v2 | 1
sandbox/move/libs/move/test/main.cpp | 4
sandbox/move/libs/move/test/move.cpp | 2
sandbox/move/libs/move/test/noncopyable.cpp | 5 --
5 files changed, 79 insertions(+), 18 deletions(-)
Modified: sandbox/move/boost/move.hpp
==============================================================================
--- sandbox/move/boost/move.hpp (original)
+++ sandbox/move/boost/move.hpp 2008-07-13 15:26:36 EDT (Sun, 13 Jul 2008)
@@ -29,6 +29,7 @@
#include <boost/type_traits/is_class.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/move/detail/config.hpp>
+#include <boost/move/detail/has_swap_overload.hpp>
/*************************************************************************************************/
@@ -107,16 +108,42 @@
/*************************************************************************************************/
+/*!
+\ingroup move_related
+\brief swap_from is used for move_ctors.
+*/
+
+template <typename T>
+struct swap_from
+{
+ swap_from(T& x)
+ : m(x)
+ {}
+
+ operator T() const
+ {
+ T x;
+ using std::swap;
+ swap(this->m, x);
+ return x;
+ }
+
+ T& m;
+};
+
+
+/*************************************************************************************************/
+
#if !defined(BOOST_MOVE_NO_HAS_MOVE_ASSIGN)
/*************************************************************************************************/
/*!
\ingroup move_related
-\brief The is_movable trait can be used to identify movable types.
+\brief The is_boost_movable trait can be used to identify types that are movable using this library.
*/
template <typename T>
-struct is_movable : boost::mpl::and_<
+struct is_boost_movable : boost::mpl::and_<
boost::mpl::or_<
boost::is_convertible<T, move_from<T> >,
boost::is_convertible<move_from<T>, T>
@@ -133,7 +160,7 @@
// unless the trait is specialized.
template <typename T>
-struct is_movable : boost::mpl::false_ { };
+struct is_boost_movable : boost::mpl::false_ { };
#endif
@@ -145,16 +172,32 @@
struct copy_tag {};
struct move_tag {};
+struct swap_tag {};
template <typename T, class Enable = void>
-struct move_type {
- typedef copy_tag type;
-};
+struct move_type :
+ boost::mpl::if_<is_boost_movable<T>, move_tag,
+ typename boost::mpl::if_<boost::detail::has_swap_overload<T>,
+ swap_tag, copy_tag>::type > {};
+
+/*************************************************************************************************/
+
+#endif
+
+/*************************************************************************************************/
+/*!
+\ingroup move_related
+\brief The is_movable trait can be used to identify movable types.
+*/
template <typename T>
-struct move_type<T, typename boost::enable_if<is_movable<T> >::type> {
- typedef move_tag type;
-};
+struct is_movable : boost::mpl::not_<boost::is_same<
+ typename boost::move_type<T>::type, copy_tag > > {};
+
+
+/*************************************************************************************************/
+
+#if !defined(BOOST_NO_SFINAE)
/*************************************************************************************************/
@@ -241,6 +284,15 @@
/*************************************************************************************************/
+/*!
+\ingroup move_related
+\brief This version of move is selected when T is swappable.
+*/
+template <typename T>
+T move(T& x, typename move_type_sink<swap_tag, T>::type = 0) { return T(swap_from<T>(x)); }
+
+/*************************************************************************************************/
+
#else // BOOST_NO_SFINAE
// On compilers without SFINAE, define copy_sink to always use the copy function.
@@ -377,7 +429,6 @@
/*************************************************************************************************/
-
/*!
\ingroup move_related
\brief Placement copy construction, selected when T is_movable is false
@@ -392,6 +443,20 @@
/*!
\ingroup move_related
+\brief Placement copy construction, selected when T is swappable.
+*/
+template <typename T> // T models Regular
+inline void move_construct(T* p, T& x, typename move_type_sink<swap_tag, T>::type = 0)
+{
+ ::new(static_cast<void*>(p)) T();
+ using std::swap;
+ swap(*p, x);
+}
+
+/*************************************************************************************************/
+
+/*!
+\ingroup move_related
\brief Similar to std::uninitialized_copy but
with move semantics, for movable types.
*/
Modified: sandbox/move/libs/move/test/Jamfile.v2
==============================================================================
--- sandbox/move/libs/move/test/Jamfile.v2 (original)
+++ sandbox/move/libs/move/test/Jamfile.v2 2008-07-13 15:26:36 EDT (Sun, 13 Jul 2008)
@@ -12,6 +12,7 @@
[ run main.cpp ]
[ run move.cpp ]
[ run noncopyable.cpp ]
+ [ run swappable.cpp ]
[ run move_test.cpp ]
[ run no_sfinae_test.cpp ]
[ run has_swap_overload.cpp ]
Modified: sandbox/move/libs/move/test/main.cpp
==============================================================================
--- sandbox/move/libs/move/test/main.cpp (original)
+++ sandbox/move/libs/move/test/main.cpp 2008-07-13 15:26:36 EDT (Sun, 13 Jul 2008)
@@ -48,7 +48,7 @@
// Test is_movable<> template function
- BOOST_CHECK(!boost::is_movable<std_vector_t>::value);
+ BOOST_CHECK(boost::is_movable<std_vector_t>::value);
BOOST_CHECK(boost::is_movable<vector_t>::value);
{ // Test move_sink<> via push_back
@@ -123,4 +123,4 @@
int test_main(int, char**) {
move_test();
return 0;
-}
\ No newline at end of file
+}
Modified: sandbox/move/libs/move/test/move.cpp
==============================================================================
--- sandbox/move/libs/move/test/move.cpp (original)
+++ sandbox/move/libs/move/test/move.cpp 2008-07-13 15:26:36 EDT (Sun, 13 Jul 2008)
@@ -144,7 +144,7 @@
z10 = boost::move(z8);
SAY(" ------ test 25, request move construct from non-movable lvalue ------- ");
- BOOST_STATIC_ASSERT(!boost::is_movable<std::string>::value);
+ BOOST_STATIC_ASSERT(boost::is_movable<std::string>::value);
std::string s1("hello");
std::string s2(boost::move(s1));
Modified: sandbox/move/libs/move/test/noncopyable.cpp
==============================================================================
--- sandbox/move/libs/move/test/noncopyable.cpp (original)
+++ sandbox/move/libs/move/test/noncopyable.cpp 2008-07-13 15:26:36 EDT (Sun, 13 Jul 2008)
@@ -152,11 +152,6 @@
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;
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