forked from boostorg/unordered
Unordered: Move around assignment stuff.
[SVN r73681]
This commit is contained in:
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user