|
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