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