Update code to be valid when the internal buckets_ data member is moved-from

This commit is contained in:
Christian Mazakas
2022-08-16 14:34:58 -07:00
parent 7b41f4783f
commit f9eae4153f
4 changed files with 58 additions and 25 deletions

View File

@ -646,7 +646,7 @@ namespace boost {
size_type bucket_count() const { return size_; } size_type bucket_count() const { return size_; }
iterator begin() const { return ++at(size_); } iterator begin() const { return size_ == 0 ? end() : ++at(size_); }
iterator end() const iterator end() const
{ {
@ -660,6 +660,10 @@ namespace boost {
local_iterator begin(size_type n) const local_iterator begin(size_type n) const
{ {
if (size_ == 0) {
return this->end(n);
}
return local_iterator( return local_iterator(
(buckets + static_cast<difference_type>(n))->next); (buckets + static_cast<difference_type>(n))->next);
} }
@ -670,12 +674,16 @@ namespace boost {
iterator at(size_type n) const iterator at(size_type n) const
{ {
if (size_ > 0) {
std::size_t const N = group::N; std::size_t const N = group::N;
iterator pbg(buckets + static_cast<difference_type>(n), iterator pbg(buckets + static_cast<difference_type>(n),
groups + static_cast<difference_type>(n / N)); groups + static_cast<difference_type>(n / N));
return pbg; return pbg;
} else {
return this->end();
}
} }
span<Bucket> raw() span<Bucket> raw()

View File

@ -2054,13 +2054,15 @@ namespace boost {
std::size_t bucket_size(std::size_t index) const std::size_t bucket_size(std::size_t index) const
{ {
std::size_t count = 0;
if (size_ > 0) {
bucket_iterator itb = buckets_.at(index); bucket_iterator itb = buckets_.at(index);
node_pointer n = itb->next; node_pointer n = itb->next;
std::size_t count = 0;
while (n) { while (n) {
++count; ++count;
n = n->next; n = n->next;
} }
}
return count; return count;
} }
@ -2420,13 +2422,16 @@ namespace boost {
node_pointer find_node_impl( node_pointer find_node_impl(
Key const& x, bucket_iterator itb) const Key const& x, bucket_iterator itb) const
{ {
node_pointer p = node_pointer();
if (itb != buckets_.end()) {
key_equal const& pred = this->key_eq(); key_equal const& pred = this->key_eq();
node_pointer p = itb->next; p = itb->next;
for (; p; p = p->next) { for (; p; p = p->next) {
if (pred(x, extractor::extract(p->value()))) { if (pred(x, extractor::extract(p->value()))) {
break; break;
} }
} }
}
return p; return p;
} }
@ -2453,6 +2458,7 @@ namespace boost {
inline iterator transparent_find( inline iterator transparent_find(
Key const& k, Hash const& h, Pred const& pred) const Key const& k, Hash const& h, Pred const& pred) const
{ {
if (size_ > 0) {
std::size_t const key_hash = h(k); std::size_t const key_hash = h(k);
bucket_iterator itb = buckets_.at(buckets_.position(key_hash)); bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
for (node_pointer p = itb->next; p; p = p->next) { for (node_pointer p = itb->next; p; p = p->next) {
@ -2460,6 +2466,7 @@ namespace boost {
return iterator(p, itb); return iterator(p, itb);
} }
} }
}
return this->end(); return this->end();
} }
@ -2467,6 +2474,7 @@ namespace boost {
template <class Key> template <class Key>
node_pointer* find_prev(Key const& key, bucket_iterator itb) node_pointer* find_prev(Key const& key, bucket_iterator itb)
{ {
if (size_ > 0) {
key_equal pred = this->key_eq(); key_equal pred = this->key_eq();
for (node_pointer* pp = boost::addressof(itb->next); *pp; for (node_pointer* pp = boost::addressof(itb->next); *pp;
pp = boost::addressof((*pp)->next)) { pp = boost::addressof((*pp)->next)) {
@ -2474,6 +2482,7 @@ namespace boost {
return pp; return pp;
} }
} }
}
typedef node_pointer* node_pointer_pointer; typedef node_pointer* node_pointer_pointer;
return node_pointer_pointer(); return node_pointer_pointer();
} }

View File

@ -2069,6 +2069,10 @@ namespace boost {
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{ {
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0); BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) / return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count()); static_cast<float>(table_.bucket_count());
@ -2506,6 +2510,10 @@ namespace boost {
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{ {
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0); BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) / return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count()); static_cast<float>(table_.bucket_count());

View File

@ -1586,6 +1586,10 @@ namespace boost {
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{ {
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0); BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) / return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count()); static_cast<float>(table_.bucket_count());
@ -1986,6 +1990,10 @@ namespace boost {
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
float unordered_multiset<T, H, P, A>::load_factor() const BOOST_NOEXCEPT float unordered_multiset<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{ {
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0); BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) / return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count()); static_cast<float>(table_.bucket_count());