diff --git a/boost/unordered/detail/fwd.hpp b/boost/unordered/detail/fwd.hpp
index c1c31ff..a4fdae1 100644
--- a/boost/unordered/detail/fwd.hpp
+++ b/boost/unordered/detail/fwd.hpp
@@ -233,16 +233,31 @@ namespace boost { namespace unordered_detail {
return node::get_value(node_);
}
- void increment_bucket(node_ptr n) {
- while(!n) {
- ++bucket_;
- n = bucket_->next_;
+ void increment_bucket() {
+ if(!node_) {
+ do {
+ ++bucket_;
+ node_ = bucket_->next_;
+ } while(!node_);
+
+ if(bucket_ == node_) {
+ bucket_ = bucket_ptr();
+ node_ = node_ptr();
+ }
}
- node_ = bucket_ == n ? node_ptr() : n;
}
void increment() {
- increment_bucket(node_->next_);
+ node_ = node_->next_;
+ increment_bucket();
+ }
+
+ void lazy_increment() {
+ node_ = node_->next_;
+ }
+
+ void check_increment() {
+ if(bucket_) increment_bucket();
}
};
@@ -738,6 +753,7 @@ namespace boost { namespace unordered_detail {
static BOOST_DEDUCED_TYPENAME Iterator::base const&
get(Iterator const& it)
{
+ it.base_.check_increment();
return it.base_;
}
};
@@ -876,34 +892,41 @@ namespace boost { namespace unordered_detail {
typedef BOOST_DEDUCED_TYPENAME buckets::iterator_base base;
typedef hash_const_iterator const_iterator;
friend class hash_const_iterator;
- base base_;
+ mutable base base_;
public:
hash_iterator() : base_() {}
explicit hash_iterator(base const& x) : base_(x) {}
BOOST_DEDUCED_TYPENAME A::reference operator*() const {
+ base_.check_increment();
return *base_;
}
value_type* operator->() const {
+ base_.check_increment();
return &*base_;
}
hash_iterator& operator++() {
- base_.increment(); return *this;
+ base_.check_increment(); base_.increment(); return *this;
}
hash_iterator operator++(int) {
- hash_iterator tmp(base_); base_.increment(); return tmp;
+ base_.check_increment(); hash_iterator tmp(base_);
+ base_.increment(); return tmp;
}
bool operator==(hash_iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ == x.base_;
}
bool operator==(const_iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ == x.base_;
}
bool operator!=(hash_iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ != x.base_;
}
bool operator!=(const_iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ != x.base_;
}
};
@@ -927,7 +950,7 @@ namespace boost { namespace unordered_detail {
typedef hash_iterator iterator;
friend class hash_iterator;
friend class iterator_access;
- base base_;
+ mutable base base_;
public:
@@ -935,27 +958,34 @@ namespace boost { namespace unordered_detail {
explicit hash_const_iterator(base const& x) : base_(x) {}
hash_const_iterator(iterator const& x) : base_(x.base_) {}
BOOST_DEDUCED_TYPENAME A::const_reference operator*() const {
+ base_.check_increment();
return *base_;
}
value_type const* operator->() const {
+ base_.check_increment();
return &*base_;
}
hash_const_iterator& operator++() {
- base_.increment(); return *this;
+ base_.check_increment(); base_.increment(); return *this;
}
hash_const_iterator operator++(int) {
- hash_const_iterator tmp(base_); base_.increment(); return tmp;
+ base_.check_increment(); hash_const_iterator tmp(base_);
+ base_.increment(); return tmp;
}
bool operator==(iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ == x.base_;
}
bool operator==(hash_const_iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ == x.base_;
}
bool operator!=(iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ != x.base_;
}
bool operator!=(hash_const_iterator const& x) const {
+ base_.check_increment(); x.base_.check_increment();
return base_ != x.base_;
}
};
diff --git a/boost/unordered/detail/table.hpp b/boost/unordered/detail/table.hpp
index 198548d..7546edc 100644
--- a/boost/unordered/detail/table.hpp
+++ b/boost/unordered/detail/table.hpp
@@ -634,7 +634,8 @@ namespace boost { namespace unordered_detail {
if (BOOST_UNORDERED_BORLAND_BOOL(it)) {
iterator_base first(iterator_base(bucket, it));
iterator_base second(first);
- second.increment_bucket(node::next_group(second.node_));
+ // Note: this is a lazy increment.
+ second.node_ = node::next_group(second.node_);
return iterator_pair(first, second);
}
else {
@@ -702,12 +703,16 @@ namespace boost { namespace unordered_detail {
{
BOOST_ASSERT(r.node_);
iterator_base next = r;
- next.increment();
+ next.lazy_increment();
--this->size_;
node::unlink_node(*r.bucket_, r.node_);
this->delete_node(r.node_);
// r has been invalidated but its bucket is still valid
- this->recompute_begin_bucket(r.bucket_, next.bucket_);
+ //this->recompute_begin_bucket(r.bucket_, next.bucket_);
+ if(next.bucket_ == this->cached_begin_bucket_ && !next.bucket_->next_) {
+ next.check_increment();
+ this->cached_begin_bucket_ = next.bucket_;
+ }
return next;
}