aboutsummaryrefslogtreecommitdiff
path: root/system/include/libcxx/__hash_table
diff options
context:
space:
mode:
Diffstat (limited to 'system/include/libcxx/__hash_table')
-rw-r--r--system/include/libcxx/__hash_table181
1 files changed, 105 insertions, 76 deletions
diff --git a/system/include/libcxx/__hash_table b/system/include/libcxx/__hash_table
index f9578fa2..ba04b3e5 100644
--- a/system/include/libcxx/__hash_table
+++ b/system/include/libcxx/__hash_table
@@ -18,7 +18,11 @@
#include <algorithm>
#include <cmath>
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -54,10 +58,31 @@ struct __hash_node
value_type __value_;
};
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__is_power2(size_t __bc)
+{
+ return __bc > 2 && !(__bc & (__bc - 1));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+__constrain_hash(size_t __h, size_t __bc)
+{
+ return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+__next_pow2(size_t __n)
+{
+ return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
+}
+
template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
-template <class _ConstNodePtr> class __hash_const_iterator;
-template <class _HashIterator> class __hash_map_iterator;
-template <class _HashIterator> class __hash_map_const_iterator;
+template <class _ConstNodePtr> class _LIBCPP_VISIBLE __hash_const_iterator;
+template <class _HashIterator> class _LIBCPP_VISIBLE __hash_map_iterator;
+template <class _HashIterator> class _LIBCPP_VISIBLE __hash_map_const_iterator;
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
class _LIBCPP_VISIBLE unordered_map;
@@ -236,7 +261,7 @@ public:
__hash_local_iterator& operator++()
{
__node_ = __node_->__next_;
- if (__node_ != nullptr && __node_->__hash_ % __bucket_count_ != __bucket_)
+ if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
__node_ = nullptr;
return *this;
}
@@ -326,7 +351,7 @@ public:
__hash_const_local_iterator& operator++()
{
__node_ = __node_->__next_;
- if (__node_ != nullptr && __node_->__hash_ % __bucket_count_ != __bucket_)
+ if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
__node_ = nullptr;
return *this;
}
@@ -471,7 +496,6 @@ public:
public:
// Create __node
typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node;
- typedef typename __node::__first_node __first_node;
typedef typename __alloc_traits::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind_alloc<__node>
@@ -482,6 +506,7 @@ public:
typedef allocator_traits<__node_allocator> __node_traits;
typedef typename __node_traits::pointer __node_pointer;
typedef typename __node_traits::const_pointer __node_const_pointer;
+ typedef __hash_node_base<__node_pointer> __first_node;
private:
@@ -600,15 +625,15 @@ public:
pair<iterator, bool> __insert_unique(const value_type& __x);
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class _P>
- pair<iterator, bool> __insert_unique(_P&& __x);
+ template <class _Pp>
+ pair<iterator, bool> __insert_unique(_Pp&& __x);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class _P>
- iterator __insert_multi(_P&& __x);
- template <class _P>
- iterator __insert_multi(const_iterator __p, _P&& __x);
+ template <class _Pp>
+ iterator __insert_multi(_Pp&& __x);
+ template <class _Pp>
+ iterator __insert_multi(const_iterator __p, _Pp&& __x);
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
iterator __insert_multi(const value_type& __x);
iterator __insert_multi(const_iterator __p, const value_type& __x);
@@ -633,15 +658,15 @@ public:
template <class _Key>
_LIBCPP_INLINE_VISIBILITY
size_type bucket(const _Key& __k) const
- {return hash_function()(__k) % bucket_count();}
+ {return __constrain_hash(hash_function()(__k), bucket_count());}
template <class _Key>
iterator find(const _Key& __x);
template <class _Key>
const_iterator find(const _Key& __x) const;
- typedef __hash_node_destructor<__node_allocator> _D;
- typedef unique_ptr<__node, _D> __node_holder;
+ typedef __hash_node_destructor<__node_allocator> _Dp;
+ typedef unique_ptr<__node, _Dp> __node_holder;
iterator erase(const_iterator __p);
iterator erase(const_iterator __first, const_iterator __last);
@@ -719,7 +744,7 @@ private:
__node_traits::propagate_on_container_copy_assignment::value>());}
void __copy_assign_alloc(const __hash_table& __u, true_type);
_LIBCPP_INLINE_VISIBILITY
- void __copy_assign_alloc(const __hash_table& __u, false_type) {}
+ void __copy_assign_alloc(const __hash_table&, false_type) {}
void __move_assign(__hash_table& __u, false_type);
void __move_assign(__hash_table& __u, true_type)
@@ -748,37 +773,37 @@ private:
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
- template <class _A>
+ template <class _Ap>
_LIBCPP_INLINE_VISIBILITY
static
void
- __swap_alloc(_A& __x, _A& __y)
+ __swap_alloc(_Ap& __x, _Ap& __y)
_NOEXCEPT_(
- !allocator_traits<_A>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<_A>::value)
+ !allocator_traits<_Ap>::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<_Ap>::value)
{
__swap_alloc(__x, __y,
integral_constant<bool,
- allocator_traits<_A>::propagate_on_container_swap::value
+ allocator_traits<_Ap>::propagate_on_container_swap::value
>());
}
- template <class _A>
+ template <class _Ap>
_LIBCPP_INLINE_VISIBILITY
static
void
- __swap_alloc(_A& __x, _A& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<_A>::value)
+ __swap_alloc(_Ap& __x, _Ap& __y, true_type)
+ _NOEXCEPT_(__is_nothrow_swappable<_Ap>::value)
{
using _VSTD::swap;
swap(__x, __y);
}
- template <class _A>
+ template <class _Ap>
_LIBCPP_INLINE_VISIBILITY
static
void
- __swap_alloc(_A& __x, _A& __y, false_type) _NOEXCEPT {}
+ __swap_alloc(_Ap&, _Ap&, false_type) _NOEXCEPT {}
void __deallocate(__node_pointer __np) _NOEXCEPT;
__node_pointer __detach() _NOEXCEPT;
@@ -867,7 +892,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
{
if (size() > 0)
{
- __bucket_list_[__p1_.first().__next_->__hash_ % bucket_count()] =
+ __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
__u.__p1_.first().__next_ = nullptr;
__u.size() = 0;
@@ -891,7 +916,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
{
__p1_.first().__next_ = __u.__p1_.first().__next_;
__u.__p1_.first().__next_ = nullptr;
- __bucket_list_[__p1_.first().__next_->__hash_ % bucket_count()] =
+ __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
size() = __u.size();
__u.size() = 0;
@@ -988,7 +1013,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
__p1_.first().__next_ = __u.__p1_.first().__next_;
if (size() > 0)
{
- __bucket_list_[__p1_.first().__next_->__hash_ % bucket_count()] =
+ __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
__u.__p1_.first().__next_ = nullptr;
__u.size() = 0;
@@ -1186,12 +1211,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __
size_t __chash;
if (__bc != 0)
{
- __chash = __nd->__hash_ % __bc;
+ __chash = __constrain_hash(__nd->__hash_, __bc);
__ndptr = __bucket_list_[__chash];
if (__ndptr != nullptr)
{
for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
- __ndptr->__hash_ % __bc == __chash;
+ __constrain_hash(__ndptr->__hash_, __bc) == __chash;
__ndptr = __ndptr->__next_)
{
if (key_eq()(__ndptr->__value_, __nd->__value_))
@@ -1202,10 +1227,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __
{
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + 1,
+ rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
- __chash = __nd->__hash_ % __bc;
+ __chash = __constrain_hash(__nd->__hash_, __bc);
}
// insert_after __bucket_list_[__chash], or __first_node if bucket is null
__node_pointer __pn = __bucket_list_[__chash];
@@ -1217,7 +1242,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__nd->__next_ != nullptr)
- __bucket_list_[__nd->__next_->__hash_ % __bc] = __nd;
+ __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd;
}
else
{
@@ -1241,11 +1266,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + 1,
+ rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
- size_t __chash = __cp->__hash_ % __bc;
+ size_t __chash = __constrain_hash(__cp->__hash_, __bc);
__node_pointer __pn = __bucket_list_[__chash];
if (__pn == nullptr)
{
@@ -1255,12 +1280,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__cp->__next_ != nullptr)
- __bucket_list_[__cp->__next_->__hash_ % __bc] = __cp;
+ __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp;
}
else
{
for (bool __found = false; __pn->__next_ != nullptr &&
- __pn->__next_->__hash_ % __bc == __chash;
+ __constrain_hash(__pn->__next_->__hash_, __bc) == __chash;
__pn = __pn->__next_)
{
// __found key_eq() action
@@ -1281,7 +1306,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c
__pn->__next_ = __cp;
if (__cp->__next_ != nullptr)
{
- size_t __nhash = __cp->__next_->__hash_ % __bc;
+ size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc);
if (__nhash != __chash)
__bucket_list_[__nhash] = __cp;
}
@@ -1302,11 +1327,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
size_type __bc = bucket_count();
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + 1,
+ rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
}
- size_t __chash = __cp->__hash_ % __bc;
+ size_t __chash = __constrain_hash(__cp->__hash_, __bc);
__node_pointer __pp = __bucket_list_[__chash];
while (__pp->__next_ != __np)
__pp = __pp->__next_;
@@ -1329,12 +1354,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
size_t __chash;
if (__bc != 0)
{
- __chash = __hash % __bc;
+ __chash = __constrain_hash(__hash, __bc);
__nd = __bucket_list_[__chash];
if (__nd != nullptr)
{
for (__nd = __nd->__next_; __nd != nullptr &&
- __nd->__hash_ % __bc == __chash;
+ __constrain_hash(__nd->__hash_, __bc) == __chash;
__nd = __nd->__next_)
{
if (key_eq()(__nd->__value_, __x))
@@ -1346,10 +1371,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
__node_holder __h = __construct_node(__x, __hash);
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
- rehash(_VSTD::max<size_type>(2 * __bc + 1,
+ rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
size_type(ceil(float(size() + 1) / max_load_factor()))));
__bc = bucket_count();
- __chash = __hash % __bc;
+ __chash = __constrain_hash(__hash, __bc);
}
// insert_after __bucket_list_[__chash], or __first_node if bucket is null
__node_pointer __pn = __bucket_list_[__chash];
@@ -1361,7 +1386,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
// fix up __bucket_list_
__bucket_list_[__chash] = __pn;
if (__h->__next_ != nullptr)
- __bucket_list_[__h->__next_->__hash_ % __bc] = __h.get();
+ __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get();
}
else
{
@@ -1418,11 +1443,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-template <class _P>
+template <class _Pp>
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_P&& __x)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x)
{
- __node_holder __h = __construct_node(_VSTD::forward<_P>(__x));
+ __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
pair<iterator, bool> __r = __node_insert_unique(__h.get());
if (__r.second)
__h.release();
@@ -1434,23 +1459,23 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_P&& __x)
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-template <class _P>
+template <class _Pp>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_P&& __x)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x)
{
- __node_holder __h = __construct_node(_VSTD::forward<_P>(__x));
+ __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
iterator __r = __node_insert_multi(__h.get());
__h.release();
return __r;
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-template <class _P>
+template <class _Pp>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
- _P&& __x)
+ _Pp&& __x)
{
- __node_holder __h = __construct_node(_VSTD::forward<_P>(__x));
+ __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
iterator __r = __node_insert_multi(__p, __h.get());
__h.release();
return __r;
@@ -1485,16 +1510,20 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
{
- __n = __next_prime(_VSTD::max<size_type>(__n, size() > 0));
+ if (__n == 1)
+ __n = 2;
+ else if (__n & (__n - 1))
+ __n = __next_prime(__n);
size_type __bc = bucket_count();
if (__n > __bc)
__rehash(__n);
- else
+ else if (__n < __bc)
{
__n = _VSTD::max<size_type>
(
__n,
- __next_prime(size_t(ceil(float(size()) / max_load_factor())))
+ __is_power2(__bc) ? __next_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
+ __next_prime(size_t(ceil(float(size()) / max_load_factor())))
);
if (__n < __bc)
__rehash(__n);
@@ -1517,13 +1546,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
__node_pointer __cp = __pp->__next_;
if (__cp != nullptr)
{
- size_type __chash = __cp->__hash_ % __nbc;
+ size_type __chash = __constrain_hash(__cp->__hash_, __nbc);
__bucket_list_[__chash] = __pp;
size_type __phash = __chash;
for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;
__cp = __pp->__next_)
{
- __chash = __cp->__hash_ % __nbc;
+ __chash = __constrain_hash(__cp->__hash_, __nbc);
if (__chash == __phash)
__pp = __cp;
else
@@ -1561,12 +1590,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
size_type __bc = bucket_count();
if (__bc != 0)
{
- size_t __chash = __hash % __bc;
+ size_t __chash = __constrain_hash(__hash, __bc);
__node_pointer __nd = __bucket_list_[__chash];
if (__nd != nullptr)
{
for (__nd = __nd->__next_; __nd != nullptr &&
- __nd->__hash_ % __bc == __chash;
+ __constrain_hash(__nd->__hash_, __bc) == __chash;
__nd = __nd->__next_)
{
if (key_eq()(__nd->__value_, __k))
@@ -1586,12 +1615,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
size_type __bc = bucket_count();
if (__bc != 0)
{
- size_t __chash = __hash % __bc;
+ size_t __chash = __constrain_hash(__hash, __bc);
__node_const_pointer __nd = __bucket_list_[__chash];
if (__nd != nullptr)
{
for (__nd = __nd->__next_; __nd != nullptr &&
- __nd->__hash_ % __bc == __chash;
+ __constrain_hash(__nd->__hash_, __bc) == __chash;
__nd = __nd->__next_)
{
if (key_eq()(__nd->__value_, __k))
@@ -1612,7 +1641,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
{
__node_allocator& __na = __node_alloc();
- __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
+ __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);
__h.get_deleter().__value_constructed = true;
__h->__hash_ = hash_function()(__h->__value_);
@@ -1628,7 +1657,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v,
size_t __hash)
{
__node_allocator& __na = __node_alloc();
- __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
+ __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
__h.get_deleter().__value_constructed = true;
__h->__hash_ = __hash;
@@ -1643,7 +1672,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v)
{
__node_allocator& __na = __node_alloc();
- __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
+ __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
__h.get_deleter().__value_constructed = true;
__h->__hash_ = hash_function()(__h->__value_);
@@ -1659,7 +1688,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v
size_t __hash)
{
__node_allocator& __na = __node_alloc();
- __node_holder __h(__node_traits::allocate(__na, 1), _D(__na));
+ __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
__h.get_deleter().__value_constructed = true;
__h->__hash_ = __hash;
@@ -1730,7 +1759,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
// current node
__node_pointer __cn = const_cast<__node_pointer>(__p.__node_);
size_type __bc = bucket_count();
- size_t __chash = __cn->__hash_ % __bc;
+ size_t __chash = __constrain_hash(__cn->__hash_, __bc);
// find previous node
__node_pointer __pn = __bucket_list_[__chash];
for (; __pn->__next_ != __cn; __pn = __pn->__next_)
@@ -1738,15 +1767,15 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
// Fix up __bucket_list_
// if __pn is not in same bucket (before begin is not in same bucket) &&
// if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
- if (__pn == _VSTD::addressof(__p1_.first()) || __pn->__hash_ % __bc != __chash)
+ if (__pn == _VSTD::addressof(__p1_.first()) || __constrain_hash(__pn->__hash_, __bc) != __chash)
{
- if (__cn->__next_ == nullptr || __cn->__next_->__hash_ % __bc != __chash)
+ if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash)
__bucket_list_[__chash] = nullptr;
}
// if __cn->__next_ is not in same bucket (nullptr is in same bucket)
if (__cn->__next_ != nullptr)
{
- size_t __nhash = __cn->__next_->__hash_ % __bc;
+ size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc);
if (__nhash != __chash)
__bucket_list_[__nhash] = __pn;
}
@@ -1754,7 +1783,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
__pn->__next_ = __cn->__next_;
__cn->__next_ = nullptr;
--size();
- return __node_holder(__cn, _D(__node_alloc(), true));
+ return __node_holder(__cn, _Dp(__node_alloc(), true));
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1877,10 +1906,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
__p2_.swap(__u.__p2_);
__p3_.swap(__u.__p3_);
if (size() > 0)
- __bucket_list_[__p1_.first().__next_->__hash_ % bucket_count()] =
+ __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
if (__u.size() > 0)
- __u.__bucket_list_[__u.__p1_.first().__next_->__hash_ % __u.bucket_count()] =
+ __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] =
static_cast<__node_pointer>(_VSTD::addressof(__u.__p1_.first()));
}
@@ -1894,7 +1923,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
if (__np != nullptr)
{
for (__np = __np->__next_; __np != nullptr &&
- __np->__hash_ % __bc == __n;
+ __constrain_hash(__np->__hash_, __bc) == __n;
__np = __np->__next_, ++__r)
;
}