$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: daniel_james_at_[hidden]
Date: 2007-12-18 17:51:31
Author: danieljames
Date: 2007-12-18 17:51:31 EST (Tue, 18 Dec 2007)
New Revision: 42153
URL: http://svn.boost.org/trac/boost/changeset/42153
Log:
Remove 'local_iterator_base'. It isn't really needed.
Text files modified: 
   sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp |   374 +++++++++++++++++---------------------- 
   1 files changed, 163 insertions(+), 211 deletions(-)
Modified: sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp	(original)
+++ sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp	2007-12-18 17:51:31 EST (Tue, 18 Dec 2007)
@@ -207,7 +207,7 @@
                 {
                     node_ptr p = node_;
                     unordered_detail::reset(node_);
-                    return link_ptr(allocators_.bucket_alloc_.address(*p));
+                    return allocators_.bucket_alloc_.address(*p);
                 }
 
             private:
@@ -256,98 +256,48 @@
                 return static_cast<node&>(*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) {}
-
-                bool not_finished() const
-                {
-                    return node_ ? true : false;
-                }
-
-                bool operator==(local_iterator_base const& x) const
-                {
-                    return node_ == x.node_;
-                }
-
-                bool operator!=(local_iterator_base const& x) const
-                {
-                    return node_ != x.node_;
-                }
-
-                reference operator*() const
-                {
-                    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_) {}
+                    : bucket_(b), node_(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) {}
+                    : bucket_(b), node_(n) {}
 
                 bool operator==(iterator_base const& x) const
                 {
-                    return local_ == x.local_;
+                    return node_ == x.node_;
                 }
 
                 bool operator!=(iterator_base const& x) const
                 {
-                    return local_ != x.local_;
+                    return node_ != x.node_;
                 }
 
                 reference operator*() const
                 {
-                    return *local_;
+                    return get_value(node_);
                 }
 
                 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 @@
                 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 @@
             }
 
 #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 @@
                 return count;
             }
 #else
-            size_type group_count(local_iterator_base) const
+            size_type group_count(link_ptr) const
             {
                 return 1;
             }
@@ -539,7 +489,7 @@
 #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 @@
 #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 @@
             // 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 @@
                 ++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 @@
                 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 @@
 
             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 @@
             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 @@
 
             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 @@
                 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 @@
             {
                 // 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 @@
                 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 @@
                 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 @@
                 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 @@
 
                     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 @@
                         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 @@
 
             // 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 @@
                 // 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 @@
                 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 @@
 
                 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 @@
                     // 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 @@
 
                         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 @@
 
                 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 @@
                     // 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 @@
                 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, bool>(
                         iterator_base(bucket, pos), false);
@@ -1709,7 +1657,7 @@
                     // 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, bool>(
                         iterator_base(bucket, n), true);
@@ -1762,9 +1710,9 @@
                     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 @@
                         }
 
                         // Nothing after this point can throw.
-                        this->link_node(a.release(), bucket);
+                        this->link_node_in_bucket(a.release(), bucket);
                     }
                 }
             }
@@ -1819,8 +1767,8 @@
             // 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 @@
             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 @@
             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 @@
             std::pair<iterator_base, iterator_base> 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<iterator_base, iterator_base>(first, second);
                 }
@@ -1873,36 +1821,34 @@
 
 private:
 #if BOOST_UNORDERED_HASH_EQUIVALENT
-            inline bool group_equals(local_iterator_base it1,
-                    local_iterator_base it2, type_wrapper<key_type>*) const
+            inline bool group_equals(link_ptr it1, link_ptr it2,
+                    type_wrapper<key_type>*) 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<key_type>*) const
+            inline bool group_equals(link_ptr it1, link_ptr it2,
+                    type_wrapper<key_type>*) 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 @@
                 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<value_type>*)0))
                             return false;
                     }
@@ -1926,22 +1872,22 @@
                 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);
-                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 @@
                 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<value_type>*)0);
                 }
 
@@ -1970,18 +1916,18 @@
             }
 
             // 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 @@
             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 @@
             typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
 
         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;
 
             friend class BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc>;
-            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<Alloc>::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 <typename Alloc>
@@ -2055,24 +2004,27 @@
             typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
 
         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;
             friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>;
-            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<Alloc>::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