Unordered: Move around assignment stuff.

[SVN r73681]
This commit is contained in:
Daniel James
2011-08-11 21:19:05 +00:00
parent 0e5930b8dc
commit 7438d7a02f
3 changed files with 51 additions and 51 deletions

View File

@ -21,6 +21,7 @@ namespace boost { namespace unordered { namespace detail {
class table : public T::buckets, public T::functions
{
table(table const&);
table& operator=(table const&);
public:
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
@ -234,13 +235,6 @@ namespace boost { namespace unordered { namespace detail {
~table()
{}
table& operator=(table const& x)
{
table tmp(x, this->node_alloc());
this->fast_swap(tmp);
return *this;
}
// Iterators
node_ptr begin() const {
@ -248,6 +242,48 @@ namespace boost { namespace unordered { namespace detail {
node_ptr() : this->buckets_[this->bucket_count_].next_;
}
void assign(table const& x)
{
table tmp(x, this->node_alloc());
this->fast_swap(tmp);
}
void move_assign(table& x)
{
// This can throw, but it only affects the function objects
// that aren't in use so it is strongly exception safe, via.
// double buffering.
set_hash_functions<hasher, key_equal> new_func_this(*this, x);
if(this->node_alloc() == x.node_alloc()) {
this->buckets::move(x); // no throw
this->size_ = x.size_;
this->max_load_ = x.max_load_;
x.size_ = 0;
}
else {
// Create new buckets in separate buckets
// which will clean up if anything throws an exception.
buckets b(this->node_alloc(), x.min_buckets_for_size(x.size_));
if (x.size_) {
// Use a temporary table because move_buckets_to leaves the
// source container in a complete mess.
table tmp(x, move_tag());
tmp.move_buckets_to(b);
}
// Start updating the data here, no throw from now on.
this->size_ = x.size_;
b.swap(*this);
this->max_load_ = x.size_ ? calculate_max_load() : 0;
}
// We've made it, the rest is no throw.
this->mlf_ = x.mlf_;
new_func_this.commit();
}
////////////////////////////////////////////////////////////////////////
// Swap & Move
@ -295,42 +331,6 @@ namespace boost { namespace unordered { namespace detail {
std::swap(this->max_load_, x.max_load_);
}
void move(table& x)
{
// This can throw, but it only affects the function objects
// that aren't in use so it is strongly exception safe, via.
// double buffering.
set_hash_functions<hasher, key_equal> new_func_this(*this, x);
if(this->node_alloc() == x.node_alloc()) {
this->buckets::move(x); // no throw
this->size_ = x.size_;
this->max_load_ = x.max_load_;
x.size_ = 0;
}
else {
// Create new buckets in separate buckets
// which will clean up if anything throws an exception.
buckets b(this->node_alloc(), x.min_buckets_for_size(x.size_));
if (x.size_) {
// Use a temporary table because move_buckets_to leaves the
// source container in a complete mess.
table tmp(x, move_tag());
tmp.move_buckets_to(b);
}
// Start updating the data here, no throw from now on.
this->size_ = x.size_;
b.swap(*this);
this->max_load_ = x.size_ ? calculate_max_load() : 0;
}
// We've made it, the rest is no throw.
this->mlf_ = x.mlf_;
new_func_this.commit();
}
////////////////////////////////////////////////////////////////////////
// Key methods

View File

@ -129,7 +129,7 @@ namespace unordered
unordered_map& operator=(
BOOST_COPY_ASSIGN_REF(unordered_map) x)
{
table_ = x.table_;
table_.assign(x.table_);
return *this;
}
@ -139,7 +139,7 @@ namespace unordered
unordered_map& operator=(
BOOST_RV_REF(unordered_map) x)
{
table_.move(x.table_);
table_.move_assign(x.table_);
return *this;
}
@ -481,7 +481,7 @@ namespace unordered
unordered_multimap& operator=(
BOOST_COPY_ASSIGN_REF(unordered_multimap) x)
{
table_ = x.table_;
table_.assign(x.table_);
return *this;
}
@ -491,7 +491,7 @@ namespace unordered
unordered_multimap& operator=(
BOOST_RV_REF(unordered_multimap) x)
{
table_.move(x.table_);
table_.move_assign(x.table_);
return *this;
}

View File

@ -128,7 +128,7 @@ namespace unordered
unordered_set& operator=(
BOOST_COPY_ASSIGN_REF(unordered_set) x)
{
table_ = x.table_;
table_.assign(x.table_);
return *this;
}
@ -138,7 +138,7 @@ namespace unordered
unordered_set& operator=(
BOOST_RV_REF(unordered_set) x)
{
table_.move(x.table_);
table_.move_assign(x.table_);
return *this;
}
@ -460,7 +460,7 @@ namespace unordered
unordered_multiset& operator=(
BOOST_COPY_ASSIGN_REF(unordered_multiset) x)
{
table_ = x.table_;
table_.assign(x.table_);
return *this;
}
@ -470,7 +470,7 @@ namespace unordered
unordered_multiset& operator=(
BOOST_RV_REF(unordered_multiset) x)
{
table_.move(x.table_);
table_.move_assign(x.table_);
return *this;
}