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 <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(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 const_iterator
00196 insert(const_iterator __iter, const value_type& __v)
00197 {
00198 size_type __old_size = _Base::bucket_count();
00199 const_iterator res =_Base::insert(__iter, __v);
00200 _M_profile_resize(__old_size, _Base::bucket_count());
00201 return res;
00202 }
00203
00204 template<typename _InputIter>
00205 void
00206 insert(_InputIter __first, _InputIter __last)
00207 {
00208 size_type __old_size = _Base::bucket_count();
00209 _Base::insert(__first, __last);
00210 _M_profile_resize(__old_size, _Base::bucket_count());
00211 }
00212
00213 void
00214 insert(const value_type* __first, const value_type* __last)
00215 {
00216 size_type __old_size = _Base::bucket_count();
00217 _Base::insert(__first, __last);
00218 _M_profile_resize(__old_size, _Base::bucket_count());
00219 }
00220
00221 void rehash(size_type __n)
00222 {
00223 size_type __old_size = _Base::bucket_count();
00224 _Base::rehash(__n);
00225 _M_profile_resize(__old_size, _Base::bucket_count());
00226 }
00227
00228 private:
00229 _Base&
00230 _M_base() { return *this; }
00231
00232 const _Base&
00233 _M_base() const { return *this; }
00234
00235 void _M_profile_resize(size_type __old_size, size_type __new_size)
00236 {
00237 if (__old_size != __new_size)
00238 {
00239 __profcxx_hashtable_resize(this, __old_size, __new_size);
00240 }
00241 }
00242 void _M_profile_destruct()
00243 {
00244 size_type __hops = 0, __lc = 0, __chain = 0;
00245 for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
00246 {
00247 while (it._M_cur_node->_M_next) {
00248 __chain++;
00249 it++;
00250 }
00251 if (__chain) {
00252 __chain++;
00253 __lc = __lc > __chain ? __lc : __chain;
00254 __hops += __chain * (__chain - 1) / 2;
00255 __chain = 0;
00256 }
00257 }
00258 __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
00259 }
00260
00261 };
00262 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00263 inline void
00264 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00265 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00266 { __x.swap(__y); }
00267
00268 #undef _GLIBCXX_BASE
00269 #undef _GLIBCXX_STD_BASE
00270 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00271 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
00272
00273
00274 template<typename _Value,
00275 typename _Hash = std::hash<_Value>,
00276 typename _Pred = std::equal_to<_Value>,
00277 typename _Alloc = std::allocator<_Value> >
00278 class unordered_multiset
00279 : public _GLIBCXX_STD_BASE
00280 {
00281 typedef typename _GLIBCXX_STD_BASE _Base;
00282
00283 public:
00284 typedef typename _Base::size_type size_type;
00285 typedef typename _Base::hasher hasher;
00286 typedef typename _Base::key_equal key_equal;
00287 typedef typename _Base::allocator_type allocator_type;
00288 typedef typename _Base::key_type key_type;
00289 typedef typename _Base::value_type value_type;
00290 typedef typename _Base::difference_type difference_type;
00291 typedef typename _Base::reference reference;
00292 typedef typename _Base::const_reference const_reference;
00293
00294 typedef typename _Base::iterator iterator;
00295 typedef typename _Base::const_iterator const_iterator;
00296
00297 explicit
00298 unordered_multiset(size_type __n = 10,
00299 const hasher& __hf = hasher(),
00300 const key_equal& __eql = key_equal(),
00301 const allocator_type& __a = allocator_type())
00302 : _Base(__n, __hf, __eql, __a)
00303 {
00304 __profcxx_hashtable_construct(this, _Base::bucket_count());
00305 }
00306
00307 template<typename _InputIterator>
00308 unordered_multiset(_InputIterator __f, _InputIterator __l,
00309 size_type __n = 10,
00310 const hasher& __hf = hasher(),
00311 const key_equal& __eql = key_equal(),
00312 const allocator_type& __a = allocator_type())
00313 : _Base(__f, __l, __n, __hf, __eql, __a)
00314 {
00315 __profcxx_hashtable_construct(this, _Base::bucket_count());
00316 }
00317
00318 unordered_multiset(const _Base& __x)
00319 : _Base(__x)
00320 {
00321 __profcxx_hashtable_construct(this, _Base::bucket_count());
00322 }
00323
00324 unordered_multiset(unordered_multiset&& __x)
00325 : _Base(std::forward<_Base>(__x))
00326 {
00327 __profcxx_hashtable_construct(this, _Base::bucket_count());
00328 }
00329
00330 unordered_multiset(initializer_list<value_type> __l,
00331 size_type __n = 10,
00332 const hasher& __hf = hasher(),
00333 const key_equal& __eql = key_equal(),
00334 const allocator_type& __a = allocator_type())
00335 : _Base(__l, __n, __hf, __eql, __a) { }
00336
00337 unordered_multiset&
00338 operator=(const unordered_multiset& __x)
00339 {
00340 *static_cast<_Base*>(this) = __x;
00341 return *this;
00342 }
00343
00344 unordered_multiset&
00345 operator=(unordered_multiset&& __x)
00346 {
00347
00348
00349 this->clear();
00350 this->swap(__x);
00351 return *this;
00352 }
00353
00354 unordered_multiset&
00355 operator=(initializer_list<value_type> __l)
00356 {
00357 this->clear();
00358 this->insert(__l);
00359 return *this;
00360 }
00361
00362 ~unordered_multiset()
00363 {
00364 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00365 _Base::size());
00366 _M_profile_destruct();
00367 }
00368
00369 void
00370 swap(unordered_multiset& __x)
00371 {
00372 _Base::swap(__x);
00373 }
00374
00375 void
00376 clear()
00377 {
00378 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
00379 _Base::size());
00380 _M_profile_destruct();
00381 _Base::clear();
00382 }
00383
00384 void
00385 insert(std::initializer_list<value_type> __l)
00386 {
00387 size_type __old_size = _Base::bucket_count();
00388 _Base::insert(__l);
00389 _M_profile_resize(__old_size, _Base::bucket_count());
00390 }
00391
00392 iterator
00393 insert(const value_type& __obj)
00394 {
00395 size_type __old_size = _Base::bucket_count();
00396 iterator __res = _Base::insert(__obj);
00397 _M_profile_resize(__old_size, _Base::bucket_count());
00398 return __res;
00399 }
00400
00401 iterator
00402 insert(iterator __iter, const value_type& __v)
00403 {
00404 size_type __old_size = _Base::bucket_count();
00405 iterator res = _Base::insert(__iter, __v);
00406 _M_profile_resize(__old_size, _Base::bucket_count());
00407 return res;
00408 }
00409
00410 const_iterator
00411 insert(const_iterator __iter, const value_type& __v)
00412 {
00413 size_type __old_size = _Base::bucket_count();
00414 const_iterator res =_Base::insert(__iter, __v);
00415 _M_profile_resize(__old_size, _Base::bucket_count());
00416 return res;
00417 }
00418
00419 template<typename _InputIter>
00420 void
00421 insert(_InputIter __first, _InputIter __last)
00422 {
00423 size_type __old_size = _Base::bucket_count();
00424 _Base::insert(__first, __last);
00425 _M_profile_resize(__old_size, _Base::bucket_count());
00426 }
00427
00428 void
00429 insert(const value_type* __first, const value_type* __last)
00430 {
00431 size_type __old_size = _Base::bucket_count();
00432 _Base::insert(__first, __last);
00433 _M_profile_resize(__old_size, _Base::bucket_count());
00434 }
00435
00436 void rehash(size_type __n)
00437 {
00438 size_type __old_size = _Base::bucket_count();
00439 _Base::rehash(__n);
00440 _M_profile_resize(__old_size, _Base::bucket_count());
00441 }
00442
00443 private:
00444 _Base&
00445 _M_base() { return *this; }
00446
00447 const _Base&
00448 _M_base() const { return *this; }
00449
00450 void _M_profile_resize(size_type __old_size, size_type __new_size)
00451 {
00452 if (__old_size != __new_size)
00453 {
00454 __profcxx_hashtable_resize(this, __old_size, __new_size);
00455 }
00456 }
00457
00458 void _M_profile_destruct()
00459 {
00460 size_type __hops = 0, __lc = 0, __chain = 0;
00461 for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
00462 {
00463 while (it._M_cur_node->_M_next) {
00464 __chain++;
00465 it++;
00466 }
00467 if (__chain) {
00468 __chain++;
00469 __lc = __lc > __chain ? __lc : __chain;
00470 __hops += __chain * (__chain - 1) / 2;
00471 __chain = 0;
00472 }
00473 }
00474 __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
00475 }
00476
00477 };
00478 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00479 inline void
00480 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00481 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00482 { __x.swap(__y); }
00483
00484 }
00485 }
00486
00487 #undef _GLIBCXX_BASE
00488 #undef _GLIBCXX_STD_BASE
00489
00490 #endif