146035553Spatrick// -*- C++ -*- 246035553Spatrick//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 10*4bdff4beSrobert#ifndef _LIBCPP___HASH_TABLE 11*4bdff4beSrobert#define _LIBCPP___HASH_TABLE 1246035553Spatrick 13*4bdff4beSrobert#include <__algorithm/max.h> 14*4bdff4beSrobert#include <__algorithm/min.h> 15*4bdff4beSrobert#include <__assert> 16*4bdff4beSrobert#include <__bit/countl.h> 1746035553Spatrick#include <__config> 1876d0caaeSpatrick#include <__debug> 19*4bdff4beSrobert#include <__functional/hash.h> 20*4bdff4beSrobert#include <__iterator/iterator_traits.h> 21*4bdff4beSrobert#include <__memory/addressof.h> 22*4bdff4beSrobert#include <__memory/allocator_traits.h> 23*4bdff4beSrobert#include <__memory/compressed_pair.h> 24*4bdff4beSrobert#include <__memory/pointer_traits.h> 25*4bdff4beSrobert#include <__memory/swap_allocator.h> 26*4bdff4beSrobert#include <__memory/unique_ptr.h> 27*4bdff4beSrobert#include <__type_traits/can_extract_key.h> 28*4bdff4beSrobert#include <__utility/forward.h> 29*4bdff4beSrobert#include <__utility/move.h> 30*4bdff4beSrobert#include <__utility/pair.h> 31*4bdff4beSrobert#include <__utility/swap.h> 3246035553Spatrick#include <cmath> 33*4bdff4beSrobert#include <cstring> 3476d0caaeSpatrick#include <initializer_list> 3546035553Spatrick#include <type_traits> 3646035553Spatrick 3746035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 3846035553Spatrick# pragma GCC system_header 3946035553Spatrick#endif 4046035553Spatrick 4146035553Spatrick_LIBCPP_PUSH_MACROS 4246035553Spatrick#include <__undef_macros> 4346035553Spatrick 4446035553Spatrick 4546035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 4646035553Spatrick 4746035553Spatricktemplate <class _Key, class _Tp> 4846035553Spatrickstruct __hash_value_type; 4946035553Spatrick 5046035553Spatricktemplate <class _Tp> 5146035553Spatrickstruct __is_hash_value_type_imp : false_type {}; 5246035553Spatrick 5346035553Spatricktemplate <class _Key, class _Value> 5446035553Spatrickstruct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; 5546035553Spatrick 5646035553Spatricktemplate <class ..._Args> 5746035553Spatrickstruct __is_hash_value_type : false_type {}; 5846035553Spatrick 5946035553Spatricktemplate <class _One> 60*4bdff4beSrobertstruct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {}; 6146035553Spatrick 6246035553Spatrick_LIBCPP_FUNC_VIS 6346035553Spatricksize_t __next_prime(size_t __n); 6446035553Spatrick 6546035553Spatricktemplate <class _NodePtr> 6646035553Spatrickstruct __hash_node_base 6746035553Spatrick{ 6846035553Spatrick typedef typename pointer_traits<_NodePtr>::element_type __node_type; 6946035553Spatrick typedef __hash_node_base __first_node; 70*4bdff4beSrobert typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; 7146035553Spatrick typedef _NodePtr __node_pointer; 7246035553Spatrick 7346035553Spatrick#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) 7446035553Spatrick typedef __node_base_pointer __next_pointer; 7546035553Spatrick#else 76*4bdff4beSrobert typedef __conditional_t<is_pointer<__node_pointer>::value, __node_base_pointer, __node_pointer> __next_pointer; 7746035553Spatrick#endif 7846035553Spatrick 7946035553Spatrick __next_pointer __next_; 8046035553Spatrick 8146035553Spatrick _LIBCPP_INLINE_VISIBILITY 8246035553Spatrick __next_pointer __ptr() _NOEXCEPT { 8346035553Spatrick return static_cast<__next_pointer>( 8446035553Spatrick pointer_traits<__node_base_pointer>::pointer_to(*this)); 8546035553Spatrick } 8646035553Spatrick 8746035553Spatrick _LIBCPP_INLINE_VISIBILITY 8846035553Spatrick __node_pointer __upcast() _NOEXCEPT { 8946035553Spatrick return static_cast<__node_pointer>( 9046035553Spatrick pointer_traits<__node_base_pointer>::pointer_to(*this)); 9146035553Spatrick } 9246035553Spatrick 9346035553Spatrick _LIBCPP_INLINE_VISIBILITY 9446035553Spatrick size_t __hash() const _NOEXCEPT { 9546035553Spatrick return static_cast<__node_type const&>(*this).__hash_; 9646035553Spatrick } 9746035553Spatrick 9846035553Spatrick _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} 9946035553Spatrick}; 10046035553Spatrick 10146035553Spatricktemplate <class _Tp, class _VoidPtr> 10276d0caaeSpatrickstruct _LIBCPP_STANDALONE_DEBUG __hash_node 10346035553Spatrick : public __hash_node_base 10446035553Spatrick < 105*4bdff4beSrobert __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > 10646035553Spatrick > 10746035553Spatrick{ 10846035553Spatrick typedef _Tp __node_value_type; 10946035553Spatrick 11046035553Spatrick size_t __hash_; 11146035553Spatrick __node_value_type __value_; 11246035553Spatrick}; 11346035553Spatrick 11446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 11546035553Spatrickbool 11646035553Spatrick__is_hash_power2(size_t __bc) 11746035553Spatrick{ 11846035553Spatrick return __bc > 2 && !(__bc & (__bc - 1)); 11946035553Spatrick} 12046035553Spatrick 12146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 12246035553Spatricksize_t 12346035553Spatrick__constrain_hash(size_t __h, size_t __bc) 12446035553Spatrick{ 12546035553Spatrick return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : 12646035553Spatrick (__h < __bc ? __h : __h % __bc); 12746035553Spatrick} 12846035553Spatrick 12946035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 13046035553Spatricksize_t 13146035553Spatrick__next_hash_pow2(size_t __n) 13246035553Spatrick{ 13376d0caaeSpatrick return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1))); 13446035553Spatrick} 13546035553Spatrick 13646035553Spatrick 13746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table; 13846035553Spatrick 13946035553Spatricktemplate <class _NodePtr> class _LIBCPP_TEMPLATE_VIS __hash_iterator; 14046035553Spatricktemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 14146035553Spatricktemplate <class _NodePtr> class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; 14246035553Spatricktemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 14346035553Spatricktemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 14446035553Spatricktemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 14546035553Spatrick 14646035553Spatricktemplate <class _Tp> 14746035553Spatrickstruct __hash_key_value_types { 14846035553Spatrick static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); 14946035553Spatrick typedef _Tp key_type; 15046035553Spatrick typedef _Tp __node_value_type; 15146035553Spatrick typedef _Tp __container_value_type; 15246035553Spatrick static const bool __is_map = false; 15346035553Spatrick 15446035553Spatrick _LIBCPP_INLINE_VISIBILITY 15546035553Spatrick static key_type const& __get_key(_Tp const& __v) { 15646035553Spatrick return __v; 15746035553Spatrick } 15846035553Spatrick _LIBCPP_INLINE_VISIBILITY 15946035553Spatrick static __container_value_type const& __get_value(__node_value_type const& __v) { 16046035553Spatrick return __v; 16146035553Spatrick } 16246035553Spatrick _LIBCPP_INLINE_VISIBILITY 16346035553Spatrick static __container_value_type* __get_ptr(__node_value_type& __n) { 16446035553Spatrick return _VSTD::addressof(__n); 16546035553Spatrick } 16646035553Spatrick _LIBCPP_INLINE_VISIBILITY 16746035553Spatrick static __container_value_type&& __move(__node_value_type& __v) { 16846035553Spatrick return _VSTD::move(__v); 16946035553Spatrick } 17046035553Spatrick}; 17146035553Spatrick 17246035553Spatricktemplate <class _Key, class _Tp> 17346035553Spatrickstruct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { 17446035553Spatrick typedef _Key key_type; 17546035553Spatrick typedef _Tp mapped_type; 17646035553Spatrick typedef __hash_value_type<_Key, _Tp> __node_value_type; 17746035553Spatrick typedef pair<const _Key, _Tp> __container_value_type; 17846035553Spatrick typedef __container_value_type __map_value_type; 17946035553Spatrick static const bool __is_map = true; 18046035553Spatrick 18146035553Spatrick _LIBCPP_INLINE_VISIBILITY 18246035553Spatrick static key_type const& __get_key(__container_value_type const& __v) { 18346035553Spatrick return __v.first; 18446035553Spatrick } 18546035553Spatrick 18646035553Spatrick template <class _Up> 18746035553Spatrick _LIBCPP_INLINE_VISIBILITY 188*4bdff4beSrobert static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&> 18946035553Spatrick __get_value(_Up& __t) { 19046035553Spatrick return __t.__get_value(); 19146035553Spatrick } 19246035553Spatrick 19346035553Spatrick template <class _Up> 19446035553Spatrick _LIBCPP_INLINE_VISIBILITY 195*4bdff4beSrobert static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&> 19646035553Spatrick __get_value(_Up& __t) { 19746035553Spatrick return __t; 19846035553Spatrick } 19946035553Spatrick 20046035553Spatrick _LIBCPP_INLINE_VISIBILITY 20146035553Spatrick static __container_value_type* __get_ptr(__node_value_type& __n) { 20246035553Spatrick return _VSTD::addressof(__n.__get_value()); 20346035553Spatrick } 20446035553Spatrick _LIBCPP_INLINE_VISIBILITY 20546035553Spatrick static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { 20646035553Spatrick return __v.__move(); 20746035553Spatrick } 20846035553Spatrick}; 20946035553Spatrick 21046035553Spatricktemplate <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, 21146035553Spatrick bool = _KVTypes::__is_map> 21246035553Spatrickstruct __hash_map_pointer_types {}; 21346035553Spatrick 21446035553Spatricktemplate <class _Tp, class _AllocPtr, class _KVTypes> 21546035553Spatrickstruct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { 21646035553Spatrick typedef typename _KVTypes::__map_value_type _Mv; 217*4bdff4beSrobert typedef __rebind_pointer_t<_AllocPtr, _Mv> 21846035553Spatrick __map_value_type_pointer; 219*4bdff4beSrobert typedef __rebind_pointer_t<_AllocPtr, const _Mv> 22046035553Spatrick __const_map_value_type_pointer; 22146035553Spatrick}; 22246035553Spatrick 22346035553Spatricktemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> 22446035553Spatrickstruct __hash_node_types; 22546035553Spatrick 22646035553Spatricktemplate <class _NodePtr, class _Tp, class _VoidPtr> 22746035553Spatrickstruct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > 22846035553Spatrick : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> 22946035553Spatrick 23046035553Spatrick{ 23146035553Spatrick typedef __hash_key_value_types<_Tp> __base; 23246035553Spatrick 23346035553Spatrickpublic: 23446035553Spatrick typedef ptrdiff_t difference_type; 23546035553Spatrick typedef size_t size_type; 23646035553Spatrick 237*4bdff4beSrobert typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; 23846035553Spatrick 23946035553Spatrick typedef typename pointer_traits<_NodePtr>::element_type __node_type; 24046035553Spatrick typedef _NodePtr __node_pointer; 24146035553Spatrick 24246035553Spatrick typedef __hash_node_base<__node_pointer> __node_base_type; 243*4bdff4beSrobert typedef __rebind_pointer_t<_NodePtr, __node_base_type> 24446035553Spatrick __node_base_pointer; 24546035553Spatrick 24646035553Spatrick typedef typename __node_base_type::__next_pointer __next_pointer; 24746035553Spatrick 24846035553Spatrick typedef _Tp __node_value_type; 249*4bdff4beSrobert typedef __rebind_pointer_t<_VoidPtr, __node_value_type> 25046035553Spatrick __node_value_type_pointer; 251*4bdff4beSrobert typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> 25246035553Spatrick __const_node_value_type_pointer; 25346035553Spatrick 25446035553Spatrickprivate: 25546035553Spatrick static_assert(!is_const<__node_type>::value, 25646035553Spatrick "_NodePtr should never be a pointer to const"); 25746035553Spatrick static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), 25846035553Spatrick "_VoidPtr does not point to unqualified void type"); 259*4bdff4beSrobert static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>, 26046035553Spatrick _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); 26146035553Spatrick}; 26246035553Spatrick 26346035553Spatricktemplate <class _HashIterator> 26446035553Spatrickstruct __hash_node_types_from_iterator; 26546035553Spatricktemplate <class _NodePtr> 26646035553Spatrickstruct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 26746035553Spatricktemplate <class _NodePtr> 26846035553Spatrickstruct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 26946035553Spatricktemplate <class _NodePtr> 27046035553Spatrickstruct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 27146035553Spatricktemplate <class _NodePtr> 27246035553Spatrickstruct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; 27346035553Spatrick 27446035553Spatrick 27546035553Spatricktemplate <class _NodeValueTp, class _VoidPtr> 27646035553Spatrickstruct __make_hash_node_types { 27746035553Spatrick typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; 278*4bdff4beSrobert typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr; 27946035553Spatrick typedef __hash_node_types<_NodePtr> type; 28046035553Spatrick}; 28146035553Spatrick 28246035553Spatricktemplate <class _NodePtr> 28346035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_iterator 28446035553Spatrick{ 28546035553Spatrick typedef __hash_node_types<_NodePtr> _NodeTypes; 28646035553Spatrick typedef _NodePtr __node_pointer; 28746035553Spatrick typedef typename _NodeTypes::__next_pointer __next_pointer; 28846035553Spatrick 28946035553Spatrick __next_pointer __node_; 29046035553Spatrick 29146035553Spatrickpublic: 29246035553Spatrick typedef forward_iterator_tag iterator_category; 29346035553Spatrick typedef typename _NodeTypes::__node_value_type value_type; 29446035553Spatrick typedef typename _NodeTypes::difference_type difference_type; 29546035553Spatrick typedef value_type& reference; 29646035553Spatrick typedef typename _NodeTypes::__node_value_type_pointer pointer; 29746035553Spatrick 29846035553Spatrick _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { 299*4bdff4beSrobert _VSTD::__debug_db_insert_i(this); 30046035553Spatrick } 30146035553Spatrick 302*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 30346035553Spatrick _LIBCPP_INLINE_VISIBILITY 30446035553Spatrick __hash_iterator(const __hash_iterator& __i) 30546035553Spatrick : __node_(__i.__node_) 30646035553Spatrick { 307*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 30846035553Spatrick } 30946035553Spatrick 31046035553Spatrick _LIBCPP_INLINE_VISIBILITY 31146035553Spatrick ~__hash_iterator() 31246035553Spatrick { 31346035553Spatrick __get_db()->__erase_i(this); 31446035553Spatrick } 31546035553Spatrick 31646035553Spatrick _LIBCPP_INLINE_VISIBILITY 31746035553Spatrick __hash_iterator& operator=(const __hash_iterator& __i) 31846035553Spatrick { 319*4bdff4beSrobert if (this != _VSTD::addressof(__i)) 32046035553Spatrick { 321*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 32246035553Spatrick __node_ = __i.__node_; 32346035553Spatrick } 32446035553Spatrick return *this; 32546035553Spatrick } 326*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE 32746035553Spatrick 32846035553Spatrick _LIBCPP_INLINE_VISIBILITY 32946035553Spatrick reference operator*() const { 33046035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 33146035553Spatrick "Attempted to dereference a non-dereferenceable unordered container iterator"); 33246035553Spatrick return __node_->__upcast()->__value_; 33346035553Spatrick } 33446035553Spatrick 33546035553Spatrick _LIBCPP_INLINE_VISIBILITY 33646035553Spatrick pointer operator->() const { 33746035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 33846035553Spatrick "Attempted to dereference a non-dereferenceable unordered container iterator"); 33946035553Spatrick return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 34046035553Spatrick } 34146035553Spatrick 34246035553Spatrick _LIBCPP_INLINE_VISIBILITY 34346035553Spatrick __hash_iterator& operator++() { 34446035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 34576d0caaeSpatrick "Attempted to increment a non-incrementable unordered container iterator"); 34646035553Spatrick __node_ = __node_->__next_; 34746035553Spatrick return *this; 34846035553Spatrick } 34946035553Spatrick 35046035553Spatrick _LIBCPP_INLINE_VISIBILITY 35146035553Spatrick __hash_iterator operator++(int) 35246035553Spatrick { 35346035553Spatrick __hash_iterator __t(*this); 35446035553Spatrick ++(*this); 35546035553Spatrick return __t; 35646035553Spatrick } 35746035553Spatrick 35846035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 35946035553Spatrick bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) 36046035553Spatrick { 36146035553Spatrick return __x.__node_ == __y.__node_; 36246035553Spatrick } 36346035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 36446035553Spatrick bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) 36546035553Spatrick {return !(__x == __y);} 36646035553Spatrick 36746035553Spatrickprivate: 36846035553Spatrick _LIBCPP_INLINE_VISIBILITY 369*4bdff4beSrobert explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT 37046035553Spatrick : __node_(__node) 37146035553Spatrick { 372*4bdff4beSrobert (void)__c; 373*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 37446035553Spatrick __get_db()->__insert_ic(this, __c); 37546035553Spatrick#endif 376*4bdff4beSrobert } 37746035553Spatrick template <class, class, class, class> friend class __hash_table; 37846035553Spatrick template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 37946035553Spatrick template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 38046035553Spatrick template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 38146035553Spatrick template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 38246035553Spatrick}; 38346035553Spatrick 38446035553Spatricktemplate <class _NodePtr> 38546035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_const_iterator 38646035553Spatrick{ 38746035553Spatrick static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, ""); 38846035553Spatrick typedef __hash_node_types<_NodePtr> _NodeTypes; 38946035553Spatrick typedef _NodePtr __node_pointer; 39046035553Spatrick typedef typename _NodeTypes::__next_pointer __next_pointer; 39146035553Spatrick 39246035553Spatrick __next_pointer __node_; 39346035553Spatrick 39446035553Spatrickpublic: 39546035553Spatrick typedef __hash_iterator<_NodePtr> __non_const_iterator; 39646035553Spatrick 39746035553Spatrick typedef forward_iterator_tag iterator_category; 39846035553Spatrick typedef typename _NodeTypes::__node_value_type value_type; 39946035553Spatrick typedef typename _NodeTypes::difference_type difference_type; 40046035553Spatrick typedef const value_type& reference; 40146035553Spatrick typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 40246035553Spatrick 40346035553Spatrick 40446035553Spatrick _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { 405*4bdff4beSrobert _VSTD::__debug_db_insert_i(this); 40646035553Spatrick } 40746035553Spatrick 40846035553Spatrick _LIBCPP_INLINE_VISIBILITY 40946035553Spatrick __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT 41046035553Spatrick : __node_(__x.__node_) 41146035553Spatrick { 412*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 413*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); 41476d0caaeSpatrick#endif 41546035553Spatrick } 41646035553Spatrick 417*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 41846035553Spatrick _LIBCPP_INLINE_VISIBILITY 41946035553Spatrick __hash_const_iterator(const __hash_const_iterator& __i) 42046035553Spatrick : __node_(__i.__node_) 42146035553Spatrick { 422*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 42346035553Spatrick } 42446035553Spatrick 42546035553Spatrick _LIBCPP_INLINE_VISIBILITY 42646035553Spatrick ~__hash_const_iterator() 42746035553Spatrick { 42846035553Spatrick __get_db()->__erase_i(this); 42946035553Spatrick } 43046035553Spatrick 43146035553Spatrick _LIBCPP_INLINE_VISIBILITY 43246035553Spatrick __hash_const_iterator& operator=(const __hash_const_iterator& __i) 43346035553Spatrick { 434*4bdff4beSrobert if (this != _VSTD::addressof(__i)) 43546035553Spatrick { 436*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 43746035553Spatrick __node_ = __i.__node_; 43846035553Spatrick } 43946035553Spatrick return *this; 44046035553Spatrick } 441*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE 44246035553Spatrick 44346035553Spatrick _LIBCPP_INLINE_VISIBILITY 44446035553Spatrick reference operator*() const { 44546035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 44646035553Spatrick "Attempted to dereference a non-dereferenceable unordered container const_iterator"); 44746035553Spatrick return __node_->__upcast()->__value_; 44846035553Spatrick } 44946035553Spatrick _LIBCPP_INLINE_VISIBILITY 45046035553Spatrick pointer operator->() const { 45146035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 45246035553Spatrick "Attempted to dereference a non-dereferenceable unordered container const_iterator"); 45346035553Spatrick return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 45446035553Spatrick } 45546035553Spatrick 45646035553Spatrick _LIBCPP_INLINE_VISIBILITY 45746035553Spatrick __hash_const_iterator& operator++() { 45846035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 45976d0caaeSpatrick "Attempted to increment a non-incrementable unordered container const_iterator"); 46046035553Spatrick __node_ = __node_->__next_; 46146035553Spatrick return *this; 46246035553Spatrick } 46346035553Spatrick 46446035553Spatrick _LIBCPP_INLINE_VISIBILITY 46546035553Spatrick __hash_const_iterator operator++(int) 46646035553Spatrick { 46746035553Spatrick __hash_const_iterator __t(*this); 46846035553Spatrick ++(*this); 46946035553Spatrick return __t; 47046035553Spatrick } 47146035553Spatrick 47246035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 47346035553Spatrick bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) 47446035553Spatrick { 47546035553Spatrick return __x.__node_ == __y.__node_; 47646035553Spatrick } 47746035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 47846035553Spatrick bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) 47946035553Spatrick {return !(__x == __y);} 48046035553Spatrick 48146035553Spatrickprivate: 48246035553Spatrick _LIBCPP_INLINE_VISIBILITY 483*4bdff4beSrobert explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT 48446035553Spatrick : __node_(__node) 48546035553Spatrick { 486*4bdff4beSrobert (void)__c; 487*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 48846035553Spatrick __get_db()->__insert_ic(this, __c); 48946035553Spatrick#endif 490*4bdff4beSrobert } 49146035553Spatrick template <class, class, class, class> friend class __hash_table; 49246035553Spatrick template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 49346035553Spatrick template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 49446035553Spatrick template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 49546035553Spatrick}; 49646035553Spatrick 49746035553Spatricktemplate <class _NodePtr> 49846035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_local_iterator 49946035553Spatrick{ 50046035553Spatrick typedef __hash_node_types<_NodePtr> _NodeTypes; 50146035553Spatrick typedef _NodePtr __node_pointer; 50246035553Spatrick typedef typename _NodeTypes::__next_pointer __next_pointer; 50346035553Spatrick 50446035553Spatrick __next_pointer __node_; 50546035553Spatrick size_t __bucket_; 50646035553Spatrick size_t __bucket_count_; 50746035553Spatrick 50846035553Spatrickpublic: 50946035553Spatrick typedef forward_iterator_tag iterator_category; 51046035553Spatrick typedef typename _NodeTypes::__node_value_type value_type; 51146035553Spatrick typedef typename _NodeTypes::difference_type difference_type; 51246035553Spatrick typedef value_type& reference; 51346035553Spatrick typedef typename _NodeTypes::__node_value_type_pointer pointer; 51446035553Spatrick 51546035553Spatrick _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { 516*4bdff4beSrobert _VSTD::__debug_db_insert_i(this); 51746035553Spatrick } 51846035553Spatrick 519*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 52046035553Spatrick _LIBCPP_INLINE_VISIBILITY 52146035553Spatrick __hash_local_iterator(const __hash_local_iterator& __i) 52246035553Spatrick : __node_(__i.__node_), 52346035553Spatrick __bucket_(__i.__bucket_), 52446035553Spatrick __bucket_count_(__i.__bucket_count_) 52546035553Spatrick { 526*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 52746035553Spatrick } 52846035553Spatrick 52946035553Spatrick _LIBCPP_INLINE_VISIBILITY 53046035553Spatrick ~__hash_local_iterator() 53146035553Spatrick { 53246035553Spatrick __get_db()->__erase_i(this); 53346035553Spatrick } 53446035553Spatrick 53546035553Spatrick _LIBCPP_INLINE_VISIBILITY 53646035553Spatrick __hash_local_iterator& operator=(const __hash_local_iterator& __i) 53746035553Spatrick { 538*4bdff4beSrobert if (this != _VSTD::addressof(__i)) 53946035553Spatrick { 540*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 54146035553Spatrick __node_ = __i.__node_; 54246035553Spatrick __bucket_ = __i.__bucket_; 54346035553Spatrick __bucket_count_ = __i.__bucket_count_; 54446035553Spatrick } 54546035553Spatrick return *this; 54646035553Spatrick } 547*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE 54846035553Spatrick 54946035553Spatrick _LIBCPP_INLINE_VISIBILITY 55046035553Spatrick reference operator*() const { 55146035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 55246035553Spatrick "Attempted to dereference a non-dereferenceable unordered container local_iterator"); 55346035553Spatrick return __node_->__upcast()->__value_; 55446035553Spatrick } 55546035553Spatrick 55646035553Spatrick _LIBCPP_INLINE_VISIBILITY 55746035553Spatrick pointer operator->() const { 55846035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 55946035553Spatrick "Attempted to dereference a non-dereferenceable unordered container local_iterator"); 56046035553Spatrick return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 56146035553Spatrick } 56246035553Spatrick 56346035553Spatrick _LIBCPP_INLINE_VISIBILITY 56446035553Spatrick __hash_local_iterator& operator++() { 56546035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 56676d0caaeSpatrick "Attempted to increment a non-incrementable unordered container local_iterator"); 56746035553Spatrick __node_ = __node_->__next_; 568*4bdff4beSrobert if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) 56946035553Spatrick __node_ = nullptr; 57046035553Spatrick return *this; 57146035553Spatrick } 57246035553Spatrick 57346035553Spatrick _LIBCPP_INLINE_VISIBILITY 57446035553Spatrick __hash_local_iterator operator++(int) 57546035553Spatrick { 57646035553Spatrick __hash_local_iterator __t(*this); 57746035553Spatrick ++(*this); 57846035553Spatrick return __t; 57946035553Spatrick } 58046035553Spatrick 58146035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 58246035553Spatrick bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) 58346035553Spatrick { 58446035553Spatrick return __x.__node_ == __y.__node_; 58546035553Spatrick } 58646035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 58746035553Spatrick bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) 58846035553Spatrick {return !(__x == __y);} 58946035553Spatrick 59046035553Spatrickprivate: 59146035553Spatrick _LIBCPP_INLINE_VISIBILITY 592*4bdff4beSrobert explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, 59346035553Spatrick size_t __bucket_count, const void* __c) _NOEXCEPT 59446035553Spatrick : __node_(__node), 59546035553Spatrick __bucket_(__bucket), 59646035553Spatrick __bucket_count_(__bucket_count) 59746035553Spatrick { 598*4bdff4beSrobert (void)__c; 599*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 60046035553Spatrick __get_db()->__insert_ic(this, __c); 60146035553Spatrick#endif 602*4bdff4beSrobert if (__node_ != nullptr) 603*4bdff4beSrobert __node_ = __node_->__next_; 604*4bdff4beSrobert } 60546035553Spatrick template <class, class, class, class> friend class __hash_table; 60646035553Spatrick template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 60746035553Spatrick template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; 60846035553Spatrick}; 60946035553Spatrick 61046035553Spatricktemplate <class _ConstNodePtr> 61146035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator 61246035553Spatrick{ 61346035553Spatrick typedef __hash_node_types<_ConstNodePtr> _NodeTypes; 61446035553Spatrick typedef _ConstNodePtr __node_pointer; 61546035553Spatrick typedef typename _NodeTypes::__next_pointer __next_pointer; 61646035553Spatrick 61746035553Spatrick __next_pointer __node_; 61846035553Spatrick size_t __bucket_; 61946035553Spatrick size_t __bucket_count_; 62046035553Spatrick 62146035553Spatrick typedef pointer_traits<__node_pointer> __pointer_traits; 62246035553Spatrick typedef typename __pointer_traits::element_type __node; 623*4bdff4beSrobert typedef __remove_const_t<__node> __non_const_node; 624*4bdff4beSrobert typedef __rebind_pointer_t<__node_pointer, __non_const_node> 62546035553Spatrick __non_const_node_pointer; 62646035553Spatrickpublic: 62746035553Spatrick typedef __hash_local_iterator<__non_const_node_pointer> 62846035553Spatrick __non_const_iterator; 62946035553Spatrick 63046035553Spatrick typedef forward_iterator_tag iterator_category; 63146035553Spatrick typedef typename _NodeTypes::__node_value_type value_type; 63246035553Spatrick typedef typename _NodeTypes::difference_type difference_type; 63346035553Spatrick typedef const value_type& reference; 63446035553Spatrick typedef typename _NodeTypes::__const_node_value_type_pointer pointer; 63546035553Spatrick 63646035553Spatrick 63746035553Spatrick _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { 638*4bdff4beSrobert _VSTD::__debug_db_insert_i(this); 63946035553Spatrick } 64046035553Spatrick 64146035553Spatrick _LIBCPP_INLINE_VISIBILITY 64246035553Spatrick __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT 64346035553Spatrick : __node_(__x.__node_), 64446035553Spatrick __bucket_(__x.__bucket_), 64546035553Spatrick __bucket_count_(__x.__bucket_count_) 64646035553Spatrick { 647*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 648*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); 64976d0caaeSpatrick#endif 65046035553Spatrick } 65146035553Spatrick 652*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 65346035553Spatrick _LIBCPP_INLINE_VISIBILITY 65446035553Spatrick __hash_const_local_iterator(const __hash_const_local_iterator& __i) 65546035553Spatrick : __node_(__i.__node_), 65646035553Spatrick __bucket_(__i.__bucket_), 65746035553Spatrick __bucket_count_(__i.__bucket_count_) 65846035553Spatrick { 659*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 66046035553Spatrick } 66146035553Spatrick 66246035553Spatrick _LIBCPP_INLINE_VISIBILITY 66346035553Spatrick ~__hash_const_local_iterator() 66446035553Spatrick { 66546035553Spatrick __get_db()->__erase_i(this); 66646035553Spatrick } 66746035553Spatrick 66846035553Spatrick _LIBCPP_INLINE_VISIBILITY 66946035553Spatrick __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) 67046035553Spatrick { 671*4bdff4beSrobert if (this != _VSTD::addressof(__i)) 67246035553Spatrick { 673*4bdff4beSrobert __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); 67446035553Spatrick __node_ = __i.__node_; 67546035553Spatrick __bucket_ = __i.__bucket_; 67646035553Spatrick __bucket_count_ = __i.__bucket_count_; 67746035553Spatrick } 67846035553Spatrick return *this; 67946035553Spatrick } 680*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE 68146035553Spatrick 68246035553Spatrick _LIBCPP_INLINE_VISIBILITY 68346035553Spatrick reference operator*() const { 68446035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 68546035553Spatrick "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); 68646035553Spatrick return __node_->__upcast()->__value_; 68746035553Spatrick } 68846035553Spatrick 68946035553Spatrick _LIBCPP_INLINE_VISIBILITY 69046035553Spatrick pointer operator->() const { 69146035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 69246035553Spatrick "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); 69346035553Spatrick return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); 69446035553Spatrick } 69546035553Spatrick 69646035553Spatrick _LIBCPP_INLINE_VISIBILITY 69746035553Spatrick __hash_const_local_iterator& operator++() { 69846035553Spatrick _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), 69976d0caaeSpatrick "Attempted to increment a non-incrementable unordered container const_local_iterator"); 70046035553Spatrick __node_ = __node_->__next_; 701*4bdff4beSrobert if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) 70246035553Spatrick __node_ = nullptr; 70346035553Spatrick return *this; 70446035553Spatrick } 70546035553Spatrick 70646035553Spatrick _LIBCPP_INLINE_VISIBILITY 70746035553Spatrick __hash_const_local_iterator operator++(int) 70846035553Spatrick { 70946035553Spatrick __hash_const_local_iterator __t(*this); 71046035553Spatrick ++(*this); 71146035553Spatrick return __t; 71246035553Spatrick } 71346035553Spatrick 71446035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 71546035553Spatrick bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) 71646035553Spatrick { 71746035553Spatrick return __x.__node_ == __y.__node_; 71846035553Spatrick } 71946035553Spatrick friend _LIBCPP_INLINE_VISIBILITY 72046035553Spatrick bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) 72146035553Spatrick {return !(__x == __y);} 72246035553Spatrick 72346035553Spatrickprivate: 72446035553Spatrick _LIBCPP_INLINE_VISIBILITY 725*4bdff4beSrobert explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, 72646035553Spatrick size_t __bucket_count, const void* __c) _NOEXCEPT 72776d0caaeSpatrick : __node_(__node_ptr), 72846035553Spatrick __bucket_(__bucket), 72946035553Spatrick __bucket_count_(__bucket_count) 73046035553Spatrick { 731*4bdff4beSrobert (void)__c; 732*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 73346035553Spatrick __get_db()->__insert_ic(this, __c); 73446035553Spatrick#endif 735*4bdff4beSrobert if (__node_ != nullptr) 736*4bdff4beSrobert __node_ = __node_->__next_; 737*4bdff4beSrobert } 73846035553Spatrick template <class, class, class, class> friend class __hash_table; 73946035553Spatrick template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 74046035553Spatrick}; 74146035553Spatrick 74246035553Spatricktemplate <class _Alloc> 74346035553Spatrickclass __bucket_list_deallocator 74446035553Spatrick{ 74546035553Spatrick typedef _Alloc allocator_type; 74646035553Spatrick typedef allocator_traits<allocator_type> __alloc_traits; 74746035553Spatrick typedef typename __alloc_traits::size_type size_type; 74846035553Spatrick 74946035553Spatrick __compressed_pair<size_type, allocator_type> __data_; 75046035553Spatrickpublic: 75146035553Spatrick typedef typename __alloc_traits::pointer pointer; 75246035553Spatrick 75346035553Spatrick _LIBCPP_INLINE_VISIBILITY 75446035553Spatrick __bucket_list_deallocator() 75546035553Spatrick _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 75646035553Spatrick : __data_(0, __default_init_tag()) {} 75746035553Spatrick 75846035553Spatrick _LIBCPP_INLINE_VISIBILITY 75946035553Spatrick __bucket_list_deallocator(const allocator_type& __a, size_type __size) 76046035553Spatrick _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 76146035553Spatrick : __data_(__size, __a) {} 76246035553Spatrick 76346035553Spatrick _LIBCPP_INLINE_VISIBILITY 76446035553Spatrick __bucket_list_deallocator(__bucket_list_deallocator&& __x) 76546035553Spatrick _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 76646035553Spatrick : __data_(_VSTD::move(__x.__data_)) 76746035553Spatrick { 76846035553Spatrick __x.size() = 0; 76946035553Spatrick } 77046035553Spatrick 77146035553Spatrick _LIBCPP_INLINE_VISIBILITY 77246035553Spatrick size_type& size() _NOEXCEPT {return __data_.first();} 77346035553Spatrick _LIBCPP_INLINE_VISIBILITY 77446035553Spatrick size_type size() const _NOEXCEPT {return __data_.first();} 77546035553Spatrick 77646035553Spatrick _LIBCPP_INLINE_VISIBILITY 77746035553Spatrick allocator_type& __alloc() _NOEXCEPT {return __data_.second();} 77846035553Spatrick _LIBCPP_INLINE_VISIBILITY 77946035553Spatrick const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} 78046035553Spatrick 78146035553Spatrick _LIBCPP_INLINE_VISIBILITY 78246035553Spatrick void operator()(pointer __p) _NOEXCEPT 78346035553Spatrick { 78446035553Spatrick __alloc_traits::deallocate(__alloc(), __p, size()); 78546035553Spatrick } 78646035553Spatrick}; 78746035553Spatrick 78846035553Spatricktemplate <class _Alloc> class __hash_map_node_destructor; 78946035553Spatrick 79046035553Spatricktemplate <class _Alloc> 79146035553Spatrickclass __hash_node_destructor 79246035553Spatrick{ 79346035553Spatrick typedef _Alloc allocator_type; 79446035553Spatrick typedef allocator_traits<allocator_type> __alloc_traits; 79546035553Spatrick 79646035553Spatrickpublic: 79746035553Spatrick typedef typename __alloc_traits::pointer pointer; 79846035553Spatrickprivate: 79946035553Spatrick typedef __hash_node_types<pointer> _NodeTypes; 80046035553Spatrick 80146035553Spatrick allocator_type& __na_; 80246035553Spatrick 80346035553Spatrickpublic: 80446035553Spatrick bool __value_constructed; 80546035553Spatrick 80646035553Spatrick __hash_node_destructor(__hash_node_destructor const&) = default; 80746035553Spatrick __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; 80846035553Spatrick 80946035553Spatrick 81046035553Spatrick _LIBCPP_INLINE_VISIBILITY 81146035553Spatrick explicit __hash_node_destructor(allocator_type& __na, 81246035553Spatrick bool __constructed = false) _NOEXCEPT 81346035553Spatrick : __na_(__na), 81446035553Spatrick __value_constructed(__constructed) 81546035553Spatrick {} 81646035553Spatrick 81746035553Spatrick _LIBCPP_INLINE_VISIBILITY 81846035553Spatrick void operator()(pointer __p) _NOEXCEPT 81946035553Spatrick { 82046035553Spatrick if (__value_constructed) 82146035553Spatrick __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); 82246035553Spatrick if (__p) 82346035553Spatrick __alloc_traits::deallocate(__na_, __p, 1); 82446035553Spatrick } 82546035553Spatrick 82646035553Spatrick template <class> friend class __hash_map_node_destructor; 82746035553Spatrick}; 82846035553Spatrick 82946035553Spatrick#if _LIBCPP_STD_VER > 14 83046035553Spatricktemplate <class _NodeType, class _Alloc> 83146035553Spatrickstruct __generic_container_node_destructor; 83246035553Spatrick 83346035553Spatricktemplate <class _Tp, class _VoidPtr, class _Alloc> 83446035553Spatrickstruct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> 83546035553Spatrick : __hash_node_destructor<_Alloc> 83646035553Spatrick{ 83746035553Spatrick using __hash_node_destructor<_Alloc>::__hash_node_destructor; 83846035553Spatrick}; 83946035553Spatrick#endif 84046035553Spatrick 84146035553Spatricktemplate <class _Key, class _Hash, class _Equal> 84246035553Spatrickstruct __enforce_unordered_container_requirements { 84346035553Spatrick#ifndef _LIBCPP_CXX03_LANG 84446035553Spatrick static_assert(__check_hash_requirements<_Key, _Hash>::value, 84546035553Spatrick "the specified hash does not meet the Hash requirements"); 84646035553Spatrick static_assert(is_copy_constructible<_Equal>::value, 84746035553Spatrick "the specified comparator is required to be copy constructible"); 84846035553Spatrick#endif 84946035553Spatrick typedef int type; 85046035553Spatrick}; 85146035553Spatrick 85246035553Spatricktemplate <class _Key, class _Hash, class _Equal> 85346035553Spatrick#ifndef _LIBCPP_CXX03_LANG 85446035553Spatrick _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, 85546035553Spatrick "the specified comparator type does not provide a viable const call operator") 85646035553Spatrick _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, 85746035553Spatrick "the specified hash functor does not provide a viable const call operator") 85846035553Spatrick#endif 85946035553Spatricktypename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type 86046035553Spatrick__diagnose_unordered_container_requirements(int); 86146035553Spatrick 86246035553Spatrick// This dummy overload is used so that the compiler won't emit a spurious 86346035553Spatrick// "no matching function for call to __diagnose_unordered_xxx" diagnostic 86446035553Spatrick// when the overload above causes a hard error. 86546035553Spatricktemplate <class _Key, class _Hash, class _Equal> 86646035553Spatrickint __diagnose_unordered_container_requirements(void*); 86746035553Spatrick 86846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 86946035553Spatrickclass __hash_table 87046035553Spatrick{ 87146035553Spatrickpublic: 87246035553Spatrick typedef _Tp value_type; 87346035553Spatrick typedef _Hash hasher; 87446035553Spatrick typedef _Equal key_equal; 87546035553Spatrick typedef _Alloc allocator_type; 87646035553Spatrick 87746035553Spatrickprivate: 87846035553Spatrick typedef allocator_traits<allocator_type> __alloc_traits; 87946035553Spatrick typedef typename 88046035553Spatrick __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type 88146035553Spatrick _NodeTypes; 88246035553Spatrickpublic: 88346035553Spatrick 88446035553Spatrick typedef typename _NodeTypes::__node_value_type __node_value_type; 88546035553Spatrick typedef typename _NodeTypes::__container_value_type __container_value_type; 88646035553Spatrick typedef typename _NodeTypes::key_type key_type; 88746035553Spatrick typedef value_type& reference; 88846035553Spatrick typedef const value_type& const_reference; 88946035553Spatrick typedef typename __alloc_traits::pointer pointer; 89046035553Spatrick typedef typename __alloc_traits::const_pointer const_pointer; 89146035553Spatrick#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE 89246035553Spatrick typedef typename __alloc_traits::size_type size_type; 89346035553Spatrick#else 89446035553Spatrick typedef typename _NodeTypes::size_type size_type; 89546035553Spatrick#endif 89646035553Spatrick typedef typename _NodeTypes::difference_type difference_type; 89746035553Spatrickpublic: 89846035553Spatrick // Create __node 89946035553Spatrick 90046035553Spatrick typedef typename _NodeTypes::__node_type __node; 901*4bdff4beSrobert typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; 90246035553Spatrick typedef allocator_traits<__node_allocator> __node_traits; 90346035553Spatrick typedef typename _NodeTypes::__void_pointer __void_pointer; 90446035553Spatrick typedef typename _NodeTypes::__node_pointer __node_pointer; 90546035553Spatrick typedef typename _NodeTypes::__node_pointer __node_const_pointer; 90646035553Spatrick typedef typename _NodeTypes::__node_base_type __first_node; 90746035553Spatrick typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; 90846035553Spatrick typedef typename _NodeTypes::__next_pointer __next_pointer; 90946035553Spatrick 91046035553Spatrickprivate: 91146035553Spatrick // check for sane allocator pointer rebinding semantics. Rebinding the 91246035553Spatrick // allocator for a new pointer type should be exactly the same as rebinding 91346035553Spatrick // the pointer using 'pointer_traits'. 91446035553Spatrick static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), 91546035553Spatrick "Allocator does not rebind pointers in a sane manner."); 916*4bdff4beSrobert typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; 91746035553Spatrick typedef allocator_traits<__node_base_allocator> __node_base_traits; 91846035553Spatrick static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), 91946035553Spatrick "Allocator does not rebind pointers in a sane manner."); 92046035553Spatrick 92146035553Spatrickprivate: 92246035553Spatrick 923*4bdff4beSrobert typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; 92446035553Spatrick typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; 92546035553Spatrick typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; 92646035553Spatrick typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; 92746035553Spatrick typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; 92846035553Spatrick 92946035553Spatrick // --- Member data begin --- 93046035553Spatrick __bucket_list __bucket_list_; 93146035553Spatrick __compressed_pair<__first_node, __node_allocator> __p1_; 93246035553Spatrick __compressed_pair<size_type, hasher> __p2_; 93346035553Spatrick __compressed_pair<float, key_equal> __p3_; 93446035553Spatrick // --- Member data end --- 93546035553Spatrick 93646035553Spatrick _LIBCPP_INLINE_VISIBILITY 93746035553Spatrick size_type& size() _NOEXCEPT {return __p2_.first();} 93846035553Spatrickpublic: 93946035553Spatrick _LIBCPP_INLINE_VISIBILITY 94046035553Spatrick size_type size() const _NOEXCEPT {return __p2_.first();} 94146035553Spatrick 94246035553Spatrick _LIBCPP_INLINE_VISIBILITY 94346035553Spatrick hasher& hash_function() _NOEXCEPT {return __p2_.second();} 94446035553Spatrick _LIBCPP_INLINE_VISIBILITY 94546035553Spatrick const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} 94646035553Spatrick 94746035553Spatrick _LIBCPP_INLINE_VISIBILITY 94846035553Spatrick float& max_load_factor() _NOEXCEPT {return __p3_.first();} 94946035553Spatrick _LIBCPP_INLINE_VISIBILITY 95046035553Spatrick float max_load_factor() const _NOEXCEPT {return __p3_.first();} 95146035553Spatrick 95246035553Spatrick _LIBCPP_INLINE_VISIBILITY 95346035553Spatrick key_equal& key_eq() _NOEXCEPT {return __p3_.second();} 95446035553Spatrick _LIBCPP_INLINE_VISIBILITY 95546035553Spatrick const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} 95646035553Spatrick 95746035553Spatrick _LIBCPP_INLINE_VISIBILITY 95846035553Spatrick __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} 95946035553Spatrick _LIBCPP_INLINE_VISIBILITY 96046035553Spatrick const __node_allocator& __node_alloc() const _NOEXCEPT 96146035553Spatrick {return __p1_.second();} 96246035553Spatrick 96346035553Spatrickpublic: 96446035553Spatrick typedef __hash_iterator<__node_pointer> iterator; 96546035553Spatrick typedef __hash_const_iterator<__node_pointer> const_iterator; 96646035553Spatrick typedef __hash_local_iterator<__node_pointer> local_iterator; 96746035553Spatrick typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; 96846035553Spatrick 96946035553Spatrick _LIBCPP_INLINE_VISIBILITY 97046035553Spatrick __hash_table() 97146035553Spatrick _NOEXCEPT_( 97246035553Spatrick is_nothrow_default_constructible<__bucket_list>::value && 97346035553Spatrick is_nothrow_default_constructible<__first_node>::value && 97446035553Spatrick is_nothrow_default_constructible<__node_allocator>::value && 97546035553Spatrick is_nothrow_default_constructible<hasher>::value && 97646035553Spatrick is_nothrow_default_constructible<key_equal>::value); 97746035553Spatrick _LIBCPP_INLINE_VISIBILITY 97846035553Spatrick __hash_table(const hasher& __hf, const key_equal& __eql); 97946035553Spatrick __hash_table(const hasher& __hf, const key_equal& __eql, 98046035553Spatrick const allocator_type& __a); 98146035553Spatrick explicit __hash_table(const allocator_type& __a); 98246035553Spatrick __hash_table(const __hash_table& __u); 98346035553Spatrick __hash_table(const __hash_table& __u, const allocator_type& __a); 98446035553Spatrick __hash_table(__hash_table&& __u) 98546035553Spatrick _NOEXCEPT_( 98646035553Spatrick is_nothrow_move_constructible<__bucket_list>::value && 98746035553Spatrick is_nothrow_move_constructible<__first_node>::value && 98846035553Spatrick is_nothrow_move_constructible<__node_allocator>::value && 98946035553Spatrick is_nothrow_move_constructible<hasher>::value && 99046035553Spatrick is_nothrow_move_constructible<key_equal>::value); 99146035553Spatrick __hash_table(__hash_table&& __u, const allocator_type& __a); 99246035553Spatrick ~__hash_table(); 99346035553Spatrick 99446035553Spatrick __hash_table& operator=(const __hash_table& __u); 99546035553Spatrick _LIBCPP_INLINE_VISIBILITY 99646035553Spatrick __hash_table& operator=(__hash_table&& __u) 99746035553Spatrick _NOEXCEPT_( 99846035553Spatrick __node_traits::propagate_on_container_move_assignment::value && 99946035553Spatrick is_nothrow_move_assignable<__node_allocator>::value && 100046035553Spatrick is_nothrow_move_assignable<hasher>::value && 100146035553Spatrick is_nothrow_move_assignable<key_equal>::value); 100246035553Spatrick template <class _InputIterator> 100346035553Spatrick void __assign_unique(_InputIterator __first, _InputIterator __last); 100446035553Spatrick template <class _InputIterator> 100546035553Spatrick void __assign_multi(_InputIterator __first, _InputIterator __last); 100646035553Spatrick 100746035553Spatrick _LIBCPP_INLINE_VISIBILITY 100846035553Spatrick size_type max_size() const _NOEXCEPT 100946035553Spatrick { 101076d0caaeSpatrick return _VSTD::min<size_type>( 101146035553Spatrick __node_traits::max_size(__node_alloc()), 101246035553Spatrick numeric_limits<difference_type >::max() 101346035553Spatrick ); 101446035553Spatrick } 101546035553Spatrick 101646035553Spatrickprivate: 101746035553Spatrick _LIBCPP_INLINE_VISIBILITY 101846035553Spatrick __next_pointer __node_insert_multi_prepare(size_t __cp_hash, 101946035553Spatrick value_type& __cp_val); 102046035553Spatrick _LIBCPP_INLINE_VISIBILITY 102146035553Spatrick void __node_insert_multi_perform(__node_pointer __cp, 102246035553Spatrick __next_pointer __pn) _NOEXCEPT; 102346035553Spatrick 102446035553Spatrick _LIBCPP_INLINE_VISIBILITY 102546035553Spatrick __next_pointer __node_insert_unique_prepare(size_t __nd_hash, 102646035553Spatrick value_type& __nd_val); 102746035553Spatrick _LIBCPP_INLINE_VISIBILITY 102846035553Spatrick void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; 102946035553Spatrick 103046035553Spatrickpublic: 103146035553Spatrick _LIBCPP_INLINE_VISIBILITY 103246035553Spatrick pair<iterator, bool> __node_insert_unique(__node_pointer __nd); 103346035553Spatrick _LIBCPP_INLINE_VISIBILITY 103446035553Spatrick iterator __node_insert_multi(__node_pointer __nd); 103546035553Spatrick _LIBCPP_INLINE_VISIBILITY 103646035553Spatrick iterator __node_insert_multi(const_iterator __p, 103746035553Spatrick __node_pointer __nd); 103846035553Spatrick 103946035553Spatrick template <class _Key, class ..._Args> 104046035553Spatrick _LIBCPP_INLINE_VISIBILITY 104146035553Spatrick pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args); 104246035553Spatrick 104346035553Spatrick template <class... _Args> 104446035553Spatrick _LIBCPP_INLINE_VISIBILITY 104546035553Spatrick pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); 104646035553Spatrick 104746035553Spatrick template <class _Pp> 104846035553Spatrick _LIBCPP_INLINE_VISIBILITY 104946035553Spatrick pair<iterator, bool> __emplace_unique(_Pp&& __x) { 105046035553Spatrick return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), 105146035553Spatrick __can_extract_key<_Pp, key_type>()); 105246035553Spatrick } 105346035553Spatrick 105446035553Spatrick template <class _First, class _Second> 105546035553Spatrick _LIBCPP_INLINE_VISIBILITY 1056*4bdff4beSrobert __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> > 1057*4bdff4beSrobert __emplace_unique(_First&& __f, _Second&& __s) { 105846035553Spatrick return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), 105946035553Spatrick _VSTD::forward<_Second>(__s)); 106046035553Spatrick } 106146035553Spatrick 106246035553Spatrick template <class... _Args> 106346035553Spatrick _LIBCPP_INLINE_VISIBILITY 106446035553Spatrick pair<iterator, bool> __emplace_unique(_Args&&... __args) { 106546035553Spatrick return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); 106646035553Spatrick } 106746035553Spatrick 106846035553Spatrick template <class _Pp> 106946035553Spatrick _LIBCPP_INLINE_VISIBILITY 107046035553Spatrick pair<iterator, bool> 107146035553Spatrick __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { 107246035553Spatrick return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); 107346035553Spatrick } 107446035553Spatrick template <class _Pp> 107546035553Spatrick _LIBCPP_INLINE_VISIBILITY 107646035553Spatrick pair<iterator, bool> 107746035553Spatrick __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { 107846035553Spatrick return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); 107946035553Spatrick } 108046035553Spatrick template <class _Pp> 108146035553Spatrick _LIBCPP_INLINE_VISIBILITY 108246035553Spatrick pair<iterator, bool> 108346035553Spatrick __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { 108446035553Spatrick return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); 108546035553Spatrick } 108646035553Spatrick 108746035553Spatrick template <class... _Args> 108846035553Spatrick _LIBCPP_INLINE_VISIBILITY 108946035553Spatrick iterator __emplace_multi(_Args&&... __args); 109046035553Spatrick template <class... _Args> 109146035553Spatrick _LIBCPP_INLINE_VISIBILITY 109246035553Spatrick iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); 109346035553Spatrick 109446035553Spatrick 109546035553Spatrick _LIBCPP_INLINE_VISIBILITY 109646035553Spatrick pair<iterator, bool> 109746035553Spatrick __insert_unique(__container_value_type&& __x) { 109846035553Spatrick return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); 109946035553Spatrick } 110046035553Spatrick 1101*4bdff4beSrobert template <class _Pp, class = __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value> > 110246035553Spatrick _LIBCPP_INLINE_VISIBILITY 110346035553Spatrick pair<iterator, bool> __insert_unique(_Pp&& __x) { 110446035553Spatrick return __emplace_unique(_VSTD::forward<_Pp>(__x)); 110546035553Spatrick } 110646035553Spatrick 110746035553Spatrick template <class _Pp> 110846035553Spatrick _LIBCPP_INLINE_VISIBILITY 110946035553Spatrick iterator __insert_multi(_Pp&& __x) { 111046035553Spatrick return __emplace_multi(_VSTD::forward<_Pp>(__x)); 111146035553Spatrick } 111246035553Spatrick 111346035553Spatrick template <class _Pp> 111446035553Spatrick _LIBCPP_INLINE_VISIBILITY 111546035553Spatrick iterator __insert_multi(const_iterator __p, _Pp&& __x) { 111646035553Spatrick return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); 111746035553Spatrick } 111846035553Spatrick 111946035553Spatrick _LIBCPP_INLINE_VISIBILITY 112046035553Spatrick pair<iterator, bool> __insert_unique(const __container_value_type& __x) { 112146035553Spatrick return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); 112246035553Spatrick } 112346035553Spatrick 112446035553Spatrick#if _LIBCPP_STD_VER > 14 112546035553Spatrick template <class _NodeHandle, class _InsertReturnType> 112646035553Spatrick _LIBCPP_INLINE_VISIBILITY 112746035553Spatrick _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); 112846035553Spatrick template <class _NodeHandle> 112946035553Spatrick _LIBCPP_INLINE_VISIBILITY 113046035553Spatrick iterator __node_handle_insert_unique(const_iterator __hint, 113146035553Spatrick _NodeHandle&& __nh); 113246035553Spatrick template <class _Table> 113346035553Spatrick _LIBCPP_INLINE_VISIBILITY 113446035553Spatrick void __node_handle_merge_unique(_Table& __source); 113546035553Spatrick 113646035553Spatrick template <class _NodeHandle> 113746035553Spatrick _LIBCPP_INLINE_VISIBILITY 113846035553Spatrick iterator __node_handle_insert_multi(_NodeHandle&& __nh); 113946035553Spatrick template <class _NodeHandle> 114046035553Spatrick _LIBCPP_INLINE_VISIBILITY 114146035553Spatrick iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); 114246035553Spatrick template <class _Table> 114346035553Spatrick _LIBCPP_INLINE_VISIBILITY 114446035553Spatrick void __node_handle_merge_multi(_Table& __source); 114546035553Spatrick 114646035553Spatrick template <class _NodeHandle> 114746035553Spatrick _LIBCPP_INLINE_VISIBILITY 114846035553Spatrick _NodeHandle __node_handle_extract(key_type const& __key); 114946035553Spatrick template <class _NodeHandle> 115046035553Spatrick _LIBCPP_INLINE_VISIBILITY 115146035553Spatrick _NodeHandle __node_handle_extract(const_iterator __it); 115246035553Spatrick#endif 115346035553Spatrick 115446035553Spatrick void clear() _NOEXCEPT; 1155*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); } 1156*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); } 1157*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n) 1158*4bdff4beSrobert { 1159*4bdff4beSrobert __rehash_unique(static_cast<size_type>(std::ceil(__n / max_load_factor()))); 1160*4bdff4beSrobert } 1161*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n) 1162*4bdff4beSrobert { 1163*4bdff4beSrobert __rehash_multi(static_cast<size_type>(std::ceil(__n / max_load_factor()))); 1164*4bdff4beSrobert } 116546035553Spatrick 116646035553Spatrick _LIBCPP_INLINE_VISIBILITY 116746035553Spatrick size_type bucket_count() const _NOEXCEPT 116846035553Spatrick { 116946035553Spatrick return __bucket_list_.get_deleter().size(); 117046035553Spatrick } 117146035553Spatrick 117246035553Spatrick _LIBCPP_INLINE_VISIBILITY 117346035553Spatrick iterator begin() _NOEXCEPT; 117446035553Spatrick _LIBCPP_INLINE_VISIBILITY 117546035553Spatrick iterator end() _NOEXCEPT; 117646035553Spatrick _LIBCPP_INLINE_VISIBILITY 117746035553Spatrick const_iterator begin() const _NOEXCEPT; 117846035553Spatrick _LIBCPP_INLINE_VISIBILITY 117946035553Spatrick const_iterator end() const _NOEXCEPT; 118046035553Spatrick 118146035553Spatrick template <class _Key> 118246035553Spatrick _LIBCPP_INLINE_VISIBILITY 118346035553Spatrick size_type bucket(const _Key& __k) const 118446035553Spatrick { 118546035553Spatrick _LIBCPP_ASSERT(bucket_count() > 0, 118646035553Spatrick "unordered container::bucket(key) called when bucket_count() == 0"); 1187*4bdff4beSrobert return std::__constrain_hash(hash_function()(__k), bucket_count()); 118846035553Spatrick } 118946035553Spatrick 119046035553Spatrick template <class _Key> 119146035553Spatrick iterator find(const _Key& __x); 119246035553Spatrick template <class _Key> 119346035553Spatrick const_iterator find(const _Key& __x) const; 119446035553Spatrick 119546035553Spatrick typedef __hash_node_destructor<__node_allocator> _Dp; 119646035553Spatrick typedef unique_ptr<__node, _Dp> __node_holder; 119746035553Spatrick 119846035553Spatrick iterator erase(const_iterator __p); 119946035553Spatrick iterator erase(const_iterator __first, const_iterator __last); 120046035553Spatrick template <class _Key> 120146035553Spatrick size_type __erase_unique(const _Key& __k); 120246035553Spatrick template <class _Key> 120346035553Spatrick size_type __erase_multi(const _Key& __k); 120446035553Spatrick __node_holder remove(const_iterator __p) _NOEXCEPT; 120546035553Spatrick 120646035553Spatrick template <class _Key> 120746035553Spatrick _LIBCPP_INLINE_VISIBILITY 120846035553Spatrick size_type __count_unique(const _Key& __k) const; 120946035553Spatrick template <class _Key> 121046035553Spatrick size_type __count_multi(const _Key& __k) const; 121146035553Spatrick 121246035553Spatrick template <class _Key> 121346035553Spatrick pair<iterator, iterator> 121446035553Spatrick __equal_range_unique(const _Key& __k); 121546035553Spatrick template <class _Key> 121646035553Spatrick pair<const_iterator, const_iterator> 121746035553Spatrick __equal_range_unique(const _Key& __k) const; 121846035553Spatrick 121946035553Spatrick template <class _Key> 122046035553Spatrick pair<iterator, iterator> 122146035553Spatrick __equal_range_multi(const _Key& __k); 122246035553Spatrick template <class _Key> 122346035553Spatrick pair<const_iterator, const_iterator> 122446035553Spatrick __equal_range_multi(const _Key& __k) const; 122546035553Spatrick 122646035553Spatrick void swap(__hash_table& __u) 122746035553Spatrick#if _LIBCPP_STD_VER <= 11 122846035553Spatrick _NOEXCEPT_( 122946035553Spatrick __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value 123046035553Spatrick && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value 123146035553Spatrick || __is_nothrow_swappable<__pointer_allocator>::value) 123246035553Spatrick && (!__node_traits::propagate_on_container_swap::value 123346035553Spatrick || __is_nothrow_swappable<__node_allocator>::value) 123446035553Spatrick ); 123546035553Spatrick#else 123646035553Spatrick _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value); 123746035553Spatrick#endif 123846035553Spatrick 123946035553Spatrick _LIBCPP_INLINE_VISIBILITY 124046035553Spatrick size_type max_bucket_count() const _NOEXCEPT 124146035553Spatrick {return max_size(); } 124246035553Spatrick size_type bucket_size(size_type __n) const; 124346035553Spatrick _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT 124446035553Spatrick { 124546035553Spatrick size_type __bc = bucket_count(); 124646035553Spatrick return __bc != 0 ? (float)size() / __bc : 0.f; 124746035553Spatrick } 124846035553Spatrick _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT 124946035553Spatrick { 125046035553Spatrick _LIBCPP_ASSERT(__mlf > 0, 125146035553Spatrick "unordered container::max_load_factor(lf) called with lf <= 0"); 125246035553Spatrick max_load_factor() = _VSTD::max(__mlf, load_factor()); 125346035553Spatrick } 125446035553Spatrick 125546035553Spatrick _LIBCPP_INLINE_VISIBILITY 125646035553Spatrick local_iterator 125746035553Spatrick begin(size_type __n) 125846035553Spatrick { 125946035553Spatrick _LIBCPP_ASSERT(__n < bucket_count(), 126046035553Spatrick "unordered container::begin(n) called with n >= bucket_count()"); 126146035553Spatrick return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); 126246035553Spatrick } 126346035553Spatrick 126446035553Spatrick _LIBCPP_INLINE_VISIBILITY 126546035553Spatrick local_iterator 126646035553Spatrick end(size_type __n) 126746035553Spatrick { 126846035553Spatrick _LIBCPP_ASSERT(__n < bucket_count(), 126946035553Spatrick "unordered container::end(n) called with n >= bucket_count()"); 127046035553Spatrick return local_iterator(nullptr, __n, bucket_count(), this); 127146035553Spatrick } 127246035553Spatrick 127346035553Spatrick _LIBCPP_INLINE_VISIBILITY 127446035553Spatrick const_local_iterator 127546035553Spatrick cbegin(size_type __n) const 127646035553Spatrick { 127746035553Spatrick _LIBCPP_ASSERT(__n < bucket_count(), 127846035553Spatrick "unordered container::cbegin(n) called with n >= bucket_count()"); 127946035553Spatrick return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); 128046035553Spatrick } 128146035553Spatrick 128246035553Spatrick _LIBCPP_INLINE_VISIBILITY 128346035553Spatrick const_local_iterator 128446035553Spatrick cend(size_type __n) const 128546035553Spatrick { 128646035553Spatrick _LIBCPP_ASSERT(__n < bucket_count(), 128746035553Spatrick "unordered container::cend(n) called with n >= bucket_count()"); 128846035553Spatrick return const_local_iterator(nullptr, __n, bucket_count(), this); 128946035553Spatrick } 129046035553Spatrick 1291*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 129246035553Spatrick 129346035553Spatrick bool __dereferenceable(const const_iterator* __i) const; 129446035553Spatrick bool __decrementable(const const_iterator* __i) const; 129546035553Spatrick bool __addable(const const_iterator* __i, ptrdiff_t __n) const; 129646035553Spatrick bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; 129746035553Spatrick 1298*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE 129946035553Spatrick 130046035553Spatrickprivate: 1301*4bdff4beSrobert template <bool _UniqueKeys> void __rehash(size_type __n); 1302*4bdff4beSrobert template <bool _UniqueKeys> void __do_rehash(size_type __n); 130346035553Spatrick 130446035553Spatrick template <class ..._Args> 130546035553Spatrick __node_holder __construct_node(_Args&& ...__args); 130646035553Spatrick 130746035553Spatrick template <class _First, class ..._Rest> 130846035553Spatrick __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); 130946035553Spatrick 131046035553Spatrick 131146035553Spatrick _LIBCPP_INLINE_VISIBILITY 131246035553Spatrick void __copy_assign_alloc(const __hash_table& __u) 131346035553Spatrick {__copy_assign_alloc(__u, integral_constant<bool, 131446035553Spatrick __node_traits::propagate_on_container_copy_assignment::value>());} 131546035553Spatrick void __copy_assign_alloc(const __hash_table& __u, true_type); 131646035553Spatrick _LIBCPP_INLINE_VISIBILITY 131746035553Spatrick void __copy_assign_alloc(const __hash_table&, false_type) {} 131846035553Spatrick 131946035553Spatrick void __move_assign(__hash_table& __u, false_type); 132046035553Spatrick void __move_assign(__hash_table& __u, true_type) 132146035553Spatrick _NOEXCEPT_( 132246035553Spatrick is_nothrow_move_assignable<__node_allocator>::value && 132346035553Spatrick is_nothrow_move_assignable<hasher>::value && 132446035553Spatrick is_nothrow_move_assignable<key_equal>::value); 132546035553Spatrick _LIBCPP_INLINE_VISIBILITY 132646035553Spatrick void __move_assign_alloc(__hash_table& __u) 132746035553Spatrick _NOEXCEPT_( 132846035553Spatrick !__node_traits::propagate_on_container_move_assignment::value || 132946035553Spatrick (is_nothrow_move_assignable<__pointer_allocator>::value && 133046035553Spatrick is_nothrow_move_assignable<__node_allocator>::value)) 133146035553Spatrick {__move_assign_alloc(__u, integral_constant<bool, 133246035553Spatrick __node_traits::propagate_on_container_move_assignment::value>());} 133346035553Spatrick _LIBCPP_INLINE_VISIBILITY 133446035553Spatrick void __move_assign_alloc(__hash_table& __u, true_type) 133546035553Spatrick _NOEXCEPT_( 133646035553Spatrick is_nothrow_move_assignable<__pointer_allocator>::value && 133746035553Spatrick is_nothrow_move_assignable<__node_allocator>::value) 133846035553Spatrick { 133946035553Spatrick __bucket_list_.get_deleter().__alloc() = 134046035553Spatrick _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); 134146035553Spatrick __node_alloc() = _VSTD::move(__u.__node_alloc()); 134246035553Spatrick } 134346035553Spatrick _LIBCPP_INLINE_VISIBILITY 134446035553Spatrick void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} 134546035553Spatrick 134646035553Spatrick void __deallocate_node(__next_pointer __np) _NOEXCEPT; 134746035553Spatrick __next_pointer __detach() _NOEXCEPT; 134846035553Spatrick 134946035553Spatrick template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; 135046035553Spatrick template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; 135146035553Spatrick}; 135246035553Spatrick 135346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 135446035553Spatrickinline 135546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() 135646035553Spatrick _NOEXCEPT_( 135746035553Spatrick is_nothrow_default_constructible<__bucket_list>::value && 135846035553Spatrick is_nothrow_default_constructible<__first_node>::value && 135946035553Spatrick is_nothrow_default_constructible<__node_allocator>::value && 136046035553Spatrick is_nothrow_default_constructible<hasher>::value && 136146035553Spatrick is_nothrow_default_constructible<key_equal>::value) 136246035553Spatrick : __p2_(0, __default_init_tag()), 136346035553Spatrick __p3_(1.0f, __default_init_tag()) 136446035553Spatrick{ 136546035553Spatrick} 136646035553Spatrick 136746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 136846035553Spatrickinline 136946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, 137046035553Spatrick const key_equal& __eql) 137146035553Spatrick : __bucket_list_(nullptr, __bucket_list_deleter()), 137246035553Spatrick __p1_(), 137346035553Spatrick __p2_(0, __hf), 137446035553Spatrick __p3_(1.0f, __eql) 137546035553Spatrick{ 137646035553Spatrick} 137746035553Spatrick 137846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 137946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, 138046035553Spatrick const key_equal& __eql, 138146035553Spatrick const allocator_type& __a) 138246035553Spatrick : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 138346035553Spatrick __p1_(__default_init_tag(), __node_allocator(__a)), 138446035553Spatrick __p2_(0, __hf), 138546035553Spatrick __p3_(1.0f, __eql) 138646035553Spatrick{ 138746035553Spatrick} 138846035553Spatrick 138946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 139046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) 139146035553Spatrick : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 139246035553Spatrick __p1_(__default_init_tag(), __node_allocator(__a)), 139346035553Spatrick __p2_(0, __default_init_tag()), 139446035553Spatrick __p3_(1.0f, __default_init_tag()) 139546035553Spatrick{ 139646035553Spatrick} 139746035553Spatrick 139846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 139946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) 140046035553Spatrick : __bucket_list_(nullptr, 140146035553Spatrick __bucket_list_deleter(allocator_traits<__pointer_allocator>:: 140246035553Spatrick select_on_container_copy_construction( 140346035553Spatrick __u.__bucket_list_.get_deleter().__alloc()), 0)), 140446035553Spatrick __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: 140546035553Spatrick select_on_container_copy_construction(__u.__node_alloc())), 140646035553Spatrick __p2_(0, __u.hash_function()), 140746035553Spatrick __p3_(__u.__p3_) 140846035553Spatrick{ 140946035553Spatrick} 141046035553Spatrick 141146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 141246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, 141346035553Spatrick const allocator_type& __a) 141446035553Spatrick : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 141546035553Spatrick __p1_(__default_init_tag(), __node_allocator(__a)), 141646035553Spatrick __p2_(0, __u.hash_function()), 141746035553Spatrick __p3_(__u.__p3_) 141846035553Spatrick{ 141946035553Spatrick} 142046035553Spatrick 142146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 142246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) 142346035553Spatrick _NOEXCEPT_( 142446035553Spatrick is_nothrow_move_constructible<__bucket_list>::value && 142546035553Spatrick is_nothrow_move_constructible<__first_node>::value && 142646035553Spatrick is_nothrow_move_constructible<__node_allocator>::value && 142746035553Spatrick is_nothrow_move_constructible<hasher>::value && 142846035553Spatrick is_nothrow_move_constructible<key_equal>::value) 142946035553Spatrick : __bucket_list_(_VSTD::move(__u.__bucket_list_)), 143046035553Spatrick __p1_(_VSTD::move(__u.__p1_)), 143146035553Spatrick __p2_(_VSTD::move(__u.__p2_)), 143246035553Spatrick __p3_(_VSTD::move(__u.__p3_)) 143346035553Spatrick{ 143446035553Spatrick if (size() > 0) 143546035553Spatrick { 1436*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 143746035553Spatrick __p1_.first().__ptr(); 143846035553Spatrick __u.__p1_.first().__next_ = nullptr; 143946035553Spatrick __u.size() = 0; 144046035553Spatrick } 144146035553Spatrick} 144246035553Spatrick 144346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 144446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, 144546035553Spatrick const allocator_type& __a) 144646035553Spatrick : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), 144746035553Spatrick __p1_(__default_init_tag(), __node_allocator(__a)), 144846035553Spatrick __p2_(0, _VSTD::move(__u.hash_function())), 144946035553Spatrick __p3_(_VSTD::move(__u.__p3_)) 145046035553Spatrick{ 145146035553Spatrick if (__a == allocator_type(__u.__node_alloc())) 145246035553Spatrick { 145346035553Spatrick __bucket_list_.reset(__u.__bucket_list_.release()); 145446035553Spatrick __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); 145546035553Spatrick __u.__bucket_list_.get_deleter().size() = 0; 145646035553Spatrick if (__u.size() > 0) 145746035553Spatrick { 145846035553Spatrick __p1_.first().__next_ = __u.__p1_.first().__next_; 145946035553Spatrick __u.__p1_.first().__next_ = nullptr; 1460*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 146146035553Spatrick __p1_.first().__ptr(); 146246035553Spatrick size() = __u.size(); 146346035553Spatrick __u.size() = 0; 146446035553Spatrick } 146546035553Spatrick } 146646035553Spatrick} 146746035553Spatrick 146846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 146946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() 147046035553Spatrick{ 147146035553Spatrick#if defined(_LIBCPP_CXX03_LANG) 147246035553Spatrick static_assert((is_copy_constructible<key_equal>::value), 147346035553Spatrick "Predicate must be copy-constructible."); 147446035553Spatrick static_assert((is_copy_constructible<hasher>::value), 147546035553Spatrick "Hasher must be copy-constructible."); 147646035553Spatrick#endif 147746035553Spatrick 147846035553Spatrick __deallocate_node(__p1_.first().__next_); 1479*4bdff4beSrobert std::__debug_db_erase_c(this); 148046035553Spatrick} 148146035553Spatrick 148246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 148346035553Spatrickvoid 148446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( 148546035553Spatrick const __hash_table& __u, true_type) 148646035553Spatrick{ 148746035553Spatrick if (__node_alloc() != __u.__node_alloc()) 148846035553Spatrick { 148946035553Spatrick clear(); 149046035553Spatrick __bucket_list_.reset(); 149146035553Spatrick __bucket_list_.get_deleter().size() = 0; 149246035553Spatrick } 149346035553Spatrick __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); 149446035553Spatrick __node_alloc() = __u.__node_alloc(); 149546035553Spatrick} 149646035553Spatrick 149746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 149846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>& 149946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) 150046035553Spatrick{ 1501*4bdff4beSrobert if (this != _VSTD::addressof(__u)) 150246035553Spatrick { 150346035553Spatrick __copy_assign_alloc(__u); 150446035553Spatrick hash_function() = __u.hash_function(); 150546035553Spatrick key_eq() = __u.key_eq(); 150646035553Spatrick max_load_factor() = __u.max_load_factor(); 150746035553Spatrick __assign_multi(__u.begin(), __u.end()); 150846035553Spatrick } 150946035553Spatrick return *this; 151046035553Spatrick} 151146035553Spatrick 151246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 151346035553Spatrickvoid 151446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) 151546035553Spatrick _NOEXCEPT 151646035553Spatrick{ 151746035553Spatrick __node_allocator& __na = __node_alloc(); 151846035553Spatrick while (__np != nullptr) 151946035553Spatrick { 152046035553Spatrick __next_pointer __next = __np->__next_; 1521*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 152246035553Spatrick __c_node* __c = __get_db()->__find_c_and_lock(this); 152346035553Spatrick for (__i_node** __p = __c->end_; __p != __c->beg_; ) 152446035553Spatrick { 152546035553Spatrick --__p; 152646035553Spatrick iterator* __i = static_cast<iterator*>((*__p)->__i_); 152746035553Spatrick if (__i->__node_ == __np) 152846035553Spatrick { 152946035553Spatrick (*__p)->__c_ = nullptr; 153046035553Spatrick if (--__c->end_ != __p) 153176d0caaeSpatrick _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 153246035553Spatrick } 153346035553Spatrick } 153446035553Spatrick __get_db()->unlock(); 153546035553Spatrick#endif 153646035553Spatrick __node_pointer __real_np = __np->__upcast(); 153746035553Spatrick __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); 153846035553Spatrick __node_traits::deallocate(__na, __real_np, 1); 153946035553Spatrick __np = __next; 154046035553Spatrick } 154146035553Spatrick} 154246035553Spatrick 154346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 154446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 154546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT 154646035553Spatrick{ 154746035553Spatrick size_type __bc = bucket_count(); 154846035553Spatrick for (size_type __i = 0; __i < __bc; ++__i) 154946035553Spatrick __bucket_list_[__i] = nullptr; 155046035553Spatrick size() = 0; 155146035553Spatrick __next_pointer __cache = __p1_.first().__next_; 155246035553Spatrick __p1_.first().__next_ = nullptr; 155346035553Spatrick return __cache; 155446035553Spatrick} 155546035553Spatrick 155646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 155746035553Spatrickvoid 155846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( 155946035553Spatrick __hash_table& __u, true_type) 156046035553Spatrick _NOEXCEPT_( 156146035553Spatrick is_nothrow_move_assignable<__node_allocator>::value && 156246035553Spatrick is_nothrow_move_assignable<hasher>::value && 156346035553Spatrick is_nothrow_move_assignable<key_equal>::value) 156446035553Spatrick{ 156546035553Spatrick clear(); 156646035553Spatrick __bucket_list_.reset(__u.__bucket_list_.release()); 156746035553Spatrick __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); 156846035553Spatrick __u.__bucket_list_.get_deleter().size() = 0; 156946035553Spatrick __move_assign_alloc(__u); 157046035553Spatrick size() = __u.size(); 157146035553Spatrick hash_function() = _VSTD::move(__u.hash_function()); 157246035553Spatrick max_load_factor() = __u.max_load_factor(); 157346035553Spatrick key_eq() = _VSTD::move(__u.key_eq()); 157446035553Spatrick __p1_.first().__next_ = __u.__p1_.first().__next_; 157546035553Spatrick if (size() > 0) 157646035553Spatrick { 1577*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 157846035553Spatrick __p1_.first().__ptr(); 157946035553Spatrick __u.__p1_.first().__next_ = nullptr; 158046035553Spatrick __u.size() = 0; 158146035553Spatrick } 1582*4bdff4beSrobert std::__debug_db_swap(this, std::addressof(__u)); 158346035553Spatrick} 158446035553Spatrick 158546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 158646035553Spatrickvoid 158746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( 158846035553Spatrick __hash_table& __u, false_type) 158946035553Spatrick{ 159046035553Spatrick if (__node_alloc() == __u.__node_alloc()) 159146035553Spatrick __move_assign(__u, true_type()); 159246035553Spatrick else 159346035553Spatrick { 159446035553Spatrick hash_function() = _VSTD::move(__u.hash_function()); 159546035553Spatrick key_eq() = _VSTD::move(__u.key_eq()); 159646035553Spatrick max_load_factor() = __u.max_load_factor(); 159746035553Spatrick if (bucket_count() != 0) 159846035553Spatrick { 159946035553Spatrick __next_pointer __cache = __detach(); 160046035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 160146035553Spatrick try 160246035553Spatrick { 160346035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS 160446035553Spatrick const_iterator __i = __u.begin(); 160546035553Spatrick while (__cache != nullptr && __u.size() != 0) 160646035553Spatrick { 160746035553Spatrick __cache->__upcast()->__value_ = 160846035553Spatrick _VSTD::move(__u.remove(__i++)->__value_); 160946035553Spatrick __next_pointer __next = __cache->__next_; 161046035553Spatrick __node_insert_multi(__cache->__upcast()); 161146035553Spatrick __cache = __next; 161246035553Spatrick } 161346035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 161446035553Spatrick } 161546035553Spatrick catch (...) 161646035553Spatrick { 161746035553Spatrick __deallocate_node(__cache); 161846035553Spatrick throw; 161946035553Spatrick } 162046035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS 162146035553Spatrick __deallocate_node(__cache); 162246035553Spatrick } 162346035553Spatrick const_iterator __i = __u.begin(); 162446035553Spatrick while (__u.size() != 0) 162546035553Spatrick { 162646035553Spatrick __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); 162746035553Spatrick __node_insert_multi(__h.get()); 162846035553Spatrick __h.release(); 162946035553Spatrick } 163046035553Spatrick } 163146035553Spatrick} 163246035553Spatrick 163346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 163446035553Spatrickinline 163546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>& 163646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) 163746035553Spatrick _NOEXCEPT_( 163846035553Spatrick __node_traits::propagate_on_container_move_assignment::value && 163946035553Spatrick is_nothrow_move_assignable<__node_allocator>::value && 164046035553Spatrick is_nothrow_move_assignable<hasher>::value && 164146035553Spatrick is_nothrow_move_assignable<key_equal>::value) 164246035553Spatrick{ 164346035553Spatrick __move_assign(__u, integral_constant<bool, 164446035553Spatrick __node_traits::propagate_on_container_move_assignment::value>()); 164546035553Spatrick return *this; 164646035553Spatrick} 164746035553Spatrick 164846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 164946035553Spatricktemplate <class _InputIterator> 165046035553Spatrickvoid 165146035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, 165246035553Spatrick _InputIterator __last) 165346035553Spatrick{ 165446035553Spatrick typedef iterator_traits<_InputIterator> _ITraits; 165546035553Spatrick typedef typename _ITraits::value_type _ItValueType; 165646035553Spatrick static_assert((is_same<_ItValueType, __container_value_type>::value), 165746035553Spatrick "__assign_unique may only be called with the containers value type"); 165846035553Spatrick 165946035553Spatrick if (bucket_count() != 0) 166046035553Spatrick { 166146035553Spatrick __next_pointer __cache = __detach(); 166246035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 166346035553Spatrick try 166446035553Spatrick { 166546035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS 166646035553Spatrick for (; __cache != nullptr && __first != __last; ++__first) 166746035553Spatrick { 166846035553Spatrick __cache->__upcast()->__value_ = *__first; 166946035553Spatrick __next_pointer __next = __cache->__next_; 167046035553Spatrick __node_insert_unique(__cache->__upcast()); 167146035553Spatrick __cache = __next; 167246035553Spatrick } 167346035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 167446035553Spatrick } 167546035553Spatrick catch (...) 167646035553Spatrick { 167746035553Spatrick __deallocate_node(__cache); 167846035553Spatrick throw; 167946035553Spatrick } 168046035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS 168146035553Spatrick __deallocate_node(__cache); 168246035553Spatrick } 168346035553Spatrick for (; __first != __last; ++__first) 168446035553Spatrick __insert_unique(*__first); 168546035553Spatrick} 168646035553Spatrick 168746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 168846035553Spatricktemplate <class _InputIterator> 168946035553Spatrickvoid 169046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, 169146035553Spatrick _InputIterator __last) 169246035553Spatrick{ 169346035553Spatrick typedef iterator_traits<_InputIterator> _ITraits; 169446035553Spatrick typedef typename _ITraits::value_type _ItValueType; 169546035553Spatrick static_assert((is_same<_ItValueType, __container_value_type>::value || 169646035553Spatrick is_same<_ItValueType, __node_value_type>::value), 169746035553Spatrick "__assign_multi may only be called with the containers value type" 169846035553Spatrick " or the nodes value type"); 169946035553Spatrick if (bucket_count() != 0) 170046035553Spatrick { 170146035553Spatrick __next_pointer __cache = __detach(); 170246035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 170346035553Spatrick try 170446035553Spatrick { 170546035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS 170646035553Spatrick for (; __cache != nullptr && __first != __last; ++__first) 170746035553Spatrick { 170846035553Spatrick __cache->__upcast()->__value_ = *__first; 170946035553Spatrick __next_pointer __next = __cache->__next_; 171046035553Spatrick __node_insert_multi(__cache->__upcast()); 171146035553Spatrick __cache = __next; 171246035553Spatrick } 171346035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 171446035553Spatrick } 171546035553Spatrick catch (...) 171646035553Spatrick { 171746035553Spatrick __deallocate_node(__cache); 171846035553Spatrick throw; 171946035553Spatrick } 172046035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS 172146035553Spatrick __deallocate_node(__cache); 172246035553Spatrick } 172346035553Spatrick for (; __first != __last; ++__first) 172446035553Spatrick __insert_multi(_NodeTypes::__get_value(*__first)); 172546035553Spatrick} 172646035553Spatrick 172746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 172846035553Spatrickinline 172946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 173046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT 173146035553Spatrick{ 173246035553Spatrick return iterator(__p1_.first().__next_, this); 173346035553Spatrick} 173446035553Spatrick 173546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 173646035553Spatrickinline 173746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 173846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT 173946035553Spatrick{ 174046035553Spatrick return iterator(nullptr, this); 174146035553Spatrick} 174246035553Spatrick 174346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 174446035553Spatrickinline 174546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 174646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT 174746035553Spatrick{ 174846035553Spatrick return const_iterator(__p1_.first().__next_, this); 174946035553Spatrick} 175046035553Spatrick 175146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 175246035553Spatrickinline 175346035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 175446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT 175546035553Spatrick{ 175646035553Spatrick return const_iterator(nullptr, this); 175746035553Spatrick} 175846035553Spatrick 175946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 176046035553Spatrickvoid 176146035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT 176246035553Spatrick{ 176346035553Spatrick if (size() > 0) 176446035553Spatrick { 176546035553Spatrick __deallocate_node(__p1_.first().__next_); 176646035553Spatrick __p1_.first().__next_ = nullptr; 176746035553Spatrick size_type __bc = bucket_count(); 176846035553Spatrick for (size_type __i = 0; __i < __bc; ++__i) 176946035553Spatrick __bucket_list_[__i] = nullptr; 177046035553Spatrick size() = 0; 177146035553Spatrick } 177246035553Spatrick} 177346035553Spatrick 177446035553Spatrick 177546035553Spatrick// Prepare the container for an insertion of the value __value with the hash 177646035553Spatrick// __hash. This does a lookup into the container to see if __value is already 177746035553Spatrick// present, and performs a rehash if necessary. Returns a pointer to the 177846035553Spatrick// existing element if it exists, otherwise nullptr. 177946035553Spatrick// 178046035553Spatrick// Note that this function does forward exceptions if key_eq() throws, and never 178146035553Spatrick// mutates __value or actually inserts into the map. 178246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 178346035553Spatrick_LIBCPP_INLINE_VISIBILITY 178446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 178546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( 178646035553Spatrick size_t __hash, value_type& __value) 178746035553Spatrick{ 178846035553Spatrick size_type __bc = bucket_count(); 178946035553Spatrick 179046035553Spatrick if (__bc != 0) 179146035553Spatrick { 1792*4bdff4beSrobert size_t __chash = std::__constrain_hash(__hash, __bc); 179346035553Spatrick __next_pointer __ndptr = __bucket_list_[__chash]; 179446035553Spatrick if (__ndptr != nullptr) 179546035553Spatrick { 179646035553Spatrick for (__ndptr = __ndptr->__next_; __ndptr != nullptr && 1797*4bdff4beSrobert std::__constrain_hash(__ndptr->__hash(), __bc) == __chash; 179846035553Spatrick __ndptr = __ndptr->__next_) 179946035553Spatrick { 180046035553Spatrick if (key_eq()(__ndptr->__upcast()->__value_, __value)) 180146035553Spatrick return __ndptr; 180246035553Spatrick } 180346035553Spatrick } 180446035553Spatrick } 180546035553Spatrick if (size()+1 > __bc * max_load_factor() || __bc == 0) 180646035553Spatrick { 1807*4bdff4beSrobert __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc), 1808*4bdff4beSrobert size_type(std::ceil(float(size() + 1) / max_load_factor())))); 180946035553Spatrick } 181046035553Spatrick return nullptr; 181146035553Spatrick} 181246035553Spatrick 181346035553Spatrick// Insert the node __nd into the container by pushing it into the right bucket, 181446035553Spatrick// and updating size(). Assumes that __nd->__hash is up-to-date, and that 181546035553Spatrick// rehashing has already occurred and that no element with the same key exists 181646035553Spatrick// in the map. 181746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 181846035553Spatrick_LIBCPP_INLINE_VISIBILITY 181946035553Spatrickvoid 182046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( 182146035553Spatrick __node_pointer __nd) _NOEXCEPT 182246035553Spatrick{ 182346035553Spatrick size_type __bc = bucket_count(); 1824*4bdff4beSrobert size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); 182546035553Spatrick // insert_after __bucket_list_[__chash], or __first_node if bucket is null 182646035553Spatrick __next_pointer __pn = __bucket_list_[__chash]; 182746035553Spatrick if (__pn == nullptr) 182846035553Spatrick { 182946035553Spatrick __pn =__p1_.first().__ptr(); 183046035553Spatrick __nd->__next_ = __pn->__next_; 183146035553Spatrick __pn->__next_ = __nd->__ptr(); 183246035553Spatrick // fix up __bucket_list_ 183346035553Spatrick __bucket_list_[__chash] = __pn; 183446035553Spatrick if (__nd->__next_ != nullptr) 1835*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); 183646035553Spatrick } 183746035553Spatrick else 183846035553Spatrick { 183946035553Spatrick __nd->__next_ = __pn->__next_; 184046035553Spatrick __pn->__next_ = __nd->__ptr(); 184146035553Spatrick } 184246035553Spatrick ++size(); 184346035553Spatrick} 184446035553Spatrick 184546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 184646035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 184746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) 184846035553Spatrick{ 184946035553Spatrick __nd->__hash_ = hash_function()(__nd->__value_); 185046035553Spatrick __next_pointer __existing_node = 185146035553Spatrick __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); 185246035553Spatrick 185346035553Spatrick // Insert the node, unless it already exists in the container. 185446035553Spatrick bool __inserted = false; 185546035553Spatrick if (__existing_node == nullptr) 185646035553Spatrick { 185746035553Spatrick __node_insert_unique_perform(__nd); 185846035553Spatrick __existing_node = __nd->__ptr(); 185946035553Spatrick __inserted = true; 186046035553Spatrick } 186146035553Spatrick return pair<iterator, bool>(iterator(__existing_node, this), __inserted); 186246035553Spatrick} 186346035553Spatrick 186446035553Spatrick// Prepare the container for an insertion of the value __cp_val with the hash 186546035553Spatrick// __cp_hash. This does a lookup into the container to see if __cp_value is 186646035553Spatrick// already present, and performs a rehash if necessary. Returns a pointer to the 186776d0caaeSpatrick// last occurrence of __cp_val in the map. 186846035553Spatrick// 186946035553Spatrick// Note that this function does forward exceptions if key_eq() throws, and never 187046035553Spatrick// mutates __value or actually inserts into the map. 187146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 187246035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer 187346035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( 187446035553Spatrick size_t __cp_hash, value_type& __cp_val) 187546035553Spatrick{ 187646035553Spatrick size_type __bc = bucket_count(); 187746035553Spatrick if (size()+1 > __bc * max_load_factor() || __bc == 0) 187846035553Spatrick { 1879*4bdff4beSrobert __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc), 1880*4bdff4beSrobert size_type(std::ceil(float(size() + 1) / max_load_factor())))); 188146035553Spatrick __bc = bucket_count(); 188246035553Spatrick } 1883*4bdff4beSrobert size_t __chash = std::__constrain_hash(__cp_hash, __bc); 188446035553Spatrick __next_pointer __pn = __bucket_list_[__chash]; 188546035553Spatrick if (__pn != nullptr) 188646035553Spatrick { 188746035553Spatrick for (bool __found = false; __pn->__next_ != nullptr && 1888*4bdff4beSrobert std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; 188946035553Spatrick __pn = __pn->__next_) 189046035553Spatrick { 189146035553Spatrick // __found key_eq() action 189246035553Spatrick // false false loop 189346035553Spatrick // true true loop 189446035553Spatrick // false true set __found to true 189546035553Spatrick // true false break 189646035553Spatrick if (__found != (__pn->__next_->__hash() == __cp_hash && 189746035553Spatrick key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) 189846035553Spatrick { 189946035553Spatrick if (!__found) 190046035553Spatrick __found = true; 190146035553Spatrick else 190246035553Spatrick break; 190346035553Spatrick } 190446035553Spatrick } 190546035553Spatrick } 190646035553Spatrick return __pn; 190746035553Spatrick} 190846035553Spatrick 190946035553Spatrick// Insert the node __cp into the container after __pn (which is the last node in 191046035553Spatrick// the bucket that compares equal to __cp). Rehashing, and checking for 191146035553Spatrick// uniqueness has already been performed (in __node_insert_multi_prepare), so 191246035553Spatrick// all we need to do is update the bucket and size(). Assumes that __cp->__hash 191346035553Spatrick// is up-to-date. 191446035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 191546035553Spatrickvoid 191646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( 191746035553Spatrick __node_pointer __cp, __next_pointer __pn) _NOEXCEPT 191846035553Spatrick{ 191946035553Spatrick size_type __bc = bucket_count(); 1920*4bdff4beSrobert size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); 192146035553Spatrick if (__pn == nullptr) 192246035553Spatrick { 192346035553Spatrick __pn =__p1_.first().__ptr(); 192446035553Spatrick __cp->__next_ = __pn->__next_; 192546035553Spatrick __pn->__next_ = __cp->__ptr(); 192646035553Spatrick // fix up __bucket_list_ 192746035553Spatrick __bucket_list_[__chash] = __pn; 192846035553Spatrick if (__cp->__next_ != nullptr) 1929*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] 193046035553Spatrick = __cp->__ptr(); 193146035553Spatrick } 193246035553Spatrick else 193346035553Spatrick { 193446035553Spatrick __cp->__next_ = __pn->__next_; 193546035553Spatrick __pn->__next_ = __cp->__ptr(); 193646035553Spatrick if (__cp->__next_ != nullptr) 193746035553Spatrick { 1938*4bdff4beSrobert size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); 193946035553Spatrick if (__nhash != __chash) 194046035553Spatrick __bucket_list_[__nhash] = __cp->__ptr(); 194146035553Spatrick } 194246035553Spatrick } 194346035553Spatrick ++size(); 194446035553Spatrick} 194546035553Spatrick 194646035553Spatrick 194746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 194846035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 194946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) 195046035553Spatrick{ 195146035553Spatrick __cp->__hash_ = hash_function()(__cp->__value_); 195246035553Spatrick __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); 195346035553Spatrick __node_insert_multi_perform(__cp, __pn); 195446035553Spatrick 195546035553Spatrick return iterator(__cp->__ptr(), this); 195646035553Spatrick} 195746035553Spatrick 195846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 195946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 196046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( 196146035553Spatrick const_iterator __p, __node_pointer __cp) 196246035553Spatrick{ 1963*4bdff4beSrobert _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 196446035553Spatrick "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" 196546035553Spatrick " referring to this unordered container"); 196646035553Spatrick if (__p != end() && key_eq()(*__p, __cp->__value_)) 196746035553Spatrick { 196846035553Spatrick __next_pointer __np = __p.__node_; 196946035553Spatrick __cp->__hash_ = __np->__hash(); 197046035553Spatrick size_type __bc = bucket_count(); 197146035553Spatrick if (size()+1 > __bc * max_load_factor() || __bc == 0) 197246035553Spatrick { 1973*4bdff4beSrobert __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc), 1974*4bdff4beSrobert size_type(std::ceil(float(size() + 1) / max_load_factor())))); 197546035553Spatrick __bc = bucket_count(); 197646035553Spatrick } 1977*4bdff4beSrobert size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); 197846035553Spatrick __next_pointer __pp = __bucket_list_[__chash]; 197946035553Spatrick while (__pp->__next_ != __np) 198046035553Spatrick __pp = __pp->__next_; 198146035553Spatrick __cp->__next_ = __np; 198246035553Spatrick __pp->__next_ = static_cast<__next_pointer>(__cp); 198346035553Spatrick ++size(); 198446035553Spatrick return iterator(static_cast<__next_pointer>(__cp), this); 198546035553Spatrick } 198646035553Spatrick return __node_insert_multi(__cp); 198746035553Spatrick} 198846035553Spatrick 198946035553Spatrick 199046035553Spatrick 199146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 199246035553Spatricktemplate <class _Key, class ..._Args> 199346035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 199446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) 199546035553Spatrick{ 199646035553Spatrick 199746035553Spatrick size_t __hash = hash_function()(__k); 199846035553Spatrick size_type __bc = bucket_count(); 199946035553Spatrick bool __inserted = false; 200046035553Spatrick __next_pointer __nd; 200146035553Spatrick size_t __chash; 200246035553Spatrick if (__bc != 0) 200346035553Spatrick { 2004*4bdff4beSrobert __chash = std::__constrain_hash(__hash, __bc); 200546035553Spatrick __nd = __bucket_list_[__chash]; 200646035553Spatrick if (__nd != nullptr) 200746035553Spatrick { 200846035553Spatrick for (__nd = __nd->__next_; __nd != nullptr && 2009*4bdff4beSrobert (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); 201046035553Spatrick __nd = __nd->__next_) 201146035553Spatrick { 201246035553Spatrick if (key_eq()(__nd->__upcast()->__value_, __k)) 201346035553Spatrick goto __done; 201446035553Spatrick } 201546035553Spatrick } 201646035553Spatrick } 201746035553Spatrick { 201846035553Spatrick __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); 201946035553Spatrick if (size()+1 > __bc * max_load_factor() || __bc == 0) 202046035553Spatrick { 2021*4bdff4beSrobert __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc), 2022*4bdff4beSrobert size_type(std::ceil(float(size() + 1) / max_load_factor())))); 202346035553Spatrick __bc = bucket_count(); 2024*4bdff4beSrobert __chash = std::__constrain_hash(__hash, __bc); 202546035553Spatrick } 202646035553Spatrick // insert_after __bucket_list_[__chash], or __first_node if bucket is null 202746035553Spatrick __next_pointer __pn = __bucket_list_[__chash]; 202846035553Spatrick if (__pn == nullptr) 202946035553Spatrick { 203046035553Spatrick __pn = __p1_.first().__ptr(); 203146035553Spatrick __h->__next_ = __pn->__next_; 203246035553Spatrick __pn->__next_ = __h.get()->__ptr(); 203346035553Spatrick // fix up __bucket_list_ 203446035553Spatrick __bucket_list_[__chash] = __pn; 203546035553Spatrick if (__h->__next_ != nullptr) 2036*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] 203746035553Spatrick = __h.get()->__ptr(); 203846035553Spatrick } 203946035553Spatrick else 204046035553Spatrick { 204146035553Spatrick __h->__next_ = __pn->__next_; 204246035553Spatrick __pn->__next_ = static_cast<__next_pointer>(__h.get()); 204346035553Spatrick } 204446035553Spatrick __nd = static_cast<__next_pointer>(__h.release()); 204546035553Spatrick // increment size 204646035553Spatrick ++size(); 204746035553Spatrick __inserted = true; 204846035553Spatrick } 204946035553Spatrick__done: 205046035553Spatrick return pair<iterator, bool>(iterator(__nd, this), __inserted); 205146035553Spatrick} 205246035553Spatrick 205346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 205446035553Spatricktemplate <class... _Args> 205546035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> 205646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) 205746035553Spatrick{ 205846035553Spatrick __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 205946035553Spatrick pair<iterator, bool> __r = __node_insert_unique(__h.get()); 206046035553Spatrick if (__r.second) 206146035553Spatrick __h.release(); 206246035553Spatrick return __r; 206346035553Spatrick} 206446035553Spatrick 206546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 206646035553Spatricktemplate <class... _Args> 206746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 206846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) 206946035553Spatrick{ 207046035553Spatrick __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 207146035553Spatrick iterator __r = __node_insert_multi(__h.get()); 207246035553Spatrick __h.release(); 207346035553Spatrick return __r; 207446035553Spatrick} 207546035553Spatrick 207646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 207746035553Spatricktemplate <class... _Args> 207846035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 207946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( 208046035553Spatrick const_iterator __p, _Args&&... __args) 208146035553Spatrick{ 2082*4bdff4beSrobert _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 208346035553Spatrick "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" 208446035553Spatrick " referring to this unordered container"); 208546035553Spatrick __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); 208646035553Spatrick iterator __r = __node_insert_multi(__p, __h.get()); 208746035553Spatrick __h.release(); 208846035553Spatrick return __r; 208946035553Spatrick} 209046035553Spatrick 209146035553Spatrick#if _LIBCPP_STD_VER > 14 209246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 209346035553Spatricktemplate <class _NodeHandle, class _InsertReturnType> 209446035553Spatrick_LIBCPP_INLINE_VISIBILITY 209546035553Spatrick_InsertReturnType 209646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( 209746035553Spatrick _NodeHandle&& __nh) 209846035553Spatrick{ 209946035553Spatrick if (__nh.empty()) 210046035553Spatrick return _InsertReturnType{end(), false, _NodeHandle()}; 210146035553Spatrick pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); 210246035553Spatrick if (__result.second) 210346035553Spatrick __nh.__release_ptr(); 210446035553Spatrick return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; 210546035553Spatrick} 210646035553Spatrick 210746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 210846035553Spatricktemplate <class _NodeHandle> 210946035553Spatrick_LIBCPP_INLINE_VISIBILITY 211046035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 211146035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( 211246035553Spatrick const_iterator, _NodeHandle&& __nh) 211346035553Spatrick{ 211446035553Spatrick if (__nh.empty()) 211546035553Spatrick return end(); 211646035553Spatrick pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_); 211746035553Spatrick if (__result.second) 211846035553Spatrick __nh.__release_ptr(); 211946035553Spatrick return __result.first; 212046035553Spatrick} 212146035553Spatrick 212246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 212346035553Spatricktemplate <class _NodeHandle> 212446035553Spatrick_LIBCPP_INLINE_VISIBILITY 212546035553Spatrick_NodeHandle 212646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( 212746035553Spatrick key_type const& __key) 212846035553Spatrick{ 212946035553Spatrick iterator __i = find(__key); 213046035553Spatrick if (__i == end()) 213146035553Spatrick return _NodeHandle(); 213246035553Spatrick return __node_handle_extract<_NodeHandle>(__i); 213346035553Spatrick} 213446035553Spatrick 213546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 213646035553Spatricktemplate <class _NodeHandle> 213746035553Spatrick_LIBCPP_INLINE_VISIBILITY 213846035553Spatrick_NodeHandle 213946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( 214046035553Spatrick const_iterator __p) 214146035553Spatrick{ 214246035553Spatrick allocator_type __alloc(__node_alloc()); 214346035553Spatrick return _NodeHandle(remove(__p).release(), __alloc); 214446035553Spatrick} 214546035553Spatrick 214646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 214746035553Spatricktemplate <class _Table> 214846035553Spatrick_LIBCPP_INLINE_VISIBILITY 214946035553Spatrickvoid 215046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( 215146035553Spatrick _Table& __source) 215246035553Spatrick{ 215346035553Spatrick static_assert(is_same<__node, typename _Table::__node>::value, ""); 215446035553Spatrick 215546035553Spatrick for (typename _Table::iterator __it = __source.begin(); 215646035553Spatrick __it != __source.end();) 215746035553Spatrick { 215846035553Spatrick __node_pointer __src_ptr = __it.__node_->__upcast(); 215946035553Spatrick size_t __hash = hash_function()(__src_ptr->__value_); 216046035553Spatrick __next_pointer __existing_node = 216146035553Spatrick __node_insert_unique_prepare(__hash, __src_ptr->__value_); 216246035553Spatrick auto __prev_iter = __it++; 216346035553Spatrick if (__existing_node == nullptr) 216446035553Spatrick { 216546035553Spatrick (void)__source.remove(__prev_iter).release(); 216646035553Spatrick __src_ptr->__hash_ = __hash; 216746035553Spatrick __node_insert_unique_perform(__src_ptr); 216846035553Spatrick } 216946035553Spatrick } 217046035553Spatrick} 217146035553Spatrick 217246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 217346035553Spatricktemplate <class _NodeHandle> 217446035553Spatrick_LIBCPP_INLINE_VISIBILITY 217546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 217646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( 217746035553Spatrick _NodeHandle&& __nh) 217846035553Spatrick{ 217946035553Spatrick if (__nh.empty()) 218046035553Spatrick return end(); 218146035553Spatrick iterator __result = __node_insert_multi(__nh.__ptr_); 218246035553Spatrick __nh.__release_ptr(); 218346035553Spatrick return __result; 218446035553Spatrick} 218546035553Spatrick 218646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 218746035553Spatricktemplate <class _NodeHandle> 218846035553Spatrick_LIBCPP_INLINE_VISIBILITY 218946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 219046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( 219146035553Spatrick const_iterator __hint, _NodeHandle&& __nh) 219246035553Spatrick{ 219346035553Spatrick if (__nh.empty()) 219446035553Spatrick return end(); 219546035553Spatrick iterator __result = __node_insert_multi(__hint, __nh.__ptr_); 219646035553Spatrick __nh.__release_ptr(); 219746035553Spatrick return __result; 219846035553Spatrick} 219946035553Spatrick 220046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 220146035553Spatricktemplate <class _Table> 220246035553Spatrick_LIBCPP_INLINE_VISIBILITY 220346035553Spatrickvoid 220446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( 220546035553Spatrick _Table& __source) 220646035553Spatrick{ 220746035553Spatrick static_assert(is_same<typename _Table::__node, __node>::value, ""); 220846035553Spatrick 220946035553Spatrick for (typename _Table::iterator __it = __source.begin(); 221046035553Spatrick __it != __source.end();) 221146035553Spatrick { 221246035553Spatrick __node_pointer __src_ptr = __it.__node_->__upcast(); 221346035553Spatrick size_t __src_hash = hash_function()(__src_ptr->__value_); 221446035553Spatrick __next_pointer __pn = 221546035553Spatrick __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); 221646035553Spatrick (void)__source.remove(__it++).release(); 221746035553Spatrick __src_ptr->__hash_ = __src_hash; 221846035553Spatrick __node_insert_multi_perform(__src_ptr, __pn); 221946035553Spatrick } 222046035553Spatrick} 222146035553Spatrick#endif // _LIBCPP_STD_VER > 14 222246035553Spatrick 222346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2224*4bdff4beSroberttemplate <bool _UniqueKeys> 222546035553Spatrickvoid 2226*4bdff4beSrobert__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) 222746035553Spatrick_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK 222846035553Spatrick{ 222946035553Spatrick if (__n == 1) 223046035553Spatrick __n = 2; 223146035553Spatrick else if (__n & (__n - 1)) 2232*4bdff4beSrobert __n = std::__next_prime(__n); 223346035553Spatrick size_type __bc = bucket_count(); 223446035553Spatrick if (__n > __bc) 2235*4bdff4beSrobert __do_rehash<_UniqueKeys>(__n); 223646035553Spatrick else if (__n < __bc) 223746035553Spatrick { 223846035553Spatrick __n = _VSTD::max<size_type> 223946035553Spatrick ( 224046035553Spatrick __n, 2241*4bdff4beSrobert std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) : 2242*4bdff4beSrobert std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor()))) 224346035553Spatrick ); 224446035553Spatrick if (__n < __bc) 2245*4bdff4beSrobert __do_rehash<_UniqueKeys>(__n); 224646035553Spatrick } 224746035553Spatrick} 224846035553Spatrick 224946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 2250*4bdff4beSroberttemplate <bool _UniqueKeys> 225146035553Spatrickvoid 2252*4bdff4beSrobert__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) 225346035553Spatrick{ 2254*4bdff4beSrobert std::__debug_db_invalidate_all(this); 225546035553Spatrick __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); 225646035553Spatrick __bucket_list_.reset(__nbc > 0 ? 225746035553Spatrick __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); 225846035553Spatrick __bucket_list_.get_deleter().size() = __nbc; 225946035553Spatrick if (__nbc > 0) 226046035553Spatrick { 226146035553Spatrick for (size_type __i = 0; __i < __nbc; ++__i) 226246035553Spatrick __bucket_list_[__i] = nullptr; 226346035553Spatrick __next_pointer __pp = __p1_.first().__ptr(); 226446035553Spatrick __next_pointer __cp = __pp->__next_; 226546035553Spatrick if (__cp != nullptr) 226646035553Spatrick { 2267*4bdff4beSrobert size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); 226846035553Spatrick __bucket_list_[__chash] = __pp; 226946035553Spatrick size_type __phash = __chash; 2270*4bdff4beSrobert for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; 227146035553Spatrick __cp = __pp->__next_) 227246035553Spatrick { 2273*4bdff4beSrobert __chash = std::__constrain_hash(__cp->__hash(), __nbc); 227446035553Spatrick if (__chash == __phash) 227546035553Spatrick __pp = __cp; 227646035553Spatrick else 227746035553Spatrick { 227846035553Spatrick if (__bucket_list_[__chash] == nullptr) 227946035553Spatrick { 228046035553Spatrick __bucket_list_[__chash] = __pp; 228146035553Spatrick __pp = __cp; 228246035553Spatrick __phash = __chash; 228346035553Spatrick } 228446035553Spatrick else 228546035553Spatrick { 228646035553Spatrick __next_pointer __np = __cp; 2287*4bdff4beSrobert if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) 2288*4bdff4beSrobert { 228946035553Spatrick for (; __np->__next_ != nullptr && 229046035553Spatrick key_eq()(__cp->__upcast()->__value_, 229146035553Spatrick __np->__next_->__upcast()->__value_); 229246035553Spatrick __np = __np->__next_) 229346035553Spatrick ; 2294*4bdff4beSrobert } 229546035553Spatrick __pp->__next_ = __np->__next_; 229646035553Spatrick __np->__next_ = __bucket_list_[__chash]->__next_; 229746035553Spatrick __bucket_list_[__chash]->__next_ = __cp; 229846035553Spatrick 229946035553Spatrick } 230046035553Spatrick } 230146035553Spatrick } 230246035553Spatrick } 230346035553Spatrick } 230446035553Spatrick} 230546035553Spatrick 230646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 230746035553Spatricktemplate <class _Key> 230846035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 230946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) 231046035553Spatrick{ 231146035553Spatrick size_t __hash = hash_function()(__k); 231246035553Spatrick size_type __bc = bucket_count(); 231346035553Spatrick if (__bc != 0) 231446035553Spatrick { 2315*4bdff4beSrobert size_t __chash = std::__constrain_hash(__hash, __bc); 231646035553Spatrick __next_pointer __nd = __bucket_list_[__chash]; 231746035553Spatrick if (__nd != nullptr) 231846035553Spatrick { 231946035553Spatrick for (__nd = __nd->__next_; __nd != nullptr && 232046035553Spatrick (__nd->__hash() == __hash 2321*4bdff4beSrobert || std::__constrain_hash(__nd->__hash(), __bc) == __chash); 232246035553Spatrick __nd = __nd->__next_) 232346035553Spatrick { 232446035553Spatrick if ((__nd->__hash() == __hash) 232546035553Spatrick && key_eq()(__nd->__upcast()->__value_, __k)) 232646035553Spatrick return iterator(__nd, this); 232746035553Spatrick } 232846035553Spatrick } 232946035553Spatrick } 233046035553Spatrick return end(); 233146035553Spatrick} 233246035553Spatrick 233346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 233446035553Spatricktemplate <class _Key> 233546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator 233646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const 233746035553Spatrick{ 233846035553Spatrick size_t __hash = hash_function()(__k); 233946035553Spatrick size_type __bc = bucket_count(); 234046035553Spatrick if (__bc != 0) 234146035553Spatrick { 2342*4bdff4beSrobert size_t __chash = std::__constrain_hash(__hash, __bc); 234346035553Spatrick __next_pointer __nd = __bucket_list_[__chash]; 234446035553Spatrick if (__nd != nullptr) 234546035553Spatrick { 234646035553Spatrick for (__nd = __nd->__next_; __nd != nullptr && 234746035553Spatrick (__hash == __nd->__hash() 2348*4bdff4beSrobert || std::__constrain_hash(__nd->__hash(), __bc) == __chash); 234946035553Spatrick __nd = __nd->__next_) 235046035553Spatrick { 235146035553Spatrick if ((__nd->__hash() == __hash) 235246035553Spatrick && key_eq()(__nd->__upcast()->__value_, __k)) 235346035553Spatrick return const_iterator(__nd, this); 235446035553Spatrick } 235546035553Spatrick } 235646035553Spatrick 235746035553Spatrick } 235846035553Spatrick return end(); 235946035553Spatrick} 236046035553Spatrick 236146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 236246035553Spatricktemplate <class ..._Args> 236346035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 236446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) 236546035553Spatrick{ 236646035553Spatrick static_assert(!__is_hash_value_type<_Args...>::value, 236746035553Spatrick "Construct cannot be called with a hash value type"); 236846035553Spatrick __node_allocator& __na = __node_alloc(); 236946035553Spatrick __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 237046035553Spatrick __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); 237146035553Spatrick __h.get_deleter().__value_constructed = true; 237246035553Spatrick __h->__hash_ = hash_function()(__h->__value_); 237346035553Spatrick __h->__next_ = nullptr; 237446035553Spatrick return __h; 237546035553Spatrick} 237646035553Spatrick 237746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 237846035553Spatricktemplate <class _First, class ..._Rest> 237946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 238046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( 238146035553Spatrick size_t __hash, _First&& __f, _Rest&& ...__rest) 238246035553Spatrick{ 238346035553Spatrick static_assert(!__is_hash_value_type<_First, _Rest...>::value, 238446035553Spatrick "Construct cannot be called with a hash value type"); 238546035553Spatrick __node_allocator& __na = __node_alloc(); 238646035553Spatrick __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 238746035553Spatrick __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), 238846035553Spatrick _VSTD::forward<_First>(__f), 238946035553Spatrick _VSTD::forward<_Rest>(__rest)...); 239046035553Spatrick __h.get_deleter().__value_constructed = true; 239146035553Spatrick __h->__hash_ = __hash; 239246035553Spatrick __h->__next_ = nullptr; 239346035553Spatrick return __h; 239446035553Spatrick} 239546035553Spatrick 239646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 239746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 239846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) 239946035553Spatrick{ 240046035553Spatrick __next_pointer __np = __p.__node_; 2401*4bdff4beSrobert _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 240246035553Spatrick "unordered container erase(iterator) called with an iterator not" 240346035553Spatrick " referring to this container"); 240446035553Spatrick _LIBCPP_ASSERT(__p != end(), 240546035553Spatrick "unordered container erase(iterator) called with a non-dereferenceable iterator"); 240646035553Spatrick iterator __r(__np, this); 240746035553Spatrick ++__r; 240846035553Spatrick remove(__p); 240946035553Spatrick return __r; 241046035553Spatrick} 241146035553Spatrick 241246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 241346035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator 241446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, 241546035553Spatrick const_iterator __last) 241646035553Spatrick{ 2417*4bdff4beSrobert _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, 241876d0caaeSpatrick "unordered container::erase(iterator, iterator) called with an iterator not" 241976d0caaeSpatrick " referring to this container"); 2420*4bdff4beSrobert _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, 242176d0caaeSpatrick "unordered container::erase(iterator, iterator) called with an iterator not" 242276d0caaeSpatrick " referring to this container"); 242346035553Spatrick for (const_iterator __p = __first; __first != __last; __p = __first) 242446035553Spatrick { 242546035553Spatrick ++__first; 242646035553Spatrick erase(__p); 242746035553Spatrick } 242846035553Spatrick __next_pointer __np = __last.__node_; 242946035553Spatrick return iterator (__np, this); 243046035553Spatrick} 243146035553Spatrick 243246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 243346035553Spatricktemplate <class _Key> 243446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 243546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) 243646035553Spatrick{ 243746035553Spatrick iterator __i = find(__k); 243846035553Spatrick if (__i == end()) 243946035553Spatrick return 0; 244046035553Spatrick erase(__i); 244146035553Spatrick return 1; 244246035553Spatrick} 244346035553Spatrick 244446035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 244546035553Spatricktemplate <class _Key> 244646035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 244746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) 244846035553Spatrick{ 244946035553Spatrick size_type __r = 0; 245046035553Spatrick iterator __i = find(__k); 245146035553Spatrick if (__i != end()) 245246035553Spatrick { 245346035553Spatrick iterator __e = end(); 245446035553Spatrick do 245546035553Spatrick { 245646035553Spatrick erase(__i++); 245746035553Spatrick ++__r; 245846035553Spatrick } while (__i != __e && key_eq()(*__i, __k)); 245946035553Spatrick } 246046035553Spatrick return __r; 246146035553Spatrick} 246246035553Spatrick 246346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 246446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder 246546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT 246646035553Spatrick{ 246746035553Spatrick // current node 246846035553Spatrick __next_pointer __cn = __p.__node_; 246946035553Spatrick size_type __bc = bucket_count(); 2470*4bdff4beSrobert size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); 247146035553Spatrick // find previous node 247246035553Spatrick __next_pointer __pn = __bucket_list_[__chash]; 247346035553Spatrick for (; __pn->__next_ != __cn; __pn = __pn->__next_) 247446035553Spatrick ; 247546035553Spatrick // Fix up __bucket_list_ 247646035553Spatrick // if __pn is not in same bucket (before begin is not in same bucket) && 247746035553Spatrick // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) 247846035553Spatrick if (__pn == __p1_.first().__ptr() 2479*4bdff4beSrobert || std::__constrain_hash(__pn->__hash(), __bc) != __chash) 248046035553Spatrick { 248146035553Spatrick if (__cn->__next_ == nullptr 2482*4bdff4beSrobert || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) 248346035553Spatrick __bucket_list_[__chash] = nullptr; 248446035553Spatrick } 248546035553Spatrick // if __cn->__next_ is not in same bucket (nullptr is in same bucket) 248646035553Spatrick if (__cn->__next_ != nullptr) 248746035553Spatrick { 2488*4bdff4beSrobert size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); 248946035553Spatrick if (__nhash != __chash) 249046035553Spatrick __bucket_list_[__nhash] = __pn; 249146035553Spatrick } 249246035553Spatrick // remove __cn 249346035553Spatrick __pn->__next_ = __cn->__next_; 249446035553Spatrick __cn->__next_ = nullptr; 249546035553Spatrick --size(); 2496*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 249746035553Spatrick __c_node* __c = __get_db()->__find_c_and_lock(this); 249846035553Spatrick for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) 249946035553Spatrick { 250046035553Spatrick --__dp; 250146035553Spatrick iterator* __i = static_cast<iterator*>((*__dp)->__i_); 250246035553Spatrick if (__i->__node_ == __cn) 250346035553Spatrick { 250446035553Spatrick (*__dp)->__c_ = nullptr; 250546035553Spatrick if (--__c->end_ != __dp) 250676d0caaeSpatrick _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); 250746035553Spatrick } 250846035553Spatrick } 250946035553Spatrick __get_db()->unlock(); 251046035553Spatrick#endif 251146035553Spatrick return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); 251246035553Spatrick} 251346035553Spatrick 251446035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 251546035553Spatricktemplate <class _Key> 251646035553Spatrickinline 251746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 251846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const 251946035553Spatrick{ 252046035553Spatrick return static_cast<size_type>(find(__k) != end()); 252146035553Spatrick} 252246035553Spatrick 252346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 252446035553Spatricktemplate <class _Key> 252546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 252646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const 252746035553Spatrick{ 252846035553Spatrick size_type __r = 0; 252946035553Spatrick const_iterator __i = find(__k); 253046035553Spatrick if (__i != end()) 253146035553Spatrick { 253246035553Spatrick const_iterator __e = end(); 253346035553Spatrick do 253446035553Spatrick { 253546035553Spatrick ++__i; 253646035553Spatrick ++__r; 253746035553Spatrick } while (__i != __e && key_eq()(*__i, __k)); 253846035553Spatrick } 253946035553Spatrick return __r; 254046035553Spatrick} 254146035553Spatrick 254246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 254346035553Spatricktemplate <class _Key> 254446035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, 254546035553Spatrick typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> 254646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( 254746035553Spatrick const _Key& __k) 254846035553Spatrick{ 254946035553Spatrick iterator __i = find(__k); 255046035553Spatrick iterator __j = __i; 255146035553Spatrick if (__i != end()) 255246035553Spatrick ++__j; 255346035553Spatrick return pair<iterator, iterator>(__i, __j); 255446035553Spatrick} 255546035553Spatrick 255646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 255746035553Spatricktemplate <class _Key> 255846035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator, 255946035553Spatrick typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> 256046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( 256146035553Spatrick const _Key& __k) const 256246035553Spatrick{ 256346035553Spatrick const_iterator __i = find(__k); 256446035553Spatrick const_iterator __j = __i; 256546035553Spatrick if (__i != end()) 256646035553Spatrick ++__j; 256746035553Spatrick return pair<const_iterator, const_iterator>(__i, __j); 256846035553Spatrick} 256946035553Spatrick 257046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 257146035553Spatricktemplate <class _Key> 257246035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, 257346035553Spatrick typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> 257446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( 257546035553Spatrick const _Key& __k) 257646035553Spatrick{ 257746035553Spatrick iterator __i = find(__k); 257846035553Spatrick iterator __j = __i; 257946035553Spatrick if (__i != end()) 258046035553Spatrick { 258146035553Spatrick iterator __e = end(); 258246035553Spatrick do 258346035553Spatrick { 258446035553Spatrick ++__j; 258546035553Spatrick } while (__j != __e && key_eq()(*__j, __k)); 258646035553Spatrick } 258746035553Spatrick return pair<iterator, iterator>(__i, __j); 258846035553Spatrick} 258946035553Spatrick 259046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 259146035553Spatricktemplate <class _Key> 259246035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator, 259346035553Spatrick typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> 259446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( 259546035553Spatrick const _Key& __k) const 259646035553Spatrick{ 259746035553Spatrick const_iterator __i = find(__k); 259846035553Spatrick const_iterator __j = __i; 259946035553Spatrick if (__i != end()) 260046035553Spatrick { 260146035553Spatrick const_iterator __e = end(); 260246035553Spatrick do 260346035553Spatrick { 260446035553Spatrick ++__j; 260546035553Spatrick } while (__j != __e && key_eq()(*__j, __k)); 260646035553Spatrick } 260746035553Spatrick return pair<const_iterator, const_iterator>(__i, __j); 260846035553Spatrick} 260946035553Spatrick 261046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 261146035553Spatrickvoid 261246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) 261346035553Spatrick#if _LIBCPP_STD_VER <= 11 261446035553Spatrick _NOEXCEPT_( 261546035553Spatrick __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value 261646035553Spatrick && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value 261746035553Spatrick || __is_nothrow_swappable<__pointer_allocator>::value) 261846035553Spatrick && (!__node_traits::propagate_on_container_swap::value 261946035553Spatrick || __is_nothrow_swappable<__node_allocator>::value) 262046035553Spatrick ) 262146035553Spatrick#else 262246035553Spatrick _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value) 262346035553Spatrick#endif 262446035553Spatrick{ 262546035553Spatrick _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || 262646035553Spatrick this->__node_alloc() == __u.__node_alloc(), 262746035553Spatrick "list::swap: Either propagate_on_container_swap must be true" 262846035553Spatrick " or the allocators must compare equal"); 262946035553Spatrick { 263046035553Spatrick __node_pointer_pointer __npp = __bucket_list_.release(); 263146035553Spatrick __bucket_list_.reset(__u.__bucket_list_.release()); 263246035553Spatrick __u.__bucket_list_.reset(__npp); 263346035553Spatrick } 263446035553Spatrick _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); 263576d0caaeSpatrick _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), 263646035553Spatrick __u.__bucket_list_.get_deleter().__alloc()); 263776d0caaeSpatrick _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); 263846035553Spatrick _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); 263946035553Spatrick __p2_.swap(__u.__p2_); 264046035553Spatrick __p3_.swap(__u.__p3_); 264146035553Spatrick if (size() > 0) 2642*4bdff4beSrobert __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = 264346035553Spatrick __p1_.first().__ptr(); 264446035553Spatrick if (__u.size() > 0) 2645*4bdff4beSrobert __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = 264646035553Spatrick __u.__p1_.first().__ptr(); 2647*4bdff4beSrobert std::__debug_db_swap(this, std::addressof(__u)); 264846035553Spatrick} 264946035553Spatrick 265046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 265146035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type 265246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const 265346035553Spatrick{ 265446035553Spatrick _LIBCPP_ASSERT(__n < bucket_count(), 265546035553Spatrick "unordered container::bucket_size(n) called with n >= bucket_count()"); 265646035553Spatrick __next_pointer __np = __bucket_list_[__n]; 265746035553Spatrick size_type __bc = bucket_count(); 265846035553Spatrick size_type __r = 0; 265946035553Spatrick if (__np != nullptr) 266046035553Spatrick { 266146035553Spatrick for (__np = __np->__next_; __np != nullptr && 2662*4bdff4beSrobert std::__constrain_hash(__np->__hash(), __bc) == __n; 2663*4bdff4beSrobert __np = __np->__next_, (void) ++__r) 266446035553Spatrick ; 266546035553Spatrick } 266646035553Spatrick return __r; 266746035553Spatrick} 266846035553Spatrick 266946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 267046035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 267146035553Spatrickvoid 267246035553Spatrickswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, 267346035553Spatrick __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) 267446035553Spatrick _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 267546035553Spatrick{ 267646035553Spatrick __x.swap(__y); 267746035553Spatrick} 267846035553Spatrick 2679*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE 268046035553Spatrick 268146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 268246035553Spatrickbool 268346035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const 268446035553Spatrick{ 268546035553Spatrick return __i->__node_ != nullptr; 268646035553Spatrick} 268746035553Spatrick 268846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 268946035553Spatrickbool 269046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const 269146035553Spatrick{ 269246035553Spatrick return false; 269346035553Spatrick} 269446035553Spatrick 269546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 269646035553Spatrickbool 269746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const 269846035553Spatrick{ 269946035553Spatrick return false; 270046035553Spatrick} 270146035553Spatrick 270246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> 270346035553Spatrickbool 270446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const 270546035553Spatrick{ 270646035553Spatrick return false; 270746035553Spatrick} 270846035553Spatrick 2709*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE 271046035553Spatrick 271146035553Spatrick_LIBCPP_END_NAMESPACE_STD 271246035553Spatrick 271346035553Spatrick_LIBCPP_POP_MACROS 271446035553Spatrick 2715*4bdff4beSrobert#endif // _LIBCPP___HASH_TABLE 2716