inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return hash_unique_table<H, P, A, K>::emplace_impl_with_node(node_constructor& a) { // No side effects in this initial code key_type const& k = this->get_key(a.value()); std::size_t hash_value = this->hash_function()(k); bucket_ptr bucket = this->bucket_ptr_from_hash(hash_value); node_ptr pos = this->find_iterator(bucket, k); if (BOOST_UNORDERED_BORLAND_BOOL(pos)) { // Found an existing key, return it (no throw). return emplace_return(iterator_base(bucket, pos), false); } else { // reserve has basic exception safety if the hash function // throws, strong otherwise. if(this->reserve_for_insert(this->size_ + 1)) bucket = this->bucket_ptr_from_hash(hash_value); // Nothing after this point can throw. return emplace_return( iterator_base(bucket, add_node(a, bucket)), true); } }
void emplace_impl_no_rehash(node_constructor& a) { key_type const& k = this->get_key(a.value()); std::size_t hash = this->hash_function()(k); std::size_t bucket_index = hash % this->bucket_count_; add_node(a, bucket_index, hash, this->find_node(bucket_index, hash, k)); }
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::node_ptr hash_unique_table<H, P, A, K>::add_node(node_constructor& a, bucket_ptr bucket) { node_ptr n = a.release(); node::add_to_bucket(n, *bucket); ++this->size_; if(bucket < this->cached_begin_bucket_) this->cached_begin_bucket_ = bucket; return n; }
node_ptr emplace_impl(node_constructor& a) { key_type const& k = this->get_key(a.value()); std::size_t hash = this->hash_function()(k); std::size_t bucket_index = hash % this->bucket_count_; node_ptr position = this->find_node(bucket_index, hash, k); // reserve has basic exception safety if the hash function // throws, strong otherwise. if(this->reserve_for_insert(this->size_ + 1)) { bucket_index = hash % this->bucket_count_; } return add_node(a, bucket_index, hash, position); }
inline node_ptr add_node( node_constructor& a, std::size_t bucket_index, std::size_t hash, node_ptr pos) { node_ptr n = a.release(); node::set_hash(n, hash); if(BOOST_UNORDERED_BORLAND_BOOL(pos)) { node::add_after_node(n, pos); if (n->next_) { std::size_t next_bucket = node::get_hash(n->next_) % this->bucket_count_; if (next_bucket != bucket_index) { this->buckets_[next_bucket].next_ = n; } } } else { bucket_ptr b = this->get_bucket(bucket_index); if (!b->next_) { bucket_ptr start_node = this->get_bucket(this->bucket_count_); if (BOOST_UNORDERED_BORLAND_BOOL(start_node->next_)) { this->buckets_[ node::get_hash(start_node->next_) % this->bucket_count_].next_ = n; } b->next_ = start_node; n->next_ = start_node->next_; start_node->next_ = n; } else { n->next_ = b->next_->next_; b->next_->next_ = n; } } ++this->size_; return n; }