24 #ifndef TSL_BHOPSCOTCH_MAP_H 25 #define TSL_BHOPSCOTCH_MAP_H 31 #include <initializer_list> 34 #include <type_traits> 58 class Hash = std::hash<Key>,
59 class KeyEqual = std::equal_to<Key>,
60 class Compare = std::less<Key>,
61 class Allocator = std::allocator<std::pair<
const Key, T>>,
62 unsigned int NeighborhoodSize = 62,
63 bool StoreHash =
false,
74 const key_type& operator()(
const std::pair<
const Key, T>& key_value)
const {
75 return key_value.first;
78 const key_type& operator()(std::pair<
const Key, T>& key_value) {
79 return key_value.first;
87 const value_type& operator()(
const std::pair<
const Key, T>& key_value)
const {
88 return key_value.second;
91 value_type& operator()(std::pair<Key, T>& key_value) {
92 return key_value.second;
99 using overflow_container_type = std::map<Key, T, Compare, Allocator>;
102 Allocator, NeighborhoodSize,
103 StoreHash, GrowthPolicy,
104 overflow_container_type>;
107 using key_type =
typename ht::key_type;
108 using mapped_type = T;
109 using value_type =
typename ht::value_type;
110 using size_type =
typename ht::size_type;
111 using difference_type =
typename ht::difference_type;
112 using hasher =
typename ht::hasher;
113 using key_equal =
typename ht::key_equal;
114 using key_compare = Compare;
115 using allocator_type =
typename ht::allocator_type;
116 using reference =
typename ht::reference;
117 using const_reference =
typename ht::const_reference;
118 using pointer =
typename ht::pointer;
119 using const_pointer =
typename ht::const_pointer;
120 using iterator =
typename ht::iterator;
121 using const_iterator =
typename ht::const_iterator;
131 const Hash& hash = Hash(),
132 const KeyEqual& equal = KeyEqual(),
133 const Allocator& alloc = Allocator(),
134 const Compare& comp = Compare()) :
135 m_ht(bucket_count, hash, equal, alloc, ht::DEFAULT_MAX_LOAD_FACTOR, comp)
140 const Allocator& alloc) :
bhopscotch_map(bucket_count, Hash(), KeyEqual(), alloc)
146 const Allocator& alloc) :
bhopscotch_map(bucket_count, hash, KeyEqual(), alloc)
153 template<
class InputIt>
155 size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
156 const Hash& hash = Hash(),
157 const KeyEqual& equal = KeyEqual(),
158 const Allocator& alloc = Allocator()) :
bhopscotch_map(bucket_count, hash, equal, alloc)
163 template<
class InputIt>
165 size_type bucket_count,
166 const Allocator& alloc) :
bhopscotch_map(first, last, bucket_count, Hash(), KeyEqual(), alloc)
170 template<
class InputIt>
172 size_type bucket_count,
174 const Allocator& alloc) :
bhopscotch_map(first, last, bucket_count, hash, KeyEqual(), alloc)
179 size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
180 const Hash& hash = Hash(),
181 const KeyEqual& equal = KeyEqual(),
182 const Allocator& alloc = Allocator()) :
183 bhopscotch_map(init.begin(), init.end(), bucket_count, hash, equal, alloc)
188 size_type bucket_count,
189 const Allocator& alloc) :
190 bhopscotch_map(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(), alloc)
195 size_type bucket_count,
197 const Allocator& alloc) :
198 bhopscotch_map(init.begin(), init.end(), bucket_count, hash, KeyEqual(), alloc)
206 m_ht.reserve(ilist.size());
207 m_ht.insert(ilist.begin(), ilist.end());
218 iterator
begin()
noexcept {
return m_ht.begin(); }
219 const_iterator
begin()
const noexcept {
return m_ht.begin(); }
220 const_iterator
cbegin()
const noexcept {
return m_ht.cbegin(); }
222 iterator
end()
noexcept {
return m_ht.end(); }
223 const_iterator
end()
const noexcept {
return m_ht.end(); }
224 const_iterator
cend()
const noexcept {
return m_ht.cend(); }
230 bool empty()
const noexcept {
return m_ht.empty(); }
231 size_type
size()
const noexcept {
return m_ht.size(); }
232 size_type
max_size()
const noexcept {
return m_ht.max_size(); }
237 void clear()
noexcept { m_ht.clear(); }
242 std::pair<iterator,
bool>
insert(
const value_type& value) {
243 return m_ht.insert(value);
246 template<
class P,
typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* =
nullptr>
247 std::pair<iterator,
bool>
insert(P&& value) {
248 return m_ht.insert(std::forward<P>(value));
251 std::pair<iterator,
bool>
insert(value_type&& value) {
252 return m_ht.insert(std::move(value));
256 iterator
insert(const_iterator hint,
const value_type& value) {
257 return m_ht.insert(hint, value);
260 template<
class P,
typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* =
nullptr>
261 iterator
insert(const_iterator hint, P&& value) {
262 return m_ht.insert(hint, std::forward<P>(value));
265 iterator
insert(const_iterator hint, value_type&& value) {
266 return m_ht.insert(hint, std::move(value));
270 template<
class InputIt>
271 void insert(InputIt first, InputIt last) {
272 m_ht.insert(first, last);
275 void insert(std::initializer_list<value_type> ilist) {
276 m_ht.insert(ilist.begin(), ilist.end());
284 return m_ht.insert_or_assign(k, std::forward<M>(obj));
289 return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj));
294 return m_ht.insert_or_assign(hint, k, std::forward<M>(obj));
299 return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj));
310 template<
class... Args>
311 std::pair<iterator,
bool>
emplace(Args&&... args) {
312 return m_ht.emplace(std::forward<Args>(args)...);
324 template<
class... Args>
326 return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
332 template<
class... Args>
333 std::pair<iterator,
bool>
try_emplace(
const key_type& k, Args&&... args) {
334 return m_ht.try_emplace(k, std::forward<Args>(args)...);
337 template<
class... Args>
338 std::pair<iterator,
bool>
try_emplace(key_type&& k, Args&&... args) {
339 return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...);
342 template<
class... Args>
343 iterator
try_emplace(const_iterator hint,
const key_type& k, Args&&... args) {
344 return m_ht.try_emplace(hint, k, std::forward<Args>(args)...);
347 template<
class... Args>
348 iterator
try_emplace(const_iterator hint, key_type&& k, Args&&... args) {
349 return m_ht.try_emplace(hint, std::move(k), std::forward<Args>(args)...);
355 iterator
erase(iterator pos) {
return m_ht.erase(pos); }
356 iterator
erase(const_iterator pos) {
return m_ht.erase(pos); }
357 iterator
erase(const_iterator first, const_iterator last) {
return m_ht.erase(first, last); }
358 size_type
erase(
const key_type& key) {
return m_ht.erase(key); }
364 size_type
erase(
const key_type& key, std::size_t precalculated_hash) {
365 return m_ht.erase(key, precalculated_hash);
373 template<
class K,
class KE = KeyEqual,
class CP = Compare,
374 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
375 size_type
erase(
const K& key) {
return m_ht.erase(key); }
383 template<
class K,
class KE = KeyEqual,
class CP = Compare,
384 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
385 size_type
erase(
const K& key, std::size_t precalculated_hash) {
return m_ht.erase(key, precalculated_hash); }
395 T&
at(
const Key& key) {
return m_ht.at(key); }
401 T&
at(
const Key& key, std::size_t precalculated_hash) {
return m_ht.at(key, precalculated_hash); }
403 const T&
at(
const Key& key)
const {
return m_ht.at(key); }
408 const T&
at(
const Key& key, std::size_t precalculated_hash)
const {
return m_ht.at(key, precalculated_hash); }
415 template<
class K,
class KE = KeyEqual,
class CP = Compare,
416 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
417 T&
at(
const K& key) {
return m_ht.at(key); }
425 template<
class K,
class KE = KeyEqual,
class CP = Compare,
426 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
427 T&
at(
const K& key, std::size_t precalculated_hash) {
return m_ht.at(key, precalculated_hash); }
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 const T&
at(
const K& key)
const {
return m_ht.at(key); }
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 const T&
at(
const K& key, std::size_t precalculated_hash)
const {
return m_ht.at(key, precalculated_hash); }
446 T&
operator[](
const Key& key) {
return m_ht[key]; }
447 T&
operator[](Key&& key) {
return m_ht[std::move(key)]; }
452 size_type
count(
const Key& key)
const {
return m_ht.count(key); }
458 size_type
count(
const Key& key, std::size_t precalculated_hash)
const {
return m_ht.count(key, precalculated_hash); }
465 template<
class K,
class KE = KeyEqual,
class CP = Compare,
466 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
467 size_type
count(
const K& key)
const {
return m_ht.count(key); }
475 template<
class K,
class KE = KeyEqual,
class CP = Compare,
476 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
477 size_type
count(
const K& key, std::size_t precalculated_hash)
const {
return m_ht.count(key, precalculated_hash); }
482 iterator
find(
const Key& key) {
return m_ht.find(key); }
488 iterator
find(
const Key& key, std::size_t precalculated_hash) {
return m_ht.find(key, precalculated_hash); }
490 const_iterator
find(
const Key& key)
const {
return m_ht.find(key); }
495 const_iterator
find(
const Key& key, std::size_t precalculated_hash)
const {
return m_ht.find(key, precalculated_hash); }
502 template<
class K,
class KE = KeyEqual,
class CP = Compare,
503 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
504 iterator
find(
const K& key) {
return m_ht.find(key); }
512 template<
class K,
class KE = KeyEqual,
class CP = Compare,
513 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
514 iterator
find(
const K& key, std::size_t precalculated_hash) {
return m_ht.find(key, precalculated_hash); }
519 template<
class K,
class KE = KeyEqual,
class CP = Compare,
520 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
521 const_iterator
find(
const K& key)
const {
return m_ht.find(key); }
526 template<
class K,
class KE = KeyEqual,
class CP = Compare,
527 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
528 const_iterator
find(
const K& key, std::size_t precalculated_hash)
const {
return m_ht.find(key, precalculated_hash); }
533 std::pair<iterator, iterator>
equal_range(
const Key& key) {
return m_ht.equal_range(key); }
539 std::pair<iterator, iterator>
equal_range(
const Key& key, std::size_t precalculated_hash) {
540 return m_ht.equal_range(key, precalculated_hash);
543 std::pair<const_iterator, const_iterator>
equal_range(
const Key& key)
const {
return m_ht.equal_range(key); }
548 std::pair<const_iterator, const_iterator>
equal_range(
const Key& key, std::size_t precalculated_hash)
const {
549 return m_ht.equal_range(key, precalculated_hash);
557 template<
class K,
class KE = KeyEqual,
class CP = Compare,
558 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
559 std::pair<iterator, iterator>
equal_range(
const K& key) {
return m_ht.equal_range(key); }
567 template<
class K,
class KE = KeyEqual,
class CP = Compare,
568 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
569 std::pair<iterator, iterator>
equal_range(
const K& key, std::size_t precalculated_hash) {
570 return m_ht.equal_range(key, precalculated_hash);
576 template<
class K,
class KE = KeyEqual,
class CP = Compare,
577 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
578 std::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const {
return m_ht.equal_range(key); }
583 template<
class K,
class KE = KeyEqual,
class CP = Compare,
584 typename std::enable_if<has_is_transparent<KE>::value && has_is_transparent<CP>::value>::type* =
nullptr>
585 std::pair<const_iterator, const_iterator>
equal_range(
const K& key, std::size_t precalculated_hash)
const {
586 return m_ht.equal_range(key, precalculated_hash);
606 void rehash(size_type count_) { m_ht.rehash(count_); }
607 void reserve(size_type count_) { m_ht.reserve(count_); }
614 key_equal
key_eq()
const {
return m_ht.key_eq(); }
615 key_compare
key_comp()
const {
return m_ht.key_comp(); }
625 return m_ht.mutable_iterator(pos);
631 if(lhs.size() != rhs.size()) {
635 for(
const auto& element_lhs : lhs) {
636 const auto it_element_rhs = rhs.find(element_lhs.first);
637 if(it_element_rhs == rhs.cend() || element_lhs.second != it_element_rhs->second) {
646 return !operator==(lhs, rhs);
665 class Hash = std::hash<Key>,
666 class KeyEqual = std::equal_to<Key>,
667 class Compare = std::less<Key>,
668 class Allocator = std::allocator<std::pair<
const Key, T>>,
669 unsigned int NeighborhoodSize = 62,
670 bool StoreHash =
false>
std::pair< iterator, bool > insert_or_assign(key_type &&k, M &&obj)
Definition: bhopscotch_map.h:288
const_iterator cbegin() const noexcept
Definition: bhopscotch_map.h:220
size_type bucket_count() const
Definition: bhopscotch_map.h:595
std::pair< iterator, bool > insert(const value_type &value)
Definition: bhopscotch_map.h:242
iterator find(const K &key)
Definition: bhopscotch_map.h:504
void insert(InputIt first, InputIt last)
Definition: bhopscotch_map.h:271
T & at(const Key &key)
Definition: bhopscotch_map.h:395
iterator begin() noexcept
Definition: bhopscotch_map.h:218
size_type overflow_size() const noexcept
Definition: bhopscotch_map.h:628
void swap(bhopscotch_map &other)
Definition: bhopscotch_map.h:390
std::pair< const_iterator, const_iterator > equal_range(const Key &key) const
Definition: bhopscotch_map.h:543
bhopscotch_map()
Definition: bhopscotch_map.h:127
Definition: hopscotch_hash.h:69
T & operator[](Key &&key)
Definition: bhopscotch_map.h:447
Definition: bhopscotch_map.h:39
iterator find(const Key &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:488
std::pair< iterator, iterator > equal_range(const Key &key)
Definition: bhopscotch_map.h:533
T & operator[](const Key &key)
Definition: bhopscotch_map.h:446
const T & at(const K &key) const
Definition: bhopscotch_map.h:434
bhopscotch_map(InputIt first, InputIt last, size_type bucket_count, const Allocator &alloc)
Definition: bhopscotch_map.h:164
std::pair< iterator, bool > insert(P &&value)
Definition: bhopscotch_map.h:247
std::pair< iterator, iterator > equal_range(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:569
iterator mutable_iterator(const_iterator pos)
Definition: bhopscotch_map.h:624
void insert(std::initializer_list< value_type > ilist)
Definition: bhopscotch_map.h:275
bool empty() const noexcept
Definition: bhopscotch_map.h:230
bhopscotch_map(const Allocator &alloc)
Definition: bhopscotch_map.h:150
const_iterator find(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:528
const T & at(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:408
bhopscotch_map(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_map.h:178
std::pair< const_iterator, const_iterator > equal_range(const K &key) const
Definition: bhopscotch_map.h:578
iterator erase(const_iterator pos)
Definition: bhopscotch_map.h:356
const_iterator end() const noexcept
Definition: bhopscotch_map.h:223
bhopscotch_map(InputIt first, InputIt last, size_type bucket_count, const Hash &hash, const Allocator &alloc)
Definition: bhopscotch_map.h:171
key_compare key_comp() const
Definition: bhopscotch_map.h:615
const_iterator begin() const noexcept
Definition: bhopscotch_map.h:219
const_iterator find(const K &key) const
Definition: bhopscotch_map.h:521
iterator end() noexcept
Definition: bhopscotch_map.h:222
bhopscotch_map(size_type bucket_count, const Hash &hash=Hash(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator(), const Compare &comp=Compare())
Definition: bhopscotch_map.h:130
bhopscotch_map & operator=(std::initializer_list< value_type > ilist)
Definition: bhopscotch_map.h:203
friend bool operator==(const bhopscotch_map &lhs, const bhopscotch_map &rhs)
Definition: bhopscotch_map.h:630
iterator find(const Key &key)
Definition: bhopscotch_map.h:482
const_iterator find(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:495
const T & at(const Key &key) const
Definition: bhopscotch_map.h:403
friend bool operator!=(const bhopscotch_map &lhs, const bhopscotch_map &rhs)
Definition: bhopscotch_map.h:645
const T & at(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:441
iterator try_emplace(const_iterator hint, const key_type &k, Args &&... args)
Definition: bhopscotch_map.h:343
hasher hash_function() const
Definition: bhopscotch_map.h:613
std::pair< iterator, bool > insert(value_type &&value)
Definition: bhopscotch_map.h:251
size_type erase(const key_type &key)
Definition: bhopscotch_map.h:358
size_type erase(const key_type &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:364
std::pair< iterator, bool > try_emplace(key_type &&k, Args &&... args)
Definition: bhopscotch_map.h:338
T & at(const Key &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:401
iterator find(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:514
void reserve(size_type count_)
Definition: bhopscotch_map.h:607
T & at(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:427
size_type max_size() const noexcept
Definition: bhopscotch_map.h:232
std::pair< iterator, bool > emplace(Args &&... args)
Definition: bhopscotch_map.h:311
const_iterator find(const Key &key) const
Definition: bhopscotch_map.h:490
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition: bhopscotch_map.h:325
iterator insert_or_assign(const_iterator hint, key_type &&k, M &&obj)
Definition: bhopscotch_map.h:298
Definition: hopscotch_growth_policy.h:49
iterator erase(iterator pos)
Definition: bhopscotch_map.h:355
size_type erase(const K &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:385
size_type count(const Key &key) const
Definition: bhopscotch_map.h:452
bhopscotch_map(size_type bucket_count, const Hash &hash, const Allocator &alloc)
Definition: bhopscotch_map.h:144
Definition: hopscotch_growth_policy.h:247
iterator insert(const_iterator hint, value_type &&value)
Definition: bhopscotch_map.h:265
iterator insert(const_iterator hint, P &&value)
Definition: bhopscotch_map.h:261
allocator_type get_allocator() const
Definition: bhopscotch_map.h:212
iterator insert(const_iterator hint, const value_type &value)
Definition: bhopscotch_map.h:256
std::pair< iterator, bool > insert_or_assign(const key_type &k, M &&obj)
Definition: bhopscotch_map.h:283
bhopscotch_map(std::initializer_list< value_type > init, size_type bucket_count, const Allocator &alloc)
Definition: bhopscotch_map.h:187
iterator erase(const_iterator first, const_iterator last)
Definition: bhopscotch_map.h:357
void max_load_factor(float ml)
Definition: bhopscotch_map.h:604
const_iterator cend() const noexcept
Definition: bhopscotch_map.h:224
bhopscotch_map(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_map.h:154
Definition: bhopscotch_map.h:65
size_type size() const noexcept
Definition: bhopscotch_map.h:231
size_type erase(const K &key)
Definition: bhopscotch_map.h:375
std::pair< const_iterator, const_iterator > equal_range(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:585
size_type count(const K &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:477
std::pair< const_iterator, const_iterator > equal_range(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:548
std::pair< iterator, bool > try_emplace(const key_type &k, Args &&... args)
Definition: bhopscotch_map.h:333
size_type count(const Key &key, std::size_t precalculated_hash) const
Definition: bhopscotch_map.h:458
void clear() noexcept
Definition: bhopscotch_map.h:237
iterator try_emplace(const_iterator hint, key_type &&k, Args &&... args)
Definition: bhopscotch_map.h:348
float load_factor() const
Definition: bhopscotch_map.h:602
std::pair< iterator, iterator > equal_range(const Key &key, std::size_t precalculated_hash)
Definition: bhopscotch_map.h:539
iterator insert_or_assign(const_iterator hint, const key_type &k, M &&obj)
Definition: bhopscotch_map.h:293
bhopscotch_map(size_type bucket_count, const Allocator &alloc)
Definition: bhopscotch_map.h:139
size_type count(const K &key) const
Definition: bhopscotch_map.h:467
std::pair< iterator, iterator > equal_range(const K &key)
Definition: bhopscotch_map.h:559
T & at(const K &key)
Definition: bhopscotch_map.h:417
Definition: hopscotch_growth_policy.h:40
size_type max_bucket_count() const
Definition: bhopscotch_map.h:596
friend void swap(bhopscotch_map &lhs, bhopscotch_map &rhs)
Definition: bhopscotch_map.h:649
void rehash(size_type count_)
Definition: bhopscotch_map.h:606
bhopscotch_map(std::initializer_list< value_type > init, size_type bucket_count, const Hash &hash, const Allocator &alloc)
Definition: bhopscotch_map.h:194
key_equal key_eq() const
Definition: bhopscotch_map.h:614
float max_load_factor() const
Definition: bhopscotch_map.h:603