|
libstdc++
|
00001 // unordered_set 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_set.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{unordered_set} 00028 */ 00029 00030 #ifndef _UNORDERED_SET_H 00031 #define _UNORDERED_SET_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 _Value, 00040 class _Hash = hash<_Value>, 00041 class _Pred = std::equal_to<_Value>, 00042 class _Alloc = std::allocator<_Value>, 00043 bool __cache_hash_code = 00044 __not_<__and_<is_integral<_Value>, is_empty<_Hash>, 00045 integral_constant<bool, !__is_final(_Hash)>, 00046 __detail::__is_noexcept_hash<_Value, _Hash>>>::value> 00047 class __unordered_set 00048 : public _Hashtable<_Value, _Value, _Alloc, 00049 std::_Identity<_Value>, _Pred, 00050 _Hash, __detail::_Mod_range_hashing, 00051 __detail::_Default_ranged_hash, 00052 __detail::_Prime_rehash_policy, 00053 __cache_hash_code, true, true>, 00054 __check_copy_constructible<_Alloc> 00055 { 00056 typedef _Hashtable<_Value, _Value, _Alloc, 00057 std::_Identity<_Value>, _Pred, 00058 _Hash, __detail::_Mod_range_hashing, 00059 __detail::_Default_ranged_hash, 00060 __detail::_Prime_rehash_policy, 00061 __cache_hash_code, true, 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 typedef typename _Base::iterator iterator; 00071 typedef typename _Base::const_iterator const_iterator; 00072 00073 explicit 00074 __unordered_set(size_type __n = 10, 00075 const hasher& __hf = hasher(), 00076 const key_equal& __eql = key_equal(), 00077 const allocator_type& __a = allocator_type()) 00078 : _Base(__n, __hf, __detail::_Mod_range_hashing(), 00079 __detail::_Default_ranged_hash(), __eql, 00080 std::_Identity<value_type>(), __a) 00081 { } 00082 00083 template<typename _InputIterator> 00084 __unordered_set(_InputIterator __f, _InputIterator __l, 00085 size_type __n = 0, 00086 const hasher& __hf = hasher(), 00087 const key_equal& __eql = key_equal(), 00088 const allocator_type& __a = allocator_type()) 00089 : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), 00090 __detail::_Default_ranged_hash(), __eql, 00091 std::_Identity<value_type>(), __a) 00092 { } 00093 00094 __unordered_set(initializer_list<value_type> __l, 00095 size_type __n = 0, 00096 const hasher& __hf = hasher(), 00097 const key_equal& __eql = key_equal(), 00098 const allocator_type& __a = allocator_type()) 00099 : _Base(__l.begin(), __l.end(), __n, __hf, 00100 __detail::_Mod_range_hashing(), 00101 __detail::_Default_ranged_hash(), __eql, 00102 std::_Identity<value_type>(), __a) 00103 { } 00104 00105 __unordered_set& 00106 operator=(initializer_list<value_type> __l) 00107 { 00108 this->clear(); 00109 this->insert(__l.begin(), __l.end()); 00110 return *this; 00111 } 00112 00113 using _Base::insert; 00114 00115 std::pair<iterator, bool> 00116 insert(value_type&& __v) 00117 { return this->_M_insert(std::move(__v), std::true_type()); } 00118 00119 iterator 00120 insert(const_iterator, value_type&& __v) 00121 { return insert(std::move(__v)).first; } 00122 }; 00123 00124 template<class _Value, 00125 class _Hash = hash<_Value>, 00126 class _Pred = std::equal_to<_Value>, 00127 class _Alloc = std::allocator<_Value>, 00128 bool __cache_hash_code = 00129 __not_<__and_<is_integral<_Value>, is_empty<_Hash>, 00130 integral_constant<bool, !__is_final(_Hash)>, 00131 __detail::__is_noexcept_hash<_Value, _Hash>>>::value> 00132 class __unordered_multiset 00133 : public _Hashtable<_Value, _Value, _Alloc, 00134 std::_Identity<_Value>, _Pred, 00135 _Hash, __detail::_Mod_range_hashing, 00136 __detail::_Default_ranged_hash, 00137 __detail::_Prime_rehash_policy, 00138 __cache_hash_code, true, false>, 00139 __check_copy_constructible<_Alloc> 00140 { 00141 typedef _Hashtable<_Value, _Value, _Alloc, 00142 std::_Identity<_Value>, _Pred, 00143 _Hash, __detail::_Mod_range_hashing, 00144 __detail::_Default_ranged_hash, 00145 __detail::_Prime_rehash_policy, 00146 __cache_hash_code, true, false> 00147 _Base; 00148 00149 public: 00150 typedef typename _Base::value_type value_type; 00151 typedef typename _Base::size_type size_type; 00152 typedef typename _Base::hasher hasher; 00153 typedef typename _Base::key_equal key_equal; 00154 typedef typename _Base::allocator_type allocator_type; 00155 typedef typename _Base::iterator iterator; 00156 typedef typename _Base::const_iterator const_iterator; 00157 00158 explicit 00159 __unordered_multiset(size_type __n = 10, 00160 const hasher& __hf = hasher(), 00161 const key_equal& __eql = key_equal(), 00162 const allocator_type& __a = allocator_type()) 00163 : _Base(__n, __hf, __detail::_Mod_range_hashing(), 00164 __detail::_Default_ranged_hash(), __eql, 00165 std::_Identity<value_type>(), __a) 00166 { } 00167 00168 00169 template<typename _InputIterator> 00170 __unordered_multiset(_InputIterator __f, _InputIterator __l, 00171 size_type __n = 0, 00172 const hasher& __hf = hasher(), 00173 const key_equal& __eql = key_equal(), 00174 const allocator_type& __a = allocator_type()) 00175 : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), 00176 __detail::_Default_ranged_hash(), __eql, 00177 std::_Identity<value_type>(), __a) 00178 { } 00179 00180 __unordered_multiset(initializer_list<value_type> __l, 00181 size_type __n = 0, 00182 const hasher& __hf = hasher(), 00183 const key_equal& __eql = key_equal(), 00184 const allocator_type& __a = allocator_type()) 00185 : _Base(__l.begin(), __l.end(), __n, __hf, 00186 __detail::_Mod_range_hashing(), 00187 __detail::_Default_ranged_hash(), __eql, 00188 std::_Identity<value_type>(), __a) 00189 { } 00190 00191 __unordered_multiset& 00192 operator=(initializer_list<value_type> __l) 00193 { 00194 this->clear(); 00195 this->insert(__l.begin(), __l.end()); 00196 return *this; 00197 } 00198 00199 using _Base::insert; 00200 00201 iterator 00202 insert(value_type&& __v) 00203 { return this->_M_insert(std::move(__v), std::false_type()); } 00204 00205 iterator 00206 insert(const_iterator, value_type&& __v) 00207 { return insert(std::move(__v)); } 00208 }; 00209 00210 template<class _Value, class _Hash, class _Pred, class _Alloc, 00211 bool __cache_hash_code> 00212 inline void 00213 swap(__unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __x, 00214 __unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __y) 00215 { __x.swap(__y); } 00216 00217 template<class _Value, class _Hash, class _Pred, class _Alloc, 00218 bool __cache_hash_code> 00219 inline void 00220 swap(__unordered_multiset<_Value, _Hash, _Pred, 00221 _Alloc, __cache_hash_code>& __x, 00222 __unordered_multiset<_Value, _Hash, _Pred, 00223 _Alloc, __cache_hash_code>& __y) 00224 { __x.swap(__y); } 00225 00226 template<class _Value, class _Hash, class _Pred, class _Alloc, 00227 bool __cache_hash_code> 00228 inline bool 00229 operator==(const __unordered_set<_Value, _Hash, _Pred, _Alloc, 00230 __cache_hash_code>& __x, 00231 const __unordered_set<_Value, _Hash, _Pred, _Alloc, 00232 __cache_hash_code>& __y) 00233 { return __x._M_equal(__y); } 00234 00235 template<class _Value, class _Hash, class _Pred, class _Alloc, 00236 bool __cache_hash_code> 00237 inline bool 00238 operator!=(const __unordered_set<_Value, _Hash, _Pred, _Alloc, 00239 __cache_hash_code>& __x, 00240 const __unordered_set<_Value, _Hash, _Pred, _Alloc, 00241 __cache_hash_code>& __y) 00242 { return !(__x == __y); } 00243 00244 template<class _Value, class _Hash, class _Pred, class _Alloc, 00245 bool __cache_hash_code> 00246 inline bool 00247 operator==(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc, 00248 __cache_hash_code>& __x, 00249 const __unordered_multiset<_Value, _Hash, _Pred, _Alloc, 00250 __cache_hash_code>& __y) 00251 { return __x._M_equal(__y); } 00252 00253 template<class _Value, class _Hash, class _Pred, class _Alloc, 00254 bool __cache_hash_code> 00255 inline bool 00256 operator!=(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc, 00257 __cache_hash_code>& __x, 00258 const __unordered_multiset<_Value, _Hash, _Pred, _Alloc, 00259 __cache_hash_code>& __y) 00260 { return !(__x == __y); } 00261 00262 /** 00263 * @brief A standard container composed of unique keys (containing 00264 * at most one of each key value) in which the elements' keys are 00265 * the elements themselves. 00266 * 00267 * @ingroup unordered_associative_containers 00268 * 00269 * Meets the requirements of a <a href="tables.html#65">container</a>, and 00270 * <a href="tables.html#xx">unordered associative container</a> 00271 * 00272 * @param Value Type of key objects. 00273 * @param Hash Hashing function object type, defaults to hash<Value>. 00274 * @param Pred Predicate function object type, defaults to equal_to<Value>. 00275 * @param Alloc Allocator type, defaults to allocator<Key>. 00276 */ 00277 template<class _Value, 00278 class _Hash = hash<_Value>, 00279 class _Pred = std::equal_to<_Value>, 00280 class _Alloc = std::allocator<_Value> > 00281 class unordered_set 00282 : public __unordered_set<_Value, _Hash, _Pred, _Alloc> 00283 { 00284 typedef __unordered_set<_Value, _Hash, _Pred, _Alloc> _Base; 00285 00286 public: 00287 typedef typename _Base::value_type value_type; 00288 typedef typename _Base::size_type size_type; 00289 typedef typename _Base::hasher hasher; 00290 typedef typename _Base::key_equal key_equal; 00291 typedef typename _Base::allocator_type allocator_type; 00292 00293 explicit 00294 unordered_set(size_type __n = 10, 00295 const hasher& __hf = hasher(), 00296 const key_equal& __eql = key_equal(), 00297 const allocator_type& __a = allocator_type()) 00298 : _Base(__n, __hf, __eql, __a) 00299 { } 00300 00301 template<typename _InputIterator> 00302 unordered_set(_InputIterator __f, _InputIterator __l, 00303 size_type __n = 0, 00304 const hasher& __hf = hasher(), 00305 const key_equal& __eql = key_equal(), 00306 const allocator_type& __a = allocator_type()) 00307 : _Base(__f, __l, __n, __hf, __eql, __a) 00308 { } 00309 00310 unordered_set(initializer_list<value_type> __l, 00311 size_type __n = 0, 00312 const hasher& __hf = hasher(), 00313 const key_equal& __eql = key_equal(), 00314 const allocator_type& __a = allocator_type()) 00315 : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a) 00316 { } 00317 00318 unordered_set& 00319 operator=(initializer_list<value_type> __l) 00320 { 00321 this->clear(); 00322 this->insert(__l.begin(), __l.end()); 00323 return *this; 00324 } 00325 }; 00326 00327 /** 00328 * @brief A standard container composed of equivalent keys 00329 * (possibly containing multiple of each key value) in which the 00330 * elements' keys are the elements themselves. 00331 * 00332 * @ingroup unordered_associative_containers 00333 * 00334 * Meets the requirements of a <a href="tables.html#65">container</a>, and 00335 * <a href="tables.html#xx">unordered associative container</a> 00336 * 00337 * @param Value Type of key objects. 00338 * @param Hash Hashing function object type, defaults to hash<Value>. 00339 * @param Pred Predicate function object type, defaults to equal_to<Value>. 00340 * @param Alloc Allocator type, defaults to allocator<Key>. 00341 */ 00342 template<class _Value, 00343 class _Hash = hash<_Value>, 00344 class _Pred = std::equal_to<_Value>, 00345 class _Alloc = std::allocator<_Value> > 00346 class unordered_multiset 00347 : public __unordered_multiset<_Value, _Hash, _Pred, _Alloc> 00348 { 00349 typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc> _Base; 00350 00351 public: 00352 typedef typename _Base::value_type value_type; 00353 typedef typename _Base::size_type size_type; 00354 typedef typename _Base::hasher hasher; 00355 typedef typename _Base::key_equal key_equal; 00356 typedef typename _Base::allocator_type allocator_type; 00357 00358 explicit 00359 unordered_multiset(size_type __n = 10, 00360 const hasher& __hf = hasher(), 00361 const key_equal& __eql = key_equal(), 00362 const allocator_type& __a = allocator_type()) 00363 : _Base(__n, __hf, __eql, __a) 00364 { } 00365 00366 00367 template<typename _InputIterator> 00368 unordered_multiset(_InputIterator __f, _InputIterator __l, 00369 size_type __n = 0, 00370 const hasher& __hf = hasher(), 00371 const key_equal& __eql = key_equal(), 00372 const allocator_type& __a = allocator_type()) 00373 : _Base(__f, __l, __n, __hf, __eql, __a) 00374 { } 00375 00376 unordered_multiset(initializer_list<value_type> __l, 00377 size_type __n = 0, 00378 const hasher& __hf = hasher(), 00379 const key_equal& __eql = key_equal(), 00380 const allocator_type& __a = allocator_type()) 00381 : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a) 00382 { } 00383 00384 unordered_multiset& 00385 operator=(initializer_list<value_type> __l) 00386 { 00387 this->clear(); 00388 this->insert(__l.begin(), __l.end()); 00389 return *this; 00390 } 00391 }; 00392 00393 template<class _Value, class _Hash, class _Pred, class _Alloc> 00394 inline void 00395 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, 00396 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) 00397 { __x.swap(__y); } 00398 00399 template<class _Value, class _Hash, class _Pred, class _Alloc> 00400 inline void 00401 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 00402 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 00403 { __x.swap(__y); } 00404 00405 template<class _Value, class _Hash, class _Pred, class _Alloc> 00406 inline bool 00407 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, 00408 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) 00409 { return __x._M_equal(__y); } 00410 00411 template<class _Value, class _Hash, class _Pred, class _Alloc> 00412 inline bool 00413 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, 00414 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) 00415 { return !(__x == __y); } 00416 00417 template<class _Value, class _Hash, class _Pred, class _Alloc> 00418 inline bool 00419 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 00420 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 00421 { return __x._M_equal(__y); } 00422 00423 template<class _Value, class _Hash, class _Pred, class _Alloc> 00424 inline bool 00425 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 00426 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 00427 { return !(__x == __y); } 00428 00429 _GLIBCXX_END_NAMESPACE_CONTAINER 00430 } // namespace std 00431 00432 #endif /* _UNORDERED_SET_H */ 00433