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