1// Profiling unordered_set/unordered_multiset implementation -*- C++ -*- 2 3// Copyright (C) 2009-2014 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10// 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License along 21// with this library; see the file COPYING3. If not see 22// <http://www.gnu.org/licenses/>. 23 24/** @file profile/unordered_set 25 * This file is a GNU profile extension to the Standard C++ Library. 26 */ 27 28#ifndef _GLIBCXX_PROFILE_UNORDERED_SET 29#define _GLIBCXX_PROFILE_UNORDERED_SET 1 30 31#if __cplusplus < 201103L 32# include <bits/c++0x_warning.h> 33#else 34# include <unordered_set> 35 36#include <profile/base.h> 37#include <profile/unordered_base.h> 38 39#define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc> 40#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 41 42namespace std _GLIBCXX_VISIBILITY(default) 43{ 44namespace __profile 45{ 46 /** @brief Unordered_set wrapper with performance instrumentation. */ 47 template<typename _Key, 48 typename _Hash = std::hash<_Key>, 49 typename _Pred = std::equal_to<_Key>, 50 typename _Alloc = std::allocator<_Key> > 51 class unordered_set 52 : public _GLIBCXX_STD_BASE, 53 public _Unordered_profile<unordered_set<_Key, _Hash, _Pred, _Alloc>, 54 true> 55 { 56 typedef _GLIBCXX_STD_BASE _Base; 57 58 _Base& 59 _M_base() noexcept { return *this; } 60 61 const _Base& 62 _M_base() const noexcept { return *this; } 63 64 public: 65 typedef typename _Base::size_type size_type; 66 typedef typename _Base::hasher hasher; 67 typedef typename _Base::key_equal key_equal; 68 typedef typename _Base::allocator_type allocator_type; 69 typedef typename _Base::key_type key_type; 70 typedef typename _Base::value_type value_type; 71 typedef typename _Base::difference_type difference_type; 72 typedef typename _Base::reference reference; 73 typedef typename _Base::const_reference const_reference; 74 75 typedef typename _Base::iterator iterator; 76 typedef typename _Base::const_iterator const_iterator; 77 78 explicit 79 unordered_set(size_type __n = 10, 80 const hasher& __hf = hasher(), 81 const key_equal& __eql = key_equal(), 82 const allocator_type& __a = allocator_type()) 83 : _Base(__n, __hf, __eql, __a) 84 { } 85 86 template<typename _InputIterator> 87 unordered_set(_InputIterator __f, _InputIterator __l, 88 size_type __n = 0, 89 const hasher& __hf = hasher(), 90 const key_equal& __eql = key_equal(), 91 const allocator_type& __a = allocator_type()) 92 : _Base(__f, __l, __n, __hf, __eql, __a) 93 { } 94 95 unordered_set(const unordered_set&) = default; 96 97 unordered_set(const _Base& __x) 98 : _Base(__x) 99 { } 100 101 unordered_set(unordered_set&&) = default; 102 103 explicit 104 unordered_set(const allocator_type& __a) 105 : _Base(__a) 106 { } 107 108 unordered_set(const unordered_set& __uset, 109 const allocator_type& __a) 110 : _Base(__uset._M_base(), __a) 111 { } 112 113 unordered_set(unordered_set&& __uset, 114 const allocator_type& __a) 115 : _Base(std::move(__uset._M_base()), __a) 116 { } 117 118 unordered_set(initializer_list<value_type> __l, 119 size_type __n = 0, 120 const hasher& __hf = hasher(), 121 const key_equal& __eql = key_equal(), 122 const allocator_type& __a = allocator_type()) 123 : _Base(__l, __n, __hf, __eql, __a) 124 { } 125 126 unordered_set& 127 operator=(const unordered_set&) = default; 128 129 unordered_set& 130 operator=(unordered_set&&) = default; 131 132 unordered_set& 133 operator=(initializer_list<value_type> __l) 134 { 135 _M_base() = __l; 136 return *this; 137 } 138 139 void 140 swap(unordered_set& __x) 141 noexcept( noexcept(__x._M_base().swap(__x)) ) 142 { _Base::swap(__x); } 143 144 void 145 clear() noexcept 146 { 147 __profcxx_hashtable_destruct(this, _Base::bucket_count(), 148 _Base::size()); 149 this->_M_profile_destruct(); 150 _Base::clear(); 151 } 152 153 template<typename... _Args> 154 std::pair<iterator, bool> 155 emplace(_Args&&... __args) 156 { 157 size_type __old_size = _Base::bucket_count(); 158 std::pair<iterator, bool> __res 159 = _Base::emplace(std::forward<_Args>(__args)...); 160 _M_profile_resize(__old_size); 161 return __res; 162 } 163 164 template<typename... _Args> 165 iterator 166 emplace_hint(const_iterator __it, _Args&&... __args) 167 { 168 size_type __old_size = _Base::bucket_count(); 169 iterator __res 170 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 171 _M_profile_resize(__old_size); 172 return __res; 173 } 174 175 void 176 insert(std::initializer_list<value_type> __l) 177 { 178 size_type __old_size = _Base::bucket_count(); 179 _Base::insert(__l); 180 _M_profile_resize(__old_size); 181 } 182 183 std::pair<iterator, bool> 184 insert(const value_type& __obj) 185 { 186 size_type __old_size = _Base::bucket_count(); 187 std::pair<iterator, bool> __res = _Base::insert(__obj); 188 _M_profile_resize(__old_size); 189 return __res; 190 } 191 192 iterator 193 insert(const_iterator __iter, const value_type& __v) 194 { 195 size_type __old_size = _Base::bucket_count(); 196 iterator __res = _Base::insert(__iter, __v); 197 _M_profile_resize(__old_size); 198 return __res; 199 } 200 201 std::pair<iterator, bool> 202 insert(value_type&& __obj) 203 { 204 size_type __old_size = _Base::bucket_count(); 205 std::pair<iterator, bool> __res = _Base::insert(std::move(__obj)); 206 _M_profile_resize(__old_size); 207 return __res; 208 } 209 210 iterator 211 insert(const_iterator __iter, value_type&& __v) 212 { 213 size_type __old_size = _Base::bucket_count(); 214 iterator __res = _Base::insert(__iter, std::move(__v)); 215 _M_profile_resize(__old_size); 216 return __res; 217 } 218 219 template<typename _InputIter> 220 void 221 insert(_InputIter __first, _InputIter __last) 222 { 223 size_type __old_size = _Base::bucket_count(); 224 _Base::insert(__first, __last); 225 _M_profile_resize(__old_size); 226 } 227 228 void 229 rehash(size_type __n) 230 { 231 size_type __old_size = _Base::bucket_count(); 232 _Base::rehash(__n); 233 _M_profile_resize(__old_size); 234 } 235 236 private: 237 void 238 _M_profile_resize(size_type __old_size) 239 { 240 size_type __new_size = _Base::bucket_count(); 241 if (__old_size != __new_size) 242 __profcxx_hashtable_resize(this, __old_size, __new_size); 243 } 244 }; 245 246 template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> 247 inline void 248 swap(unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, 249 unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) 250 { __x.swap(__y); } 251 252 template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> 253 inline bool 254 operator==(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, 255 const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) 256 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; } 257 258 template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> 259 inline bool 260 operator!=(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, 261 const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) 262 { return !(__x == __y); } 263 264#undef _GLIBCXX_BASE 265#undef _GLIBCXX_STD_BASE 266#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 267#define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc> 268 269 /** @brief Unordered_multiset wrapper with performance instrumentation. */ 270 template<typename _Value, 271 typename _Hash = std::hash<_Value>, 272 typename _Pred = std::equal_to<_Value>, 273 typename _Alloc = std::allocator<_Value> > 274 class unordered_multiset 275 : public _GLIBCXX_STD_BASE, 276 public _Unordered_profile<unordered_multiset<_Value, 277 _Hash, _Pred, _Alloc>, 278 false> 279 { 280 typedef _GLIBCXX_STD_BASE _Base; 281 282 _Base& 283 _M_base() noexcept { return *this; } 284 285 const _Base& 286 _M_base() const noexcept { return *this; } 287 288 public: 289 typedef typename _Base::size_type size_type; 290 typedef typename _Base::hasher hasher; 291 typedef typename _Base::key_equal key_equal; 292 typedef typename _Base::allocator_type allocator_type; 293 typedef typename _Base::key_type key_type; 294 typedef typename _Base::value_type value_type; 295 typedef typename _Base::difference_type difference_type; 296 typedef typename _Base::reference reference; 297 typedef typename _Base::const_reference const_reference; 298 299 typedef typename _Base::iterator iterator; 300 typedef typename _Base::const_iterator const_iterator; 301 302 explicit 303 unordered_multiset(size_type __n = 10, 304 const hasher& __hf = hasher(), 305 const key_equal& __eql = key_equal(), 306 const allocator_type& __a = allocator_type()) 307 : _Base(__n, __hf, __eql, __a) 308 { } 309 310 template<typename _InputIterator> 311 unordered_multiset(_InputIterator __f, _InputIterator __l, 312 size_type __n = 0, 313 const hasher& __hf = hasher(), 314 const key_equal& __eql = key_equal(), 315 const allocator_type& __a = allocator_type()) 316 : _Base(__f, __l, __n, __hf, __eql, __a) 317 { } 318 319 unordered_multiset(const unordered_multiset&) = default; 320 321 unordered_multiset(const _Base& __x) 322 : _Base(__x) 323 { } 324 325 unordered_multiset(unordered_multiset&&) = default; 326 327 explicit 328 unordered_multiset(const allocator_type& __a) 329 : _Base(__a) 330 { } 331 332 unordered_multiset(const unordered_multiset& __umset, 333 const allocator_type& __a) 334 : _Base(__umset._M_base(), __a) 335 { } 336 337 unordered_multiset(unordered_multiset&& __umset, 338 const allocator_type& __a) 339 : _Base(std::move(__umset._M_base()), __a) 340 { } 341 342 unordered_multiset(initializer_list<value_type> __l, 343 size_type __n = 0, 344 const hasher& __hf = hasher(), 345 const key_equal& __eql = key_equal(), 346 const allocator_type& __a = allocator_type()) 347 : _Base(__l, __n, __hf, __eql, __a) 348 { } 349 350 unordered_multiset& 351 operator=(const unordered_multiset&) = default; 352 353 unordered_multiset& 354 operator=(unordered_multiset&&) = default; 355 356 unordered_multiset& 357 operator=(initializer_list<value_type> __l) 358 { 359 _M_base() = __l; 360 return *this; 361 } 362 363 void 364 swap(unordered_multiset& __x) 365 noexcept( noexcept(__x._M_base().swap(__x)) ) 366 { _Base::swap(__x); } 367 368 void 369 clear() noexcept 370 { 371 __profcxx_hashtable_destruct(this, _Base::bucket_count(), 372 _Base::size()); 373 this->_M_profile_destruct(); 374 _Base::clear(); 375 } 376 377 template<typename... _Args> 378 iterator 379 emplace(_Args&&... __args) 380 { 381 size_type __old_size = _Base::bucket_count(); 382 iterator __res = _Base::emplace(std::forward<_Args>(__args)...); 383 _M_profile_resize(__old_size); 384 return __res; 385 } 386 387 template<typename... _Args> 388 iterator 389 emplace_hint(const_iterator __it, _Args&&... __args) 390 { 391 size_type __old_size = _Base::bucket_count(); 392 iterator __res 393 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 394 _M_profile_resize(__old_size); 395 return __res; 396 } 397 398 void 399 insert(std::initializer_list<value_type> __l) 400 { 401 size_type __old_size = _Base::bucket_count(); 402 _Base::insert(__l); 403 _M_profile_resize(__old_size); 404 } 405 406 iterator 407 insert(const value_type& __obj) 408 { 409 size_type __old_size = _Base::bucket_count(); 410 iterator __res = _Base::insert(__obj); 411 _M_profile_resize(__old_size); 412 return __res; 413 } 414 415 iterator 416 insert(const_iterator __iter, const value_type& __v) 417 { 418 size_type __old_size = _Base::bucket_count(); 419 iterator __res = _Base::insert(__iter, __v); 420 _M_profile_resize(__old_size); 421 return __res; 422 } 423 424 iterator 425 insert(value_type&& __obj) 426 { 427 size_type __old_size = _Base::bucket_count(); 428 iterator __res = _Base::insert(std::move(__obj)); 429 _M_profile_resize(__old_size); 430 return __res; 431 } 432 433 iterator 434 insert(const_iterator __iter, value_type&& __v) 435 { 436 size_type __old_size = _Base::bucket_count(); 437 iterator __res = _Base::insert(__iter, std::move(__v)); 438 _M_profile_resize(__old_size); 439 return __res; 440 } 441 442 template<typename _InputIter> 443 void 444 insert(_InputIter __first, _InputIter __last) 445 { 446 size_type __old_size = _Base::bucket_count(); 447 _Base::insert(__first, __last); 448 _M_profile_resize(__old_size); 449 } 450 451 void 452 rehash(size_type __n) 453 { 454 size_type __old_size = _Base::bucket_count(); 455 _Base::rehash(__n); 456 _M_profile_resize(__old_size); 457 } 458 459 private: 460 void 461 _M_profile_resize(size_type __old_size) 462 { 463 size_type __new_size = _Base::bucket_count(); 464 if (__old_size != __new_size) 465 __profcxx_hashtable_resize(this, __old_size, __new_size); 466 } 467 }; 468 469 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 470 inline void 471 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 472 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 473 { __x.swap(__y); } 474 475 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 476 inline bool 477 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 478 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 479 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; } 480 481 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 482 inline bool 483 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 484 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 485 { return !(__x == __y); } 486 487} // namespace __profile 488} // namespace std 489 490#undef _GLIBCXX_BASE 491#undef _GLIBCXX_STD_BASE 492 493#endif // C++11 494 495#endif 496