hopscotch-map
bhopscotch_set.h
Go to the documentation of this file.
1 /**
2  * MIT License
3  *
4  * Copyright (c) 2017 Tessil
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef TSL_BHOPSCOTCH_SET_H
25 #define TSL_BHOPSCOTCH_SET_H
26 
27 
28 #include <algorithm>
29 #include <cstddef>
30 #include <functional>
31 #include <initializer_list>
32 #include <memory>
33 #include <set>
34 #include <type_traits>
35 #include <utility>
36 #include "hopscotch_hash.h"
37 
38 
39 namespace tsl {
40 
41 
42 /**
43  * Similar to tsl::hopscotch_set but instead of using a list for overflowing elements it uses
44  * a binary search tree. It thus needs an additional template parameter Compare. Compare should
45  * be arithmetically coherent with KeyEqual.
46  *
47  * The binary search tree allows the set to have a worst-case scenario of O(log n) for search
48  * and delete, even if the hash function maps all the elements to the same bucket.
49  * For insert, the amortized worst case is O(log n), but the worst case is O(n) in case of rehash.
50  *
51  * This makes the set resistant to DoS attacks (but doesn't preclude you to have a good hash function,
52  * as an element in the bucket array is faster to retrieve than in the tree).
53  *
54  * @copydoc hopscotch_set
55  */
56 template<class Key,
57  class Hash = std::hash<Key>,
58  class KeyEqual = std::equal_to<Key>,
59  class Compare = std::less<Key>,
60  class Allocator = std::allocator<Key>,
61  unsigned int NeighborhoodSize = 62,
62  bool StoreHash = false,
63  class GrowthPolicy = tsl::hh::power_of_two_growth_policy<2>>
65 private:
66  template<typename U>
67  using has_is_transparent = tsl::detail_hopscotch_hash::has_is_transparent<U>;
68 
69  class KeySelect {
70  public:
71  using key_type = Key;
72 
73  const key_type& operator()(const Key& key) const {
74  return key;
75  }
76 
77  key_type& operator()(Key& key) {
78  return key;
79  }
80  };
81 
82 
83  using overflow_container_type = std::set<Key, Compare, Allocator>;
84  using ht = tsl::detail_hopscotch_hash::hopscotch_hash<Key, KeySelect, void,
85  Hash, KeyEqual,
86  Allocator, NeighborhoodSize,
87  StoreHash, GrowthPolicy,
88  overflow_container_type>;
89 
90 public:
91  using key_type = typename ht::key_type;
92  using value_type = typename ht::value_type;
93  using size_type = typename ht::size_type;
94  using difference_type = typename ht::difference_type;
95  using hasher = typename ht::hasher;
96  using key_equal = typename ht::key_equal;
97  using key_compare = Compare;
98  using allocator_type = typename ht::allocator_type;
99  using reference = typename ht::reference;
100  using const_reference = typename ht::const_reference;
101  using pointer = typename ht::pointer;
102  using const_pointer = typename ht::const_pointer;
103  using iterator = typename ht::iterator;
104  using const_iterator = typename ht::const_iterator;
105 
106 
107  /*
108  * Constructors
109  */
110  bhopscotch_set() : bhopscotch_set(ht::DEFAULT_INIT_BUCKETS_SIZE) {
111  }
112 
113  explicit bhopscotch_set(size_type bucket_count,
114  const Hash& hash = Hash(),
115  const KeyEqual& equal = KeyEqual(),
116  const Allocator& alloc = Allocator(),
117  const Compare& comp = Compare()) :
118  m_ht(bucket_count, hash, equal, alloc, ht::DEFAULT_MAX_LOAD_FACTOR, comp)
119  {
120  }
121 
122  bhopscotch_set(size_type bucket_count,
123  const Allocator& alloc) : bhopscotch_set(bucket_count, Hash(), KeyEqual(), alloc)
124  {
125  }
126 
127  bhopscotch_set(size_type bucket_count,
128  const Hash& hash,
129  const Allocator& alloc) : bhopscotch_set(bucket_count, hash, KeyEqual(), alloc)
130  {
131  }
132 
133  explicit bhopscotch_set(const Allocator& alloc) : bhopscotch_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
134  }
135 
136  template<class InputIt>
137  bhopscotch_set(InputIt first, InputIt last,
138  size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
139  const Hash& hash = Hash(),
140  const KeyEqual& equal = KeyEqual(),
141  const Allocator& alloc = Allocator()) : bhopscotch_set(bucket_count, hash, equal, alloc)
142  {
143  insert(first, last);
144  }
145 
146  template<class InputIt>
147  bhopscotch_set(InputIt first, InputIt last,
148  size_type bucket_count,
149  const Allocator& alloc) : bhopscotch_set(first, last, bucket_count, Hash(), KeyEqual(), alloc)
150  {
151  }
152 
153  template<class InputIt>
154  bhopscotch_set(InputIt first, InputIt last,
155  size_type bucket_count,
156  const Hash& hash,
157  const Allocator& alloc) : bhopscotch_set(first, last, bucket_count, hash, KeyEqual(), alloc)
158  {
159  }
160 
161  bhopscotch_set(std::initializer_list<value_type> init,
162  size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
163  const Hash& hash = Hash(),
164  const KeyEqual& equal = KeyEqual(),
165  const Allocator& alloc = Allocator()) :
166  bhopscotch_set(init.begin(), init.end(), bucket_count, hash, equal, alloc)
167  {
168  }
169 
170  bhopscotch_set(std::initializer_list<value_type> init,
171  size_type bucket_count,
172  const Allocator& alloc) :
173  bhopscotch_set(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(), alloc)
174  {
175  }
176 
177  bhopscotch_set(std::initializer_list<value_type> init,
178  size_type bucket_count,
179  const Hash& hash,
180  const Allocator& alloc) :
181  bhopscotch_set(init.begin(), init.end(), bucket_count, hash, KeyEqual(), alloc)
182  {
183  }
184 
185 
186  bhopscotch_set& operator=(std::initializer_list<value_type> ilist) {
187  m_ht.clear();
188 
189  m_ht.reserve(ilist.size());
190  m_ht.insert(ilist.begin(), ilist.end());
191 
192  return *this;
193  }
194 
195  allocator_type get_allocator() const { return m_ht.get_allocator(); }
196 
197 
198  /*
199  * Iterators
200  */
201  iterator begin() noexcept { return m_ht.begin(); }
202  const_iterator begin() const noexcept { return m_ht.begin(); }
203  const_iterator cbegin() const noexcept { return m_ht.cbegin(); }
204 
205  iterator end() noexcept { return m_ht.end(); }
206  const_iterator end() const noexcept { return m_ht.end(); }
207  const_iterator cend() const noexcept { return m_ht.cend(); }
208 
209 
210  /*
211  * Capacity
212  */
213  bool empty() const noexcept { return m_ht.empty(); }
214  size_type size() const noexcept { return m_ht.size(); }
215  size_type max_size() const noexcept { return m_ht.max_size(); }
216 
217  /*
218  * Modifiers
219  */
220  void clear() noexcept { m_ht.clear(); }
221 
222 
223 
224 
225  std::pair<iterator, bool> insert(const value_type& value) { return m_ht.insert(value); }
226  std::pair<iterator, bool> insert(value_type&& value) { return m_ht.insert(std::move(value)); }
227 
228  iterator insert(const_iterator hint, const value_type& value) { return m_ht.insert(hint, value); }
229  iterator insert(const_iterator hint, value_type&& value) { return m_ht.insert(hint, std::move(value)); }
230 
231  template<class InputIt>
232  void insert(InputIt first, InputIt last) { m_ht.insert(first, last); }
233  void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist.begin(), ilist.end()); }
234 
235 
236 
237 
238  /**
239  * Due to the way elements are stored, emplace will need to move or copy the key-value once.
240  * The method is equivalent to insert(value_type(std::forward<Args>(args)...));
241  *
242  * Mainly here for compatibility with the std::unordered_map interface.
243  */
244  template<class... Args>
245  std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); }
246 
247 
248 
249 
250  /**
251  * Due to the way elements are stored, emplace_hint will need to move or copy the key-value once.
252  * The method is equivalent to insert(hint, value_type(std::forward<Args>(args)...));
253  *
254  * Mainly here for compatibility with the std::unordered_map interface.
255  */
256  template<class... Args>
257  iterator emplace_hint(const_iterator hint, Args&&... args) {
258  return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
259  }
260 
261 
262 
263 
264  iterator erase(iterator pos) { return m_ht.erase(pos); }
265  iterator erase(const_iterator pos) { return m_ht.erase(pos); }
266  iterator erase(const_iterator first, const_iterator last) { return m_ht.erase(first, last); }
267  size_type erase(const key_type& key) { return m_ht.erase(key); }
268 
269  /**
270  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
271  * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
272  */
273  size_type erase(const key_type& key, std::size_t precalculated_hash) {
274  return m_ht.erase(key, precalculated_hash);
275  }
276 
277  /**
278  * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent
279  * and Compare::is_transparent exist.
280  * If so, K must be hashable and comparable to Key.
281  */
282  template<class K, class KE = KeyEqual, class CP = Compare,
283  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
284  size_type erase(const K& key) { return m_ht.erase(key); }
285 
286  /**
287  * @copydoc erase(const K& key)
288  *
289  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
290  * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
291  */
292  template<class K, class KE = KeyEqual, class CP = Compare,
293  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
294  size_type erase(const K& key, std::size_t precalculated_hash) { return m_ht.erase(key, precalculated_hash); }
295 
296 
297 
298 
299  void swap(bhopscotch_set& other) { other.m_ht.swap(m_ht); }
300 
301 
302  /*
303  * Lookup
304  */
305  size_type count(const Key& key) const { return m_ht.count(key); }
306 
307  /**
308  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
309  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
310  */
311  size_type count(const Key& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
312 
313  /**
314  * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent
315  * and Compare::is_transparent exist.
316  * If so, K must be hashable and comparable to Key.
317  */
318  template<class K, class KE = KeyEqual, class CP = Compare,
319  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
320  size_type count(const K& key) const { return m_ht.count(key); }
321 
322  /**
323  * @copydoc count(const K& key) const
324  *
325  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
326  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
327  */
328  template<class K, class KE = KeyEqual, class CP = Compare,
329  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
330  size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
331 
332 
333 
334 
335  iterator find(const Key& key) { return m_ht.find(key); }
336 
337  /**
338  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
339  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
340  */
341  iterator find(const Key& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
342 
343  const_iterator find(const Key& key) const { return m_ht.find(key); }
344 
345  /**
346  * @copydoc find(const Key& key, std::size_t precalculated_hash)
347  */
348  const_iterator find(const Key& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); }
349 
350  /**
351  * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent
352  * and Compare::is_transparent exist.
353  * If so, K must be hashable and comparable to Key.
354  */
355  template<class K, class KE = KeyEqual, class CP = Compare,
356  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
357  iterator find(const K& key) { return m_ht.find(key); }
358 
359  /**
360  * @copydoc find(const K& key)
361  *
362  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
363  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
364  */
365  template<class K, class KE = KeyEqual, class CP = Compare,
366  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
367  iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
368 
369  /**
370  * @copydoc find(const K& key)
371  */
372  template<class K, class KE = KeyEqual, class CP = Compare,
373  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
374  const_iterator find(const K& key) const { return m_ht.find(key); }
375 
376  /**
377  * @copydoc find(const K& key)
378  *
379  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
380  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
381  */
382  template<class K, class KE = KeyEqual, class CP = Compare,
383  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
384  const_iterator find(const K& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); }
385 
386 
387 
388 
389  std::pair<iterator, iterator> equal_range(const Key& key) { return m_ht.equal_range(key); }
390 
391  /**
392  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
393  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
394  */
395  std::pair<iterator, iterator> equal_range(const Key& key, std::size_t precalculated_hash) {
396  return m_ht.equal_range(key, precalculated_hash);
397  }
398 
399  std::pair<const_iterator, const_iterator> equal_range(const Key& key) const { return m_ht.equal_range(key); }
400 
401  /**
402  * @copydoc equal_range(const Key& key, std::size_t precalculated_hash)
403  */
404  std::pair<const_iterator, const_iterator> equal_range(const Key& key, std::size_t precalculated_hash) const {
405  return m_ht.equal_range(key, precalculated_hash);
406  }
407 
408  /**
409  * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent
410  * and Compare::is_transparent exist.
411  * If so, K must be hashable and comparable to Key.
412  */
413  template<class K, class KE = KeyEqual, class CP = Compare,
414  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
415  std::pair<iterator, iterator> equal_range(const K& key) { return m_ht.equal_range(key); }
416 
417  /**
418  * @copydoc equal_range(const K& key)
419  *
420  * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
421  * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
422  */
423  template<class K, class KE = KeyEqual, class CP = Compare,
424  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
425  std::pair<iterator, iterator> equal_range(const K& key, std::size_t precalculated_hash) {
426  return m_ht.equal_range(key, precalculated_hash);
427  }
428 
429  /**
430  * @copydoc equal_range(const K& key)
431  */
432  template<class K, class KE = KeyEqual, class CP = Compare,
433  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
434  std::pair<const_iterator, const_iterator> equal_range(const K& key) const { return m_ht.equal_range(key); }
435 
436  /**
437  * @copydoc equal_range(const K& key, std::size_t precalculated_hash)
438  */
439  template<class K, class KE = KeyEqual, class CP = Compare,
440  typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* = nullptr>
441  std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t precalculated_hash) const {
442  return m_ht.equal_range(key, precalculated_hash);
443  }
444 
445 
446 
447 
448  /*
449  * Bucket interface
450  */
451  size_type bucket_count() const { return m_ht.bucket_count(); }
452  size_type max_bucket_count() const { return m_ht.max_bucket_count(); }
453 
454 
455  /*
456  * Hash policy
457  */
458  float load_factor() const { return m_ht.load_factor(); }
459  float max_load_factor() const { return m_ht.max_load_factor(); }
460  void max_load_factor(float ml) { m_ht.max_load_factor(ml); }
461 
462  void rehash(size_type count_) { m_ht.rehash(count_); }
463  void reserve(size_type count_) { m_ht.reserve(count_); }
464 
465 
466  /*
467  * Observers
468  */
469  hasher hash_function() const { return m_ht.hash_function(); }
470  key_equal key_eq() const { return m_ht.key_eq(); }
471  key_compare key_comp() const { return m_ht.key_comp(); }
472 
473 
474  /*
475  * Other
476  */
477 
478  /**
479  * Convert a const_iterator to an iterator.
480  */
481  iterator mutable_iterator(const_iterator pos) {
482  return m_ht.mutable_iterator(pos);
483  }
484 
485  size_type overflow_size() const noexcept { return m_ht.overflow_size(); }
486 
487  friend bool operator==(const bhopscotch_set& lhs, const bhopscotch_set& rhs) {
488  if(lhs.size() != rhs.size()) {
489  return false;
490  }
491 
492  for(const auto& element_lhs : lhs) {
493  const auto it_element_rhs = rhs.find(element_lhs);
494  if(it_element_rhs == rhs.cend()) {
495  return false;
496  }
497  }
498 
499  return true;
500  }
501 
502  friend bool operator!=(const bhopscotch_set& lhs, const bhopscotch_set& rhs) {
503  return !operator==(lhs, rhs);
504  }
505 
506  friend void swap(bhopscotch_set& lhs, bhopscotch_set& rhs) {
507  lhs.swap(rhs);
508  }
509 
510 private:
511  ht m_ht;
512 };
513 
514 
515 /**
516  * Same as `tsl::bhopscotch_set<Key, Hash, KeyEqual, Compare, Allocator, NeighborhoodSize, StoreHash, tsl::hh::prime_growth_policy>`.
517  */
518 template<class Key,
519  class Hash = std::hash<Key>,
520  class KeyEqual = std::equal_to<Key>,
521  class Compare = std::less<Key>,
522  class Allocator = std::allocator<Key>,
523  unsigned int NeighborhoodSize = 62,
524  bool StoreHash = false>
525 using bhopscotch_pg_set = bhopscotch_set<Key, Hash, KeyEqual, Compare, Allocator, NeighborhoodSize, StoreHash, tsl::hh::prime_growth_policy>;
526 
527 } // end namespace tsl
528 
529 #endif
void swap(bhopscotch_set &other)
Definition: bhopscotch_set.h:299
bhopscotch_set(InputIt first, InputIt last, size_type bucket_count=ht::DEFAULT_INIT_BUCKETS_SIZE, const Hash &hash=Hash(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator())
Definition: bhopscotch_set.h:137
void max_load_factor(float ml)
Definition: bhopscotch_set.h:460
bhopscotch_set()
Definition: bhopscotch_set.h:110
bhopscotch_set(size_type bucket_count, const Hash &hash=Hash(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator(), const Compare &comp=Compare())
Definition: bhopscotch_set.h:113
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition: bhopscotch_set.h:257
size_type overflow_size() const noexcept
Definition: bhopscotch_set.h:485
std::pair< iterator, bool > insert(const value_type &value)
Definition: bhopscotch_set.h:225
Definition: hopscotch_hash.h:69
bhopscotch_set(InputIt first, InputIt last, size_type bucket_count, const Allocator &alloc)
Definition: bhopscotch_set.h:147
std::pair< iterator, iterator > equal_range(const Key &key, std::size_t precalculated_hash)
Definition: bhopscotch_set.h:395
void rehash(size_type count_)
Definition: bhopscotch_set.h:462
Definition: bhopscotch_map.h:39
float load_factor() const
Definition: bhopscotch_set.h:458
iterator find(const Key &key)
Definition: bhopscotch_set.h:335
bool empty() const noexcept
Definition: bhopscotch_set.h:213
bhopscotch_set(InputIt first, InputIt last, size_type bucket_count, const Hash &hash, const Allocator &alloc)
Definition: bhopscotch_set.h:154
size_type erase(const key_type &key)
Definition: bhopscotch_set.h:267
iterator begin() noexcept
Definition: bhopscotch_set.h:201
void clear() noexcept
Definition: bhopscotch_set.h:220
bhopscotch_set(size_type bucket_count, const Allocator &alloc)
Definition: bhopscotch_set.h:122
const_iterator cend() const noexcept
Definition: bhopscotch_set.h:207
std::pair< iterator, bool > insert(value_type &&value)
Definition: bhopscotch_set.h:226
size_type erase(const K &key)
Definition: bhopscotch_set.h:284
std::pair< iterator, iterator > equal_range(const Key &key)
Definition: bhopscotch_set.h:389
void insert(std::initializer_list< value_type > ilist)
Definition: bhopscotch_set.h:233
iterator erase(const_iterator pos)
Definition: bhopscotch_set.h:265
iterator find(const K &key)
Definition: bhopscotch_set.h:357
Definition: bhopscotch_set.h:64
size_type max_size() const noexcept
Definition: bhopscotch_set.h:215
size_type size() const noexcept
Definition: bhopscotch_set.h:214
bhopscotch_set(size_type bucket_count, const Hash &hash, const Allocator &alloc)
Definition: bhopscotch_set.h:127
key_compare key_comp() const
Definition: bhopscotch_set.h:471
allocator_type get_allocator() const
Definition: bhopscotch_set.h:195
iterator find(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_set.h:367
friend void swap(bhopscotch_set &lhs, bhopscotch_set &rhs)
Definition: bhopscotch_set.h:506
const_iterator find(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_set.h:348
bhopscotch_set(const Allocator &alloc)
Definition: bhopscotch_set.h:133
iterator end() noexcept
Definition: bhopscotch_set.h:205
key_equal key_eq() const
Definition: bhopscotch_set.h:470
std::pair< const_iterator, const_iterator > equal_range(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_set.h:404
size_type erase(const key_type &key, std::size_t precalculated_hash)
Definition: bhopscotch_set.h:273
size_type count(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_set.h:311
hasher hash_function() const
Definition: bhopscotch_set.h:469
const_iterator end() const noexcept
Definition: bhopscotch_set.h:206
Definition: hopscotch_growth_policy.h:49
const_iterator find(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_set.h:384
size_type count(const Key &key) const
Definition: bhopscotch_set.h:305
bhopscotch_set(std::initializer_list< value_type > init, size_type bucket_count, const Allocator &alloc)
Definition: bhopscotch_set.h:170
std::pair< const_iterator, const_iterator > equal_range(const Key &key) const
Definition: bhopscotch_set.h:399
std::pair< const_iterator, const_iterator > equal_range(const K &key) const
Definition: bhopscotch_set.h:434
Definition: hopscotch_growth_policy.h:247
iterator find(const Key &key, std::size_t precalculated_hash)
Definition: bhopscotch_set.h:341
std::pair< iterator, iterator > equal_range(const K &key)
Definition: bhopscotch_set.h:415
friend bool operator==(const bhopscotch_set &lhs, const bhopscotch_set &rhs)
Definition: bhopscotch_set.h:487
size_type max_bucket_count() const
Definition: bhopscotch_set.h:452
std::pair< const_iterator, const_iterator > equal_range(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_set.h:441
size_type bucket_count() const
Definition: bhopscotch_set.h:451
void insert(InputIt first, InputIt last)
Definition: bhopscotch_set.h:232
const_iterator find(const Key &key) const
Definition: bhopscotch_set.h:343
iterator insert(const_iterator hint, const value_type &value)
Definition: bhopscotch_set.h:228
friend bool operator!=(const bhopscotch_set &lhs, const bhopscotch_set &rhs)
Definition: bhopscotch_set.h:502
const_iterator begin() const noexcept
Definition: bhopscotch_set.h:202
iterator erase(iterator pos)
Definition: bhopscotch_set.h:264
bhopscotch_set(std::initializer_list< value_type > init, size_type bucket_count=ht::DEFAULT_INIT_BUCKETS_SIZE, const Hash &hash=Hash(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator())
Definition: bhopscotch_set.h:161
size_type count(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_set.h:330
void reserve(size_type count_)
Definition: bhopscotch_set.h:463
std::pair< iterator, iterator > equal_range(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_set.h:425
const_iterator find(const K &key) const
Definition: bhopscotch_set.h:374
iterator insert(const_iterator hint, value_type &&value)
Definition: bhopscotch_set.h:229
iterator mutable_iterator(const_iterator pos)
Definition: bhopscotch_set.h:481
size_type erase(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_set.h:294
bhopscotch_set(std::initializer_list< value_type > init, size_type bucket_count, const Hash &hash, const Allocator &alloc)
Definition: bhopscotch_set.h:177
std::pair< iterator, bool > emplace(Args &&... args)
Definition: bhopscotch_set.h:245
Definition: hopscotch_growth_policy.h:40
iterator erase(const_iterator first, const_iterator last)
Definition: bhopscotch_set.h:266
float max_load_factor() const
Definition: bhopscotch_set.h:459
size_type count(const K &key) const
Definition: bhopscotch_set.h:320
const_iterator cbegin() const noexcept
Definition: bhopscotch_set.h:203
bhopscotch_set & operator=(std::initializer_list< value_type > ilist)
Definition: bhopscotch_set.h:186