1 // unordered_map implementation -*- C++ -*- 2 3 // Copyright (C) 2010, 2011 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file bits/unordered_map.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{unordered_map} 28 */ 29 30 #ifndef _UNORDERED_MAP_H 31 #define _UNORDERED_MAP_H 32 33 namespace std _GLIBCXX_VISIBILITY(default) 34 { 35 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 36 37 // NB: When we get typedef templates these class definitions 38 // will be unnecessary. 39 template<class _Key, class _Tp, 40 class _Hash = hash<_Key>, 41 class _Pred = std::equal_to<_Key>, 42 class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, 43 bool __cache_hash_code = 44 __not_<__and_<is_integral<_Key>, is_empty<_Hash>, 45 integral_constant<bool, !__is_final(_Hash)>, 46 __detail::__is_noexcept_hash<_Key, _Hash>>>::value> 47 class __unordered_map 48 : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, 49 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 50 _Hash, __detail::_Mod_range_hashing, 51 __detail::_Default_ranged_hash, 52 __detail::_Prime_rehash_policy, 53 __cache_hash_code, false, true> 54 { 55 typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, 56 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 57 _Hash, __detail::_Mod_range_hashing, 58 __detail::_Default_ranged_hash, 59 __detail::_Prime_rehash_policy, 60 __cache_hash_code, false, true> 61 _Base; 62 63 public: 64 typedef typename _Base::value_type value_type; 65 typedef typename _Base::size_type size_type; 66 typedef typename _Base::hasher hasher; 67 typedef typename _Base::key_equal key_equal; 68 typedef typename _Base::allocator_type allocator_type; 69 70 explicit 71 __unordered_map(size_type __n = 10, 72 const hasher& __hf = hasher(), 73 const key_equal& __eql = key_equal(), 74 const allocator_type& __a = allocator_type()) 75 : _Base(__n, __hf, __detail::_Mod_range_hashing(), 76 __detail::_Default_ranged_hash(), 77 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 78 { } 79 80 template<typename _InputIterator> 81 __unordered_map(_InputIterator __f, _InputIterator __l, 82 size_type __n = 0, 83 const hasher& __hf = hasher(), 84 const key_equal& __eql = key_equal(), 85 const allocator_type& __a = allocator_type()) 86 : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), 87 __detail::_Default_ranged_hash(), 88 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 89 { } 90 91 __unordered_map(initializer_list<value_type> __l, 92 size_type __n = 0, 93 const hasher& __hf = hasher(), 94 const key_equal& __eql = key_equal(), 95 const allocator_type& __a = allocator_type()) 96 : _Base(__l.begin(), __l.end(), __n, __hf, 97 __detail::_Mod_range_hashing(), 98 __detail::_Default_ranged_hash(), 99 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 100 { } 101 102 __unordered_map& 103 operator=(initializer_list<value_type> __l) 104 { 105 this->clear(); 106 this->insert(__l.begin(), __l.end()); 107 return *this; 108 } 109 }; 110 111 template<class _Key, class _Tp, 112 class _Hash = hash<_Key>, 113 class _Pred = std::equal_to<_Key>, 114 class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, 115 bool __cache_hash_code = 116 __not_<__and_<is_integral<_Key>, is_empty<_Hash>, 117 integral_constant<bool, !__is_final(_Hash)>, 118 __detail::__is_noexcept_hash<_Key, _Hash>>>::value> 119 class __unordered_multimap 120 : public _Hashtable<_Key, std::pair<const _Key, _Tp>, 121 _Alloc, 122 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 123 _Hash, __detail::_Mod_range_hashing, 124 __detail::_Default_ranged_hash, 125 __detail::_Prime_rehash_policy, 126 __cache_hash_code, false, false> 127 { 128 typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, 129 _Alloc, 130 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 131 _Hash, __detail::_Mod_range_hashing, 132 __detail::_Default_ranged_hash, 133 __detail::_Prime_rehash_policy, 134 __cache_hash_code, false, false> 135 _Base; 136 137 public: 138 typedef typename _Base::value_type value_type; 139 typedef typename _Base::size_type size_type; 140 typedef typename _Base::hasher hasher; 141 typedef typename _Base::key_equal key_equal; 142 typedef typename _Base::allocator_type allocator_type; 143 144 explicit 145 __unordered_multimap(size_type __n = 10, 146 const hasher& __hf = hasher(), 147 const key_equal& __eql = key_equal(), 148 const allocator_type& __a = allocator_type()) 149 : _Base(__n, __hf, __detail::_Mod_range_hashing(), 150 __detail::_Default_ranged_hash(), 151 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 152 { } 153 154 155 template<typename _InputIterator> 156 __unordered_multimap(_InputIterator __f, _InputIterator __l, 157 size_type __n = 0, 158 const hasher& __hf = hasher(), 159 const key_equal& __eql = key_equal(), 160 const allocator_type& __a = allocator_type()) 161 : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), 162 __detail::_Default_ranged_hash(), 163 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 164 { } 165 166 __unordered_multimap(initializer_list<value_type> __l, 167 size_type __n = 0, 168 const hasher& __hf = hasher(), 169 const key_equal& __eql = key_equal(), 170 const allocator_type& __a = allocator_type()) 171 : _Base(__l.begin(), __l.end(), __n, __hf, 172 __detail::_Mod_range_hashing(), 173 __detail::_Default_ranged_hash(), 174 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 175 { } 176 177 __unordered_multimap& 178 operator=(initializer_list<value_type> __l) 179 { 180 this->clear(); 181 this->insert(__l.begin(), __l.end()); 182 return *this; 183 } 184 }; 185 186 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 187 bool __cache_hash_code> 188 inline void 189 swap(__unordered_map<_Key, _Tp, _Hash, _Pred, 190 _Alloc, __cache_hash_code>& __x, 191 __unordered_map<_Key, _Tp, _Hash, _Pred, 192 _Alloc, __cache_hash_code>& __y) 193 { __x.swap(__y); } 194 195 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 196 bool __cache_hash_code> 197 inline void 198 swap(__unordered_multimap<_Key, _Tp, _Hash, _Pred, 199 _Alloc, __cache_hash_code>& __x, 200 __unordered_multimap<_Key, _Tp, _Hash, _Pred, 201 _Alloc, __cache_hash_code>& __y) 202 { __x.swap(__y); } 203 204 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 205 bool __cache_hash_code> 206 inline bool 207 operator==(const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 208 __cache_hash_code>& __x, 209 const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 210 __cache_hash_code>& __y) 211 { return __x._M_equal(__y); } 212 213 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 214 bool __cache_hash_code> 215 inline bool 216 operator!=(const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 217 __cache_hash_code>& __x, 218 const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 219 __cache_hash_code>& __y) 220 { return !(__x == __y); } 221 222 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 223 bool __cache_hash_code> 224 inline bool 225 operator==(const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 226 __cache_hash_code>& __x, 227 const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 228 __cache_hash_code>& __y) 229 { return __x._M_equal(__y); } 230 231 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 232 bool __cache_hash_code> 233 inline bool 234 operator!=(const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 235 __cache_hash_code>& __x, 236 const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 237 __cache_hash_code>& __y) 238 { return !(__x == __y); } 239 240 /** 241 * @brief A standard container composed of unique keys (containing 242 * at most one of each key value) that associates values of another type 243 * with the keys. 244 * 245 * @ingroup unordered_associative_containers 246 * 247 * Meets the requirements of a <a href="tables.html#65">container</a>, and 248 * <a href="tables.html#xx">unordered associative container</a> 249 * 250 * @param Key Type of key objects. 251 * @param Tp Type of mapped objects. 252 * @param Hash Hashing function object type, defaults to hash<Value>. 253 * @param Pred Predicate function object type, defaults to equal_to<Value>. 254 * @param Alloc Allocator type, defaults to allocator<Key>. 255 * 256 * The resulting value type of the container is std::pair<const Key, Tp>. 257 */ 258 template<class _Key, class _Tp, 259 class _Hash = hash<_Key>, 260 class _Pred = std::equal_to<_Key>, 261 class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 262 class unordered_map 263 : public __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> 264 { 265 typedef __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> _Base; 266 267 public: 268 typedef typename _Base::value_type value_type; 269 typedef typename _Base::size_type size_type; 270 typedef typename _Base::hasher hasher; 271 typedef typename _Base::key_equal key_equal; 272 typedef typename _Base::allocator_type allocator_type; 273 274 explicit 275 unordered_map(size_type __n = 10, 276 const hasher& __hf = hasher(), 277 const key_equal& __eql = key_equal(), 278 const allocator_type& __a = allocator_type()) 279 : _Base(__n, __hf, __eql, __a) 280 { } 281 282 template<typename _InputIterator> 283 unordered_map(_InputIterator __f, _InputIterator __l, 284 size_type __n = 0, 285 const hasher& __hf = hasher(), 286 const key_equal& __eql = key_equal(), 287 const allocator_type& __a = allocator_type()) 288 : _Base(__f, __l, __n, __hf, __eql, __a) 289 { } 290 291 unordered_map(initializer_list<value_type> __l, 292 size_type __n = 0, 293 const hasher& __hf = hasher(), 294 const key_equal& __eql = key_equal(), 295 const allocator_type& __a = allocator_type()) 296 : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a) 297 { } 298 299 unordered_map& 300 operator=(initializer_list<value_type> __l) 301 { 302 this->clear(); 303 this->insert(__l.begin(), __l.end()); 304 return *this; 305 } 306 }; 307 308 /** 309 * @brief A standard container composed of equivalent keys 310 * (possibly containing multiple of each key value) that associates 311 * values of another type with the keys. 312 * 313 * @ingroup unordered_associative_containers 314 * 315 * Meets the requirements of a <a href="tables.html#65">container</a>, and 316 * <a href="tables.html#xx">unordered associative container</a> 317 * 318 * @param Key Type of key objects. 319 * @param Tp Type of mapped objects. 320 * @param Hash Hashing function object type, defaults to hash<Value>. 321 * @param Pred Predicate function object type, defaults to equal_to<Value>. 322 * @param Alloc Allocator type, defaults to allocator<Key>. 323 * 324 * The resulting value type of the container is std::pair<const Key, Tp>. 325 */ 326 template<class _Key, class _Tp, 327 class _Hash = hash<_Key>, 328 class _Pred = std::equal_to<_Key>, 329 class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 330 class unordered_multimap 331 : public __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> 332 { 333 typedef __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> _Base; 334 335 public: 336 typedef typename _Base::value_type value_type; 337 typedef typename _Base::size_type size_type; 338 typedef typename _Base::hasher hasher; 339 typedef typename _Base::key_equal key_equal; 340 typedef typename _Base::allocator_type allocator_type; 341 342 explicit 343 unordered_multimap(size_type __n = 10, 344 const hasher& __hf = hasher(), 345 const key_equal& __eql = key_equal(), 346 const allocator_type& __a = allocator_type()) 347 : _Base(__n, __hf, __eql, __a) 348 { } 349 350 template<typename _InputIterator> 351 unordered_multimap(_InputIterator __f, _InputIterator __l, 352 size_type __n = 0, 353 const hasher& __hf = hasher(), 354 const key_equal& __eql = key_equal(), 355 const allocator_type& __a = allocator_type()) 356 : _Base(__f, __l, __n, __hf, __eql, __a) 357 { } 358 359 unordered_multimap(initializer_list<value_type> __l, 360 size_type __n = 0, 361 const hasher& __hf = hasher(), 362 const key_equal& __eql = key_equal(), 363 const allocator_type& __a = allocator_type()) 364 : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a) 365 { } 366 367 unordered_multimap& 368 operator=(initializer_list<value_type> __l) 369 { 370 this->clear(); 371 this->insert(__l.begin(), __l.end()); 372 return *this; 373 } 374 }; 375 376 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 377 inline void 378 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 379 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 380 { __x.swap(__y); } 381 382 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 383 inline void 384 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 385 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 386 { __x.swap(__y); } 387 388 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 389 inline bool 390 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 391 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 392 { return __x._M_equal(__y); } 393 394 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 395 inline bool 396 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 397 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 398 { return !(__x == __y); } 399 400 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 401 inline bool 402 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 403 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 404 { return __x._M_equal(__y); } 405 406 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 407 inline bool 408 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 409 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 410 { return !(__x == __y); } 411 412 _GLIBCXX_END_NAMESPACE_CONTAINER 413 } // namespace std 414 415 #endif /* _UNORDERED_MAP_H */ 416