|
libstdc++
|
00001 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*- 00002 00003 // Copyright (C) 2009-2015 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 along 00021 // with this library; see the file COPYING3. If not see 00022 // <http://www.gnu.org/licenses/>. 00023 00024 /** @file profile/unordered_map 00025 * This file is a GNU profile extension to the Standard C++ Library. 00026 */ 00027 00028 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP 00029 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1 00030 00031 #if __cplusplus < 201103L 00032 # include <bits/c++0x_warning.h> 00033 #else 00034 # include <unordered_map> 00035 00036 #include <profile/base.h> 00037 #include <profile/unordered_base.h> 00038 00039 #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> 00040 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 00041 00042 namespace std _GLIBCXX_VISIBILITY(default) 00043 { 00044 namespace __profile 00045 { 00046 /// Class std::unordered_map wrapper with performance instrumentation. 00047 template<typename _Key, typename _Tp, 00048 typename _Hash = std::hash<_Key>, 00049 typename _Pred = std::equal_to<_Key>, 00050 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 00051 class unordered_map 00052 : public _GLIBCXX_STD_BASE, 00053 public _Unordered_profile<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, 00054 true> 00055 { 00056 typedef typename _GLIBCXX_STD_BASE _Base; 00057 00058 _Base& 00059 _M_base() noexcept { return *this; } 00060 00061 const _Base& 00062 _M_base() const noexcept { return *this; } 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 unordered_map() = default; 00080 00081 explicit 00082 unordered_map(size_type __n, 00083 const hasher& __hf = hasher(), 00084 const key_equal& __eql = key_equal(), 00085 const allocator_type& __a = allocator_type()) 00086 : _Base(__n, __hf, __eql, __a) { } 00087 00088 template<typename _InputIterator> 00089 unordered_map(_InputIterator __f, _InputIterator __l, 00090 size_type __n = 0, 00091 const hasher& __hf = hasher(), 00092 const key_equal& __eql = key_equal(), 00093 const allocator_type& __a = allocator_type()) 00094 : _Base(__f, __l, __n, __hf, __eql, __a) { } 00095 00096 unordered_map(const unordered_map&) = default; 00097 00098 unordered_map(const _Base& __x) 00099 : _Base(__x) { } 00100 00101 unordered_map(unordered_map&&) = default; 00102 00103 explicit 00104 unordered_map(const allocator_type& __a) 00105 : _Base(__a) { } 00106 00107 unordered_map(const unordered_map& __umap, 00108 const allocator_type& __a) 00109 : _Base(__umap, __a) { } 00110 00111 unordered_map(unordered_map&& __umap, 00112 const allocator_type& __a) 00113 : _Base(std::move(__umap._M_base()), __a) { } 00114 00115 unordered_map(initializer_list<value_type> __l, 00116 size_type __n = 0, 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_map& 00123 operator=(const unordered_map&) = default; 00124 00125 unordered_map& 00126 operator=(unordered_map&&) = default; 00127 00128 unordered_map& 00129 operator=(initializer_list<value_type> __l) 00130 { 00131 this->_M_profile_destruct(); 00132 _M_base() = __l; 00133 this->_M_profile_construct(); 00134 return *this; 00135 } 00136 00137 void 00138 clear() noexcept 00139 { 00140 this->_M_profile_destruct(); 00141 _Base::clear(); 00142 this->_M_profile_construct(); 00143 } 00144 00145 template<typename... _Args> 00146 std::pair<iterator, bool> 00147 emplace(_Args&&... __args) 00148 { 00149 size_type __old_size = _Base::bucket_count(); 00150 std::pair<iterator, bool> __res 00151 = _Base::emplace(std::forward<_Args>(__args)...); 00152 this->_M_profile_resize(__old_size); 00153 return __res; 00154 } 00155 00156 template<typename... _Args> 00157 iterator 00158 emplace_hint(const_iterator __it, _Args&&... __args) 00159 { 00160 size_type __old_size = _Base::bucket_count(); 00161 iterator __res 00162 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 00163 this->_M_profile_resize(__old_size); 00164 return __res; 00165 } 00166 00167 void 00168 insert(std::initializer_list<value_type> __l) 00169 { 00170 size_type __old_size = _Base::bucket_count(); 00171 _Base::insert(__l); 00172 this->_M_profile_resize(__old_size); 00173 } 00174 00175 std::pair<iterator, bool> 00176 insert(const value_type& __obj) 00177 { 00178 size_type __old_size = _Base::bucket_count(); 00179 std::pair<iterator, bool> __res = _Base::insert(__obj); 00180 this->_M_profile_resize(__old_size); 00181 return __res; 00182 } 00183 00184 iterator 00185 insert(const_iterator __iter, const value_type& __v) 00186 { 00187 size_type __old_size = _Base::bucket_count(); 00188 iterator __res = _Base::insert(__iter, __v); 00189 this->_M_profile_resize(__old_size); 00190 return __res; 00191 } 00192 00193 template<typename _Pair, typename = typename 00194 std::enable_if<std::is_constructible<value_type, 00195 _Pair&&>::value>::type> 00196 std::pair<iterator, bool> 00197 insert(_Pair&& __obj) 00198 { 00199 size_type __old_size = _Base::bucket_count(); 00200 std::pair<iterator, bool> __res 00201 = _Base::insert(std::forward<_Pair>(__obj)); 00202 this->_M_profile_resize(__old_size); 00203 return __res; 00204 } 00205 00206 template<typename _Pair, typename = typename 00207 std::enable_if<std::is_constructible<value_type, 00208 _Pair&&>::value>::type> 00209 iterator 00210 insert(const_iterator __iter, _Pair&& __v) 00211 { 00212 size_type __old_size = _Base::bucket_count(); 00213 iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); 00214 this->_M_profile_resize(__old_size); 00215 return __res; 00216 } 00217 00218 template<typename _InputIter> 00219 void 00220 insert(_InputIter __first, _InputIter __last) 00221 { 00222 size_type __old_size = _Base::bucket_count(); 00223 _Base::insert(__first, __last); 00224 this->_M_profile_resize(__old_size); 00225 } 00226 00227 // operator[] 00228 mapped_type& 00229 operator[](const _Key& __k) 00230 { 00231 size_type __old_size = _Base::bucket_count(); 00232 mapped_type& __res = _M_base()[__k]; 00233 this->_M_profile_resize(__old_size); 00234 return __res; 00235 } 00236 00237 mapped_type& 00238 operator[](_Key&& __k) 00239 { 00240 size_type __old_size = _Base::bucket_count(); 00241 mapped_type& __res = _M_base()[std::move(__k)]; 00242 this->_M_profile_resize(__old_size); 00243 return __res; 00244 } 00245 00246 void 00247 swap(unordered_map& __x) 00248 noexcept( noexcept(__x._M_base().swap(__x)) ) 00249 { 00250 _Base::swap(__x._M_base()); 00251 this->_M_swap(__x); 00252 } 00253 00254 void rehash(size_type __n) 00255 { 00256 size_type __old_size = _Base::bucket_count(); 00257 _Base::rehash(__n); 00258 this->_M_profile_resize(__old_size); 00259 } 00260 }; 00261 00262 template<typename _Key, typename _Tp, typename _Hash, 00263 typename _Pred, typename _Alloc> 00264 inline void 00265 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00266 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00267 { __x.swap(__y); } 00268 00269 template<typename _Key, typename _Tp, typename _Hash, 00270 typename _Pred, typename _Alloc> 00271 inline bool 00272 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00273 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00274 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; } 00275 00276 template<typename _Key, typename _Tp, typename _Hash, 00277 typename _Pred, typename _Alloc> 00278 inline bool 00279 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00280 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00281 { return !(__x == __y); } 00282 00283 #undef _GLIBCXX_BASE 00284 #undef _GLIBCXX_STD_BASE 00285 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> 00286 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 00287 00288 /// Class std::unordered_multimap wrapper with performance instrumentation. 00289 template<typename _Key, typename _Tp, 00290 typename _Hash = std::hash<_Key>, 00291 typename _Pred = std::equal_to<_Key>, 00292 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 00293 class unordered_multimap 00294 : public _GLIBCXX_STD_BASE, 00295 public _Unordered_profile<unordered_multimap<_Key, _Tp, 00296 _Hash, _Pred, _Alloc>, 00297 false> 00298 { 00299 typedef typename _GLIBCXX_STD_BASE _Base; 00300 00301 _Base& 00302 _M_base() noexcept { return *this; } 00303 00304 const _Base& 00305 _M_base() const noexcept { return *this; } 00306 00307 public: 00308 typedef typename _Base::size_type size_type; 00309 typedef typename _Base::hasher hasher; 00310 typedef typename _Base::key_equal key_equal; 00311 typedef typename _Base::allocator_type allocator_type; 00312 typedef typename _Base::key_type key_type; 00313 typedef typename _Base::value_type value_type; 00314 typedef typename _Base::difference_type difference_type; 00315 typedef typename _Base::reference reference; 00316 typedef typename _Base::const_reference const_reference; 00317 00318 typedef typename _Base::iterator iterator; 00319 typedef typename _Base::const_iterator const_iterator; 00320 00321 unordered_multimap() = default; 00322 00323 explicit 00324 unordered_multimap(size_type __n, 00325 const hasher& __hf = hasher(), 00326 const key_equal& __eql = key_equal(), 00327 const allocator_type& __a = allocator_type()) 00328 : _Base(__n, __hf, __eql, __a) { } 00329 00330 template<typename _InputIterator> 00331 unordered_multimap(_InputIterator __f, _InputIterator __l, 00332 size_type __n = 0, 00333 const hasher& __hf = hasher(), 00334 const key_equal& __eql = key_equal(), 00335 const allocator_type& __a = allocator_type()) 00336 : _Base(__f, __l, __n, __hf, __eql, __a) { } 00337 00338 unordered_multimap(const unordered_multimap&) = default; 00339 00340 unordered_multimap(const _Base& __x) 00341 : _Base(__x) { } 00342 00343 unordered_multimap(unordered_multimap&&) = default; 00344 00345 explicit 00346 unordered_multimap(const allocator_type& __a) 00347 : _Base(__a) { } 00348 00349 unordered_multimap(const unordered_multimap& __ummap, 00350 const allocator_type& __a) 00351 : _Base(__ummap._M_base(), __a) { } 00352 00353 unordered_multimap(unordered_multimap&& __ummap, 00354 const allocator_type& __a) 00355 : _Base(std::move(__ummap._M_base()), __a) { } 00356 00357 unordered_multimap(initializer_list<value_type> __l, 00358 size_type __n = 0, 00359 const hasher& __hf = hasher(), 00360 const key_equal& __eql = key_equal(), 00361 const allocator_type& __a = allocator_type()) 00362 : _Base(__l, __n, __hf, __eql, __a) { } 00363 00364 unordered_multimap& 00365 operator=(const unordered_multimap&) = default; 00366 00367 unordered_multimap& 00368 operator=(unordered_multimap&&) = default; 00369 00370 unordered_multimap& 00371 operator=(initializer_list<value_type> __l) 00372 { 00373 this->_M_profile_destruct(); 00374 _M_base() = __l; 00375 this->_M_profile_construct(); 00376 return *this; 00377 } 00378 00379 void 00380 clear() noexcept 00381 { 00382 this->_M_profile_destruct(); 00383 _Base::clear(); 00384 this->_M_profile_construct(); 00385 } 00386 00387 template<typename... _Args> 00388 iterator 00389 emplace(_Args&&... __args) 00390 { 00391 size_type __old_size = _Base::bucket_count(); 00392 iterator __res 00393 = _Base::emplace(std::forward<_Args>(__args)...); 00394 this->_M_profile_resize(__old_size); 00395 return __res; 00396 } 00397 00398 template<typename... _Args> 00399 iterator 00400 emplace_hint(const_iterator __it, _Args&&... __args) 00401 { 00402 size_type __old_size = _Base::bucket_count(); 00403 iterator __res 00404 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 00405 this->_M_profile_resize(__old_size); 00406 return __res; 00407 } 00408 00409 void 00410 insert(std::initializer_list<value_type> __l) 00411 { 00412 size_type __old_size = _Base::bucket_count(); 00413 _Base::insert(__l); 00414 this->_M_profile_resize(__old_size); 00415 } 00416 00417 iterator 00418 insert(const value_type& __obj) 00419 { 00420 size_type __old_size = _Base::bucket_count(); 00421 iterator __res = _Base::insert(__obj); 00422 this->_M_profile_resize(__old_size); 00423 return __res; 00424 } 00425 00426 iterator 00427 insert(const_iterator __iter, const value_type& __v) 00428 { 00429 size_type __old_size = _Base::bucket_count(); 00430 iterator __res = _Base::insert(__iter, __v); 00431 this->_M_profile_resize(__old_size); 00432 return __res; 00433 } 00434 00435 template<typename _Pair, typename = typename 00436 std::enable_if<std::is_constructible<value_type, 00437 _Pair&&>::value>::type> 00438 iterator 00439 insert(_Pair&& __obj) 00440 { 00441 size_type __old_size = _Base::bucket_count(); 00442 iterator __res = _Base::insert(std::forward<_Pair>(__obj)); 00443 this->_M_profile_resize(__old_size); 00444 return __res; 00445 } 00446 00447 template<typename _Pair, typename = typename 00448 std::enable_if<std::is_constructible<value_type, 00449 _Pair&&>::value>::type> 00450 iterator 00451 insert(const_iterator __iter, _Pair&& __v) 00452 { 00453 size_type __old_size = _Base::bucket_count(); 00454 iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); 00455 this->_M_profile_resize(__old_size); 00456 return __res; 00457 } 00458 00459 template<typename _InputIter> 00460 void 00461 insert(_InputIter __first, _InputIter __last) 00462 { 00463 size_type __old_size = _Base::bucket_count(); 00464 _Base::insert(__first, __last); 00465 this->_M_profile_resize(__old_size); 00466 } 00467 00468 void 00469 swap(unordered_multimap& __x) 00470 noexcept( noexcept(__x._M_base().swap(__x)) ) 00471 { 00472 _Base::swap(__x._M_base()); 00473 this->_M_swap(__x); 00474 } 00475 00476 void 00477 rehash(size_type __n) 00478 { 00479 size_type __old_size = _Base::bucket_count(); 00480 _Base::rehash(__n); 00481 this->_M_profile_resize(__old_size); 00482 } 00483 }; 00484 00485 template<typename _Key, typename _Tp, typename _Hash, 00486 typename _Pred, typename _Alloc> 00487 inline void 00488 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00489 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00490 { __x.swap(__y); } 00491 00492 template<typename _Key, typename _Tp, typename _Hash, 00493 typename _Pred, typename _Alloc> 00494 inline bool 00495 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00496 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00497 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; } 00498 00499 template<typename _Key, typename _Tp, typename _Hash, 00500 typename _Pred, typename _Alloc> 00501 inline bool 00502 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 00503 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 00504 { return !(__x == __y); } 00505 00506 } // namespace __profile 00507 } // namespace std 00508 00509 #undef _GLIBCXX_BASE 00510 #undef _GLIBCXX_STD_BASE 00511 00512 #endif // C++11 00513 00514 #endif