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