1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===-------------------------- hash_map ----------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_HASH_MAP 11*0b57cec5SDimitry Andric#define _LIBCPP_HASH_MAP 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric hash_map synopsis 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andricnamespace __gnu_cxx 18*0b57cec5SDimitry Andric{ 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, 21*0b57cec5SDimitry Andric class Alloc = allocator<pair<const Key, T>>> 22*0b57cec5SDimitry Andricclass hash_map 23*0b57cec5SDimitry Andric{ 24*0b57cec5SDimitry Andricpublic: 25*0b57cec5SDimitry Andric // types 26*0b57cec5SDimitry Andric typedef Key key_type; 27*0b57cec5SDimitry Andric typedef T mapped_type; 28*0b57cec5SDimitry Andric typedef Hash hasher; 29*0b57cec5SDimitry Andric typedef Pred key_equal; 30*0b57cec5SDimitry Andric typedef Alloc allocator_type; 31*0b57cec5SDimitry Andric typedef pair<const key_type, mapped_type> value_type; 32*0b57cec5SDimitry Andric typedef value_type& reference; 33*0b57cec5SDimitry Andric typedef const value_type& const_reference; 34*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::pointer pointer; 35*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 36*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::size_type size_type; 37*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::difference_type difference_type; 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric typedef /unspecified/ iterator; 40*0b57cec5SDimitry Andric typedef /unspecified/ const_iterator; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric explicit hash_map(size_type n = 193, const hasher& hf = hasher(), 43*0b57cec5SDimitry Andric const key_equal& eql = key_equal(), 44*0b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 45*0b57cec5SDimitry Andric template <class InputIterator> 46*0b57cec5SDimitry Andric hash_map(InputIterator f, InputIterator l, 47*0b57cec5SDimitry Andric size_type n = 193, const hasher& hf = hasher(), 48*0b57cec5SDimitry Andric const key_equal& eql = key_equal(), 49*0b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 50*0b57cec5SDimitry Andric hash_map(const hash_map&); 51*0b57cec5SDimitry Andric ~hash_map(); 52*0b57cec5SDimitry Andric hash_map& operator=(const hash_map&); 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric allocator_type get_allocator() const; 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric bool empty() const; 57*0b57cec5SDimitry Andric size_type size() const; 58*0b57cec5SDimitry Andric size_type max_size() const; 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric iterator begin(); 61*0b57cec5SDimitry Andric iterator end(); 62*0b57cec5SDimitry Andric const_iterator begin() const; 63*0b57cec5SDimitry Andric const_iterator end() const; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric pair<iterator, bool> insert(const value_type& obj); 66*0b57cec5SDimitry Andric template <class InputIterator> 67*0b57cec5SDimitry Andric void insert(InputIterator first, InputIterator last); 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric void erase(const_iterator position); 70*0b57cec5SDimitry Andric size_type erase(const key_type& k); 71*0b57cec5SDimitry Andric void erase(const_iterator first, const_iterator last); 72*0b57cec5SDimitry Andric void clear(); 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric void swap(hash_map&); 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric hasher hash_funct() const; 77*0b57cec5SDimitry Andric key_equal key_eq() const; 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric iterator find(const key_type& k); 80*0b57cec5SDimitry Andric const_iterator find(const key_type& k) const; 81*0b57cec5SDimitry Andric size_type count(const key_type& k) const; 82*0b57cec5SDimitry Andric pair<iterator, iterator> equal_range(const key_type& k); 83*0b57cec5SDimitry Andric pair<const_iterator, const_iterator> equal_range(const key_type& k) const; 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric mapped_type& operator[](const key_type& k); 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric size_type bucket_count() const; 88*0b57cec5SDimitry Andric size_type max_bucket_count() const; 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric size_type elems_in_bucket(size_type n) const; 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric void resize(size_type n); 93*0b57cec5SDimitry Andric}; 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 96*0b57cec5SDimitry Andric void swap(hash_map<Key, T, Hash, Pred, Alloc>& x, 97*0b57cec5SDimitry Andric hash_map<Key, T, Hash, Pred, Alloc>& y); 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 100*0b57cec5SDimitry Andric bool 101*0b57cec5SDimitry Andric operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x, 102*0b57cec5SDimitry Andric const hash_map<Key, T, Hash, Pred, Alloc>& y); 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 105*0b57cec5SDimitry Andric bool 106*0b57cec5SDimitry Andric operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x, 107*0b57cec5SDimitry Andric const hash_map<Key, T, Hash, Pred, Alloc>& y); 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, 110*0b57cec5SDimitry Andric class Alloc = allocator<pair<const Key, T>>> 111*0b57cec5SDimitry Andricclass hash_multimap 112*0b57cec5SDimitry Andric{ 113*0b57cec5SDimitry Andricpublic: 114*0b57cec5SDimitry Andric // types 115*0b57cec5SDimitry Andric typedef Key key_type; 116*0b57cec5SDimitry Andric typedef T mapped_type; 117*0b57cec5SDimitry Andric typedef Hash hasher; 118*0b57cec5SDimitry Andric typedef Pred key_equal; 119*0b57cec5SDimitry Andric typedef Alloc allocator_type; 120*0b57cec5SDimitry Andric typedef pair<const key_type, mapped_type> value_type; 121*0b57cec5SDimitry Andric typedef value_type& reference; 122*0b57cec5SDimitry Andric typedef const value_type& const_reference; 123*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::pointer pointer; 124*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 125*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::size_type size_type; 126*0b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::difference_type difference_type; 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric typedef /unspecified/ iterator; 129*0b57cec5SDimitry Andric typedef /unspecified/ const_iterator; 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(), 132*0b57cec5SDimitry Andric const key_equal& eql = key_equal(), 133*0b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 134*0b57cec5SDimitry Andric template <class InputIterator> 135*0b57cec5SDimitry Andric hash_multimap(InputIterator f, InputIterator l, 136*0b57cec5SDimitry Andric size_type n = 193, const hasher& hf = hasher(), 137*0b57cec5SDimitry Andric const key_equal& eql = key_equal(), 138*0b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 139*0b57cec5SDimitry Andric explicit hash_multimap(const allocator_type&); 140*0b57cec5SDimitry Andric hash_multimap(const hash_multimap&); 141*0b57cec5SDimitry Andric ~hash_multimap(); 142*0b57cec5SDimitry Andric hash_multimap& operator=(const hash_multimap&); 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric allocator_type get_allocator() const; 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric bool empty() const; 147*0b57cec5SDimitry Andric size_type size() const; 148*0b57cec5SDimitry Andric size_type max_size() const; 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric iterator begin(); 151*0b57cec5SDimitry Andric iterator end(); 152*0b57cec5SDimitry Andric const_iterator begin() const; 153*0b57cec5SDimitry Andric const_iterator end() const; 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric iterator insert(const value_type& obj); 156*0b57cec5SDimitry Andric template <class InputIterator> 157*0b57cec5SDimitry Andric void insert(InputIterator first, InputIterator last); 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric void erase(const_iterator position); 160*0b57cec5SDimitry Andric size_type erase(const key_type& k); 161*0b57cec5SDimitry Andric void erase(const_iterator first, const_iterator last); 162*0b57cec5SDimitry Andric void clear(); 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric void swap(hash_multimap&); 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric hasher hash_funct() const; 167*0b57cec5SDimitry Andric key_equal key_eq() const; 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric iterator find(const key_type& k); 170*0b57cec5SDimitry Andric const_iterator find(const key_type& k) const; 171*0b57cec5SDimitry Andric size_type count(const key_type& k) const; 172*0b57cec5SDimitry Andric pair<iterator, iterator> equal_range(const key_type& k); 173*0b57cec5SDimitry Andric pair<const_iterator, const_iterator> equal_range(const key_type& k) const; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric size_type bucket_count() const; 176*0b57cec5SDimitry Andric size_type max_bucket_count() const; 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric size_type elems_in_bucket(size_type n) const; 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric void resize(size_type n); 181*0b57cec5SDimitry Andric}; 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 184*0b57cec5SDimitry Andric void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x, 185*0b57cec5SDimitry Andric hash_multimap<Key, T, Hash, Pred, Alloc>& y); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 188*0b57cec5SDimitry Andric bool 189*0b57cec5SDimitry Andric operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x, 190*0b57cec5SDimitry Andric const hash_multimap<Key, T, Hash, Pred, Alloc>& y); 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 193*0b57cec5SDimitry Andric bool 194*0b57cec5SDimitry Andric operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x, 195*0b57cec5SDimitry Andric const hash_multimap<Key, T, Hash, Pred, Alloc>& y); 196*0b57cec5SDimitry Andric 197*0b57cec5SDimitry Andric} // __gnu_cxx 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric*/ 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric#include <__config> 202*0b57cec5SDimitry Andric#include <__hash_table> 203*0b57cec5SDimitry Andric#include <functional> 204*0b57cec5SDimitry Andric#include <stdexcept> 205*0b57cec5SDimitry Andric#include <type_traits> 206*0b57cec5SDimitry Andric#include <ext/__hash> 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric#if __DEPRECATED 209*0b57cec5SDimitry Andric#if defined(_LIBCPP_WARNING) 210*0b57cec5SDimitry Andric _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map>") 211*0b57cec5SDimitry Andric#else 212*0b57cec5SDimitry Andric# warning Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map> 213*0b57cec5SDimitry Andric#endif 214*0b57cec5SDimitry Andric#endif 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 217*0b57cec5SDimitry Andric#pragma GCC system_header 218*0b57cec5SDimitry Andric#endif 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andricnamespace __gnu_cxx { 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andrictemplate <class _Tp, class _Hash, 223*0b57cec5SDimitry Andric bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value 224*0b57cec5SDimitry Andric > 225*0b57cec5SDimitry Andricclass __hash_map_hasher 226*0b57cec5SDimitry Andric : private _Hash 227*0b57cec5SDimitry Andric{ 228*0b57cec5SDimitry Andricpublic: 229*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {} 230*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {} 231*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;} 232*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 233*0b57cec5SDimitry Andric size_t operator()(const _Tp& __x) const 234*0b57cec5SDimitry Andric {return static_cast<const _Hash&>(*this)(__x.first);} 235*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 236*0b57cec5SDimitry Andric size_t operator()(const typename _Tp::first_type& __x) const 237*0b57cec5SDimitry Andric {return static_cast<const _Hash&>(*this)(__x);} 238*0b57cec5SDimitry Andric}; 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andrictemplate <class _Tp, class _Hash> 241*0b57cec5SDimitry Andricclass __hash_map_hasher<_Tp, _Hash, false> 242*0b57cec5SDimitry Andric{ 243*0b57cec5SDimitry Andric _Hash __hash_; 244*0b57cec5SDimitry Andricpublic: 245*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {} 246*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {} 247*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;} 248*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 249*0b57cec5SDimitry Andric size_t operator()(const _Tp& __x) const 250*0b57cec5SDimitry Andric {return __hash_(__x.first);} 251*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 252*0b57cec5SDimitry Andric size_t operator()(const typename _Tp::first_type& __x) const 253*0b57cec5SDimitry Andric {return __hash_(__x);} 254*0b57cec5SDimitry Andric}; 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andrictemplate <class _Tp, class _Pred, 257*0b57cec5SDimitry Andric bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value 258*0b57cec5SDimitry Andric > 259*0b57cec5SDimitry Andricclass __hash_map_equal 260*0b57cec5SDimitry Andric : private _Pred 261*0b57cec5SDimitry Andric{ 262*0b57cec5SDimitry Andricpublic: 263*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {} 264*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {} 265*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;} 266*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 267*0b57cec5SDimitry Andric bool operator()(const _Tp& __x, const _Tp& __y) const 268*0b57cec5SDimitry Andric {return static_cast<const _Pred&>(*this)(__x.first, __y.first);} 269*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 270*0b57cec5SDimitry Andric bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const 271*0b57cec5SDimitry Andric {return static_cast<const _Pred&>(*this)(__x, __y.first);} 272*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 273*0b57cec5SDimitry Andric bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const 274*0b57cec5SDimitry Andric {return static_cast<const _Pred&>(*this)(__x.first, __y);} 275*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 276*0b57cec5SDimitry Andric bool operator()(const typename _Tp::first_type& __x, 277*0b57cec5SDimitry Andric const typename _Tp::first_type& __y) const 278*0b57cec5SDimitry Andric {return static_cast<const _Pred&>(*this)(__x, __y);} 279*0b57cec5SDimitry Andric}; 280*0b57cec5SDimitry Andric 281*0b57cec5SDimitry Andrictemplate <class _Tp, class _Pred> 282*0b57cec5SDimitry Andricclass __hash_map_equal<_Tp, _Pred, false> 283*0b57cec5SDimitry Andric{ 284*0b57cec5SDimitry Andric _Pred __pred_; 285*0b57cec5SDimitry Andricpublic: 286*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {} 287*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {} 288*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;} 289*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 290*0b57cec5SDimitry Andric bool operator()(const _Tp& __x, const _Tp& __y) const 291*0b57cec5SDimitry Andric {return __pred_(__x.first, __y.first);} 292*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 293*0b57cec5SDimitry Andric bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const 294*0b57cec5SDimitry Andric {return __pred_(__x, __y.first);} 295*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 296*0b57cec5SDimitry Andric bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const 297*0b57cec5SDimitry Andric {return __pred_(__x.first, __y);} 298*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 299*0b57cec5SDimitry Andric bool operator()(const typename _Tp::first_type& __x, 300*0b57cec5SDimitry Andric const typename _Tp::first_type& __y) const 301*0b57cec5SDimitry Andric {return __pred_(__x, __y);} 302*0b57cec5SDimitry Andric}; 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andrictemplate <class _Alloc> 305*0b57cec5SDimitry Andricclass __hash_map_node_destructor 306*0b57cec5SDimitry Andric{ 307*0b57cec5SDimitry Andric typedef _Alloc allocator_type; 308*0b57cec5SDimitry Andric typedef std::allocator_traits<allocator_type> __alloc_traits; 309*0b57cec5SDimitry Andric typedef typename __alloc_traits::value_type::__node_value_type value_type; 310*0b57cec5SDimitry Andricpublic: 311*0b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 312*0b57cec5SDimitry Andricprivate: 313*0b57cec5SDimitry Andric typedef typename value_type::first_type first_type; 314*0b57cec5SDimitry Andric typedef typename value_type::second_type second_type; 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric allocator_type& __na_; 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andric __hash_map_node_destructor& operator=(const __hash_map_node_destructor&); 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andricpublic: 321*0b57cec5SDimitry Andric bool __first_constructed; 322*0b57cec5SDimitry Andric bool __second_constructed; 323*0b57cec5SDimitry Andric 324*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 325*0b57cec5SDimitry Andric explicit __hash_map_node_destructor(allocator_type& __na) 326*0b57cec5SDimitry Andric : __na_(__na), 327*0b57cec5SDimitry Andric __first_constructed(false), 328*0b57cec5SDimitry Andric __second_constructed(false) 329*0b57cec5SDimitry Andric {} 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 332*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 333*0b57cec5SDimitry Andric __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x) 334*0b57cec5SDimitry Andric : __na_(__x.__na_), 335*0b57cec5SDimitry Andric __first_constructed(__x.__value_constructed), 336*0b57cec5SDimitry Andric __second_constructed(__x.__value_constructed) 337*0b57cec5SDimitry Andric { 338*0b57cec5SDimitry Andric __x.__value_constructed = false; 339*0b57cec5SDimitry Andric } 340*0b57cec5SDimitry Andric#else // _LIBCPP_CXX03_LANG 341*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 342*0b57cec5SDimitry Andric __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x) 343*0b57cec5SDimitry Andric : __na_(__x.__na_), 344*0b57cec5SDimitry Andric __first_constructed(__x.__value_constructed), 345*0b57cec5SDimitry Andric __second_constructed(__x.__value_constructed) 346*0b57cec5SDimitry Andric { 347*0b57cec5SDimitry Andric const_cast<bool&>(__x.__value_constructed) = false; 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 350*0b57cec5SDimitry Andric 351*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 352*0b57cec5SDimitry Andric void operator()(pointer __p) 353*0b57cec5SDimitry Andric { 354*0b57cec5SDimitry Andric if (__second_constructed) 355*0b57cec5SDimitry Andric __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second)); 356*0b57cec5SDimitry Andric if (__first_constructed) 357*0b57cec5SDimitry Andric __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first)); 358*0b57cec5SDimitry Andric if (__p) 359*0b57cec5SDimitry Andric __alloc_traits::deallocate(__na_, __p, 1); 360*0b57cec5SDimitry Andric } 361*0b57cec5SDimitry Andric}; 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andrictemplate <class _HashIterator> 364*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_iterator 365*0b57cec5SDimitry Andric{ 366*0b57cec5SDimitry Andric _HashIterator __i_; 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric typedef const typename _HashIterator::value_type::first_type key_type; 369*0b57cec5SDimitry Andric typedef typename _HashIterator::value_type::second_type mapped_type; 370*0b57cec5SDimitry Andricpublic: 371*0b57cec5SDimitry Andric typedef std::forward_iterator_tag iterator_category; 372*0b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> value_type; 373*0b57cec5SDimitry Andric typedef typename _HashIterator::difference_type difference_type; 374*0b57cec5SDimitry Andric typedef value_type& reference; 375*0b57cec5SDimitry Andric typedef typename std::__rebind_pointer<typename _HashIterator::pointer, value_type>::type 376*0b57cec5SDimitry Andric pointer; 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {} 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {} 381*0b57cec5SDimitry Andric 382*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();} 383*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();} 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;} 386*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 387*0b57cec5SDimitry Andric __hash_map_iterator operator++(int) 388*0b57cec5SDimitry Andric { 389*0b57cec5SDimitry Andric __hash_map_iterator __t(*this); 390*0b57cec5SDimitry Andric ++(*this); 391*0b57cec5SDimitry Andric return __t; 392*0b57cec5SDimitry Andric } 393*0b57cec5SDimitry Andric 394*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 395*0b57cec5SDimitry Andric bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) 396*0b57cec5SDimitry Andric {return __x.__i_ == __y.__i_;} 397*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 398*0b57cec5SDimitry Andric bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) 399*0b57cec5SDimitry Andric {return __x.__i_ != __y.__i_;} 400*0b57cec5SDimitry Andric 401*0b57cec5SDimitry Andric template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map; 402*0b57cec5SDimitry Andric template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap; 403*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 404*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 405*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 406*0b57cec5SDimitry Andric}; 407*0b57cec5SDimitry Andric 408*0b57cec5SDimitry Andrictemplate <class _HashIterator> 409*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator 410*0b57cec5SDimitry Andric{ 411*0b57cec5SDimitry Andric _HashIterator __i_; 412*0b57cec5SDimitry Andric 413*0b57cec5SDimitry Andric typedef const typename _HashIterator::value_type::first_type key_type; 414*0b57cec5SDimitry Andric typedef typename _HashIterator::value_type::second_type mapped_type; 415*0b57cec5SDimitry Andricpublic: 416*0b57cec5SDimitry Andric typedef std::forward_iterator_tag iterator_category; 417*0b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> value_type; 418*0b57cec5SDimitry Andric typedef typename _HashIterator::difference_type difference_type; 419*0b57cec5SDimitry Andric typedef const value_type& reference; 420*0b57cec5SDimitry Andric typedef typename std::__rebind_pointer<typename _HashIterator::pointer, const value_type>::type 421*0b57cec5SDimitry Andric pointer; 422*0b57cec5SDimitry Andric 423*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {} 424*0b57cec5SDimitry Andric 425*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 426*0b57cec5SDimitry Andric __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {} 427*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 428*0b57cec5SDimitry Andric __hash_map_const_iterator( 429*0b57cec5SDimitry Andric __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i) 430*0b57cec5SDimitry Andric : __i_(__i.__i_) {} 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 433*0b57cec5SDimitry Andric reference operator*() const {return *operator->();} 434*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 435*0b57cec5SDimitry Andric pointer operator->() const {return (pointer)__i_.operator->();} 436*0b57cec5SDimitry Andric 437*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 438*0b57cec5SDimitry Andric __hash_map_const_iterator& operator++() {++__i_; return *this;} 439*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 440*0b57cec5SDimitry Andric __hash_map_const_iterator operator++(int) 441*0b57cec5SDimitry Andric { 442*0b57cec5SDimitry Andric __hash_map_const_iterator __t(*this); 443*0b57cec5SDimitry Andric ++(*this); 444*0b57cec5SDimitry Andric return __t; 445*0b57cec5SDimitry Andric } 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 448*0b57cec5SDimitry Andric bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) 449*0b57cec5SDimitry Andric {return __x.__i_ == __y.__i_;} 450*0b57cec5SDimitry Andric friend _LIBCPP_INLINE_VISIBILITY 451*0b57cec5SDimitry Andric bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) 452*0b57cec5SDimitry Andric {return __x.__i_ != __y.__i_;} 453*0b57cec5SDimitry Andric 454*0b57cec5SDimitry Andric template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map; 455*0b57cec5SDimitry Andric template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap; 456*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 457*0b57cec5SDimitry Andric template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 458*0b57cec5SDimitry Andric}; 459*0b57cec5SDimitry Andric 460*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>, 461*0b57cec5SDimitry Andric class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 462*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_map 463*0b57cec5SDimitry Andric{ 464*0b57cec5SDimitry Andricpublic: 465*0b57cec5SDimitry Andric // types 466*0b57cec5SDimitry Andric typedef _Key key_type; 467*0b57cec5SDimitry Andric typedef _Tp mapped_type; 468*0b57cec5SDimitry Andric typedef _Tp data_type; 469*0b57cec5SDimitry Andric typedef _Hash hasher; 470*0b57cec5SDimitry Andric typedef _Pred key_equal; 471*0b57cec5SDimitry Andric typedef _Alloc allocator_type; 472*0b57cec5SDimitry Andric typedef std::pair<const key_type, mapped_type> value_type; 473*0b57cec5SDimitry Andric typedef value_type& reference; 474*0b57cec5SDimitry Andric typedef const value_type& const_reference; 475*0b57cec5SDimitry Andric 476*0b57cec5SDimitry Andricprivate: 477*0b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> __value_type; 478*0b57cec5SDimitry Andric typedef __hash_map_hasher<__value_type, hasher> __hasher; 479*0b57cec5SDimitry Andric typedef __hash_map_equal<__value_type, key_equal> __key_equal; 480*0b57cec5SDimitry Andric typedef typename std::__rebind_alloc_helper< 481*0b57cec5SDimitry Andric std::allocator_traits<allocator_type>, __value_type>::type __allocator_type; 482*0b57cec5SDimitry Andric 483*0b57cec5SDimitry Andric typedef std::__hash_table<__value_type, __hasher, 484*0b57cec5SDimitry Andric __key_equal, __allocator_type> __table; 485*0b57cec5SDimitry Andric 486*0b57cec5SDimitry Andric __table __table_; 487*0b57cec5SDimitry Andric 488*0b57cec5SDimitry Andric typedef typename __table::__node_pointer __node_pointer; 489*0b57cec5SDimitry Andric typedef typename __table::__node_const_pointer __node_const_pointer; 490*0b57cec5SDimitry Andric typedef typename __table::__node_traits __node_traits; 491*0b57cec5SDimitry Andric typedef typename __table::__node_allocator __node_allocator; 492*0b57cec5SDimitry Andric typedef typename __table::__node __node; 493*0b57cec5SDimitry Andric typedef __hash_map_node_destructor<__node_allocator> _Dp; 494*0b57cec5SDimitry Andric typedef std::unique_ptr<__node, _Dp> __node_holder; 495*0b57cec5SDimitry Andric typedef std::allocator_traits<allocator_type> __alloc_traits; 496*0b57cec5SDimitry Andricpublic: 497*0b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 498*0b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 499*0b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 500*0b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 501*0b57cec5SDimitry Andric 502*0b57cec5SDimitry Andric typedef __hash_map_iterator<typename __table::iterator> iterator; 503*0b57cec5SDimitry Andric typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; 504*0b57cec5SDimitry Andric 505*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);} 506*0b57cec5SDimitry Andric explicit hash_map(size_type __n, const hasher& __hf = hasher(), 507*0b57cec5SDimitry Andric const key_equal& __eql = key_equal()); 508*0b57cec5SDimitry Andric hash_map(size_type __n, const hasher& __hf, 509*0b57cec5SDimitry Andric const key_equal& __eql, 510*0b57cec5SDimitry Andric const allocator_type& __a); 511*0b57cec5SDimitry Andric template <class _InputIterator> 512*0b57cec5SDimitry Andric hash_map(_InputIterator __first, _InputIterator __last); 513*0b57cec5SDimitry Andric template <class _InputIterator> 514*0b57cec5SDimitry Andric hash_map(_InputIterator __first, _InputIterator __last, 515*0b57cec5SDimitry Andric size_type __n, const hasher& __hf = hasher(), 516*0b57cec5SDimitry Andric const key_equal& __eql = key_equal()); 517*0b57cec5SDimitry Andric template <class _InputIterator> 518*0b57cec5SDimitry Andric hash_map(_InputIterator __first, _InputIterator __last, 519*0b57cec5SDimitry Andric size_type __n, const hasher& __hf, 520*0b57cec5SDimitry Andric const key_equal& __eql, 521*0b57cec5SDimitry Andric const allocator_type& __a); 522*0b57cec5SDimitry Andric hash_map(const hash_map& __u); 523*0b57cec5SDimitry Andric 524*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 525*0b57cec5SDimitry Andric allocator_type get_allocator() const 526*0b57cec5SDimitry Andric {return allocator_type(__table_.__node_alloc());} 527*0b57cec5SDimitry Andric 528*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 529*0b57cec5SDimitry Andric bool empty() const {return __table_.size() == 0;} 530*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 531*0b57cec5SDimitry Andric size_type size() const {return __table_.size();} 532*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 533*0b57cec5SDimitry Andric size_type max_size() const {return __table_.max_size();} 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 536*0b57cec5SDimitry Andric iterator begin() {return __table_.begin();} 537*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 538*0b57cec5SDimitry Andric iterator end() {return __table_.end();} 539*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 540*0b57cec5SDimitry Andric const_iterator begin() const {return __table_.begin();} 541*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 542*0b57cec5SDimitry Andric const_iterator end() const {return __table_.end();} 543*0b57cec5SDimitry Andric 544*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 545*0b57cec5SDimitry Andric std::pair<iterator, bool> insert(const value_type& __x) 546*0b57cec5SDimitry Andric {return __table_.__insert_unique(__x);} 547*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 548*0b57cec5SDimitry Andric iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} 549*0b57cec5SDimitry Andric template <class _InputIterator> 550*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 551*0b57cec5SDimitry Andric void insert(_InputIterator __first, _InputIterator __last); 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 554*0b57cec5SDimitry Andric void erase(const_iterator __p) {__table_.erase(__p.__i_);} 555*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 556*0b57cec5SDimitry Andric size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} 557*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 558*0b57cec5SDimitry Andric void erase(const_iterator __first, const_iterator __last) 559*0b57cec5SDimitry Andric {__table_.erase(__first.__i_, __last.__i_);} 560*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 561*0b57cec5SDimitry Andric void clear() {__table_.clear();} 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 564*0b57cec5SDimitry Andric void swap(hash_map& __u) {__table_.swap(__u.__table_);} 565*0b57cec5SDimitry Andric 566*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 567*0b57cec5SDimitry Andric hasher hash_funct() const 568*0b57cec5SDimitry Andric {return __table_.hash_function().hash_function();} 569*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 570*0b57cec5SDimitry Andric key_equal key_eq() const 571*0b57cec5SDimitry Andric {return __table_.key_eq().key_eq();} 572*0b57cec5SDimitry Andric 573*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 574*0b57cec5SDimitry Andric iterator find(const key_type& __k) {return __table_.find(__k);} 575*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 576*0b57cec5SDimitry Andric const_iterator find(const key_type& __k) const {return __table_.find(__k);} 577*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 578*0b57cec5SDimitry Andric size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} 579*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 580*0b57cec5SDimitry Andric std::pair<iterator, iterator> equal_range(const key_type& __k) 581*0b57cec5SDimitry Andric {return __table_.__equal_range_unique(__k);} 582*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 583*0b57cec5SDimitry Andric std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const 584*0b57cec5SDimitry Andric {return __table_.__equal_range_unique(__k);} 585*0b57cec5SDimitry Andric 586*0b57cec5SDimitry Andric mapped_type& operator[](const key_type& __k); 587*0b57cec5SDimitry Andric 588*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 589*0b57cec5SDimitry Andric size_type bucket_count() const {return __table_.bucket_count();} 590*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 591*0b57cec5SDimitry Andric size_type max_bucket_count() const {return __table_.max_bucket_count();} 592*0b57cec5SDimitry Andric 593*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 594*0b57cec5SDimitry Andric size_type elems_in_bucket(size_type __n) const 595*0b57cec5SDimitry Andric {return __table_.bucket_size(__n);} 596*0b57cec5SDimitry Andric 597*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 598*0b57cec5SDimitry Andric void resize(size_type __n) {__table_.rehash(__n);} 599*0b57cec5SDimitry Andric 600*0b57cec5SDimitry Andricprivate: 601*0b57cec5SDimitry Andric __node_holder __construct_node(const key_type& __k); 602*0b57cec5SDimitry Andric}; 603*0b57cec5SDimitry Andric 604*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 605*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 606*0b57cec5SDimitry Andric size_type __n, const hasher& __hf, const key_equal& __eql) 607*0b57cec5SDimitry Andric : __table_(__hf, __eql) 608*0b57cec5SDimitry Andric{ 609*0b57cec5SDimitry Andric __table_.rehash(__n); 610*0b57cec5SDimitry Andric} 611*0b57cec5SDimitry Andric 612*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 613*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 614*0b57cec5SDimitry Andric size_type __n, const hasher& __hf, const key_equal& __eql, 615*0b57cec5SDimitry Andric const allocator_type& __a) 616*0b57cec5SDimitry Andric : __table_(__hf, __eql, __a) 617*0b57cec5SDimitry Andric{ 618*0b57cec5SDimitry Andric __table_.rehash(__n); 619*0b57cec5SDimitry Andric} 620*0b57cec5SDimitry Andric 621*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 622*0b57cec5SDimitry Andrictemplate <class _InputIterator> 623*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 624*0b57cec5SDimitry Andric _InputIterator __first, _InputIterator __last) 625*0b57cec5SDimitry Andric{ 626*0b57cec5SDimitry Andric __table_.rehash(193); 627*0b57cec5SDimitry Andric insert(__first, __last); 628*0b57cec5SDimitry Andric} 629*0b57cec5SDimitry Andric 630*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 631*0b57cec5SDimitry Andrictemplate <class _InputIterator> 632*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 633*0b57cec5SDimitry Andric _InputIterator __first, _InputIterator __last, size_type __n, 634*0b57cec5SDimitry Andric const hasher& __hf, const key_equal& __eql) 635*0b57cec5SDimitry Andric : __table_(__hf, __eql) 636*0b57cec5SDimitry Andric{ 637*0b57cec5SDimitry Andric __table_.rehash(__n); 638*0b57cec5SDimitry Andric insert(__first, __last); 639*0b57cec5SDimitry Andric} 640*0b57cec5SDimitry Andric 641*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 642*0b57cec5SDimitry Andrictemplate <class _InputIterator> 643*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 644*0b57cec5SDimitry Andric _InputIterator __first, _InputIterator __last, size_type __n, 645*0b57cec5SDimitry Andric const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 646*0b57cec5SDimitry Andric : __table_(__hf, __eql, __a) 647*0b57cec5SDimitry Andric{ 648*0b57cec5SDimitry Andric __table_.rehash(__n); 649*0b57cec5SDimitry Andric insert(__first, __last); 650*0b57cec5SDimitry Andric} 651*0b57cec5SDimitry Andric 652*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 653*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 654*0b57cec5SDimitry Andric const hash_map& __u) 655*0b57cec5SDimitry Andric : __table_(__u.__table_) 656*0b57cec5SDimitry Andric{ 657*0b57cec5SDimitry Andric __table_.rehash(__u.bucket_count()); 658*0b57cec5SDimitry Andric insert(__u.begin(), __u.end()); 659*0b57cec5SDimitry Andric} 660*0b57cec5SDimitry Andric 661*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 662*0b57cec5SDimitry Andrictypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder 663*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) 664*0b57cec5SDimitry Andric{ 665*0b57cec5SDimitry Andric __node_allocator& __na = __table_.__node_alloc(); 666*0b57cec5SDimitry Andric __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 667*0b57cec5SDimitry Andric __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k); 668*0b57cec5SDimitry Andric __h.get_deleter().__first_constructed = true; 669*0b57cec5SDimitry Andric __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second)); 670*0b57cec5SDimitry Andric __h.get_deleter().__second_constructed = true; 671*0b57cec5SDimitry Andric return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 672*0b57cec5SDimitry Andric} 673*0b57cec5SDimitry Andric 674*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 675*0b57cec5SDimitry Andrictemplate <class _InputIterator> 676*0b57cec5SDimitry Andricinline 677*0b57cec5SDimitry Andricvoid 678*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, 679*0b57cec5SDimitry Andric _InputIterator __last) 680*0b57cec5SDimitry Andric{ 681*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 682*0b57cec5SDimitry Andric __table_.__insert_unique(*__first); 683*0b57cec5SDimitry Andric} 684*0b57cec5SDimitry Andric 685*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 686*0b57cec5SDimitry Andric_Tp& 687*0b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) 688*0b57cec5SDimitry Andric{ 689*0b57cec5SDimitry Andric iterator __i = find(__k); 690*0b57cec5SDimitry Andric if (__i != end()) 691*0b57cec5SDimitry Andric return __i->second; 692*0b57cec5SDimitry Andric __node_holder __h = __construct_node(__k); 693*0b57cec5SDimitry Andric std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); 694*0b57cec5SDimitry Andric __h.release(); 695*0b57cec5SDimitry Andric return __r.first->second; 696*0b57cec5SDimitry Andric} 697*0b57cec5SDimitry Andric 698*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 699*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 700*0b57cec5SDimitry Andricvoid 701*0b57cec5SDimitry Andricswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 702*0b57cec5SDimitry Andric hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 703*0b57cec5SDimitry Andric{ 704*0b57cec5SDimitry Andric __x.swap(__y); 705*0b57cec5SDimitry Andric} 706*0b57cec5SDimitry Andric 707*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 708*0b57cec5SDimitry Andricbool 709*0b57cec5SDimitry Andricoperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 710*0b57cec5SDimitry Andric const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 711*0b57cec5SDimitry Andric{ 712*0b57cec5SDimitry Andric if (__x.size() != __y.size()) 713*0b57cec5SDimitry Andric return false; 714*0b57cec5SDimitry Andric typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator 715*0b57cec5SDimitry Andric const_iterator; 716*0b57cec5SDimitry Andric for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); 717*0b57cec5SDimitry Andric __i != __ex; ++__i) 718*0b57cec5SDimitry Andric { 719*0b57cec5SDimitry Andric const_iterator __j = __y.find(__i->first); 720*0b57cec5SDimitry Andric if (__j == __ey || !(*__i == *__j)) 721*0b57cec5SDimitry Andric return false; 722*0b57cec5SDimitry Andric } 723*0b57cec5SDimitry Andric return true; 724*0b57cec5SDimitry Andric} 725*0b57cec5SDimitry Andric 726*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 727*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 728*0b57cec5SDimitry Andricbool 729*0b57cec5SDimitry Andricoperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 730*0b57cec5SDimitry Andric const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 731*0b57cec5SDimitry Andric{ 732*0b57cec5SDimitry Andric return !(__x == __y); 733*0b57cec5SDimitry Andric} 734*0b57cec5SDimitry Andric 735*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>, 736*0b57cec5SDimitry Andric class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 737*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multimap 738*0b57cec5SDimitry Andric{ 739*0b57cec5SDimitry Andricpublic: 740*0b57cec5SDimitry Andric // types 741*0b57cec5SDimitry Andric typedef _Key key_type; 742*0b57cec5SDimitry Andric typedef _Tp mapped_type; 743*0b57cec5SDimitry Andric typedef _Tp data_type; 744*0b57cec5SDimitry Andric typedef _Hash hasher; 745*0b57cec5SDimitry Andric typedef _Pred key_equal; 746*0b57cec5SDimitry Andric typedef _Alloc allocator_type; 747*0b57cec5SDimitry Andric typedef std::pair<const key_type, mapped_type> value_type; 748*0b57cec5SDimitry Andric typedef value_type& reference; 749*0b57cec5SDimitry Andric typedef const value_type& const_reference; 750*0b57cec5SDimitry Andric 751*0b57cec5SDimitry Andricprivate: 752*0b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> __value_type; 753*0b57cec5SDimitry Andric typedef __hash_map_hasher<__value_type, hasher> __hasher; 754*0b57cec5SDimitry Andric typedef __hash_map_equal<__value_type, key_equal> __key_equal; 755*0b57cec5SDimitry Andric typedef typename std::__rebind_alloc_helper<std::allocator_traits<allocator_type>, __value_type>::type __allocator_type; 756*0b57cec5SDimitry Andric 757*0b57cec5SDimitry Andric typedef std::__hash_table<__value_type, __hasher, 758*0b57cec5SDimitry Andric __key_equal, __allocator_type> __table; 759*0b57cec5SDimitry Andric 760*0b57cec5SDimitry Andric __table __table_; 761*0b57cec5SDimitry Andric 762*0b57cec5SDimitry Andric typedef typename __table::__node_traits __node_traits; 763*0b57cec5SDimitry Andric typedef typename __table::__node_allocator __node_allocator; 764*0b57cec5SDimitry Andric typedef typename __table::__node __node; 765*0b57cec5SDimitry Andric typedef __hash_map_node_destructor<__node_allocator> _Dp; 766*0b57cec5SDimitry Andric typedef std::unique_ptr<__node, _Dp> __node_holder; 767*0b57cec5SDimitry Andric typedef std::allocator_traits<allocator_type> __alloc_traits; 768*0b57cec5SDimitry Andricpublic: 769*0b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 770*0b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 771*0b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 772*0b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 773*0b57cec5SDimitry Andric 774*0b57cec5SDimitry Andric typedef __hash_map_iterator<typename __table::iterator> iterator; 775*0b57cec5SDimitry Andric typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; 776*0b57cec5SDimitry Andric 777*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 778*0b57cec5SDimitry Andric hash_multimap() {__table_.rehash(193);} 779*0b57cec5SDimitry Andric explicit hash_multimap(size_type __n, const hasher& __hf = hasher(), 780*0b57cec5SDimitry Andric const key_equal& __eql = key_equal()); 781*0b57cec5SDimitry Andric hash_multimap(size_type __n, const hasher& __hf, 782*0b57cec5SDimitry Andric const key_equal& __eql, 783*0b57cec5SDimitry Andric const allocator_type& __a); 784*0b57cec5SDimitry Andric template <class _InputIterator> 785*0b57cec5SDimitry Andric hash_multimap(_InputIterator __first, _InputIterator __last); 786*0b57cec5SDimitry Andric template <class _InputIterator> 787*0b57cec5SDimitry Andric hash_multimap(_InputIterator __first, _InputIterator __last, 788*0b57cec5SDimitry Andric size_type __n, const hasher& __hf = hasher(), 789*0b57cec5SDimitry Andric const key_equal& __eql = key_equal()); 790*0b57cec5SDimitry Andric template <class _InputIterator> 791*0b57cec5SDimitry Andric hash_multimap(_InputIterator __first, _InputIterator __last, 792*0b57cec5SDimitry Andric size_type __n, const hasher& __hf, 793*0b57cec5SDimitry Andric const key_equal& __eql, 794*0b57cec5SDimitry Andric const allocator_type& __a); 795*0b57cec5SDimitry Andric hash_multimap(const hash_multimap& __u); 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 798*0b57cec5SDimitry Andric allocator_type get_allocator() const 799*0b57cec5SDimitry Andric {return allocator_type(__table_.__node_alloc());} 800*0b57cec5SDimitry Andric 801*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 802*0b57cec5SDimitry Andric bool empty() const {return __table_.size() == 0;} 803*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 804*0b57cec5SDimitry Andric size_type size() const {return __table_.size();} 805*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 806*0b57cec5SDimitry Andric size_type max_size() const {return __table_.max_size();} 807*0b57cec5SDimitry Andric 808*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 809*0b57cec5SDimitry Andric iterator begin() {return __table_.begin();} 810*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 811*0b57cec5SDimitry Andric iterator end() {return __table_.end();} 812*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 813*0b57cec5SDimitry Andric const_iterator begin() const {return __table_.begin();} 814*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 815*0b57cec5SDimitry Andric const_iterator end() const {return __table_.end();} 816*0b57cec5SDimitry Andric 817*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 818*0b57cec5SDimitry Andric iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} 819*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 820*0b57cec5SDimitry Andric iterator insert(const_iterator, const value_type& __x) {return insert(__x);} 821*0b57cec5SDimitry Andric template <class _InputIterator> 822*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 823*0b57cec5SDimitry Andric void insert(_InputIterator __first, _InputIterator __last); 824*0b57cec5SDimitry Andric 825*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 826*0b57cec5SDimitry Andric void erase(const_iterator __p) {__table_.erase(__p.__i_);} 827*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 828*0b57cec5SDimitry Andric size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} 829*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 830*0b57cec5SDimitry Andric void erase(const_iterator __first, const_iterator __last) 831*0b57cec5SDimitry Andric {__table_.erase(__first.__i_, __last.__i_);} 832*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 833*0b57cec5SDimitry Andric void clear() {__table_.clear();} 834*0b57cec5SDimitry Andric 835*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 836*0b57cec5SDimitry Andric void swap(hash_multimap& __u) {__table_.swap(__u.__table_);} 837*0b57cec5SDimitry Andric 838*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 839*0b57cec5SDimitry Andric hasher hash_funct() const 840*0b57cec5SDimitry Andric {return __table_.hash_function().hash_function();} 841*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 842*0b57cec5SDimitry Andric key_equal key_eq() const 843*0b57cec5SDimitry Andric {return __table_.key_eq().key_eq();} 844*0b57cec5SDimitry Andric 845*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 846*0b57cec5SDimitry Andric iterator find(const key_type& __k) {return __table_.find(__k);} 847*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 848*0b57cec5SDimitry Andric const_iterator find(const key_type& __k) const {return __table_.find(__k);} 849*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 850*0b57cec5SDimitry Andric size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} 851*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 852*0b57cec5SDimitry Andric std::pair<iterator, iterator> equal_range(const key_type& __k) 853*0b57cec5SDimitry Andric {return __table_.__equal_range_multi(__k);} 854*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 855*0b57cec5SDimitry Andric std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const 856*0b57cec5SDimitry Andric {return __table_.__equal_range_multi(__k);} 857*0b57cec5SDimitry Andric 858*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 859*0b57cec5SDimitry Andric size_type bucket_count() const {return __table_.bucket_count();} 860*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 861*0b57cec5SDimitry Andric size_type max_bucket_count() const {return __table_.max_bucket_count();} 862*0b57cec5SDimitry Andric 863*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 864*0b57cec5SDimitry Andric size_type elems_in_bucket(size_type __n) const 865*0b57cec5SDimitry Andric {return __table_.bucket_size(__n);} 866*0b57cec5SDimitry Andric 867*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 868*0b57cec5SDimitry Andric void resize(size_type __n) {__table_.rehash(__n);} 869*0b57cec5SDimitry Andric}; 870*0b57cec5SDimitry Andric 871*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 872*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 873*0b57cec5SDimitry Andric size_type __n, const hasher& __hf, const key_equal& __eql) 874*0b57cec5SDimitry Andric : __table_(__hf, __eql) 875*0b57cec5SDimitry Andric{ 876*0b57cec5SDimitry Andric __table_.rehash(__n); 877*0b57cec5SDimitry Andric} 878*0b57cec5SDimitry Andric 879*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 880*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 881*0b57cec5SDimitry Andric size_type __n, const hasher& __hf, const key_equal& __eql, 882*0b57cec5SDimitry Andric const allocator_type& __a) 883*0b57cec5SDimitry Andric : __table_(__hf, __eql, __a) 884*0b57cec5SDimitry Andric{ 885*0b57cec5SDimitry Andric __table_.rehash(__n); 886*0b57cec5SDimitry Andric} 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 889*0b57cec5SDimitry Andrictemplate <class _InputIterator> 890*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 891*0b57cec5SDimitry Andric _InputIterator __first, _InputIterator __last) 892*0b57cec5SDimitry Andric{ 893*0b57cec5SDimitry Andric __table_.rehash(193); 894*0b57cec5SDimitry Andric insert(__first, __last); 895*0b57cec5SDimitry Andric} 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 898*0b57cec5SDimitry Andrictemplate <class _InputIterator> 899*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 900*0b57cec5SDimitry Andric _InputIterator __first, _InputIterator __last, size_type __n, 901*0b57cec5SDimitry Andric const hasher& __hf, const key_equal& __eql) 902*0b57cec5SDimitry Andric : __table_(__hf, __eql) 903*0b57cec5SDimitry Andric{ 904*0b57cec5SDimitry Andric __table_.rehash(__n); 905*0b57cec5SDimitry Andric insert(__first, __last); 906*0b57cec5SDimitry Andric} 907*0b57cec5SDimitry Andric 908*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 909*0b57cec5SDimitry Andrictemplate <class _InputIterator> 910*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 911*0b57cec5SDimitry Andric _InputIterator __first, _InputIterator __last, size_type __n, 912*0b57cec5SDimitry Andric const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 913*0b57cec5SDimitry Andric : __table_(__hf, __eql, __a) 914*0b57cec5SDimitry Andric{ 915*0b57cec5SDimitry Andric __table_.rehash(__n); 916*0b57cec5SDimitry Andric insert(__first, __last); 917*0b57cec5SDimitry Andric} 918*0b57cec5SDimitry Andric 919*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 920*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 921*0b57cec5SDimitry Andric const hash_multimap& __u) 922*0b57cec5SDimitry Andric : __table_(__u.__table_) 923*0b57cec5SDimitry Andric{ 924*0b57cec5SDimitry Andric __table_.rehash(__u.bucket_count()); 925*0b57cec5SDimitry Andric insert(__u.begin(), __u.end()); 926*0b57cec5SDimitry Andric} 927*0b57cec5SDimitry Andric 928*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 929*0b57cec5SDimitry Andrictemplate <class _InputIterator> 930*0b57cec5SDimitry Andricinline 931*0b57cec5SDimitry Andricvoid 932*0b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, 933*0b57cec5SDimitry Andric _InputIterator __last) 934*0b57cec5SDimitry Andric{ 935*0b57cec5SDimitry Andric for (; __first != __last; ++__first) 936*0b57cec5SDimitry Andric __table_.__insert_multi(*__first); 937*0b57cec5SDimitry Andric} 938*0b57cec5SDimitry Andric 939*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 940*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 941*0b57cec5SDimitry Andricvoid 942*0b57cec5SDimitry Andricswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 943*0b57cec5SDimitry Andric hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 944*0b57cec5SDimitry Andric{ 945*0b57cec5SDimitry Andric __x.swap(__y); 946*0b57cec5SDimitry Andric} 947*0b57cec5SDimitry Andric 948*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 949*0b57cec5SDimitry Andricbool 950*0b57cec5SDimitry Andricoperator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 951*0b57cec5SDimitry Andric const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 952*0b57cec5SDimitry Andric{ 953*0b57cec5SDimitry Andric if (__x.size() != __y.size()) 954*0b57cec5SDimitry Andric return false; 955*0b57cec5SDimitry Andric typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator 956*0b57cec5SDimitry Andric const_iterator; 957*0b57cec5SDimitry Andric typedef std::pair<const_iterator, const_iterator> _EqRng; 958*0b57cec5SDimitry Andric for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) 959*0b57cec5SDimitry Andric { 960*0b57cec5SDimitry Andric _EqRng __xeq = __x.equal_range(__i->first); 961*0b57cec5SDimitry Andric _EqRng __yeq = __y.equal_range(__i->first); 962*0b57cec5SDimitry Andric if (_VSTD::distance(__xeq.first, __xeq.second) != 963*0b57cec5SDimitry Andric _VSTD::distance(__yeq.first, __yeq.second) || 964*0b57cec5SDimitry Andric !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) 965*0b57cec5SDimitry Andric return false; 966*0b57cec5SDimitry Andric __i = __xeq.second; 967*0b57cec5SDimitry Andric } 968*0b57cec5SDimitry Andric return true; 969*0b57cec5SDimitry Andric} 970*0b57cec5SDimitry Andric 971*0b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 972*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 973*0b57cec5SDimitry Andricbool 974*0b57cec5SDimitry Andricoperator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 975*0b57cec5SDimitry Andric const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 976*0b57cec5SDimitry Andric{ 977*0b57cec5SDimitry Andric return !(__x == __y); 978*0b57cec5SDimitry Andric} 979*0b57cec5SDimitry Andric 980*0b57cec5SDimitry Andric} // __gnu_cxx 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andric#endif // _LIBCPP_HASH_MAP 983