Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2008-04-13 10:13:34


Author: danieljames
Date: 2008-04-13 10:13:33 EDT (Sun, 13 Apr 2008)
New Revision: 44368
URL: http://svn.boost.org/trac/boost/changeset/44368

Log:
Use a cut down version of the work in progress move library to implement move
semantics on more compilers. Unfortunately the move constructor with allocator
isn't really practical at the moment, since in the case where the container
can't be moved, and the allocators aren't equal it will copy the container
twice.

Added:
   branches/unordered/trunk/boost/unordered/detail/config.hpp
      - copied, changed from r44362, /sandbox/move/boost/move/detail/config.hpp
   branches/unordered/trunk/boost/unordered/detail/move.hpp
      - copied, changed from r44363, /sandbox/move/boost/move.hpp
Text files modified:
   branches/unordered/trunk/boost/unordered/detail/config.hpp | 8
   branches/unordered/trunk/boost/unordered/detail/move.hpp | 206 ++-------------------------------------
   branches/unordered/trunk/boost/unordered_map.hpp | 71 +++++++++----
   branches/unordered/trunk/boost/unordered_set.hpp | 70 ++++++++----
   4 files changed, 108 insertions(+), 247 deletions(-)

Copied: branches/unordered/trunk/boost/unordered/detail/config.hpp (from r44362, /sandbox/move/boost/move/detail/config.hpp)
==============================================================================
--- /sandbox/move/boost/move/detail/config.hpp (original)
+++ branches/unordered/trunk/boost/unordered/detail/config.hpp 2008-04-13 10:13:33 EDT (Sun, 13 Apr 2008)
@@ -3,16 +3,16 @@
 // 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)
 
-#if !defined(BOOST_MOVE_DETAIL_CONFIG_HEADER)
-#define BOOST_MOVE_DETAIL_CONFIG_HEADER
+#if !defined(BOOST_UNORDERED_DETAIL_CONFIG_HEADER)
+#define BOOST_UNORDERED_DETAIL_CONFIG_HEADER
 
 #include <boost/config.hpp>
 
 #if defined(BOOST_NO_SFINAE)
-# define BOOST_MOVE_NO_HAS_MOVE_ASSIGN
+# define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
 #elif defined(__GNUC__) && \
     (__GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
-# define BOOST_MOVE_NO_HAS_MOVE_ASSIGN
+# define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
 #endif
 
 #endif

Copied: branches/unordered/trunk/boost/unordered/detail/move.hpp (from r44363, /sandbox/move/boost/move.hpp)
==============================================================================
--- /sandbox/move/boost/move.hpp (original)
+++ branches/unordered/trunk/boost/unordered/detail/move.hpp 2008-04-13 10:13:33 EDT (Sun, 13 Apr 2008)
@@ -8,30 +8,24 @@
 
 /*************************************************************************************************/
 
-#ifndef BOOST_MOVE_HPP
-#define BOOST_MOVE_HPP
+#ifndef BOOST_UNORDERED_DETAIL_MOVE_HEADER
+#define BOOST_UNORDERED_DETAIL_MOVE_HEADER
 
-#include <cassert>
-#include <iterator>
-#include <memory>
 
-#include <boost/iterator/iterator_adaptor.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/and.hpp>
 #include <boost/mpl/or.hpp>
 #include <boost/mpl/not.hpp>
-#include <boost/mpl/assert.hpp>
-#include <boost/range/begin.hpp>
-#include <boost/range/end.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_traits/is_class.hpp>
 #include <boost/utility/enable_if.hpp>
-#include <boost/move/detail/config.hpp>
+#include <boost/unordered/detail/config.hpp>
 
 /*************************************************************************************************/
 
 namespace boost {
+namespace unordered_detail {
 
 /*************************************************************************************************/
 
@@ -39,7 +33,7 @@
 
 /*************************************************************************************************/
 
-#if !defined(BOOST_MOVE_NO_HAS_MOVE_ASSIGN)
+#if !defined(BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN)
 
 /*************************************************************************************************/
 
@@ -70,7 +64,7 @@
 
 /*************************************************************************************************/
 
-#endif // BOOST_MOVE_NO_HAS_MOVE_ASSIGN
+#endif // BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
 
 /*************************************************************************************************/
 
@@ -106,7 +100,7 @@
 
 /*************************************************************************************************/
 
-#if !defined(BOOST_MOVE_NO_HAS_MOVE_ASSIGN)
+#if !defined(BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN)
 
 /*************************************************************************************************/
 
@@ -123,7 +117,7 @@
 
 /*************************************************************************************************/
 
-#else // BOOST_MOVE_NO_HAS_MOVE_ASSIGN
+#else // BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
 
 // On compilers which don't have adequate SFINAE support, treat most types as unmovable,
 // unless the trait is specialized.
@@ -151,7 +145,7 @@
           typename R = void*>
 struct copy_sink : boost::enable_if<
                         boost::mpl::and_<
- boost::move_detail::is_convertible<T, U>,
+ boost::unordered_detail::move_detail::is_convertible<T, U>,
                             boost::mpl::not_<is_movable<T> >
>,
                         R
@@ -172,7 +166,7 @@
           typename R = void*>
 struct move_sink : boost::enable_if<
                         boost::mpl::and_<
- boost::move_detail::is_convertible<T, U>,
+ boost::unordered_detail::move_detail::is_convertible<T, U>,
                             is_movable<T>
>,
                         R
@@ -224,185 +218,7 @@
 
 #endif // BOOST_NO_SFINAE
 
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Iterator pair version of move. Similar to std::copy but with move semantics,
-for movable types, otherwise with copy semantics.
-*/
-template <typename I, // I models InputIterator
- typename O> // O models OutputIterator
-O move(I f, I l, O result)
-{
- while (f != l) {
- *result = boost::move(*f);
- ++f; ++result;
- }
- return result;
-}
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief \ref concept_convertible_to_range version of move. Similar to copy but with move semantics,
-for movable types, otherwise with copy semantics.
-*/
-template <typename I, // I models InputRange
- typename O> // O models OutputIterator
-inline O move(I& in, O out) { return boost::move(boost::begin(in), boost::end(in), out); }
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Iterator pair version of move_backwards. Similar to std::copy_backwards but with move semantics,
-for movable types, otherwise with copy semantics.
-*/
-template <typename I, // I models BidirectionalIterator
- typename O> // O models BidirectionalIterator
-O move_backward(I f, I l, O result)
-{
- while (f != l) {
- --l; --result;
- *result = boost::move(*l);
- }
- return result;
-}
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief \ref concept_convertible_to_range version of move_backwards. Similar to std::copy_backwards but
-with move semantics, for movable types, otherwise with copy semantics.
-*/
-template <typename I, // I models BidirectionalRange
- typename O> // O models BidirectionalIterator
-inline O move_backward(I& in, O out)
-{ return move_backward(boost::begin(in), boost::end(in), out); }
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Similar to std::back_insert_iterator but
-with move semantics, for movable types, otherwise with copy semantics.
-*/
-
-template <typename C> // C models Container
-class back_move_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
-{
- C* container_m;
-
- public:
- typedef C container_type;
-
- explicit back_move_iterator(C& x) : container_m(&x) { }
-
- back_move_iterator& operator=(typename C::value_type x)
- { container_m->push_back(move(x)); return *this; }
-
- back_move_iterator& operator*() { return *this; }
- back_move_iterator& operator++() { return *this; }
- back_move_iterator& operator++(int) { return *this; }
-};
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Similar to std::back_inserter but
-with move semantics, for movable types, otherwise with copy semantics.
-*/
-
-template <typename C> // C models Container
-inline back_move_iterator<C> back_mover(C& x) { return back_move_iterator<C>(x); }
-
-/*************************************************************************************************/
-
-#if !defined(BOOST_NO_SFINAE)
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Placement move construction, selected when T is_movable is true
-*/
-
-template <typename T> // T models Regular
-inline void move_construct(T* p, T& x, typename move_sink<T>::type = 0)
-{
- ::new(static_cast<void*>(p)) T(move_from<T>(x));
-}
-
-/*************************************************************************************************/
-
-
-/*!
-\ingroup move_related
-\brief Placement copy construction, selected when T is_movable is false
-*/
-template <typename T> // T models Regular
-inline void move_construct(T* p, const T& x, typename copy_sink<T>::type = 0)
-{
- ::new(static_cast<void*>(p)) T(x);
-}
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Similar to std::uninitialized_copy but
-with move semantics, for movable types.
-*/
-template <typename I, // I models InputIterator
- typename F> // F models ForwardIterator
-F uninitialized_move(I f, I l, F r,
- typename move_sink<typename std::iterator_traits<I>::value_type>::type = 0)
-{
- while (f != l) {
- boost::move_construct(&*r, *f);
- ++f; ++r;
- }
- return r;
-}
-
-/*************************************************************************************************/
-
-/*!
-\ingroup move_related
-\brief Behaves as to std::uninitialized_copy , invoked when I's value_type is not movable.
-*/
-template <typename I, // I models InputIterator
- typename F> // F models ForwardIterator
-F uninitialized_move(I f, I l, F r,
- typename copy_sink<typename std::iterator_traits<I>::value_type>::type = 0)
-{
- return std::uninitialized_copy(f, l, r);
-}
-
-/*************************************************************************************************/
-
-#else // BOOST_NO_SFINAE
-
-template <typename T>
-inline void move_construct(T* p, const T& x)
-{
- ::new(static_cast<void*>(p)) T(x);
-}
-
-template <typename I, // I models InputIterator
- typename F> // F models ForwardIterator
-F uninitialized_move(I f, I l, F r)
-{
- return std::uninitialized_copy(f, l, r);
-}
-
-#endif
-
-/*************************************************************************************************/
+} // namespace unordered_detail
 } // namespace boost
 
 /*************************************************************************************************/

Modified: branches/unordered/trunk/boost/unordered_map.hpp
==============================================================================
--- branches/unordered/trunk/boost/unordered_map.hpp (original)
+++ branches/unordered/trunk/boost/unordered_map.hpp 2008-04-13 10:13:33 EDT (Sun, 13 Apr 2008)
@@ -21,6 +21,10 @@
 #include <boost/unordered/detail/hash_table.hpp>
 #include <boost/functional/hash.hpp>
 
+#if !defined(BOOST_HAS_RVALUE_REFS)
+#include <boost/unordered/detail/move.hpp>
+#endif
+
 namespace boost
 {
     template <class Key,
@@ -83,18 +87,6 @@
         {
         }
 
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_map(unordered_map&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_map(unordered_map&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-#endif
-
         template <class InputIterator>
         unordered_map(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -113,11 +105,32 @@
         }
 
 #if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_map(unordered_map&& other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_map(unordered_map&& other, allocator_type const& a)
+ : base(other.base, a, boost::unordered_detail::move_tag())
+ {
+ }
+
         unordered_map& operator=(unordered_map&& x)
         {
             base.move(x.base);
             return *this;
         }
+#else
+ unordered_map(boost::unordered_detail::move_from<unordered_map> other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_map& operator=(unordered_map x)
+ {
+ base.move(x.base);
+ return *this;
+ }
 #endif
 
     private:
@@ -427,18 +440,6 @@
         {
         }
 
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_multimap(unordered_multimap&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_multimap(unordered_multimap&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-#endif
-
         template <class InputIterator>
         unordered_multimap(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -457,13 +458,35 @@
         }
 
 #if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_multimap(unordered_multimap&& other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_multimap(unordered_multimap&& other, allocator_type const& a)
+ : base(other.base, a, boost::unordered_detail::move_tag())
+ {
+ }
+
         unordered_multimap& operator=(unordered_multimap&& x)
         {
             base.move(x.base);
             return *this;
         }
+#else
+ unordered_multimap(boost::unordered_detail::move_from<unordered_multimap> other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_multimap& operator=(unordered_multimap x)
+ {
+ base.move(x.base);
+ return *this;
+ }
 #endif
 
+
     private:
 
         BOOST_DEDUCED_TYPENAME implementation::iterator_base const&

Modified: branches/unordered/trunk/boost/unordered_set.hpp
==============================================================================
--- branches/unordered/trunk/boost/unordered_set.hpp (original)
+++ branches/unordered/trunk/boost/unordered_set.hpp 2008-04-13 10:13:33 EDT (Sun, 13 Apr 2008)
@@ -21,6 +21,10 @@
 #include <boost/unordered/detail/hash_table.hpp>
 #include <boost/functional/hash.hpp>
 
+#if !defined(BOOST_HAS_RVALUE_REFS)
+#include <boost/unordered/detail/move.hpp>
+#endif
+
 namespace boost
 {
     template <class Value,
@@ -81,18 +85,6 @@
         {
         }
 
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_set(unordered_set&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_set(unordered_set&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-#endif
-
         template <class InputIterator>
         unordered_set(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -110,11 +102,32 @@
         }
 
 #if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_set(unordered_set&& other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_set(unordered_set&& other, allocator_type const& a)
+ : base(other.base, a, boost::unordered_detail::move_tag())
+ {
+ }
+
         unordered_set& operator=(unordered_set&& x)
         {
             base.move(x.base);
             return *this;
         }
+#else
+ unordered_set(boost::unordered_detail::move_from<unordered_set> other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_set& operator=(unordered_set x)
+ {
+ base.move(x.base);
+ return *this;
+ }
 #endif
 
     private:
@@ -396,18 +409,6 @@
         {
         }
 
-#if defined(BOOST_HAS_RVALUE_REFS)
- unordered_multiset(unordered_multiset&& other)
- : base(other.base, boost::unordered_detail::move_tag())
- {
- }
-
- unordered_multiset(unordered_multiset&& other, allocator_type const& a)
- : base(other.base, a, boost::unordered_detail::move_tag())
- {
- }
-#endif
-
         template <class InputIterator>
         unordered_multiset(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -425,11 +426,32 @@
         }
 
 #if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_multiset(unordered_multiset&& other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_multiset(unordered_multiset&& other, allocator_type const& a)
+ : base(other.base, a, boost::unordered_detail::move_tag())
+ {
+ }
+
         unordered_multiset& operator=(unordered_multiset&& x)
         {
             base.move(x.base);
             return *this;
         }
+#else
+ unordered_multiset(boost::unordered_detail::move_from<unordered_multiset> other)
+ : base(other.base, boost::unordered_detail::move_tag())
+ {
+ }
+
+ unordered_multiset& operator=(unordered_multiset x)
+ {
+ base.move(x.base);
+ return *this;
+ }
 #endif
 
     private:


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