mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Refactor internal implementation to use "fast closed-addressing" aka fca
This commit is contained in:
1000
include/boost/unordered/detail/fca.hpp
Normal file
1000
include/boost/unordered/detail/fca.hpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2005-2016 Daniel James
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -25,25 +26,18 @@ namespace boost {
|
||||
typedef boost::unordered::detail::allocator_traits<value_allocator>
|
||||
value_allocator_traits;
|
||||
|
||||
typedef boost::unordered::detail::pick_node<A, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::table<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<value_type> extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
typedef typename boost::allocator_void_pointer<value_allocator>::type
|
||||
void_pointer;
|
||||
|
||||
typedef boost::unordered::iterator_detail::iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::l_iterator<node> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node>
|
||||
cl_iterator;
|
||||
typedef boost::unordered::node_handle_map<
|
||||
node<value_type, void_pointer>, K, M, A>
|
||||
node_type;
|
||||
|
||||
typedef boost::unordered::node_handle_map<node, K, M, A> node_type;
|
||||
typedef boost::unordered::insert_return_type_map<node, K, M, A>
|
||||
insert_return_type;
|
||||
typedef typename table::iterator iterator;
|
||||
typedef boost::unordered::insert_return_type_map<iterator, node_type> insert_return_type;
|
||||
};
|
||||
|
||||
template <typename K, typename M, typename H, typename P, typename A>
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2005-2016 Daniel James
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -24,24 +25,18 @@ namespace boost {
|
||||
typedef boost::unordered::detail::allocator_traits<value_allocator>
|
||||
value_allocator_traits;
|
||||
|
||||
typedef boost::unordered::detail::pick_node<A, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::table<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<T>::type policy;
|
||||
typedef typename boost::allocator_void_pointer<value_allocator>::type
|
||||
void_pointer;
|
||||
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node>
|
||||
cl_iterator;
|
||||
typedef boost::unordered::node_handle_set<
|
||||
node<value_type, void_pointer>, T, A>
|
||||
node_type;
|
||||
|
||||
typedef boost::unordered::node_handle_set<node, T, A> node_type;
|
||||
typedef boost::unordered::insert_return_type_set<node, T, A>
|
||||
typedef typename table::c_iterator iterator;
|
||||
typedef boost::unordered::insert_return_type_set<iterator, node_type>
|
||||
insert_return_type;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -57,8 +58,6 @@ namespace boost {
|
||||
typedef boost::unordered::detail::map<A, K, T, H, P> types;
|
||||
typedef typename types::value_allocator_traits value_allocator_traits;
|
||||
typedef typename types::table table;
|
||||
typedef typename table::node_pointer node_pointer;
|
||||
typedef typename table::link_pointer link_pointer;
|
||||
|
||||
public:
|
||||
typedef typename value_allocator_traits::pointer pointer;
|
||||
@ -97,7 +96,7 @@ namespace boost {
|
||||
|
||||
unordered_map(unordered_map const&);
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
unordered_map(BOOST_RV_REF(unordered_map) other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
@ -188,9 +187,9 @@ namespace boost {
|
||||
return table_.node_alloc();
|
||||
}
|
||||
|
||||
// iterators
|
||||
// // iterators
|
||||
|
||||
iterator begin() BOOST_NOEXCEPT { return iterator(table_.begin()); }
|
||||
iterator begin() BOOST_NOEXCEPT { return table_.begin(); }
|
||||
|
||||
const_iterator begin() const BOOST_NOEXCEPT
|
||||
{
|
||||
@ -445,7 +444,7 @@ namespace boost {
|
||||
insert_return_type insert(BOOST_RV_REF(node_type) np)
|
||||
{
|
||||
insert_return_type result;
|
||||
table_.move_insert_node_type_unique(np, result);
|
||||
table_.move_insert_node_type_unique((node_type&)np, result);
|
||||
return boost::move(result);
|
||||
}
|
||||
|
||||
@ -728,8 +727,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
erase(BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
return table_.erase_key_unique_impl(
|
||||
this->key_eq(), boost::forward<Key>(k));
|
||||
return table_.erase_key_unique_impl(boost::forward<Key>(k));
|
||||
}
|
||||
|
||||
BOOST_UNORDERED_DEPRECATED("Use erase instead")
|
||||
@ -774,9 +772,7 @@ namespace boost {
|
||||
iterator>::type
|
||||
find(const Key& key)
|
||||
{
|
||||
return iterator(table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq()));
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -784,9 +780,7 @@ namespace boost {
|
||||
const_iterator>::type
|
||||
find(const Key& key) const
|
||||
{
|
||||
return const_iterator(table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq()));
|
||||
return const_iterator(table_.find(key));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
@ -801,9 +795,7 @@ namespace boost {
|
||||
|
||||
bool contains(const key_type& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -811,9 +803,7 @@ namespace boost {
|
||||
bool>::type
|
||||
contains(const Key& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
size_type count(const key_type&) const;
|
||||
@ -823,14 +813,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
count(const Key& k) const
|
||||
{
|
||||
std::size_t const key_hash =
|
||||
table::policy::apply_hash(this->hash_function(), k);
|
||||
|
||||
P const& eq = this->key_eq();
|
||||
|
||||
node_pointer p = table_.find_node_impl(key_hash, k, eq);
|
||||
|
||||
return (p ? 1 : 0);
|
||||
return (table_.find(k) != this->end() ? 1 : 0);
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type&);
|
||||
@ -842,12 +825,13 @@ namespace boost {
|
||||
std::pair<iterator, iterator> >::type
|
||||
equal_range(const Key& key)
|
||||
{
|
||||
node_pointer p = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq());
|
||||
iterator first = table_.find(key);
|
||||
iterator last = first;
|
||||
if (last != this->end()) {
|
||||
++last;
|
||||
}
|
||||
|
||||
return std::make_pair(
|
||||
iterator(p), iterator(p ? table::next_node(p) : p));
|
||||
return std::make_pair(first, last);
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -855,12 +839,13 @@ namespace boost {
|
||||
std::pair<const_iterator, const_iterator> >::type
|
||||
equal_range(const Key& key) const
|
||||
{
|
||||
node_pointer p = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq());
|
||||
iterator first = table_.find(key);
|
||||
iterator last = first;
|
||||
if (last != this->end()) {
|
||||
++last;
|
||||
}
|
||||
|
||||
return std::make_pair(
|
||||
const_iterator(p), const_iterator(p ? table::next_node(p) : p));
|
||||
return std::make_pair(first, last);
|
||||
}
|
||||
|
||||
mapped_type& operator[](const key_type&);
|
||||
@ -872,7 +857,7 @@ namespace boost {
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
return table_.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
@ -889,16 +874,15 @@ namespace boost {
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return table_.begin(n);
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type) { return local_iterator(); }
|
||||
|
||||
const_local_iterator end(size_type) const
|
||||
{
|
||||
return const_local_iterator();
|
||||
@ -906,7 +890,7 @@ namespace boost {
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type) const
|
||||
@ -1026,8 +1010,6 @@ namespace boost {
|
||||
typedef boost::unordered::detail::map<A, K, T, H, P> types;
|
||||
typedef typename types::value_allocator_traits value_allocator_traits;
|
||||
typedef typename types::table table;
|
||||
typedef typename table::node_pointer node_pointer;
|
||||
typedef typename table::link_pointer link_pointer;
|
||||
|
||||
public:
|
||||
typedef typename value_allocator_traits::pointer pointer;
|
||||
@ -1394,7 +1376,7 @@ namespace boost {
|
||||
|
||||
node_type extract(const key_type& k)
|
||||
{
|
||||
return node_type(table_.extract_by_key(k), table_.node_alloc());
|
||||
return node_type(table_.extract_by_key_impl(k), table_.node_alloc());
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -1437,8 +1419,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
erase(BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
return table_.erase_key_equiv_impl(
|
||||
this->key_eq(), boost::forward<Key>(k));
|
||||
return table_.erase_key_equiv_impl(boost::forward<Key>(k));
|
||||
}
|
||||
|
||||
BOOST_UNORDERED_DEPRECATED("Use erase instead")
|
||||
@ -1483,9 +1464,7 @@ namespace boost {
|
||||
iterator>::type
|
||||
find(const Key& key)
|
||||
{
|
||||
return iterator(table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq()));
|
||||
return table_.find(key);
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -1493,9 +1472,7 @@ namespace boost {
|
||||
const_iterator>::type
|
||||
find(const Key& key) const
|
||||
{
|
||||
return const_iterator(table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq()));
|
||||
return const_iterator(table_.find(key));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
@ -1510,9 +1487,7 @@ namespace boost {
|
||||
|
||||
bool contains(key_type const& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -1520,9 +1495,7 @@ namespace boost {
|
||||
bool>::type
|
||||
contains(const Key& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
size_type count(const key_type&) const;
|
||||
@ -1532,11 +1505,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
count(const Key& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
|
||||
return n ? table_.group_count(n) : 0;
|
||||
return table_.group_count(k);
|
||||
}
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type&);
|
||||
@ -1548,12 +1517,8 @@ namespace boost {
|
||||
std::pair<iterator, iterator> >::type
|
||||
equal_range(const Key& key)
|
||||
{
|
||||
node_pointer p = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq());
|
||||
|
||||
return std::make_pair(
|
||||
iterator(p), iterator(p ? table_.next_group(p) : p));
|
||||
iterator p = table_.find(key);
|
||||
return std::make_pair(p, table_.next_group(key, p));
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -1561,19 +1526,16 @@ namespace boost {
|
||||
std::pair<const_iterator, const_iterator> >::type
|
||||
equal_range(const Key& key) const
|
||||
{
|
||||
node_pointer p = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), key), key,
|
||||
this->key_eq());
|
||||
|
||||
iterator p = table_.find(key);
|
||||
return std::make_pair(
|
||||
const_iterator(p), const_iterator(p ? table_.next_group(p) : p));
|
||||
const_iterator(p), const_iterator(table_.next_group(key, p)));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
return table_.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
@ -1590,12 +1552,12 @@ namespace boost {
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type) { return local_iterator(); }
|
||||
@ -1607,7 +1569,7 @@ namespace boost {
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type) const
|
||||
@ -1730,7 +1692,7 @@ namespace boost {
|
||||
unordered_map::value_allocator_traits::
|
||||
select_on_container_copy_construction(other.get_allocator()))
|
||||
{
|
||||
if (other.table_.size_) {
|
||||
if (other.size()) {
|
||||
table_.copy_buckets(
|
||||
other.table_, boost::unordered::detail::true_type());
|
||||
}
|
||||
@ -1894,29 +1856,25 @@ namespace boost {
|
||||
typename unordered_map<K, T, H, P, A>::iterator
|
||||
unordered_map<K, T, H, P, A>::erase(iterator position)
|
||||
{
|
||||
node_pointer node = table::get_node(position);
|
||||
BOOST_ASSERT(node);
|
||||
node_pointer next = table::next_node(node);
|
||||
table_.erase_nodes_unique(node, next);
|
||||
return iterator(next);
|
||||
const_iterator last = position;
|
||||
++last;
|
||||
return table_.erase_nodes_range(position, last);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
typename unordered_map<K, T, H, P, A>::iterator
|
||||
unordered_map<K, T, H, P, A>::erase(const_iterator position)
|
||||
{
|
||||
node_pointer node = table::get_node(position);
|
||||
BOOST_ASSERT(node);
|
||||
node_pointer next = table::next_node(node);
|
||||
table_.erase_nodes_unique(node, next);
|
||||
return iterator(next);
|
||||
const_iterator last = position;
|
||||
++last;
|
||||
return table_.erase_nodes_range(position, last);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
typename unordered_map<K, T, H, P, A>::size_type
|
||||
unordered_map<K, T, H, P, A>::erase(const key_type& k)
|
||||
{
|
||||
return table_.erase_key_unique_impl(this->key_eq(), k);
|
||||
return table_.erase_key_unique_impl(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -1924,11 +1882,7 @@ namespace boost {
|
||||
unordered_map<K, T, H, P, A>::erase(
|
||||
const_iterator first, const_iterator last)
|
||||
{
|
||||
node_pointer last_node = table::get_node(last);
|
||||
if (first == last)
|
||||
return iterator(last_node);
|
||||
table_.erase_nodes_unique(table::get_node(first), last_node);
|
||||
return iterator(last_node);
|
||||
return table_.erase_nodes_range(first, last);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -1998,14 +1952,14 @@ namespace boost {
|
||||
typename unordered_map<K, T, H, P, A>::iterator
|
||||
unordered_map<K, T, H, P, A>::find(const key_type& k)
|
||||
{
|
||||
return iterator(table_.find_node(k));
|
||||
return iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
typename unordered_map<K, T, H, P, A>::const_iterator
|
||||
unordered_map<K, T, H, P, A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2015,8 +1969,7 @@ namespace boost {
|
||||
unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
|
||||
CompatibleHash const& hash, CompatiblePredicate const& eq)
|
||||
{
|
||||
return iterator(
|
||||
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
|
||||
return table_.transparent_find(k, hash, eq);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2026,8 +1979,7 @@ namespace boost {
|
||||
unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
|
||||
CompatibleHash const& hash, CompatiblePredicate const& eq) const
|
||||
{
|
||||
return const_iterator(
|
||||
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
|
||||
return table_.transparent_find(k, hash, eq);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2042,8 +1994,12 @@ namespace boost {
|
||||
typename unordered_map<K, T, H, P, A>::iterator>
|
||||
unordered_map<K, T, H, P, A>::equal_range(const key_type& k)
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return std::make_pair(iterator(n), iterator(n ? table::next_node(n) : n));
|
||||
iterator first = table_.find(k);
|
||||
iterator second = first;
|
||||
if (second != this->end()) {
|
||||
++second;
|
||||
}
|
||||
return std::make_pair(first, second);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2051,9 +2007,12 @@ namespace boost {
|
||||
typename unordered_map<K, T, H, P, A>::const_iterator>
|
||||
unordered_map<K, T, H, P, A>::equal_range(const key_type& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return std::make_pair(
|
||||
const_iterator(n), const_iterator(n ? table::next_node(n) : n));
|
||||
iterator first = table_.find(k);
|
||||
iterator second = first;
|
||||
if (second != this->end()) {
|
||||
++second;
|
||||
}
|
||||
return std::make_pair(const_iterator(first), const_iterator(second));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2074,10 +2033,12 @@ namespace boost {
|
||||
typename unordered_map<K, T, H, P, A>::mapped_type&
|
||||
unordered_map<K, T, H, P, A>::at(const key_type& k)
|
||||
{
|
||||
typedef typename table::node_pointer node_pointer;
|
||||
|
||||
if (table_.size_) {
|
||||
node_pointer n = table_.find_node(k);
|
||||
if (n)
|
||||
return n->value().second;
|
||||
node_pointer p = table_.find_node(k);
|
||||
if (p)
|
||||
return p->value().second;
|
||||
}
|
||||
|
||||
boost::throw_exception(
|
||||
@ -2088,10 +2049,12 @@ namespace boost {
|
||||
typename unordered_map<K, T, H, P, A>::mapped_type const&
|
||||
unordered_map<K, T, H, P, A>::at(const key_type& k) const
|
||||
{
|
||||
typedef typename table::node_pointer node_pointer;
|
||||
|
||||
if (table_.size_) {
|
||||
node_pointer n = table_.find_node(k);
|
||||
if (n)
|
||||
return n->value().second;
|
||||
node_pointer p = table_.find_node(k);
|
||||
if (p)
|
||||
return p->value().second;
|
||||
}
|
||||
|
||||
boost::throw_exception(
|
||||
@ -2110,9 +2073,9 @@ namespace boost {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(table_.bucket_count_ != 0);
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count_);
|
||||
static_cast<float>(table_.bucket_count());
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2130,8 +2093,7 @@ namespace boost {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void unordered_map<K, T, H, P, A>::reserve(size_type n)
|
||||
{
|
||||
table_.rehash(static_cast<std::size_t>(
|
||||
std::ceil(static_cast<double>(n) / table_.mlf_)));
|
||||
table_.reserve(n);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2377,22 +2339,20 @@ namespace boost {
|
||||
typename unordered_multimap<K, T, H, P, A>::iterator
|
||||
unordered_multimap<K, T, H, P, A>::erase(iterator position)
|
||||
{
|
||||
node_pointer node = table::get_node(position);
|
||||
BOOST_ASSERT(node);
|
||||
node_pointer next = table::next_node(node);
|
||||
table_.erase_nodes_equiv(node, next);
|
||||
return iterator(next);
|
||||
BOOST_ASSERT(position != this->end());
|
||||
iterator next = position;
|
||||
++next;
|
||||
return table_.erase_nodes_range(position, next);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
typename unordered_multimap<K, T, H, P, A>::iterator
|
||||
unordered_multimap<K, T, H, P, A>::erase(const_iterator position)
|
||||
{
|
||||
node_pointer node = table::get_node(position);
|
||||
BOOST_ASSERT(node);
|
||||
node_pointer next = table::next_node(node);
|
||||
table_.erase_nodes_equiv(node, next);
|
||||
return iterator(next);
|
||||
BOOST_ASSERT(position != this->end());
|
||||
const_iterator next = position;
|
||||
++next;
|
||||
return table_.erase_nodes_range(position, next);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2407,11 +2367,7 @@ namespace boost {
|
||||
unordered_multimap<K, T, H, P, A>::erase(
|
||||
const_iterator first, const_iterator last)
|
||||
{
|
||||
node_pointer last_node = table::get_node(last);
|
||||
if (first == last)
|
||||
return iterator(last_node);
|
||||
table_.erase_nodes_equiv(table::get_node(first), last_node);
|
||||
return iterator(last_node);
|
||||
return table_.erase_nodes_range(first, last);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2489,14 +2445,14 @@ namespace boost {
|
||||
typename unordered_multimap<K, T, H, P, A>::iterator
|
||||
unordered_multimap<K, T, H, P, A>::find(const key_type& k)
|
||||
{
|
||||
return iterator(table_.find_node(k));
|
||||
return iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
typename unordered_multimap<K, T, H, P, A>::const_iterator
|
||||
unordered_multimap<K, T, H, P, A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2506,8 +2462,7 @@ namespace boost {
|
||||
unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
|
||||
CompatibleHash const& hash, CompatiblePredicate const& eq)
|
||||
{
|
||||
return iterator(
|
||||
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
|
||||
return table_.transparent_find(k, hash, eq);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2525,8 +2480,7 @@ namespace boost {
|
||||
typename unordered_multimap<K, T, H, P, A>::size_type
|
||||
unordered_multimap<K, T, H, P, A>::count(const key_type& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return n ? table_.group_count(n) : 0;
|
||||
return table_.group_count(k);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2534,9 +2488,8 @@ namespace boost {
|
||||
typename unordered_multimap<K, T, H, P, A>::iterator>
|
||||
unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k)
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return std::make_pair(
|
||||
iterator(n), iterator(n ? table_.next_group(n) : n));
|
||||
iterator n = table_.find(k);
|
||||
return std::make_pair(n, (n == end() ? n : table_.next_group(k, n)));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2544,9 +2497,9 @@ namespace boost {
|
||||
typename unordered_multimap<K, T, H, P, A>::const_iterator>
|
||||
unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return std::make_pair(
|
||||
const_iterator(n), const_iterator(n ? table_.next_group(n) : n));
|
||||
iterator n = table_.find(k);
|
||||
return std::make_pair(const_iterator(n),
|
||||
const_iterator(n == end() ? n : table_.next_group(k, n)));
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2561,9 +2514,9 @@ namespace boost {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(table_.bucket_count_ != 0);
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count_);
|
||||
static_cast<float>(table_.bucket_count());
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2582,8 +2535,7 @@ namespace boost {
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void unordered_multimap<K, T, H, P, A>::reserve(size_type n)
|
||||
{
|
||||
table_.rehash(static_cast<std::size_t>(
|
||||
std::ceil(static_cast<double>(n) / table_.mlf_)));
|
||||
table_.reserve(n);
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
@ -2643,16 +2595,14 @@ namespace boost {
|
||||
template <class K2, class T2, class H2, class P2, class A2>
|
||||
friend class boost::unordered::unordered_multimap;
|
||||
|
||||
typedef typename boost::unordered::detail::rebind_wrap<A,
|
||||
std::pair<K const, T> >::type value_allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<value_allocator>
|
||||
value_allocator_traits;
|
||||
typedef typename boost::allocator_rebind<A, std::pair<K const, T> >::type
|
||||
value_allocator;
|
||||
|
||||
typedef N node;
|
||||
typedef typename boost::unordered::detail::rebind_wrap<A, node>::type
|
||||
node_allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<node_allocator>
|
||||
node_allocator_traits;
|
||||
typedef typename node_allocator_traits::pointer node_pointer;
|
||||
typedef typename boost::allocator_rebind<A, node>::type node_allocator;
|
||||
|
||||
typedef
|
||||
typename boost::allocator_pointer<node_allocator>::type node_pointer;
|
||||
|
||||
public:
|
||||
typedef K key_type;
|
||||
@ -2681,8 +2631,8 @@ namespace boost {
|
||||
}
|
||||
|
||||
node_handle_map(BOOST_RV_REF(node_handle_map) n) BOOST_NOEXCEPT
|
||||
: ptr_(n.ptr_),
|
||||
alloc_(boost::move(n.alloc_))
|
||||
: ptr_(n.ptr_),
|
||||
alloc_(boost::move(n.alloc_))
|
||||
{
|
||||
n.ptr_ = node_pointer();
|
||||
}
|
||||
@ -2690,8 +2640,8 @@ namespace boost {
|
||||
node_handle_map& operator=(BOOST_RV_REF(node_handle_map) n)
|
||||
{
|
||||
BOOST_ASSERT(!alloc_.has_value() ||
|
||||
value_allocator_traits::
|
||||
propagate_on_container_move_assignment::value ||
|
||||
boost::allocator_propagate_on_container_move_assignment<
|
||||
value_allocator>::type::value ||
|
||||
(n.alloc_.has_value() && alloc_ == n.alloc_));
|
||||
|
||||
if (ptr_) {
|
||||
@ -2702,8 +2652,8 @@ namespace boost {
|
||||
}
|
||||
|
||||
if (!alloc_.has_value() ||
|
||||
value_allocator_traits::propagate_on_container_move_assignment::
|
||||
value) {
|
||||
boost::allocator_propagate_on_container_move_assignment<
|
||||
value_allocator>::type::value) {
|
||||
alloc_ = boost::move(n.alloc_);
|
||||
}
|
||||
ptr_ = n.ptr_;
|
||||
@ -2731,14 +2681,17 @@ namespace boost {
|
||||
}
|
||||
|
||||
void swap(node_handle_map& n) BOOST_NOEXCEPT_IF(
|
||||
value_allocator_traits::propagate_on_container_swap::value ||
|
||||
value_allocator_traits::is_always_equal::value)
|
||||
boost::allocator_propagate_on_container_swap<
|
||||
value_allocator>::type::value ||
|
||||
boost::allocator_is_always_equal<value_allocator>::type::value)
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
!alloc_.has_value() || !n.alloc_.has_value() ||
|
||||
value_allocator_traits::propagate_on_container_swap::value ||
|
||||
alloc_ == n.alloc_);
|
||||
if (value_allocator_traits::propagate_on_container_swap::value ||
|
||||
|
||||
BOOST_ASSERT(!alloc_.has_value() || !n.alloc_.has_value() ||
|
||||
boost::allocator_propagate_on_container_swap<
|
||||
value_allocator>::type::value ||
|
||||
alloc_ == n.alloc_);
|
||||
if (boost::allocator_propagate_on_container_swap<
|
||||
value_allocator>::type::value ||
|
||||
!alloc_.has_value() || !n.alloc_.has_value()) {
|
||||
boost::swap(alloc_, n.alloc_);
|
||||
}
|
||||
@ -2753,25 +2706,25 @@ namespace boost {
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
template <class N, class K, class T, class A> struct insert_return_type_map
|
||||
template <class Iter, class NodeType> struct insert_return_type_map
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_map)
|
||||
|
||||
typedef typename boost::unordered::detail::rebind_wrap<A,
|
||||
std::pair<K const, T> >::type value_allocator;
|
||||
typedef N node_;
|
||||
// typedef typename boost::allocator_rebind<A,
|
||||
// std::pair<K const, T> >::type value_allocator;
|
||||
// typedef N node_;
|
||||
|
||||
public:
|
||||
Iter position;
|
||||
bool inserted;
|
||||
boost::unordered::iterator_detail::iterator<node_> position;
|
||||
boost::unordered::node_handle_map<N, K, T, A> node;
|
||||
NodeType node;
|
||||
|
||||
insert_return_type_map() : inserted(false), position(), node() {}
|
||||
insert_return_type_map() : position(), inserted(false), node() {}
|
||||
|
||||
insert_return_type_map(BOOST_RV_REF(insert_return_type_map)
|
||||
x) BOOST_NOEXCEPT : inserted(x.inserted),
|
||||
position(x.position),
|
||||
x) BOOST_NOEXCEPT : position(x.position),
|
||||
inserted(x.inserted),
|
||||
node(boost::move(x.node))
|
||||
{
|
||||
}
|
||||
@ -2785,9 +2738,9 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
|
||||
template <class N, class K, class T, class A>
|
||||
void swap(insert_return_type_map<N, K, T, A>& x,
|
||||
insert_return_type_map<N, K, T, A>& y)
|
||||
template <class Iter, class NodeType>
|
||||
void swap(insert_return_type_map<Iter, NodeType>& x,
|
||||
insert_return_type_map<Iter, NodeType>& y)
|
||||
{
|
||||
boost::swap(x.node, y.node);
|
||||
boost::swap(x.inserted, y.inserted);
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2008-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -59,7 +60,7 @@ namespace boost {
|
||||
unordered_multimap<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
template <class N, class K, class T, class A> class node_handle_map;
|
||||
template <class N, class K, class T, class A> struct insert_return_type_map;
|
||||
template <class Iter, class NodeType> struct insert_return_type_map;
|
||||
}
|
||||
|
||||
using boost::unordered::unordered_map;
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -55,8 +56,6 @@ namespace boost {
|
||||
typedef boost::unordered::detail::set<A, T, H, P> types;
|
||||
typedef typename types::value_allocator_traits value_allocator_traits;
|
||||
typedef typename types::table table;
|
||||
typedef typename table::node_pointer node_pointer;
|
||||
typedef typename table::link_pointer link_pointer;
|
||||
|
||||
public:
|
||||
typedef typename value_allocator_traits::pointer pointer;
|
||||
@ -68,9 +67,9 @@ namespace boost {
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef typename table::iterator iterator;
|
||||
typedef typename table::c_iterator iterator;
|
||||
typedef typename table::c_iterator const_iterator;
|
||||
typedef typename table::l_iterator local_iterator;
|
||||
typedef typename table::cl_iterator local_iterator;
|
||||
typedef typename table::cl_iterator const_local_iterator;
|
||||
typedef typename types::node_type node_type;
|
||||
typedef typename types::insert_return_type insert_return_type;
|
||||
@ -411,7 +410,7 @@ namespace boost {
|
||||
|
||||
node_type extract(const key_type& k)
|
||||
{
|
||||
return node_type(table_.extract_by_key(k), table_.node_alloc());
|
||||
return node_type(table_.extract_by_key_impl(k), table_.node_alloc());
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -455,8 +454,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
erase(BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
return table_.erase_key_unique_impl(
|
||||
this->key_eq(), boost::forward<Key>(k));
|
||||
return table_.erase_key_unique_impl(boost::forward<Key>(k));
|
||||
}
|
||||
|
||||
BOOST_UNORDERED_DEPRECATED("Use erase instead")
|
||||
@ -500,9 +498,7 @@ namespace boost {
|
||||
const_iterator>::type
|
||||
find(const Key& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq()));
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
@ -512,9 +508,7 @@ namespace boost {
|
||||
|
||||
bool contains(key_type const& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -522,9 +516,7 @@ namespace boost {
|
||||
bool>::type
|
||||
contains(const Key& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
size_type count(const key_type&) const;
|
||||
@ -534,11 +526,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
count(const Key& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
|
||||
return n ? 1 : 0;
|
||||
return table_.find(k) != this->end() ? 1 : 0;
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
@ -549,19 +537,20 @@ namespace boost {
|
||||
std::pair<const_iterator, const_iterator> >::type
|
||||
equal_range(Key const& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
iterator n = table_.find(k);
|
||||
iterator m = n;
|
||||
if (m != this->end()) {
|
||||
++m;
|
||||
}
|
||||
|
||||
return std::make_pair(
|
||||
const_iterator(n), const_iterator(n ? table::next_node(n) : n));
|
||||
return std::make_pair(const_iterator(n), const_iterator(m));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
return table_.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
@ -578,12 +567,12 @@ namespace boost {
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type) { return local_iterator(); }
|
||||
@ -595,7 +584,7 @@ namespace boost {
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type) const
|
||||
@ -684,8 +673,6 @@ namespace boost {
|
||||
typedef boost::unordered::detail::set<A, T, H, P> types;
|
||||
typedef typename types::value_allocator_traits value_allocator_traits;
|
||||
typedef typename types::table table;
|
||||
typedef typename table::node_pointer node_pointer;
|
||||
typedef typename table::link_pointer link_pointer;
|
||||
|
||||
public:
|
||||
typedef typename value_allocator_traits::pointer pointer;
|
||||
@ -697,9 +684,9 @@ namespace boost {
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef typename table::iterator iterator;
|
||||
typedef typename table::c_iterator iterator;
|
||||
typedef typename table::c_iterator const_iterator;
|
||||
typedef typename table::l_iterator local_iterator;
|
||||
typedef typename table::cl_iterator local_iterator;
|
||||
typedef typename table::cl_iterator const_local_iterator;
|
||||
typedef typename types::node_type node_type;
|
||||
|
||||
@ -1035,7 +1022,7 @@ namespace boost {
|
||||
|
||||
node_type extract(const key_type& k)
|
||||
{
|
||||
return node_type(table_.extract_by_key(k), table_.node_alloc());
|
||||
return node_type(table_.extract_by_key_impl(k), table_.node_alloc());
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -1076,7 +1063,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
erase(const Key& k)
|
||||
{
|
||||
return table_.erase_key_equiv_impl(this->key_eq(), k);
|
||||
return table_.erase_key_equiv_impl(k);
|
||||
}
|
||||
|
||||
iterator erase(const_iterator, const_iterator);
|
||||
@ -1121,9 +1108,7 @@ namespace boost {
|
||||
const_iterator>::type
|
||||
find(const Key& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq()));
|
||||
return table_.find(k);
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
@ -1133,9 +1118,7 @@ namespace boost {
|
||||
|
||||
bool contains(const key_type& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
template <class Key>
|
||||
@ -1143,9 +1126,7 @@ namespace boost {
|
||||
bool>::type
|
||||
contains(const Key& k) const
|
||||
{
|
||||
return 0 != table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
return table_.find(k) != this->end();
|
||||
}
|
||||
|
||||
size_type count(const key_type&) const;
|
||||
@ -1155,11 +1136,7 @@ namespace boost {
|
||||
size_type>::type
|
||||
count(const Key& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
|
||||
return n ? table_.group_count(n) : 0;
|
||||
return table_.group_count(k);
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(
|
||||
@ -1170,19 +1147,16 @@ namespace boost {
|
||||
std::pair<const_iterator, const_iterator> >::type
|
||||
equal_range(const Key& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node_impl(
|
||||
table::policy::apply_hash(this->hash_function(), k), k,
|
||||
this->key_eq());
|
||||
|
||||
return std::make_pair(
|
||||
const_iterator(n), const_iterator(n ? table_.next_group(n) : n));
|
||||
iterator first = table_.find(k);
|
||||
iterator last = table_.next_group(k, first);
|
||||
return std::make_pair(const_iterator(first), const_iterator(last));
|
||||
}
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
return table_.bucket_count();
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
@ -1199,12 +1173,12 @@ namespace boost {
|
||||
|
||||
local_iterator begin(size_type n)
|
||||
{
|
||||
return local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator begin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
local_iterator end(size_type) { return local_iterator(); }
|
||||
@ -1216,7 +1190,7 @@ namespace boost {
|
||||
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
return const_local_iterator(table_.begin(n), n, table_.bucket_count_);
|
||||
return const_local_iterator(table_.begin(n));
|
||||
}
|
||||
|
||||
const_local_iterator cend(size_type) const
|
||||
@ -1319,7 +1293,7 @@ namespace boost {
|
||||
unordered_set::value_allocator_traits::
|
||||
select_on_container_copy_construction(other.get_allocator()))
|
||||
{
|
||||
if (other.table_.size_) {
|
||||
if (other.size()) {
|
||||
table_.copy_buckets(
|
||||
other.table_, boost::unordered::detail::true_type());
|
||||
}
|
||||
@ -1483,29 +1457,23 @@ namespace boost {
|
||||
typename unordered_set<T, H, P, A>::iterator
|
||||
unordered_set<T, H, P, A>::erase(const_iterator position)
|
||||
{
|
||||
node_pointer node = table::get_node(position);
|
||||
BOOST_ASSERT(node);
|
||||
node_pointer next = table::next_node(node);
|
||||
table_.erase_nodes_unique(node, next);
|
||||
return iterator(next);
|
||||
const_iterator last = position;
|
||||
++last;
|
||||
return table_.erase_nodes_range(position, last);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
typename unordered_set<T, H, P, A>::size_type
|
||||
unordered_set<T, H, P, A>::erase(const key_type& k)
|
||||
{
|
||||
return table_.erase_key_unique_impl(this->key_eq(), k);
|
||||
return table_.erase_key_unique_impl(k);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
typename unordered_set<T, H, P, A>::iterator
|
||||
unordered_set<T, H, P, A>::erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
node_pointer last_node = table::get_node(last);
|
||||
if (first == last)
|
||||
return iterator(last_node);
|
||||
table_.erase_nodes_unique(table::get_node(first), last_node);
|
||||
return iterator(last_node);
|
||||
return table_.erase_nodes_range(first, last);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1575,7 +1543,7 @@ namespace boost {
|
||||
typename unordered_set<T, H, P, A>::const_iterator
|
||||
unordered_set<T, H, P, A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1585,8 +1553,7 @@ namespace boost {
|
||||
unordered_set<T, H, P, A>::find(CompatibleKey const& k,
|
||||
CompatibleHash const& hash, CompatiblePredicate const& eq) const
|
||||
{
|
||||
return const_iterator(
|
||||
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
|
||||
return table_.transparent_find(k, hash, eq);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1601,9 +1568,12 @@ namespace boost {
|
||||
typename unordered_set<T, H, P, A>::const_iterator>
|
||||
unordered_set<T, H, P, A>::equal_range(const key_type& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return std::make_pair(
|
||||
const_iterator(n), const_iterator(n ? table::next_node(n) : n));
|
||||
iterator first = table_.find(k);
|
||||
iterator second = first;
|
||||
if (second != this->end()) {
|
||||
++second;
|
||||
}
|
||||
return std::make_pair(first, second);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1618,9 +1588,9 @@ namespace boost {
|
||||
template <class T, class H, class P, class A>
|
||||
float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(table_.bucket_count_ != 0);
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count_);
|
||||
static_cast<float>(table_.bucket_count());
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1638,8 +1608,7 @@ namespace boost {
|
||||
template <class T, class H, class P, class A>
|
||||
void unordered_set<T, H, P, A>::reserve(size_type n)
|
||||
{
|
||||
table_.rehash(static_cast<std::size_t>(
|
||||
std::ceil(static_cast<double>(n) / table_.mlf_)));
|
||||
table_.reserve(n);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1883,11 +1852,11 @@ namespace boost {
|
||||
typename unordered_multiset<T, H, P, A>::iterator
|
||||
unordered_multiset<T, H, P, A>::erase(const_iterator position)
|
||||
{
|
||||
node_pointer node = table::get_node(position);
|
||||
BOOST_ASSERT(node);
|
||||
node_pointer next = table::next_node(node);
|
||||
table_.erase_nodes_equiv(node, next);
|
||||
return iterator(next);
|
||||
BOOST_ASSERT(position != this->end());
|
||||
iterator next = position;
|
||||
++next;
|
||||
table_.erase_nodes_range(position, next);
|
||||
return next;
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1902,11 +1871,7 @@ namespace boost {
|
||||
unordered_multiset<T, H, P, A>::erase(
|
||||
const_iterator first, const_iterator last)
|
||||
{
|
||||
node_pointer last_node = table::get_node(last);
|
||||
if (first == last)
|
||||
return iterator(last_node);
|
||||
table_.erase_nodes_equiv(table::get_node(first), last_node);
|
||||
return iterator(last_node);
|
||||
return table_.erase_nodes_range(first, last);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1984,7 +1949,7 @@ namespace boost {
|
||||
typename unordered_multiset<T, H, P, A>::const_iterator
|
||||
unordered_multiset<T, H, P, A>::find(const key_type& k) const
|
||||
{
|
||||
return const_iterator(table_.find_node(k));
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -1994,16 +1959,14 @@ namespace boost {
|
||||
unordered_multiset<T, H, P, A>::find(CompatibleKey const& k,
|
||||
CompatibleHash const& hash, CompatiblePredicate const& eq) const
|
||||
{
|
||||
return const_iterator(
|
||||
table_.find_node_impl(table::policy::apply_hash(hash, k), k, eq));
|
||||
return table_.transparent_find(k, hash, eq);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
typename unordered_multiset<T, H, P, A>::size_type
|
||||
unordered_multiset<T, H, P, A>::count(const key_type& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return n ? table_.group_count(n) : 0;
|
||||
return table_.group_count(k);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -2011,9 +1974,9 @@ namespace boost {
|
||||
typename unordered_multiset<T, H, P, A>::const_iterator>
|
||||
unordered_multiset<T, H, P, A>::equal_range(const key_type& k) const
|
||||
{
|
||||
node_pointer n = table_.find_node(k);
|
||||
return std::make_pair(
|
||||
const_iterator(n), const_iterator(n ? table_.next_group(n) : n));
|
||||
iterator n = table_.find(k);
|
||||
return std::make_pair(const_iterator(n),
|
||||
const_iterator(n == end() ? n : table_.next_group(k, n)));
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -2028,9 +1991,9 @@ namespace boost {
|
||||
template <class T, class H, class P, class A>
|
||||
float unordered_multiset<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(table_.bucket_count_ != 0);
|
||||
BOOST_ASSERT(table_.bucket_count() != 0);
|
||||
return static_cast<float>(table_.size_) /
|
||||
static_cast<float>(table_.bucket_count_);
|
||||
static_cast<float>(table_.bucket_count());
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -2048,8 +2011,7 @@ namespace boost {
|
||||
template <class T, class H, class P, class A>
|
||||
void unordered_multiset<T, H, P, A>::reserve(size_type n)
|
||||
{
|
||||
table_.rehash(static_cast<std::size_t>(
|
||||
std::ceil(static_cast<double>(n) / table_.mlf_)));
|
||||
table_.reserve(n);
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
@ -2217,25 +2179,25 @@ namespace boost {
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
template <typename N, typename T, typename A> struct insert_return_type_set
|
||||
template <class Iter, class NodeType> struct insert_return_type_set
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_set)
|
||||
|
||||
typedef typename boost::unordered::detail::rebind_wrap<A, T>::type
|
||||
value_allocator;
|
||||
typedef N node_;
|
||||
// typedef typename boost::unordered::detail::rebind_wrap<A, T>::type
|
||||
// value_allocator;
|
||||
// typedef N node_;
|
||||
|
||||
public:
|
||||
Iter position;
|
||||
bool inserted;
|
||||
boost::unordered::iterator_detail::c_iterator<node_> position;
|
||||
boost::unordered::node_handle_set<N, T, A> node;
|
||||
NodeType node;
|
||||
|
||||
insert_return_type_set() : inserted(false), position(), node() {}
|
||||
insert_return_type_set() : position(), inserted(false), node() {}
|
||||
|
||||
insert_return_type_set(BOOST_RV_REF(insert_return_type_set)
|
||||
x) BOOST_NOEXCEPT : inserted(x.inserted),
|
||||
position(x.position),
|
||||
x) BOOST_NOEXCEPT : position(x.position),
|
||||
inserted(x.inserted),
|
||||
node(boost::move(x.node))
|
||||
{
|
||||
}
|
||||
@ -2249,9 +2211,9 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename N, typename T, typename A>
|
||||
template <class Iter, class NodeType>
|
||||
void swap(
|
||||
insert_return_type_set<N, T, A>& x, insert_return_type_set<N, T, A>& y)
|
||||
insert_return_type_set<Iter, NodeType>& x, insert_return_type_set<Iter, NodeType>& y)
|
||||
{
|
||||
boost::swap(x.node, y.node);
|
||||
boost::swap(x.inserted, y.inserted);
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2008-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -57,7 +58,7 @@ namespace boost {
|
||||
unordered_multiset<K, H, P, A>& c, Predicate pred);
|
||||
|
||||
template <class N, class T, class A> class node_handle_set;
|
||||
template <class N, class T, class A> struct insert_return_type_set;
|
||||
template <class Iter, class NodeType> struct insert_return_type_set;
|
||||
}
|
||||
|
||||
using boost::unordered::unordered_set;
|
||||
|
@ -70,13 +70,13 @@ test-suite unordered
|
||||
[ run unordered/rehash_tests.cpp ]
|
||||
[ run unordered/equality_tests.cpp ]
|
||||
[ run unordered/swap_tests.cpp ]
|
||||
[ run unordered/detail_tests.cpp ]
|
||||
# [ run unordered/detail_tests.cpp ]
|
||||
[ run unordered/deduction_tests.cpp ]
|
||||
[ run unordered/scoped_allocator.cpp : : : <toolset>msvc-14.0:<build>no ]
|
||||
[ run unordered/transparent_tests.cpp ]
|
||||
[ run unordered/reserve_tests.cpp ]
|
||||
[ run unordered/contains_tests.cpp ]
|
||||
[ run unordered/mix_policy.cpp ]
|
||||
# [ run unordered/mix_policy.cpp ]
|
||||
[ run unordered/erase_if.cpp ]
|
||||
[ run unordered/scary_tests.cpp ]
|
||||
|
||||
|
Reference in New Issue
Block a user