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