Remove 'local_iterator_base'. It isn't really needed.

[SVN r42153]
This commit is contained in:
Daniel James
2007-12-18 22:51:31 +00:00
parent c30bb968f4
commit 73dea3ed4d

View File

@@ -207,7 +207,7 @@ namespace boost {
{ {
node_ptr p = node_; node_ptr p = node_;
unordered_detail::reset(node_); unordered_detail::reset(node_);
return link_ptr(allocators_.bucket_alloc_.address(*p)); return allocators_.bucket_alloc_.address(*p);
} }
private: private:
@@ -256,31 +256,31 @@ namespace boost {
return static_cast<node&>(*p).value_; return static_cast<node&>(*p).value_;
} }
class local_iterator_base class iterator_base
{ {
public: public:
bucket_ptr bucket_;
link_ptr node_; link_ptr node_;
local_iterator_base() iterator_base()
: node_() : bucket_(), node_()
{ {
BOOST_HASH_MSVC_RESET_PTR(bucket_);
BOOST_HASH_MSVC_RESET_PTR(node_); BOOST_HASH_MSVC_RESET_PTR(node_);
} }
explicit local_iterator_base(link_ptr n) explicit iterator_base(bucket_ptr b)
: node_(n) {} : bucket_(b), node_(b->next_) {}
bool not_finished() const iterator_base(bucket_ptr b, link_ptr n)
{ : bucket_(b), node_(n) {}
return node_ ? true : false;
}
bool operator==(local_iterator_base const& x) const bool operator==(iterator_base const& x) const
{ {
return node_ == x.node_; return node_ == x.node_;
} }
bool operator!=(local_iterator_base const& x) const bool operator!=(iterator_base const& x) const
{ {
return node_ != x.node_; return node_ != x.node_;
} }
@@ -290,64 +290,14 @@ namespace boost {
return get_value(node_); return get_value(node_);
} }
value_type* operator->() const
{
return &get_value(node_);
}
void increment()
{
BOOST_ASSERT(node_);
node_ = node_->next_;
}
void next_group()
{
node_ = BOOST_UNORDERED_TABLE_DATA::next_group(node_);
}
};
class iterator_base
{
public:
bucket_ptr bucket_;
local_iterator_base local_;
iterator_base()
: bucket_(), local_() {}
explicit iterator_base(bucket_ptr b)
: bucket_(b), local_(b->next_) {}
iterator_base(bucket_ptr b, link_ptr n)
: bucket_(b), local_(n) {}
iterator_base(bucket_ptr b, local_iterator_base const& it)
: bucket_(b), local_(it) {}
bool operator==(iterator_base const& x) const
{
return local_ == x.local_;
}
bool operator!=(iterator_base const& x) const
{
return local_ != x.local_;
}
reference operator*() const
{
return *local_;
}
void increment() void increment()
{ {
BOOST_ASSERT(bucket_); BOOST_ASSERT(bucket_);
local_.increment(); node_ = node_->next_;
while (!local_.node_) { while (!node_) {
++bucket_; ++bucket_;
local_ = local_iterator_base(bucket_->next_); node_ = bucket_->next_;
} }
} }
}; };
@@ -467,41 +417,42 @@ namespace boost {
return iterator_base(buckets_ + bucket_count_); return iterator_base(buckets_ + bucket_count_);
} }
local_iterator_base begin(size_type n) const link_ptr begin(size_type n) const
{ {
return local_iterator_base(buckets_[n].next_); return buckets_[n].next_;
} }
local_iterator_base end(size_type) const link_ptr end(size_type) const
{ {
return local_iterator_base(); link_ptr ptr = link_ptr();
BOOST_HASH_MSVC_RESET_PTR(ptr);
return ptr;
} }
local_iterator_base begin(bucket_ptr b) const link_ptr begin(bucket_ptr b) const
{ {
return local_iterator_base(b->next_); return b->next_;
} }
// Bucket Size // Bucket Size
// no throw // no throw
size_type node_count(local_iterator_base it) const size_type node_count(link_ptr it) const
{ {
size_type count = 0; size_type count = 0;
while(it.not_finished()) { while(BOOST_HASH_BORLAND_BOOL(it)) {
++count; ++count;
it.increment(); it = it->next_;
} }
return count; return count;
} }
size_type node_count(local_iterator_base it1, size_type node_count(link_ptr it1, link_ptr it2) const
local_iterator_base it2) const
{ {
size_type count = 0; size_type count = 0;
while(it1 != it2) { while(it1 != it2) {
++count; ++count;
it1.increment(); it1 = it1->next_;
} }
return count; return count;
} }
@@ -512,10 +463,9 @@ namespace boost {
} }
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
size_type group_count(local_iterator_base first_node) const size_type group_count(link_ptr it) const
{ {
size_type count = 0; size_type count = 0;
link_ptr it = first_node.node_;
link_ptr first = it; link_ptr first = it;
do { do {
++count; ++count;
@@ -524,7 +474,7 @@ namespace boost {
return count; return count;
} }
#else #else
size_type group_count(local_iterator_base) const size_type group_count(link_ptr) const
{ {
return 1; return 1;
} }
@@ -539,7 +489,7 @@ namespace boost {
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
static link_ptr* get_for_erase(iterator_base r) static link_ptr* get_for_erase(iterator_base r)
{ {
link_ptr n = r.local_.node_; link_ptr n = r.node_;
// If the element isn't the first in its group, then // If the element isn't the first in its group, then
// the link to it will be found in the previous element // the link to it will be found in the previous element
@@ -556,7 +506,7 @@ namespace boost {
#else #else
static link_ptr* get_for_erase(iterator_base r) static link_ptr* get_for_erase(iterator_base r)
{ {
link_ptr n = r.local_.node_; link_ptr n = r.node_;
link_ptr* it = &r.bucket_->next_; link_ptr* it = &r.bucket_->next_;
while(*it != n) it = &(*it)->next_; while(*it != n) it = &(*it)->next_;
return it; return it;
@@ -571,10 +521,10 @@ namespace boost {
// no throw // no throw
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
void link_node(link_ptr n, local_iterator_base pos) void link_node(link_ptr n, link_ptr pos)
{ {
node& node_ref = get_node(n); node& node_ref = get_node(n);
node& pos_ref = get_node(pos.node_); node& pos_ref = get_node(pos);
node_ref.next_ = pos_ref.group_prev_->next_; node_ref.next_ = pos_ref.group_prev_->next_;
node_ref.group_prev_ = pos_ref.group_prev_; node_ref.group_prev_ = pos_ref.group_prev_;
pos_ref.group_prev_->next_ = n; pos_ref.group_prev_->next_ = n;
@@ -582,7 +532,7 @@ namespace boost {
++size_; ++size_;
} }
void link_node(link_ptr n, bucket_ptr base) void link_node_in_bucket(link_ptr n, bucket_ptr base)
{ {
node& node_ref = get_node(n); node& node_ref = get_node(n);
node_ref.next_ = base->next_; node_ref.next_ = base->next_;
@@ -602,7 +552,7 @@ namespace boost {
if(base < cached_begin_bucket_) cached_begin_bucket_ = base; if(base < cached_begin_bucket_) cached_begin_bucket_ = base;
} }
#else #else
void link_node(link_ptr n, bucket_ptr base) void link_node_in_bucket(link_ptr n, bucket_ptr base)
{ {
n->next_ = base->next_; n->next_ = base->next_;
base->next_ = n; base->next_ = n;
@@ -612,7 +562,7 @@ namespace boost {
void link_group(link_ptr n, bucket_ptr base, size_type) void link_group(link_ptr n, bucket_ptr base, size_type)
{ {
link_node(n, base); link_node_in_bucket(n, base);
} }
#endif #endif
@@ -620,7 +570,7 @@ namespace boost {
void unlink_node(iterator_base it) void unlink_node(iterator_base it)
{ {
link_ptr* pos = get_for_erase(it); link_ptr* pos = get_for_erase(it);
node* n = &get_node(it.local_.node_); node* n = &get_node(it.node_);
link_ptr next = n->next_; link_ptr next = n->next_;
if(n->group_prev_ == *pos) { if(n->group_prev_ == *pos) {
@@ -649,7 +599,7 @@ namespace boost {
size_type unlink_group(link_ptr* pos) size_type unlink_group(link_ptr* pos)
{ {
size_type count = group_count(local_iterator_base(*pos)); size_type count = group_count(*pos);
size_ -= count; size_ -= count;
link_ptr last = last_in_group(*pos); link_ptr last = last_in_group(*pos);
*pos = last->next_; *pos = last->next_;
@@ -676,31 +626,28 @@ namespace boost {
link_ptr* it = get_for_erase(n); link_ptr* it = get_for_erase(n);
split_group(*it); split_group(*it);
unordered_detail::reset(*it); unordered_detail::reset(*it);
size_ -= node_count(n.local_); size_ -= node_count(n.node_);
} }
void unlink_nodes(iterator_base begin, iterator_base end) void unlink_nodes(iterator_base begin, iterator_base end)
{ {
BOOST_ASSERT(begin.bucket_ == end.bucket_); BOOST_ASSERT(begin.bucket_ == end.bucket_);
local_iterator_base local_end = end.local_; size_ -= node_count(begin.node_, end.node_);
size_ -= node_count(begin.local_, local_end);
link_ptr* it = get_for_erase(begin); link_ptr* it = get_for_erase(begin);
split_group(*it, local_end.node_); split_group(*it, end.node_);
*it = local_end.node_; *it = end.node_;
} }
void unlink_nodes(bucket_ptr base, iterator_base end) void unlink_nodes(bucket_ptr base, iterator_base end)
{ {
BOOST_ASSERT(base == end.bucket_); BOOST_ASSERT(base == end.bucket_);
local_iterator_base local_end = end.local_; split_group(end.node_);
split_group(local_end.node_);
link_ptr ptr(base->next_); link_ptr ptr(base->next_);
base->next_ = local_end.node_; base->next_ = end.node_;
size_ -= node_count(local_iterator_base(ptr), local_end); size_ -= node_count(ptr, end.node_);
} }
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
@@ -711,8 +658,11 @@ namespace boost {
{ {
// If split is at the beginning of the group then there's // If split is at the beginning of the group then there's
// nothing to split. // nothing to split.
if(prev_in_group(split)->next_ != split) if(prev_in_group(split)->next_ != split) {
return link_ptr(); link_ptr ptr = link_ptr();
BOOST_HASH_MSVC_RESET_PTR(ptr);
return ptr;
}
// Find the start of the group. // Find the start of the group.
link_ptr start = split; link_ptr start = split;
@@ -768,7 +718,7 @@ namespace boost {
link_ptr n = construct_node(v); link_ptr n = construct_node(v);
// Rest is no throw // Rest is no throw
link_node(n, base); link_node_in_bucket(n, base);
return iterator_base(base, n); return iterator_base(base, n);
} }
@@ -779,39 +729,38 @@ namespace boost {
link_ptr n = construct_node(v); link_ptr n = construct_node(v);
// Rest is no throw // Rest is no throw
link_node(n, position.local_); link_node(n, position.node_);
return iterator_base(position.bucket_, n); return iterator_base(position.bucket_, n);
} }
iterator_base create_node(value_type const& v, iterator_base create_node(value_type const& v,
bucket_ptr base, local_iterator_base position) bucket_ptr base, link_ptr position)
{ {
// throws, strong exception-safety: // throws, strong exception-safety:
link_ptr n = construct_node(v); link_ptr n = construct_node(v);
// Rest is no throw // Rest is no throw
if(position.not_finished()) if(BOOST_HASH_BORLAND_BOOL(position))
link_node(n, position); link_node(n, position);
else else
link_node(n, base); link_node_in_bucket(n, base);
return iterator_base(base, n); return iterator_base(base, n);
} }
#endif #endif
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
void copy_group(local_iterator_base it, bucket_ptr dst) void copy_group(link_ptr it, bucket_ptr dst)
{ {
local_iterator_base end = it; link_ptr end = next_group(it);
end.next_group(); iterator_base pos = create_node(get_value(it), dst);
iterator_base pos = create_node(*it, dst); for(it = it->next_; it != end; it = it->next_)
for(it.increment(); it != end; it.increment()) create_node(get_value(it), pos);
create_node(*it, pos);
} }
#else #else
void copy_group(local_iterator_base it, bucket_ptr dst) void copy_group(link_ptr it, bucket_ptr dst)
{ {
create_node(*it, dst); create_node(get_value(it), dst);
} }
#endif #endif
@@ -889,7 +838,7 @@ namespace boost {
iterator_base next = r; iterator_base next = r;
next.increment(); next.increment();
unlink_node(r); unlink_node(r);
allocators_.destroy(r.local_.node_); allocators_.destroy(r.node_);
// r has been invalidated but its bucket is still valid // r has been invalidated but its bucket is still valid
recompute_begin_bucket(r.bucket_, next.bucket_); recompute_begin_bucket(r.bucket_, next.bucket_);
return next; return next;
@@ -903,7 +852,7 @@ namespace boost {
if (r1.bucket_ == r2.bucket_) { if (r1.bucket_ == r2.bucket_) {
unlink_nodes(r1, r2); unlink_nodes(r1, r2);
delete_nodes(r1.local_.node_, r2.local_.node_); delete_nodes(r1.node_, r2.node_);
// No need to call recompute_begin_bucket because // No need to call recompute_begin_bucket because
// the nodes are only deleted from one bucket, which // the nodes are only deleted from one bucket, which
@@ -914,17 +863,17 @@ namespace boost {
BOOST_ASSERT(r1.bucket_ < r2.bucket_); BOOST_ASSERT(r1.bucket_ < r2.bucket_);
unlink_nodes(r1); unlink_nodes(r1);
delete_to_bucket_end(r1.local_.node_); delete_to_bucket_end(r1.node_);
for(bucket_ptr i = r1.bucket_ + 1; i != r2.bucket_; ++i) { for(bucket_ptr i = r1.bucket_ + 1; i != r2.bucket_; ++i) {
size_ -= node_count(local_iterator_base(i->next_)); size_ -= node_count(i->next_);
clear_bucket(i); clear_bucket(i);
} }
if(r2 != end()) { if(r2 != end()) {
link_ptr first = r2.bucket_->next_; link_ptr first = r2.bucket_->next_;
unlink_nodes(r2.bucket_, r2); unlink_nodes(r2.bucket_, r2);
delete_nodes(first, r2.local_.node_); delete_nodes(first, r2.node_);
} }
// r1 has been invalidated but its bucket is still // r1 has been invalidated but its bucket is still
@@ -1024,7 +973,6 @@ namespace boost {
// iterators // iterators
typedef BOOST_DEDUCED_TYPENAME data::local_iterator_base local_iterator_base;
typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base; typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;
private: private:
@@ -1487,11 +1435,11 @@ namespace boost {
// no throw: // no throw:
for(bucket_ptr i = src.cached_begin_bucket_; i != end; ++i) { for(bucket_ptr i = src.cached_begin_bucket_; i != end; ++i) {
// no throw: // no throw:
for(local_iterator_base it = src.begin(i); for(link_ptr it = src.begin(i);
it.not_finished(); it.next_group()) { BOOST_HASH_BORLAND_BOOL(it); it = data::next_group(it)) {
// hash function can throw. // hash function can throw.
bucket_ptr dst_bucket = dst.buckets_ + bucket_ptr dst_bucket = dst.buckets_ +
dst.index_from_hash(hf(extract_key(*it))); dst.index_from_hash(hf(extract_key(data::get_value(it))));
// throws, strong // throws, strong
dst.copy_group(it, dst_bucket); dst.copy_group(it, dst_bucket);
} }
@@ -1517,7 +1465,7 @@ namespace boost {
size_type hash_value = hash_function()(k); size_type hash_value = hash_function()(k);
bucket_ptr bucket = this->buckets_ bucket_ptr bucket = this->buckets_
+ this->index_from_hash(hash_value); + this->index_from_hash(hash_value);
local_iterator_base position = find_iterator(bucket, k); link_ptr position = find_iterator(bucket, k);
// Create the node before rehashing in case it throws an // Create the node before rehashing in case it throws an
// exception (need strong safety in such a case). // exception (need strong safety in such a case).
@@ -1533,12 +1481,12 @@ namespace boost {
link_ptr n = a.release(); link_ptr n = a.release();
// I'm relying on local_iterator_base not being invalidated by // I'm relying on link_ptr not being invalidated by
// the rehash here. // the rehash here.
if(position.not_finished()) if(BOOST_HASH_BORLAND_BOOL(position))
this->link_node(n, position); this->link_node(n, position);
else else
this->link_node(n, bucket); this->link_node_in_bucket(n, bucket);
return iterator_base(bucket, n); return iterator_base(bucket, n);
} }
@@ -1559,9 +1507,9 @@ namespace boost {
// Find the first node in the group - so that the node // Find the first node in the group - so that the node
// will be inserted at the end of the group. // will be inserted at the end of the group.
local_iterator_base start(it.local_); link_ptr start(it.node_);
while(this->prev_in_group(start.node_)->next_ == start.node_) while(this->prev_in_group(start)->next_ == start)
start.node_ = this->prev_in_group(start.node_); start = this->prev_in_group(start);
// Create the node before rehashing in case it throws an // Create the node before rehashing in case it throws an
// exception (need strong safety in such a case). // exception (need strong safety in such a case).
@@ -1605,12 +1553,12 @@ namespace boost {
key_type const& k = extract_key(a.get()->value_); key_type const& k = extract_key(a.get()->value_);
bucket_ptr bucket = get_bucket(k); bucket_ptr bucket = get_bucket(k);
local_iterator_base position = find_iterator(bucket, k); link_ptr position = find_iterator(bucket, k);
if(position.not_finished()) if(BOOST_HASH_BORLAND_BOOL(position))
this->link_node(a.release(), position); this->link_node(a.release(), position);
else else
this->link_node(a.release(), bucket); this->link_node_in_bucket(a.release(), bucket);
} }
} }
} }
@@ -1648,10 +1596,10 @@ namespace boost {
size_type hash_value = hash_function()(k); size_type hash_value = hash_function()(k);
bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value); bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
local_iterator_base pos = find_iterator(bucket, k); link_ptr pos = find_iterator(bucket, k);
if (pos.not_finished()) if (BOOST_HASH_BORLAND_BOOL(pos))
return *pos; return data::get_value(pos);
else else
{ {
// Side effects only in this block. // Side effects only in this block.
@@ -1669,9 +1617,9 @@ namespace boost {
// Nothing after this point can throw. // Nothing after this point can throw.
link_ptr n = a.release(); link_ptr n = a.release();
this->link_node(n, bucket); this->link_node_in_bucket(n, bucket);
return *local_iterator_base(n); return data::get_value(n);
} }
} }
@@ -1685,9 +1633,9 @@ namespace boost {
key_type const& k = extract_key(v); key_type const& k = extract_key(v);
size_type hash_value = hash_function()(k); size_type hash_value = hash_function()(k);
bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value); bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
local_iterator_base pos = find_iterator(bucket, k); link_ptr pos = find_iterator(bucket, k);
if (pos.not_finished()) { if (BOOST_HASH_BORLAND_BOOL(pos)) {
// Found an existing key, return it (no throw). // Found an existing key, return it (no throw).
return std::pair<iterator_base, bool>( return std::pair<iterator_base, bool>(
iterator_base(bucket, pos), false); iterator_base(bucket, pos), false);
@@ -1709,7 +1657,7 @@ namespace boost {
// Nothing after this point can throw. // Nothing after this point can throw.
link_ptr n = a.release(); link_ptr n = a.release();
this->link_node(n, bucket); this->link_node_in_bucket(n, bucket);
return std::pair<iterator_base, bool>( return std::pair<iterator_base, bool>(
iterator_base(bucket, n), true); iterator_base(bucket, n), true);
@@ -1762,9 +1710,9 @@ namespace boost {
size_type hash_value = hash_function()(extract_key(*i)); size_type hash_value = hash_function()(extract_key(*i));
bucket_ptr bucket = this->buckets_ bucket_ptr bucket = this->buckets_
+ this->index_from_hash(hash_value); + this->index_from_hash(hash_value);
local_iterator_base pos = find_iterator(bucket, extract_key(*i)); link_ptr pos = find_iterator(bucket, extract_key(*i));
if (!pos.not_finished()) { if (!BOOST_HASH_BORLAND_BOOL(pos)) {
// Doesn't already exist, add to bucket. // Doesn't already exist, add to bucket.
// Side effects only in this block. // Side effects only in this block.
@@ -1782,7 +1730,7 @@ namespace boost {
} }
// Nothing after this point can throw. // Nothing after this point can throw.
this->link_node(a.release(), bucket); this->link_node_in_bucket(a.release(), bucket);
} }
} }
} }
@@ -1819,8 +1767,8 @@ namespace boost {
// strong exception safety, no side effects // strong exception safety, no side effects
size_type count(key_type const& k) const size_type count(key_type const& k) const
{ {
local_iterator_base it = find_iterator(k); // throws, strong link_ptr it = find_iterator(k); // throws, strong
return it.not_finished() ? this->group_count(it) : 0; return BOOST_HASH_BORLAND_BOOL(it) ? this->group_count(it) : 0;
} }
// find // find
@@ -1829,9 +1777,9 @@ namespace boost {
iterator_base find(key_type const& k) const iterator_base find(key_type const& k) const
{ {
bucket_ptr bucket = get_bucket(k); bucket_ptr bucket = get_bucket(k);
local_iterator_base it = find_iterator(bucket, k); link_ptr it = find_iterator(bucket, k);
if (it.not_finished()) if (BOOST_HASH_BORLAND_BOOL(it))
return iterator_base(bucket, it); return iterator_base(bucket, it);
else else
return this->end(); return this->end();
@@ -1840,10 +1788,10 @@ namespace boost {
value_type& at(key_type const& k) const value_type& at(key_type const& k) const
{ {
bucket_ptr bucket = get_bucket(k); bucket_ptr bucket = get_bucket(k);
local_iterator_base it = find_iterator(bucket, k); link_ptr it = find_iterator(bucket, k);
if (it.not_finished()) if (BOOST_HASH_BORLAND_BOOL(it))
return *it; return data::get_value(it);
else else
throw std::out_of_range("Unable to find key in unordered_map."); throw std::out_of_range("Unable to find key in unordered_map.");
} }
@@ -1854,10 +1802,10 @@ namespace boost {
std::pair<iterator_base, iterator_base> equal_range(key_type const& k) const std::pair<iterator_base, iterator_base> equal_range(key_type const& k) const
{ {
bucket_ptr bucket = get_bucket(k); bucket_ptr bucket = get_bucket(k);
local_iterator_base it = find_iterator(bucket, k); link_ptr it = find_iterator(bucket, k);
if (it.not_finished()) { if (BOOST_HASH_BORLAND_BOOL(it)) {
iterator_base first(iterator_base(bucket, it)); iterator_base first(iterator_base(bucket, it));
iterator_base second(iterator_base(bucket, this->last_in_group(it.node_))); iterator_base second(iterator_base(bucket, this->last_in_group(it)));
second.increment(); second.increment();
return std::pair<iterator_base, iterator_base>(first, second); return std::pair<iterator_base, iterator_base>(first, second);
} }
@@ -1873,36 +1821,34 @@ namespace boost {
private: private:
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
inline bool group_equals(local_iterator_base it1, inline bool group_equals(link_ptr it1, link_ptr it2,
local_iterator_base it2, type_wrapper<key_type>*) const type_wrapper<key_type>*) const
{ {
return this->group_count(it1) == this->group_count(it2); return this->group_count(it1) == this->group_count(it2);
} }
inline bool group_equals(local_iterator_base it1, inline bool group_equals(link_ptr it1, link_ptr it2, void*) const
local_iterator_base it2, void*) const
{ {
if(!it2.not_finished()) return false; if(!BOOST_HASH_BORLAND_BOOL(it2)) return false;
local_iterator_base end1 = it1, end2 = it2; link_ptr end1 = data::next_group(it1);
end1.next_group(); end2.next_group(); link_ptr end2 = data::next_group(it2);
do { do {
if(it1->second != it2->second) return false; if(data::get_value(it1).second != data::get_value(it2).second) return false;
it1.increment(); it1 = it1->next_;
it2.increment(); it2 = it2->next_;
} while(it1 != end1 && it2 != end2); } while(it1 != end1 && it2 != end2);
return it1 == end1 && it2 == end2; return it1 == end1 && it2 == end2;
} }
#else #else
inline bool group_equals(local_iterator_base it1, inline bool group_equals(link_ptr it1, link_ptr it2,
local_iterator_base it2, type_wrapper<key_type>*) const type_wrapper<key_type>*) const
{ {
return true; return true;
} }
inline bool group_equals(local_iterator_base it1, inline bool group_equals(link_ptr it1, link_ptr it2, void*) const
local_iterator_base it2, void*) const
{ {
return it1->second == it2->second; return data::get_value(it1).second == data::get_value(it2).second;
} }
#endif #endif
@@ -1914,10 +1860,10 @@ public:
for(bucket_ptr i = this->cached_begin_bucket_, for(bucket_ptr i = this->cached_begin_bucket_,
j = this->buckets_ + this->bucket_count_; i != j; ++i) j = this->buckets_ + this->bucket_count_; i != j; ++i)
{ {
for(local_iterator_base it(i->next_); it.not_finished(); it.next_group()) for(link_ptr it(i->next_); BOOST_HASH_BORLAND_BOOL(it); it = data::next_group(it))
{ {
local_iterator_base other_pos = other.find_iterator(other.extract_key(*it)); link_ptr other_pos = other.find_iterator(other.extract_key(data::get_value(it)));
if(!other_pos.not_finished() || if(!BOOST_HASH_BORLAND_BOOL(other_pos) ||
!group_equals(it, other_pos, (type_wrapper<value_type>*)0)) !group_equals(it, other_pos, (type_wrapper<value_type>*)0))
return false; return false;
} }
@@ -1926,22 +1872,22 @@ public:
return true; return true;
} }
inline bool group_hash(local_iterator_base it, type_wrapper<key_type>*) const inline bool group_hash(link_ptr it, type_wrapper<key_type>*) const
{ {
std::size_t seed = this->group_count(it); std::size_t seed = this->group_count(it);
boost::hash_combine(seed, hash_function()(*it)); boost::hash_combine(seed, hash_function()(data::get_value(it)));
return seed; return seed;
} }
inline bool group_hash(local_iterator_base it, void*) const inline bool group_hash(link_ptr it, void*) const
{ {
std::size_t seed = hash_function()(it->first); std::size_t seed = hash_function()(data::get_value(it).first);
local_iterator_base end = it; link_ptr end = data::next_group(it);
end.next_group();
do { do {
boost::hash_combine(seed, it->second); boost::hash_combine(seed, data::get_value(it).second);
it = it->next_;
} while(it != end); } while(it != end);
return seed; return seed;
@@ -1954,7 +1900,7 @@ public:
for(bucket_ptr i = this->cached_begin_bucket_, for(bucket_ptr i = this->cached_begin_bucket_,
j = this->buckets_ + this->bucket_count_; i != j; ++i) j = this->buckets_ + this->bucket_count_; i != j; ++i)
{ {
for(local_iterator_base it(i->next_); it.not_finished(); it.next_group()) for(link_ptr it(i->next_); BOOST_HASH_BORLAND_BOOL(it); it = data::next_group(it))
seed ^= group_hash(it, (type_wrapper<value_type>*)0); seed ^= group_hash(it, (type_wrapper<value_type>*)0);
} }
@@ -1970,18 +1916,18 @@ public:
} }
// strong exception safety, no side effects // strong exception safety, no side effects
local_iterator_base find_iterator(key_type const& k) const link_ptr find_iterator(key_type const& k) const
{ {
return find_iterator(get_bucket(k), k); return find_iterator(get_bucket(k), k);
} }
// strong exception safety, no side effects // strong exception safety, no side effects
local_iterator_base find_iterator(bucket_ptr bucket, link_ptr find_iterator(bucket_ptr bucket,
key_type const& k) const key_type const& k) const
{ {
local_iterator_base it = this->begin(bucket); link_ptr it = this->begin(bucket);
while (it.not_finished() && !equal(k, *it)) while (BOOST_HASH_BORLAND_BOOL(it) && !equal(k, data::get_value(it)))
it.next_group(); it = data::next_group(it);
return it; return it;
} }
@@ -1990,8 +1936,8 @@ public:
link_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const link_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const
{ {
link_ptr* it = &bucket->next_; link_ptr* it = &bucket->next_;
while(BOOST_HASH_BORLAND_BOOL(*it) && !equal(k, this->get_value(*it))) while(BOOST_HASH_BORLAND_BOOL(*it) && !equal(k, data::get_value(*it)))
it = &this->next_group(*it); it = &data::next_group(*it);
return it; return it;
} }
@@ -2022,24 +1968,27 @@ public:
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type; typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
private: private:
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base; typedef BOOST_UNORDERED_TABLE_DATA<Alloc> data;
typedef BOOST_DEDUCED_TYPENAME data::link_ptr ptr;
typedef BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator; typedef BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator;
friend class BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc>; friend class BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc>;
base base_; ptr ptr_;
public: public:
BOOST_UNORDERED_LOCAL_ITERATOR() : base_() {} BOOST_UNORDERED_LOCAL_ITERATOR() : ptr_() {
explicit BOOST_UNORDERED_LOCAL_ITERATOR(base x) : base_(x) {} BOOST_HASH_MSVC_RESET_PTR(ptr_);
}
explicit BOOST_UNORDERED_LOCAL_ITERATOR(ptr x) : ptr_(x) {}
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const
{ return *base_; } { return data::get_value(ptr_); }
value_type* operator->() const { return &*base_; } value_type* operator->() const { return &data::get_value(ptr_); }
BOOST_UNORDERED_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; } BOOST_UNORDERED_LOCAL_ITERATOR& operator++() { ptr_ = ptr_->next_; return *this; }
BOOST_UNORDERED_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; } BOOST_UNORDERED_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_LOCAL_ITERATOR tmp(ptr_); ptr_ = ptr_->next_; return tmp; }
bool operator==(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return base_ == x.base_; } bool operator==(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return ptr_ == x.ptr_; }
bool operator==(const_local_iterator x) const { return base_ == x.base_; } bool operator==(const_local_iterator x) const { return ptr_ == x.ptr_; }
bool operator!=(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return base_ != x.base_; } bool operator!=(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return ptr_ != x.ptr_; }
bool operator!=(const_local_iterator x) const { return base_ != x.base_; } bool operator!=(const_local_iterator x) const { return ptr_ != x.ptr_; }
}; };
template <typename Alloc> template <typename Alloc>
@@ -2055,24 +2004,27 @@ public:
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type; typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
private: private:
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base; typedef BOOST_UNORDERED_TABLE_DATA<Alloc> data;
typedef BOOST_DEDUCED_TYPENAME data::link_ptr ptr;
typedef BOOST_UNORDERED_LOCAL_ITERATOR<Alloc> local_iterator; typedef BOOST_UNORDERED_LOCAL_ITERATOR<Alloc> local_iterator;
friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>; friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>;
base base_; ptr ptr_;
public: public:
BOOST_UNORDERED_CONST_LOCAL_ITERATOR() : base_() {} BOOST_UNORDERED_CONST_LOCAL_ITERATOR() : ptr_() {
explicit BOOST_UNORDERED_CONST_LOCAL_ITERATOR(base x) : base_(x) {} BOOST_HASH_MSVC_RESET_PTR(ptr_);
BOOST_UNORDERED_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {} }
explicit BOOST_UNORDERED_CONST_LOCAL_ITERATOR(ptr x) : ptr_(x) {}
BOOST_UNORDERED_CONST_LOCAL_ITERATOR(local_iterator x) : ptr_(x.ptr_) {}
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
operator*() const { return *base_; } operator*() const { return data::get_value(ptr_); }
value_type const* operator->() const { return &*base_; } value_type const* operator->() const { return &data::get_value(ptr_); }
BOOST_UNORDERED_CONST_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; } BOOST_UNORDERED_CONST_LOCAL_ITERATOR& operator++() { ptr_ = ptr_->next_; return *this; }
BOOST_UNORDERED_CONST_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_CONST_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; } BOOST_UNORDERED_CONST_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_CONST_LOCAL_ITERATOR tmp(ptr_); ptr_ = ptr_->next_; return tmp; }
bool operator==(local_iterator x) const { return base_ == x.base_; } bool operator==(local_iterator x) const { return ptr_ == x.ptr_; }
bool operator==(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return base_ == x.base_; } bool operator==(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return ptr_ == x.ptr_; }
bool operator!=(local_iterator x) const { return base_ != x.base_; } bool operator!=(local_iterator x) const { return ptr_ != x.ptr_; }
bool operator!=(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return base_ != x.base_; } bool operator!=(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return ptr_ != x.ptr_; }
}; };
// iterators // iterators