forked from boostorg/unordered
Cleaner create_buckets implementation
This commit is contained in:
@ -2898,57 +2898,37 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
|
|||||||
// Strong exception safety.
|
// Strong exception safety.
|
||||||
void create_buckets(std::size_t new_count)
|
void create_buckets(std::size_t new_count)
|
||||||
{
|
{
|
||||||
std::size_t length = new_count + 1;
|
link_pointer dummy_node;
|
||||||
bucket_pointer new_buckets =
|
|
||||||
bucket_allocator_traits::allocate(bucket_alloc(), length);
|
|
||||||
bucket_pointer constructed = new_buckets;
|
|
||||||
|
|
||||||
// TODO: Apart from constructing the dummy node this is now
|
// Construct the new buckets and dummy node, and destroy the old buckets
|
||||||
// nothrow, so maybe rearrange it a bit so that less
|
if (buckets_) {
|
||||||
// exception handling is required.
|
dummy_node =
|
||||||
BOOST_TRY
|
(buckets_ + static_cast<std::ptrdiff_t>(bucket_count_))->next_;
|
||||||
{
|
bucket_pointer new_buckets = bucket_allocator_traits::allocate(
|
||||||
bucket_pointer end =
|
bucket_alloc(), new_count + 1);
|
||||||
new_buckets + static_cast<std::ptrdiff_t>(new_count);
|
destroy_buckets();
|
||||||
for (; constructed != end; ++constructed) {
|
buckets_ = new_buckets;
|
||||||
new (boost::addressof(*constructed)) bucket();
|
} else if (bucket::extra_node) {
|
||||||
}
|
node_constructor a(node_alloc());
|
||||||
|
a.create_node();
|
||||||
if (buckets_) {
|
buckets_ = bucket_allocator_traits::allocate(
|
||||||
// Copy the nodes to the new buckets, including the dummy
|
bucket_alloc(), new_count + 1);
|
||||||
// node if there is one.
|
dummy_node = a.release();
|
||||||
new (boost::addressof(*constructed)) bucket(
|
} else {
|
||||||
(buckets_ + static_cast<std::ptrdiff_t>(bucket_count_))
|
dummy_node = link_pointer();
|
||||||
->next_);
|
buckets_ = bucket_allocator_traits::allocate(
|
||||||
++constructed;
|
bucket_alloc(), new_count + 1);
|
||||||
destroy_buckets();
|
|
||||||
} else if (bucket::extra_node) {
|
|
||||||
node_constructor a(node_alloc());
|
|
||||||
a.create_node();
|
|
||||||
|
|
||||||
new (boost::addressof(*constructed)) bucket(a.release());
|
|
||||||
++constructed;
|
|
||||||
} else {
|
|
||||||
new (boost::addressof(*constructed)) bucket();
|
|
||||||
++constructed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
BOOST_CATCH(...)
|
|
||||||
{
|
|
||||||
for (bucket_pointer p = new_buckets; p != constructed; ++p) {
|
|
||||||
boost::unordered::detail::func::destroy(boost::addressof(*p));
|
|
||||||
}
|
|
||||||
|
|
||||||
bucket_allocator_traits::deallocate(
|
|
||||||
bucket_alloc(), new_buckets, length);
|
|
||||||
|
|
||||||
BOOST_RETHROW;
|
|
||||||
}
|
|
||||||
BOOST_CATCH_END
|
|
||||||
|
|
||||||
|
// nothrow from here...
|
||||||
bucket_count_ = new_count;
|
bucket_count_ = new_count;
|
||||||
buckets_ = new_buckets;
|
|
||||||
recalculate_max_load();
|
recalculate_max_load();
|
||||||
|
|
||||||
|
bucket_pointer end = buckets_ + static_cast<std::ptrdiff_t>(new_count);
|
||||||
|
for (bucket_pointer i = buckets_; i != end; ++i) {
|
||||||
|
new (boost::addressof(*i)) bucket();
|
||||||
|
}
|
||||||
|
new (boost::addressof(*end)) bucket(dummy_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user