13e519524SHoward Hinnant// -*- C++ -*- 23e519524SHoward Hinnant//===----------------------------------------------------------------------===// 33e519524SHoward Hinnant// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 73e519524SHoward Hinnant// 83e519524SHoward Hinnant//===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 10cc82a1b0SLouis Dionne#ifndef _LIBCPP___HASH_TABLE 11cc82a1b0SLouis Dionne#define _LIBCPP___HASH_TABLE 123e519524SHoward Hinnant 132e2f3158SNikolas Klauser#include <__algorithm/max.h> 142e2f3158SNikolas Klauser#include <__algorithm/min.h> 15f87aa19bSLouis Dionne#include <__assert> 16bfbd73f8SArthur O'Dwyer#include <__bits> // __libcpp_clz 173e519524SHoward Hinnant#include <__config> 18bfbd73f8SArthur O'Dwyer#include <__debug> 192e2f3158SNikolas Klauser#include <__functional/hash.h> 203cd4531bSNikolas Klauser#include <__iterator/iterator_traits.h> 21*f4fb72e6SNikolas Klauser#include <__memory/swap_allocator.h> 2252915d78SNikolas Klauser#include <__utility/swap.h> 233e519524SHoward Hinnant#include <cmath> 24bfbd73f8SArthur O'Dwyer#include <initializer_list> 25bfbd73f8SArthur O'Dwyer#include <memory> 2604333f9bSEric Fiselier#include <type_traits> 2752915d78SNikolas Klauser 28073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 293e519524SHoward Hinnant# pragma GCC system_header 30073458b1SHoward Hinnant#endif 313e519524SHoward Hinnant 32a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS 33a016efb1SEric Fiselier#include <__undef_macros> 343e519524SHoward Hinnant 35fcd02211SEric Fiselier 36a016efb1SEric Fiselier_LIBCPP_BEGIN_NAMESPACE_STD 37a016efb1SEric Fiselier 38fcd02211SEric Fiseliertemplate <class _Key, class _Tp> 39fcd02211SEric Fiselierstruct __hash_value_type; 40fcd02211SEric Fiselier 41fcd02211SEric Fiseliertemplate <class _Tp> 42fcd02211SEric Fiselierstruct __is_hash_value_type_imp : false_type {}; 43fcd02211SEric Fiselier 44fcd02211SEric Fiseliertemplate <class _Key, class _Value> 45fcd02211SEric Fiselierstruct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; 46fcd02211SEric Fiselier 47fcd02211SEric Fiseliertemplate <class ..._Args> 48fcd02211SEric Fiselierstruct __is_hash_value_type : false_type {}; 49fcd02211SEric Fiselier 50fcd02211SEric Fiseliertemplate <class _One> 51f7558068SNikolas Klauserstruct __is_hash_value_type<_One> : __is_hash_value_type_imp<__uncvref_t<_One> > {}; 52fcd02211SEric Fiselier 536e41256fSHoward Hinnant_LIBCPP_FUNC_VIS 54ce53420eSHoward Hinnantsize_t __next_prime(size_t __n); 553e519524SHoward Hinnant 563e519524SHoward Hinnanttemplate <class _NodePtr> 573e519524SHoward Hinnantstruct __hash_node_base 583e519524SHoward Hinnant{ 5940492ba4SEric Fiselier typedef typename pointer_traits<_NodePtr>::element_type __node_type; 603e519524SHoward Hinnant typedef __hash_node_base __first_node; 6140492ba4SEric Fiselier typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer; 6240492ba4SEric Fiselier typedef _NodePtr __node_pointer; 633e519524SHoward Hinnant 6440492ba4SEric Fiselier#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) 6540492ba4SEric Fiselier typedef __node_base_pointer __next_pointer; 6640492ba4SEric Fiselier#else 6740492ba4SEric Fiselier typedef typename conditional< 6840492ba4SEric Fiselier is_pointer<__node_pointer>::value, 6940492ba4SEric Fiselier __node_base_pointer, 7040492ba4SEric Fiselier __node_pointer>::type __next_pointer; 7140492ba4SEric Fiselier#endif 7240492ba4SEric Fiselier 7340492ba4SEric Fiselier __next_pointer __next_; 7440492ba4SEric Fiselier 7540492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY 7640492ba4SEric Fiselier __next_pointer __ptr() _NOEXCEPT { 7740492ba4SEric Fiselier return static_cast<__next_pointer>( 7840492ba4SEric Fiselier pointer_traits<__node_base_pointer>::pointer_to(*this)); 7940492ba4SEric Fiselier } 8040492ba4SEric Fiselier 8140492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY 8240492ba4SEric Fiselier __node_pointer __upcast() _NOEXCEPT { 8340492ba4SEric Fiselier return static_cast<__node_pointer>( 8440492ba4SEric Fiselier pointer_traits<__node_base_pointer>::pointer_to(*this)); 8540492ba4SEric Fiselier } 8640492ba4SEric Fiselier 8740492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY 8840492ba4SEric Fiselier size_t __hash() const _NOEXCEPT { 8940492ba4SEric Fiselier return static_cast<__node_type const&>(*this).__hash_; 9040492ba4SEric Fiselier } 913e519524SHoward Hinnant 923714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} 933e519524SHoward Hinnant}; 943e519524SHoward Hinnant 953e519524SHoward Hinnanttemplate <class _Tp, class _VoidPtr> 967c2f5827SAmy Huangstruct _LIBCPP_STANDALONE_DEBUG __hash_node 973e519524SHoward Hinnant : public __hash_node_base 983e519524SHoward Hinnant < 99934b0921SEric Fiselier typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type 1003e519524SHoward Hinnant > 1013e519524SHoward Hinnant{ 10275d0dcfdSEric Fiselier typedef _Tp __node_value_type; 1033e519524SHoward Hinnant 1043e519524SHoward Hinnant size_t __hash_; 10575d0dcfdSEric Fiselier __node_value_type __value_; 1063e519524SHoward Hinnant}; 1073e519524SHoward Hinnant 1084cb38a82SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1094cb38a82SHoward Hinnantbool 1109ba5c11bSEric Fiselier__is_hash_power2(size_t __bc) 1114cb38a82SHoward Hinnant{ 1124cb38a82SHoward Hinnant return __bc > 2 && !(__bc & (__bc - 1)); 1134cb38a82SHoward Hinnant} 1144cb38a82SHoward Hinnant 1154cb38a82SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1164cb38a82SHoward Hinnantsize_t 1174cb38a82SHoward Hinnant__constrain_hash(size_t __h, size_t __bc) 1184cb38a82SHoward Hinnant{ 119118cb418SEric Fiselier return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : 120118cb418SEric Fiselier (__h < __bc ? __h : __h % __bc); 1214cb38a82SHoward Hinnant} 1224cb38a82SHoward Hinnant 1234cb38a82SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1244cb38a82SHoward Hinnantsize_t 1259ba5c11bSEric Fiselier__next_hash_pow2(size_t __n) 1264cb38a82SHoward Hinnant{ 127d586f92cSArthur O'Dwyer return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1))); 1284cb38a82SHoward Hinnant} 1294cb38a82SHoward Hinnant 130fde79b40SDuncan P. N. Exon Smith 131ce53420eSHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table; 13275d0dcfdSEric Fiselier 133e2f2d1edSEric Fiseliertemplate <class _NodePtr> class _LIBCPP_TEMPLATE_VIS __hash_iterator; 134e2f2d1edSEric Fiseliertemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 135e2f2d1edSEric Fiseliertemplate <class _NodePtr> class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; 136e2f2d1edSEric Fiseliertemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 137e2f2d1edSEric Fiseliertemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 138e2f2d1edSEric Fiseliertemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 1393e519524SHoward Hinnant 14075d0dcfdSEric Fiseliertemplate <class _Tp> 14143b121dfSEric Fiselierstruct __hash_key_value_types { 14275d0dcfdSEric Fiselier static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); 14375d0dcfdSEric Fiselier typedef _Tp key_type; 14475d0dcfdSEric Fiselier typedef _Tp __node_value_type; 14575d0dcfdSEric Fiselier typedef _Tp __container_value_type; 14675d0dcfdSEric Fiselier static const bool __is_map = false; 147fcd02211SEric Fiselier 148fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 149fcd02211SEric Fiselier static key_type const& __get_key(_Tp const& __v) { 150fcd02211SEric Fiselier return __v; 151fcd02211SEric Fiselier } 152fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 153fcd02211SEric Fiselier static __container_value_type const& __get_value(__node_value_type const& __v) { 154fcd02211SEric Fiselier return __v; 155fcd02211SEric Fiselier } 156fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 157fcd02211SEric Fiselier static __container_value_type* __get_ptr(__node_value_type& __n) { 158fcd02211SEric Fiselier return _VSTD::addressof(__n); 159fcd02211SEric Fiselier } 160fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 161fcd02211SEric Fiselier static __container_value_type&& __move(__node_value_type& __v) { 162fcd02211SEric Fiselier return _VSTD::move(__v); 163fcd02211SEric Fiselier } 16475d0dcfdSEric Fiselier}; 16575d0dcfdSEric Fiselier 16675d0dcfdSEric Fiseliertemplate <class _Key, class _Tp> 16743b121dfSEric Fiselierstruct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { 16875d0dcfdSEric Fiselier typedef _Key key_type; 16975d0dcfdSEric Fiselier typedef _Tp mapped_type; 17075d0dcfdSEric Fiselier typedef __hash_value_type<_Key, _Tp> __node_value_type; 17175d0dcfdSEric Fiselier typedef pair<const _Key, _Tp> __container_value_type; 17275d0dcfdSEric Fiselier typedef __container_value_type __map_value_type; 17375d0dcfdSEric Fiselier static const bool __is_map = true; 174fcd02211SEric Fiselier 175fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 176fcd02211SEric Fiselier static key_type const& __get_key(__container_value_type const& __v) { 177fcd02211SEric Fiselier return __v.first; 178fcd02211SEric Fiselier } 179fcd02211SEric Fiselier 180fcd02211SEric Fiselier template <class _Up> 181fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1824887d047SNikolas Klauser static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&> 183fcd02211SEric Fiselier __get_value(_Up& __t) { 184f52318b4SErik Pilkington return __t.__get_value(); 185fcd02211SEric Fiselier } 186fcd02211SEric Fiselier 187fcd02211SEric Fiselier template <class _Up> 188fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1894887d047SNikolas Klauser static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&> 190fcd02211SEric Fiselier __get_value(_Up& __t) { 191fcd02211SEric Fiselier return __t; 192fcd02211SEric Fiselier } 193fcd02211SEric Fiselier 194fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 195fcd02211SEric Fiselier static __container_value_type* __get_ptr(__node_value_type& __n) { 196f52318b4SErik Pilkington return _VSTD::addressof(__n.__get_value()); 197fcd02211SEric Fiselier } 198fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 199f52318b4SErik Pilkington static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { 200f52318b4SErik Pilkington return __v.__move(); 201fcd02211SEric Fiselier } 20275d0dcfdSEric Fiselier}; 20375d0dcfdSEric Fiselier 20443b121dfSEric Fiseliertemplate <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, 20575d0dcfdSEric Fiselier bool = _KVTypes::__is_map> 20643b121dfSEric Fiselierstruct __hash_map_pointer_types {}; 20775d0dcfdSEric Fiselier 20875d0dcfdSEric Fiseliertemplate <class _Tp, class _AllocPtr, class _KVTypes> 20943b121dfSEric Fiselierstruct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { 21075d0dcfdSEric Fiselier typedef typename _KVTypes::__map_value_type _Mv; 21175d0dcfdSEric Fiselier typedef typename __rebind_pointer<_AllocPtr, _Mv>::type 21275d0dcfdSEric Fiselier __map_value_type_pointer; 21375d0dcfdSEric Fiselier typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type 21475d0dcfdSEric Fiselier __const_map_value_type_pointer; 21575d0dcfdSEric Fiselier}; 21675d0dcfdSEric Fiselier 21775d0dcfdSEric Fiseliertemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> 21875d0dcfdSEric Fiselierstruct __hash_node_types; 21975d0dcfdSEric Fiselier 22075d0dcfdSEric Fiseliertemplate <class _NodePtr, class _Tp, class _VoidPtr> 22175d0dcfdSEric Fiselierstruct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > 22243b121dfSEric Fiselier : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> 22375d0dcfdSEric Fiselier 22475d0dcfdSEric Fiselier{ 22543b121dfSEric Fiselier typedef __hash_key_value_types<_Tp> __base; 22675d0dcfdSEric Fiselier 22775d0dcfdSEric Fiselierpublic: 22875d0dcfdSEric Fiselier typedef ptrdiff_t difference_type; 22975d0dcfdSEric Fiselier typedef size_t size_type; 23075d0dcfdSEric Fiselier 23175d0dcfdSEric Fiselier typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; 23275d0dcfdSEric Fiselier 23375d0dcfdSEric Fiselier typedef typename pointer_traits<_NodePtr>::element_type __node_type; 23475d0dcfdSEric Fiselier typedef _NodePtr __node_pointer; 23575d0dcfdSEric Fiselier 23675d0dcfdSEric Fiselier typedef __hash_node_base<__node_pointer> __node_base_type; 23775d0dcfdSEric Fiselier typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type 23875d0dcfdSEric Fiselier __node_base_pointer; 23975d0dcfdSEric Fiselier 24040492ba4SEric Fiselier typedef typename __node_base_type::__next_pointer __next_pointer; 24140492ba4SEric Fiselier 24275d0dcfdSEric Fiselier typedef _Tp __node_value_type; 24375d0dcfdSEric Fiselier typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type 24475d0dcfdSEric Fiselier __node_value_type_pointer; 24575d0dcfdSEric Fiselier typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type 24675d0dcfdSEric Fiselier __const_node_value_type_pointer; 24740492ba4SEric Fiselier 24875d0dcfdSEric Fiselierprivate: 24975d0dcfdSEric Fiselier static_assert(!is_const<__node_type>::value, 25075d0dcfdSEric Fiselier "_NodePtr should never be a pointer to const"); 25175d0dcfdSEric Fiselier static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), 25275d0dcfdSEric Fiselier "_VoidPtr does not point to unqualified void type"); 25375d0dcfdSEric Fiselier static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, 25475d0dcfdSEric Fiselier _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); 25575d0dcfdSEric Fiselier}; 25675d0dcfdSEric Fiselier 25775d0dcfdSEric Fiseliertemplate <class _HashIterator> 25875d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator; 25975d0dcfdSEric Fiseliertemplate <class _NodePtr> 26075d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 26175d0dcfdSEric Fiseliertemplate <class _NodePtr> 26275d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 26375d0dcfdSEric Fiseliertemplate <class _NodePtr> 26475d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 26575d0dcfdSEric Fiseliertemplate <class _NodePtr> 26675d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 26775d0dcfdSEric Fiselier 26875d0dcfdSEric Fiselier 26975d0dcfdSEric Fiseliertemplate <class _NodeValueTp, class _VoidPtr> 27075d0dcfdSEric Fiselierstruct __make_hash_node_types { 27175d0dcfdSEric Fiselier typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; 27275d0dcfdSEric Fiselier typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; 27375d0dcfdSEric Fiselier typedef __hash_node_types<_NodePtr> type; 27475d0dcfdSEric Fiselier}; 27575d0dcfdSEric Fiselier 2763e519524SHoward Hinnanttemplate <class _NodePtr> 277e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_iterator 2783e519524SHoward Hinnant{ 27975d0dcfdSEric Fiselier typedef __hash_node_types<_NodePtr> _NodeTypes; 2803e519524SHoward Hinnant typedef _NodePtr __node_pointer; 28140492ba4SEric Fiselier typedef typename _NodeTypes::__next_pointer __next_pointer; 2823e519524SHoward Hinnant 28340492ba4SEric Fiselier __next_pointer __node_; 2843e519524SHoward Hinnant 2853e519524SHoward Hinnantpublic: 2863e519524SHoward Hinnant typedef forward_iterator_tag iterator_category; 28775d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_value_type value_type; 28875d0dcfdSEric Fiselier typedef typename _NodeTypes::difference_type difference_type; 2893e519524SHoward Hinnant typedef value_type& reference; 29075d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_value_type_pointer pointer; 2913e519524SHoward Hinnant 29240492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { 293caf5548cSNikolas Klauser _VSTD::__debug_db_insert_i(this); 294b24c8024SHoward Hinnant } 295b24c8024SHoward Hinnant 296f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 29743d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 298b24c8024SHoward Hinnant __hash_iterator(const __hash_iterator& __i) 299b24c8024SHoward Hinnant : __node_(__i.__node_) 300b24c8024SHoward Hinnant { 301968e2739SMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 302b24c8024SHoward Hinnant } 303b24c8024SHoward Hinnant 30443d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 305b24c8024SHoward Hinnant ~__hash_iterator() 306b24c8024SHoward Hinnant { 307b24c8024SHoward Hinnant __get_db()->__erase_i(this); 308b24c8024SHoward Hinnant } 309b24c8024SHoward Hinnant 310b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 311b24c8024SHoward Hinnant __hash_iterator& operator=(const __hash_iterator& __i) 312b24c8024SHoward Hinnant { 313d6e2c95dSMark de Wever if (this != _VSTD::addressof(__i)) 314b24c8024SHoward Hinnant { 315d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 316b24c8024SHoward Hinnant __node_ = __i.__node_; 317b24c8024SHoward Hinnant } 318b24c8024SHoward Hinnant return *this; 319b24c8024SHoward Hinnant } 320f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE 321b24c8024SHoward Hinnant 322b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 32340492ba4SEric Fiselier reference operator*() const { 32440492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 325b24c8024SHoward Hinnant "Attempted to dereference a non-dereferenceable unordered container iterator"); 32640492ba4SEric Fiselier return __node_->__upcast()->__value_; 327b24c8024SHoward Hinnant } 3283e519524SHoward Hinnant 32943d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 33040492ba4SEric Fiselier pointer operator->() const { 33140492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 33240492ba4SEric Fiselier "Attempted to dereference a non-dereferenceable unordered container iterator"); 33340492ba4SEric Fiselier return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 33440492ba4SEric Fiselier } 33540492ba4SEric Fiselier 33640492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY 33740492ba4SEric Fiselier __hash_iterator& operator++() { 33840492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 33996100f15SKristina Bessonova "Attempted to increment a non-incrementable unordered container iterator"); 3403e519524SHoward Hinnant __node_ = __node_->__next_; 3413e519524SHoward Hinnant return *this; 3423e519524SHoward Hinnant } 3433e519524SHoward Hinnant 34443d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 3453e519524SHoward Hinnant __hash_iterator operator++(int) 3463e519524SHoward Hinnant { 3473e519524SHoward Hinnant __hash_iterator __t(*this); 3483e519524SHoward Hinnant ++(*this); 3493e519524SHoward Hinnant return __t; 3503e519524SHoward Hinnant } 3513e519524SHoward Hinnant 35243d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 35343d99238SHoward Hinnant bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) 354b24c8024SHoward Hinnant { 355b24c8024SHoward Hinnant return __x.__node_ == __y.__node_; 356b24c8024SHoward Hinnant } 35743d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 35843d99238SHoward Hinnant bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) 359b24c8024SHoward Hinnant {return !(__x == __y);} 3603e519524SHoward Hinnant 3613e519524SHoward Hinnantprivate: 362b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 363f86c2b6fSArthur O'Dwyer explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT 364b24c8024SHoward Hinnant : __node_(__node) 365b24c8024SHoward Hinnant { 3664eab04f8SLouis Dionne (void)__c; 367f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 368b24c8024SHoward Hinnant __get_db()->__insert_ic(this, __c); 369b24c8024SHoward Hinnant#endif 3704eab04f8SLouis Dionne } 3713e519524SHoward Hinnant template <class, class, class, class> friend class __hash_table; 372e2f2d1edSEric Fiselier template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 373e2f2d1edSEric Fiselier template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 374e2f2d1edSEric Fiselier template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 375e2f2d1edSEric Fiselier template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 3763e519524SHoward Hinnant}; 3773e519524SHoward Hinnant 37875d0dcfdSEric Fiseliertemplate <class _NodePtr> 379e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_const_iterator 3803e519524SHoward Hinnant{ 38175d0dcfdSEric Fiselier static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, ""); 38275d0dcfdSEric Fiselier typedef __hash_node_types<_NodePtr> _NodeTypes; 38375d0dcfdSEric Fiselier typedef _NodePtr __node_pointer; 38440492ba4SEric Fiselier typedef typename _NodeTypes::__next_pointer __next_pointer; 385757373e6SEric Fiselier 38640492ba4SEric Fiselier __next_pointer __node_; 3873e519524SHoward Hinnant 3883e519524SHoward Hinnantpublic: 389757373e6SEric Fiselier typedef __hash_iterator<_NodePtr> __non_const_iterator; 390757373e6SEric Fiselier 3913e519524SHoward Hinnant typedef forward_iterator_tag iterator_category; 39275d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_value_type value_type; 39375d0dcfdSEric Fiselier typedef typename _NodeTypes::difference_type difference_type; 3943e519524SHoward Hinnant typedef const value_type& reference; 39575d0dcfdSEric Fiselier typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 39675d0dcfdSEric Fiselier 3973e519524SHoward Hinnant 39840492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { 399caf5548cSNikolas Klauser _VSTD::__debug_db_insert_i(this); 400b24c8024SHoward Hinnant } 40140492ba4SEric Fiselier 40243d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 4033714107eSHoward Hinnant __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT 4043e519524SHoward Hinnant : __node_(__x.__node_) 405b24c8024SHoward Hinnant { 406f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 407d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); 408870827f6SLouis Dionne#endif 409b24c8024SHoward Hinnant } 410b24c8024SHoward Hinnant 411f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 41243d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 413b24c8024SHoward Hinnant __hash_const_iterator(const __hash_const_iterator& __i) 414b24c8024SHoward Hinnant : __node_(__i.__node_) 415b24c8024SHoward Hinnant { 416d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 417b24c8024SHoward Hinnant } 418b24c8024SHoward Hinnant 41943d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 420b24c8024SHoward Hinnant ~__hash_const_iterator() 421b24c8024SHoward Hinnant { 422b24c8024SHoward Hinnant __get_db()->__erase_i(this); 423b24c8024SHoward Hinnant } 424b24c8024SHoward Hinnant 425b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 426b24c8024SHoward Hinnant __hash_const_iterator& operator=(const __hash_const_iterator& __i) 427b24c8024SHoward Hinnant { 428d6e2c95dSMark de Wever if (this != _VSTD::addressof(__i)) 429b24c8024SHoward Hinnant { 430d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 431b24c8024SHoward Hinnant __node_ = __i.__node_; 432b24c8024SHoward Hinnant } 433b24c8024SHoward Hinnant return *this; 434b24c8024SHoward Hinnant } 435f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE 436b24c8024SHoward Hinnant 437b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 43840492ba4SEric Fiselier reference operator*() const { 43940492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 440b24c8024SHoward Hinnant "Attempted to dereference a non-dereferenceable unordered container const_iterator"); 44140492ba4SEric Fiselier return __node_->__upcast()->__value_; 442b24c8024SHoward Hinnant } 443b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 44440492ba4SEric Fiselier pointer operator->() const { 44540492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 446b24c8024SHoward Hinnant "Attempted to dereference a non-dereferenceable unordered container const_iterator"); 44740492ba4SEric Fiselier return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 448b24c8024SHoward Hinnant } 4493e519524SHoward Hinnant 45043d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 45140492ba4SEric Fiselier __hash_const_iterator& operator++() { 45240492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 45396100f15SKristina Bessonova "Attempted to increment a non-incrementable unordered container const_iterator"); 4543e519524SHoward Hinnant __node_ = __node_->__next_; 4553e519524SHoward Hinnant return *this; 4563e519524SHoward Hinnant } 4573e519524SHoward Hinnant 45843d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 4593e519524SHoward Hinnant __hash_const_iterator operator++(int) 4603e519524SHoward Hinnant { 4613e519524SHoward Hinnant __hash_const_iterator __t(*this); 4623e519524SHoward Hinnant ++(*this); 4633e519524SHoward Hinnant return __t; 4643e519524SHoward Hinnant } 4653e519524SHoward Hinnant 46643d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 46743d99238SHoward Hinnant bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) 468b24c8024SHoward Hinnant { 469b24c8024SHoward Hinnant return __x.__node_ == __y.__node_; 470b24c8024SHoward Hinnant } 47143d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 47243d99238SHoward Hinnant bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) 473b24c8024SHoward Hinnant {return !(__x == __y);} 4743e519524SHoward Hinnant 4753e519524SHoward Hinnantprivate: 476b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 477f86c2b6fSArthur O'Dwyer explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT 478b24c8024SHoward Hinnant : __node_(__node) 479b24c8024SHoward Hinnant { 4804eab04f8SLouis Dionne (void)__c; 481f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 482b24c8024SHoward Hinnant __get_db()->__insert_ic(this, __c); 483b24c8024SHoward Hinnant#endif 4844eab04f8SLouis Dionne } 4853e519524SHoward Hinnant template <class, class, class, class> friend class __hash_table; 486e2f2d1edSEric Fiselier template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 487e2f2d1edSEric Fiselier template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 488e2f2d1edSEric Fiselier template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 4893e519524SHoward Hinnant}; 4903e519524SHoward Hinnant 4913e519524SHoward Hinnanttemplate <class _NodePtr> 492e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_local_iterator 4933e519524SHoward Hinnant{ 49475d0dcfdSEric Fiselier typedef __hash_node_types<_NodePtr> _NodeTypes; 4953e519524SHoward Hinnant typedef _NodePtr __node_pointer; 49640492ba4SEric Fiselier typedef typename _NodeTypes::__next_pointer __next_pointer; 4973e519524SHoward Hinnant 49840492ba4SEric Fiselier __next_pointer __node_; 4993e519524SHoward Hinnant size_t __bucket_; 5003e519524SHoward Hinnant size_t __bucket_count_; 5013e519524SHoward Hinnant 5023e519524SHoward Hinnantpublic: 5033e519524SHoward Hinnant typedef forward_iterator_tag iterator_category; 50475d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_value_type value_type; 50575d0dcfdSEric Fiselier typedef typename _NodeTypes::difference_type difference_type; 5063e519524SHoward Hinnant typedef value_type& reference; 50775d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_value_type_pointer pointer; 5083e519524SHoward Hinnant 50940492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { 510caf5548cSNikolas Klauser _VSTD::__debug_db_insert_i(this); 511b24c8024SHoward Hinnant } 512b24c8024SHoward Hinnant 513f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 51443d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 515b24c8024SHoward Hinnant __hash_local_iterator(const __hash_local_iterator& __i) 516b24c8024SHoward Hinnant : __node_(__i.__node_), 517b24c8024SHoward Hinnant __bucket_(__i.__bucket_), 518b24c8024SHoward Hinnant __bucket_count_(__i.__bucket_count_) 519b24c8024SHoward Hinnant { 520d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 521b24c8024SHoward Hinnant } 522b24c8024SHoward Hinnant 52343d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 524b24c8024SHoward Hinnant ~__hash_local_iterator() 525b24c8024SHoward Hinnant { 526b24c8024SHoward Hinnant __get_db()->__erase_i(this); 527b24c8024SHoward Hinnant } 528b24c8024SHoward Hinnant 529b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 530b24c8024SHoward Hinnant __hash_local_iterator& operator=(const __hash_local_iterator& __i) 531b24c8024SHoward Hinnant { 532d6e2c95dSMark de Wever if (this != _VSTD::addressof(__i)) 533b24c8024SHoward Hinnant { 534d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 535b24c8024SHoward Hinnant __node_ = __i.__node_; 536b24c8024SHoward Hinnant __bucket_ = __i.__bucket_; 537b24c8024SHoward Hinnant __bucket_count_ = __i.__bucket_count_; 538b24c8024SHoward Hinnant } 539b24c8024SHoward Hinnant return *this; 540b24c8024SHoward Hinnant } 541f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE 542b24c8024SHoward Hinnant 543b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 54440492ba4SEric Fiselier reference operator*() const { 54540492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 546b24c8024SHoward Hinnant "Attempted to dereference a non-dereferenceable unordered container local_iterator"); 54740492ba4SEric Fiselier return __node_->__upcast()->__value_; 548b24c8024SHoward Hinnant } 5493e519524SHoward Hinnant 55043d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 55140492ba4SEric Fiselier pointer operator->() const { 55240492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 55340492ba4SEric Fiselier "Attempted to dereference a non-dereferenceable unordered container local_iterator"); 55440492ba4SEric Fiselier return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 55540492ba4SEric Fiselier } 55640492ba4SEric Fiselier 55740492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY 55840492ba4SEric Fiselier __hash_local_iterator& operator++() { 55940492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 56096100f15SKristina Bessonova "Attempted to increment a non-incrementable unordered container local_iterator"); 5613e519524SHoward Hinnant __node_ = __node_->__next_; 56240492ba4SEric Fiselier if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) 5633e519524SHoward Hinnant __node_ = nullptr; 5643e519524SHoward Hinnant return *this; 5653e519524SHoward Hinnant } 5663e519524SHoward Hinnant 56743d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 5683e519524SHoward Hinnant __hash_local_iterator operator++(int) 5693e519524SHoward Hinnant { 5703e519524SHoward Hinnant __hash_local_iterator __t(*this); 5713e519524SHoward Hinnant ++(*this); 5723e519524SHoward Hinnant return __t; 5733e519524SHoward Hinnant } 5743e519524SHoward Hinnant 57543d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 57643d99238SHoward Hinnant bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) 577b24c8024SHoward Hinnant { 578b24c8024SHoward Hinnant return __x.__node_ == __y.__node_; 579b24c8024SHoward Hinnant } 58043d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 58143d99238SHoward Hinnant bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) 582b24c8024SHoward Hinnant {return !(__x == __y);} 5833e519524SHoward Hinnant 5843e519524SHoward Hinnantprivate: 585b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 586f86c2b6fSArthur O'Dwyer explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, 587b24c8024SHoward Hinnant size_t __bucket_count, const void* __c) _NOEXCEPT 588b24c8024SHoward Hinnant : __node_(__node), 589b24c8024SHoward Hinnant __bucket_(__bucket), 590b24c8024SHoward Hinnant __bucket_count_(__bucket_count) 591b24c8024SHoward Hinnant { 5924eab04f8SLouis Dionne (void)__c; 593f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 594b24c8024SHoward Hinnant __get_db()->__insert_ic(this, __c); 595b24c8024SHoward Hinnant#endif 5964eab04f8SLouis Dionne if (__node_ != nullptr) 5974eab04f8SLouis Dionne __node_ = __node_->__next_; 5984eab04f8SLouis Dionne } 5993e519524SHoward Hinnant template <class, class, class, class> friend class __hash_table; 600e2f2d1edSEric Fiselier template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 601e2f2d1edSEric Fiselier template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 6023e519524SHoward Hinnant}; 6033e519524SHoward Hinnant 6043e519524SHoward Hinnanttemplate <class _ConstNodePtr> 605e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator 6063e519524SHoward Hinnant{ 60775d0dcfdSEric Fiselier typedef __hash_node_types<_ConstNodePtr> _NodeTypes; 6083e519524SHoward Hinnant typedef _ConstNodePtr __node_pointer; 60940492ba4SEric Fiselier typedef typename _NodeTypes::__next_pointer __next_pointer; 6103e519524SHoward Hinnant 61140492ba4SEric Fiselier __next_pointer __node_; 6123e519524SHoward Hinnant size_t __bucket_; 6133e519524SHoward Hinnant size_t __bucket_count_; 6143e519524SHoward Hinnant 6153e519524SHoward Hinnant typedef pointer_traits<__node_pointer> __pointer_traits; 6163e519524SHoward Hinnant typedef typename __pointer_traits::element_type __node; 6173e519524SHoward Hinnant typedef typename remove_const<__node>::type __non_const_node; 618934b0921SEric Fiselier typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type 6193e519524SHoward Hinnant __non_const_node_pointer; 620757373e6SEric Fiselierpublic: 6213e519524SHoward Hinnant typedef __hash_local_iterator<__non_const_node_pointer> 6223e519524SHoward Hinnant __non_const_iterator; 623757373e6SEric Fiselier 6243e519524SHoward Hinnant typedef forward_iterator_tag iterator_category; 62575d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_value_type value_type; 62675d0dcfdSEric Fiselier typedef typename _NodeTypes::difference_type difference_type; 6273e519524SHoward Hinnant typedef const value_type& reference; 62875d0dcfdSEric Fiselier typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 6293e519524SHoward Hinnant 630934b0921SEric Fiselier 63140492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { 632caf5548cSNikolas Klauser _VSTD::__debug_db_insert_i(this); 633b24c8024SHoward Hinnant } 634b24c8024SHoward Hinnant 63543d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 6363714107eSHoward Hinnant __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT 6373e519524SHoward Hinnant : __node_(__x.__node_), 6383e519524SHoward Hinnant __bucket_(__x.__bucket_), 6393e519524SHoward Hinnant __bucket_count_(__x.__bucket_count_) 640b24c8024SHoward Hinnant { 641f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 642d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); 643870827f6SLouis Dionne#endif 644b24c8024SHoward Hinnant } 645b24c8024SHoward Hinnant 646f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 64743d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 648b24c8024SHoward Hinnant __hash_const_local_iterator(const __hash_const_local_iterator& __i) 649b24c8024SHoward Hinnant : __node_(__i.__node_), 650b24c8024SHoward Hinnant __bucket_(__i.__bucket_), 651b24c8024SHoward Hinnant __bucket_count_(__i.__bucket_count_) 652b24c8024SHoward Hinnant { 653d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 654b24c8024SHoward Hinnant } 655b24c8024SHoward Hinnant 65643d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 657b24c8024SHoward Hinnant ~__hash_const_local_iterator() 658b24c8024SHoward Hinnant { 659b24c8024SHoward Hinnant __get_db()->__erase_i(this); 660b24c8024SHoward Hinnant } 661b24c8024SHoward Hinnant 662b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 663b24c8024SHoward Hinnant __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) 664b24c8024SHoward Hinnant { 665d6e2c95dSMark de Wever if (this != _VSTD::addressof(__i)) 666b24c8024SHoward Hinnant { 667d6e2c95dSMark de Wever __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 668b24c8024SHoward Hinnant __node_ = __i.__node_; 669b24c8024SHoward Hinnant __bucket_ = __i.__bucket_; 670b24c8024SHoward Hinnant __bucket_count_ = __i.__bucket_count_; 671b24c8024SHoward Hinnant } 672b24c8024SHoward Hinnant return *this; 673b24c8024SHoward Hinnant } 674f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE 675b24c8024SHoward Hinnant 676b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 67740492ba4SEric Fiselier reference operator*() const { 67840492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 679b24c8024SHoward Hinnant "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); 68040492ba4SEric Fiselier return __node_->__upcast()->__value_; 681b24c8024SHoward Hinnant } 6823e519524SHoward Hinnant 68343d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 68440492ba4SEric Fiselier pointer operator->() const { 68540492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 68640492ba4SEric Fiselier "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); 68740492ba4SEric Fiselier return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 68840492ba4SEric Fiselier } 68940492ba4SEric Fiselier 69040492ba4SEric Fiselier _LIBCPP_INLINE_VISIBILITY 69140492ba4SEric Fiselier __hash_const_local_iterator& operator++() { 69240492ba4SEric Fiselier _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 69396100f15SKristina Bessonova "Attempted to increment a non-incrementable unordered container const_local_iterator"); 6943e519524SHoward Hinnant __node_ = __node_->__next_; 69540492ba4SEric Fiselier if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) 6963e519524SHoward Hinnant __node_ = nullptr; 6973e519524SHoward Hinnant return *this; 6983e519524SHoward Hinnant } 6993e519524SHoward Hinnant 70043d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7013e519524SHoward Hinnant __hash_const_local_iterator operator++(int) 7023e519524SHoward Hinnant { 7033e519524SHoward Hinnant __hash_const_local_iterator __t(*this); 7043e519524SHoward Hinnant ++(*this); 7053e519524SHoward Hinnant return __t; 7063e519524SHoward Hinnant } 7073e519524SHoward Hinnant 70843d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 70943d99238SHoward Hinnant bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) 710b24c8024SHoward Hinnant { 711b24c8024SHoward Hinnant return __x.__node_ == __y.__node_; 712b24c8024SHoward Hinnant } 71343d99238SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 71443d99238SHoward Hinnant bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) 715b24c8024SHoward Hinnant {return !(__x == __y);} 7163e519524SHoward Hinnant 7173e519524SHoward Hinnantprivate: 718b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 719f86c2b6fSArthur O'Dwyer explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, 720b24c8024SHoward Hinnant size_t __bucket_count, const void* __c) _NOEXCEPT 7212e4755ffSLouis Dionne : __node_(__node_ptr), 722b24c8024SHoward Hinnant __bucket_(__bucket), 723b24c8024SHoward Hinnant __bucket_count_(__bucket_count) 724b24c8024SHoward Hinnant { 7254eab04f8SLouis Dionne (void)__c; 726f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 727b24c8024SHoward Hinnant __get_db()->__insert_ic(this, __c); 728b24c8024SHoward Hinnant#endif 7294eab04f8SLouis Dionne if (__node_ != nullptr) 7304eab04f8SLouis Dionne __node_ = __node_->__next_; 7314eab04f8SLouis Dionne } 7323e519524SHoward Hinnant template <class, class, class, class> friend class __hash_table; 733e2f2d1edSEric Fiselier template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 7343e519524SHoward Hinnant}; 7353e519524SHoward Hinnant 7363e519524SHoward Hinnanttemplate <class _Alloc> 7373e519524SHoward Hinnantclass __bucket_list_deallocator 7383e519524SHoward Hinnant{ 7393e519524SHoward Hinnant typedef _Alloc allocator_type; 7403e519524SHoward Hinnant typedef allocator_traits<allocator_type> __alloc_traits; 7413e519524SHoward Hinnant typedef typename __alloc_traits::size_type size_type; 7423e519524SHoward Hinnant 7433e519524SHoward Hinnant __compressed_pair<size_type, allocator_type> __data_; 7443e519524SHoward Hinnantpublic: 7453e519524SHoward Hinnant typedef typename __alloc_traits::pointer pointer; 7463e519524SHoward Hinnant 74743d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7483e519524SHoward Hinnant __bucket_list_deallocator() 7493714107eSHoward Hinnant _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 750549545b6SEric Fiselier : __data_(0, __default_init_tag()) {} 75143d99238SHoward Hinnant 75243d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7533e519524SHoward Hinnant __bucket_list_deallocator(const allocator_type& __a, size_type __size) 7543714107eSHoward Hinnant _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 7553e519524SHoward Hinnant : __data_(__size, __a) {} 7563e519524SHoward Hinnant 75743d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7583e519524SHoward Hinnant __bucket_list_deallocator(__bucket_list_deallocator&& __x) 7593714107eSHoward Hinnant _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 760ce48a113SHoward Hinnant : __data_(_VSTD::move(__x.__data_)) 7613e519524SHoward Hinnant { 7623e519524SHoward Hinnant __x.size() = 0; 7633e519524SHoward Hinnant } 7643e519524SHoward Hinnant 7653714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7663714107eSHoward Hinnant size_type& size() _NOEXCEPT {return __data_.first();} 7673714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7683714107eSHoward Hinnant size_type size() const _NOEXCEPT {return __data_.first();} 7693e519524SHoward Hinnant 77043d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7713714107eSHoward Hinnant allocator_type& __alloc() _NOEXCEPT {return __data_.second();} 7723714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7733714107eSHoward Hinnant const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} 7743714107eSHoward Hinnant 7753714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 7763714107eSHoward Hinnant void operator()(pointer __p) _NOEXCEPT 7773e519524SHoward Hinnant { 7783e519524SHoward Hinnant __alloc_traits::deallocate(__alloc(), __p, size()); 7793e519524SHoward Hinnant } 7803e519524SHoward Hinnant}; 7813e519524SHoward Hinnant 782ce53420eSHoward Hinnanttemplate <class _Alloc> class __hash_map_node_destructor; 7833e519524SHoward Hinnant 7843e519524SHoward Hinnanttemplate <class _Alloc> 7853e519524SHoward Hinnantclass __hash_node_destructor 7863e519524SHoward Hinnant{ 7873e519524SHoward Hinnant typedef _Alloc allocator_type; 7883e519524SHoward Hinnant typedef allocator_traits<allocator_type> __alloc_traits; 78975d0dcfdSEric Fiselier 7903e519524SHoward Hinnantpublic: 7913e519524SHoward Hinnant typedef typename __alloc_traits::pointer pointer; 7923e519524SHoward Hinnantprivate: 793fcd02211SEric Fiselier typedef __hash_node_types<pointer> _NodeTypes; 7943e519524SHoward Hinnant 7953e519524SHoward Hinnant allocator_type& __na_; 7963e519524SHoward Hinnant 7973e519524SHoward Hinnantpublic: 7983e519524SHoward Hinnant bool __value_constructed; 7993e519524SHoward Hinnant 800f97936faSEric Fiselier __hash_node_destructor(__hash_node_destructor const&) = default; 801f97936faSEric Fiselier __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; 802f97936faSEric Fiselier 803f97936faSEric Fiselier 80443d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 805f622b58cSHoward Hinnant explicit __hash_node_destructor(allocator_type& __na, 806f622b58cSHoward Hinnant bool __constructed = false) _NOEXCEPT 8073e519524SHoward Hinnant : __na_(__na), 808f622b58cSHoward Hinnant __value_constructed(__constructed) 8093e519524SHoward Hinnant {} 8103e519524SHoward Hinnant 81143d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 8123714107eSHoward Hinnant void operator()(pointer __p) _NOEXCEPT 8133e519524SHoward Hinnant { 8143e519524SHoward Hinnant if (__value_constructed) 815fcd02211SEric Fiselier __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); 8163e519524SHoward Hinnant if (__p) 8173e519524SHoward Hinnant __alloc_traits::deallocate(__na_, __p, 1); 8183e519524SHoward Hinnant } 8193e519524SHoward Hinnant 8203e519524SHoward Hinnant template <class> friend class __hash_map_node_destructor; 8213e519524SHoward Hinnant}; 8223e519524SHoward Hinnant 823b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14 824b0386a51SErik Pilkingtontemplate <class _NodeType, class _Alloc> 825b0386a51SErik Pilkingtonstruct __generic_container_node_destructor; 826b0386a51SErik Pilkington 827b0386a51SErik Pilkingtontemplate <class _Tp, class _VoidPtr, class _Alloc> 828b0386a51SErik Pilkingtonstruct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> 829b0386a51SErik Pilkington : __hash_node_destructor<_Alloc> 830b0386a51SErik Pilkington{ 831b0386a51SErik Pilkington using __hash_node_destructor<_Alloc>::__hash_node_destructor; 832b0386a51SErik Pilkington}; 833b0386a51SErik Pilkington#endif 83404333f9bSEric Fiselier 8353560fbf3SLouis Dionnetemplate <class _Key, class _Hash, class _Equal> 8363560fbf3SLouis Dionnestruct __enforce_unordered_container_requirements { 83704333f9bSEric Fiselier#ifndef _LIBCPP_CXX03_LANG 838bd6a2d85SEric Fiselier static_assert(__check_hash_requirements<_Key, _Hash>::value, 839bd6a2d85SEric Fiselier "the specified hash does not meet the Hash requirements"); 840acb21581SEric Fiselier static_assert(is_copy_constructible<_Equal>::value, 841acb21581SEric Fiselier "the specified comparator is required to be copy constructible"); 8423560fbf3SLouis Dionne#endif 8433560fbf3SLouis Dionne typedef int type; 84404333f9bSEric Fiselier}; 84504333f9bSEric Fiselier 8463560fbf3SLouis Dionnetemplate <class _Key, class _Hash, class _Equal> 8473560fbf3SLouis Dionne#ifndef _LIBCPP_CXX03_LANG 8483560fbf3SLouis Dionne _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, 8497c142fccSLouis Dionne "the specified comparator type does not provide a viable const call operator") 8503560fbf3SLouis Dionne _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, 8517c142fccSLouis Dionne "the specified hash functor does not provide a viable const call operator") 8523560fbf3SLouis Dionne#endif 8533560fbf3SLouis Dionnetypename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type 8543560fbf3SLouis Dionne__diagnose_unordered_container_requirements(int); 8553560fbf3SLouis Dionne 8563560fbf3SLouis Dionne// This dummy overload is used so that the compiler won't emit a spurious 8573560fbf3SLouis Dionne// "no matching function for call to __diagnose_unordered_xxx" diagnostic 8583560fbf3SLouis Dionne// when the overload above causes a hard error. 8593560fbf3SLouis Dionnetemplate <class _Key, class _Hash, class _Equal> 8603560fbf3SLouis Dionneint __diagnose_unordered_container_requirements(void*); 86104333f9bSEric Fiselier 8623e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 8633e519524SHoward Hinnantclass __hash_table 8643e519524SHoward Hinnant{ 8653e519524SHoward Hinnantpublic: 8663e519524SHoward Hinnant typedef _Tp value_type; 8673e519524SHoward Hinnant typedef _Hash hasher; 8683e519524SHoward Hinnant typedef _Equal key_equal; 8693e519524SHoward Hinnant typedef _Alloc allocator_type; 8703e519524SHoward Hinnant 8713e519524SHoward Hinnantprivate: 8723e519524SHoward Hinnant typedef allocator_traits<allocator_type> __alloc_traits; 87375d0dcfdSEric Fiselier typedef typename 87475d0dcfdSEric Fiselier __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type 87575d0dcfdSEric Fiselier _NodeTypes; 8763e519524SHoward Hinnantpublic: 877fcd02211SEric Fiselier 878fcd02211SEric Fiselier typedef typename _NodeTypes::__node_value_type __node_value_type; 879fcd02211SEric Fiselier typedef typename _NodeTypes::__container_value_type __container_value_type; 880fde79b40SDuncan P. N. Exon Smith typedef typename _NodeTypes::key_type key_type; 8813e519524SHoward Hinnant typedef value_type& reference; 8823e519524SHoward Hinnant typedef const value_type& const_reference; 8833e519524SHoward Hinnant typedef typename __alloc_traits::pointer pointer; 8843e519524SHoward Hinnant typedef typename __alloc_traits::const_pointer const_pointer; 88575d0dcfdSEric Fiselier#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE 8863e519524SHoward Hinnant typedef typename __alloc_traits::size_type size_type; 88775d0dcfdSEric Fiselier#else 88875d0dcfdSEric Fiselier typedef typename _NodeTypes::size_type size_type; 88975d0dcfdSEric Fiselier#endif 89075d0dcfdSEric Fiselier typedef typename _NodeTypes::difference_type difference_type; 8913e519524SHoward Hinnantpublic: 8923e519524SHoward Hinnant // Create __node 89375d0dcfdSEric Fiselier 89475d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_type __node; 8951f508014SMarshall Clow typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; 8963e519524SHoward Hinnant typedef allocator_traits<__node_allocator> __node_traits; 8978e39768cSEric Fiselier typedef typename _NodeTypes::__void_pointer __void_pointer; 89875d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_pointer __node_pointer; 89975d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_pointer __node_const_pointer; 90075d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_base_type __first_node; 90175d0dcfdSEric Fiselier typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 90240492ba4SEric Fiselier typedef typename _NodeTypes::__next_pointer __next_pointer; 90375d0dcfdSEric Fiselier 90475d0dcfdSEric Fiselierprivate: 90575d0dcfdSEric Fiselier // check for sane allocator pointer rebinding semantics. Rebinding the 90675d0dcfdSEric Fiselier // allocator for a new pointer type should be exactly the same as rebinding 90775d0dcfdSEric Fiselier // the pointer using 'pointer_traits'. 90875d0dcfdSEric Fiselier static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), 90975d0dcfdSEric Fiselier "Allocator does not rebind pointers in a sane manner."); 91075d0dcfdSEric Fiselier typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type 91175d0dcfdSEric Fiselier __node_base_allocator; 91275d0dcfdSEric Fiselier typedef allocator_traits<__node_base_allocator> __node_base_traits; 91375d0dcfdSEric Fiselier static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), 91475d0dcfdSEric Fiselier "Allocator does not rebind pointers in a sane manner."); 9153e519524SHoward Hinnant 9163e519524SHoward Hinnantprivate: 9173e519524SHoward Hinnant 91840492ba4SEric Fiselier typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator; 9193e519524SHoward Hinnant typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; 92040492ba4SEric Fiselier typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; 9213e519524SHoward Hinnant typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; 9223e519524SHoward Hinnant typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; 9233e519524SHoward Hinnant 9243e519524SHoward Hinnant // --- Member data begin --- 9253e519524SHoward Hinnant __bucket_list __bucket_list_; 9263e519524SHoward Hinnant __compressed_pair<__first_node, __node_allocator> __p1_; 9273e519524SHoward Hinnant __compressed_pair<size_type, hasher> __p2_; 9283e519524SHoward Hinnant __compressed_pair<float, key_equal> __p3_; 9293e519524SHoward Hinnant // --- Member data end --- 9303e519524SHoward Hinnant 9313714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9323714107eSHoward Hinnant size_type& size() _NOEXCEPT {return __p2_.first();} 9333e519524SHoward Hinnantpublic: 9343714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9353714107eSHoward Hinnant size_type size() const _NOEXCEPT {return __p2_.first();} 9363e519524SHoward Hinnant 9373714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9383714107eSHoward Hinnant hasher& hash_function() _NOEXCEPT {return __p2_.second();} 9393714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9403714107eSHoward Hinnant const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} 9413e519524SHoward Hinnant 9423714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9433714107eSHoward Hinnant float& max_load_factor() _NOEXCEPT {return __p3_.first();} 9443714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9453714107eSHoward Hinnant float max_load_factor() const _NOEXCEPT {return __p3_.first();} 9463e519524SHoward Hinnant 9473714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9483714107eSHoward Hinnant key_equal& key_eq() _NOEXCEPT {return __p3_.second();} 9493714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9503714107eSHoward Hinnant const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} 9513e519524SHoward Hinnant 9523714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9533714107eSHoward Hinnant __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} 9543714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 9553714107eSHoward Hinnant const __node_allocator& __node_alloc() const _NOEXCEPT 9563714107eSHoward Hinnant {return __p1_.second();} 9573e519524SHoward Hinnant 9583e519524SHoward Hinnantpublic: 9593e519524SHoward Hinnant typedef __hash_iterator<__node_pointer> iterator; 960307f8143SHoward Hinnant typedef __hash_const_iterator<__node_pointer> const_iterator; 9613e519524SHoward Hinnant typedef __hash_local_iterator<__node_pointer> local_iterator; 962307f8143SHoward Hinnant typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; 9633e519524SHoward Hinnant 964906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 9653714107eSHoward Hinnant __hash_table() 9663714107eSHoward Hinnant _NOEXCEPT_( 9673714107eSHoward Hinnant is_nothrow_default_constructible<__bucket_list>::value && 9683714107eSHoward Hinnant is_nothrow_default_constructible<__first_node>::value && 9693714107eSHoward Hinnant is_nothrow_default_constructible<__node_allocator>::value && 9703714107eSHoward Hinnant is_nothrow_default_constructible<hasher>::value && 9713714107eSHoward Hinnant is_nothrow_default_constructible<key_equal>::value); 972906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 9733e519524SHoward Hinnant __hash_table(const hasher& __hf, const key_equal& __eql); 9743e519524SHoward Hinnant __hash_table(const hasher& __hf, const key_equal& __eql, 9753e519524SHoward Hinnant const allocator_type& __a); 9763e519524SHoward Hinnant explicit __hash_table(const allocator_type& __a); 9773e519524SHoward Hinnant __hash_table(const __hash_table& __u); 9783e519524SHoward Hinnant __hash_table(const __hash_table& __u, const allocator_type& __a); 9793714107eSHoward Hinnant __hash_table(__hash_table&& __u) 9803714107eSHoward Hinnant _NOEXCEPT_( 9813714107eSHoward Hinnant is_nothrow_move_constructible<__bucket_list>::value && 9823714107eSHoward Hinnant is_nothrow_move_constructible<__first_node>::value && 9833714107eSHoward Hinnant is_nothrow_move_constructible<__node_allocator>::value && 9843714107eSHoward Hinnant is_nothrow_move_constructible<hasher>::value && 9853714107eSHoward Hinnant is_nothrow_move_constructible<key_equal>::value); 9863e519524SHoward Hinnant __hash_table(__hash_table&& __u, const allocator_type& __a); 9873e519524SHoward Hinnant ~__hash_table(); 9883e519524SHoward Hinnant 9893e519524SHoward Hinnant __hash_table& operator=(const __hash_table& __u); 990906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 9913714107eSHoward Hinnant __hash_table& operator=(__hash_table&& __u) 9923714107eSHoward Hinnant _NOEXCEPT_( 9933714107eSHoward Hinnant __node_traits::propagate_on_container_move_assignment::value && 9943714107eSHoward Hinnant is_nothrow_move_assignable<__node_allocator>::value && 9953714107eSHoward Hinnant is_nothrow_move_assignable<hasher>::value && 9963714107eSHoward Hinnant is_nothrow_move_assignable<key_equal>::value); 9973e519524SHoward Hinnant template <class _InputIterator> 9983e519524SHoward Hinnant void __assign_unique(_InputIterator __first, _InputIterator __last); 9993e519524SHoward Hinnant template <class _InputIterator> 10003e519524SHoward Hinnant void __assign_multi(_InputIterator __first, _InputIterator __last); 10013e519524SHoward Hinnant 100243d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 10033714107eSHoward Hinnant size_type max_size() const _NOEXCEPT 10043e519524SHoward Hinnant { 1005d586f92cSArthur O'Dwyer return _VSTD::min<size_type>( 1006341c9dd9SEric Fiselier __node_traits::max_size(__node_alloc()), 100755b31b4eSEric Fiselier numeric_limits<difference_type >::max() 100855b31b4eSEric Fiselier ); 10093e519524SHoward Hinnant } 10103e519524SHoward Hinnant 10115c4e07aeSErik Pilkingtonprivate: 10125c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10135c4e07aeSErik Pilkington __next_pointer __node_insert_multi_prepare(size_t __cp_hash, 10145c4e07aeSErik Pilkington value_type& __cp_val); 10155c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10165c4e07aeSErik Pilkington void __node_insert_multi_perform(__node_pointer __cp, 10175c4e07aeSErik Pilkington __next_pointer __pn) _NOEXCEPT; 10185c4e07aeSErik Pilkington 10195c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10205c4e07aeSErik Pilkington __next_pointer __node_insert_unique_prepare(size_t __nd_hash, 10215c4e07aeSErik Pilkington value_type& __nd_val); 10225c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10235c4e07aeSErik Pilkington void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; 10245c4e07aeSErik Pilkington 10255c4e07aeSErik Pilkingtonpublic: 10265c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10273e519524SHoward Hinnant pair<iterator, bool> __node_insert_unique(__node_pointer __nd); 10285c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10293e519524SHoward Hinnant iterator __node_insert_multi(__node_pointer __nd); 10305c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 10313e519524SHoward Hinnant iterator __node_insert_multi(const_iterator __p, 10323e519524SHoward Hinnant __node_pointer __nd); 10333e519524SHoward Hinnant 1034fcd02211SEric Fiselier template <class _Key, class ..._Args> 1035fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1036fcd02211SEric Fiselier pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args); 1037fcd02211SEric Fiselier 10383e519524SHoward Hinnant template <class... _Args> 1039fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1040fde79b40SDuncan P. N. Exon Smith pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); 1041fde79b40SDuncan P. N. Exon Smith 1042fde79b40SDuncan P. N. Exon Smith template <class _Pp> 1043fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1044fde79b40SDuncan P. N. Exon Smith pair<iterator, bool> __emplace_unique(_Pp&& __x) { 1045fde79b40SDuncan P. N. Exon Smith return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), 1046fde79b40SDuncan P. N. Exon Smith __can_extract_key<_Pp, key_type>()); 1047fde79b40SDuncan P. N. Exon Smith } 104850088684SEric Fiselier 104950088684SEric Fiselier template <class _First, class _Second> 105050088684SEric Fiselier _LIBCPP_INLINE_VISIBILITY 10514887d047SNikolas Klauser __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> > 10524887d047SNikolas Klauser __emplace_unique(_First&& __f, _Second&& __s) { 105350088684SEric Fiselier return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), 105450088684SEric Fiselier _VSTD::forward<_Second>(__s)); 105550088684SEric Fiselier } 105650088684SEric Fiselier 10573e519524SHoward Hinnant template <class... _Args> 1058fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1059fde79b40SDuncan P. N. Exon Smith pair<iterator, bool> __emplace_unique(_Args&&... __args) { 1060fde79b40SDuncan P. N. Exon Smith return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); 1061fde79b40SDuncan P. N. Exon Smith } 1062fde79b40SDuncan P. N. Exon Smith 1063fde79b40SDuncan P. N. Exon Smith template <class _Pp> 1064fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1065fde79b40SDuncan P. N. Exon Smith pair<iterator, bool> 1066fde79b40SDuncan P. N. Exon Smith __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { 1067fde79b40SDuncan P. N. Exon Smith return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); 1068fde79b40SDuncan P. N. Exon Smith } 1069fde79b40SDuncan P. N. Exon Smith template <class _Pp> 1070fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1071fde79b40SDuncan P. N. Exon Smith pair<iterator, bool> 1072fde79b40SDuncan P. N. Exon Smith __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { 1073fde79b40SDuncan P. N. Exon Smith return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); 1074fde79b40SDuncan P. N. Exon Smith } 1075fde79b40SDuncan P. N. Exon Smith template <class _Pp> 1076fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 1077fde79b40SDuncan P. N. Exon Smith pair<iterator, bool> 1078fde79b40SDuncan P. N. Exon Smith __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { 1079fde79b40SDuncan P. N. Exon Smith return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); 1080fde79b40SDuncan P. N. Exon Smith } 1081fde79b40SDuncan P. N. Exon Smith 1082fde79b40SDuncan P. N. Exon Smith template <class... _Args> 1083fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 10843e519524SHoward Hinnant iterator __emplace_multi(_Args&&... __args); 10853e519524SHoward Hinnant template <class... _Args> 1086fde79b40SDuncan P. N. Exon Smith _LIBCPP_INLINE_VISIBILITY 10873e519524SHoward Hinnant iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); 10883e519524SHoward Hinnant 1089fcd02211SEric Fiselier 1090de3f2b39SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1091fcd02211SEric Fiselier pair<iterator, bool> 1092fcd02211SEric Fiselier __insert_unique(__container_value_type&& __x) { 1093fcd02211SEric Fiselier return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); 1094fcd02211SEric Fiselier } 1095fcd02211SEric Fiselier 10964887d047SNikolas Klauser template <class _Pp, class = __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value> > 1097de3f2b39SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1098fcd02211SEric Fiselier pair<iterator, bool> __insert_unique(_Pp&& __x) { 1099fcd02211SEric Fiselier return __emplace_unique(_VSTD::forward<_Pp>(__x)); 1100fcd02211SEric Fiselier } 1101fcd02211SEric Fiselier 1102fcd02211SEric Fiselier template <class _Pp> 1103fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1104fcd02211SEric Fiselier iterator __insert_multi(_Pp&& __x) { 1105fcd02211SEric Fiselier return __emplace_multi(_VSTD::forward<_Pp>(__x)); 1106fcd02211SEric Fiselier } 1107fcd02211SEric Fiselier 1108fcd02211SEric Fiselier template <class _Pp> 1109fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1110fcd02211SEric Fiselier iterator __insert_multi(const_iterator __p, _Pp&& __x) { 1111fcd02211SEric Fiselier return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); 1112fcd02211SEric Fiselier } 1113fcd02211SEric Fiselier 1114fcd02211SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1115fcd02211SEric Fiselier pair<iterator, bool> __insert_unique(const __container_value_type& __x) { 1116fcd02211SEric Fiselier return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); 1117fcd02211SEric Fiselier } 11183e519524SHoward Hinnant 1119b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14 1120b0386a51SErik Pilkington template <class _NodeHandle, class _InsertReturnType> 1121b0386a51SErik Pilkington _LIBCPP_INLINE_VISIBILITY 1122b0386a51SErik Pilkington _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); 1123b0386a51SErik Pilkington template <class _NodeHandle> 1124b0386a51SErik Pilkington _LIBCPP_INLINE_VISIBILITY 1125b0386a51SErik Pilkington iterator __node_handle_insert_unique(const_iterator __hint, 1126b0386a51SErik Pilkington _NodeHandle&& __nh); 11275c4e07aeSErik Pilkington template <class _Table> 11285c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 11295c4e07aeSErik Pilkington void __node_handle_merge_unique(_Table& __source); 1130b0386a51SErik Pilkington 1131b0386a51SErik Pilkington template <class _NodeHandle> 1132b0386a51SErik Pilkington _LIBCPP_INLINE_VISIBILITY 1133b0386a51SErik Pilkington iterator __node_handle_insert_multi(_NodeHandle&& __nh); 1134b0386a51SErik Pilkington template <class _NodeHandle> 1135b0386a51SErik Pilkington _LIBCPP_INLINE_VISIBILITY 1136b0386a51SErik Pilkington iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); 11375c4e07aeSErik Pilkington template <class _Table> 11385c4e07aeSErik Pilkington _LIBCPP_INLINE_VISIBILITY 11395c4e07aeSErik Pilkington void __node_handle_merge_multi(_Table& __source); 1140b0386a51SErik Pilkington 1141b0386a51SErik Pilkington template <class _NodeHandle> 1142b0386a51SErik Pilkington _LIBCPP_INLINE_VISIBILITY 1143b0386a51SErik Pilkington _NodeHandle __node_handle_extract(key_type const& __key); 1144b0386a51SErik Pilkington template <class _NodeHandle> 1145b0386a51SErik Pilkington _LIBCPP_INLINE_VISIBILITY 1146b0386a51SErik Pilkington _NodeHandle __node_handle_extract(const_iterator __it); 1147b0386a51SErik Pilkington#endif 1148b0386a51SErik Pilkington 11493714107eSHoward Hinnant void clear() _NOEXCEPT; 11503085e42fSIvan Trofimov _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); } 11513085e42fSIvan Trofimov _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); } 11523085e42fSIvan Trofimov _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n) 11533085e42fSIvan Trofimov { 11543085e42fSIvan Trofimov __rehash_unique(static_cast<size_type>(ceil(__n / max_load_factor()))); 11553085e42fSIvan Trofimov } 11563085e42fSIvan Trofimov _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n) 11573085e42fSIvan Trofimov { 11583085e42fSIvan Trofimov __rehash_multi(static_cast<size_type>(ceil(__n / max_load_factor()))); 11593085e42fSIvan Trofimov } 116043d99238SHoward Hinnant 116143d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 11623714107eSHoward Hinnant size_type bucket_count() const _NOEXCEPT 11633e519524SHoward Hinnant { 11643e519524SHoward Hinnant return __bucket_list_.get_deleter().size(); 11653e519524SHoward Hinnant } 11663e519524SHoward Hinnant 1167906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 11683714107eSHoward Hinnant iterator begin() _NOEXCEPT; 1169906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 11703714107eSHoward Hinnant iterator end() _NOEXCEPT; 1171906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 11723714107eSHoward Hinnant const_iterator begin() const _NOEXCEPT; 1173906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 11743714107eSHoward Hinnant const_iterator end() const _NOEXCEPT; 11753e519524SHoward Hinnant 11763e519524SHoward Hinnant template <class _Key> 117743d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 11783e519524SHoward Hinnant size_type bucket(const _Key& __k) const 1179e5c13decSHoward Hinnant { 1180e5c13decSHoward Hinnant _LIBCPP_ASSERT(bucket_count() > 0, 1181e5c13decSHoward Hinnant "unordered container::bucket(key) called when bucket_count() == 0"); 1182e5c13decSHoward Hinnant return __constrain_hash(hash_function()(__k), bucket_count()); 1183e5c13decSHoward Hinnant } 11843e519524SHoward Hinnant 11853e519524SHoward Hinnant template <class _Key> 11863e519524SHoward Hinnant iterator find(const _Key& __x); 11873e519524SHoward Hinnant template <class _Key> 11883e519524SHoward Hinnant const_iterator find(const _Key& __x) const; 11893e519524SHoward Hinnant 1190c003db1fSHoward Hinnant typedef __hash_node_destructor<__node_allocator> _Dp; 1191c003db1fSHoward Hinnant typedef unique_ptr<__node, _Dp> __node_holder; 11923e519524SHoward Hinnant 11933e519524SHoward Hinnant iterator erase(const_iterator __p); 11943e519524SHoward Hinnant iterator erase(const_iterator __first, const_iterator __last); 11953e519524SHoward Hinnant template <class _Key> 11963e519524SHoward Hinnant size_type __erase_unique(const _Key& __k); 11973e519524SHoward Hinnant template <class _Key> 11983e519524SHoward Hinnant size_type __erase_multi(const _Key& __k); 11993714107eSHoward Hinnant __node_holder remove(const_iterator __p) _NOEXCEPT; 12003e519524SHoward Hinnant 12013e519524SHoward Hinnant template <class _Key> 1202906c872dSEvgeniy Stepanov _LIBCPP_INLINE_VISIBILITY 12033e519524SHoward Hinnant size_type __count_unique(const _Key& __k) const; 12043e519524SHoward Hinnant template <class _Key> 12053e519524SHoward Hinnant size_type __count_multi(const _Key& __k) const; 12063e519524SHoward Hinnant 12073e519524SHoward Hinnant template <class _Key> 12083e519524SHoward Hinnant pair<iterator, iterator> 12093e519524SHoward Hinnant __equal_range_unique(const _Key& __k); 12103e519524SHoward Hinnant template <class _Key> 12113e519524SHoward Hinnant pair<const_iterator, const_iterator> 12123e519524SHoward Hinnant __equal_range_unique(const _Key& __k) const; 12133e519524SHoward Hinnant 12143e519524SHoward Hinnant template <class _Key> 12153e519524SHoward Hinnant pair<iterator, iterator> 12163e519524SHoward Hinnant __equal_range_multi(const _Key& __k); 12173e519524SHoward Hinnant template <class _Key> 12183e519524SHoward Hinnant pair<const_iterator, const_iterator> 12193e519524SHoward Hinnant __equal_range_multi(const _Key& __k) const; 12203e519524SHoward Hinnant 12213714107eSHoward Hinnant void swap(__hash_table& __u) 122287a82490SEric Fiselier#if _LIBCPP_STD_VER <= 11 122361b302f9SEric Fiselier _NOEXCEPT_( 1224e3fbe143SMarshall Clow __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value 1225e3fbe143SMarshall Clow && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value 1226e3fbe143SMarshall Clow || __is_nothrow_swappable<__pointer_allocator>::value) 1227e3fbe143SMarshall Clow && (!__node_traits::propagate_on_container_swap::value 1228e3fbe143SMarshall Clow || __is_nothrow_swappable<__node_allocator>::value) 1229e3fbe143SMarshall Clow ); 123087a82490SEric Fiselier#else 123161b302f9SEric Fiselier _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value); 123287a82490SEric Fiselier#endif 12333e519524SHoward Hinnant 123443d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 12353714107eSHoward Hinnant size_type max_bucket_count() const _NOEXCEPT 123655b31b4eSEric Fiselier {return max_size(); } 12373e519524SHoward Hinnant size_type bucket_size(size_type __n) const; 12383714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT 12393e519524SHoward Hinnant { 12403e519524SHoward Hinnant size_type __bc = bucket_count(); 12413e519524SHoward Hinnant return __bc != 0 ? (float)size() / __bc : 0.f; 12423e519524SHoward Hinnant } 12433714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT 1244e5c13decSHoward Hinnant { 1245e5c13decSHoward Hinnant _LIBCPP_ASSERT(__mlf > 0, 1246e5c13decSHoward Hinnant "unordered container::max_load_factor(lf) called with lf <= 0"); 1247e5c13decSHoward Hinnant max_load_factor() = _VSTD::max(__mlf, load_factor()); 1248e5c13decSHoward Hinnant } 12493e519524SHoward Hinnant 1250b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1251b24c8024SHoward Hinnant local_iterator 1252b24c8024SHoward Hinnant begin(size_type __n) 1253b24c8024SHoward Hinnant { 1254e5c13decSHoward Hinnant _LIBCPP_ASSERT(__n < bucket_count(), 1255e5c13decSHoward Hinnant "unordered container::begin(n) called with n >= bucket_count()"); 1256b24c8024SHoward Hinnant return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); 1257b24c8024SHoward Hinnant } 1258b24c8024SHoward Hinnant 1259b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1260b24c8024SHoward Hinnant local_iterator 1261b24c8024SHoward Hinnant end(size_type __n) 1262b24c8024SHoward Hinnant { 1263e5c13decSHoward Hinnant _LIBCPP_ASSERT(__n < bucket_count(), 1264e5c13decSHoward Hinnant "unordered container::end(n) called with n >= bucket_count()"); 1265b24c8024SHoward Hinnant return local_iterator(nullptr, __n, bucket_count(), this); 1266b24c8024SHoward Hinnant } 1267b24c8024SHoward Hinnant 1268b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1269b24c8024SHoward Hinnant const_local_iterator 1270b24c8024SHoward Hinnant cbegin(size_type __n) const 1271b24c8024SHoward Hinnant { 1272e5c13decSHoward Hinnant _LIBCPP_ASSERT(__n < bucket_count(), 1273e5c13decSHoward Hinnant "unordered container::cbegin(n) called with n >= bucket_count()"); 1274b24c8024SHoward Hinnant return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); 1275b24c8024SHoward Hinnant } 1276b24c8024SHoward Hinnant 1277b24c8024SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1278b24c8024SHoward Hinnant const_local_iterator 1279b24c8024SHoward Hinnant cend(size_type __n) const 1280b24c8024SHoward Hinnant { 1281e5c13decSHoward Hinnant _LIBCPP_ASSERT(__n < bucket_count(), 1282e5c13decSHoward Hinnant "unordered container::cend(n) called with n >= bucket_count()"); 1283b24c8024SHoward Hinnant return const_local_iterator(nullptr, __n, bucket_count(), this); 1284b24c8024SHoward Hinnant } 1285b24c8024SHoward Hinnant 1286f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 1287b24c8024SHoward Hinnant 1288b24c8024SHoward Hinnant bool __dereferenceable(const const_iterator* __i) const; 1289b24c8024SHoward Hinnant bool __decrementable(const const_iterator* __i) const; 1290b24c8024SHoward Hinnant bool __addable(const const_iterator* __i, ptrdiff_t __n) const; 1291b24c8024SHoward Hinnant bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; 1292b24c8024SHoward Hinnant 1293f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE 1294b24c8024SHoward Hinnant 12953e519524SHoward Hinnantprivate: 12963085e42fSIvan Trofimov template <bool _UniqueKeys> void __rehash(size_type __n); 12973085e42fSIvan Trofimov template <bool _UniqueKeys> void __do_rehash(size_type __n); 12983e519524SHoward Hinnant 12993e519524SHoward Hinnant template <class ..._Args> 13003e519524SHoward Hinnant __node_holder __construct_node(_Args&& ...__args); 1301fcd02211SEric Fiselier 1302fcd02211SEric Fiselier template <class _First, class ..._Rest> 1303fcd02211SEric Fiselier __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); 1304fcd02211SEric Fiselier 13053e519524SHoward Hinnant 130643d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 13073e519524SHoward Hinnant void __copy_assign_alloc(const __hash_table& __u) 13083e519524SHoward Hinnant {__copy_assign_alloc(__u, integral_constant<bool, 13093e519524SHoward Hinnant __node_traits::propagate_on_container_copy_assignment::value>());} 13103e519524SHoward Hinnant void __copy_assign_alloc(const __hash_table& __u, true_type); 131143d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1312c206366fSHoward Hinnant void __copy_assign_alloc(const __hash_table&, false_type) {} 13133e519524SHoward Hinnant 13143e519524SHoward Hinnant void __move_assign(__hash_table& __u, false_type); 13153714107eSHoward Hinnant void __move_assign(__hash_table& __u, true_type) 13163714107eSHoward Hinnant _NOEXCEPT_( 13173714107eSHoward Hinnant is_nothrow_move_assignable<__node_allocator>::value && 13183714107eSHoward Hinnant is_nothrow_move_assignable<hasher>::value && 13193714107eSHoward Hinnant is_nothrow_move_assignable<key_equal>::value); 13203714107eSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 13213714107eSHoward Hinnant void __move_assign_alloc(__hash_table& __u) 13223714107eSHoward Hinnant _NOEXCEPT_( 13233714107eSHoward Hinnant !__node_traits::propagate_on_container_move_assignment::value || 13243714107eSHoward Hinnant (is_nothrow_move_assignable<__pointer_allocator>::value && 13253714107eSHoward Hinnant is_nothrow_move_assignable<__node_allocator>::value)) 13263e519524SHoward Hinnant {__move_assign_alloc(__u, integral_constant<bool, 13273e519524SHoward Hinnant __node_traits::propagate_on_container_move_assignment::value>());} 132843d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 13293e519524SHoward Hinnant void __move_assign_alloc(__hash_table& __u, true_type) 13303714107eSHoward Hinnant _NOEXCEPT_( 13313714107eSHoward Hinnant is_nothrow_move_assignable<__pointer_allocator>::value && 13323714107eSHoward Hinnant is_nothrow_move_assignable<__node_allocator>::value) 13333e519524SHoward Hinnant { 13343e519524SHoward Hinnant __bucket_list_.get_deleter().__alloc() = 1335ce48a113SHoward Hinnant _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); 1336ce48a113SHoward Hinnant __node_alloc() = _VSTD::move(__u.__node_alloc()); 13373e519524SHoward Hinnant } 133843d99238SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 13393714107eSHoward Hinnant void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} 13403e519524SHoward Hinnant 1341cd71f447SEric Fiselier void __deallocate_node(__next_pointer __np) _NOEXCEPT; 134240492ba4SEric Fiselier __next_pointer __detach() _NOEXCEPT; 1343307f8143SHoward Hinnant 1344e2f2d1edSEric Fiselier template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 1345e2f2d1edSEric Fiselier template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 13463e519524SHoward Hinnant}; 13473e519524SHoward Hinnant 13483e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1349906c872dSEvgeniy Stepanovinline 13503e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() 13513714107eSHoward Hinnant _NOEXCEPT_( 13523714107eSHoward Hinnant is_nothrow_default_constructible<__bucket_list>::value && 13533714107eSHoward Hinnant is_nothrow_default_constructible<__first_node>::value && 1354e2e332a5SEric Fiselier is_nothrow_default_constructible<__node_allocator>::value && 13553714107eSHoward Hinnant is_nothrow_default_constructible<hasher>::value && 13563714107eSHoward Hinnant is_nothrow_default_constructible<key_equal>::value) 1357549545b6SEric Fiselier : __p2_(0, __default_init_tag()), 1358549545b6SEric Fiselier __p3_(1.0f, __default_init_tag()) 13593e519524SHoward Hinnant{ 13603e519524SHoward Hinnant} 13613e519524SHoward Hinnant 13623e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1363906c872dSEvgeniy Stepanovinline 13643e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, 13653e519524SHoward Hinnant const key_equal& __eql) 13663e519524SHoward Hinnant : __bucket_list_(nullptr, __bucket_list_deleter()), 13673e519524SHoward Hinnant __p1_(), 13683e519524SHoward Hinnant __p2_(0, __hf), 13693e519524SHoward Hinnant __p3_(1.0f, __eql) 13703e519524SHoward Hinnant{ 13713e519524SHoward Hinnant} 13723e519524SHoward Hinnant 13733e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 13743e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, 13753e519524SHoward Hinnant const key_equal& __eql, 13763e519524SHoward Hinnant const allocator_type& __a) 13773e519524SHoward Hinnant : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1378549545b6SEric Fiselier __p1_(__default_init_tag(), __node_allocator(__a)), 13793e519524SHoward Hinnant __p2_(0, __hf), 13803e519524SHoward Hinnant __p3_(1.0f, __eql) 13813e519524SHoward Hinnant{ 13823e519524SHoward Hinnant} 13833e519524SHoward Hinnant 13843e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 13853e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) 13863e519524SHoward Hinnant : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1387549545b6SEric Fiselier __p1_(__default_init_tag(), __node_allocator(__a)), 1388549545b6SEric Fiselier __p2_(0, __default_init_tag()), 1389549545b6SEric Fiselier __p3_(1.0f, __default_init_tag()) 13903e519524SHoward Hinnant{ 13913e519524SHoward Hinnant} 13923e519524SHoward Hinnant 13933e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 13943e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) 13953e519524SHoward Hinnant : __bucket_list_(nullptr, 13963e519524SHoward Hinnant __bucket_list_deleter(allocator_traits<__pointer_allocator>:: 13973e519524SHoward Hinnant select_on_container_copy_construction( 13983e519524SHoward Hinnant __u.__bucket_list_.get_deleter().__alloc()), 0)), 1399549545b6SEric Fiselier __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: 14003e519524SHoward Hinnant select_on_container_copy_construction(__u.__node_alloc())), 14013e519524SHoward Hinnant __p2_(0, __u.hash_function()), 14023e519524SHoward Hinnant __p3_(__u.__p3_) 14033e519524SHoward Hinnant{ 14043e519524SHoward Hinnant} 14053e519524SHoward Hinnant 14063e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 14073e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, 14083e519524SHoward Hinnant const allocator_type& __a) 14093e519524SHoward Hinnant : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1410549545b6SEric Fiselier __p1_(__default_init_tag(), __node_allocator(__a)), 14113e519524SHoward Hinnant __p2_(0, __u.hash_function()), 14123e519524SHoward Hinnant __p3_(__u.__p3_) 14133e519524SHoward Hinnant{ 14143e519524SHoward Hinnant} 14153e519524SHoward Hinnant 14163e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 14173e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) 14183714107eSHoward Hinnant _NOEXCEPT_( 14193714107eSHoward Hinnant is_nothrow_move_constructible<__bucket_list>::value && 14203714107eSHoward Hinnant is_nothrow_move_constructible<__first_node>::value && 1421e2e332a5SEric Fiselier is_nothrow_move_constructible<__node_allocator>::value && 14223714107eSHoward Hinnant is_nothrow_move_constructible<hasher>::value && 14233714107eSHoward Hinnant is_nothrow_move_constructible<key_equal>::value) 1424ce48a113SHoward Hinnant : __bucket_list_(_VSTD::move(__u.__bucket_list_)), 1425ce48a113SHoward Hinnant __p1_(_VSTD::move(__u.__p1_)), 1426ce48a113SHoward Hinnant __p2_(_VSTD::move(__u.__p2_)), 1427ce48a113SHoward Hinnant __p3_(_VSTD::move(__u.__p3_)) 14283e519524SHoward Hinnant{ 14293e519524SHoward Hinnant if (size() > 0) 14303e519524SHoward Hinnant { 143140492ba4SEric Fiselier __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 143240492ba4SEric Fiselier __p1_.first().__ptr(); 14333e519524SHoward Hinnant __u.__p1_.first().__next_ = nullptr; 14343e519524SHoward Hinnant __u.size() = 0; 14353e519524SHoward Hinnant } 14363e519524SHoward Hinnant} 14373e519524SHoward Hinnant 14383e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 14393e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, 14403e519524SHoward Hinnant const allocator_type& __a) 14413e519524SHoward Hinnant : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1442549545b6SEric Fiselier __p1_(__default_init_tag(), __node_allocator(__a)), 1443ce48a113SHoward Hinnant __p2_(0, _VSTD::move(__u.hash_function())), 1444ce48a113SHoward Hinnant __p3_(_VSTD::move(__u.__p3_)) 14453e519524SHoward Hinnant{ 14463e519524SHoward Hinnant if (__a == allocator_type(__u.__node_alloc())) 14473e519524SHoward Hinnant { 14483e519524SHoward Hinnant __bucket_list_.reset(__u.__bucket_list_.release()); 14493e519524SHoward Hinnant __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); 14503e519524SHoward Hinnant __u.__bucket_list_.get_deleter().size() = 0; 14513e519524SHoward Hinnant if (__u.size() > 0) 14523e519524SHoward Hinnant { 14533e519524SHoward Hinnant __p1_.first().__next_ = __u.__p1_.first().__next_; 14543e519524SHoward Hinnant __u.__p1_.first().__next_ = nullptr; 145540492ba4SEric Fiselier __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 145640492ba4SEric Fiselier __p1_.first().__ptr(); 14573e519524SHoward Hinnant size() = __u.size(); 14583e519524SHoward Hinnant __u.size() = 0; 14593e519524SHoward Hinnant } 14603e519524SHoward Hinnant } 14613e519524SHoward Hinnant} 14623e519524SHoward Hinnant 14633e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 14643e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() 14653e519524SHoward Hinnant{ 1466acb21581SEric Fiselier#if defined(_LIBCPP_CXX03_LANG) 14673b8669edSMarshall Clow static_assert((is_copy_constructible<key_equal>::value), 14683b8669edSMarshall Clow "Predicate must be copy-constructible."); 14693b8669edSMarshall Clow static_assert((is_copy_constructible<hasher>::value), 14703b8669edSMarshall Clow "Hasher must be copy-constructible."); 147104333f9bSEric Fiselier#endif 1472acb21581SEric Fiselier 1473cd71f447SEric Fiselier __deallocate_node(__p1_.first().__next_); 147408f68dfeSNikolas Klauser std::__debug_db_erase_c(this); 14753e519524SHoward Hinnant} 14763e519524SHoward Hinnant 14773e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 14783e519524SHoward Hinnantvoid 14793e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( 14803e519524SHoward Hinnant const __hash_table& __u, true_type) 14813e519524SHoward Hinnant{ 14823e519524SHoward Hinnant if (__node_alloc() != __u.__node_alloc()) 14833e519524SHoward Hinnant { 14843e519524SHoward Hinnant clear(); 14853e519524SHoward Hinnant __bucket_list_.reset(); 14863e519524SHoward Hinnant __bucket_list_.get_deleter().size() = 0; 14873e519524SHoward Hinnant } 14883e519524SHoward Hinnant __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); 14893e519524SHoward Hinnant __node_alloc() = __u.__node_alloc(); 14903e519524SHoward Hinnant} 14913e519524SHoward Hinnant 14923e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 14933e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>& 14943e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) 14953e519524SHoward Hinnant{ 1496b8608b87SMark de Wever if (this != _VSTD::addressof(__u)) 14973e519524SHoward Hinnant { 14983e519524SHoward Hinnant __copy_assign_alloc(__u); 14993e519524SHoward Hinnant hash_function() = __u.hash_function(); 15003e519524SHoward Hinnant key_eq() = __u.key_eq(); 15013e519524SHoward Hinnant max_load_factor() = __u.max_load_factor(); 15023e519524SHoward Hinnant __assign_multi(__u.begin(), __u.end()); 15033e519524SHoward Hinnant } 15043e519524SHoward Hinnant return *this; 15053e519524SHoward Hinnant} 15063e519524SHoward Hinnant 15073e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 15083e519524SHoward Hinnantvoid 1509cd71f447SEric Fiselier__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) 15103714107eSHoward Hinnant _NOEXCEPT 15113e519524SHoward Hinnant{ 15123e519524SHoward Hinnant __node_allocator& __na = __node_alloc(); 15133e519524SHoward Hinnant while (__np != nullptr) 15143e519524SHoward Hinnant { 151540492ba4SEric Fiselier __next_pointer __next = __np->__next_; 1516f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 1517b24c8024SHoward Hinnant __c_node* __c = __get_db()->__find_c_and_lock(this); 1518b24c8024SHoward Hinnant for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1519b24c8024SHoward Hinnant { 1520b24c8024SHoward Hinnant --__p; 1521b24c8024SHoward Hinnant iterator* __i = static_cast<iterator*>((*__p)->__i_); 1522b24c8024SHoward Hinnant if (__i->__node_ == __np) 1523b24c8024SHoward Hinnant { 1524b24c8024SHoward Hinnant (*__p)->__c_ = nullptr; 1525b24c8024SHoward Hinnant if (--__c->end_ != __p) 15263696227cSArthur O'Dwyer _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1527b24c8024SHoward Hinnant } 1528b24c8024SHoward Hinnant } 1529b24c8024SHoward Hinnant __get_db()->unlock(); 1530b24c8024SHoward Hinnant#endif 153140492ba4SEric Fiselier __node_pointer __real_np = __np->__upcast(); 153240492ba4SEric Fiselier __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); 153340492ba4SEric Fiselier __node_traits::deallocate(__na, __real_np, 1); 15343e519524SHoward Hinnant __np = __next; 15353e519524SHoward Hinnant } 15363e519524SHoward Hinnant} 15373e519524SHoward Hinnant 15383e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 153940492ba4SEric Fiseliertypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 15403714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT 15413e519524SHoward Hinnant{ 15423e519524SHoward Hinnant size_type __bc = bucket_count(); 15433e519524SHoward Hinnant for (size_type __i = 0; __i < __bc; ++__i) 15443e519524SHoward Hinnant __bucket_list_[__i] = nullptr; 15453e519524SHoward Hinnant size() = 0; 154640492ba4SEric Fiselier __next_pointer __cache = __p1_.first().__next_; 15473e519524SHoward Hinnant __p1_.first().__next_ = nullptr; 15483e519524SHoward Hinnant return __cache; 15493e519524SHoward Hinnant} 15503e519524SHoward Hinnant 15513e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 15523e519524SHoward Hinnantvoid 15533e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( 15543e519524SHoward Hinnant __hash_table& __u, true_type) 15553714107eSHoward Hinnant _NOEXCEPT_( 15563714107eSHoward Hinnant is_nothrow_move_assignable<__node_allocator>::value && 15573714107eSHoward Hinnant is_nothrow_move_assignable<hasher>::value && 15583714107eSHoward Hinnant is_nothrow_move_assignable<key_equal>::value) 15593e519524SHoward Hinnant{ 15603e519524SHoward Hinnant clear(); 15613e519524SHoward Hinnant __bucket_list_.reset(__u.__bucket_list_.release()); 15623e519524SHoward Hinnant __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); 15633e519524SHoward Hinnant __u.__bucket_list_.get_deleter().size() = 0; 15643e519524SHoward Hinnant __move_assign_alloc(__u); 15653e519524SHoward Hinnant size() = __u.size(); 1566ce48a113SHoward Hinnant hash_function() = _VSTD::move(__u.hash_function()); 15673e519524SHoward Hinnant max_load_factor() = __u.max_load_factor(); 1568ce48a113SHoward Hinnant key_eq() = _VSTD::move(__u.key_eq()); 15693e519524SHoward Hinnant __p1_.first().__next_ = __u.__p1_.first().__next_; 15703e519524SHoward Hinnant if (size() > 0) 15713e519524SHoward Hinnant { 157240492ba4SEric Fiselier __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 157340492ba4SEric Fiselier __p1_.first().__ptr(); 15743e519524SHoward Hinnant __u.__p1_.first().__next_ = nullptr; 15753e519524SHoward Hinnant __u.size() = 0; 15763e519524SHoward Hinnant } 157708f68dfeSNikolas Klauser std::__debug_db_swap(this, std::addressof(__u)); 15783e519524SHoward Hinnant} 15793e519524SHoward Hinnant 15803e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 15813e519524SHoward Hinnantvoid 15823e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( 15833e519524SHoward Hinnant __hash_table& __u, false_type) 15843e519524SHoward Hinnant{ 15853e519524SHoward Hinnant if (__node_alloc() == __u.__node_alloc()) 15863e519524SHoward Hinnant __move_assign(__u, true_type()); 15873e519524SHoward Hinnant else 15883e519524SHoward Hinnant { 1589ce48a113SHoward Hinnant hash_function() = _VSTD::move(__u.hash_function()); 1590ce48a113SHoward Hinnant key_eq() = _VSTD::move(__u.key_eq()); 15913e519524SHoward Hinnant max_load_factor() = __u.max_load_factor(); 15923e519524SHoward Hinnant if (bucket_count() != 0) 15933e519524SHoward Hinnant { 159440492ba4SEric Fiselier __next_pointer __cache = __detach(); 15953e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 15963e519524SHoward Hinnant try 15973e519524SHoward Hinnant { 1598b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 15993e519524SHoward Hinnant const_iterator __i = __u.begin(); 16003e519524SHoward Hinnant while (__cache != nullptr && __u.size() != 0) 16013e519524SHoward Hinnant { 160240492ba4SEric Fiselier __cache->__upcast()->__value_ = 160340492ba4SEric Fiselier _VSTD::move(__u.remove(__i++)->__value_); 160440492ba4SEric Fiselier __next_pointer __next = __cache->__next_; 160540492ba4SEric Fiselier __node_insert_multi(__cache->__upcast()); 16063e519524SHoward Hinnant __cache = __next; 16073e519524SHoward Hinnant } 16083e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 16093e519524SHoward Hinnant } 16103e519524SHoward Hinnant catch (...) 16113e519524SHoward Hinnant { 1612cd71f447SEric Fiselier __deallocate_node(__cache); 16133e519524SHoward Hinnant throw; 16143e519524SHoward Hinnant } 1615b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 1616cd71f447SEric Fiselier __deallocate_node(__cache); 16173e519524SHoward Hinnant } 16183e519524SHoward Hinnant const_iterator __i = __u.begin(); 16193e519524SHoward Hinnant while (__u.size() != 0) 16203e519524SHoward Hinnant { 1621fcd02211SEric Fiselier __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); 16223e519524SHoward Hinnant __node_insert_multi(__h.get()); 16233e519524SHoward Hinnant __h.release(); 16243e519524SHoward Hinnant } 16253e519524SHoward Hinnant } 16263e519524SHoward Hinnant} 16273e519524SHoward Hinnant 16283e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1629906c872dSEvgeniy Stepanovinline 16303e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>& 16313e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) 16323714107eSHoward Hinnant _NOEXCEPT_( 16333714107eSHoward Hinnant __node_traits::propagate_on_container_move_assignment::value && 16343714107eSHoward Hinnant is_nothrow_move_assignable<__node_allocator>::value && 16353714107eSHoward Hinnant is_nothrow_move_assignable<hasher>::value && 16363714107eSHoward Hinnant is_nothrow_move_assignable<key_equal>::value) 16373e519524SHoward Hinnant{ 16383e519524SHoward Hinnant __move_assign(__u, integral_constant<bool, 16393e519524SHoward Hinnant __node_traits::propagate_on_container_move_assignment::value>()); 16403e519524SHoward Hinnant return *this; 16413e519524SHoward Hinnant} 16423e519524SHoward Hinnant 16433e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 16443e519524SHoward Hinnanttemplate <class _InputIterator> 16453e519524SHoward Hinnantvoid 16463e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, 16473e519524SHoward Hinnant _InputIterator __last) 16483e519524SHoward Hinnant{ 1649fcd02211SEric Fiselier typedef iterator_traits<_InputIterator> _ITraits; 1650fcd02211SEric Fiselier typedef typename _ITraits::value_type _ItValueType; 1651fcd02211SEric Fiselier static_assert((is_same<_ItValueType, __container_value_type>::value), 1652fcd02211SEric Fiselier "__assign_unique may only be called with the containers value type"); 1653fcd02211SEric Fiselier 16543e519524SHoward Hinnant if (bucket_count() != 0) 16553e519524SHoward Hinnant { 165640492ba4SEric Fiselier __next_pointer __cache = __detach(); 16573e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 16583e519524SHoward Hinnant try 16593e519524SHoward Hinnant { 1660b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 16613e519524SHoward Hinnant for (; __cache != nullptr && __first != __last; ++__first) 16623e519524SHoward Hinnant { 166340492ba4SEric Fiselier __cache->__upcast()->__value_ = *__first; 166440492ba4SEric Fiselier __next_pointer __next = __cache->__next_; 166540492ba4SEric Fiselier __node_insert_unique(__cache->__upcast()); 16663e519524SHoward Hinnant __cache = __next; 16673e519524SHoward Hinnant } 16683e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 16693e519524SHoward Hinnant } 16703e519524SHoward Hinnant catch (...) 16713e519524SHoward Hinnant { 1672cd71f447SEric Fiselier __deallocate_node(__cache); 16733e519524SHoward Hinnant throw; 16743e519524SHoward Hinnant } 1675b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 1676cd71f447SEric Fiselier __deallocate_node(__cache); 16773e519524SHoward Hinnant } 16783e519524SHoward Hinnant for (; __first != __last; ++__first) 16793e519524SHoward Hinnant __insert_unique(*__first); 16803e519524SHoward Hinnant} 16813e519524SHoward Hinnant 16823e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 16833e519524SHoward Hinnanttemplate <class _InputIterator> 16843e519524SHoward Hinnantvoid 16853e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, 16863e519524SHoward Hinnant _InputIterator __last) 16873e519524SHoward Hinnant{ 1688fcd02211SEric Fiselier typedef iterator_traits<_InputIterator> _ITraits; 1689fcd02211SEric Fiselier typedef typename _ITraits::value_type _ItValueType; 1690fcd02211SEric Fiselier static_assert((is_same<_ItValueType, __container_value_type>::value || 1691fcd02211SEric Fiselier is_same<_ItValueType, __node_value_type>::value), 1692fcd02211SEric Fiselier "__assign_multi may only be called with the containers value type" 1693fcd02211SEric Fiselier " or the nodes value type"); 16943e519524SHoward Hinnant if (bucket_count() != 0) 16953e519524SHoward Hinnant { 169640492ba4SEric Fiselier __next_pointer __cache = __detach(); 16973e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 16983e519524SHoward Hinnant try 16993e519524SHoward Hinnant { 1700b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 17013e519524SHoward Hinnant for (; __cache != nullptr && __first != __last; ++__first) 17023e519524SHoward Hinnant { 170340492ba4SEric Fiselier __cache->__upcast()->__value_ = *__first; 170440492ba4SEric Fiselier __next_pointer __next = __cache->__next_; 170540492ba4SEric Fiselier __node_insert_multi(__cache->__upcast()); 17063e519524SHoward Hinnant __cache = __next; 17073e519524SHoward Hinnant } 17083e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 17093e519524SHoward Hinnant } 17103e519524SHoward Hinnant catch (...) 17113e519524SHoward Hinnant { 1712cd71f447SEric Fiselier __deallocate_node(__cache); 17133e519524SHoward Hinnant throw; 17143e519524SHoward Hinnant } 1715b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS 1716cd71f447SEric Fiselier __deallocate_node(__cache); 17173e519524SHoward Hinnant } 17183e519524SHoward Hinnant for (; __first != __last; ++__first) 1719fcd02211SEric Fiselier __insert_multi(_NodeTypes::__get_value(*__first)); 17203e519524SHoward Hinnant} 17213e519524SHoward Hinnant 17223e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1723906c872dSEvgeniy Stepanovinline 17243e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 17253714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT 17263e519524SHoward Hinnant{ 1727b24c8024SHoward Hinnant return iterator(__p1_.first().__next_, this); 17283e519524SHoward Hinnant} 17293e519524SHoward Hinnant 17303e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1731906c872dSEvgeniy Stepanovinline 17323e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 17333714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT 17343e519524SHoward Hinnant{ 1735b24c8024SHoward Hinnant return iterator(nullptr, this); 17363e519524SHoward Hinnant} 17373e519524SHoward Hinnant 17383e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1739906c872dSEvgeniy Stepanovinline 17403e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 17413714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT 17423e519524SHoward Hinnant{ 1743b24c8024SHoward Hinnant return const_iterator(__p1_.first().__next_, this); 17443e519524SHoward Hinnant} 17453e519524SHoward Hinnant 17463e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1747906c872dSEvgeniy Stepanovinline 17483e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 17493714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT 17503e519524SHoward Hinnant{ 1751b24c8024SHoward Hinnant return const_iterator(nullptr, this); 17523e519524SHoward Hinnant} 17533e519524SHoward Hinnant 17543e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 17553e519524SHoward Hinnantvoid 17563714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT 17573e519524SHoward Hinnant{ 17583e519524SHoward Hinnant if (size() > 0) 17593e519524SHoward Hinnant { 1760cd71f447SEric Fiselier __deallocate_node(__p1_.first().__next_); 17613e519524SHoward Hinnant __p1_.first().__next_ = nullptr; 17623e519524SHoward Hinnant size_type __bc = bucket_count(); 17631f8da84bSHoward Hinnant for (size_type __i = 0; __i < __bc; ++__i) 17643e519524SHoward Hinnant __bucket_list_[__i] = nullptr; 17653e519524SHoward Hinnant size() = 0; 17663e519524SHoward Hinnant } 17673e519524SHoward Hinnant} 17683e519524SHoward Hinnant 17695c4e07aeSErik Pilkington 17705c4e07aeSErik Pilkington// Prepare the container for an insertion of the value __value with the hash 17715c4e07aeSErik Pilkington// __hash. This does a lookup into the container to see if __value is already 17725c4e07aeSErik Pilkington// present, and performs a rehash if necessary. Returns a pointer to the 17735c4e07aeSErik Pilkington// existing element if it exists, otherwise nullptr. 17745c4e07aeSErik Pilkington// 17755c4e07aeSErik Pilkington// Note that this function does forward exceptions if key_eq() throws, and never 17765c4e07aeSErik Pilkington// mutates __value or actually inserts into the map. 17773e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 17785c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY 17795c4e07aeSErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 17805c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( 17815c4e07aeSErik Pilkington size_t __hash, value_type& __value) 17823e519524SHoward Hinnant{ 17833e519524SHoward Hinnant size_type __bc = bucket_count(); 17845c4e07aeSErik Pilkington 17853e519524SHoward Hinnant if (__bc != 0) 17863e519524SHoward Hinnant { 17875c4e07aeSErik Pilkington size_t __chash = __constrain_hash(__hash, __bc); 17885c4e07aeSErik Pilkington __next_pointer __ndptr = __bucket_list_[__chash]; 17893e519524SHoward Hinnant if (__ndptr != nullptr) 17903e519524SHoward Hinnant { 17913e519524SHoward Hinnant for (__ndptr = __ndptr->__next_; __ndptr != nullptr && 179240492ba4SEric Fiselier __constrain_hash(__ndptr->__hash(), __bc) == __chash; 17933e519524SHoward Hinnant __ndptr = __ndptr->__next_) 17943e519524SHoward Hinnant { 17955c4e07aeSErik Pilkington if (key_eq()(__ndptr->__upcast()->__value_, __value)) 17965c4e07aeSErik Pilkington return __ndptr; 17973e519524SHoward Hinnant } 17983e519524SHoward Hinnant } 17993e519524SHoward Hinnant } 18003e519524SHoward Hinnant if (size()+1 > __bc * max_load_factor() || __bc == 0) 18013e519524SHoward Hinnant { 18023085e42fSIvan Trofimov __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 18033e519524SHoward Hinnant size_type(ceil(float(size() + 1) / max_load_factor())))); 18043e519524SHoward Hinnant } 18055c4e07aeSErik Pilkington return nullptr; 18065c4e07aeSErik Pilkington} 18075c4e07aeSErik Pilkington 18085c4e07aeSErik Pilkington// Insert the node __nd into the container by pushing it into the right bucket, 18095c4e07aeSErik Pilkington// and updating size(). Assumes that __nd->__hash is up-to-date, and that 18105c4e07aeSErik Pilkington// rehashing has already occurred and that no element with the same key exists 18115c4e07aeSErik Pilkington// in the map. 18125c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 18135c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY 18145c4e07aeSErik Pilkingtonvoid 18155c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( 18165c4e07aeSErik Pilkington __node_pointer __nd) _NOEXCEPT 18175c4e07aeSErik Pilkington{ 18185c4e07aeSErik Pilkington size_type __bc = bucket_count(); 18195c4e07aeSErik Pilkington size_t __chash = __constrain_hash(__nd->__hash(), __bc); 18203e519524SHoward Hinnant // insert_after __bucket_list_[__chash], or __first_node if bucket is null 182140492ba4SEric Fiselier __next_pointer __pn = __bucket_list_[__chash]; 18223e519524SHoward Hinnant if (__pn == nullptr) 18233e519524SHoward Hinnant { 182440492ba4SEric Fiselier __pn =__p1_.first().__ptr(); 18253e519524SHoward Hinnant __nd->__next_ = __pn->__next_; 182640492ba4SEric Fiselier __pn->__next_ = __nd->__ptr(); 18273e519524SHoward Hinnant // fix up __bucket_list_ 18283e519524SHoward Hinnant __bucket_list_[__chash] = __pn; 18293e519524SHoward Hinnant if (__nd->__next_ != nullptr) 183040492ba4SEric Fiselier __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); 18313e519524SHoward Hinnant } 18323e519524SHoward Hinnant else 18333e519524SHoward Hinnant { 18343e519524SHoward Hinnant __nd->__next_ = __pn->__next_; 183540492ba4SEric Fiselier __pn->__next_ = __nd->__ptr(); 18363e519524SHoward Hinnant } 18373e519524SHoward Hinnant ++size(); 18383e519524SHoward Hinnant} 18393e519524SHoward Hinnant 18403e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 18415c4e07aeSErik Pilkingtonpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 18425c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) 18433e519524SHoward Hinnant{ 18445c4e07aeSErik Pilkington __nd->__hash_ = hash_function()(__nd->__value_); 18455c4e07aeSErik Pilkington __next_pointer __existing_node = 18465c4e07aeSErik Pilkington __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); 18475c4e07aeSErik Pilkington 18485c4e07aeSErik Pilkington // Insert the node, unless it already exists in the container. 18495c4e07aeSErik Pilkington bool __inserted = false; 18505c4e07aeSErik Pilkington if (__existing_node == nullptr) 18515c4e07aeSErik Pilkington { 18525c4e07aeSErik Pilkington __node_insert_unique_perform(__nd); 18535c4e07aeSErik Pilkington __existing_node = __nd->__ptr(); 18545c4e07aeSErik Pilkington __inserted = true; 18555c4e07aeSErik Pilkington } 18565c4e07aeSErik Pilkington return pair<iterator, bool>(iterator(__existing_node, this), __inserted); 18575c4e07aeSErik Pilkington} 18585c4e07aeSErik Pilkington 18595c4e07aeSErik Pilkington// Prepare the container for an insertion of the value __cp_val with the hash 18605c4e07aeSErik Pilkington// __cp_hash. This does a lookup into the container to see if __cp_value is 18615c4e07aeSErik Pilkington// already present, and performs a rehash if necessary. Returns a pointer to the 1862b6f19174SArthur O'Dwyer// last occurrence of __cp_val in the map. 18635c4e07aeSErik Pilkington// 18645c4e07aeSErik Pilkington// Note that this function does forward exceptions if key_eq() throws, and never 18655c4e07aeSErik Pilkington// mutates __value or actually inserts into the map. 18665c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 18675c4e07aeSErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 18685c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( 18695c4e07aeSErik Pilkington size_t __cp_hash, value_type& __cp_val) 18705c4e07aeSErik Pilkington{ 18713e519524SHoward Hinnant size_type __bc = bucket_count(); 18723e519524SHoward Hinnant if (size()+1 > __bc * max_load_factor() || __bc == 0) 18733e519524SHoward Hinnant { 18743085e42fSIvan Trofimov __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 18753e519524SHoward Hinnant size_type(ceil(float(size() + 1) / max_load_factor())))); 18763e519524SHoward Hinnant __bc = bucket_count(); 18773e519524SHoward Hinnant } 18785c4e07aeSErik Pilkington size_t __chash = __constrain_hash(__cp_hash, __bc); 187940492ba4SEric Fiselier __next_pointer __pn = __bucket_list_[__chash]; 18805c4e07aeSErik Pilkington if (__pn != nullptr) 18815c4e07aeSErik Pilkington { 18825c4e07aeSErik Pilkington for (bool __found = false; __pn->__next_ != nullptr && 18835c4e07aeSErik Pilkington __constrain_hash(__pn->__next_->__hash(), __bc) == __chash; 18845c4e07aeSErik Pilkington __pn = __pn->__next_) 18855c4e07aeSErik Pilkington { 18865c4e07aeSErik Pilkington // __found key_eq() action 18875c4e07aeSErik Pilkington // false false loop 18885c4e07aeSErik Pilkington // true true loop 18895c4e07aeSErik Pilkington // false true set __found to true 18905c4e07aeSErik Pilkington // true false break 18915c4e07aeSErik Pilkington if (__found != (__pn->__next_->__hash() == __cp_hash && 18925c4e07aeSErik Pilkington key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) 18935c4e07aeSErik Pilkington { 18945c4e07aeSErik Pilkington if (!__found) 18955c4e07aeSErik Pilkington __found = true; 18965c4e07aeSErik Pilkington else 18975c4e07aeSErik Pilkington break; 18985c4e07aeSErik Pilkington } 18995c4e07aeSErik Pilkington } 19005c4e07aeSErik Pilkington } 19015c4e07aeSErik Pilkington return __pn; 19025c4e07aeSErik Pilkington} 19035c4e07aeSErik Pilkington 19045c4e07aeSErik Pilkington// Insert the node __cp into the container after __pn (which is the last node in 19055c4e07aeSErik Pilkington// the bucket that compares equal to __cp). Rehashing, and checking for 19065c4e07aeSErik Pilkington// uniqueness has already been performed (in __node_insert_multi_prepare), so 19075c4e07aeSErik Pilkington// all we need to do is update the bucket and size(). Assumes that __cp->__hash 19085c4e07aeSErik Pilkington// is up-to-date. 19095c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 19105c4e07aeSErik Pilkingtonvoid 19115c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( 19125c4e07aeSErik Pilkington __node_pointer __cp, __next_pointer __pn) _NOEXCEPT 19135c4e07aeSErik Pilkington{ 19145c4e07aeSErik Pilkington size_type __bc = bucket_count(); 19155c4e07aeSErik Pilkington size_t __chash = __constrain_hash(__cp->__hash_, __bc); 19163e519524SHoward Hinnant if (__pn == nullptr) 19173e519524SHoward Hinnant { 191840492ba4SEric Fiselier __pn =__p1_.first().__ptr(); 19193e519524SHoward Hinnant __cp->__next_ = __pn->__next_; 192040492ba4SEric Fiselier __pn->__next_ = __cp->__ptr(); 19213e519524SHoward Hinnant // fix up __bucket_list_ 19223e519524SHoward Hinnant __bucket_list_[__chash] = __pn; 19233e519524SHoward Hinnant if (__cp->__next_ != nullptr) 192440492ba4SEric Fiselier __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] 192540492ba4SEric Fiselier = __cp->__ptr(); 19263e519524SHoward Hinnant } 19273e519524SHoward Hinnant else 19283e519524SHoward Hinnant { 19293e519524SHoward Hinnant __cp->__next_ = __pn->__next_; 193040492ba4SEric Fiselier __pn->__next_ = __cp->__ptr(); 19313e519524SHoward Hinnant if (__cp->__next_ != nullptr) 19323e519524SHoward Hinnant { 193340492ba4SEric Fiselier size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc); 19343e519524SHoward Hinnant if (__nhash != __chash) 193540492ba4SEric Fiselier __bucket_list_[__nhash] = __cp->__ptr(); 19363e519524SHoward Hinnant } 19373e519524SHoward Hinnant } 19383e519524SHoward Hinnant ++size(); 19395c4e07aeSErik Pilkington} 19405c4e07aeSErik Pilkington 19415c4e07aeSErik Pilkington 19425c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 19435c4e07aeSErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 19445c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) 19455c4e07aeSErik Pilkington{ 19465c4e07aeSErik Pilkington __cp->__hash_ = hash_function()(__cp->__value_); 19475c4e07aeSErik Pilkington __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); 19485c4e07aeSErik Pilkington __node_insert_multi_perform(__cp, __pn); 19495c4e07aeSErik Pilkington 195040492ba4SEric Fiselier return iterator(__cp->__ptr(), this); 19513e519524SHoward Hinnant} 19523e519524SHoward Hinnant 19533e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 19543e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 19553e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( 19563e519524SHoward Hinnant const_iterator __p, __node_pointer __cp) 19573e519524SHoward Hinnant{ 1958d6e2c95dSMark de Wever _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 19592f51de56SHoward Hinnant "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" 19602f51de56SHoward Hinnant " referring to this unordered container"); 19613e519524SHoward Hinnant if (__p != end() && key_eq()(*__p, __cp->__value_)) 19623e519524SHoward Hinnant { 196340492ba4SEric Fiselier __next_pointer __np = __p.__node_; 196440492ba4SEric Fiselier __cp->__hash_ = __np->__hash(); 19653e519524SHoward Hinnant size_type __bc = bucket_count(); 19663e519524SHoward Hinnant if (size()+1 > __bc * max_load_factor() || __bc == 0) 19673e519524SHoward Hinnant { 19683085e42fSIvan Trofimov __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 19693e519524SHoward Hinnant size_type(ceil(float(size() + 1) / max_load_factor())))); 19703e519524SHoward Hinnant __bc = bucket_count(); 19713e519524SHoward Hinnant } 19724cb38a82SHoward Hinnant size_t __chash = __constrain_hash(__cp->__hash_, __bc); 197340492ba4SEric Fiselier __next_pointer __pp = __bucket_list_[__chash]; 19743e519524SHoward Hinnant while (__pp->__next_ != __np) 19753e519524SHoward Hinnant __pp = __pp->__next_; 19763e519524SHoward Hinnant __cp->__next_ = __np; 197740492ba4SEric Fiselier __pp->__next_ = static_cast<__next_pointer>(__cp); 19783e519524SHoward Hinnant ++size(); 197940492ba4SEric Fiselier return iterator(static_cast<__next_pointer>(__cp), this); 19803e519524SHoward Hinnant } 19813e519524SHoward Hinnant return __node_insert_multi(__cp); 19823e519524SHoward Hinnant} 19833e519524SHoward Hinnant 1984de3f2b39SEric Fiselier 1985de3f2b39SEric Fiselier 1986de3f2b39SEric Fiseliertemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1987fcd02211SEric Fiseliertemplate <class _Key, class ..._Args> 1988de3f2b39SEric Fiselierpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 1989fcd02211SEric Fiselier__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) 1990de3f2b39SEric Fiselier{ 1991fcd02211SEric Fiselier 1992fcd02211SEric Fiselier size_t __hash = hash_function()(__k); 19933e519524SHoward Hinnant size_type __bc = bucket_count(); 19943e519524SHoward Hinnant bool __inserted = false; 199540492ba4SEric Fiselier __next_pointer __nd; 19963e519524SHoward Hinnant size_t __chash; 19973e519524SHoward Hinnant if (__bc != 0) 19983e519524SHoward Hinnant { 19994cb38a82SHoward Hinnant __chash = __constrain_hash(__hash, __bc); 20003e519524SHoward Hinnant __nd = __bucket_list_[__chash]; 20013e519524SHoward Hinnant if (__nd != nullptr) 20023e519524SHoward Hinnant { 20033e519524SHoward Hinnant for (__nd = __nd->__next_; __nd != nullptr && 20041a06fe5fSEric Fiselier (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash); 20053e519524SHoward Hinnant __nd = __nd->__next_) 20063e519524SHoward Hinnant { 200740492ba4SEric Fiselier if (key_eq()(__nd->__upcast()->__value_, __k)) 20083e519524SHoward Hinnant goto __done; 20093e519524SHoward Hinnant } 20103e519524SHoward Hinnant } 20113e519524SHoward Hinnant } 20123e519524SHoward Hinnant { 2013fcd02211SEric Fiselier __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); 20143e519524SHoward Hinnant if (size()+1 > __bc * max_load_factor() || __bc == 0) 20153e519524SHoward Hinnant { 20163085e42fSIvan Trofimov __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 20173e519524SHoward Hinnant size_type(ceil(float(size() + 1) / max_load_factor())))); 20183e519524SHoward Hinnant __bc = bucket_count(); 20194cb38a82SHoward Hinnant __chash = __constrain_hash(__hash, __bc); 20203e519524SHoward Hinnant } 20213e519524SHoward Hinnant // insert_after __bucket_list_[__chash], or __first_node if bucket is null 202240492ba4SEric Fiselier __next_pointer __pn = __bucket_list_[__chash]; 20233e519524SHoward Hinnant if (__pn == nullptr) 20243e519524SHoward Hinnant { 202540492ba4SEric Fiselier __pn = __p1_.first().__ptr(); 20263e519524SHoward Hinnant __h->__next_ = __pn->__next_; 202740492ba4SEric Fiselier __pn->__next_ = __h.get()->__ptr(); 20283e519524SHoward Hinnant // fix up __bucket_list_ 20293e519524SHoward Hinnant __bucket_list_[__chash] = __pn; 20303e519524SHoward Hinnant if (__h->__next_ != nullptr) 203140492ba4SEric Fiselier __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)] 203240492ba4SEric Fiselier = __h.get()->__ptr(); 20333e519524SHoward Hinnant } 20343e519524SHoward Hinnant else 20353e519524SHoward Hinnant { 20363e519524SHoward Hinnant __h->__next_ = __pn->__next_; 203740492ba4SEric Fiselier __pn->__next_ = static_cast<__next_pointer>(__h.get()); 20383e519524SHoward Hinnant } 203940492ba4SEric Fiselier __nd = static_cast<__next_pointer>(__h.release()); 20403e519524SHoward Hinnant // increment size 20413e519524SHoward Hinnant ++size(); 20423e519524SHoward Hinnant __inserted = true; 20433e519524SHoward Hinnant } 20443e519524SHoward Hinnant__done: 2045b24c8024SHoward Hinnant return pair<iterator, bool>(iterator(__nd, this), __inserted); 20463e519524SHoward Hinnant} 20473e519524SHoward Hinnant 20483e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 20493e519524SHoward Hinnanttemplate <class... _Args> 20503e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 2051fde79b40SDuncan P. N. Exon Smith__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) 20523e519524SHoward Hinnant{ 2053ce48a113SHoward Hinnant __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 20543e519524SHoward Hinnant pair<iterator, bool> __r = __node_insert_unique(__h.get()); 20553e519524SHoward Hinnant if (__r.second) 20563e519524SHoward Hinnant __h.release(); 20573e519524SHoward Hinnant return __r; 20583e519524SHoward Hinnant} 20593e519524SHoward Hinnant 20603e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 20613e519524SHoward Hinnanttemplate <class... _Args> 20623e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 20633e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) 20643e519524SHoward Hinnant{ 2065ce48a113SHoward Hinnant __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 20663e519524SHoward Hinnant iterator __r = __node_insert_multi(__h.get()); 20673e519524SHoward Hinnant __h.release(); 20683e519524SHoward Hinnant return __r; 20693e519524SHoward Hinnant} 20703e519524SHoward Hinnant 20713e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 20723e519524SHoward Hinnanttemplate <class... _Args> 20733e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 20743e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( 20753e519524SHoward Hinnant const_iterator __p, _Args&&... __args) 20763e519524SHoward Hinnant{ 2077d6e2c95dSMark de Wever _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 2078e5c13decSHoward Hinnant "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" 2079e5c13decSHoward Hinnant " referring to this unordered container"); 2080ce48a113SHoward Hinnant __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 20813e519524SHoward Hinnant iterator __r = __node_insert_multi(__p, __h.get()); 20823e519524SHoward Hinnant __h.release(); 20833e519524SHoward Hinnant return __r; 20843e519524SHoward Hinnant} 20853e519524SHoward Hinnant 2086b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14 2087b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2088b0386a51SErik Pilkingtontemplate <class _NodeHandle, class _InsertReturnType> 2089b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY 2090b0386a51SErik Pilkington_InsertReturnType 2091b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( 2092b0386a51SErik Pilkington _NodeHandle&& __nh) 2093b0386a51SErik Pilkington{ 2094b0386a51SErik Pilkington if (__nh.empty()) 2095b0386a51SErik Pilkington return _InsertReturnType{end(), false, _NodeHandle()}; 2096b0386a51SErik Pilkington pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); 2097b0386a51SErik Pilkington if (__result.second) 20986886f1e3SEric Fiselier __nh.__release_ptr(); 2099b0386a51SErik Pilkington return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; 2100b0386a51SErik Pilkington} 2101b0386a51SErik Pilkington 2102b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2103b0386a51SErik Pilkingtontemplate <class _NodeHandle> 2104b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY 2105b0386a51SErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2106b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( 2107b0386a51SErik Pilkington const_iterator, _NodeHandle&& __nh) 2108b0386a51SErik Pilkington{ 2109b0386a51SErik Pilkington if (__nh.empty()) 2110b0386a51SErik Pilkington return end(); 2111b0386a51SErik Pilkington pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); 2112b0386a51SErik Pilkington if (__result.second) 21136886f1e3SEric Fiselier __nh.__release_ptr(); 2114b0386a51SErik Pilkington return __result.first; 2115b0386a51SErik Pilkington} 2116b0386a51SErik Pilkington 2117b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2118b0386a51SErik Pilkingtontemplate <class _NodeHandle> 2119b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY 2120b0386a51SErik Pilkington_NodeHandle 2121b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( 2122b0386a51SErik Pilkington key_type const& __key) 2123b0386a51SErik Pilkington{ 2124b0386a51SErik Pilkington iterator __i = find(__key); 2125b0386a51SErik Pilkington if (__i == end()) 2126b0386a51SErik Pilkington return _NodeHandle(); 2127b0386a51SErik Pilkington return __node_handle_extract<_NodeHandle>(__i); 2128b0386a51SErik Pilkington} 2129b0386a51SErik Pilkington 2130b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2131b0386a51SErik Pilkingtontemplate <class _NodeHandle> 2132b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY 2133b0386a51SErik Pilkington_NodeHandle 2134b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( 2135b0386a51SErik Pilkington const_iterator __p) 2136b0386a51SErik Pilkington{ 2137b0386a51SErik Pilkington allocator_type __alloc(__node_alloc()); 2138b0386a51SErik Pilkington return _NodeHandle(remove(__p).release(), __alloc); 2139b0386a51SErik Pilkington} 2140b0386a51SErik Pilkington 2141b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 21425c4e07aeSErik Pilkingtontemplate <class _Table> 21435c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY 21445c4e07aeSErik Pilkingtonvoid 21455c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( 21465c4e07aeSErik Pilkington _Table& __source) 21475c4e07aeSErik Pilkington{ 21485c4e07aeSErik Pilkington static_assert(is_same<__node, typename _Table::__node>::value, ""); 21495c4e07aeSErik Pilkington 21505c4e07aeSErik Pilkington for (typename _Table::iterator __it = __source.begin(); 21515c4e07aeSErik Pilkington __it != __source.end();) 21525c4e07aeSErik Pilkington { 21535c4e07aeSErik Pilkington __node_pointer __src_ptr = __it.__node_->__upcast(); 21545c4e07aeSErik Pilkington size_t __hash = hash_function()(__src_ptr->__value_); 21555c4e07aeSErik Pilkington __next_pointer __existing_node = 21565c4e07aeSErik Pilkington __node_insert_unique_prepare(__hash, __src_ptr->__value_); 21575c4e07aeSErik Pilkington auto __prev_iter = __it++; 21585c4e07aeSErik Pilkington if (__existing_node == nullptr) 21595c4e07aeSErik Pilkington { 21605c4e07aeSErik Pilkington (void)__source.remove(__prev_iter).release(); 21615c4e07aeSErik Pilkington __src_ptr->__hash_ = __hash; 21625c4e07aeSErik Pilkington __node_insert_unique_perform(__src_ptr); 21635c4e07aeSErik Pilkington } 21645c4e07aeSErik Pilkington } 21655c4e07aeSErik Pilkington} 21665c4e07aeSErik Pilkington 21675c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2168b0386a51SErik Pilkingtontemplate <class _NodeHandle> 2169b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY 2170b0386a51SErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2171b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( 2172b0386a51SErik Pilkington _NodeHandle&& __nh) 2173b0386a51SErik Pilkington{ 2174b0386a51SErik Pilkington if (__nh.empty()) 2175b0386a51SErik Pilkington return end(); 2176b0386a51SErik Pilkington iterator __result = __node_insert_multi(__nh.__ptr_); 21776886f1e3SEric Fiselier __nh.__release_ptr(); 2178b0386a51SErik Pilkington return __result; 2179b0386a51SErik Pilkington} 2180b0386a51SErik Pilkington 2181b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2182b0386a51SErik Pilkingtontemplate <class _NodeHandle> 2183b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY 2184b0386a51SErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2185b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( 2186b0386a51SErik Pilkington const_iterator __hint, _NodeHandle&& __nh) 2187b0386a51SErik Pilkington{ 2188b0386a51SErik Pilkington if (__nh.empty()) 2189b0386a51SErik Pilkington return end(); 2190b0386a51SErik Pilkington iterator __result = __node_insert_multi(__hint, __nh.__ptr_); 21916886f1e3SEric Fiselier __nh.__release_ptr(); 2192b0386a51SErik Pilkington return __result; 2193b0386a51SErik Pilkington} 2194b0386a51SErik Pilkington 21955c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 21965c4e07aeSErik Pilkingtontemplate <class _Table> 21975c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY 21985c4e07aeSErik Pilkingtonvoid 21995c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( 22005c4e07aeSErik Pilkington _Table& __source) 22015c4e07aeSErik Pilkington{ 22025c4e07aeSErik Pilkington static_assert(is_same<typename _Table::__node, __node>::value, ""); 22035c4e07aeSErik Pilkington 22045c4e07aeSErik Pilkington for (typename _Table::iterator __it = __source.begin(); 22055c4e07aeSErik Pilkington __it != __source.end();) 22065c4e07aeSErik Pilkington { 22075c4e07aeSErik Pilkington __node_pointer __src_ptr = __it.__node_->__upcast(); 22085c4e07aeSErik Pilkington size_t __src_hash = hash_function()(__src_ptr->__value_); 22095c4e07aeSErik Pilkington __next_pointer __pn = 22105c4e07aeSErik Pilkington __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); 22115c4e07aeSErik Pilkington (void)__source.remove(__it++).release(); 22125c4e07aeSErik Pilkington __src_ptr->__hash_ = __src_hash; 22135c4e07aeSErik Pilkington __node_insert_multi_perform(__src_ptr, __pn); 22145c4e07aeSErik Pilkington } 22155c4e07aeSErik Pilkington} 2216b0386a51SErik Pilkington#endif // _LIBCPP_STD_VER > 14 2217b0386a51SErik Pilkington 22183e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 22193085e42fSIvan Trofimovtemplate <bool _UniqueKeys> 22203e519524SHoward Hinnantvoid 22213085e42fSIvan Trofimov__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) 2222954966c1SMarshall Clow_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 22233e519524SHoward Hinnant{ 2224553b09b5SDan Albert if (__n == 1) 22254cb38a82SHoward Hinnant __n = 2; 22264cb38a82SHoward Hinnant else if (__n & (__n - 1)) 22274cb38a82SHoward Hinnant __n = __next_prime(__n); 22283e519524SHoward Hinnant size_type __bc = bucket_count(); 22293e519524SHoward Hinnant if (__n > __bc) 22303085e42fSIvan Trofimov __do_rehash<_UniqueKeys>(__n); 22314cb38a82SHoward Hinnant else if (__n < __bc) 22323e519524SHoward Hinnant { 2233ce48a113SHoward Hinnant __n = _VSTD::max<size_type> 22343e519524SHoward Hinnant ( 22353e519524SHoward Hinnant __n, 22369ba5c11bSEric Fiselier __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) : 22373e519524SHoward Hinnant __next_prime(size_t(ceil(float(size()) / max_load_factor()))) 22383e519524SHoward Hinnant ); 22393e519524SHoward Hinnant if (__n < __bc) 22403085e42fSIvan Trofimov __do_rehash<_UniqueKeys>(__n); 22413e519524SHoward Hinnant } 22423e519524SHoward Hinnant} 22433e519524SHoward Hinnant 22443e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 22453085e42fSIvan Trofimovtemplate <bool _UniqueKeys> 22463e519524SHoward Hinnantvoid 22473085e42fSIvan Trofimov__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) 22483e519524SHoward Hinnant{ 224908f68dfeSNikolas Klauser std::__debug_db_invalidate_all(this); 22503e519524SHoward Hinnant __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); 22513e519524SHoward Hinnant __bucket_list_.reset(__nbc > 0 ? 22523e519524SHoward Hinnant __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); 22533e519524SHoward Hinnant __bucket_list_.get_deleter().size() = __nbc; 22543e519524SHoward Hinnant if (__nbc > 0) 22553e519524SHoward Hinnant { 22563e519524SHoward Hinnant for (size_type __i = 0; __i < __nbc; ++__i) 22573e519524SHoward Hinnant __bucket_list_[__i] = nullptr; 225840492ba4SEric Fiselier __next_pointer __pp = __p1_.first().__ptr(); 225940492ba4SEric Fiselier __next_pointer __cp = __pp->__next_; 22603e519524SHoward Hinnant if (__cp != nullptr) 22613e519524SHoward Hinnant { 226240492ba4SEric Fiselier size_type __chash = __constrain_hash(__cp->__hash(), __nbc); 22633e519524SHoward Hinnant __bucket_list_[__chash] = __pp; 22643e519524SHoward Hinnant size_type __phash = __chash; 226516bf4339SArthur O'Dwyer for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; 22663e519524SHoward Hinnant __cp = __pp->__next_) 22673e519524SHoward Hinnant { 226840492ba4SEric Fiselier __chash = __constrain_hash(__cp->__hash(), __nbc); 22693e519524SHoward Hinnant if (__chash == __phash) 22703e519524SHoward Hinnant __pp = __cp; 22713e519524SHoward Hinnant else 22723e519524SHoward Hinnant { 22733e519524SHoward Hinnant if (__bucket_list_[__chash] == nullptr) 22743e519524SHoward Hinnant { 22753e519524SHoward Hinnant __bucket_list_[__chash] = __pp; 22763e519524SHoward Hinnant __pp = __cp; 22773e519524SHoward Hinnant __phash = __chash; 22783e519524SHoward Hinnant } 22793e519524SHoward Hinnant else 22803e519524SHoward Hinnant { 228140492ba4SEric Fiselier __next_pointer __np = __cp; 22823085e42fSIvan Trofimov if _LIBCPP_CONSTEXPR_AFTER_CXX14 (!_UniqueKeys) 22833085e42fSIvan Trofimov { 22843e519524SHoward Hinnant for (; __np->__next_ != nullptr && 228540492ba4SEric Fiselier key_eq()(__cp->__upcast()->__value_, 228640492ba4SEric Fiselier __np->__next_->__upcast()->__value_); 22873e519524SHoward Hinnant __np = __np->__next_) 22883e519524SHoward Hinnant ; 22893085e42fSIvan Trofimov } 22903e519524SHoward Hinnant __pp->__next_ = __np->__next_; 22913e519524SHoward Hinnant __np->__next_ = __bucket_list_[__chash]->__next_; 22923e519524SHoward Hinnant __bucket_list_[__chash]->__next_ = __cp; 22933e519524SHoward Hinnant 22943e519524SHoward Hinnant } 22953e519524SHoward Hinnant } 22963e519524SHoward Hinnant } 22973e519524SHoward Hinnant } 22983e519524SHoward Hinnant } 22993e519524SHoward Hinnant} 23003e519524SHoward Hinnant 23013e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 23023e519524SHoward Hinnanttemplate <class _Key> 23033e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 23043e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) 23053e519524SHoward Hinnant{ 23063e519524SHoward Hinnant size_t __hash = hash_function()(__k); 23073e519524SHoward Hinnant size_type __bc = bucket_count(); 23083e519524SHoward Hinnant if (__bc != 0) 23093e519524SHoward Hinnant { 23104cb38a82SHoward Hinnant size_t __chash = __constrain_hash(__hash, __bc); 231140492ba4SEric Fiselier __next_pointer __nd = __bucket_list_[__chash]; 23123e519524SHoward Hinnant if (__nd != nullptr) 23133e519524SHoward Hinnant { 23143e519524SHoward Hinnant for (__nd = __nd->__next_; __nd != nullptr && 231540492ba4SEric Fiselier (__nd->__hash() == __hash 231640492ba4SEric Fiselier || __constrain_hash(__nd->__hash(), __bc) == __chash); 23173e519524SHoward Hinnant __nd = __nd->__next_) 23183e519524SHoward Hinnant { 231940492ba4SEric Fiselier if ((__nd->__hash() == __hash) 232040492ba4SEric Fiselier && key_eq()(__nd->__upcast()->__value_, __k)) 2321b24c8024SHoward Hinnant return iterator(__nd, this); 23223e519524SHoward Hinnant } 23233e519524SHoward Hinnant } 23243e519524SHoward Hinnant } 23253e519524SHoward Hinnant return end(); 23263e519524SHoward Hinnant} 23273e519524SHoward Hinnant 23283e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 23293e519524SHoward Hinnanttemplate <class _Key> 23303e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 23313e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const 23323e519524SHoward Hinnant{ 23333e519524SHoward Hinnant size_t __hash = hash_function()(__k); 23343e519524SHoward Hinnant size_type __bc = bucket_count(); 23353e519524SHoward Hinnant if (__bc != 0) 23363e519524SHoward Hinnant { 23374cb38a82SHoward Hinnant size_t __chash = __constrain_hash(__hash, __bc); 233840492ba4SEric Fiselier __next_pointer __nd = __bucket_list_[__chash]; 23393e519524SHoward Hinnant if (__nd != nullptr) 23403e519524SHoward Hinnant { 23413e519524SHoward Hinnant for (__nd = __nd->__next_; __nd != nullptr && 234240492ba4SEric Fiselier (__hash == __nd->__hash() 234340492ba4SEric Fiselier || __constrain_hash(__nd->__hash(), __bc) == __chash); 23443e519524SHoward Hinnant __nd = __nd->__next_) 23453e519524SHoward Hinnant { 234640492ba4SEric Fiselier if ((__nd->__hash() == __hash) 234740492ba4SEric Fiselier && key_eq()(__nd->__upcast()->__value_, __k)) 2348b24c8024SHoward Hinnant return const_iterator(__nd, this); 23493e519524SHoward Hinnant } 23503e519524SHoward Hinnant } 23513e519524SHoward Hinnant 23523e519524SHoward Hinnant } 23533e519524SHoward Hinnant return end(); 23543e519524SHoward Hinnant} 23553e519524SHoward Hinnant 23563e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 23573e519524SHoward Hinnanttemplate <class ..._Args> 23583e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 23593e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) 23603e519524SHoward Hinnant{ 2361fcd02211SEric Fiselier static_assert(!__is_hash_value_type<_Args...>::value, 2362fcd02211SEric Fiselier "Construct cannot be called with a hash value type"); 23633e519524SHoward Hinnant __node_allocator& __na = __node_alloc(); 2364c003db1fSHoward Hinnant __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 2365fcd02211SEric Fiselier __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); 23663e519524SHoward Hinnant __h.get_deleter().__value_constructed = true; 23673e519524SHoward Hinnant __h->__hash_ = hash_function()(__h->__value_); 23683e519524SHoward Hinnant __h->__next_ = nullptr; 23693e519524SHoward Hinnant return __h; 23703e519524SHoward Hinnant} 23713e519524SHoward Hinnant 23723e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2373fcd02211SEric Fiseliertemplate <class _First, class ..._Rest> 23743e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 2375fcd02211SEric Fiselier__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( 2376fcd02211SEric Fiselier size_t __hash, _First&& __f, _Rest&& ...__rest) 23773e519524SHoward Hinnant{ 2378fcd02211SEric Fiselier static_assert(!__is_hash_value_type<_First, _Rest...>::value, 2379fcd02211SEric Fiselier "Construct cannot be called with a hash value type"); 23803e519524SHoward Hinnant __node_allocator& __na = __node_alloc(); 2381c003db1fSHoward Hinnant __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 2382fcd02211SEric Fiselier __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), 2383fcd02211SEric Fiselier _VSTD::forward<_First>(__f), 2384fcd02211SEric Fiselier _VSTD::forward<_Rest>(__rest)...); 23853e519524SHoward Hinnant __h.get_deleter().__value_constructed = true; 23863e519524SHoward Hinnant __h->__hash_ = __hash; 23873e519524SHoward Hinnant __h->__next_ = nullptr; 2388179b1f8cSHoward Hinnant return __h; 23893e519524SHoward Hinnant} 23903e519524SHoward Hinnant 23913e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 23923e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 23933e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) 23943e519524SHoward Hinnant{ 239540492ba4SEric Fiselier __next_pointer __np = __p.__node_; 2396d6e2c95dSMark de Wever _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 2397b24c8024SHoward Hinnant "unordered container erase(iterator) called with an iterator not" 2398b24c8024SHoward Hinnant " referring to this container"); 2399c87c8917SLouis Dionne _LIBCPP_ASSERT(__p != end(), 2400b24c8024SHoward Hinnant "unordered container erase(iterator) called with a non-dereferenceable iterator"); 2401b24c8024SHoward Hinnant iterator __r(__np, this); 24023e519524SHoward Hinnant ++__r; 24033e519524SHoward Hinnant remove(__p); 24043e519524SHoward Hinnant return __r; 24053e519524SHoward Hinnant} 24063e519524SHoward Hinnant 24073e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 24083e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 24093e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, 24103e519524SHoward Hinnant const_iterator __last) 24113e519524SHoward Hinnant{ 2412d6e2c95dSMark de Wever _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, 24138a867878SKristina Bessonova "unordered container::erase(iterator, iterator) called with an iterator not" 24148a867878SKristina Bessonova " referring to this container"); 2415d6e2c95dSMark de Wever _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, 24168a867878SKristina Bessonova "unordered container::erase(iterator, iterator) called with an iterator not" 24178a867878SKristina Bessonova " referring to this container"); 24183e519524SHoward Hinnant for (const_iterator __p = __first; __first != __last; __p = __first) 24193e519524SHoward Hinnant { 24203e519524SHoward Hinnant ++__first; 24213e519524SHoward Hinnant erase(__p); 24223e519524SHoward Hinnant } 242340492ba4SEric Fiselier __next_pointer __np = __last.__node_; 2424b24c8024SHoward Hinnant return iterator (__np, this); 24253e519524SHoward Hinnant} 24263e519524SHoward Hinnant 24273e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 24283e519524SHoward Hinnanttemplate <class _Key> 24293e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 24303e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) 24313e519524SHoward Hinnant{ 24323e519524SHoward Hinnant iterator __i = find(__k); 24333e519524SHoward Hinnant if (__i == end()) 24343e519524SHoward Hinnant return 0; 24353e519524SHoward Hinnant erase(__i); 24363e519524SHoward Hinnant return 1; 24373e519524SHoward Hinnant} 24383e519524SHoward Hinnant 24393e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 24403e519524SHoward Hinnanttemplate <class _Key> 24413e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 24423e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) 24433e519524SHoward Hinnant{ 24443e519524SHoward Hinnant size_type __r = 0; 24453e519524SHoward Hinnant iterator __i = find(__k); 24463e519524SHoward Hinnant if (__i != end()) 24473e519524SHoward Hinnant { 24483e519524SHoward Hinnant iterator __e = end(); 24493e519524SHoward Hinnant do 24503e519524SHoward Hinnant { 24513e519524SHoward Hinnant erase(__i++); 24523e519524SHoward Hinnant ++__r; 24533e519524SHoward Hinnant } while (__i != __e && key_eq()(*__i, __k)); 24543e519524SHoward Hinnant } 24553e519524SHoward Hinnant return __r; 24563e519524SHoward Hinnant} 24573e519524SHoward Hinnant 24583e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 24593e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 24603714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT 24613e519524SHoward Hinnant{ 24623e519524SHoward Hinnant // current node 246340492ba4SEric Fiselier __next_pointer __cn = __p.__node_; 24643e519524SHoward Hinnant size_type __bc = bucket_count(); 246540492ba4SEric Fiselier size_t __chash = __constrain_hash(__cn->__hash(), __bc); 24663e519524SHoward Hinnant // find previous node 246740492ba4SEric Fiselier __next_pointer __pn = __bucket_list_[__chash]; 24683e519524SHoward Hinnant for (; __pn->__next_ != __cn; __pn = __pn->__next_) 24693e519524SHoward Hinnant ; 24703e519524SHoward Hinnant // Fix up __bucket_list_ 24713e519524SHoward Hinnant // if __pn is not in same bucket (before begin is not in same bucket) && 24723e519524SHoward Hinnant // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) 247340492ba4SEric Fiselier if (__pn == __p1_.first().__ptr() 247440492ba4SEric Fiselier || __constrain_hash(__pn->__hash(), __bc) != __chash) 24753e519524SHoward Hinnant { 247640492ba4SEric Fiselier if (__cn->__next_ == nullptr 247740492ba4SEric Fiselier || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash) 24783e519524SHoward Hinnant __bucket_list_[__chash] = nullptr; 24793e519524SHoward Hinnant } 24803e519524SHoward Hinnant // if __cn->__next_ is not in same bucket (nullptr is in same bucket) 24813e519524SHoward Hinnant if (__cn->__next_ != nullptr) 24823e519524SHoward Hinnant { 248340492ba4SEric Fiselier size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc); 24843e519524SHoward Hinnant if (__nhash != __chash) 24853e519524SHoward Hinnant __bucket_list_[__nhash] = __pn; 24863e519524SHoward Hinnant } 24873e519524SHoward Hinnant // remove __cn 24883e519524SHoward Hinnant __pn->__next_ = __cn->__next_; 24893e519524SHoward Hinnant __cn->__next_ = nullptr; 24903e519524SHoward Hinnant --size(); 2491f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 2492b24c8024SHoward Hinnant __c_node* __c = __get_db()->__find_c_and_lock(this); 2493780b51dfSEric Fiselier for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) 2494b24c8024SHoward Hinnant { 2495780b51dfSEric Fiselier --__dp; 2496780b51dfSEric Fiselier iterator* __i = static_cast<iterator*>((*__dp)->__i_); 2497b24c8024SHoward Hinnant if (__i->__node_ == __cn) 2498b24c8024SHoward Hinnant { 2499780b51dfSEric Fiselier (*__dp)->__c_ = nullptr; 2500780b51dfSEric Fiselier if (--__c->end_ != __dp) 25013696227cSArthur O'Dwyer _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); 2502b24c8024SHoward Hinnant } 2503b24c8024SHoward Hinnant } 2504b24c8024SHoward Hinnant __get_db()->unlock(); 2505b24c8024SHoward Hinnant#endif 250640492ba4SEric Fiselier return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); 25073e519524SHoward Hinnant} 25083e519524SHoward Hinnant 25093e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 25103e519524SHoward Hinnanttemplate <class _Key> 2511906c872dSEvgeniy Stepanovinline 25123e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 25133e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const 25143e519524SHoward Hinnant{ 25153e519524SHoward Hinnant return static_cast<size_type>(find(__k) != end()); 25163e519524SHoward Hinnant} 25173e519524SHoward Hinnant 25183e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 25193e519524SHoward Hinnanttemplate <class _Key> 25203e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 25213e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const 25223e519524SHoward Hinnant{ 25233e519524SHoward Hinnant size_type __r = 0; 25243e519524SHoward Hinnant const_iterator __i = find(__k); 25253e519524SHoward Hinnant if (__i != end()) 25263e519524SHoward Hinnant { 25273e519524SHoward Hinnant const_iterator __e = end(); 25283e519524SHoward Hinnant do 25293e519524SHoward Hinnant { 25303e519524SHoward Hinnant ++__i; 25313e519524SHoward Hinnant ++__r; 25323e519524SHoward Hinnant } while (__i != __e && key_eq()(*__i, __k)); 25333e519524SHoward Hinnant } 25343e519524SHoward Hinnant return __r; 25353e519524SHoward Hinnant} 25363e519524SHoward Hinnant 25373e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 25383e519524SHoward Hinnanttemplate <class _Key> 25393e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, 25403e519524SHoward Hinnant typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> 25413e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( 25423e519524SHoward Hinnant const _Key& __k) 25433e519524SHoward Hinnant{ 25443e519524SHoward Hinnant iterator __i = find(__k); 25453e519524SHoward Hinnant iterator __j = __i; 25463e519524SHoward Hinnant if (__i != end()) 25473e519524SHoward Hinnant ++__j; 25483e519524SHoward Hinnant return pair<iterator, iterator>(__i, __j); 25493e519524SHoward Hinnant} 25503e519524SHoward Hinnant 25513e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 25523e519524SHoward Hinnanttemplate <class _Key> 25533e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator, 25543e519524SHoward Hinnant typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> 25553e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( 25563e519524SHoward Hinnant const _Key& __k) const 25573e519524SHoward Hinnant{ 25583e519524SHoward Hinnant const_iterator __i = find(__k); 25593e519524SHoward Hinnant const_iterator __j = __i; 25603e519524SHoward Hinnant if (__i != end()) 25613e519524SHoward Hinnant ++__j; 25623e519524SHoward Hinnant return pair<const_iterator, const_iterator>(__i, __j); 25633e519524SHoward Hinnant} 25643e519524SHoward Hinnant 25653e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 25663e519524SHoward Hinnanttemplate <class _Key> 25673e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, 25683e519524SHoward Hinnant typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> 25693e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( 25703e519524SHoward Hinnant const _Key& __k) 25713e519524SHoward Hinnant{ 25723e519524SHoward Hinnant iterator __i = find(__k); 25733e519524SHoward Hinnant iterator __j = __i; 25743e519524SHoward Hinnant if (__i != end()) 25753e519524SHoward Hinnant { 25763e519524SHoward Hinnant iterator __e = end(); 25773e519524SHoward Hinnant do 25783e519524SHoward Hinnant { 25793e519524SHoward Hinnant ++__j; 25803e519524SHoward Hinnant } while (__j != __e && key_eq()(*__j, __k)); 25813e519524SHoward Hinnant } 25823e519524SHoward Hinnant return pair<iterator, iterator>(__i, __j); 25833e519524SHoward Hinnant} 25843e519524SHoward Hinnant 25853e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 25863e519524SHoward Hinnanttemplate <class _Key> 25873e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator, 25883e519524SHoward Hinnant typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> 25893e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( 25903e519524SHoward Hinnant const _Key& __k) const 25913e519524SHoward Hinnant{ 25923e519524SHoward Hinnant const_iterator __i = find(__k); 25933e519524SHoward Hinnant const_iterator __j = __i; 25943e519524SHoward Hinnant if (__i != end()) 25953e519524SHoward Hinnant { 25963e519524SHoward Hinnant const_iterator __e = end(); 25973e519524SHoward Hinnant do 25983e519524SHoward Hinnant { 25993e519524SHoward Hinnant ++__j; 26003e519524SHoward Hinnant } while (__j != __e && key_eq()(*__j, __k)); 26013e519524SHoward Hinnant } 26023e519524SHoward Hinnant return pair<const_iterator, const_iterator>(__i, __j); 26033e519524SHoward Hinnant} 26043e519524SHoward Hinnant 26053e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 26063e519524SHoward Hinnantvoid 26073e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) 260887a82490SEric Fiselier#if _LIBCPP_STD_VER <= 11 260961b302f9SEric Fiselier _NOEXCEPT_( 2610e3fbe143SMarshall Clow __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value 2611e3fbe143SMarshall Clow && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value 2612e3fbe143SMarshall Clow || __is_nothrow_swappable<__pointer_allocator>::value) 2613e3fbe143SMarshall Clow && (!__node_traits::propagate_on_container_swap::value 2614e3fbe143SMarshall Clow || __is_nothrow_swappable<__node_allocator>::value) 2615e3fbe143SMarshall Clow ) 261687a82490SEric Fiselier#else 261761b302f9SEric Fiselier _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value) 261887a82490SEric Fiselier#endif 26193e519524SHoward Hinnant{ 2620780b51dfSEric Fiselier _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || 2621780b51dfSEric Fiselier this->__node_alloc() == __u.__node_alloc(), 2622780b51dfSEric Fiselier "list::swap: Either propagate_on_container_swap must be true" 2623780b51dfSEric Fiselier " or the allocators must compare equal"); 26243e519524SHoward Hinnant { 26253e519524SHoward Hinnant __node_pointer_pointer __npp = __bucket_list_.release(); 26263e519524SHoward Hinnant __bucket_list_.reset(__u.__bucket_list_.release()); 26273e519524SHoward Hinnant __u.__bucket_list_.reset(__npp); 26283e519524SHoward Hinnant } 2629ce48a113SHoward Hinnant _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); 26306e965df6SArthur O'Dwyer _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), 26313e519524SHoward Hinnant __u.__bucket_list_.get_deleter().__alloc()); 26326e965df6SArthur O'Dwyer _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); 2633ce48a113SHoward Hinnant _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); 26343e519524SHoward Hinnant __p2_.swap(__u.__p2_); 26353e519524SHoward Hinnant __p3_.swap(__u.__p3_); 26363e519524SHoward Hinnant if (size() > 0) 263740492ba4SEric Fiselier __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 263840492ba4SEric Fiselier __p1_.first().__ptr(); 26393e519524SHoward Hinnant if (__u.size() > 0) 264040492ba4SEric Fiselier __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = 264140492ba4SEric Fiselier __u.__p1_.first().__ptr(); 264208f68dfeSNikolas Klauser std::__debug_db_swap(this, std::addressof(__u)); 26433e519524SHoward Hinnant} 26443e519524SHoward Hinnant 26453e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 26463e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 26473e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const 26483e519524SHoward Hinnant{ 2649e5c13decSHoward Hinnant _LIBCPP_ASSERT(__n < bucket_count(), 2650e5c13decSHoward Hinnant "unordered container::bucket_size(n) called with n >= bucket_count()"); 265140492ba4SEric Fiselier __next_pointer __np = __bucket_list_[__n]; 26523e519524SHoward Hinnant size_type __bc = bucket_count(); 26533e519524SHoward Hinnant size_type __r = 0; 26543e519524SHoward Hinnant if (__np != nullptr) 26553e519524SHoward Hinnant { 26563e519524SHoward Hinnant for (__np = __np->__next_; __np != nullptr && 265740492ba4SEric Fiselier __constrain_hash(__np->__hash(), __bc) == __n; 265816bf4339SArthur O'Dwyer __np = __np->__next_, (void) ++__r) 26593e519524SHoward Hinnant ; 26603e519524SHoward Hinnant } 26613e519524SHoward Hinnant return __r; 26623e519524SHoward Hinnant} 26633e519524SHoward Hinnant 26643714107eSHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 26653714107eSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 26663714107eSHoward Hinnantvoid 26673714107eSHoward Hinnantswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, 26683714107eSHoward Hinnant __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) 26693714107eSHoward Hinnant _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 26703714107eSHoward Hinnant{ 26713714107eSHoward Hinnant __x.swap(__y); 26723714107eSHoward Hinnant} 26733714107eSHoward Hinnant 2674f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE 2675b24c8024SHoward Hinnant 2676b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2677b24c8024SHoward Hinnantbool 2678b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const 2679b24c8024SHoward Hinnant{ 2680b24c8024SHoward Hinnant return __i->__node_ != nullptr; 2681b24c8024SHoward Hinnant} 2682b24c8024SHoward Hinnant 2683b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2684b24c8024SHoward Hinnantbool 2685b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const 2686b24c8024SHoward Hinnant{ 2687b24c8024SHoward Hinnant return false; 2688b24c8024SHoward Hinnant} 2689b24c8024SHoward Hinnant 2690b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2691b24c8024SHoward Hinnantbool 2692b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const 2693b24c8024SHoward Hinnant{ 2694b24c8024SHoward Hinnant return false; 2695b24c8024SHoward Hinnant} 2696b24c8024SHoward Hinnant 2697b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2698b24c8024SHoward Hinnantbool 2699b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const 2700b24c8024SHoward Hinnant{ 2701b24c8024SHoward Hinnant return false; 2702b24c8024SHoward Hinnant} 2703b24c8024SHoward Hinnant 2704f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE 2705a016efb1SEric Fiselier 27063e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 27073e519524SHoward Hinnant 2708a016efb1SEric Fiselier_LIBCPP_POP_MACROS 2709a016efb1SEric Fiselier 2710cc82a1b0SLouis Dionne#endif // _LIBCPP___HASH_TABLE 2711