1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP__HASH_TABLE 11*4d6fc14bSjoerg#define _LIBCPP__HASH_TABLE 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg#include <__config> 14*4d6fc14bSjoerg#include <initializer_list> 15*4d6fc14bSjoerg#include <memory> 16*4d6fc14bSjoerg#include <iterator> 17*4d6fc14bSjoerg#include <algorithm> 18*4d6fc14bSjoerg#include <cmath> 19*4d6fc14bSjoerg#include <utility> 20*4d6fc14bSjoerg#include <type_traits> 21*4d6fc14bSjoerg 22*4d6fc14bSjoerg#include <__debug> 23*4d6fc14bSjoerg 24*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 25*4d6fc14bSjoerg#pragma GCC system_header 26*4d6fc14bSjoerg#endif 27*4d6fc14bSjoerg 28*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS 29*4d6fc14bSjoerg#include <__undef_macros> 30*4d6fc14bSjoerg 31*4d6fc14bSjoerg 32*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 33*4d6fc14bSjoerg 34*4d6fc14bSjoergtemplate <class _Key, class _Tp> 35*4d6fc14bSjoergstruct __hash_value_type; 36*4d6fc14bSjoerg 37*4d6fc14bSjoergtemplate <class _Tp> 38*4d6fc14bSjoergstruct __is_hash_value_type_imp : false_type {}; 39*4d6fc14bSjoerg 40*4d6fc14bSjoergtemplate <class _Key, class _Value> 41*4d6fc14bSjoergstruct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; 42*4d6fc14bSjoerg 43*4d6fc14bSjoergtemplate <class ..._Args> 44*4d6fc14bSjoergstruct __is_hash_value_type : false_type {}; 45*4d6fc14bSjoerg 46*4d6fc14bSjoergtemplate <class _One> 47*4d6fc14bSjoergstruct __is_hash_value_type<_One> : __is_hash_value_type_imp<typename __uncvref<_One>::type> {}; 48*4d6fc14bSjoerg 49*4d6fc14bSjoerg_LIBCPP_FUNC_VIS 50*4d6fc14bSjoergsize_t __next_prime(size_t __n); 51*4d6fc14bSjoerg 52*4d6fc14bSjoergtemplate <class _NodePtr> 53*4d6fc14bSjoergstruct __hash_node_base 54*4d6fc14bSjoerg{ 55*4d6fc14bSjoerg typedef typename pointer_traits<_NodePtr>::element_type __node_type; 56*4d6fc14bSjoerg typedef __hash_node_base __first_node; 57*4d6fc14bSjoerg typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer; 58*4d6fc14bSjoerg typedef _NodePtr __node_pointer; 59*4d6fc14bSjoerg 60*4d6fc14bSjoerg#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) 61*4d6fc14bSjoerg typedef __node_base_pointer __next_pointer; 62*4d6fc14bSjoerg#else 63*4d6fc14bSjoerg typedef typename conditional< 64*4d6fc14bSjoerg is_pointer<__node_pointer>::value, 65*4d6fc14bSjoerg __node_base_pointer, 66*4d6fc14bSjoerg __node_pointer>::type __next_pointer; 67*4d6fc14bSjoerg#endif 68*4d6fc14bSjoerg 69*4d6fc14bSjoerg __next_pointer __next_; 70*4d6fc14bSjoerg 71*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 72*4d6fc14bSjoerg __next_pointer __ptr() _NOEXCEPT { 73*4d6fc14bSjoerg return static_cast<__next_pointer>( 74*4d6fc14bSjoerg pointer_traits<__node_base_pointer>::pointer_to(*this)); 75*4d6fc14bSjoerg } 76*4d6fc14bSjoerg 77*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 78*4d6fc14bSjoerg __node_pointer __upcast() _NOEXCEPT { 79*4d6fc14bSjoerg return static_cast<__node_pointer>( 80*4d6fc14bSjoerg pointer_traits<__node_base_pointer>::pointer_to(*this)); 81*4d6fc14bSjoerg } 82*4d6fc14bSjoerg 83*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 84*4d6fc14bSjoerg size_t __hash() const _NOEXCEPT { 85*4d6fc14bSjoerg return static_cast<__node_type const&>(*this).__hash_; 86*4d6fc14bSjoerg } 87*4d6fc14bSjoerg 88*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} 89*4d6fc14bSjoerg}; 90*4d6fc14bSjoerg 91*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr> 92*4d6fc14bSjoergstruct _LIBCPP_STANDALONE_DEBUG __hash_node 93*4d6fc14bSjoerg : public __hash_node_base 94*4d6fc14bSjoerg < 95*4d6fc14bSjoerg typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type 96*4d6fc14bSjoerg > 97*4d6fc14bSjoerg{ 98*4d6fc14bSjoerg typedef _Tp __node_value_type; 99*4d6fc14bSjoerg 100*4d6fc14bSjoerg size_t __hash_; 101*4d6fc14bSjoerg __node_value_type __value_; 102*4d6fc14bSjoerg}; 103*4d6fc14bSjoerg 104*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 105*4d6fc14bSjoergbool 106*4d6fc14bSjoerg__is_hash_power2(size_t __bc) 107*4d6fc14bSjoerg{ 108*4d6fc14bSjoerg return __bc > 2 && !(__bc & (__bc - 1)); 109*4d6fc14bSjoerg} 110*4d6fc14bSjoerg 111*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 112*4d6fc14bSjoergsize_t 113*4d6fc14bSjoerg__constrain_hash(size_t __h, size_t __bc) 114*4d6fc14bSjoerg{ 115*4d6fc14bSjoerg return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : 116*4d6fc14bSjoerg (__h < __bc ? __h : __h % __bc); 117*4d6fc14bSjoerg} 118*4d6fc14bSjoerg 119*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 120*4d6fc14bSjoergsize_t 121*4d6fc14bSjoerg__next_hash_pow2(size_t __n) 122*4d6fc14bSjoerg{ 123*4d6fc14bSjoerg return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1))); 124*4d6fc14bSjoerg} 125*4d6fc14bSjoerg 126*4d6fc14bSjoerg 127*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table; 128*4d6fc14bSjoerg 129*4d6fc14bSjoergtemplate <class _NodePtr> class _LIBCPP_TEMPLATE_VIS __hash_iterator; 130*4d6fc14bSjoergtemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 131*4d6fc14bSjoergtemplate <class _NodePtr> class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; 132*4d6fc14bSjoergtemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 133*4d6fc14bSjoergtemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 134*4d6fc14bSjoergtemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 135*4d6fc14bSjoerg 136*4d6fc14bSjoergtemplate <class _Tp> 137*4d6fc14bSjoergstruct __hash_key_value_types { 138*4d6fc14bSjoerg static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); 139*4d6fc14bSjoerg typedef _Tp key_type; 140*4d6fc14bSjoerg typedef _Tp __node_value_type; 141*4d6fc14bSjoerg typedef _Tp __container_value_type; 142*4d6fc14bSjoerg static const bool __is_map = false; 143*4d6fc14bSjoerg 144*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 145*4d6fc14bSjoerg static key_type const& __get_key(_Tp const& __v) { 146*4d6fc14bSjoerg return __v; 147*4d6fc14bSjoerg } 148*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 149*4d6fc14bSjoerg static __container_value_type const& __get_value(__node_value_type const& __v) { 150*4d6fc14bSjoerg return __v; 151*4d6fc14bSjoerg } 152*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 153*4d6fc14bSjoerg static __container_value_type* __get_ptr(__node_value_type& __n) { 154*4d6fc14bSjoerg return _VSTD::addressof(__n); 155*4d6fc14bSjoerg } 156*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 157*4d6fc14bSjoerg static __container_value_type&& __move(__node_value_type& __v) { 158*4d6fc14bSjoerg return _VSTD::move(__v); 159*4d6fc14bSjoerg } 160*4d6fc14bSjoerg}; 161*4d6fc14bSjoerg 162*4d6fc14bSjoergtemplate <class _Key, class _Tp> 163*4d6fc14bSjoergstruct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { 164*4d6fc14bSjoerg typedef _Key key_type; 165*4d6fc14bSjoerg typedef _Tp mapped_type; 166*4d6fc14bSjoerg typedef __hash_value_type<_Key, _Tp> __node_value_type; 167*4d6fc14bSjoerg typedef pair<const _Key, _Tp> __container_value_type; 168*4d6fc14bSjoerg typedef __container_value_type __map_value_type; 169*4d6fc14bSjoerg static const bool __is_map = true; 170*4d6fc14bSjoerg 171*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 172*4d6fc14bSjoerg static key_type const& __get_key(__container_value_type const& __v) { 173*4d6fc14bSjoerg return __v.first; 174*4d6fc14bSjoerg } 175*4d6fc14bSjoerg 176*4d6fc14bSjoerg template <class _Up> 177*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 178*4d6fc14bSjoerg static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, 179*4d6fc14bSjoerg __container_value_type const&>::type 180*4d6fc14bSjoerg __get_value(_Up& __t) { 181*4d6fc14bSjoerg return __t.__get_value(); 182*4d6fc14bSjoerg } 183*4d6fc14bSjoerg 184*4d6fc14bSjoerg template <class _Up> 185*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 186*4d6fc14bSjoerg static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, 187*4d6fc14bSjoerg __container_value_type const&>::type 188*4d6fc14bSjoerg __get_value(_Up& __t) { 189*4d6fc14bSjoerg return __t; 190*4d6fc14bSjoerg } 191*4d6fc14bSjoerg 192*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 193*4d6fc14bSjoerg static __container_value_type* __get_ptr(__node_value_type& __n) { 194*4d6fc14bSjoerg return _VSTD::addressof(__n.__get_value()); 195*4d6fc14bSjoerg } 196*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 197*4d6fc14bSjoerg static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { 198*4d6fc14bSjoerg return __v.__move(); 199*4d6fc14bSjoerg } 200*4d6fc14bSjoerg}; 201*4d6fc14bSjoerg 202*4d6fc14bSjoergtemplate <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, 203*4d6fc14bSjoerg bool = _KVTypes::__is_map> 204*4d6fc14bSjoergstruct __hash_map_pointer_types {}; 205*4d6fc14bSjoerg 206*4d6fc14bSjoergtemplate <class _Tp, class _AllocPtr, class _KVTypes> 207*4d6fc14bSjoergstruct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { 208*4d6fc14bSjoerg typedef typename _KVTypes::__map_value_type _Mv; 209*4d6fc14bSjoerg typedef typename __rebind_pointer<_AllocPtr, _Mv>::type 210*4d6fc14bSjoerg __map_value_type_pointer; 211*4d6fc14bSjoerg typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type 212*4d6fc14bSjoerg __const_map_value_type_pointer; 213*4d6fc14bSjoerg}; 214*4d6fc14bSjoerg 215*4d6fc14bSjoergtemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> 216*4d6fc14bSjoergstruct __hash_node_types; 217*4d6fc14bSjoerg 218*4d6fc14bSjoergtemplate <class _NodePtr, class _Tp, class _VoidPtr> 219*4d6fc14bSjoergstruct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > 220*4d6fc14bSjoerg : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> 221*4d6fc14bSjoerg 222*4d6fc14bSjoerg{ 223*4d6fc14bSjoerg typedef __hash_key_value_types<_Tp> __base; 224*4d6fc14bSjoerg 225*4d6fc14bSjoergpublic: 226*4d6fc14bSjoerg typedef ptrdiff_t difference_type; 227*4d6fc14bSjoerg typedef size_t size_type; 228*4d6fc14bSjoerg 229*4d6fc14bSjoerg typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; 230*4d6fc14bSjoerg 231*4d6fc14bSjoerg typedef typename pointer_traits<_NodePtr>::element_type __node_type; 232*4d6fc14bSjoerg typedef _NodePtr __node_pointer; 233*4d6fc14bSjoerg 234*4d6fc14bSjoerg typedef __hash_node_base<__node_pointer> __node_base_type; 235*4d6fc14bSjoerg typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type 236*4d6fc14bSjoerg __node_base_pointer; 237*4d6fc14bSjoerg 238*4d6fc14bSjoerg typedef typename __node_base_type::__next_pointer __next_pointer; 239*4d6fc14bSjoerg 240*4d6fc14bSjoerg typedef _Tp __node_value_type; 241*4d6fc14bSjoerg typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type 242*4d6fc14bSjoerg __node_value_type_pointer; 243*4d6fc14bSjoerg typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type 244*4d6fc14bSjoerg __const_node_value_type_pointer; 245*4d6fc14bSjoerg 246*4d6fc14bSjoergprivate: 247*4d6fc14bSjoerg static_assert(!is_const<__node_type>::value, 248*4d6fc14bSjoerg "_NodePtr should never be a pointer to const"); 249*4d6fc14bSjoerg static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), 250*4d6fc14bSjoerg "_VoidPtr does not point to unqualified void type"); 251*4d6fc14bSjoerg static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, 252*4d6fc14bSjoerg _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); 253*4d6fc14bSjoerg}; 254*4d6fc14bSjoerg 255*4d6fc14bSjoergtemplate <class _HashIterator> 256*4d6fc14bSjoergstruct __hash_node_types_from_iterator; 257*4d6fc14bSjoergtemplate <class _NodePtr> 258*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 259*4d6fc14bSjoergtemplate <class _NodePtr> 260*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 261*4d6fc14bSjoergtemplate <class _NodePtr> 262*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 263*4d6fc14bSjoergtemplate <class _NodePtr> 264*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 265*4d6fc14bSjoerg 266*4d6fc14bSjoerg 267*4d6fc14bSjoergtemplate <class _NodeValueTp, class _VoidPtr> 268*4d6fc14bSjoergstruct __make_hash_node_types { 269*4d6fc14bSjoerg typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; 270*4d6fc14bSjoerg typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; 271*4d6fc14bSjoerg typedef __hash_node_types<_NodePtr> type; 272*4d6fc14bSjoerg}; 273*4d6fc14bSjoerg 274*4d6fc14bSjoergtemplate <class _NodePtr> 275*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_iterator 276*4d6fc14bSjoerg{ 277*4d6fc14bSjoerg typedef __hash_node_types<_NodePtr> _NodeTypes; 278*4d6fc14bSjoerg typedef _NodePtr __node_pointer; 279*4d6fc14bSjoerg typedef typename _NodeTypes::__next_pointer __next_pointer; 280*4d6fc14bSjoerg 281*4d6fc14bSjoerg __next_pointer __node_; 282*4d6fc14bSjoerg 283*4d6fc14bSjoergpublic: 284*4d6fc14bSjoerg typedef forward_iterator_tag iterator_category; 285*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type value_type; 286*4d6fc14bSjoerg typedef typename _NodeTypes::difference_type difference_type; 287*4d6fc14bSjoerg typedef value_type& reference; 288*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type_pointer pointer; 289*4d6fc14bSjoerg 290*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { 291*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 292*4d6fc14bSjoerg __get_db()->__insert_i(this); 293*4d6fc14bSjoerg#endif 294*4d6fc14bSjoerg } 295*4d6fc14bSjoerg 296*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 297*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 298*4d6fc14bSjoerg __hash_iterator(const __hash_iterator& __i) 299*4d6fc14bSjoerg : __node_(__i.__node_) 300*4d6fc14bSjoerg { 301*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 302*4d6fc14bSjoerg } 303*4d6fc14bSjoerg 304*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 305*4d6fc14bSjoerg ~__hash_iterator() 306*4d6fc14bSjoerg { 307*4d6fc14bSjoerg __get_db()->__erase_i(this); 308*4d6fc14bSjoerg } 309*4d6fc14bSjoerg 310*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 311*4d6fc14bSjoerg __hash_iterator& operator=(const __hash_iterator& __i) 312*4d6fc14bSjoerg { 313*4d6fc14bSjoerg if (this != &__i) 314*4d6fc14bSjoerg { 315*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 316*4d6fc14bSjoerg __node_ = __i.__node_; 317*4d6fc14bSjoerg } 318*4d6fc14bSjoerg return *this; 319*4d6fc14bSjoerg } 320*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2 321*4d6fc14bSjoerg 322*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 323*4d6fc14bSjoerg reference operator*() const { 324*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 325*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container iterator"); 326*4d6fc14bSjoerg return __node_->__upcast()->__value_; 327*4d6fc14bSjoerg } 328*4d6fc14bSjoerg 329*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 330*4d6fc14bSjoerg pointer operator->() const { 331*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 332*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container iterator"); 333*4d6fc14bSjoerg return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 334*4d6fc14bSjoerg } 335*4d6fc14bSjoerg 336*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 337*4d6fc14bSjoerg __hash_iterator& operator++() { 338*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 339*4d6fc14bSjoerg "Attempted to increment a non-incrementable unordered container iterator"); 340*4d6fc14bSjoerg __node_ = __node_->__next_; 341*4d6fc14bSjoerg return *this; 342*4d6fc14bSjoerg } 343*4d6fc14bSjoerg 344*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 345*4d6fc14bSjoerg __hash_iterator operator++(int) 346*4d6fc14bSjoerg { 347*4d6fc14bSjoerg __hash_iterator __t(*this); 348*4d6fc14bSjoerg ++(*this); 349*4d6fc14bSjoerg return __t; 350*4d6fc14bSjoerg } 351*4d6fc14bSjoerg 352*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 353*4d6fc14bSjoerg bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) 354*4d6fc14bSjoerg { 355*4d6fc14bSjoerg return __x.__node_ == __y.__node_; 356*4d6fc14bSjoerg } 357*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 358*4d6fc14bSjoerg bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) 359*4d6fc14bSjoerg {return !(__x == __y);} 360*4d6fc14bSjoerg 361*4d6fc14bSjoergprivate: 362*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 363*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 364*4d6fc14bSjoerg __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT 365*4d6fc14bSjoerg : __node_(__node) 366*4d6fc14bSjoerg { 367*4d6fc14bSjoerg __get_db()->__insert_ic(this, __c); 368*4d6fc14bSjoerg } 369*4d6fc14bSjoerg#else 370*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 371*4d6fc14bSjoerg __hash_iterator(__next_pointer __node) _NOEXCEPT 372*4d6fc14bSjoerg : __node_(__node) 373*4d6fc14bSjoerg {} 374*4d6fc14bSjoerg#endif 375*4d6fc14bSjoerg template <class, class, class, class> friend class __hash_table; 376*4d6fc14bSjoerg template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 377*4d6fc14bSjoerg template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 378*4d6fc14bSjoerg template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 379*4d6fc14bSjoerg template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 380*4d6fc14bSjoerg}; 381*4d6fc14bSjoerg 382*4d6fc14bSjoergtemplate <class _NodePtr> 383*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_const_iterator 384*4d6fc14bSjoerg{ 385*4d6fc14bSjoerg static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, ""); 386*4d6fc14bSjoerg typedef __hash_node_types<_NodePtr> _NodeTypes; 387*4d6fc14bSjoerg typedef _NodePtr __node_pointer; 388*4d6fc14bSjoerg typedef typename _NodeTypes::__next_pointer __next_pointer; 389*4d6fc14bSjoerg 390*4d6fc14bSjoerg __next_pointer __node_; 391*4d6fc14bSjoerg 392*4d6fc14bSjoergpublic: 393*4d6fc14bSjoerg typedef __hash_iterator<_NodePtr> __non_const_iterator; 394*4d6fc14bSjoerg 395*4d6fc14bSjoerg typedef forward_iterator_tag iterator_category; 396*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type value_type; 397*4d6fc14bSjoerg typedef typename _NodeTypes::difference_type difference_type; 398*4d6fc14bSjoerg typedef const value_type& reference; 399*4d6fc14bSjoerg typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 400*4d6fc14bSjoerg 401*4d6fc14bSjoerg 402*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { 403*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 404*4d6fc14bSjoerg __get_db()->__insert_i(this); 405*4d6fc14bSjoerg#endif 406*4d6fc14bSjoerg } 407*4d6fc14bSjoerg 408*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 409*4d6fc14bSjoerg __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT 410*4d6fc14bSjoerg : __node_(__x.__node_) 411*4d6fc14bSjoerg { 412*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 413*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__x); 414*4d6fc14bSjoerg#endif 415*4d6fc14bSjoerg } 416*4d6fc14bSjoerg 417*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 418*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 419*4d6fc14bSjoerg __hash_const_iterator(const __hash_const_iterator& __i) 420*4d6fc14bSjoerg : __node_(__i.__node_) 421*4d6fc14bSjoerg { 422*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 423*4d6fc14bSjoerg } 424*4d6fc14bSjoerg 425*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 426*4d6fc14bSjoerg ~__hash_const_iterator() 427*4d6fc14bSjoerg { 428*4d6fc14bSjoerg __get_db()->__erase_i(this); 429*4d6fc14bSjoerg } 430*4d6fc14bSjoerg 431*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 432*4d6fc14bSjoerg __hash_const_iterator& operator=(const __hash_const_iterator& __i) 433*4d6fc14bSjoerg { 434*4d6fc14bSjoerg if (this != &__i) 435*4d6fc14bSjoerg { 436*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 437*4d6fc14bSjoerg __node_ = __i.__node_; 438*4d6fc14bSjoerg } 439*4d6fc14bSjoerg return *this; 440*4d6fc14bSjoerg } 441*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2 442*4d6fc14bSjoerg 443*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 444*4d6fc14bSjoerg reference operator*() const { 445*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 446*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container const_iterator"); 447*4d6fc14bSjoerg return __node_->__upcast()->__value_; 448*4d6fc14bSjoerg } 449*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 450*4d6fc14bSjoerg pointer operator->() const { 451*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 452*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container const_iterator"); 453*4d6fc14bSjoerg return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 454*4d6fc14bSjoerg } 455*4d6fc14bSjoerg 456*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 457*4d6fc14bSjoerg __hash_const_iterator& operator++() { 458*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 459*4d6fc14bSjoerg "Attempted to increment a non-incrementable unordered container const_iterator"); 460*4d6fc14bSjoerg __node_ = __node_->__next_; 461*4d6fc14bSjoerg return *this; 462*4d6fc14bSjoerg } 463*4d6fc14bSjoerg 464*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 465*4d6fc14bSjoerg __hash_const_iterator operator++(int) 466*4d6fc14bSjoerg { 467*4d6fc14bSjoerg __hash_const_iterator __t(*this); 468*4d6fc14bSjoerg ++(*this); 469*4d6fc14bSjoerg return __t; 470*4d6fc14bSjoerg } 471*4d6fc14bSjoerg 472*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 473*4d6fc14bSjoerg bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) 474*4d6fc14bSjoerg { 475*4d6fc14bSjoerg return __x.__node_ == __y.__node_; 476*4d6fc14bSjoerg } 477*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 478*4d6fc14bSjoerg bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) 479*4d6fc14bSjoerg {return !(__x == __y);} 480*4d6fc14bSjoerg 481*4d6fc14bSjoergprivate: 482*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 483*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 484*4d6fc14bSjoerg __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT 485*4d6fc14bSjoerg : __node_(__node) 486*4d6fc14bSjoerg { 487*4d6fc14bSjoerg __get_db()->__insert_ic(this, __c); 488*4d6fc14bSjoerg } 489*4d6fc14bSjoerg#else 490*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 491*4d6fc14bSjoerg __hash_const_iterator(__next_pointer __node) _NOEXCEPT 492*4d6fc14bSjoerg : __node_(__node) 493*4d6fc14bSjoerg {} 494*4d6fc14bSjoerg#endif 495*4d6fc14bSjoerg template <class, class, class, class> friend class __hash_table; 496*4d6fc14bSjoerg template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 497*4d6fc14bSjoerg template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 498*4d6fc14bSjoerg template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 499*4d6fc14bSjoerg}; 500*4d6fc14bSjoerg 501*4d6fc14bSjoergtemplate <class _NodePtr> 502*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_local_iterator 503*4d6fc14bSjoerg{ 504*4d6fc14bSjoerg typedef __hash_node_types<_NodePtr> _NodeTypes; 505*4d6fc14bSjoerg typedef _NodePtr __node_pointer; 506*4d6fc14bSjoerg typedef typename _NodeTypes::__next_pointer __next_pointer; 507*4d6fc14bSjoerg 508*4d6fc14bSjoerg __next_pointer __node_; 509*4d6fc14bSjoerg size_t __bucket_; 510*4d6fc14bSjoerg size_t __bucket_count_; 511*4d6fc14bSjoerg 512*4d6fc14bSjoergpublic: 513*4d6fc14bSjoerg typedef forward_iterator_tag iterator_category; 514*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type value_type; 515*4d6fc14bSjoerg typedef typename _NodeTypes::difference_type difference_type; 516*4d6fc14bSjoerg typedef value_type& reference; 517*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type_pointer pointer; 518*4d6fc14bSjoerg 519*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { 520*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 521*4d6fc14bSjoerg __get_db()->__insert_i(this); 522*4d6fc14bSjoerg#endif 523*4d6fc14bSjoerg } 524*4d6fc14bSjoerg 525*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 526*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 527*4d6fc14bSjoerg __hash_local_iterator(const __hash_local_iterator& __i) 528*4d6fc14bSjoerg : __node_(__i.__node_), 529*4d6fc14bSjoerg __bucket_(__i.__bucket_), 530*4d6fc14bSjoerg __bucket_count_(__i.__bucket_count_) 531*4d6fc14bSjoerg { 532*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 533*4d6fc14bSjoerg } 534*4d6fc14bSjoerg 535*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 536*4d6fc14bSjoerg ~__hash_local_iterator() 537*4d6fc14bSjoerg { 538*4d6fc14bSjoerg __get_db()->__erase_i(this); 539*4d6fc14bSjoerg } 540*4d6fc14bSjoerg 541*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 542*4d6fc14bSjoerg __hash_local_iterator& operator=(const __hash_local_iterator& __i) 543*4d6fc14bSjoerg { 544*4d6fc14bSjoerg if (this != &__i) 545*4d6fc14bSjoerg { 546*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 547*4d6fc14bSjoerg __node_ = __i.__node_; 548*4d6fc14bSjoerg __bucket_ = __i.__bucket_; 549*4d6fc14bSjoerg __bucket_count_ = __i.__bucket_count_; 550*4d6fc14bSjoerg } 551*4d6fc14bSjoerg return *this; 552*4d6fc14bSjoerg } 553*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2 554*4d6fc14bSjoerg 555*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 556*4d6fc14bSjoerg reference operator*() const { 557*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 558*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container local_iterator"); 559*4d6fc14bSjoerg return __node_->__upcast()->__value_; 560*4d6fc14bSjoerg } 561*4d6fc14bSjoerg 562*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 563*4d6fc14bSjoerg pointer operator->() const { 564*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 565*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container local_iterator"); 566*4d6fc14bSjoerg return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 567*4d6fc14bSjoerg } 568*4d6fc14bSjoerg 569*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 570*4d6fc14bSjoerg __hash_local_iterator& operator++() { 571*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 572*4d6fc14bSjoerg "Attempted to increment a non-incrementable unordered container local_iterator"); 573*4d6fc14bSjoerg __node_ = __node_->__next_; 574*4d6fc14bSjoerg if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) 575*4d6fc14bSjoerg __node_ = nullptr; 576*4d6fc14bSjoerg return *this; 577*4d6fc14bSjoerg } 578*4d6fc14bSjoerg 579*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 580*4d6fc14bSjoerg __hash_local_iterator operator++(int) 581*4d6fc14bSjoerg { 582*4d6fc14bSjoerg __hash_local_iterator __t(*this); 583*4d6fc14bSjoerg ++(*this); 584*4d6fc14bSjoerg return __t; 585*4d6fc14bSjoerg } 586*4d6fc14bSjoerg 587*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 588*4d6fc14bSjoerg bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) 589*4d6fc14bSjoerg { 590*4d6fc14bSjoerg return __x.__node_ == __y.__node_; 591*4d6fc14bSjoerg } 592*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 593*4d6fc14bSjoerg bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) 594*4d6fc14bSjoerg {return !(__x == __y);} 595*4d6fc14bSjoerg 596*4d6fc14bSjoergprivate: 597*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 598*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 599*4d6fc14bSjoerg __hash_local_iterator(__next_pointer __node, size_t __bucket, 600*4d6fc14bSjoerg size_t __bucket_count, const void* __c) _NOEXCEPT 601*4d6fc14bSjoerg : __node_(__node), 602*4d6fc14bSjoerg __bucket_(__bucket), 603*4d6fc14bSjoerg __bucket_count_(__bucket_count) 604*4d6fc14bSjoerg { 605*4d6fc14bSjoerg __get_db()->__insert_ic(this, __c); 606*4d6fc14bSjoerg if (__node_ != nullptr) 607*4d6fc14bSjoerg __node_ = __node_->__next_; 608*4d6fc14bSjoerg } 609*4d6fc14bSjoerg#else 610*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 611*4d6fc14bSjoerg __hash_local_iterator(__next_pointer __node, size_t __bucket, 612*4d6fc14bSjoerg size_t __bucket_count) _NOEXCEPT 613*4d6fc14bSjoerg : __node_(__node), 614*4d6fc14bSjoerg __bucket_(__bucket), 615*4d6fc14bSjoerg __bucket_count_(__bucket_count) 616*4d6fc14bSjoerg { 617*4d6fc14bSjoerg if (__node_ != nullptr) 618*4d6fc14bSjoerg __node_ = __node_->__next_; 619*4d6fc14bSjoerg } 620*4d6fc14bSjoerg#endif 621*4d6fc14bSjoerg template <class, class, class, class> friend class __hash_table; 622*4d6fc14bSjoerg template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 623*4d6fc14bSjoerg template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 624*4d6fc14bSjoerg}; 625*4d6fc14bSjoerg 626*4d6fc14bSjoergtemplate <class _ConstNodePtr> 627*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator 628*4d6fc14bSjoerg{ 629*4d6fc14bSjoerg typedef __hash_node_types<_ConstNodePtr> _NodeTypes; 630*4d6fc14bSjoerg typedef _ConstNodePtr __node_pointer; 631*4d6fc14bSjoerg typedef typename _NodeTypes::__next_pointer __next_pointer; 632*4d6fc14bSjoerg 633*4d6fc14bSjoerg __next_pointer __node_; 634*4d6fc14bSjoerg size_t __bucket_; 635*4d6fc14bSjoerg size_t __bucket_count_; 636*4d6fc14bSjoerg 637*4d6fc14bSjoerg typedef pointer_traits<__node_pointer> __pointer_traits; 638*4d6fc14bSjoerg typedef typename __pointer_traits::element_type __node; 639*4d6fc14bSjoerg typedef typename remove_const<__node>::type __non_const_node; 640*4d6fc14bSjoerg typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type 641*4d6fc14bSjoerg __non_const_node_pointer; 642*4d6fc14bSjoergpublic: 643*4d6fc14bSjoerg typedef __hash_local_iterator<__non_const_node_pointer> 644*4d6fc14bSjoerg __non_const_iterator; 645*4d6fc14bSjoerg 646*4d6fc14bSjoerg typedef forward_iterator_tag iterator_category; 647*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type value_type; 648*4d6fc14bSjoerg typedef typename _NodeTypes::difference_type difference_type; 649*4d6fc14bSjoerg typedef const value_type& reference; 650*4d6fc14bSjoerg typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 651*4d6fc14bSjoerg 652*4d6fc14bSjoerg 653*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { 654*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 655*4d6fc14bSjoerg __get_db()->__insert_i(this); 656*4d6fc14bSjoerg#endif 657*4d6fc14bSjoerg } 658*4d6fc14bSjoerg 659*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 660*4d6fc14bSjoerg __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT 661*4d6fc14bSjoerg : __node_(__x.__node_), 662*4d6fc14bSjoerg __bucket_(__x.__bucket_), 663*4d6fc14bSjoerg __bucket_count_(__x.__bucket_count_) 664*4d6fc14bSjoerg { 665*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 666*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__x); 667*4d6fc14bSjoerg#endif 668*4d6fc14bSjoerg } 669*4d6fc14bSjoerg 670*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 671*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 672*4d6fc14bSjoerg __hash_const_local_iterator(const __hash_const_local_iterator& __i) 673*4d6fc14bSjoerg : __node_(__i.__node_), 674*4d6fc14bSjoerg __bucket_(__i.__bucket_), 675*4d6fc14bSjoerg __bucket_count_(__i.__bucket_count_) 676*4d6fc14bSjoerg { 677*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 678*4d6fc14bSjoerg } 679*4d6fc14bSjoerg 680*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 681*4d6fc14bSjoerg ~__hash_const_local_iterator() 682*4d6fc14bSjoerg { 683*4d6fc14bSjoerg __get_db()->__erase_i(this); 684*4d6fc14bSjoerg } 685*4d6fc14bSjoerg 686*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 687*4d6fc14bSjoerg __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) 688*4d6fc14bSjoerg { 689*4d6fc14bSjoerg if (this != &__i) 690*4d6fc14bSjoerg { 691*4d6fc14bSjoerg __get_db()->__iterator_copy(this, &__i); 692*4d6fc14bSjoerg __node_ = __i.__node_; 693*4d6fc14bSjoerg __bucket_ = __i.__bucket_; 694*4d6fc14bSjoerg __bucket_count_ = __i.__bucket_count_; 695*4d6fc14bSjoerg } 696*4d6fc14bSjoerg return *this; 697*4d6fc14bSjoerg } 698*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2 699*4d6fc14bSjoerg 700*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 701*4d6fc14bSjoerg reference operator*() const { 702*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 703*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); 704*4d6fc14bSjoerg return __node_->__upcast()->__value_; 705*4d6fc14bSjoerg } 706*4d6fc14bSjoerg 707*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 708*4d6fc14bSjoerg pointer operator->() const { 709*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 710*4d6fc14bSjoerg "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); 711*4d6fc14bSjoerg return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 712*4d6fc14bSjoerg } 713*4d6fc14bSjoerg 714*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 715*4d6fc14bSjoerg __hash_const_local_iterator& operator++() { 716*4d6fc14bSjoerg _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 717*4d6fc14bSjoerg "Attempted to increment a non-incrementable unordered container const_local_iterator"); 718*4d6fc14bSjoerg __node_ = __node_->__next_; 719*4d6fc14bSjoerg if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) 720*4d6fc14bSjoerg __node_ = nullptr; 721*4d6fc14bSjoerg return *this; 722*4d6fc14bSjoerg } 723*4d6fc14bSjoerg 724*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 725*4d6fc14bSjoerg __hash_const_local_iterator operator++(int) 726*4d6fc14bSjoerg { 727*4d6fc14bSjoerg __hash_const_local_iterator __t(*this); 728*4d6fc14bSjoerg ++(*this); 729*4d6fc14bSjoerg return __t; 730*4d6fc14bSjoerg } 731*4d6fc14bSjoerg 732*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 733*4d6fc14bSjoerg bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) 734*4d6fc14bSjoerg { 735*4d6fc14bSjoerg return __x.__node_ == __y.__node_; 736*4d6fc14bSjoerg } 737*4d6fc14bSjoerg friend _LIBCPP_INLINE_VISIBILITY 738*4d6fc14bSjoerg bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) 739*4d6fc14bSjoerg {return !(__x == __y);} 740*4d6fc14bSjoerg 741*4d6fc14bSjoergprivate: 742*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 743*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 744*4d6fc14bSjoerg __hash_const_local_iterator(__next_pointer __node, size_t __bucket, 745*4d6fc14bSjoerg size_t __bucket_count, const void* __c) _NOEXCEPT 746*4d6fc14bSjoerg : __node_(__node), 747*4d6fc14bSjoerg __bucket_(__bucket), 748*4d6fc14bSjoerg __bucket_count_(__bucket_count) 749*4d6fc14bSjoerg { 750*4d6fc14bSjoerg __get_db()->__insert_ic(this, __c); 751*4d6fc14bSjoerg if (__node_ != nullptr) 752*4d6fc14bSjoerg __node_ = __node_->__next_; 753*4d6fc14bSjoerg } 754*4d6fc14bSjoerg#else 755*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 756*4d6fc14bSjoerg __hash_const_local_iterator(__next_pointer __node, size_t __bucket, 757*4d6fc14bSjoerg size_t __bucket_count) _NOEXCEPT 758*4d6fc14bSjoerg : __node_(__node), 759*4d6fc14bSjoerg __bucket_(__bucket), 760*4d6fc14bSjoerg __bucket_count_(__bucket_count) 761*4d6fc14bSjoerg { 762*4d6fc14bSjoerg if (__node_ != nullptr) 763*4d6fc14bSjoerg __node_ = __node_->__next_; 764*4d6fc14bSjoerg } 765*4d6fc14bSjoerg#endif 766*4d6fc14bSjoerg template <class, class, class, class> friend class __hash_table; 767*4d6fc14bSjoerg template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 768*4d6fc14bSjoerg}; 769*4d6fc14bSjoerg 770*4d6fc14bSjoergtemplate <class _Alloc> 771*4d6fc14bSjoergclass __bucket_list_deallocator 772*4d6fc14bSjoerg{ 773*4d6fc14bSjoerg typedef _Alloc allocator_type; 774*4d6fc14bSjoerg typedef allocator_traits<allocator_type> __alloc_traits; 775*4d6fc14bSjoerg typedef typename __alloc_traits::size_type size_type; 776*4d6fc14bSjoerg 777*4d6fc14bSjoerg __compressed_pair<size_type, allocator_type> __data_; 778*4d6fc14bSjoergpublic: 779*4d6fc14bSjoerg typedef typename __alloc_traits::pointer pointer; 780*4d6fc14bSjoerg 781*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 782*4d6fc14bSjoerg __bucket_list_deallocator() 783*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 784*4d6fc14bSjoerg : __data_(0, __default_init_tag()) {} 785*4d6fc14bSjoerg 786*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 787*4d6fc14bSjoerg __bucket_list_deallocator(const allocator_type& __a, size_type __size) 788*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 789*4d6fc14bSjoerg : __data_(__size, __a) {} 790*4d6fc14bSjoerg 791*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 792*4d6fc14bSjoerg __bucket_list_deallocator(__bucket_list_deallocator&& __x) 793*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 794*4d6fc14bSjoerg : __data_(_VSTD::move(__x.__data_)) 795*4d6fc14bSjoerg { 796*4d6fc14bSjoerg __x.size() = 0; 797*4d6fc14bSjoerg } 798*4d6fc14bSjoerg 799*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 800*4d6fc14bSjoerg size_type& size() _NOEXCEPT {return __data_.first();} 801*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 802*4d6fc14bSjoerg size_type size() const _NOEXCEPT {return __data_.first();} 803*4d6fc14bSjoerg 804*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 805*4d6fc14bSjoerg allocator_type& __alloc() _NOEXCEPT {return __data_.second();} 806*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 807*4d6fc14bSjoerg const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} 808*4d6fc14bSjoerg 809*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 810*4d6fc14bSjoerg void operator()(pointer __p) _NOEXCEPT 811*4d6fc14bSjoerg { 812*4d6fc14bSjoerg __alloc_traits::deallocate(__alloc(), __p, size()); 813*4d6fc14bSjoerg } 814*4d6fc14bSjoerg}; 815*4d6fc14bSjoerg 816*4d6fc14bSjoergtemplate <class _Alloc> class __hash_map_node_destructor; 817*4d6fc14bSjoerg 818*4d6fc14bSjoergtemplate <class _Alloc> 819*4d6fc14bSjoergclass __hash_node_destructor 820*4d6fc14bSjoerg{ 821*4d6fc14bSjoerg typedef _Alloc allocator_type; 822*4d6fc14bSjoerg typedef allocator_traits<allocator_type> __alloc_traits; 823*4d6fc14bSjoerg 824*4d6fc14bSjoergpublic: 825*4d6fc14bSjoerg typedef typename __alloc_traits::pointer pointer; 826*4d6fc14bSjoergprivate: 827*4d6fc14bSjoerg typedef __hash_node_types<pointer> _NodeTypes; 828*4d6fc14bSjoerg 829*4d6fc14bSjoerg allocator_type& __na_; 830*4d6fc14bSjoerg 831*4d6fc14bSjoergpublic: 832*4d6fc14bSjoerg bool __value_constructed; 833*4d6fc14bSjoerg 834*4d6fc14bSjoerg __hash_node_destructor(__hash_node_destructor const&) = default; 835*4d6fc14bSjoerg __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; 836*4d6fc14bSjoerg 837*4d6fc14bSjoerg 838*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 839*4d6fc14bSjoerg explicit __hash_node_destructor(allocator_type& __na, 840*4d6fc14bSjoerg bool __constructed = false) _NOEXCEPT 841*4d6fc14bSjoerg : __na_(__na), 842*4d6fc14bSjoerg __value_constructed(__constructed) 843*4d6fc14bSjoerg {} 844*4d6fc14bSjoerg 845*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 846*4d6fc14bSjoerg void operator()(pointer __p) _NOEXCEPT 847*4d6fc14bSjoerg { 848*4d6fc14bSjoerg if (__value_constructed) 849*4d6fc14bSjoerg __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); 850*4d6fc14bSjoerg if (__p) 851*4d6fc14bSjoerg __alloc_traits::deallocate(__na_, __p, 1); 852*4d6fc14bSjoerg } 853*4d6fc14bSjoerg 854*4d6fc14bSjoerg template <class> friend class __hash_map_node_destructor; 855*4d6fc14bSjoerg}; 856*4d6fc14bSjoerg 857*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14 858*4d6fc14bSjoergtemplate <class _NodeType, class _Alloc> 859*4d6fc14bSjoergstruct __generic_container_node_destructor; 860*4d6fc14bSjoerg 861*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr, class _Alloc> 862*4d6fc14bSjoergstruct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> 863*4d6fc14bSjoerg : __hash_node_destructor<_Alloc> 864*4d6fc14bSjoerg{ 865*4d6fc14bSjoerg using __hash_node_destructor<_Alloc>::__hash_node_destructor; 866*4d6fc14bSjoerg}; 867*4d6fc14bSjoerg#endif 868*4d6fc14bSjoerg 869*4d6fc14bSjoergtemplate <class _Key, class _Hash, class _Equal> 870*4d6fc14bSjoergstruct __enforce_unordered_container_requirements { 871*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG 872*4d6fc14bSjoerg static_assert(__check_hash_requirements<_Key, _Hash>::value, 873*4d6fc14bSjoerg "the specified hash does not meet the Hash requirements"); 874*4d6fc14bSjoerg static_assert(is_copy_constructible<_Equal>::value, 875*4d6fc14bSjoerg "the specified comparator is required to be copy constructible"); 876*4d6fc14bSjoerg#endif 877*4d6fc14bSjoerg typedef int type; 878*4d6fc14bSjoerg}; 879*4d6fc14bSjoerg 880*4d6fc14bSjoergtemplate <class _Key, class _Hash, class _Equal> 881*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG 882*4d6fc14bSjoerg _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, 883*4d6fc14bSjoerg "the specified comparator type does not provide a viable const call operator") 884*4d6fc14bSjoerg _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, 885*4d6fc14bSjoerg "the specified hash functor does not provide a viable const call operator") 886*4d6fc14bSjoerg#endif 887*4d6fc14bSjoergtypename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type 888*4d6fc14bSjoerg__diagnose_unordered_container_requirements(int); 889*4d6fc14bSjoerg 890*4d6fc14bSjoerg// This dummy overload is used so that the compiler won't emit a spurious 891*4d6fc14bSjoerg// "no matching function for call to __diagnose_unordered_xxx" diagnostic 892*4d6fc14bSjoerg// when the overload above causes a hard error. 893*4d6fc14bSjoergtemplate <class _Key, class _Hash, class _Equal> 894*4d6fc14bSjoergint __diagnose_unordered_container_requirements(void*); 895*4d6fc14bSjoerg 896*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 897*4d6fc14bSjoergclass __hash_table 898*4d6fc14bSjoerg{ 899*4d6fc14bSjoergpublic: 900*4d6fc14bSjoerg typedef _Tp value_type; 901*4d6fc14bSjoerg typedef _Hash hasher; 902*4d6fc14bSjoerg typedef _Equal key_equal; 903*4d6fc14bSjoerg typedef _Alloc allocator_type; 904*4d6fc14bSjoerg 905*4d6fc14bSjoergprivate: 906*4d6fc14bSjoerg typedef allocator_traits<allocator_type> __alloc_traits; 907*4d6fc14bSjoerg typedef typename 908*4d6fc14bSjoerg __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type 909*4d6fc14bSjoerg _NodeTypes; 910*4d6fc14bSjoergpublic: 911*4d6fc14bSjoerg 912*4d6fc14bSjoerg typedef typename _NodeTypes::__node_value_type __node_value_type; 913*4d6fc14bSjoerg typedef typename _NodeTypes::__container_value_type __container_value_type; 914*4d6fc14bSjoerg typedef typename _NodeTypes::key_type key_type; 915*4d6fc14bSjoerg typedef value_type& reference; 916*4d6fc14bSjoerg typedef const value_type& const_reference; 917*4d6fc14bSjoerg typedef typename __alloc_traits::pointer pointer; 918*4d6fc14bSjoerg typedef typename __alloc_traits::const_pointer const_pointer; 919*4d6fc14bSjoerg#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE 920*4d6fc14bSjoerg typedef typename __alloc_traits::size_type size_type; 921*4d6fc14bSjoerg#else 922*4d6fc14bSjoerg typedef typename _NodeTypes::size_type size_type; 923*4d6fc14bSjoerg#endif 924*4d6fc14bSjoerg typedef typename _NodeTypes::difference_type difference_type; 925*4d6fc14bSjoergpublic: 926*4d6fc14bSjoerg // Create __node 927*4d6fc14bSjoerg 928*4d6fc14bSjoerg typedef typename _NodeTypes::__node_type __node; 929*4d6fc14bSjoerg typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; 930*4d6fc14bSjoerg typedef allocator_traits<__node_allocator> __node_traits; 931*4d6fc14bSjoerg typedef typename _NodeTypes::__void_pointer __void_pointer; 932*4d6fc14bSjoerg typedef typename _NodeTypes::__node_pointer __node_pointer; 933*4d6fc14bSjoerg typedef typename _NodeTypes::__node_pointer __node_const_pointer; 934*4d6fc14bSjoerg typedef typename _NodeTypes::__node_base_type __first_node; 935*4d6fc14bSjoerg typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 936*4d6fc14bSjoerg typedef typename _NodeTypes::__next_pointer __next_pointer; 937*4d6fc14bSjoerg 938*4d6fc14bSjoergprivate: 939*4d6fc14bSjoerg // check for sane allocator pointer rebinding semantics. Rebinding the 940*4d6fc14bSjoerg // allocator for a new pointer type should be exactly the same as rebinding 941*4d6fc14bSjoerg // the pointer using 'pointer_traits'. 942*4d6fc14bSjoerg static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), 943*4d6fc14bSjoerg "Allocator does not rebind pointers in a sane manner."); 944*4d6fc14bSjoerg typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type 945*4d6fc14bSjoerg __node_base_allocator; 946*4d6fc14bSjoerg typedef allocator_traits<__node_base_allocator> __node_base_traits; 947*4d6fc14bSjoerg static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), 948*4d6fc14bSjoerg "Allocator does not rebind pointers in a sane manner."); 949*4d6fc14bSjoerg 950*4d6fc14bSjoergprivate: 951*4d6fc14bSjoerg 952*4d6fc14bSjoerg typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator; 953*4d6fc14bSjoerg typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; 954*4d6fc14bSjoerg typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; 955*4d6fc14bSjoerg typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; 956*4d6fc14bSjoerg typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; 957*4d6fc14bSjoerg 958*4d6fc14bSjoerg // --- Member data begin --- 959*4d6fc14bSjoerg __bucket_list __bucket_list_; 960*4d6fc14bSjoerg __compressed_pair<__first_node, __node_allocator> __p1_; 961*4d6fc14bSjoerg __compressed_pair<size_type, hasher> __p2_; 962*4d6fc14bSjoerg __compressed_pair<float, key_equal> __p3_; 963*4d6fc14bSjoerg // --- Member data end --- 964*4d6fc14bSjoerg 965*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 966*4d6fc14bSjoerg size_type& size() _NOEXCEPT {return __p2_.first();} 967*4d6fc14bSjoergpublic: 968*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 969*4d6fc14bSjoerg size_type size() const _NOEXCEPT {return __p2_.first();} 970*4d6fc14bSjoerg 971*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 972*4d6fc14bSjoerg hasher& hash_function() _NOEXCEPT {return __p2_.second();} 973*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 974*4d6fc14bSjoerg const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} 975*4d6fc14bSjoerg 976*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 977*4d6fc14bSjoerg float& max_load_factor() _NOEXCEPT {return __p3_.first();} 978*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 979*4d6fc14bSjoerg float max_load_factor() const _NOEXCEPT {return __p3_.first();} 980*4d6fc14bSjoerg 981*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 982*4d6fc14bSjoerg key_equal& key_eq() _NOEXCEPT {return __p3_.second();} 983*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 984*4d6fc14bSjoerg const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} 985*4d6fc14bSjoerg 986*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 987*4d6fc14bSjoerg __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} 988*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 989*4d6fc14bSjoerg const __node_allocator& __node_alloc() const _NOEXCEPT 990*4d6fc14bSjoerg {return __p1_.second();} 991*4d6fc14bSjoerg 992*4d6fc14bSjoergpublic: 993*4d6fc14bSjoerg typedef __hash_iterator<__node_pointer> iterator; 994*4d6fc14bSjoerg typedef __hash_const_iterator<__node_pointer> const_iterator; 995*4d6fc14bSjoerg typedef __hash_local_iterator<__node_pointer> local_iterator; 996*4d6fc14bSjoerg typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; 997*4d6fc14bSjoerg 998*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 999*4d6fc14bSjoerg __hash_table() 1000*4d6fc14bSjoerg _NOEXCEPT_( 1001*4d6fc14bSjoerg is_nothrow_default_constructible<__bucket_list>::value && 1002*4d6fc14bSjoerg is_nothrow_default_constructible<__first_node>::value && 1003*4d6fc14bSjoerg is_nothrow_default_constructible<__node_allocator>::value && 1004*4d6fc14bSjoerg is_nothrow_default_constructible<hasher>::value && 1005*4d6fc14bSjoerg is_nothrow_default_constructible<key_equal>::value); 1006*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1007*4d6fc14bSjoerg __hash_table(const hasher& __hf, const key_equal& __eql); 1008*4d6fc14bSjoerg __hash_table(const hasher& __hf, const key_equal& __eql, 1009*4d6fc14bSjoerg const allocator_type& __a); 1010*4d6fc14bSjoerg explicit __hash_table(const allocator_type& __a); 1011*4d6fc14bSjoerg __hash_table(const __hash_table& __u); 1012*4d6fc14bSjoerg __hash_table(const __hash_table& __u, const allocator_type& __a); 1013*4d6fc14bSjoerg __hash_table(__hash_table&& __u) 1014*4d6fc14bSjoerg _NOEXCEPT_( 1015*4d6fc14bSjoerg is_nothrow_move_constructible<__bucket_list>::value && 1016*4d6fc14bSjoerg is_nothrow_move_constructible<__first_node>::value && 1017*4d6fc14bSjoerg is_nothrow_move_constructible<__node_allocator>::value && 1018*4d6fc14bSjoerg is_nothrow_move_constructible<hasher>::value && 1019*4d6fc14bSjoerg is_nothrow_move_constructible<key_equal>::value); 1020*4d6fc14bSjoerg __hash_table(__hash_table&& __u, const allocator_type& __a); 1021*4d6fc14bSjoerg ~__hash_table(); 1022*4d6fc14bSjoerg 1023*4d6fc14bSjoerg __hash_table& operator=(const __hash_table& __u); 1024*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1025*4d6fc14bSjoerg __hash_table& operator=(__hash_table&& __u) 1026*4d6fc14bSjoerg _NOEXCEPT_( 1027*4d6fc14bSjoerg __node_traits::propagate_on_container_move_assignment::value && 1028*4d6fc14bSjoerg is_nothrow_move_assignable<__node_allocator>::value && 1029*4d6fc14bSjoerg is_nothrow_move_assignable<hasher>::value && 1030*4d6fc14bSjoerg is_nothrow_move_assignable<key_equal>::value); 1031*4d6fc14bSjoerg template <class _InputIterator> 1032*4d6fc14bSjoerg void __assign_unique(_InputIterator __first, _InputIterator __last); 1033*4d6fc14bSjoerg template <class _InputIterator> 1034*4d6fc14bSjoerg void __assign_multi(_InputIterator __first, _InputIterator __last); 1035*4d6fc14bSjoerg 1036*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1037*4d6fc14bSjoerg size_type max_size() const _NOEXCEPT 1038*4d6fc14bSjoerg { 1039*4d6fc14bSjoerg return _VSTD::min<size_type>( 1040*4d6fc14bSjoerg __node_traits::max_size(__node_alloc()), 1041*4d6fc14bSjoerg numeric_limits<difference_type >::max() 1042*4d6fc14bSjoerg ); 1043*4d6fc14bSjoerg } 1044*4d6fc14bSjoerg 1045*4d6fc14bSjoergprivate: 1046*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1047*4d6fc14bSjoerg __next_pointer __node_insert_multi_prepare(size_t __cp_hash, 1048*4d6fc14bSjoerg value_type& __cp_val); 1049*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1050*4d6fc14bSjoerg void __node_insert_multi_perform(__node_pointer __cp, 1051*4d6fc14bSjoerg __next_pointer __pn) _NOEXCEPT; 1052*4d6fc14bSjoerg 1053*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1054*4d6fc14bSjoerg __next_pointer __node_insert_unique_prepare(size_t __nd_hash, 1055*4d6fc14bSjoerg value_type& __nd_val); 1056*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1057*4d6fc14bSjoerg void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; 1058*4d6fc14bSjoerg 1059*4d6fc14bSjoergpublic: 1060*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1061*4d6fc14bSjoerg pair<iterator, bool> __node_insert_unique(__node_pointer __nd); 1062*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1063*4d6fc14bSjoerg iterator __node_insert_multi(__node_pointer __nd); 1064*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1065*4d6fc14bSjoerg iterator __node_insert_multi(const_iterator __p, 1066*4d6fc14bSjoerg __node_pointer __nd); 1067*4d6fc14bSjoerg 1068*4d6fc14bSjoerg template <class _Key, class ..._Args> 1069*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1070*4d6fc14bSjoerg pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args); 1071*4d6fc14bSjoerg 1072*4d6fc14bSjoerg template <class... _Args> 1073*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1074*4d6fc14bSjoerg pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); 1075*4d6fc14bSjoerg 1076*4d6fc14bSjoerg template <class _Pp> 1077*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1078*4d6fc14bSjoerg pair<iterator, bool> __emplace_unique(_Pp&& __x) { 1079*4d6fc14bSjoerg return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), 1080*4d6fc14bSjoerg __can_extract_key<_Pp, key_type>()); 1081*4d6fc14bSjoerg } 1082*4d6fc14bSjoerg 1083*4d6fc14bSjoerg template <class _First, class _Second> 1084*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1085*4d6fc14bSjoerg typename enable_if< 1086*4d6fc14bSjoerg __can_extract_map_key<_First, key_type, __container_value_type>::value, 1087*4d6fc14bSjoerg pair<iterator, bool> 1088*4d6fc14bSjoerg >::type __emplace_unique(_First&& __f, _Second&& __s) { 1089*4d6fc14bSjoerg return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), 1090*4d6fc14bSjoerg _VSTD::forward<_Second>(__s)); 1091*4d6fc14bSjoerg } 1092*4d6fc14bSjoerg 1093*4d6fc14bSjoerg template <class... _Args> 1094*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1095*4d6fc14bSjoerg pair<iterator, bool> __emplace_unique(_Args&&... __args) { 1096*4d6fc14bSjoerg return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); 1097*4d6fc14bSjoerg } 1098*4d6fc14bSjoerg 1099*4d6fc14bSjoerg template <class _Pp> 1100*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1101*4d6fc14bSjoerg pair<iterator, bool> 1102*4d6fc14bSjoerg __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { 1103*4d6fc14bSjoerg return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); 1104*4d6fc14bSjoerg } 1105*4d6fc14bSjoerg template <class _Pp> 1106*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1107*4d6fc14bSjoerg pair<iterator, bool> 1108*4d6fc14bSjoerg __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { 1109*4d6fc14bSjoerg return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); 1110*4d6fc14bSjoerg } 1111*4d6fc14bSjoerg template <class _Pp> 1112*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1113*4d6fc14bSjoerg pair<iterator, bool> 1114*4d6fc14bSjoerg __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { 1115*4d6fc14bSjoerg return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); 1116*4d6fc14bSjoerg } 1117*4d6fc14bSjoerg 1118*4d6fc14bSjoerg template <class... _Args> 1119*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1120*4d6fc14bSjoerg iterator __emplace_multi(_Args&&... __args); 1121*4d6fc14bSjoerg template <class... _Args> 1122*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1123*4d6fc14bSjoerg iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); 1124*4d6fc14bSjoerg 1125*4d6fc14bSjoerg 1126*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1127*4d6fc14bSjoerg pair<iterator, bool> 1128*4d6fc14bSjoerg __insert_unique(__container_value_type&& __x) { 1129*4d6fc14bSjoerg return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); 1130*4d6fc14bSjoerg } 1131*4d6fc14bSjoerg 1132*4d6fc14bSjoerg template <class _Pp, class = typename enable_if< 1133*4d6fc14bSjoerg !__is_same_uncvref<_Pp, __container_value_type>::value 1134*4d6fc14bSjoerg >::type> 1135*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1136*4d6fc14bSjoerg pair<iterator, bool> __insert_unique(_Pp&& __x) { 1137*4d6fc14bSjoerg return __emplace_unique(_VSTD::forward<_Pp>(__x)); 1138*4d6fc14bSjoerg } 1139*4d6fc14bSjoerg 1140*4d6fc14bSjoerg template <class _Pp> 1141*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1142*4d6fc14bSjoerg iterator __insert_multi(_Pp&& __x) { 1143*4d6fc14bSjoerg return __emplace_multi(_VSTD::forward<_Pp>(__x)); 1144*4d6fc14bSjoerg } 1145*4d6fc14bSjoerg 1146*4d6fc14bSjoerg template <class _Pp> 1147*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1148*4d6fc14bSjoerg iterator __insert_multi(const_iterator __p, _Pp&& __x) { 1149*4d6fc14bSjoerg return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); 1150*4d6fc14bSjoerg } 1151*4d6fc14bSjoerg 1152*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1153*4d6fc14bSjoerg pair<iterator, bool> __insert_unique(const __container_value_type& __x) { 1154*4d6fc14bSjoerg return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); 1155*4d6fc14bSjoerg } 1156*4d6fc14bSjoerg 1157*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14 1158*4d6fc14bSjoerg template <class _NodeHandle, class _InsertReturnType> 1159*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1160*4d6fc14bSjoerg _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); 1161*4d6fc14bSjoerg template <class _NodeHandle> 1162*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1163*4d6fc14bSjoerg iterator __node_handle_insert_unique(const_iterator __hint, 1164*4d6fc14bSjoerg _NodeHandle&& __nh); 1165*4d6fc14bSjoerg template <class _Table> 1166*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1167*4d6fc14bSjoerg void __node_handle_merge_unique(_Table& __source); 1168*4d6fc14bSjoerg 1169*4d6fc14bSjoerg template <class _NodeHandle> 1170*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1171*4d6fc14bSjoerg iterator __node_handle_insert_multi(_NodeHandle&& __nh); 1172*4d6fc14bSjoerg template <class _NodeHandle> 1173*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1174*4d6fc14bSjoerg iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); 1175*4d6fc14bSjoerg template <class _Table> 1176*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1177*4d6fc14bSjoerg void __node_handle_merge_multi(_Table& __source); 1178*4d6fc14bSjoerg 1179*4d6fc14bSjoerg template <class _NodeHandle> 1180*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1181*4d6fc14bSjoerg _NodeHandle __node_handle_extract(key_type const& __key); 1182*4d6fc14bSjoerg template <class _NodeHandle> 1183*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1184*4d6fc14bSjoerg _NodeHandle __node_handle_extract(const_iterator __it); 1185*4d6fc14bSjoerg#endif 1186*4d6fc14bSjoerg 1187*4d6fc14bSjoerg void clear() _NOEXCEPT; 1188*4d6fc14bSjoerg void rehash(size_type __n); 1189*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) 1190*4d6fc14bSjoerg {rehash(static_cast<size_type>(ceil(__n / max_load_factor())));} 1191*4d6fc14bSjoerg 1192*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1193*4d6fc14bSjoerg size_type bucket_count() const _NOEXCEPT 1194*4d6fc14bSjoerg { 1195*4d6fc14bSjoerg return __bucket_list_.get_deleter().size(); 1196*4d6fc14bSjoerg } 1197*4d6fc14bSjoerg 1198*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1199*4d6fc14bSjoerg iterator begin() _NOEXCEPT; 1200*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1201*4d6fc14bSjoerg iterator end() _NOEXCEPT; 1202*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1203*4d6fc14bSjoerg const_iterator begin() const _NOEXCEPT; 1204*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1205*4d6fc14bSjoerg const_iterator end() const _NOEXCEPT; 1206*4d6fc14bSjoerg 1207*4d6fc14bSjoerg template <class _Key> 1208*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1209*4d6fc14bSjoerg size_type bucket(const _Key& __k) const 1210*4d6fc14bSjoerg { 1211*4d6fc14bSjoerg _LIBCPP_ASSERT(bucket_count() > 0, 1212*4d6fc14bSjoerg "unordered container::bucket(key) called when bucket_count() == 0"); 1213*4d6fc14bSjoerg return __constrain_hash(hash_function()(__k), bucket_count()); 1214*4d6fc14bSjoerg } 1215*4d6fc14bSjoerg 1216*4d6fc14bSjoerg template <class _Key> 1217*4d6fc14bSjoerg iterator find(const _Key& __x); 1218*4d6fc14bSjoerg template <class _Key> 1219*4d6fc14bSjoerg const_iterator find(const _Key& __x) const; 1220*4d6fc14bSjoerg 1221*4d6fc14bSjoerg typedef __hash_node_destructor<__node_allocator> _Dp; 1222*4d6fc14bSjoerg typedef unique_ptr<__node, _Dp> __node_holder; 1223*4d6fc14bSjoerg 1224*4d6fc14bSjoerg iterator erase(const_iterator __p); 1225*4d6fc14bSjoerg iterator erase(const_iterator __first, const_iterator __last); 1226*4d6fc14bSjoerg template <class _Key> 1227*4d6fc14bSjoerg size_type __erase_unique(const _Key& __k); 1228*4d6fc14bSjoerg template <class _Key> 1229*4d6fc14bSjoerg size_type __erase_multi(const _Key& __k); 1230*4d6fc14bSjoerg __node_holder remove(const_iterator __p) _NOEXCEPT; 1231*4d6fc14bSjoerg 1232*4d6fc14bSjoerg template <class _Key> 1233*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1234*4d6fc14bSjoerg size_type __count_unique(const _Key& __k) const; 1235*4d6fc14bSjoerg template <class _Key> 1236*4d6fc14bSjoerg size_type __count_multi(const _Key& __k) const; 1237*4d6fc14bSjoerg 1238*4d6fc14bSjoerg template <class _Key> 1239*4d6fc14bSjoerg pair<iterator, iterator> 1240*4d6fc14bSjoerg __equal_range_unique(const _Key& __k); 1241*4d6fc14bSjoerg template <class _Key> 1242*4d6fc14bSjoerg pair<const_iterator, const_iterator> 1243*4d6fc14bSjoerg __equal_range_unique(const _Key& __k) const; 1244*4d6fc14bSjoerg 1245*4d6fc14bSjoerg template <class _Key> 1246*4d6fc14bSjoerg pair<iterator, iterator> 1247*4d6fc14bSjoerg __equal_range_multi(const _Key& __k); 1248*4d6fc14bSjoerg template <class _Key> 1249*4d6fc14bSjoerg pair<const_iterator, const_iterator> 1250*4d6fc14bSjoerg __equal_range_multi(const _Key& __k) const; 1251*4d6fc14bSjoerg 1252*4d6fc14bSjoerg void swap(__hash_table& __u) 1253*4d6fc14bSjoerg#if _LIBCPP_STD_VER <= 11 1254*4d6fc14bSjoerg _NOEXCEPT_( 1255*4d6fc14bSjoerg __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value 1256*4d6fc14bSjoerg && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value 1257*4d6fc14bSjoerg || __is_nothrow_swappable<__pointer_allocator>::value) 1258*4d6fc14bSjoerg && (!__node_traits::propagate_on_container_swap::value 1259*4d6fc14bSjoerg || __is_nothrow_swappable<__node_allocator>::value) 1260*4d6fc14bSjoerg ); 1261*4d6fc14bSjoerg#else 1262*4d6fc14bSjoerg _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value); 1263*4d6fc14bSjoerg#endif 1264*4d6fc14bSjoerg 1265*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1266*4d6fc14bSjoerg size_type max_bucket_count() const _NOEXCEPT 1267*4d6fc14bSjoerg {return max_size(); } 1268*4d6fc14bSjoerg size_type bucket_size(size_type __n) const; 1269*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT 1270*4d6fc14bSjoerg { 1271*4d6fc14bSjoerg size_type __bc = bucket_count(); 1272*4d6fc14bSjoerg return __bc != 0 ? (float)size() / __bc : 0.f; 1273*4d6fc14bSjoerg } 1274*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT 1275*4d6fc14bSjoerg { 1276*4d6fc14bSjoerg _LIBCPP_ASSERT(__mlf > 0, 1277*4d6fc14bSjoerg "unordered container::max_load_factor(lf) called with lf <= 0"); 1278*4d6fc14bSjoerg max_load_factor() = _VSTD::max(__mlf, load_factor()); 1279*4d6fc14bSjoerg } 1280*4d6fc14bSjoerg 1281*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1282*4d6fc14bSjoerg local_iterator 1283*4d6fc14bSjoerg begin(size_type __n) 1284*4d6fc14bSjoerg { 1285*4d6fc14bSjoerg _LIBCPP_ASSERT(__n < bucket_count(), 1286*4d6fc14bSjoerg "unordered container::begin(n) called with n >= bucket_count()"); 1287*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1288*4d6fc14bSjoerg return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); 1289*4d6fc14bSjoerg#else 1290*4d6fc14bSjoerg return local_iterator(__bucket_list_[__n], __n, bucket_count()); 1291*4d6fc14bSjoerg#endif 1292*4d6fc14bSjoerg } 1293*4d6fc14bSjoerg 1294*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1295*4d6fc14bSjoerg local_iterator 1296*4d6fc14bSjoerg end(size_type __n) 1297*4d6fc14bSjoerg { 1298*4d6fc14bSjoerg _LIBCPP_ASSERT(__n < bucket_count(), 1299*4d6fc14bSjoerg "unordered container::end(n) called with n >= bucket_count()"); 1300*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1301*4d6fc14bSjoerg return local_iterator(nullptr, __n, bucket_count(), this); 1302*4d6fc14bSjoerg#else 1303*4d6fc14bSjoerg return local_iterator(nullptr, __n, bucket_count()); 1304*4d6fc14bSjoerg#endif 1305*4d6fc14bSjoerg } 1306*4d6fc14bSjoerg 1307*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1308*4d6fc14bSjoerg const_local_iterator 1309*4d6fc14bSjoerg cbegin(size_type __n) const 1310*4d6fc14bSjoerg { 1311*4d6fc14bSjoerg _LIBCPP_ASSERT(__n < bucket_count(), 1312*4d6fc14bSjoerg "unordered container::cbegin(n) called with n >= bucket_count()"); 1313*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1314*4d6fc14bSjoerg return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); 1315*4d6fc14bSjoerg#else 1316*4d6fc14bSjoerg return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); 1317*4d6fc14bSjoerg#endif 1318*4d6fc14bSjoerg } 1319*4d6fc14bSjoerg 1320*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1321*4d6fc14bSjoerg const_local_iterator 1322*4d6fc14bSjoerg cend(size_type __n) const 1323*4d6fc14bSjoerg { 1324*4d6fc14bSjoerg _LIBCPP_ASSERT(__n < bucket_count(), 1325*4d6fc14bSjoerg "unordered container::cend(n) called with n >= bucket_count()"); 1326*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1327*4d6fc14bSjoerg return const_local_iterator(nullptr, __n, bucket_count(), this); 1328*4d6fc14bSjoerg#else 1329*4d6fc14bSjoerg return const_local_iterator(nullptr, __n, bucket_count()); 1330*4d6fc14bSjoerg#endif 1331*4d6fc14bSjoerg } 1332*4d6fc14bSjoerg 1333*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1334*4d6fc14bSjoerg 1335*4d6fc14bSjoerg bool __dereferenceable(const const_iterator* __i) const; 1336*4d6fc14bSjoerg bool __decrementable(const const_iterator* __i) const; 1337*4d6fc14bSjoerg bool __addable(const const_iterator* __i, ptrdiff_t __n) const; 1338*4d6fc14bSjoerg bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; 1339*4d6fc14bSjoerg 1340*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2 1341*4d6fc14bSjoerg 1342*4d6fc14bSjoergprivate: 1343*4d6fc14bSjoerg void __rehash(size_type __n); 1344*4d6fc14bSjoerg 1345*4d6fc14bSjoerg template <class ..._Args> 1346*4d6fc14bSjoerg __node_holder __construct_node(_Args&& ...__args); 1347*4d6fc14bSjoerg 1348*4d6fc14bSjoerg template <class _First, class ..._Rest> 1349*4d6fc14bSjoerg __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); 1350*4d6fc14bSjoerg 1351*4d6fc14bSjoerg 1352*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1353*4d6fc14bSjoerg void __copy_assign_alloc(const __hash_table& __u) 1354*4d6fc14bSjoerg {__copy_assign_alloc(__u, integral_constant<bool, 1355*4d6fc14bSjoerg __node_traits::propagate_on_container_copy_assignment::value>());} 1356*4d6fc14bSjoerg void __copy_assign_alloc(const __hash_table& __u, true_type); 1357*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1358*4d6fc14bSjoerg void __copy_assign_alloc(const __hash_table&, false_type) {} 1359*4d6fc14bSjoerg 1360*4d6fc14bSjoerg void __move_assign(__hash_table& __u, false_type); 1361*4d6fc14bSjoerg void __move_assign(__hash_table& __u, true_type) 1362*4d6fc14bSjoerg _NOEXCEPT_( 1363*4d6fc14bSjoerg is_nothrow_move_assignable<__node_allocator>::value && 1364*4d6fc14bSjoerg is_nothrow_move_assignable<hasher>::value && 1365*4d6fc14bSjoerg is_nothrow_move_assignable<key_equal>::value); 1366*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1367*4d6fc14bSjoerg void __move_assign_alloc(__hash_table& __u) 1368*4d6fc14bSjoerg _NOEXCEPT_( 1369*4d6fc14bSjoerg !__node_traits::propagate_on_container_move_assignment::value || 1370*4d6fc14bSjoerg (is_nothrow_move_assignable<__pointer_allocator>::value && 1371*4d6fc14bSjoerg is_nothrow_move_assignable<__node_allocator>::value)) 1372*4d6fc14bSjoerg {__move_assign_alloc(__u, integral_constant<bool, 1373*4d6fc14bSjoerg __node_traits::propagate_on_container_move_assignment::value>());} 1374*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1375*4d6fc14bSjoerg void __move_assign_alloc(__hash_table& __u, true_type) 1376*4d6fc14bSjoerg _NOEXCEPT_( 1377*4d6fc14bSjoerg is_nothrow_move_assignable<__pointer_allocator>::value && 1378*4d6fc14bSjoerg is_nothrow_move_assignable<__node_allocator>::value) 1379*4d6fc14bSjoerg { 1380*4d6fc14bSjoerg __bucket_list_.get_deleter().__alloc() = 1381*4d6fc14bSjoerg _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); 1382*4d6fc14bSjoerg __node_alloc() = _VSTD::move(__u.__node_alloc()); 1383*4d6fc14bSjoerg } 1384*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 1385*4d6fc14bSjoerg void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} 1386*4d6fc14bSjoerg 1387*4d6fc14bSjoerg void __deallocate_node(__next_pointer __np) _NOEXCEPT; 1388*4d6fc14bSjoerg __next_pointer __detach() _NOEXCEPT; 1389*4d6fc14bSjoerg 1390*4d6fc14bSjoerg template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 1391*4d6fc14bSjoerg template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 1392*4d6fc14bSjoerg}; 1393*4d6fc14bSjoerg 1394*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1395*4d6fc14bSjoerginline 1396*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() 1397*4d6fc14bSjoerg _NOEXCEPT_( 1398*4d6fc14bSjoerg is_nothrow_default_constructible<__bucket_list>::value && 1399*4d6fc14bSjoerg is_nothrow_default_constructible<__first_node>::value && 1400*4d6fc14bSjoerg is_nothrow_default_constructible<__node_allocator>::value && 1401*4d6fc14bSjoerg is_nothrow_default_constructible<hasher>::value && 1402*4d6fc14bSjoerg is_nothrow_default_constructible<key_equal>::value) 1403*4d6fc14bSjoerg : __p2_(0, __default_init_tag()), 1404*4d6fc14bSjoerg __p3_(1.0f, __default_init_tag()) 1405*4d6fc14bSjoerg{ 1406*4d6fc14bSjoerg} 1407*4d6fc14bSjoerg 1408*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1409*4d6fc14bSjoerginline 1410*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, 1411*4d6fc14bSjoerg const key_equal& __eql) 1412*4d6fc14bSjoerg : __bucket_list_(nullptr, __bucket_list_deleter()), 1413*4d6fc14bSjoerg __p1_(), 1414*4d6fc14bSjoerg __p2_(0, __hf), 1415*4d6fc14bSjoerg __p3_(1.0f, __eql) 1416*4d6fc14bSjoerg{ 1417*4d6fc14bSjoerg} 1418*4d6fc14bSjoerg 1419*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1420*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, 1421*4d6fc14bSjoerg const key_equal& __eql, 1422*4d6fc14bSjoerg const allocator_type& __a) 1423*4d6fc14bSjoerg : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1424*4d6fc14bSjoerg __p1_(__default_init_tag(), __node_allocator(__a)), 1425*4d6fc14bSjoerg __p2_(0, __hf), 1426*4d6fc14bSjoerg __p3_(1.0f, __eql) 1427*4d6fc14bSjoerg{ 1428*4d6fc14bSjoerg} 1429*4d6fc14bSjoerg 1430*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1431*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) 1432*4d6fc14bSjoerg : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1433*4d6fc14bSjoerg __p1_(__default_init_tag(), __node_allocator(__a)), 1434*4d6fc14bSjoerg __p2_(0, __default_init_tag()), 1435*4d6fc14bSjoerg __p3_(1.0f, __default_init_tag()) 1436*4d6fc14bSjoerg{ 1437*4d6fc14bSjoerg} 1438*4d6fc14bSjoerg 1439*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1440*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) 1441*4d6fc14bSjoerg : __bucket_list_(nullptr, 1442*4d6fc14bSjoerg __bucket_list_deleter(allocator_traits<__pointer_allocator>:: 1443*4d6fc14bSjoerg select_on_container_copy_construction( 1444*4d6fc14bSjoerg __u.__bucket_list_.get_deleter().__alloc()), 0)), 1445*4d6fc14bSjoerg __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: 1446*4d6fc14bSjoerg select_on_container_copy_construction(__u.__node_alloc())), 1447*4d6fc14bSjoerg __p2_(0, __u.hash_function()), 1448*4d6fc14bSjoerg __p3_(__u.__p3_) 1449*4d6fc14bSjoerg{ 1450*4d6fc14bSjoerg} 1451*4d6fc14bSjoerg 1452*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1453*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, 1454*4d6fc14bSjoerg const allocator_type& __a) 1455*4d6fc14bSjoerg : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1456*4d6fc14bSjoerg __p1_(__default_init_tag(), __node_allocator(__a)), 1457*4d6fc14bSjoerg __p2_(0, __u.hash_function()), 1458*4d6fc14bSjoerg __p3_(__u.__p3_) 1459*4d6fc14bSjoerg{ 1460*4d6fc14bSjoerg} 1461*4d6fc14bSjoerg 1462*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1463*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) 1464*4d6fc14bSjoerg _NOEXCEPT_( 1465*4d6fc14bSjoerg is_nothrow_move_constructible<__bucket_list>::value && 1466*4d6fc14bSjoerg is_nothrow_move_constructible<__first_node>::value && 1467*4d6fc14bSjoerg is_nothrow_move_constructible<__node_allocator>::value && 1468*4d6fc14bSjoerg is_nothrow_move_constructible<hasher>::value && 1469*4d6fc14bSjoerg is_nothrow_move_constructible<key_equal>::value) 1470*4d6fc14bSjoerg : __bucket_list_(_VSTD::move(__u.__bucket_list_)), 1471*4d6fc14bSjoerg __p1_(_VSTD::move(__u.__p1_)), 1472*4d6fc14bSjoerg __p2_(_VSTD::move(__u.__p2_)), 1473*4d6fc14bSjoerg __p3_(_VSTD::move(__u.__p3_)) 1474*4d6fc14bSjoerg{ 1475*4d6fc14bSjoerg if (size() > 0) 1476*4d6fc14bSjoerg { 1477*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 1478*4d6fc14bSjoerg __p1_.first().__ptr(); 1479*4d6fc14bSjoerg __u.__p1_.first().__next_ = nullptr; 1480*4d6fc14bSjoerg __u.size() = 0; 1481*4d6fc14bSjoerg } 1482*4d6fc14bSjoerg} 1483*4d6fc14bSjoerg 1484*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1485*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, 1486*4d6fc14bSjoerg const allocator_type& __a) 1487*4d6fc14bSjoerg : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 1488*4d6fc14bSjoerg __p1_(__default_init_tag(), __node_allocator(__a)), 1489*4d6fc14bSjoerg __p2_(0, _VSTD::move(__u.hash_function())), 1490*4d6fc14bSjoerg __p3_(_VSTD::move(__u.__p3_)) 1491*4d6fc14bSjoerg{ 1492*4d6fc14bSjoerg if (__a == allocator_type(__u.__node_alloc())) 1493*4d6fc14bSjoerg { 1494*4d6fc14bSjoerg __bucket_list_.reset(__u.__bucket_list_.release()); 1495*4d6fc14bSjoerg __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); 1496*4d6fc14bSjoerg __u.__bucket_list_.get_deleter().size() = 0; 1497*4d6fc14bSjoerg if (__u.size() > 0) 1498*4d6fc14bSjoerg { 1499*4d6fc14bSjoerg __p1_.first().__next_ = __u.__p1_.first().__next_; 1500*4d6fc14bSjoerg __u.__p1_.first().__next_ = nullptr; 1501*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 1502*4d6fc14bSjoerg __p1_.first().__ptr(); 1503*4d6fc14bSjoerg size() = __u.size(); 1504*4d6fc14bSjoerg __u.size() = 0; 1505*4d6fc14bSjoerg } 1506*4d6fc14bSjoerg } 1507*4d6fc14bSjoerg} 1508*4d6fc14bSjoerg 1509*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1510*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() 1511*4d6fc14bSjoerg{ 1512*4d6fc14bSjoerg#if defined(_LIBCPP_CXX03_LANG) 1513*4d6fc14bSjoerg static_assert((is_copy_constructible<key_equal>::value), 1514*4d6fc14bSjoerg "Predicate must be copy-constructible."); 1515*4d6fc14bSjoerg static_assert((is_copy_constructible<hasher>::value), 1516*4d6fc14bSjoerg "Hasher must be copy-constructible."); 1517*4d6fc14bSjoerg#endif 1518*4d6fc14bSjoerg 1519*4d6fc14bSjoerg __deallocate_node(__p1_.first().__next_); 1520*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1521*4d6fc14bSjoerg __get_db()->__erase_c(this); 1522*4d6fc14bSjoerg#endif 1523*4d6fc14bSjoerg} 1524*4d6fc14bSjoerg 1525*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1526*4d6fc14bSjoergvoid 1527*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( 1528*4d6fc14bSjoerg const __hash_table& __u, true_type) 1529*4d6fc14bSjoerg{ 1530*4d6fc14bSjoerg if (__node_alloc() != __u.__node_alloc()) 1531*4d6fc14bSjoerg { 1532*4d6fc14bSjoerg clear(); 1533*4d6fc14bSjoerg __bucket_list_.reset(); 1534*4d6fc14bSjoerg __bucket_list_.get_deleter().size() = 0; 1535*4d6fc14bSjoerg } 1536*4d6fc14bSjoerg __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); 1537*4d6fc14bSjoerg __node_alloc() = __u.__node_alloc(); 1538*4d6fc14bSjoerg} 1539*4d6fc14bSjoerg 1540*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1541*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>& 1542*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) 1543*4d6fc14bSjoerg{ 1544*4d6fc14bSjoerg if (this != &__u) 1545*4d6fc14bSjoerg { 1546*4d6fc14bSjoerg __copy_assign_alloc(__u); 1547*4d6fc14bSjoerg hash_function() = __u.hash_function(); 1548*4d6fc14bSjoerg key_eq() = __u.key_eq(); 1549*4d6fc14bSjoerg max_load_factor() = __u.max_load_factor(); 1550*4d6fc14bSjoerg __assign_multi(__u.begin(), __u.end()); 1551*4d6fc14bSjoerg } 1552*4d6fc14bSjoerg return *this; 1553*4d6fc14bSjoerg} 1554*4d6fc14bSjoerg 1555*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1556*4d6fc14bSjoergvoid 1557*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) 1558*4d6fc14bSjoerg _NOEXCEPT 1559*4d6fc14bSjoerg{ 1560*4d6fc14bSjoerg __node_allocator& __na = __node_alloc(); 1561*4d6fc14bSjoerg while (__np != nullptr) 1562*4d6fc14bSjoerg { 1563*4d6fc14bSjoerg __next_pointer __next = __np->__next_; 1564*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1565*4d6fc14bSjoerg __c_node* __c = __get_db()->__find_c_and_lock(this); 1566*4d6fc14bSjoerg for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1567*4d6fc14bSjoerg { 1568*4d6fc14bSjoerg --__p; 1569*4d6fc14bSjoerg iterator* __i = static_cast<iterator*>((*__p)->__i_); 1570*4d6fc14bSjoerg if (__i->__node_ == __np) 1571*4d6fc14bSjoerg { 1572*4d6fc14bSjoerg (*__p)->__c_ = nullptr; 1573*4d6fc14bSjoerg if (--__c->end_ != __p) 1574*4d6fc14bSjoerg _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1575*4d6fc14bSjoerg } 1576*4d6fc14bSjoerg } 1577*4d6fc14bSjoerg __get_db()->unlock(); 1578*4d6fc14bSjoerg#endif 1579*4d6fc14bSjoerg __node_pointer __real_np = __np->__upcast(); 1580*4d6fc14bSjoerg __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); 1581*4d6fc14bSjoerg __node_traits::deallocate(__na, __real_np, 1); 1582*4d6fc14bSjoerg __np = __next; 1583*4d6fc14bSjoerg } 1584*4d6fc14bSjoerg} 1585*4d6fc14bSjoerg 1586*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1587*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 1588*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT 1589*4d6fc14bSjoerg{ 1590*4d6fc14bSjoerg size_type __bc = bucket_count(); 1591*4d6fc14bSjoerg for (size_type __i = 0; __i < __bc; ++__i) 1592*4d6fc14bSjoerg __bucket_list_[__i] = nullptr; 1593*4d6fc14bSjoerg size() = 0; 1594*4d6fc14bSjoerg __next_pointer __cache = __p1_.first().__next_; 1595*4d6fc14bSjoerg __p1_.first().__next_ = nullptr; 1596*4d6fc14bSjoerg return __cache; 1597*4d6fc14bSjoerg} 1598*4d6fc14bSjoerg 1599*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1600*4d6fc14bSjoergvoid 1601*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( 1602*4d6fc14bSjoerg __hash_table& __u, true_type) 1603*4d6fc14bSjoerg _NOEXCEPT_( 1604*4d6fc14bSjoerg is_nothrow_move_assignable<__node_allocator>::value && 1605*4d6fc14bSjoerg is_nothrow_move_assignable<hasher>::value && 1606*4d6fc14bSjoerg is_nothrow_move_assignable<key_equal>::value) 1607*4d6fc14bSjoerg{ 1608*4d6fc14bSjoerg clear(); 1609*4d6fc14bSjoerg __bucket_list_.reset(__u.__bucket_list_.release()); 1610*4d6fc14bSjoerg __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); 1611*4d6fc14bSjoerg __u.__bucket_list_.get_deleter().size() = 0; 1612*4d6fc14bSjoerg __move_assign_alloc(__u); 1613*4d6fc14bSjoerg size() = __u.size(); 1614*4d6fc14bSjoerg hash_function() = _VSTD::move(__u.hash_function()); 1615*4d6fc14bSjoerg max_load_factor() = __u.max_load_factor(); 1616*4d6fc14bSjoerg key_eq() = _VSTD::move(__u.key_eq()); 1617*4d6fc14bSjoerg __p1_.first().__next_ = __u.__p1_.first().__next_; 1618*4d6fc14bSjoerg if (size() > 0) 1619*4d6fc14bSjoerg { 1620*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 1621*4d6fc14bSjoerg __p1_.first().__ptr(); 1622*4d6fc14bSjoerg __u.__p1_.first().__next_ = nullptr; 1623*4d6fc14bSjoerg __u.size() = 0; 1624*4d6fc14bSjoerg } 1625*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1626*4d6fc14bSjoerg __get_db()->swap(this, &__u); 1627*4d6fc14bSjoerg#endif 1628*4d6fc14bSjoerg} 1629*4d6fc14bSjoerg 1630*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1631*4d6fc14bSjoergvoid 1632*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( 1633*4d6fc14bSjoerg __hash_table& __u, false_type) 1634*4d6fc14bSjoerg{ 1635*4d6fc14bSjoerg if (__node_alloc() == __u.__node_alloc()) 1636*4d6fc14bSjoerg __move_assign(__u, true_type()); 1637*4d6fc14bSjoerg else 1638*4d6fc14bSjoerg { 1639*4d6fc14bSjoerg hash_function() = _VSTD::move(__u.hash_function()); 1640*4d6fc14bSjoerg key_eq() = _VSTD::move(__u.key_eq()); 1641*4d6fc14bSjoerg max_load_factor() = __u.max_load_factor(); 1642*4d6fc14bSjoerg if (bucket_count() != 0) 1643*4d6fc14bSjoerg { 1644*4d6fc14bSjoerg __next_pointer __cache = __detach(); 1645*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 1646*4d6fc14bSjoerg try 1647*4d6fc14bSjoerg { 1648*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 1649*4d6fc14bSjoerg const_iterator __i = __u.begin(); 1650*4d6fc14bSjoerg while (__cache != nullptr && __u.size() != 0) 1651*4d6fc14bSjoerg { 1652*4d6fc14bSjoerg __cache->__upcast()->__value_ = 1653*4d6fc14bSjoerg _VSTD::move(__u.remove(__i++)->__value_); 1654*4d6fc14bSjoerg __next_pointer __next = __cache->__next_; 1655*4d6fc14bSjoerg __node_insert_multi(__cache->__upcast()); 1656*4d6fc14bSjoerg __cache = __next; 1657*4d6fc14bSjoerg } 1658*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 1659*4d6fc14bSjoerg } 1660*4d6fc14bSjoerg catch (...) 1661*4d6fc14bSjoerg { 1662*4d6fc14bSjoerg __deallocate_node(__cache); 1663*4d6fc14bSjoerg throw; 1664*4d6fc14bSjoerg } 1665*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 1666*4d6fc14bSjoerg __deallocate_node(__cache); 1667*4d6fc14bSjoerg } 1668*4d6fc14bSjoerg const_iterator __i = __u.begin(); 1669*4d6fc14bSjoerg while (__u.size() != 0) 1670*4d6fc14bSjoerg { 1671*4d6fc14bSjoerg __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); 1672*4d6fc14bSjoerg __node_insert_multi(__h.get()); 1673*4d6fc14bSjoerg __h.release(); 1674*4d6fc14bSjoerg } 1675*4d6fc14bSjoerg } 1676*4d6fc14bSjoerg} 1677*4d6fc14bSjoerg 1678*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1679*4d6fc14bSjoerginline 1680*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>& 1681*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) 1682*4d6fc14bSjoerg _NOEXCEPT_( 1683*4d6fc14bSjoerg __node_traits::propagate_on_container_move_assignment::value && 1684*4d6fc14bSjoerg is_nothrow_move_assignable<__node_allocator>::value && 1685*4d6fc14bSjoerg is_nothrow_move_assignable<hasher>::value && 1686*4d6fc14bSjoerg is_nothrow_move_assignable<key_equal>::value) 1687*4d6fc14bSjoerg{ 1688*4d6fc14bSjoerg __move_assign(__u, integral_constant<bool, 1689*4d6fc14bSjoerg __node_traits::propagate_on_container_move_assignment::value>()); 1690*4d6fc14bSjoerg return *this; 1691*4d6fc14bSjoerg} 1692*4d6fc14bSjoerg 1693*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1694*4d6fc14bSjoergtemplate <class _InputIterator> 1695*4d6fc14bSjoergvoid 1696*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, 1697*4d6fc14bSjoerg _InputIterator __last) 1698*4d6fc14bSjoerg{ 1699*4d6fc14bSjoerg typedef iterator_traits<_InputIterator> _ITraits; 1700*4d6fc14bSjoerg typedef typename _ITraits::value_type _ItValueType; 1701*4d6fc14bSjoerg static_assert((is_same<_ItValueType, __container_value_type>::value), 1702*4d6fc14bSjoerg "__assign_unique may only be called with the containers value type"); 1703*4d6fc14bSjoerg 1704*4d6fc14bSjoerg if (bucket_count() != 0) 1705*4d6fc14bSjoerg { 1706*4d6fc14bSjoerg __next_pointer __cache = __detach(); 1707*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 1708*4d6fc14bSjoerg try 1709*4d6fc14bSjoerg { 1710*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 1711*4d6fc14bSjoerg for (; __cache != nullptr && __first != __last; ++__first) 1712*4d6fc14bSjoerg { 1713*4d6fc14bSjoerg __cache->__upcast()->__value_ = *__first; 1714*4d6fc14bSjoerg __next_pointer __next = __cache->__next_; 1715*4d6fc14bSjoerg __node_insert_unique(__cache->__upcast()); 1716*4d6fc14bSjoerg __cache = __next; 1717*4d6fc14bSjoerg } 1718*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 1719*4d6fc14bSjoerg } 1720*4d6fc14bSjoerg catch (...) 1721*4d6fc14bSjoerg { 1722*4d6fc14bSjoerg __deallocate_node(__cache); 1723*4d6fc14bSjoerg throw; 1724*4d6fc14bSjoerg } 1725*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 1726*4d6fc14bSjoerg __deallocate_node(__cache); 1727*4d6fc14bSjoerg } 1728*4d6fc14bSjoerg for (; __first != __last; ++__first) 1729*4d6fc14bSjoerg __insert_unique(*__first); 1730*4d6fc14bSjoerg} 1731*4d6fc14bSjoerg 1732*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1733*4d6fc14bSjoergtemplate <class _InputIterator> 1734*4d6fc14bSjoergvoid 1735*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, 1736*4d6fc14bSjoerg _InputIterator __last) 1737*4d6fc14bSjoerg{ 1738*4d6fc14bSjoerg typedef iterator_traits<_InputIterator> _ITraits; 1739*4d6fc14bSjoerg typedef typename _ITraits::value_type _ItValueType; 1740*4d6fc14bSjoerg static_assert((is_same<_ItValueType, __container_value_type>::value || 1741*4d6fc14bSjoerg is_same<_ItValueType, __node_value_type>::value), 1742*4d6fc14bSjoerg "__assign_multi may only be called with the containers value type" 1743*4d6fc14bSjoerg " or the nodes value type"); 1744*4d6fc14bSjoerg if (bucket_count() != 0) 1745*4d6fc14bSjoerg { 1746*4d6fc14bSjoerg __next_pointer __cache = __detach(); 1747*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 1748*4d6fc14bSjoerg try 1749*4d6fc14bSjoerg { 1750*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 1751*4d6fc14bSjoerg for (; __cache != nullptr && __first != __last; ++__first) 1752*4d6fc14bSjoerg { 1753*4d6fc14bSjoerg __cache->__upcast()->__value_ = *__first; 1754*4d6fc14bSjoerg __next_pointer __next = __cache->__next_; 1755*4d6fc14bSjoerg __node_insert_multi(__cache->__upcast()); 1756*4d6fc14bSjoerg __cache = __next; 1757*4d6fc14bSjoerg } 1758*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 1759*4d6fc14bSjoerg } 1760*4d6fc14bSjoerg catch (...) 1761*4d6fc14bSjoerg { 1762*4d6fc14bSjoerg __deallocate_node(__cache); 1763*4d6fc14bSjoerg throw; 1764*4d6fc14bSjoerg } 1765*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 1766*4d6fc14bSjoerg __deallocate_node(__cache); 1767*4d6fc14bSjoerg } 1768*4d6fc14bSjoerg for (; __first != __last; ++__first) 1769*4d6fc14bSjoerg __insert_multi(_NodeTypes::__get_value(*__first)); 1770*4d6fc14bSjoerg} 1771*4d6fc14bSjoerg 1772*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1773*4d6fc14bSjoerginline 1774*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 1775*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT 1776*4d6fc14bSjoerg{ 1777*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1778*4d6fc14bSjoerg return iterator(__p1_.first().__next_, this); 1779*4d6fc14bSjoerg#else 1780*4d6fc14bSjoerg return iterator(__p1_.first().__next_); 1781*4d6fc14bSjoerg#endif 1782*4d6fc14bSjoerg} 1783*4d6fc14bSjoerg 1784*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1785*4d6fc14bSjoerginline 1786*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 1787*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT 1788*4d6fc14bSjoerg{ 1789*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1790*4d6fc14bSjoerg return iterator(nullptr, this); 1791*4d6fc14bSjoerg#else 1792*4d6fc14bSjoerg return iterator(nullptr); 1793*4d6fc14bSjoerg#endif 1794*4d6fc14bSjoerg} 1795*4d6fc14bSjoerg 1796*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1797*4d6fc14bSjoerginline 1798*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 1799*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT 1800*4d6fc14bSjoerg{ 1801*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1802*4d6fc14bSjoerg return const_iterator(__p1_.first().__next_, this); 1803*4d6fc14bSjoerg#else 1804*4d6fc14bSjoerg return const_iterator(__p1_.first().__next_); 1805*4d6fc14bSjoerg#endif 1806*4d6fc14bSjoerg} 1807*4d6fc14bSjoerg 1808*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1809*4d6fc14bSjoerginline 1810*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 1811*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT 1812*4d6fc14bSjoerg{ 1813*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1814*4d6fc14bSjoerg return const_iterator(nullptr, this); 1815*4d6fc14bSjoerg#else 1816*4d6fc14bSjoerg return const_iterator(nullptr); 1817*4d6fc14bSjoerg#endif 1818*4d6fc14bSjoerg} 1819*4d6fc14bSjoerg 1820*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1821*4d6fc14bSjoergvoid 1822*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT 1823*4d6fc14bSjoerg{ 1824*4d6fc14bSjoerg if (size() > 0) 1825*4d6fc14bSjoerg { 1826*4d6fc14bSjoerg __deallocate_node(__p1_.first().__next_); 1827*4d6fc14bSjoerg __p1_.first().__next_ = nullptr; 1828*4d6fc14bSjoerg size_type __bc = bucket_count(); 1829*4d6fc14bSjoerg for (size_type __i = 0; __i < __bc; ++__i) 1830*4d6fc14bSjoerg __bucket_list_[__i] = nullptr; 1831*4d6fc14bSjoerg size() = 0; 1832*4d6fc14bSjoerg } 1833*4d6fc14bSjoerg} 1834*4d6fc14bSjoerg 1835*4d6fc14bSjoerg 1836*4d6fc14bSjoerg// Prepare the container for an insertion of the value __value with the hash 1837*4d6fc14bSjoerg// __hash. This does a lookup into the container to see if __value is already 1838*4d6fc14bSjoerg// present, and performs a rehash if necessary. Returns a pointer to the 1839*4d6fc14bSjoerg// existing element if it exists, otherwise nullptr. 1840*4d6fc14bSjoerg// 1841*4d6fc14bSjoerg// Note that this function does forward exceptions if key_eq() throws, and never 1842*4d6fc14bSjoerg// mutates __value or actually inserts into the map. 1843*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1844*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 1845*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 1846*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( 1847*4d6fc14bSjoerg size_t __hash, value_type& __value) 1848*4d6fc14bSjoerg{ 1849*4d6fc14bSjoerg size_type __bc = bucket_count(); 1850*4d6fc14bSjoerg 1851*4d6fc14bSjoerg if (__bc != 0) 1852*4d6fc14bSjoerg { 1853*4d6fc14bSjoerg size_t __chash = __constrain_hash(__hash, __bc); 1854*4d6fc14bSjoerg __next_pointer __ndptr = __bucket_list_[__chash]; 1855*4d6fc14bSjoerg if (__ndptr != nullptr) 1856*4d6fc14bSjoerg { 1857*4d6fc14bSjoerg for (__ndptr = __ndptr->__next_; __ndptr != nullptr && 1858*4d6fc14bSjoerg __constrain_hash(__ndptr->__hash(), __bc) == __chash; 1859*4d6fc14bSjoerg __ndptr = __ndptr->__next_) 1860*4d6fc14bSjoerg { 1861*4d6fc14bSjoerg if (key_eq()(__ndptr->__upcast()->__value_, __value)) 1862*4d6fc14bSjoerg return __ndptr; 1863*4d6fc14bSjoerg } 1864*4d6fc14bSjoerg } 1865*4d6fc14bSjoerg } 1866*4d6fc14bSjoerg if (size()+1 > __bc * max_load_factor() || __bc == 0) 1867*4d6fc14bSjoerg { 1868*4d6fc14bSjoerg rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 1869*4d6fc14bSjoerg size_type(ceil(float(size() + 1) / max_load_factor())))); 1870*4d6fc14bSjoerg } 1871*4d6fc14bSjoerg return nullptr; 1872*4d6fc14bSjoerg} 1873*4d6fc14bSjoerg 1874*4d6fc14bSjoerg// Insert the node __nd into the container by pushing it into the right bucket, 1875*4d6fc14bSjoerg// and updating size(). Assumes that __nd->__hash is up-to-date, and that 1876*4d6fc14bSjoerg// rehashing has already occurred and that no element with the same key exists 1877*4d6fc14bSjoerg// in the map. 1878*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1879*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 1880*4d6fc14bSjoergvoid 1881*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( 1882*4d6fc14bSjoerg __node_pointer __nd) _NOEXCEPT 1883*4d6fc14bSjoerg{ 1884*4d6fc14bSjoerg size_type __bc = bucket_count(); 1885*4d6fc14bSjoerg size_t __chash = __constrain_hash(__nd->__hash(), __bc); 1886*4d6fc14bSjoerg // insert_after __bucket_list_[__chash], or __first_node if bucket is null 1887*4d6fc14bSjoerg __next_pointer __pn = __bucket_list_[__chash]; 1888*4d6fc14bSjoerg if (__pn == nullptr) 1889*4d6fc14bSjoerg { 1890*4d6fc14bSjoerg __pn =__p1_.first().__ptr(); 1891*4d6fc14bSjoerg __nd->__next_ = __pn->__next_; 1892*4d6fc14bSjoerg __pn->__next_ = __nd->__ptr(); 1893*4d6fc14bSjoerg // fix up __bucket_list_ 1894*4d6fc14bSjoerg __bucket_list_[__chash] = __pn; 1895*4d6fc14bSjoerg if (__nd->__next_ != nullptr) 1896*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); 1897*4d6fc14bSjoerg } 1898*4d6fc14bSjoerg else 1899*4d6fc14bSjoerg { 1900*4d6fc14bSjoerg __nd->__next_ = __pn->__next_; 1901*4d6fc14bSjoerg __pn->__next_ = __nd->__ptr(); 1902*4d6fc14bSjoerg } 1903*4d6fc14bSjoerg ++size(); 1904*4d6fc14bSjoerg} 1905*4d6fc14bSjoerg 1906*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1907*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 1908*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) 1909*4d6fc14bSjoerg{ 1910*4d6fc14bSjoerg __nd->__hash_ = hash_function()(__nd->__value_); 1911*4d6fc14bSjoerg __next_pointer __existing_node = 1912*4d6fc14bSjoerg __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); 1913*4d6fc14bSjoerg 1914*4d6fc14bSjoerg // Insert the node, unless it already exists in the container. 1915*4d6fc14bSjoerg bool __inserted = false; 1916*4d6fc14bSjoerg if (__existing_node == nullptr) 1917*4d6fc14bSjoerg { 1918*4d6fc14bSjoerg __node_insert_unique_perform(__nd); 1919*4d6fc14bSjoerg __existing_node = __nd->__ptr(); 1920*4d6fc14bSjoerg __inserted = true; 1921*4d6fc14bSjoerg } 1922*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 1923*4d6fc14bSjoerg return pair<iterator, bool>(iterator(__existing_node, this), __inserted); 1924*4d6fc14bSjoerg#else 1925*4d6fc14bSjoerg return pair<iterator, bool>(iterator(__existing_node), __inserted); 1926*4d6fc14bSjoerg#endif 1927*4d6fc14bSjoerg} 1928*4d6fc14bSjoerg 1929*4d6fc14bSjoerg// Prepare the container for an insertion of the value __cp_val with the hash 1930*4d6fc14bSjoerg// __cp_hash. This does a lookup into the container to see if __cp_value is 1931*4d6fc14bSjoerg// already present, and performs a rehash if necessary. Returns a pointer to the 1932*4d6fc14bSjoerg// last occurrence of __cp_val in the map. 1933*4d6fc14bSjoerg// 1934*4d6fc14bSjoerg// Note that this function does forward exceptions if key_eq() throws, and never 1935*4d6fc14bSjoerg// mutates __value or actually inserts into the map. 1936*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1937*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 1938*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( 1939*4d6fc14bSjoerg size_t __cp_hash, value_type& __cp_val) 1940*4d6fc14bSjoerg{ 1941*4d6fc14bSjoerg size_type __bc = bucket_count(); 1942*4d6fc14bSjoerg if (size()+1 > __bc * max_load_factor() || __bc == 0) 1943*4d6fc14bSjoerg { 1944*4d6fc14bSjoerg rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 1945*4d6fc14bSjoerg size_type(ceil(float(size() + 1) / max_load_factor())))); 1946*4d6fc14bSjoerg __bc = bucket_count(); 1947*4d6fc14bSjoerg } 1948*4d6fc14bSjoerg size_t __chash = __constrain_hash(__cp_hash, __bc); 1949*4d6fc14bSjoerg __next_pointer __pn = __bucket_list_[__chash]; 1950*4d6fc14bSjoerg if (__pn != nullptr) 1951*4d6fc14bSjoerg { 1952*4d6fc14bSjoerg for (bool __found = false; __pn->__next_ != nullptr && 1953*4d6fc14bSjoerg __constrain_hash(__pn->__next_->__hash(), __bc) == __chash; 1954*4d6fc14bSjoerg __pn = __pn->__next_) 1955*4d6fc14bSjoerg { 1956*4d6fc14bSjoerg // __found key_eq() action 1957*4d6fc14bSjoerg // false false loop 1958*4d6fc14bSjoerg // true true loop 1959*4d6fc14bSjoerg // false true set __found to true 1960*4d6fc14bSjoerg // true false break 1961*4d6fc14bSjoerg if (__found != (__pn->__next_->__hash() == __cp_hash && 1962*4d6fc14bSjoerg key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) 1963*4d6fc14bSjoerg { 1964*4d6fc14bSjoerg if (!__found) 1965*4d6fc14bSjoerg __found = true; 1966*4d6fc14bSjoerg else 1967*4d6fc14bSjoerg break; 1968*4d6fc14bSjoerg } 1969*4d6fc14bSjoerg } 1970*4d6fc14bSjoerg } 1971*4d6fc14bSjoerg return __pn; 1972*4d6fc14bSjoerg} 1973*4d6fc14bSjoerg 1974*4d6fc14bSjoerg// Insert the node __cp into the container after __pn (which is the last node in 1975*4d6fc14bSjoerg// the bucket that compares equal to __cp). Rehashing, and checking for 1976*4d6fc14bSjoerg// uniqueness has already been performed (in __node_insert_multi_prepare), so 1977*4d6fc14bSjoerg// all we need to do is update the bucket and size(). Assumes that __cp->__hash 1978*4d6fc14bSjoerg// is up-to-date. 1979*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 1980*4d6fc14bSjoergvoid 1981*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( 1982*4d6fc14bSjoerg __node_pointer __cp, __next_pointer __pn) _NOEXCEPT 1983*4d6fc14bSjoerg{ 1984*4d6fc14bSjoerg size_type __bc = bucket_count(); 1985*4d6fc14bSjoerg size_t __chash = __constrain_hash(__cp->__hash_, __bc); 1986*4d6fc14bSjoerg if (__pn == nullptr) 1987*4d6fc14bSjoerg { 1988*4d6fc14bSjoerg __pn =__p1_.first().__ptr(); 1989*4d6fc14bSjoerg __cp->__next_ = __pn->__next_; 1990*4d6fc14bSjoerg __pn->__next_ = __cp->__ptr(); 1991*4d6fc14bSjoerg // fix up __bucket_list_ 1992*4d6fc14bSjoerg __bucket_list_[__chash] = __pn; 1993*4d6fc14bSjoerg if (__cp->__next_ != nullptr) 1994*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] 1995*4d6fc14bSjoerg = __cp->__ptr(); 1996*4d6fc14bSjoerg } 1997*4d6fc14bSjoerg else 1998*4d6fc14bSjoerg { 1999*4d6fc14bSjoerg __cp->__next_ = __pn->__next_; 2000*4d6fc14bSjoerg __pn->__next_ = __cp->__ptr(); 2001*4d6fc14bSjoerg if (__cp->__next_ != nullptr) 2002*4d6fc14bSjoerg { 2003*4d6fc14bSjoerg size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc); 2004*4d6fc14bSjoerg if (__nhash != __chash) 2005*4d6fc14bSjoerg __bucket_list_[__nhash] = __cp->__ptr(); 2006*4d6fc14bSjoerg } 2007*4d6fc14bSjoerg } 2008*4d6fc14bSjoerg ++size(); 2009*4d6fc14bSjoerg} 2010*4d6fc14bSjoerg 2011*4d6fc14bSjoerg 2012*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2013*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2014*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) 2015*4d6fc14bSjoerg{ 2016*4d6fc14bSjoerg __cp->__hash_ = hash_function()(__cp->__value_); 2017*4d6fc14bSjoerg __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); 2018*4d6fc14bSjoerg __node_insert_multi_perform(__cp, __pn); 2019*4d6fc14bSjoerg 2020*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2021*4d6fc14bSjoerg return iterator(__cp->__ptr(), this); 2022*4d6fc14bSjoerg#else 2023*4d6fc14bSjoerg return iterator(__cp->__ptr()); 2024*4d6fc14bSjoerg#endif 2025*4d6fc14bSjoerg} 2026*4d6fc14bSjoerg 2027*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2028*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2029*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( 2030*4d6fc14bSjoerg const_iterator __p, __node_pointer __cp) 2031*4d6fc14bSjoerg{ 2032*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2033*4d6fc14bSjoerg _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, 2034*4d6fc14bSjoerg "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" 2035*4d6fc14bSjoerg " referring to this unordered container"); 2036*4d6fc14bSjoerg#endif 2037*4d6fc14bSjoerg if (__p != end() && key_eq()(*__p, __cp->__value_)) 2038*4d6fc14bSjoerg { 2039*4d6fc14bSjoerg __next_pointer __np = __p.__node_; 2040*4d6fc14bSjoerg __cp->__hash_ = __np->__hash(); 2041*4d6fc14bSjoerg size_type __bc = bucket_count(); 2042*4d6fc14bSjoerg if (size()+1 > __bc * max_load_factor() || __bc == 0) 2043*4d6fc14bSjoerg { 2044*4d6fc14bSjoerg rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 2045*4d6fc14bSjoerg size_type(ceil(float(size() + 1) / max_load_factor())))); 2046*4d6fc14bSjoerg __bc = bucket_count(); 2047*4d6fc14bSjoerg } 2048*4d6fc14bSjoerg size_t __chash = __constrain_hash(__cp->__hash_, __bc); 2049*4d6fc14bSjoerg __next_pointer __pp = __bucket_list_[__chash]; 2050*4d6fc14bSjoerg while (__pp->__next_ != __np) 2051*4d6fc14bSjoerg __pp = __pp->__next_; 2052*4d6fc14bSjoerg __cp->__next_ = __np; 2053*4d6fc14bSjoerg __pp->__next_ = static_cast<__next_pointer>(__cp); 2054*4d6fc14bSjoerg ++size(); 2055*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2056*4d6fc14bSjoerg return iterator(static_cast<__next_pointer>(__cp), this); 2057*4d6fc14bSjoerg#else 2058*4d6fc14bSjoerg return iterator(static_cast<__next_pointer>(__cp)); 2059*4d6fc14bSjoerg#endif 2060*4d6fc14bSjoerg } 2061*4d6fc14bSjoerg return __node_insert_multi(__cp); 2062*4d6fc14bSjoerg} 2063*4d6fc14bSjoerg 2064*4d6fc14bSjoerg 2065*4d6fc14bSjoerg 2066*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2067*4d6fc14bSjoergtemplate <class _Key, class ..._Args> 2068*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 2069*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) 2070*4d6fc14bSjoerg{ 2071*4d6fc14bSjoerg 2072*4d6fc14bSjoerg size_t __hash = hash_function()(__k); 2073*4d6fc14bSjoerg size_type __bc = bucket_count(); 2074*4d6fc14bSjoerg bool __inserted = false; 2075*4d6fc14bSjoerg __next_pointer __nd; 2076*4d6fc14bSjoerg size_t __chash; 2077*4d6fc14bSjoerg if (__bc != 0) 2078*4d6fc14bSjoerg { 2079*4d6fc14bSjoerg __chash = __constrain_hash(__hash, __bc); 2080*4d6fc14bSjoerg __nd = __bucket_list_[__chash]; 2081*4d6fc14bSjoerg if (__nd != nullptr) 2082*4d6fc14bSjoerg { 2083*4d6fc14bSjoerg for (__nd = __nd->__next_; __nd != nullptr && 2084*4d6fc14bSjoerg (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash); 2085*4d6fc14bSjoerg __nd = __nd->__next_) 2086*4d6fc14bSjoerg { 2087*4d6fc14bSjoerg if (key_eq()(__nd->__upcast()->__value_, __k)) 2088*4d6fc14bSjoerg goto __done; 2089*4d6fc14bSjoerg } 2090*4d6fc14bSjoerg } 2091*4d6fc14bSjoerg } 2092*4d6fc14bSjoerg { 2093*4d6fc14bSjoerg __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); 2094*4d6fc14bSjoerg if (size()+1 > __bc * max_load_factor() || __bc == 0) 2095*4d6fc14bSjoerg { 2096*4d6fc14bSjoerg rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), 2097*4d6fc14bSjoerg size_type(ceil(float(size() + 1) / max_load_factor())))); 2098*4d6fc14bSjoerg __bc = bucket_count(); 2099*4d6fc14bSjoerg __chash = __constrain_hash(__hash, __bc); 2100*4d6fc14bSjoerg } 2101*4d6fc14bSjoerg // insert_after __bucket_list_[__chash], or __first_node if bucket is null 2102*4d6fc14bSjoerg __next_pointer __pn = __bucket_list_[__chash]; 2103*4d6fc14bSjoerg if (__pn == nullptr) 2104*4d6fc14bSjoerg { 2105*4d6fc14bSjoerg __pn = __p1_.first().__ptr(); 2106*4d6fc14bSjoerg __h->__next_ = __pn->__next_; 2107*4d6fc14bSjoerg __pn->__next_ = __h.get()->__ptr(); 2108*4d6fc14bSjoerg // fix up __bucket_list_ 2109*4d6fc14bSjoerg __bucket_list_[__chash] = __pn; 2110*4d6fc14bSjoerg if (__h->__next_ != nullptr) 2111*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)] 2112*4d6fc14bSjoerg = __h.get()->__ptr(); 2113*4d6fc14bSjoerg } 2114*4d6fc14bSjoerg else 2115*4d6fc14bSjoerg { 2116*4d6fc14bSjoerg __h->__next_ = __pn->__next_; 2117*4d6fc14bSjoerg __pn->__next_ = static_cast<__next_pointer>(__h.get()); 2118*4d6fc14bSjoerg } 2119*4d6fc14bSjoerg __nd = static_cast<__next_pointer>(__h.release()); 2120*4d6fc14bSjoerg // increment size 2121*4d6fc14bSjoerg ++size(); 2122*4d6fc14bSjoerg __inserted = true; 2123*4d6fc14bSjoerg } 2124*4d6fc14bSjoerg__done: 2125*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2126*4d6fc14bSjoerg return pair<iterator, bool>(iterator(__nd, this), __inserted); 2127*4d6fc14bSjoerg#else 2128*4d6fc14bSjoerg return pair<iterator, bool>(iterator(__nd), __inserted); 2129*4d6fc14bSjoerg#endif 2130*4d6fc14bSjoerg} 2131*4d6fc14bSjoerg 2132*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2133*4d6fc14bSjoergtemplate <class... _Args> 2134*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 2135*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) 2136*4d6fc14bSjoerg{ 2137*4d6fc14bSjoerg __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2138*4d6fc14bSjoerg pair<iterator, bool> __r = __node_insert_unique(__h.get()); 2139*4d6fc14bSjoerg if (__r.second) 2140*4d6fc14bSjoerg __h.release(); 2141*4d6fc14bSjoerg return __r; 2142*4d6fc14bSjoerg} 2143*4d6fc14bSjoerg 2144*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2145*4d6fc14bSjoergtemplate <class... _Args> 2146*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2147*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) 2148*4d6fc14bSjoerg{ 2149*4d6fc14bSjoerg __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2150*4d6fc14bSjoerg iterator __r = __node_insert_multi(__h.get()); 2151*4d6fc14bSjoerg __h.release(); 2152*4d6fc14bSjoerg return __r; 2153*4d6fc14bSjoerg} 2154*4d6fc14bSjoerg 2155*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2156*4d6fc14bSjoergtemplate <class... _Args> 2157*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2158*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( 2159*4d6fc14bSjoerg const_iterator __p, _Args&&... __args) 2160*4d6fc14bSjoerg{ 2161*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2162*4d6fc14bSjoerg _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, 2163*4d6fc14bSjoerg "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" 2164*4d6fc14bSjoerg " referring to this unordered container"); 2165*4d6fc14bSjoerg#endif 2166*4d6fc14bSjoerg __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 2167*4d6fc14bSjoerg iterator __r = __node_insert_multi(__p, __h.get()); 2168*4d6fc14bSjoerg __h.release(); 2169*4d6fc14bSjoerg return __r; 2170*4d6fc14bSjoerg} 2171*4d6fc14bSjoerg 2172*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14 2173*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2174*4d6fc14bSjoergtemplate <class _NodeHandle, class _InsertReturnType> 2175*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2176*4d6fc14bSjoerg_InsertReturnType 2177*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( 2178*4d6fc14bSjoerg _NodeHandle&& __nh) 2179*4d6fc14bSjoerg{ 2180*4d6fc14bSjoerg if (__nh.empty()) 2181*4d6fc14bSjoerg return _InsertReturnType{end(), false, _NodeHandle()}; 2182*4d6fc14bSjoerg pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); 2183*4d6fc14bSjoerg if (__result.second) 2184*4d6fc14bSjoerg __nh.__release_ptr(); 2185*4d6fc14bSjoerg return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; 2186*4d6fc14bSjoerg} 2187*4d6fc14bSjoerg 2188*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2189*4d6fc14bSjoergtemplate <class _NodeHandle> 2190*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2191*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2192*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( 2193*4d6fc14bSjoerg const_iterator, _NodeHandle&& __nh) 2194*4d6fc14bSjoerg{ 2195*4d6fc14bSjoerg if (__nh.empty()) 2196*4d6fc14bSjoerg return end(); 2197*4d6fc14bSjoerg pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); 2198*4d6fc14bSjoerg if (__result.second) 2199*4d6fc14bSjoerg __nh.__release_ptr(); 2200*4d6fc14bSjoerg return __result.first; 2201*4d6fc14bSjoerg} 2202*4d6fc14bSjoerg 2203*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2204*4d6fc14bSjoergtemplate <class _NodeHandle> 2205*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2206*4d6fc14bSjoerg_NodeHandle 2207*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( 2208*4d6fc14bSjoerg key_type const& __key) 2209*4d6fc14bSjoerg{ 2210*4d6fc14bSjoerg iterator __i = find(__key); 2211*4d6fc14bSjoerg if (__i == end()) 2212*4d6fc14bSjoerg return _NodeHandle(); 2213*4d6fc14bSjoerg return __node_handle_extract<_NodeHandle>(__i); 2214*4d6fc14bSjoerg} 2215*4d6fc14bSjoerg 2216*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2217*4d6fc14bSjoergtemplate <class _NodeHandle> 2218*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2219*4d6fc14bSjoerg_NodeHandle 2220*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( 2221*4d6fc14bSjoerg const_iterator __p) 2222*4d6fc14bSjoerg{ 2223*4d6fc14bSjoerg allocator_type __alloc(__node_alloc()); 2224*4d6fc14bSjoerg return _NodeHandle(remove(__p).release(), __alloc); 2225*4d6fc14bSjoerg} 2226*4d6fc14bSjoerg 2227*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2228*4d6fc14bSjoergtemplate <class _Table> 2229*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2230*4d6fc14bSjoergvoid 2231*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( 2232*4d6fc14bSjoerg _Table& __source) 2233*4d6fc14bSjoerg{ 2234*4d6fc14bSjoerg static_assert(is_same<__node, typename _Table::__node>::value, ""); 2235*4d6fc14bSjoerg 2236*4d6fc14bSjoerg for (typename _Table::iterator __it = __source.begin(); 2237*4d6fc14bSjoerg __it != __source.end();) 2238*4d6fc14bSjoerg { 2239*4d6fc14bSjoerg __node_pointer __src_ptr = __it.__node_->__upcast(); 2240*4d6fc14bSjoerg size_t __hash = hash_function()(__src_ptr->__value_); 2241*4d6fc14bSjoerg __next_pointer __existing_node = 2242*4d6fc14bSjoerg __node_insert_unique_prepare(__hash, __src_ptr->__value_); 2243*4d6fc14bSjoerg auto __prev_iter = __it++; 2244*4d6fc14bSjoerg if (__existing_node == nullptr) 2245*4d6fc14bSjoerg { 2246*4d6fc14bSjoerg (void)__source.remove(__prev_iter).release(); 2247*4d6fc14bSjoerg __src_ptr->__hash_ = __hash; 2248*4d6fc14bSjoerg __node_insert_unique_perform(__src_ptr); 2249*4d6fc14bSjoerg } 2250*4d6fc14bSjoerg } 2251*4d6fc14bSjoerg} 2252*4d6fc14bSjoerg 2253*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2254*4d6fc14bSjoergtemplate <class _NodeHandle> 2255*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2256*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2257*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( 2258*4d6fc14bSjoerg _NodeHandle&& __nh) 2259*4d6fc14bSjoerg{ 2260*4d6fc14bSjoerg if (__nh.empty()) 2261*4d6fc14bSjoerg return end(); 2262*4d6fc14bSjoerg iterator __result = __node_insert_multi(__nh.__ptr_); 2263*4d6fc14bSjoerg __nh.__release_ptr(); 2264*4d6fc14bSjoerg return __result; 2265*4d6fc14bSjoerg} 2266*4d6fc14bSjoerg 2267*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2268*4d6fc14bSjoergtemplate <class _NodeHandle> 2269*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2270*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2271*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( 2272*4d6fc14bSjoerg const_iterator __hint, _NodeHandle&& __nh) 2273*4d6fc14bSjoerg{ 2274*4d6fc14bSjoerg if (__nh.empty()) 2275*4d6fc14bSjoerg return end(); 2276*4d6fc14bSjoerg iterator __result = __node_insert_multi(__hint, __nh.__ptr_); 2277*4d6fc14bSjoerg __nh.__release_ptr(); 2278*4d6fc14bSjoerg return __result; 2279*4d6fc14bSjoerg} 2280*4d6fc14bSjoerg 2281*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2282*4d6fc14bSjoergtemplate <class _Table> 2283*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY 2284*4d6fc14bSjoergvoid 2285*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( 2286*4d6fc14bSjoerg _Table& __source) 2287*4d6fc14bSjoerg{ 2288*4d6fc14bSjoerg static_assert(is_same<typename _Table::__node, __node>::value, ""); 2289*4d6fc14bSjoerg 2290*4d6fc14bSjoerg for (typename _Table::iterator __it = __source.begin(); 2291*4d6fc14bSjoerg __it != __source.end();) 2292*4d6fc14bSjoerg { 2293*4d6fc14bSjoerg __node_pointer __src_ptr = __it.__node_->__upcast(); 2294*4d6fc14bSjoerg size_t __src_hash = hash_function()(__src_ptr->__value_); 2295*4d6fc14bSjoerg __next_pointer __pn = 2296*4d6fc14bSjoerg __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); 2297*4d6fc14bSjoerg (void)__source.remove(__it++).release(); 2298*4d6fc14bSjoerg __src_ptr->__hash_ = __src_hash; 2299*4d6fc14bSjoerg __node_insert_multi_perform(__src_ptr, __pn); 2300*4d6fc14bSjoerg } 2301*4d6fc14bSjoerg} 2302*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 14 2303*4d6fc14bSjoerg 2304*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2305*4d6fc14bSjoergvoid 2306*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n) 2307*4d6fc14bSjoerg_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 2308*4d6fc14bSjoerg{ 2309*4d6fc14bSjoerg if (__n == 1) 2310*4d6fc14bSjoerg __n = 2; 2311*4d6fc14bSjoerg else if (__n & (__n - 1)) 2312*4d6fc14bSjoerg __n = __next_prime(__n); 2313*4d6fc14bSjoerg size_type __bc = bucket_count(); 2314*4d6fc14bSjoerg if (__n > __bc) 2315*4d6fc14bSjoerg __rehash(__n); 2316*4d6fc14bSjoerg else if (__n < __bc) 2317*4d6fc14bSjoerg { 2318*4d6fc14bSjoerg __n = _VSTD::max<size_type> 2319*4d6fc14bSjoerg ( 2320*4d6fc14bSjoerg __n, 2321*4d6fc14bSjoerg __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) : 2322*4d6fc14bSjoerg __next_prime(size_t(ceil(float(size()) / max_load_factor()))) 2323*4d6fc14bSjoerg ); 2324*4d6fc14bSjoerg if (__n < __bc) 2325*4d6fc14bSjoerg __rehash(__n); 2326*4d6fc14bSjoerg } 2327*4d6fc14bSjoerg} 2328*4d6fc14bSjoerg 2329*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2330*4d6fc14bSjoergvoid 2331*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) 2332*4d6fc14bSjoerg{ 2333*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2334*4d6fc14bSjoerg __get_db()->__invalidate_all(this); 2335*4d6fc14bSjoerg#endif 2336*4d6fc14bSjoerg __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); 2337*4d6fc14bSjoerg __bucket_list_.reset(__nbc > 0 ? 2338*4d6fc14bSjoerg __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); 2339*4d6fc14bSjoerg __bucket_list_.get_deleter().size() = __nbc; 2340*4d6fc14bSjoerg if (__nbc > 0) 2341*4d6fc14bSjoerg { 2342*4d6fc14bSjoerg for (size_type __i = 0; __i < __nbc; ++__i) 2343*4d6fc14bSjoerg __bucket_list_[__i] = nullptr; 2344*4d6fc14bSjoerg __next_pointer __pp = __p1_.first().__ptr(); 2345*4d6fc14bSjoerg __next_pointer __cp = __pp->__next_; 2346*4d6fc14bSjoerg if (__cp != nullptr) 2347*4d6fc14bSjoerg { 2348*4d6fc14bSjoerg size_type __chash = __constrain_hash(__cp->__hash(), __nbc); 2349*4d6fc14bSjoerg __bucket_list_[__chash] = __pp; 2350*4d6fc14bSjoerg size_type __phash = __chash; 2351*4d6fc14bSjoerg for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr; 2352*4d6fc14bSjoerg __cp = __pp->__next_) 2353*4d6fc14bSjoerg { 2354*4d6fc14bSjoerg __chash = __constrain_hash(__cp->__hash(), __nbc); 2355*4d6fc14bSjoerg if (__chash == __phash) 2356*4d6fc14bSjoerg __pp = __cp; 2357*4d6fc14bSjoerg else 2358*4d6fc14bSjoerg { 2359*4d6fc14bSjoerg if (__bucket_list_[__chash] == nullptr) 2360*4d6fc14bSjoerg { 2361*4d6fc14bSjoerg __bucket_list_[__chash] = __pp; 2362*4d6fc14bSjoerg __pp = __cp; 2363*4d6fc14bSjoerg __phash = __chash; 2364*4d6fc14bSjoerg } 2365*4d6fc14bSjoerg else 2366*4d6fc14bSjoerg { 2367*4d6fc14bSjoerg __next_pointer __np = __cp; 2368*4d6fc14bSjoerg for (; __np->__next_ != nullptr && 2369*4d6fc14bSjoerg key_eq()(__cp->__upcast()->__value_, 2370*4d6fc14bSjoerg __np->__next_->__upcast()->__value_); 2371*4d6fc14bSjoerg __np = __np->__next_) 2372*4d6fc14bSjoerg ; 2373*4d6fc14bSjoerg __pp->__next_ = __np->__next_; 2374*4d6fc14bSjoerg __np->__next_ = __bucket_list_[__chash]->__next_; 2375*4d6fc14bSjoerg __bucket_list_[__chash]->__next_ = __cp; 2376*4d6fc14bSjoerg 2377*4d6fc14bSjoerg } 2378*4d6fc14bSjoerg } 2379*4d6fc14bSjoerg } 2380*4d6fc14bSjoerg } 2381*4d6fc14bSjoerg } 2382*4d6fc14bSjoerg} 2383*4d6fc14bSjoerg 2384*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2385*4d6fc14bSjoergtemplate <class _Key> 2386*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2387*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) 2388*4d6fc14bSjoerg{ 2389*4d6fc14bSjoerg size_t __hash = hash_function()(__k); 2390*4d6fc14bSjoerg size_type __bc = bucket_count(); 2391*4d6fc14bSjoerg if (__bc != 0) 2392*4d6fc14bSjoerg { 2393*4d6fc14bSjoerg size_t __chash = __constrain_hash(__hash, __bc); 2394*4d6fc14bSjoerg __next_pointer __nd = __bucket_list_[__chash]; 2395*4d6fc14bSjoerg if (__nd != nullptr) 2396*4d6fc14bSjoerg { 2397*4d6fc14bSjoerg for (__nd = __nd->__next_; __nd != nullptr && 2398*4d6fc14bSjoerg (__nd->__hash() == __hash 2399*4d6fc14bSjoerg || __constrain_hash(__nd->__hash(), __bc) == __chash); 2400*4d6fc14bSjoerg __nd = __nd->__next_) 2401*4d6fc14bSjoerg { 2402*4d6fc14bSjoerg if ((__nd->__hash() == __hash) 2403*4d6fc14bSjoerg && key_eq()(__nd->__upcast()->__value_, __k)) 2404*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2405*4d6fc14bSjoerg return iterator(__nd, this); 2406*4d6fc14bSjoerg#else 2407*4d6fc14bSjoerg return iterator(__nd); 2408*4d6fc14bSjoerg#endif 2409*4d6fc14bSjoerg } 2410*4d6fc14bSjoerg } 2411*4d6fc14bSjoerg } 2412*4d6fc14bSjoerg return end(); 2413*4d6fc14bSjoerg} 2414*4d6fc14bSjoerg 2415*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2416*4d6fc14bSjoergtemplate <class _Key> 2417*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 2418*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const 2419*4d6fc14bSjoerg{ 2420*4d6fc14bSjoerg size_t __hash = hash_function()(__k); 2421*4d6fc14bSjoerg size_type __bc = bucket_count(); 2422*4d6fc14bSjoerg if (__bc != 0) 2423*4d6fc14bSjoerg { 2424*4d6fc14bSjoerg size_t __chash = __constrain_hash(__hash, __bc); 2425*4d6fc14bSjoerg __next_pointer __nd = __bucket_list_[__chash]; 2426*4d6fc14bSjoerg if (__nd != nullptr) 2427*4d6fc14bSjoerg { 2428*4d6fc14bSjoerg for (__nd = __nd->__next_; __nd != nullptr && 2429*4d6fc14bSjoerg (__hash == __nd->__hash() 2430*4d6fc14bSjoerg || __constrain_hash(__nd->__hash(), __bc) == __chash); 2431*4d6fc14bSjoerg __nd = __nd->__next_) 2432*4d6fc14bSjoerg { 2433*4d6fc14bSjoerg if ((__nd->__hash() == __hash) 2434*4d6fc14bSjoerg && key_eq()(__nd->__upcast()->__value_, __k)) 2435*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2436*4d6fc14bSjoerg return const_iterator(__nd, this); 2437*4d6fc14bSjoerg#else 2438*4d6fc14bSjoerg return const_iterator(__nd); 2439*4d6fc14bSjoerg#endif 2440*4d6fc14bSjoerg } 2441*4d6fc14bSjoerg } 2442*4d6fc14bSjoerg 2443*4d6fc14bSjoerg } 2444*4d6fc14bSjoerg return end(); 2445*4d6fc14bSjoerg} 2446*4d6fc14bSjoerg 2447*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2448*4d6fc14bSjoergtemplate <class ..._Args> 2449*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 2450*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) 2451*4d6fc14bSjoerg{ 2452*4d6fc14bSjoerg static_assert(!__is_hash_value_type<_Args...>::value, 2453*4d6fc14bSjoerg "Construct cannot be called with a hash value type"); 2454*4d6fc14bSjoerg __node_allocator& __na = __node_alloc(); 2455*4d6fc14bSjoerg __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 2456*4d6fc14bSjoerg __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); 2457*4d6fc14bSjoerg __h.get_deleter().__value_constructed = true; 2458*4d6fc14bSjoerg __h->__hash_ = hash_function()(__h->__value_); 2459*4d6fc14bSjoerg __h->__next_ = nullptr; 2460*4d6fc14bSjoerg return __h; 2461*4d6fc14bSjoerg} 2462*4d6fc14bSjoerg 2463*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2464*4d6fc14bSjoergtemplate <class _First, class ..._Rest> 2465*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 2466*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( 2467*4d6fc14bSjoerg size_t __hash, _First&& __f, _Rest&& ...__rest) 2468*4d6fc14bSjoerg{ 2469*4d6fc14bSjoerg static_assert(!__is_hash_value_type<_First, _Rest...>::value, 2470*4d6fc14bSjoerg "Construct cannot be called with a hash value type"); 2471*4d6fc14bSjoerg __node_allocator& __na = __node_alloc(); 2472*4d6fc14bSjoerg __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 2473*4d6fc14bSjoerg __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), 2474*4d6fc14bSjoerg _VSTD::forward<_First>(__f), 2475*4d6fc14bSjoerg _VSTD::forward<_Rest>(__rest)...); 2476*4d6fc14bSjoerg __h.get_deleter().__value_constructed = true; 2477*4d6fc14bSjoerg __h->__hash_ = __hash; 2478*4d6fc14bSjoerg __h->__next_ = nullptr; 2479*4d6fc14bSjoerg return __h; 2480*4d6fc14bSjoerg} 2481*4d6fc14bSjoerg 2482*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2483*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2484*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) 2485*4d6fc14bSjoerg{ 2486*4d6fc14bSjoerg __next_pointer __np = __p.__node_; 2487*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2488*4d6fc14bSjoerg _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, 2489*4d6fc14bSjoerg "unordered container erase(iterator) called with an iterator not" 2490*4d6fc14bSjoerg " referring to this container"); 2491*4d6fc14bSjoerg _LIBCPP_ASSERT(__p != end(), 2492*4d6fc14bSjoerg "unordered container erase(iterator) called with a non-dereferenceable iterator"); 2493*4d6fc14bSjoerg iterator __r(__np, this); 2494*4d6fc14bSjoerg#else 2495*4d6fc14bSjoerg iterator __r(__np); 2496*4d6fc14bSjoerg#endif 2497*4d6fc14bSjoerg ++__r; 2498*4d6fc14bSjoerg remove(__p); 2499*4d6fc14bSjoerg return __r; 2500*4d6fc14bSjoerg} 2501*4d6fc14bSjoerg 2502*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2503*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 2504*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, 2505*4d6fc14bSjoerg const_iterator __last) 2506*4d6fc14bSjoerg{ 2507*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2508*4d6fc14bSjoerg _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, 2509*4d6fc14bSjoerg "unordered container::erase(iterator, iterator) called with an iterator not" 2510*4d6fc14bSjoerg " referring to this container"); 2511*4d6fc14bSjoerg _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, 2512*4d6fc14bSjoerg "unordered container::erase(iterator, iterator) called with an iterator not" 2513*4d6fc14bSjoerg " referring to this container"); 2514*4d6fc14bSjoerg#endif 2515*4d6fc14bSjoerg for (const_iterator __p = __first; __first != __last; __p = __first) 2516*4d6fc14bSjoerg { 2517*4d6fc14bSjoerg ++__first; 2518*4d6fc14bSjoerg erase(__p); 2519*4d6fc14bSjoerg } 2520*4d6fc14bSjoerg __next_pointer __np = __last.__node_; 2521*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2522*4d6fc14bSjoerg return iterator (__np, this); 2523*4d6fc14bSjoerg#else 2524*4d6fc14bSjoerg return iterator (__np); 2525*4d6fc14bSjoerg#endif 2526*4d6fc14bSjoerg} 2527*4d6fc14bSjoerg 2528*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2529*4d6fc14bSjoergtemplate <class _Key> 2530*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 2531*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) 2532*4d6fc14bSjoerg{ 2533*4d6fc14bSjoerg iterator __i = find(__k); 2534*4d6fc14bSjoerg if (__i == end()) 2535*4d6fc14bSjoerg return 0; 2536*4d6fc14bSjoerg erase(__i); 2537*4d6fc14bSjoerg return 1; 2538*4d6fc14bSjoerg} 2539*4d6fc14bSjoerg 2540*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2541*4d6fc14bSjoergtemplate <class _Key> 2542*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 2543*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) 2544*4d6fc14bSjoerg{ 2545*4d6fc14bSjoerg size_type __r = 0; 2546*4d6fc14bSjoerg iterator __i = find(__k); 2547*4d6fc14bSjoerg if (__i != end()) 2548*4d6fc14bSjoerg { 2549*4d6fc14bSjoerg iterator __e = end(); 2550*4d6fc14bSjoerg do 2551*4d6fc14bSjoerg { 2552*4d6fc14bSjoerg erase(__i++); 2553*4d6fc14bSjoerg ++__r; 2554*4d6fc14bSjoerg } while (__i != __e && key_eq()(*__i, __k)); 2555*4d6fc14bSjoerg } 2556*4d6fc14bSjoerg return __r; 2557*4d6fc14bSjoerg} 2558*4d6fc14bSjoerg 2559*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2560*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 2561*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT 2562*4d6fc14bSjoerg{ 2563*4d6fc14bSjoerg // current node 2564*4d6fc14bSjoerg __next_pointer __cn = __p.__node_; 2565*4d6fc14bSjoerg size_type __bc = bucket_count(); 2566*4d6fc14bSjoerg size_t __chash = __constrain_hash(__cn->__hash(), __bc); 2567*4d6fc14bSjoerg // find previous node 2568*4d6fc14bSjoerg __next_pointer __pn = __bucket_list_[__chash]; 2569*4d6fc14bSjoerg for (; __pn->__next_ != __cn; __pn = __pn->__next_) 2570*4d6fc14bSjoerg ; 2571*4d6fc14bSjoerg // Fix up __bucket_list_ 2572*4d6fc14bSjoerg // if __pn is not in same bucket (before begin is not in same bucket) && 2573*4d6fc14bSjoerg // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) 2574*4d6fc14bSjoerg if (__pn == __p1_.first().__ptr() 2575*4d6fc14bSjoerg || __constrain_hash(__pn->__hash(), __bc) != __chash) 2576*4d6fc14bSjoerg { 2577*4d6fc14bSjoerg if (__cn->__next_ == nullptr 2578*4d6fc14bSjoerg || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash) 2579*4d6fc14bSjoerg __bucket_list_[__chash] = nullptr; 2580*4d6fc14bSjoerg } 2581*4d6fc14bSjoerg // if __cn->__next_ is not in same bucket (nullptr is in same bucket) 2582*4d6fc14bSjoerg if (__cn->__next_ != nullptr) 2583*4d6fc14bSjoerg { 2584*4d6fc14bSjoerg size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc); 2585*4d6fc14bSjoerg if (__nhash != __chash) 2586*4d6fc14bSjoerg __bucket_list_[__nhash] = __pn; 2587*4d6fc14bSjoerg } 2588*4d6fc14bSjoerg // remove __cn 2589*4d6fc14bSjoerg __pn->__next_ = __cn->__next_; 2590*4d6fc14bSjoerg __cn->__next_ = nullptr; 2591*4d6fc14bSjoerg --size(); 2592*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2593*4d6fc14bSjoerg __c_node* __c = __get_db()->__find_c_and_lock(this); 2594*4d6fc14bSjoerg for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) 2595*4d6fc14bSjoerg { 2596*4d6fc14bSjoerg --__dp; 2597*4d6fc14bSjoerg iterator* __i = static_cast<iterator*>((*__dp)->__i_); 2598*4d6fc14bSjoerg if (__i->__node_ == __cn) 2599*4d6fc14bSjoerg { 2600*4d6fc14bSjoerg (*__dp)->__c_ = nullptr; 2601*4d6fc14bSjoerg if (--__c->end_ != __dp) 2602*4d6fc14bSjoerg _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); 2603*4d6fc14bSjoerg } 2604*4d6fc14bSjoerg } 2605*4d6fc14bSjoerg __get_db()->unlock(); 2606*4d6fc14bSjoerg#endif 2607*4d6fc14bSjoerg return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); 2608*4d6fc14bSjoerg} 2609*4d6fc14bSjoerg 2610*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2611*4d6fc14bSjoergtemplate <class _Key> 2612*4d6fc14bSjoerginline 2613*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 2614*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const 2615*4d6fc14bSjoerg{ 2616*4d6fc14bSjoerg return static_cast<size_type>(find(__k) != end()); 2617*4d6fc14bSjoerg} 2618*4d6fc14bSjoerg 2619*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2620*4d6fc14bSjoergtemplate <class _Key> 2621*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 2622*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const 2623*4d6fc14bSjoerg{ 2624*4d6fc14bSjoerg size_type __r = 0; 2625*4d6fc14bSjoerg const_iterator __i = find(__k); 2626*4d6fc14bSjoerg if (__i != end()) 2627*4d6fc14bSjoerg { 2628*4d6fc14bSjoerg const_iterator __e = end(); 2629*4d6fc14bSjoerg do 2630*4d6fc14bSjoerg { 2631*4d6fc14bSjoerg ++__i; 2632*4d6fc14bSjoerg ++__r; 2633*4d6fc14bSjoerg } while (__i != __e && key_eq()(*__i, __k)); 2634*4d6fc14bSjoerg } 2635*4d6fc14bSjoerg return __r; 2636*4d6fc14bSjoerg} 2637*4d6fc14bSjoerg 2638*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2639*4d6fc14bSjoergtemplate <class _Key> 2640*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, 2641*4d6fc14bSjoerg typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> 2642*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( 2643*4d6fc14bSjoerg const _Key& __k) 2644*4d6fc14bSjoerg{ 2645*4d6fc14bSjoerg iterator __i = find(__k); 2646*4d6fc14bSjoerg iterator __j = __i; 2647*4d6fc14bSjoerg if (__i != end()) 2648*4d6fc14bSjoerg ++__j; 2649*4d6fc14bSjoerg return pair<iterator, iterator>(__i, __j); 2650*4d6fc14bSjoerg} 2651*4d6fc14bSjoerg 2652*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2653*4d6fc14bSjoergtemplate <class _Key> 2654*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator, 2655*4d6fc14bSjoerg typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> 2656*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( 2657*4d6fc14bSjoerg const _Key& __k) const 2658*4d6fc14bSjoerg{ 2659*4d6fc14bSjoerg const_iterator __i = find(__k); 2660*4d6fc14bSjoerg const_iterator __j = __i; 2661*4d6fc14bSjoerg if (__i != end()) 2662*4d6fc14bSjoerg ++__j; 2663*4d6fc14bSjoerg return pair<const_iterator, const_iterator>(__i, __j); 2664*4d6fc14bSjoerg} 2665*4d6fc14bSjoerg 2666*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2667*4d6fc14bSjoergtemplate <class _Key> 2668*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, 2669*4d6fc14bSjoerg typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> 2670*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( 2671*4d6fc14bSjoerg const _Key& __k) 2672*4d6fc14bSjoerg{ 2673*4d6fc14bSjoerg iterator __i = find(__k); 2674*4d6fc14bSjoerg iterator __j = __i; 2675*4d6fc14bSjoerg if (__i != end()) 2676*4d6fc14bSjoerg { 2677*4d6fc14bSjoerg iterator __e = end(); 2678*4d6fc14bSjoerg do 2679*4d6fc14bSjoerg { 2680*4d6fc14bSjoerg ++__j; 2681*4d6fc14bSjoerg } while (__j != __e && key_eq()(*__j, __k)); 2682*4d6fc14bSjoerg } 2683*4d6fc14bSjoerg return pair<iterator, iterator>(__i, __j); 2684*4d6fc14bSjoerg} 2685*4d6fc14bSjoerg 2686*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2687*4d6fc14bSjoergtemplate <class _Key> 2688*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator, 2689*4d6fc14bSjoerg typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> 2690*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( 2691*4d6fc14bSjoerg const _Key& __k) const 2692*4d6fc14bSjoerg{ 2693*4d6fc14bSjoerg const_iterator __i = find(__k); 2694*4d6fc14bSjoerg const_iterator __j = __i; 2695*4d6fc14bSjoerg if (__i != end()) 2696*4d6fc14bSjoerg { 2697*4d6fc14bSjoerg const_iterator __e = end(); 2698*4d6fc14bSjoerg do 2699*4d6fc14bSjoerg { 2700*4d6fc14bSjoerg ++__j; 2701*4d6fc14bSjoerg } while (__j != __e && key_eq()(*__j, __k)); 2702*4d6fc14bSjoerg } 2703*4d6fc14bSjoerg return pair<const_iterator, const_iterator>(__i, __j); 2704*4d6fc14bSjoerg} 2705*4d6fc14bSjoerg 2706*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2707*4d6fc14bSjoergvoid 2708*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) 2709*4d6fc14bSjoerg#if _LIBCPP_STD_VER <= 11 2710*4d6fc14bSjoerg _NOEXCEPT_( 2711*4d6fc14bSjoerg __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value 2712*4d6fc14bSjoerg && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value 2713*4d6fc14bSjoerg || __is_nothrow_swappable<__pointer_allocator>::value) 2714*4d6fc14bSjoerg && (!__node_traits::propagate_on_container_swap::value 2715*4d6fc14bSjoerg || __is_nothrow_swappable<__node_allocator>::value) 2716*4d6fc14bSjoerg ) 2717*4d6fc14bSjoerg#else 2718*4d6fc14bSjoerg _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value) 2719*4d6fc14bSjoerg#endif 2720*4d6fc14bSjoerg{ 2721*4d6fc14bSjoerg _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || 2722*4d6fc14bSjoerg this->__node_alloc() == __u.__node_alloc(), 2723*4d6fc14bSjoerg "list::swap: Either propagate_on_container_swap must be true" 2724*4d6fc14bSjoerg " or the allocators must compare equal"); 2725*4d6fc14bSjoerg { 2726*4d6fc14bSjoerg __node_pointer_pointer __npp = __bucket_list_.release(); 2727*4d6fc14bSjoerg __bucket_list_.reset(__u.__bucket_list_.release()); 2728*4d6fc14bSjoerg __u.__bucket_list_.reset(__npp); 2729*4d6fc14bSjoerg } 2730*4d6fc14bSjoerg _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); 2731*4d6fc14bSjoerg _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), 2732*4d6fc14bSjoerg __u.__bucket_list_.get_deleter().__alloc()); 2733*4d6fc14bSjoerg _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); 2734*4d6fc14bSjoerg _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); 2735*4d6fc14bSjoerg __p2_.swap(__u.__p2_); 2736*4d6fc14bSjoerg __p3_.swap(__u.__p3_); 2737*4d6fc14bSjoerg if (size() > 0) 2738*4d6fc14bSjoerg __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 2739*4d6fc14bSjoerg __p1_.first().__ptr(); 2740*4d6fc14bSjoerg if (__u.size() > 0) 2741*4d6fc14bSjoerg __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = 2742*4d6fc14bSjoerg __u.__p1_.first().__ptr(); 2743*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2744*4d6fc14bSjoerg __get_db()->swap(this, &__u); 2745*4d6fc14bSjoerg#endif 2746*4d6fc14bSjoerg} 2747*4d6fc14bSjoerg 2748*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2749*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 2750*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const 2751*4d6fc14bSjoerg{ 2752*4d6fc14bSjoerg _LIBCPP_ASSERT(__n < bucket_count(), 2753*4d6fc14bSjoerg "unordered container::bucket_size(n) called with n >= bucket_count()"); 2754*4d6fc14bSjoerg __next_pointer __np = __bucket_list_[__n]; 2755*4d6fc14bSjoerg size_type __bc = bucket_count(); 2756*4d6fc14bSjoerg size_type __r = 0; 2757*4d6fc14bSjoerg if (__np != nullptr) 2758*4d6fc14bSjoerg { 2759*4d6fc14bSjoerg for (__np = __np->__next_; __np != nullptr && 2760*4d6fc14bSjoerg __constrain_hash(__np->__hash(), __bc) == __n; 2761*4d6fc14bSjoerg __np = __np->__next_, ++__r) 2762*4d6fc14bSjoerg ; 2763*4d6fc14bSjoerg } 2764*4d6fc14bSjoerg return __r; 2765*4d6fc14bSjoerg} 2766*4d6fc14bSjoerg 2767*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2768*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 2769*4d6fc14bSjoergvoid 2770*4d6fc14bSjoergswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, 2771*4d6fc14bSjoerg __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) 2772*4d6fc14bSjoerg _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 2773*4d6fc14bSjoerg{ 2774*4d6fc14bSjoerg __x.swap(__y); 2775*4d6fc14bSjoerg} 2776*4d6fc14bSjoerg 2777*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2 2778*4d6fc14bSjoerg 2779*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2780*4d6fc14bSjoergbool 2781*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const 2782*4d6fc14bSjoerg{ 2783*4d6fc14bSjoerg return __i->__node_ != nullptr; 2784*4d6fc14bSjoerg} 2785*4d6fc14bSjoerg 2786*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2787*4d6fc14bSjoergbool 2788*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const 2789*4d6fc14bSjoerg{ 2790*4d6fc14bSjoerg return false; 2791*4d6fc14bSjoerg} 2792*4d6fc14bSjoerg 2793*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2794*4d6fc14bSjoergbool 2795*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const 2796*4d6fc14bSjoerg{ 2797*4d6fc14bSjoerg return false; 2798*4d6fc14bSjoerg} 2799*4d6fc14bSjoerg 2800*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2801*4d6fc14bSjoergbool 2802*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const 2803*4d6fc14bSjoerg{ 2804*4d6fc14bSjoerg return false; 2805*4d6fc14bSjoerg} 2806*4d6fc14bSjoerg 2807*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2 2808*4d6fc14bSjoerg 2809*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD 2810*4d6fc14bSjoerg 2811*4d6fc14bSjoerg_LIBCPP_POP_MACROS 2812*4d6fc14bSjoerg 2813*4d6fc14bSjoerg#endif // _LIBCPP__HASH_TABLE 2814