Skip to content

Commit

Permalink
Update code to be valid when the internal buckets_ data member is m…
Browse files Browse the repository at this point in the history
…oved-from
  • Loading branch information
cmazakas committed Aug 17, 2022
1 parent 7b41f47 commit 3a1c475
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 25 deletions.
18 changes: 13 additions & 5 deletions include/boost/unordered/detail/fca.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ namespace boost {

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
{
Expand All @@ -660,6 +660,10 @@ namespace boost {

local_iterator begin(size_type n) const
{
if (size_ == 0) {
return this->end(n);
}

return local_iterator(
(buckets + static_cast<difference_type>(n))->next);
}
Expand All @@ -670,12 +674,16 @@ namespace boost {

iterator at(size_type n) const
{
std::size_t const N = group::N;
if (size_ > 0) {
std::size_t const N = group::N;

iterator pbg(buckets + static_cast<difference_type>(n),
groups + static_cast<difference_type>(n / N));
iterator pbg(buckets + static_cast<difference_type>(n),
groups + static_cast<difference_type>(n / N));

return pbg;
return pbg;
} else {
return this->end();
}
}

span<Bucket> raw()
Expand Down
49 changes: 29 additions & 20 deletions include/boost/unordered/detail/implementation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2054,12 +2054,14 @@ namespace boost {

std::size_t bucket_size(std::size_t index) const
{
bucket_iterator itb = buckets_.at(index);
node_pointer n = itb->next;
std::size_t count = 0;
while (n) {
++count;
n = n->next;
if (size_ > 0) {
bucket_iterator itb = buckets_.at(index);
node_pointer n = itb->next;
while (n) {
++count;
n = n->next;
}
}
return count;
}
Expand Down Expand Up @@ -2420,11 +2422,14 @@ namespace boost {
node_pointer find_node_impl(
Key const& x, bucket_iterator itb) const
{
key_equal const& pred = this->key_eq();
node_pointer p = itb->next;
for (; p; p = p->next) {
if (pred(x, extractor::extract(p->value()))) {
break;
node_pointer p = node_pointer();
if (itb != buckets_.end()) {
key_equal const& pred = this->key_eq();
p = itb->next;
for (; p; p = p->next) {
if (pred(x, extractor::extract(p->value()))) {
break;
}
}
}
return p;
Expand Down Expand Up @@ -2453,11 +2458,13 @@ namespace boost {
inline iterator transparent_find(
Key const& k, Hash const& h, Pred const& pred) const
{
std::size_t const key_hash = h(k);
bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
for (node_pointer p = itb->next; p; p = p->next) {
if (BOOST_LIKELY(pred(k, extractor::extract(p->value())))) {
return iterator(p, itb);
if (size_ > 0) {
std::size_t const key_hash = h(k);
bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
for (node_pointer p = itb->next; p; p = p->next) {
if (BOOST_LIKELY(pred(k, extractor::extract(p->value())))) {
return iterator(p, itb);
}
}
}

Expand All @@ -2467,11 +2474,13 @@ namespace boost {
template <class Key>
node_pointer* find_prev(Key const& key, bucket_iterator itb)
{
key_equal pred = this->key_eq();
for (node_pointer* pp = boost::addressof(itb->next); *pp;
pp = boost::addressof((*pp)->next)) {
if (pred(key, extractor::extract((*pp)->value()))) {
return pp;
if (size_ > 0) {
key_equal pred = this->key_eq();
for (node_pointer* pp = boost::addressof(itb->next); *pp;
pp = boost::addressof((*pp)->next)) {
if (pred(key, extractor::extract((*pp)->value()))) {
return pp;
}
}
}
typedef node_pointer* node_pointer_pointer;
Expand Down
8 changes: 8 additions & 0 deletions include/boost/unordered/unordered_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2069,6 +2069,10 @@ namespace boost {
template <class K, class T, class H, class P, class A>
float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
if (table_.size_ == 0) {
return 0.0;
}

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

BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count());
Expand Down
8 changes: 8 additions & 0 deletions include/boost/unordered/unordered_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,10 @@ namespace boost {
template <class T, class H, class P, class A>
float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
if (table_.size_ == 0) {
return 0.0;
}

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

BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count());
Expand Down

0 comments on commit 3a1c475

Please sign in to comment.