|
libstdc++
|
00001 // unordered_map implementation -*- C++ -*- 00002 00003 // Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/unordered_map.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{unordered_map} 00028 */ 00029 00030 #ifndef _UNORDERED_MAP_H 00031 #define _UNORDERED_MAP_H 00032 00033 namespace std _GLIBCXX_VISIBILITY(default) 00034 { 00035 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 00036 00037 // NB: When we get typedef templates these class definitions 00038 // will be unnecessary. 00039 template<class _Key, class _Tp, 00040 class _Hash = hash<_Key>, 00041 class _Pred = std::equal_to<_Key>, 00042 class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, 00043 bool __cache_hash_code = 00044 __not_<__and_<is_integral<_Key>, is_empty<_Hash>, 00045 integral_constant<bool, !__is_final(_Hash)>, 00046 __detail::__is_noexcept_hash<_Key, _Hash>>>::value> 00047 class __unordered_map 00048 : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, 00049 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 00050 _Hash, __detail::_Mod_range_hashing, 00051 __detail::_Default_ranged_hash, 00052 __detail::_Prime_rehash_policy, 00053 __cache_hash_code, false, true>, 00054 __check_copy_constructible<_Alloc> 00055 { 00056 typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, 00057 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 00058 _Hash, __detail::_Mod_range_hashing, 00059 __detail::_Default_ranged_hash, 00060 __detail::_Prime_rehash_policy, 00061 __cache_hash_code, false, true> 00062 _Base; 00063 00064 public: 00065 typedef typename _Base::value_type value_type; 00066 typedef typename _Base::size_type size_type; 00067 typedef typename _Base::hasher hasher; 00068 typedef typename _Base::key_equal key_equal; 00069 typedef typename _Base::allocator_type allocator_type; 00070 00071 explicit 00072 __unordered_map(size_type __n = 10, 00073 const hasher& __hf = hasher(), 00074 const key_equal& __eql = key_equal(), 00075 const allocator_type& __a = allocator_type()) 00076 : _Base(__n, __hf, __detail::_Mod_range_hashing(), 00077 __detail::_Default_ranged_hash(), 00078 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 00079 { } 00080 00081 template<typename _InputIterator> 00082 __unordered_map(_InputIterator __f, _InputIterator __l, 00083 size_type __n = 0, 00084 const hasher& __hf = hasher(), 00085 const key_equal& __eql = key_equal(), 00086 const allocator_type& __a = allocator_type()) 00087 : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), 00088 __detail::_Default_ranged_hash(), 00089 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 00090 { } 00091 00092 __unordered_map(initializer_list<value_type> __l, 00093 size_type __n = 0, 00094 const hasher& __hf = hasher(), 00095 const key_equal& __eql = key_equal(), 00096 const allocator_type& __a = allocator_type()) 00097 : _Base(__l.begin(), __l.end(), __n, __hf, 00098 __detail::_Mod_range_hashing(), 00099 __detail::_Default_ranged_hash(), 00100 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 00101 { } 00102 00103 __unordered_map& 00104 operator=(initializer_list<value_type> __l) 00105 { 00106 this->clear(); 00107 this->insert(__l.begin(), __l.end()); 00108 return *this; 00109 } 00110 }; 00111 00112 template<class _Key, class _Tp, 00113 class _Hash = hash<_Key>, 00114 class _Pred = std::equal_to<_Key>, 00115 class _Alloc = std::allocator<std::pair<const _Key, _Tp> >, 00116 bool __cache_hash_code = 00117 __not_<__and_<is_integral<_Key>, is_empty<_Hash>, 00118 integral_constant<bool, !__is_final(_Hash)>, 00119 __detail::__is_noexcept_hash<_Key, _Hash>>>::value> 00120 class __unordered_multimap 00121 : public _Hashtable<_Key, std::pair<const _Key, _Tp>, 00122 _Alloc, 00123 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 00124 _Hash, __detail::_Mod_range_hashing, 00125 __detail::_Default_ranged_hash, 00126 __detail::_Prime_rehash_policy, 00127 __cache_hash_code, false, false>, 00128 __check_copy_constructible<_Alloc> 00129 { 00130 typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, 00131 _Alloc, 00132 std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 00133 _Hash, __detail::_Mod_range_hashing, 00134 __detail::_Default_ranged_hash, 00135 __detail::_Prime_rehash_policy, 00136 __cache_hash_code, false, false> 00137 _Base; 00138 00139 public: 00140 typedef typename _Base::value_type value_type; 00141 typedef typename _Base::size_type size_type; 00142 typedef typename _Base::hasher hasher; 00143 typedef typename _Base::key_equal key_equal; 00144 typedef typename _Base::allocator_type allocator_type; 00145 00146 explicit 00147 __unordered_multimap(size_type __n = 10, 00148 const hasher& __hf = hasher(), 00149 const key_equal& __eql = key_equal(), 00150 const allocator_type& __a = allocator_type()) 00151 : _Base(__n, __hf, __detail::_Mod_range_hashing(), 00152 __detail::_Default_ranged_hash(), 00153 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 00154 { } 00155 00156 00157 template<typename _InputIterator> 00158 __unordered_multimap(_InputIterator __f, _InputIterator __l, 00159 size_type __n = 0, 00160 const hasher& __hf = hasher(), 00161 const key_equal& __eql = key_equal(), 00162 const allocator_type& __a = allocator_type()) 00163 : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), 00164 __detail::_Default_ranged_hash(), 00165 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 00166 { } 00167 00168 __unordered_multimap(initializer_list<value_type> __l, 00169 size_type __n = 0, 00170 const hasher& __hf = hasher(), 00171 const key_equal& __eql = key_equal(), 00172 const allocator_type& __a = allocator_type()) 00173 : _Base(__l.begin(), __l.end(), __n, __hf, 00174 __detail::_Mod_range_hashing(), 00175 __detail::_Default_ranged_hash(), 00176 __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) 00177 { } 00178 00179 __unordered_multimap& 00180 operator=(initializer_list<value_type> __l) 00181 { 00182 this->clear(); 00183 this->insert(__l.begin(), __l.end()); 00184 return *this; 00185 } 00186 }; 00187 00188 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 00189 bool __cache_hash_code> 00190 inline void 00191 swap(__unordered_map<_Key, _Tp, _Hash, _Pred, 00192 _Alloc, __cache_hash_code>& __x, 00193 __unordered_map<_Key, _Tp, _Hash, _Pred, 00194 _Alloc, __cache_hash_code>& __y) 00195 { __x.swap(__y); } 00196 00197 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 00198 bool __cache_hash_code> 00199 inline void 00200 swap(__unordered_multimap<_Key, _Tp, _Hash, _Pred, 00201 _Alloc, __cache_hash_code>& __x, 00202 __unordered_multimap<_Key, _Tp, _Hash, _Pred, 00203 _Alloc, __cache_hash_code>& __y) 00204 { __x.swap(__y); } 00205 00206 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 00207 bool __cache_hash_code> 00208 inline bool 00209 operator==(const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 00210 __cache_hash_code>& __x, 00211 const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 00212 __cache_hash_code>& __y) 00213 { return __x._M_equal(__y); } 00214 00215 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 00216 bool __cache_hash_code> 00217 inline bool 00218 operator!=(const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 00219 __cache_hash_code>& __x, 00220 const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc, 00221 __cache_hash_code>& __y) 00222 { return !(__x == __y); } 00223 00224 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 00225 bool __cache_hash_code> 00226 inline bool 00227 operator==(const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 00228 __cache_hash_code>& __x, 00229 const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 00230 __cache_hash_code>& __y) 00231 { return __x._M_equal(__y); } 00232 00233 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, 00234 bool __cache_hash_code> 00235 inline bool 00236 operator!=(const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 00237 __cache_hash_code>& __x, 00238 const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc, 00239 __cache_hash_code>& __y) 00240 { return !(__x == __y); } 00241 00242 /** 00243 * @brief A standard container composed of unique keys (containing 00244 * at most one of each key value) that associates values of another type 00245 * with the keys. 00246 * 00247 * @ingroup unordered_associative_containers 00248 * 00249 * Meets the requirements of a <a href="tables.html#65">container</a>, and 00250 * <a href="tables.html#xx">unordered associative container</a> 00251 * 00252 * @param Key Type of key objects. 00253 * @param Tp Type of mapped objects. 00254 * @param Hash Hashing function object type, defaults to hash<Value>. 00255 * @param Pred Predicate function object type, defaults to equal_to<Value>. 00256 * @param Alloc Allocator type, defaults to allocator<Key>. 00257 * 00258 * The resulting value type of the container is std::pair<const Key, Tp>. 00259 */ 00260 template<class _Key, class _Tp, 00261 class _Hash = hash<_Key>, 00262 class _Pred = std::equal_to<_Key>, 00263 class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 00264 class unordered_map 00265 : public __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> 00266 { 00267 typedef __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> _Base; 00268 00269 public: 00270 typedef typename _Base::value_type value_type; 00271 typedef typename _Base::size_type size_type; 00272 typedef typename _Base::hasher hasher; 00273 typedef typename _Base::key_equal key_equal; 00274 typedef typename _Base::allocator_type allocator_type; 00275 00276 explicit 00277 unordered_map(size_type __n = 10, 00278 const hasher& __hf = hasher(), 00279 const key_equal& __eql = key_equal(), 00280 const allocator_type& __a = allocator_type()) 00281 : _Base(__n, __hf, __eql, __a) 00282 { } 00283 00284 template<typename _InputIterator> 00285 unordered_map(_InputIterator __f, _InputIterator __l, 00286 size_type __n = 0, 00287 const hasher& __hf = hasher(), 00288 const key_equal& __eql = key_equal(), 00289 const allocator_type& __a = allocator_type()) 00290 : _Base(__f, __l, __n, __hf, __eql, __a) 00291 { } 00292 00293 unordered_map(initializer_list<value_type> __l, 00294 size_type __n = 0, 00295 const hasher& __hf = hasher(), 00296 const key_equal& __eql = key_equal(), 00297 const allocator_type& __a = allocator_type()) 00298 : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a) 00299 { } 00300 00301 unordered_map& 00302 operator=(initializer_list<value_type> __l) 00303 { 00304 this->clear(); 00305 this->insert(__l.begin(), __l.end()); 00306 return *this; 00307 } 00308 }; 00309 00310 /** 00311 * @brief A standard container composed of equivalent keys 00312 * (possibly containing multiple of each key value) that associates 00313 * values of another type with the keys. 00314 * 00315 * @ingroup unordered_associative_containers 00316 * 00317 * Meets the requirements of a <a href="tables.html#65">container</a>, and 00318 * <a href="tables.html#xx">unordered associative container</a> 00319 * 00320 * @param Key Type of key objects. 00321 * @param Tp Type of mapped objects. 00322 * @param Hash Hashing function object type, defaults to hash<Value>. 00323 * @param Pred Predicate function object type, defaults to equal_to<Value>. 00324 * @param Alloc Allocator type, defaults to allocator<Key>. 00325 * 00326 * The resulting value type of the container is std::pair<const Key, Tp>. 00327 */ 00328 template<class _Key, class _Tp, 00329 class _Hash = hash<_Key>, 00330 class _Pred = std::equal_to<_Key>, 00331 class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 00332 class unordered_multimap 00333 : public __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> 00334 { 00335 typedef __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> _Base; 00336 00337 public: 00338 typedef typename _Base::value_type value_type; 00339 typedef typename _Base::size_type size_type; 00340 typedef typename _Base::hasher hasher; 00341 typedef typename _Base::key_equal key_equal; 00342 typedef typename _Base::allocator_type allocator_type; 00343 00344 explicit 00345 unordered_multimap(size_type __n = 10, 00346 const hasher& __hf = hasher(), 00347 const key_equal& __eql = key_equal(), 00348 const allocator_type& __a = allocator_type()) 00349 : _Base(__n, __hf, __eql, __a) 00350 { } 00351 00352 template<typename _InputIterator> 00353 unordered_multimap(_InputIterator __f, _InputIterator __l, 00354 size_type __n = 0, 00355 const hasher& __hf = hasher(), 00356 const key_equal& __eql = key_equal(), 00357 const allocator_type& __a = allocator_type()) 00358 : _Base(__f, __l, __n, __hf, __eql, __a) 00359 { } 00360 00361 unordered_multimap(initializer_list<value_type> __l, 00362 size_type __n = 0, 00363 const hasher& __hf = hasher(), 00364 const key_equal& __eql = key_equal(), 00365 const allocator_type& __a = allocator_type()) 00366 : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a) 00367 { } 00368 00369 unordered_multimap& 00370 operator=(initializer_list<value_type> __l) 00371 { 00372 this->clear(); 00373 this->insert(__l.begin(), __l.end()); 00374 return *this; 00375 } 00376 }; 00377 00378 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 00379 inline void 00380 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00381 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00382 { __x.swap(__y); } 00383 00384 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 00385 inline void 00386 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00387 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00388 { __x.swap(__y); } 00389 00390 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 00391 inline bool 00392 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00393 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00394 { return __x._M_equal(__y); } 00395 00396 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 00397 inline bool 00398 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00399 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00400 { return !(__x == __y); } 00401 00402 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 00403 inline bool 00404 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00405 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00406 { return __x._M_equal(__y); } 00407 00408 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 00409 inline bool 00410 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00411 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00412 { return !(__x == __y); } 00413 00414 _GLIBCXX_END_NAMESPACE_CONTAINER 00415 } // namespace std 00416 00417 #endif /* _UNORDERED_MAP_H */