Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2008-04-06 15:41:19


Author: danieljames
Date: 2008-04-06 15:41:19 EDT (Sun, 06 Apr 2008)
New Revision: 44076
URL: http://svn.boost.org/trac/boost/changeset/44076

Log:
Move semantics for compilers with rvalue references.
Text files modified:
   branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp | 86 ++++++++++++++++++++++++++++++++-------
   branches/unordered/trunk/boost/unordered_map.hpp | 42 +++++++++++++++++++
   branches/unordered/trunk/boost/unordered_set.hpp | 42 +++++++++++++++++++
   branches/unordered/trunk/libs/unordered/test/unordered/Jamfile.v2 | 1
   4 files changed, 154 insertions(+), 17 deletions(-)

Modified: branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp (original)
+++ branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp 2008-04-06 15:41:19 EDT (Sun, 06 Apr 2008)
@@ -323,22 +323,8 @@
                 buckets_(), bucket_count_(next_prime(n)),
                 cached_begin_bucket_(), size_(0)
             {
- // The array constructor will clean up in the event of an
- // exception.
- allocator_array_constructor<bucket_allocator>
- constructor(allocators_.bucket_alloc_);
-
- // Creates an extra bucket to act as a sentinel.
- constructor.construct(bucket(), bucket_count_ + 1);
-
- cached_begin_bucket_ = constructor.get() + static_cast<difference_type>(bucket_count_);
-
- // Set up the sentinel.
- cached_begin_bucket_->next_ = link_ptr(cached_begin_bucket_);
-
- // Only release the buckets once everything is successfully
- // done.
- buckets_ = constructor.release();
+ BOOST_UNORDERED_MSVC_RESET_PTR(buckets_);
+ create_buckets();
             }
 
             BOOST_UNORDERED_TABLE_DATA(BOOST_UNORDERED_TABLE_DATA const& x, size_type n)
@@ -346,6 +332,40 @@
                 buckets_(), bucket_count_(next_prime(n)),
                 cached_begin_bucket_(), size_(0)
             {
+ BOOST_UNORDERED_MSVC_RESET_PTR(buckets_);
+ create_buckets();
+ }
+
+#if defined(BOOST_HAS_RVALUE_REFS)
+ BOOST_UNORDERED_TABLE_DATA(BOOST_UNORDERED_TABLE_DATA&& x)
+ : allocators_(x.allocators_),
+ buckets_(x.buckets_), bucket_count_(x.bucket_count_),
+ cached_begin_bucket_(x.cached_begin_bucket_), size_(x.size_)
+ {
+ unordered_detail::reset(x.buckets_);
+ }
+
+ BOOST_UNORDERED_TABLE_DATA(BOOST_UNORDERED_TABLE_DATA&& x,
+ value_allocator const& a, size_type n)
+ : allocators_(a), buckets_(), bucket_count_(),
+ cached_begin_bucket_(), size_(0)
+ {
+ if(allocators_ == x.allocators_) {
+ buckets_ = x.buckets_;
+ bucket_count_ = x.bucket_count_;
+ cached_begin_bucket_ = x.cached_begin_bucket_;
+ size_ = x.size_;
+ unordered_detail::reset(x.buckets_);
+ }
+ else {
+ BOOST_UNORDERED_MSVC_RESET_PTR(buckets_);
+ bucket_count_ = next_prime(n);
+ create_buckets();
+ }
+ }
+#endif
+
+ void create_buckets() {
                 // The array constructor will clean up in the event of an
                 // exception.
                 allocator_array_constructor<bucket_allocator>
@@ -356,7 +376,7 @@
 
                 cached_begin_bucket_ = constructor.get() + static_cast<difference_type>(bucket_count_);
 
- // Set up the sentinel
+ // Set up the sentinel.
                 cached_begin_bucket_->next_ = link_ptr(cached_begin_bucket_);
 
                 // Only release the buckets once everything is successfully
@@ -1114,6 +1134,38 @@
                 copy_buckets(x.data_, data_, current_functions());
             }
 
+#if defined(BOOST_HAS_RVALUE_REFS)
+ // Move Construct
+
+ BOOST_UNORDERED_TABLE(BOOST_UNORDERED_TABLE&& x)
+ : func1_(x.current_functions()), // throws
+ func2_(x.current_functions()), // throws
+ func_(&BOOST_UNORDERED_TABLE::func1_), // no throw
+ mlf_(x.mlf_), // no throw
+ data_(std::move(x.data_)) // throws
+ {
+ calculate_max_load(); // no throw
+ }
+
+ BOOST_UNORDERED_TABLE(BOOST_UNORDERED_TABLE&& x,
+ value_allocator const& a)
+ : func1_(x.current_functions()), // throws
+ func2_(x.current_functions()), // throws
+ func_(&BOOST_UNORDERED_TABLE::func1_), // no throw
+ mlf_(x.mlf_), // no throw
+ data_(std::move(x.data_),
+ a, x.min_buckets_for_size(x.size())) // throws
+ {
+ calculate_max_load(); // no throw
+
+ if(x.data_.buckets_) {
+ // This can throw, but BOOST_UNORDERED_TABLE_DATA's destructor will clean
+ // up.
+ copy_buckets(x.data_, data_, current_functions());
+ }
+ }
+#endif
+
             // Assign
             //
             // basic exception safety, if copy_functions of reserver throws

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-06 15:41:19 EDT (Sun, 06 Apr 2008)
@@ -83,6 +83,18 @@
         {
         }
 
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_map(unordered_map&& other)
+ : base(std::move(other.base))
+ {
+ }
+
+ unordered_map(unordered_map&& other, allocator_type const& a)
+ : base(std::move(other.base), a)
+ {
+ }
+#endif
+
         template <class InputIterator>
         unordered_map(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -100,6 +112,15 @@
         {
         }
 
+// TODO: Do this properly?
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_map& operator=(unordered_map&& x)
+ {
+ swap(x);
+ return *this;
+ }
+#endif
+
     private:
 
         BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
@@ -407,6 +428,18 @@
         {
         }
 
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_multimap(unordered_multimap&& other)
+ : base(std::move(other.base))
+ {
+ }
+
+ unordered_multimap(unordered_multimap&& other, allocator_type const& a)
+ : base(std::move(other.base), a)
+ {
+ }
+#endif
+
         template <class InputIterator>
         unordered_multimap(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -424,6 +457,15 @@
         {
         }
 
+// TODO: Do this properly?
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_multimap& operator=(unordered_multimap&& x)
+ {
+ swap(x);
+ 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-06 15:41:19 EDT (Sun, 06 Apr 2008)
@@ -81,6 +81,18 @@
         {
         }
 
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_set(unordered_set&& other)
+ : base(std::move(other.base))
+ {
+ }
+
+ unordered_set(unordered_set&& other, allocator_type const& a)
+ : base(std::move(other.base), a)
+ {
+ }
+#endif
+
         template <class InputIterator>
         unordered_set(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -97,6 +109,15 @@
         {
         }
 
+// TODO: Do this properly?
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_set& operator=(unordered_set&& x)
+ {
+ swap(x);
+ return *this;
+ }
+#endif
+
     private:
 
         BOOST_DEDUCED_TYPENAME implementation::iterator_base const&
@@ -376,6 +397,18 @@
         {
         }
 
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_multiset(unordered_multiset&& other)
+ : base(std::move(other.base))
+ {
+ }
+
+ unordered_multiset(unordered_multiset&& other, allocator_type const& a)
+ : base(std::move(other.base), a)
+ {
+ }
+#endif
+
         template <class InputIterator>
         unordered_multiset(InputIterator f, InputIterator l)
             : base(f, l, boost::unordered_detail::default_initial_bucket_count,
@@ -392,6 +425,15 @@
         {
         }
 
+// TODO: Do this properly?
+#if defined(BOOST_HAS_RVALUE_REFS)
+ unordered_multiset& operator=(unordered_multiset&& x)
+ {
+ swap(x);
+ return *this;
+ }
+#endif
+
     private:
 
         BOOST_DEDUCED_TYPENAME implementation::iterator_base const&

Modified: branches/unordered/trunk/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/unordered/trunk/libs/unordered/test/unordered/Jamfile.v2 (original)
+++ branches/unordered/trunk/libs/unordered/test/unordered/Jamfile.v2 2008-04-06 15:41:19 EDT (Sun, 06 Apr 2008)
@@ -21,6 +21,7 @@
         [ run equivalent_keys_tests.cpp ]
         [ run constructor_tests.cpp ]
         [ run copy_tests.cpp ]
+ [ run move_tests.cpp ]
         [ run assign_tests.cpp ]
         [ run insert_tests.cpp ]
         [ run insert_stable_tests.cpp ]


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