OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
hopscotch_sc_set.h
1 
24 #ifndef TSL_HOPSCOTCH_SC_SET_H
25 #define TSL_HOPSCOTCH_SC_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 
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::power_of_two_growth_policy>
65 private:
66  template<typename 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>;
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  hopscotch_sc_set() : hopscotch_sc_set(ht::DEFAULT_INIT_BUCKETS_SIZE) {
111  }
112 
113  explicit hopscotch_sc_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  hopscotch_sc_set(size_type bucket_count,
123  const Allocator& alloc) : hopscotch_sc_set(bucket_count, Hash(), KeyEqual(), alloc)
124  {
125  }
126 
127  hopscotch_sc_set(size_type bucket_count,
128  const Hash& hash,
129  const Allocator& alloc) : hopscotch_sc_set(bucket_count, hash, KeyEqual(), alloc)
130  {
131  }
132 
133  explicit hopscotch_sc_set(const Allocator& alloc) : hopscotch_sc_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
134  }
135 
136  template<class InputIt>
137  hopscotch_sc_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()) : hopscotch_sc_set(bucket_count, hash, equal, alloc)
142  {
143  insert(first, last);
144  }
145 
146  template<class InputIt>
147  hopscotch_sc_set(InputIt first, InputIt last,
148  size_type bucket_count,
149  const Allocator& alloc) : hopscotch_sc_set(first, last, bucket_count, Hash(), KeyEqual(), alloc)
150  {
151  }
152 
153  template<class InputIt>
154  hopscotch_sc_set(InputIt first, InputIt last,
155  size_type bucket_count,
156  const Hash& hash,
157  const Allocator& alloc) : hopscotch_sc_set(first, last, bucket_count, hash, KeyEqual(), alloc)
158  {
159  }
160 
161  hopscotch_sc_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  hopscotch_sc_set(init.begin(), init.end(), bucket_count, hash, equal, alloc)
167  {
168  }
169 
170  hopscotch_sc_set(std::initializer_list<value_type> init,
171  size_type bucket_count,
172  const Allocator& alloc) :
173  hopscotch_sc_set(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(), alloc)
174  {
175  }
176 
177  hopscotch_sc_set(std::initializer_list<value_type> init,
178  size_type bucket_count,
179  const Hash& hash,
180  const Allocator& alloc) :
181  hopscotch_sc_set(init.begin(), init.end(), bucket_count, hash, KeyEqual(), alloc)
182  {
183  }
184 
185 
186  hopscotch_sc_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 
244  template<class... Args>
245  std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); }
246 
247 
248 
249 
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 
273  size_type erase(const key_type& key, std::size_t precalculated_hash) {
274  return m_ht.erase(key, precalculated_hash);
275  }
276 
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 
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(hopscotch_sc_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 
311  size_type count(const Key& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); }
312 
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 
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 
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 
348  const_iterator find(const Key& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); }
349 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 hopscotch_sc_set& lhs, const hopscotch_sc_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 hopscotch_sc_set& lhs, const hopscotch_sc_set& rhs) {
503  return !operator==(lhs, rhs);
504  }
505 
506  friend void swap(hopscotch_sc_set& lhs, hopscotch_sc_set& rhs) {
507  lhs.swap(rhs);
508  }
509 
510 private:
511  ht m_ht;
512 };
513 
514 
515 } // end namespace tsl
516 
517 
518 #endif
size_type count(const K &key) const
iterator mutable_iterator(const_iterator pos)
iterator find(const Key &key, std::size_t precalculated_hash)
std::pair< iterator, iterator > equal_range(const Key &key, std::size_t precalculated_hash)
const_iterator find(const K &key, std::size_t precalculated_hash) const
std::pair< iterator, bool > emplace(Args &&... args)
iterator emplace_hint(const_iterator hint, Args &&... args)
iterator find(const K &key, std::size_t precalculated_hash)
const_iterator find(const K &key) const
iterator find(const K &key)
size_type count(const Key &key, std::size_t precalculated_hash) const
std::pair< const_iterator, const_iterator > equal_range(const Key &key, std::size_t precalculated_hash) const
std::pair< iterator, iterator > equal_range(const K &key, std::size_t precalculated_hash)
const_iterator find(const Key &key, std::size_t precalculated_hash) const
std::pair< const_iterator, const_iterator > equal_range(const K &key) const
size_type erase(const key_type &key, std::size_t precalculated_hash)
Structure required for the Sph Harmonic amplitude dictionary arguments.
size_type erase(const K &key, std::size_t precalculated_hash)
OutputIteratorT OffsetT ReductionOpT OuputT init
< [in] The initial value of the reduction
size_type erase(const K &key)
std::pair< iterator, iterator > equal_range(const K &key)
size_type count(const K &key, std::size_t precalculated_hash) const
std::pair< const_iterator, const_iterator > equal_range(const K &key, std::size_t precalculated_hash) const