00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef _GLIBCXX_PROFILE_UNORDERED_SET
00035 #define _GLIBCXX_PROFILE_UNORDERED_SET 1
00036
00037 #include <profile/base.h>
00038
00039 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00040 # include <unordered_set>
00041 #else
00042 # include <bits/c++0x_warning.h>
00043 #endif
00044
00045 #include <initializer_list>
00046
00047 #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
00048 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00049
00050 namespace std
00051 {
00052 namespace __profile
00053 {
00054
00055 template<typename _Key,
00056 typename _Hash = std::hash<_Key>,
00057 typename _Pred = std::equal_to<_Key>,
00058 typename _Alloc = std::allocator<_Key> >
00059 class unordered_set
00060 : public _GLIBCXX_STD_BASE
00061 {
00062 typedef typename _GLIBCXX_STD_BASE _Base;
00063
00064 public:
00065 typedef typename _Base::size_type size_type;
00066 typedef typename _Base::hasher hasher;
00067 typedef typename _Base::key_equal key_equal;
00068 typedef typename _Base::allocator_type allocator_type;
00069 typedef typename _Base::key_type key_type;
00070 typedef typename _Base::value_type value_type;
00071 typedef typename _Base::difference_type difference_type;
00072 typedef typename _Base::reference reference;
00073 typedef typename _Base::const_reference const_reference;
00074
00075 typedef typename _Base::iterator iterator;
00076 typedef typename _Base::const_iterator const_iterator;
00077
00078 explicit
00079 unordered_set(size_type __n = 10,
00080 const hasher& __hf = hasher(),
00081 const key_equal& __eql = key_equal(),
00082 const allocator_type& __a = allocator_type())
00083 : _Base(__n, __hf, __eql, __a)
00084 {
00085 __profcxx_hashtable_construct(this, _Base::bucket_count());
00086 __profcxx_hashtable_construct2(this);
00087 }
00088
00089 template<typename _InputIterator>
00090 unordered_set(_InputIterator __f, _InputIterator __l,
00091 size_type __n = 10,
00092 const hasher& __hf = hasher(),
00093 const key_equal& __eql = key_equal(),
00094 const allocator_type& __a = allocator_type())
00095 : _Base(__f, __l, __n, __hf, __eql, __a)
00096 {
00097 __profcxx_hashtable_construct(this, _Base::bucket_count());
00098 __profcxx_hashtable_construct2(this);
00099 }
00100
00101 unordered_set(const _Base& __x)
00102 : _Base(__x)
00103 {
00104 __profcxx_hashtable_construct(this, _Base::bucket_count());
00105 __profcxx_hashtable_construct2(this);
00106 }
00107
00108 unordered_set(unordered_set&& __x)
00109 : _Base(std::forward<_Base>(__x))
00110 {
00111 __profcxx_hashtable_construct(this, _Base::bucket_count());
00112 __profcxx_hashtable_construct2(this);
00113 }
00114
00115 unordered_set(initializer_list<value_type> __l,
00116 size_type __n = 10,
00117 const hasher& __hf = hasher(),
00118 const key_equal& __eql = key_equal(),
00119 const allocator_type& __a = allocator_type())
00120 : _Base(__l, __n, __hf, __eql, __a) { }
00121
00122 unordered_set&
00123 operator=(const unordered_set& __x)
00124 {
00125 *static_cast<_Base*>(this) = __x;
00126 return *this;
00127 }
00128
00129 unordered_set&
00130 operator=(unordered_set&& __x)
00131 {
00132
00133
00134 this->clear();
00135 this->swap(__x);
00136 return *this;
00137 }
00138
00139 unordered_set&
00140 operator=(initializer_list<value_type> __l)
00141 {
00142 this->clear();
00143 this->insert(__l);
00144 return *this;
00145 }
00146
00147 ~unordered_set()
00148 {
00149 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00150 _Base::size());
00151 _M_profile_destruct();
00152 }
00153
00154 void
00155 swap(unordered_set& __x)
00156 {
00157 _Base::swap(__x);
00158 }
00159
00160 void
00161 clear()
00162 {
00163 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00164 _Base::size());
00165 _M_profile_destruct();
00166 _Base::clear();
00167 }
00168
00169 void
00170 insert(std::initializer_list<value_type> __l)
00171 {
00172 size_type __old_size = _Base::bucket_count();
00173 _Base::insert(__l);
00174 _M_profile_resize(__old_size, _Base::bucket_count());
00175 }
00176
00177 std::pair<iterator, bool>
00178 insert(const value_type& __obj)
00179 {
00180 size_type __old_size = _Base::bucket_count();
00181 std::pair<iterator, bool> __res = _Base::insert(__obj);
00182 _M_profile_resize(__old_size, _Base::bucket_count());
00183 return __res;
00184 }
00185
00186 iterator
00187 insert(const_iterator __iter, const value_type& __v)
00188 {
00189 size_type __old_size = _Base::bucket_count();
00190 iterator __res = _Base::insert(__iter, __v);
00191 _M_profile_resize(__old_size, _Base::bucket_count());
00192 return __res;
00193 }
00194
00195 template<typename _InputIter>
00196 void
00197 insert(_InputIter __first, _InputIter __last)
00198 {
00199 size_type __old_size = _Base::bucket_count();
00200 _Base::insert(__first, __last);
00201 _M_profile_resize(__old_size, _Base::bucket_count());
00202 }
00203
00204 void
00205 insert(const value_type* __first, const value_type* __last)
00206 {
00207 size_type __old_size = _Base::bucket_count();
00208 _Base::insert(__first, __last);
00209 _M_profile_resize(__old_size, _Base::bucket_count());
00210 }
00211
00212 void rehash(size_type __n)
00213 {
00214 size_type __old_size = _Base::bucket_count();
00215 _Base::rehash(__n);
00216 _M_profile_resize(__old_size, _Base::bucket_count());
00217 }
00218
00219 private:
00220 _Base&
00221 _M_base() { return *this; }
00222
00223 const _Base&
00224 _M_base() const { return *this; }
00225
00226 void
00227 _M_profile_resize(size_type __old_size, size_type __new_size)
00228 {
00229 if (__old_size != __new_size)
00230 __profcxx_hashtable_resize(this, __old_size, __new_size);
00231 }
00232
00233 void
00234 _M_profile_destruct()
00235 {
00236 size_type __hops = 0, __lc = 0, __chain = 0;
00237 for (iterator __it = _M_base().begin(); __it != _M_base().end();
00238 ++__it)
00239 {
00240 while (__it._M_cur_node->_M_next)
00241 {
00242 ++__chain;
00243 ++__it;
00244 }
00245
00246 if (__chain)
00247 {
00248 ++__chain;
00249 __lc = __lc > __chain ? __lc : __chain;
00250 __hops += __chain * (__chain - 1) / 2;
00251 __chain = 0;
00252 }
00253 }
00254 __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
00255 }
00256
00257 };
00258
00259 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00260 inline void
00261 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00262 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00263 { __x.swap(__y); }
00264
00265 #undef _GLIBCXX_BASE
00266 #undef _GLIBCXX_STD_BASE
00267 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00268 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
00269
00270
00271 template<typename _Value,
00272 typename _Hash = std::hash<_Value>,
00273 typename _Pred = std::equal_to<_Value>,
00274 typename _Alloc = std::allocator<_Value> >
00275 class unordered_multiset
00276 : public _GLIBCXX_STD_BASE
00277 {
00278 typedef typename _GLIBCXX_STD_BASE _Base;
00279
00280 public:
00281 typedef typename _Base::size_type size_type;
00282 typedef typename _Base::hasher hasher;
00283 typedef typename _Base::key_equal key_equal;
00284 typedef typename _Base::allocator_type allocator_type;
00285 typedef typename _Base::key_type key_type;
00286 typedef typename _Base::value_type value_type;
00287 typedef typename _Base::difference_type difference_type;
00288 typedef typename _Base::reference reference;
00289 typedef typename _Base::const_reference const_reference;
00290
00291 typedef typename _Base::iterator iterator;
00292 typedef typename _Base::const_iterator const_iterator;
00293
00294 explicit
00295 unordered_multiset(size_type __n = 10,
00296 const hasher& __hf = hasher(),
00297 const key_equal& __eql = key_equal(),
00298 const allocator_type& __a = allocator_type())
00299 : _Base(__n, __hf, __eql, __a)
00300 {
00301 __profcxx_hashtable_construct(this, _Base::bucket_count());
00302 }
00303
00304 template<typename _InputIterator>
00305 unordered_multiset(_InputIterator __f, _InputIterator __l,
00306 size_type __n = 10,
00307 const hasher& __hf = hasher(),
00308 const key_equal& __eql = key_equal(),
00309 const allocator_type& __a = allocator_type())
00310 : _Base(__f, __l, __n, __hf, __eql, __a)
00311 {
00312 __profcxx_hashtable_construct(this, _Base::bucket_count());
00313 }
00314
00315 unordered_multiset(const _Base& __x)
00316 : _Base(__x)
00317 {
00318 __profcxx_hashtable_construct(this, _Base::bucket_count());
00319 }
00320
00321 unordered_multiset(unordered_multiset&& __x)
00322 : _Base(std::forward<_Base>(__x))
00323 {
00324 __profcxx_hashtable_construct(this, _Base::bucket_count());
00325 }
00326
00327 unordered_multiset(initializer_list<value_type> __l,
00328 size_type __n = 10,
00329 const hasher& __hf = hasher(),
00330 const key_equal& __eql = key_equal(),
00331 const allocator_type& __a = allocator_type())
00332 : _Base(__l, __n, __hf, __eql, __a) { }
00333
00334 unordered_multiset&
00335 operator=(const unordered_multiset& __x)
00336 {
00337 *static_cast<_Base*>(this) = __x;
00338 return *this;
00339 }
00340
00341 unordered_multiset&
00342 operator=(unordered_multiset&& __x)
00343 {
00344
00345
00346 this->clear();
00347 this->swap(__x);
00348 return *this;
00349 }
00350
00351 unordered_multiset&
00352 operator=(initializer_list<value_type> __l)
00353 {
00354 this->clear();
00355 this->insert(__l);
00356 return *this;
00357 }
00358
00359 ~unordered_multiset()
00360 {
00361 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00362 _Base::size());
00363 _M_profile_destruct();
00364 }
00365
00366 void
00367 swap(unordered_multiset& __x)
00368 {
00369 _Base::swap(__x);
00370 }
00371
00372 void
00373 clear()
00374 {
00375 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00376 _Base::size());
00377 _M_profile_destruct();
00378 _Base::clear();
00379 }
00380
00381 void
00382 insert(std::initializer_list<value_type> __l)
00383 {
00384 size_type __old_size = _Base::bucket_count();
00385 _Base::insert(__l);
00386 _M_profile_resize(__old_size, _Base::bucket_count());
00387 }
00388
00389 iterator
00390 insert(const value_type& __obj)
00391 {
00392 size_type __old_size = _Base::bucket_count();
00393 iterator __res = _Base::insert(__obj);
00394 _M_profile_resize(__old_size, _Base::bucket_count());
00395 return __res;
00396 }
00397
00398 iterator
00399 insert(const_iterator __iter, const value_type& __v)
00400 {
00401 size_type __old_size = _Base::bucket_count();
00402 iterator __res = _Base::insert(__iter, __v);
00403 _M_profile_resize(__old_size, _Base::bucket_count());
00404 return __res;
00405 }
00406
00407 template<typename _InputIter>
00408 void
00409 insert(_InputIter __first, _InputIter __last)
00410 {
00411 size_type __old_size = _Base::bucket_count();
00412 _Base::insert(__first, __last);
00413 _M_profile_resize(__old_size, _Base::bucket_count());
00414 }
00415
00416 void
00417 insert(const value_type* __first, const value_type* __last)
00418 {
00419 size_type __old_size = _Base::bucket_count();
00420 _Base::insert(__first, __last);
00421 _M_profile_resize(__old_size, _Base::bucket_count());
00422 }
00423
00424 void rehash(size_type __n)
00425 {
00426 size_type __old_size = _Base::bucket_count();
00427 _Base::rehash(__n);
00428 _M_profile_resize(__old_size, _Base::bucket_count());
00429 }
00430
00431 private:
00432 _Base&
00433 _M_base() { return *this; }
00434
00435 const _Base&
00436 _M_base() const { return *this; }
00437
00438 void
00439 _M_profile_resize(size_type __old_size, size_type __new_size)
00440 {
00441 if (__old_size != __new_size)
00442 __profcxx_hashtable_resize(this, __old_size, __new_size);
00443 }
00444
00445 void
00446 _M_profile_destruct()
00447 {
00448 size_type __hops = 0, __lc = 0, __chain = 0;
00449 for (iterator __it = _M_base().begin(); __it != _M_base().end();
00450 ++__it)
00451 {
00452 while (__it._M_cur_node->_M_next)
00453 {
00454 ++__chain;
00455 ++__it;
00456 }
00457
00458 if (__chain)
00459 {
00460 ++__chain;
00461 __lc = __lc > __chain ? __lc : __chain;
00462 __hops += __chain * (__chain - 1) / 2;
00463 __chain = 0;
00464 }
00465 }
00466 __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
00467 }
00468
00469 };
00470
00471 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00472 inline void
00473 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00474 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00475 { __x.swap(__y); }
00476
00477 }
00478 }
00479
00480 #undef _GLIBCXX_BASE
00481 #undef _GLIBCXX_STD_BASE
00482
00483 #endif