Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2008-04-06 15:48:59


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

Log:
Do move assignment 'properly'.
Text files modified:
   branches/unordered/trunk/boost/unordered/detail/hash_table_impl.hpp | 53 +++++++++++++++++++++++++++++++++++++++
   branches/unordered/trunk/boost/unordered_map.hpp | 6 +---
   branches/unordered/trunk/boost/unordered_set.hpp | 6 +---
   3 files changed, 56 insertions(+), 9 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:48:59 EDT (Sun, 06 Apr 2008)
@@ -365,6 +365,12 @@
             }
 #endif
 
+ // no throw
+ ~BOOST_UNORDERED_TABLE_DATA()
+ {
+ if(buckets_) delete_buckets();
+ }
+
             void create_buckets() {
                 // The array constructor will clean up in the event of an
                 // exception.
@@ -385,7 +391,7 @@
             }
 
             // no throw
- ~BOOST_UNORDERED_TABLE_DATA()
+ void delete_buckets()
             {
                 if(buckets_) {
                     bucket_ptr begin = cached_begin_bucket_;
@@ -420,6 +426,16 @@
                 std::swap(size_, other.size_);
             }
 
+ // no throw
+ void move(BOOST_UNORDERED_TABLE_DATA&& other)
+ {
+ delete_buckets();
+ buckets_ = other.buckets_;
+ bucket_count_ = other.bucket_count_;
+ cached_begin_bucket_ = other.cached_begin_bucket_;
+ size_ = other.size_;
+ }
+
             // Return the bucket for a hashed value.
             //
             // no throw
@@ -1237,6 +1253,41 @@
                 x.calculate_max_load();
             }
 
+ // Move
+ //
+ // ----------------------------------------------------------------
+ //
+ // Strong exception safety (might change unused function objects)
+ //
+ // Can throw if hash or predicate object's copy constructor throws
+ // or if allocators are unequal.
+
+ void move(BOOST_UNORDERED_TABLE&& x)
+ {
+ // This only effects the function objects that aren't in use
+ // so it is strongly exception safe, via. double buffering.
+ functions_ptr new_func_this = copy_functions(x); // throws
+
+ if(data_.allocators_ == x.data_.allocators_) {
+ data_.move(x.data_); // no throw
+ }
+ else {
+ // Create new buckets in separate HASH_TABLE_DATA objects
+ // which will clean up if anything throws an exception.
+ // (all can throw, but with no effect as these are new objects).
+ data new_this(data_, x.min_buckets_for_size(x.data_.size_));
+ copy_buckets(x.data_, new_this, this->*new_func_this);
+
+ // Start updating the data here, no throw from now on.
+ data_.move(new_this);
+ }
+
+ // We've made it, the rest is no throw.
+ mlf_ = x.mlf_;
+ func_ = new_func_this;
+ calculate_max_load();
+ }
+
         private:
 
             functions const& current_functions() const

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:48:59 EDT (Sun, 06 Apr 2008)
@@ -112,11 +112,10 @@
         {
         }
 
-// TODO: Do this properly?
 #if defined(BOOST_HAS_RVALUE_REFS)
         unordered_map& operator=(unordered_map&& x)
         {
- swap(x);
+ base.move(x.base);
             return *this;
         }
 #endif
@@ -457,11 +456,10 @@
         {
         }
 
-// TODO: Do this properly?
 #if defined(BOOST_HAS_RVALUE_REFS)
         unordered_multimap& operator=(unordered_multimap&& x)
         {
- swap(x);
+ base.move(x.base);
             return *this;
         }
 #endif

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:48:59 EDT (Sun, 06 Apr 2008)
@@ -109,11 +109,10 @@
         {
         }
 
-// TODO: Do this properly?
 #if defined(BOOST_HAS_RVALUE_REFS)
         unordered_set& operator=(unordered_set&& x)
         {
- swap(x);
+ base.move(x.base);
             return *this;
         }
 #endif
@@ -425,11 +424,10 @@
         {
         }
 
-// TODO: Do this properly?
 #if defined(BOOST_HAS_RVALUE_REFS)
         unordered_multiset& operator=(unordered_multiset&& x)
         {
- swap(x);
+ base.move(x.base);
             return *this;
         }
 #endif


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