From 9772c01161e2bbfb93127416c6c5429b51b55e30 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 22 Oct 2016 10:04:36 +0100 Subject: [PATCH] Replace several uses of iterators with node pointers. Which is to some extent going in circles, as this is how the containers were originally implemented. But I think this is cleaner. It also fixes a minor problem where the internal and external iterator types are different for some containers, as the external iterators are all const. --- include/boost/unordered/detail/buckets.hpp | 14 +- include/boost/unordered/detail/equivalent.hpp | 156 +++++++++--------- include/boost/unordered/detail/table.hpp | 33 ++-- include/boost/unordered/detail/unique.hpp | 134 ++++++++------- include/boost/unordered/unordered_map.hpp | 28 ++-- include/boost/unordered/unordered_set.hpp | 14 +- 6 files changed, 196 insertions(+), 183 deletions(-) diff --git a/include/boost/unordered/detail/buckets.hpp b/include/boost/unordered/detail/buckets.hpp index e0835c56..b857bfd6 100644 --- a/include/boost/unordered/detail/buckets.hpp +++ b/include/boost/unordered/detail/buckets.hpp @@ -61,7 +61,6 @@ namespace boost { namespace unordered { namespace iterator_detail { private: #endif typedef typename Node::node_pointer node_pointer; - typedef boost::unordered::iterator_detail::iterator n_iterator; node_pointer ptr_; std::size_t bucket_; std::size_t bucket_count_; @@ -72,8 +71,8 @@ namespace boost { namespace unordered { namespace iterator_detail { l_iterator() BOOST_NOEXCEPT : ptr_() {} - l_iterator(n_iterator x, std::size_t b, std::size_t c) BOOST_NOEXCEPT - : ptr_(x.node_), bucket_(b), bucket_count_(c) {} + l_iterator(node_pointer n, std::size_t b, std::size_t c) BOOST_NOEXCEPT + : ptr_(n), bucket_(b), bucket_count_(c) {} value_type& operator*() const { return ptr_->value(); @@ -120,7 +119,6 @@ namespace boost { namespace unordered { namespace iterator_detail { private: typedef typename Node::node_pointer node_pointer; - typedef boost::unordered::iterator_detail::iterator n_iterator; node_pointer ptr_; std::size_t bucket_; std::size_t bucket_count_; @@ -131,8 +129,8 @@ namespace boost { namespace unordered { namespace iterator_detail { cl_iterator() BOOST_NOEXCEPT : ptr_() {} - cl_iterator(n_iterator x, std::size_t b, std::size_t c) BOOST_NOEXCEPT : - ptr_(x.node_), bucket_(b), bucket_count_(c) {} + cl_iterator(node_pointer n, std::size_t b, std::size_t c) BOOST_NOEXCEPT : + ptr_(n), bucket_(b), bucket_count_(c) {} cl_iterator(boost::unordered::iterator_detail::l_iterator< Node, Policy> const& x) BOOST_NOEXCEPT : @@ -186,10 +184,6 @@ namespace boost { namespace unordered { namespace iterator_detail { #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template friend struct boost::unordered::iterator_detail::c_iterator; - template - friend struct boost::unordered::iterator_detail::l_iterator; - template - friend struct boost::unordered::iterator_detail::cl_iterator; template friend struct boost::unordered::detail::table; template diff --git a/include/boost/unordered/detail/equivalent.hpp b/include/boost/unordered/detail/equivalent.hpp index 76825f20..16fc1f10 100644 --- a/include/boost/unordered/detail/equivalent.hpp +++ b/include/boost/unordered/detail/equivalent.hpp @@ -188,48 +188,58 @@ namespace boost { namespace unordered { namespace detail { this->move_init(x); } + // Node functions. + + static inline node_pointer next_node(link_pointer n) { + return static_cast(n->next_); + } + + static inline node_pointer next_group(node_pointer n) { + return static_cast(n->group_prev_->next_); + } + // Accessors template - iterator find_node_impl( + node_pointer find_node_impl( std::size_t key_hash, Key const& k, Pred const& eq) const { std::size_t bucket_index = this->hash_to_bucket(key_hash); - iterator n = this->begin(bucket_index); + node_pointer n = this->begin(bucket_index); for (;;) { - if (!n.node_) return n; + if (!n) return n; - std::size_t node_hash = n.node_->hash_; + std::size_t node_hash = n->hash_; if (key_hash == node_hash) { - if (eq(k, this->get_key(*n))) + if (eq(k, this->get_key(n->value()))) return n; } else { if (this->hash_to_bucket(node_hash) != bucket_index) - return iterator(); + return node_pointer(); } - n = iterator(n.node_->group_prev_->next_); + n = next_group(n); } } std::size_t count(key_type const& k) const { - iterator n = this->find_node(k); - if (!n.node_) return 0; + node_pointer n = this->find_node(k); + if (!n) return 0; std::size_t x = 0; - node_pointer it = n.node_; + node_pointer it = n; do { it = it->group_prev_; ++x; - } while(it != n.node_); + } while(it != n); return x; } @@ -237,9 +247,8 @@ namespace boost { namespace unordered { namespace detail { std::pair equal_range(key_type const& k) const { - iterator n = this->find_node(k); - return std::make_pair( - n, n.node_ ? iterator(n.node_->group_prev_->next_) : n); + node_pointer n = this->find_node(k); + return std::make_pair(iterator(n), iterator(n ? next_group(n) : n)); } // Equality @@ -248,12 +257,12 @@ namespace boost { namespace unordered { namespace detail { { if(this->size_ != other.size_) return false; - for(iterator n1 = this->begin(); n1.node_;) + for(iterator n1(this->begin()); n1.node_;) { - iterator n2 = other.find_matching_node(n1); + iterator n2(other.find_matching_node(n1)); if (!n2.node_) return false; - iterator end1(n1.node_->group_prev_->next_); - iterator end2(n2.node_->group_prev_->next_); + iterator end1(next_group(n1.node_)); + iterator end2(next_group(n2.node_)); if (!group_equals(n1, end1, n2, end2)) return false; n1 = end1; } @@ -336,17 +345,17 @@ namespace boost { namespace unordered { namespace detail { pos->group_prev_ = n; } - inline iterator add_node( + inline node_pointer add_node( node_pointer n, std::size_t key_hash, - iterator pos) + node_pointer pos) { n->hash_ = key_hash; - if (pos.node_) { - this->add_to_node_group(n, pos.node_); + if (pos) { + this->add_to_node_group(n, pos); if (n->next_) { std::size_t next_bucket = this->hash_to_bucket( - static_cast(n->next_)->hash_); + next_node(n)->hash_); if (next_bucket != this->hash_to_bucket(key_hash)) { this->get_bucket(next_bucket)->next_ = n; } @@ -362,7 +371,7 @@ namespace boost { namespace unordered { namespace detail { if (start_node->next_) { this->get_bucket(this->hash_to_bucket( - static_cast(start_node->next_)->hash_ + next_node(start_node)->hash_ ))->next_ = n; } @@ -377,10 +386,10 @@ namespace boost { namespace unordered { namespace detail { } } ++this->size_; - return iterator(n); + return n; } - inline iterator add_using_hint( + inline node_pointer add_using_hint( node_pointer n, node_pointer hint) { @@ -388,13 +397,13 @@ namespace boost { namespace unordered { namespace detail { this->add_to_node_group(n, hint); if (n->next_ != hint && n->next_) { std::size_t next_bucket = this->hash_to_bucket( - static_cast(n->next_)->hash_); + next_node(n)->hash_); if (next_bucket != this->hash_to_bucket(n->hash_)) { this->get_bucket(next_bucket)->next_ = n; } } ++this->size_; - return iterator(n); + return n; } @@ -451,9 +460,9 @@ namespace boost { namespace unordered { namespace detail { node_tmp a(n, this->node_alloc()); key_type const& k = this->get_key(a.node_->value()); std::size_t key_hash = this->hash(k); - iterator position = this->find_node(key_hash, k); + node_pointer position = this->find_node(key_hash, k); this->reserve_for_insert(this->size_ + 1); - return this->add_node(a.release(), key_hash, position); + return iterator(this->add_node(a.release(), key_hash, position)); } iterator emplace_hint_impl(c_iterator hint, node_pointer n) @@ -462,13 +471,13 @@ namespace boost { namespace unordered { namespace detail { key_type const& k = this->get_key(a.node_->value()); if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) { this->reserve_for_insert(this->size_ + 1); - return this->add_using_hint(a.release(), hint.node_); + return iterator(this->add_using_hint(a.release(), hint.node_)); } else { std::size_t key_hash = this->hash(k); - iterator position = this->find_node(key_hash, k); + node_pointer position = this->find_node(key_hash, k); this->reserve_for_insert(this->size_ + 1); - return this->add_node(a.release(), key_hash, position); + return iterator(this->add_node(a.release(), key_hash, position)); } } @@ -477,7 +486,7 @@ namespace boost { namespace unordered { namespace detail { node_tmp a(n, this->node_alloc()); key_type const& k = this->get_key(a.node_->value()); std::size_t key_hash = this->hash(k); - iterator position = this->find_node(key_hash, k); + node_pointer position = this->find_node(key_hash, k); this->add_node(a.release(), key_hash, position); } @@ -535,21 +544,21 @@ namespace boost { namespace unordered { namespace detail { link_pointer prev = this->get_previous_start(bucket_index); if (!prev) return 0; + node_pointer first_node; + for (;;) { if (!prev->next_) return 0; - std::size_t node_hash = - static_cast(prev->next_)->hash_; + first_node = next_node(prev); + std::size_t node_hash = first_node->hash_; if (this->hash_to_bucket(node_hash) != bucket_index) return 0; if (node_hash == key_hash && - this->key_eq()(k, this->get_key( - static_cast(prev->next_)->value()))) + this->key_eq()(k, this->get_key(first_node->value()))) break; - prev = static_cast(prev->next_)->group_prev_; + prev = first_node->group_prev_; } - node_pointer first_node = static_cast(prev->next_); link_pointer end = first_node->group_prev_->next_; std::size_t deleted_count = this->delete_nodes(prev, end); @@ -560,10 +569,9 @@ namespace boost { namespace unordered { namespace detail { iterator erase(c_iterator r) { BOOST_ASSERT(r.node_); - iterator next(r.node_); - ++next; - erase_nodes(r.node_, next.node_); - return next; + node_pointer next = next_node(r.node_); + erase_nodes(r.node_, next); + return iterator(next); } iterator erase_range(c_iterator r1, c_iterator r2) @@ -588,13 +596,12 @@ namespace boost { namespace unordered { namespace detail { if (!prev) { prev = this->get_previous_start(bucket_index); while (prev->next_ != i) - prev = static_cast(prev->next_)->group_prev_; + prev = next_node(prev)->group_prev_; } // Delete the nodes. do { - link_pointer group_end = - static_cast(prev->next_)->group_prev_->next_; + link_pointer group_end = next_group(next_node(prev)); this->delete_nodes(prev, group_end); bucket_index = this->fix_bucket(bucket_index, prev); } while(prev->next_ != j); @@ -634,17 +641,17 @@ namespace boost { namespace unordered { namespace detail { void copy_buckets(table const& src) { this->create_buckets(this->bucket_count_); - for (iterator n = src.begin(); n.node_;) { - std::size_t key_hash = n.node_->hash_; - iterator group_end(n.node_->group_prev_->next_); - iterator pos = this->add_node( + for (node_pointer n = src.begin(); n;) { + std::size_t key_hash = n->hash_; + node_pointer group_end(next_group(n)); + node_pointer pos = this->add_node( boost::unordered::detail::func::construct_value( - this->node_alloc(), *n), key_hash, iterator()); - for (++n; n != group_end; ++n) + this->node_alloc(), n->value()), key_hash, node_pointer()); + for (n = next_node(n); n != group_end; n = next_node(n)) { this->add_node( boost::unordered::detail::func::construct_value( - this->node_alloc(), *n), key_hash, pos); + this->node_alloc(), n->value()), key_hash, pos); } } } @@ -652,43 +659,43 @@ namespace boost { namespace unordered { namespace detail { void move_buckets(table const& src) { this->create_buckets(this->bucket_count_); - for (iterator n = src.begin(); n.node_;) { - std::size_t key_hash = n.node_->hash_; - iterator group_end(n.node_->group_prev_->next_); - iterator pos = this->add_node( + for (node_pointer n = src.begin(); n;) { + std::size_t key_hash = n->hash_; + node_pointer group_end(next_group(n)); + node_pointer pos = this->add_node( boost::unordered::detail::func::construct_value( - this->node_alloc(), boost::move(*n)), key_hash, iterator()); - for (++n; n != group_end; ++n) + this->node_alloc(), boost::move(n->value())), key_hash, node_pointer()); + for (n = next_node(n); n != group_end; n = next_node(n)) { this->add_node( boost::unordered::detail::func::construct_value( - this->node_alloc(), boost::move(*n)), key_hash, pos); + this->node_alloc(), boost::move(n->value())), key_hash, pos); } } } void assign_buckets(table const& src) { node_holder holder(*this); - for (iterator n = src.begin(); n.node_;) { - std::size_t key_hash = n.node_->hash_; - iterator group_end(n.node_->group_prev_->next_); - iterator pos = this->add_node(holder.copy_of(*n), key_hash, iterator()); - for (++n; n != group_end; ++n) + for (node_pointer n = src.begin(); n;) { + std::size_t key_hash = n->hash_; + node_pointer group_end(next_group(n)); + node_pointer pos = this->add_node(holder.copy_of(n->value()), key_hash, node_pointer()); + for (n = next_node(n); n != group_end; n = next_node(n)) { - this->add_node(holder.copy_of(*n), key_hash, pos); + this->add_node(holder.copy_of(n->value()), key_hash, pos); } } } void move_assign_buckets(table& src) { node_holder holder(*this); - for (iterator n = src.begin(); n.node_;) { - std::size_t key_hash = n.node_->hash_; - iterator group_end(n.node_->group_prev_->next_); - iterator pos = this->add_node(holder.move_copy_of(*n), key_hash, iterator()); - for (++n; n != group_end; ++n) + for (node_pointer n = src.begin(); n;) { + std::size_t key_hash = n->hash_; + node_pointer group_end(next_group(n)); + node_pointer pos = this->add_node(holder.move_copy_of(n->value()), key_hash, node_pointer()); + for (n = next_node(n); n != group_end; n = next_node(n)) { - this->add_node(holder.move_copy_of(*n), key_hash, pos); + this->add_node(holder.move_copy_of(n->value()), key_hash, pos); } } } @@ -701,8 +708,7 @@ namespace boost { namespace unordered { namespace detail { this->create_buckets(num_buckets); link_pointer prev = this->get_previous_start(); while (prev->next_) - prev = place_in_bucket(*this, prev, - static_cast(prev->next_)->group_prev_); + prev = place_in_bucket(*this, prev, next_node(prev)->group_prev_); } // Iterate through the nodes placing them in the correct buckets. diff --git a/include/boost/unordered/detail/table.hpp b/include/boost/unordered/detail/table.hpp index 6ae1d73e..10e03cb8 100644 --- a/include/boost/unordered/detail/table.hpp +++ b/include/boost/unordered/detail/table.hpp @@ -130,6 +130,13 @@ namespace boost { namespace unordered { namespace detail { std::size_t max_load_; bucket_pointer buckets_; + //////////////////////////////////////////////////////////////////////// + // Node functions + + static inline node_pointer next_node(link_pointer n) { + return static_cast(n->next_); + } + //////////////////////////////////////////////////////////////////////// // Data access @@ -176,16 +183,16 @@ namespace boost { namespace unordered { namespace detail { return get_bucket(bucket_index)->next_; } - iterator begin() const + node_pointer begin() const { - return size_ ? iterator(get_previous_start()->next_) : iterator(); + return size_ ? next_node(get_previous_start()) : node_pointer(); } - iterator begin(std::size_t bucket_index) const + node_pointer begin(std::size_t bucket_index) const { - if (!size_) return iterator(); + if (!size_) return node_pointer(); link_pointer prev = get_previous_start(bucket_index); - return prev ? iterator(prev->next_) : iterator(); + return prev ? next_node(prev) : node_pointer(); } std::size_t hash_to_bucket(std::size_t hash_value) const @@ -202,14 +209,14 @@ namespace boost { namespace unordered { namespace detail { std::size_t bucket_size(std::size_t index) const { - iterator it = begin(index); - if (!it.node_) return 0; + node_pointer n = begin(index); + if (!n) return 0; std::size_t count = 0; - while(it.node_ && hash_to_bucket(it.node_->hash_) == index) + while(n && hash_to_bucket(n->hash_) == index) { ++count; - ++it; + n = next_node(n); } return count; @@ -698,7 +705,7 @@ namespace boost { namespace unordered { namespace detail { // Find Node template - iterator generic_find_node( + node_pointer generic_find_node( Key const& k, Hash const& hf, Pred const& eq) const @@ -707,7 +714,7 @@ namespace boost { namespace unordered { namespace detail { find_node_impl(policy::apply_hash(hf, k), k, eq); } - iterator find_node( + node_pointer find_node( std::size_t key_hash, key_type const& k) const { @@ -715,13 +722,13 @@ namespace boost { namespace unordered { namespace detail { find_node_impl(key_hash, k, this->key_eq()); } - iterator find_node(key_type const& k) const + node_pointer find_node(key_type const& k) const { return static_cast(this)-> find_node_impl(hash(k), k, this->key_eq()); } - iterator find_matching_node(iterator n) const + node_pointer find_matching_node(iterator n) const { // TODO: Does this apply to C++11? // diff --git a/include/boost/unordered/detail/unique.hpp b/include/boost/unordered/detail/unique.hpp index eb26c232..52fd3cde 100644 --- a/include/boost/unordered/detail/unique.hpp +++ b/include/boost/unordered/detail/unique.hpp @@ -186,47 +186,53 @@ namespace boost { namespace unordered { namespace detail { this->move_init(x); } + // Node functions. + + static inline node_pointer next_node(link_pointer n) { + return static_cast(n->next_); + } + // Accessors template - iterator find_node_impl( + node_pointer find_node_impl( std::size_t key_hash, Key const& k, Pred const& eq) const { std::size_t bucket_index = this->hash_to_bucket(key_hash); - iterator n = this->begin(bucket_index); + node_pointer n = this->begin(bucket_index); for (;;) { - if (!n.node_) return n; + if (!n) return n; - std::size_t node_hash = n.node_->hash_; + std::size_t node_hash = n->hash_; if (key_hash == node_hash) { - if (eq(k, this->get_key(*n))) + if (eq(k, this->get_key(n->value()))) return n; } else { if (this->hash_to_bucket(node_hash) != bucket_index) - return iterator(); + return node_pointer(); } - ++n; + n = next_node(n); } } std::size_t count(key_type const& k) const { - return this->find_node(k).node_ ? 1 : 0; + return this->find_node(k) ? 1 : 0; } value_type& at(key_type const& k) const { if (this->size_) { - iterator it = this->find_node(k); - if (it.node_) return *it; + node_pointer n = this->find_node(k); + if (n) return n->value(); } boost::throw_exception( @@ -236,10 +242,8 @@ namespace boost { namespace unordered { namespace detail { std::pair equal_range(key_type const& k) const { - iterator n = this->find_node(k); - iterator n2 = n; - if (n2.node_) ++n2; - return std::make_pair(n, n2); + node_pointer n = this->find_node(k); + return std::make_pair(iterator(n), iterator(n ? next_node(n) : n)); } // equals @@ -248,11 +252,11 @@ namespace boost { namespace unordered { namespace detail { { if(this->size_ != other.size_) return false; - for(iterator n1 = this->begin(); n1.node_; ++n1) + for(iterator n1(this->begin()); n1.node_; ++n1) { - iterator n2 = other.find_matching_node(n1); + node_pointer n2 = other.find_matching_node(n1); - if (!n2.node_ || *n1 != *n2) + if (!n2 || *n1 != n2->value()) return false; } @@ -261,7 +265,7 @@ namespace boost { namespace unordered { namespace detail { // Emplace/Insert - inline iterator add_node( + inline node_pointer add_node( node_pointer n, std::size_t key_hash) { @@ -275,7 +279,7 @@ namespace boost { namespace unordered { namespace detail { if (start_node->next_) { this->get_bucket(this->hash_to_bucket( - static_cast(start_node->next_)->hash_) + next_node(start_node)->hash_) )->next_ = n; } @@ -290,10 +294,10 @@ namespace boost { namespace unordered { namespace detail { } ++this->size_; - return iterator(n); + return n; } - inline iterator resize_and_add_node(node_pointer n, std::size_t key_hash) + inline node_pointer resize_and_add_node(node_pointer n, std::size_t key_hash) { node_tmp b(n, this->node_alloc()); this->reserve_for_insert(this->size_ + 1); @@ -303,11 +307,15 @@ namespace boost { namespace unordered { namespace detail { value_type& operator[](key_type const& k) { std::size_t key_hash = this->hash(k); - iterator pos = this->find_node(key_hash, k); - if (pos.node_) return *pos; - return *this->resize_and_add_node( - boost::unordered::detail::func::construct_pair(this->node_alloc(), k), - key_hash); + node_pointer pos = this->find_node(key_hash, k); + if (pos) { + return pos->value(); + } + else { + return this->resize_and_add_node( + boost::unordered::detail::func::construct_pair(this->node_alloc(), k), + key_hash)->value(); + } } #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) @@ -316,7 +324,7 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::please_ignore_this_overload> const&) { BOOST_ASSERT(false); - return emplace_return(this->begin(), false); + return emplace_return(iterator(), false); } iterator emplace_hint(c_iterator, @@ -324,21 +332,21 @@ namespace boost { namespace unordered { namespace detail { boost::unordered::detail::please_ignore_this_overload> const&) { BOOST_ASSERT(false); - return this->begin(); + return iterator(); } # else emplace_return emplace( boost::unordered::detail::please_ignore_this_overload const&) { BOOST_ASSERT(false); - return emplace_return(this->begin(), false); + return emplace_return(iterator(), false); } iterator emplace_hint(c_iterator, boost::unordered::detail::please_ignore_this_overload const&) { BOOST_ASSERT(false); - return this->begin(); + return iterator(); } # endif #endif @@ -405,16 +413,16 @@ namespace boost { namespace unordered { namespace detail { BOOST_UNORDERED_EMPLACE_ARGS) { std::size_t key_hash = this->hash(k); - iterator pos = this->find_node(key_hash, k); - if (pos.node_) { - return emplace_return(pos, false); + node_pointer pos = this->find_node(key_hash, k); + if (pos) { + return emplace_return(iterator(pos), false); } else { return emplace_return( - this->resize_and_add_node( + iterator(this->resize_and_add_node( boost::unordered::detail::func::construct_value_generic( this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD), - key_hash), + key_hash)), true); } } @@ -432,12 +440,12 @@ namespace boost { namespace unordered { namespace detail { return iterator(hint.node_); } std::size_t key_hash = this->hash(k); - iterator pos = this->find_node(key_hash, k); - if (pos.node_) { - return pos; + node_pointer pos = this->find_node(key_hash, k); + if (pos) { + return iterator(pos); } else { - return this->resize_and_add_node(b.release(), key_hash); + return iterator(this->resize_and_add_node(b.release(), key_hash)); } } @@ -450,13 +458,13 @@ namespace boost { namespace unordered { namespace detail { this->node_alloc()); key_type const& k = this->get_key(b.node_->value()); std::size_t key_hash = this->hash(k); - iterator pos = this->find_node(key_hash, k); - if (pos.node_) { - return emplace_return(pos, false); + node_pointer pos = this->find_node(key_hash, k); + if (pos) { + return emplace_return(iterator(pos), false); } else { return emplace_return( - this->resize_and_add_node(b.release(), key_hash), + iterator(this->resize_and_add_node(b.release(), key_hash)), true); } } @@ -497,9 +505,9 @@ namespace boost { namespace unordered { namespace detail { { // No side effects in this initial code std::size_t key_hash = this->hash(k); - iterator pos = this->find_node(key_hash, k); + node_pointer pos = this->find_node(key_hash, k); - if (!pos.node_) { + if (!pos) { node_tmp b( boost::unordered::detail::func::construct_value(this->node_alloc(), *i), this->node_alloc()); @@ -523,9 +531,9 @@ namespace boost { namespace unordered { namespace detail { key_type const& k = this->get_key(b.node_->value()); std::size_t key_hash = this->hash(k); - iterator pos = this->find_node(key_hash, k); + node_pointer pos = this->find_node(key_hash, k); - if (pos.node_) { + if (pos) { a.reclaim(b.release()); } else { @@ -554,18 +562,17 @@ namespace boost { namespace unordered { namespace detail { for (;;) { if (!prev->next_) return 0; - std::size_t node_hash = - static_cast(prev->next_)->hash_; + std::size_t node_hash = next_node(prev)->hash_; if (this->hash_to_bucket(node_hash) != bucket_index) return 0; if (node_hash == key_hash && this->key_eq()(k, this->get_key( - static_cast(prev->next_)->value()))) + next_node(prev)->value()))) break; prev = prev->next_; } - link_pointer end = static_cast(prev->next_)->next_; + link_pointer end = next_node(prev)->next_; std::size_t deleted_count = this->delete_nodes(prev, end); this->fix_bucket(bucket_index, prev); @@ -575,10 +582,9 @@ namespace boost { namespace unordered { namespace detail { iterator erase(c_iterator r) { BOOST_ASSERT(r.node_); - iterator next(r.node_); - ++next; - erase_nodes(r.node_, next.node_); - return next; + node_pointer next = next_node(r.node_); + erase_nodes(r.node_, next); + return iterator(next); } iterator erase_range(c_iterator r1, c_iterator r2) @@ -609,36 +615,36 @@ namespace boost { namespace unordered { namespace detail { void copy_buckets(table const& src) { this->create_buckets(this->bucket_count_); - for(iterator n = src.begin(); n.node_; ++n) { + for(node_pointer n = src.begin(); n; n = next_node(n)) { this->add_node( boost::unordered::detail::func::construct_value( - this->node_alloc(), *n), n.node_->hash_); + this->node_alloc(), n->value()), n->hash_); } } void move_buckets(table const& src) { this->create_buckets(this->bucket_count_); - for(iterator n = src.begin(); n.node_; ++n) { + for(node_pointer n = src.begin(); n; n = next_node(n)) { this->add_node( boost::unordered::detail::func::construct_value( - this->node_alloc(), boost::move(*n)), n.node_->hash_); + this->node_alloc(), boost::move(n->value())), n->hash_); } } void assign_buckets(table const& src) { node_holder holder(*this); - for(iterator n = src.begin(); n.node_; ++n) { - this->add_node(holder.copy_of(*n), n.node_->hash_); + for(node_pointer n = src.begin(); n; n = next_node(n)) { + this->add_node(holder.copy_of(n->value()), n->hash_); } } void move_assign_buckets(table& src) { node_holder holder(*this); - for(iterator n = src.begin(); n.node_; ++n) { - this->add_node(holder.move_copy_of(*n), n.node_->hash_); + for(node_pointer n = src.begin(); n; n = next_node(n)) { + this->add_node(holder.move_copy_of(n->value()), n->hash_); } } @@ -657,7 +663,7 @@ namespace boost { namespace unordered { namespace detail { // pre: prev->next_ is not null. static link_pointer place_in_bucket(table& dst, link_pointer prev) { - node_pointer n = static_cast(prev->next_); + node_pointer n = next_node(prev); bucket_pointer b = dst.get_bucket(dst.hash_to_bucket(n->hash_)); if (!b->next_) { diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index fc6fbe0e..84f144c5 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -202,12 +202,12 @@ namespace unordered iterator begin() BOOST_NOEXCEPT { - return table_.begin(); + return iterator(table_.begin()); } const_iterator begin() const BOOST_NOEXCEPT { - return table_.begin(); + return const_iterator(table_.begin()); } iterator end() BOOST_NOEXCEPT @@ -222,7 +222,7 @@ namespace unordered const_iterator cbegin() const BOOST_NOEXCEPT { - return table_.begin(); + return const_iterator(table_.begin()); } const_iterator cend() const BOOST_NOEXCEPT @@ -686,12 +686,12 @@ namespace unordered iterator begin() BOOST_NOEXCEPT { - return table_.begin(); + return iterator(table_.begin()); } const_iterator begin() const BOOST_NOEXCEPT { - return table_.begin(); + return const_iterator(table_.begin()); } iterator end() BOOST_NOEXCEPT @@ -706,7 +706,7 @@ namespace unordered const_iterator cbegin() const BOOST_NOEXCEPT { - return table_.begin(); + return const_iterator(table_.begin()); } const_iterator cend() const BOOST_NOEXCEPT @@ -1208,14 +1208,14 @@ namespace unordered typename unordered_map::iterator unordered_map::find(const key_type& k) { - return table_.find_node(k); + return iterator(table_.find_node(k)); } template typename unordered_map::const_iterator unordered_map::find(const key_type& k) const { - return table_.find_node(k); + return const_iterator(table_.find_node(k)); } template @@ -1227,7 +1227,7 @@ namespace unordered CompatibleHash const& hash, CompatiblePredicate const& eq) { - return table_.generic_find_node(k, hash, eq); + return iterator(table_.generic_find_node(k, hash, eq)); } template @@ -1239,7 +1239,7 @@ namespace unordered CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return table_.generic_find_node(k, hash, eq); + return const_iterator(table_.generic_find_node(k, hash, eq)); } template @@ -1520,14 +1520,14 @@ namespace unordered typename unordered_multimap::iterator unordered_multimap::find(const key_type& k) { - return table_.find_node(k); + return iterator(table_.find_node(k)); } template typename unordered_multimap::const_iterator unordered_multimap::find(const key_type& k) const { - return table_.find_node(k); + return const_iterator(table_.find_node(k)); } template @@ -1539,7 +1539,7 @@ namespace unordered CompatibleHash const& hash, CompatiblePredicate const& eq) { - return table_.generic_find_node(k, hash, eq); + return iterator(table_.generic_find_node(k, hash, eq)); } template @@ -1551,7 +1551,7 @@ namespace unordered CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return table_.generic_find_node(k, hash, eq); + return const_iterator(table_.generic_find_node(k, hash, eq)); } template diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index aa9911bc..be17c399 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -199,12 +199,12 @@ namespace unordered iterator begin() BOOST_NOEXCEPT { - return table_.begin(); + return iterator(table_.begin()); } const_iterator begin() const BOOST_NOEXCEPT { - return table_.begin(); + return const_iterator(table_.begin()); } iterator end() BOOST_NOEXCEPT @@ -219,7 +219,7 @@ namespace unordered const_iterator cbegin() const BOOST_NOEXCEPT { - return table_.begin(); + return const_iterator(table_.begin()); } const_iterator cend() const BOOST_NOEXCEPT @@ -1161,7 +1161,7 @@ namespace unordered typename unordered_set::const_iterator unordered_set::find(const key_type& k) const { - return table_.find_node(k); + return const_iterator(table_.find_node(k)); } template @@ -1173,7 +1173,7 @@ namespace unordered CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return table_.generic_find_node(k, hash, eq); + return const_iterator(table_.generic_find_node(k, hash, eq)); } template @@ -1445,7 +1445,7 @@ namespace unordered typename unordered_multiset::const_iterator unordered_multiset::find(const key_type& k) const { - return table_.find_node(k); + return const_iterator(table_.find_node(k)); } template @@ -1457,7 +1457,7 @@ namespace unordered CompatibleHash const& hash, CompatiblePredicate const& eq) const { - return table_.generic_find_node(k, hash, eq); + return const_iterator(table_.generic_find_node(k, hash, eq)); } template