CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
hashmap.h
Go to the documentation of this file.
9#ifndef CPPCOMMON_CONTAINERS_HASHMAP_H
10#define CPPCOMMON_CONTAINERS_HASHMAP_H
11
12#include <algorithm>
13#include <cassert>
14#include <cstddef>
15#include <functional>
16#include <iterator>
17#include <limits>
18#include <stdexcept>
19#include <vector>
20
21namespace CppCommon {
22
23template <class TContainer, typename TKey, typename TValue>
24class HashMapIterator;
25template <class TContainer, typename TKey, typename TValue>
27template <class TContainer, typename TKey, typename TValue>
29template <class TContainer, typename TKey, typename TValue>
31
33
43template <typename TKey, typename TValue, typename THash = std::hash<TKey>, typename TEqual = std::equal_to<TKey>, typename TAllocator = std::allocator<std::pair<TKey, TValue>>>
45{
46 friend class HashMapIterator<HashMap<TKey, TValue, THash, TEqual, TAllocator>, TKey, TValue>;
47 friend class HashMapConstIterator<HashMap<TKey, TValue, THash, TEqual, TAllocator>, TKey, TValue>;
48 friend class HashMapReverseIterator<HashMap<TKey, TValue, THash, TEqual, TAllocator>, TKey, TValue>;
49 friend class HashMapConstReverseIterator<HashMap<TKey, TValue, THash, TEqual, TAllocator>, TKey, TValue>;
50
51public:
52 // Standard container type definitions
53 typedef TKey key_type;
54 typedef TValue mapped_type;
55 typedef std::pair<TKey, TValue> value_type;
59 typedef const value_type* const_pointer;
60 typedef ptrdiff_t difference_type;
61 typedef size_t size_type;
66
68
75 explicit HashMap(size_t capacity = 128, const TKey& blank = TKey(), const THash& hash = THash(), const TEqual& equal = TEqual(), const TAllocator& allocator = TAllocator());
76 template <class InputIterator>
77 HashMap(InputIterator first, InputIterator last, bool unused, size_t capacity = 128, const TKey& blank = TKey(), const THash& hash = THash(), const TEqual& equal = TEqual(), const TAllocator& allocator = TAllocator());
78 HashMap(const HashMap& hashmap);
79 HashMap(const HashMap& hashmap, size_t capacity);
80 HashMap(HashMap&&) = default;
81 ~HashMap() = default;
82
83 HashMap& operator=(const HashMap& hashmap);
84 HashMap& operator=(HashMap&&) = default;
85
87 explicit operator bool() const noexcept { return !empty(); }
88
90 mapped_type& operator[](const TKey& key) { return emplace_internal(key).first->second; }
91
93 bool empty() const noexcept { return _size == 0; }
94
96 size_t size() const noexcept { return _size; }
98 size_t max_size() const noexcept { return std::numeric_limits<size_type>::max(); }
100 size_t bucket_count() const noexcept { return _buckets.size(); }
102 size_t max_bucket_count() const noexcept { return std::numeric_limits<size_type>::max(); }
103
105 size_t key_hash(const TKey& key) const noexcept { return _hash(key); }
107 bool key_equal(const TKey& key1, const TKey& key2) const noexcept { return _equal(key1, key2); }
108
110 iterator begin() noexcept;
111 const_iterator begin() const noexcept;
112 const_iterator cbegin() const noexcept;
114 iterator end() noexcept;
115 const_iterator end() const noexcept;
116 const_iterator cend() const noexcept;
117
119 reverse_iterator rbegin() noexcept;
120 const_reverse_iterator rbegin() const noexcept;
121 const_reverse_iterator crbegin() const noexcept;
123 reverse_iterator rend() noexcept;
124 const_reverse_iterator rend() const noexcept;
125 const_reverse_iterator crend() const noexcept;
126
128 iterator find(const TKey& key) noexcept;
129 const_iterator find(const TKey& key) const noexcept;
130
132 std::pair<iterator, iterator> equal_range(const TKey& key) noexcept;
133 std::pair<const_iterator, const_iterator> equal_range(const TKey& key) const noexcept;
134
136 size_t count(const TKey& key) const noexcept { return (find(key) == end()) ? 0 : 1; }
137
139
143 mapped_type& at(const TKey& key) noexcept;
145
149 const mapped_type& at(const TKey& key) const noexcept;
150
152
156 std::pair<iterator, bool> insert(const value_type& item);
158
162 std::pair<iterator, bool> insert(value_type&& item);
163
165
169 template <typename... Args>
170 std::pair<iterator, bool> emplace(Args&&... args);
171
173
177 size_t erase(const TKey& key);
179
182 void erase(const const_iterator& position);
183
185
188 void rehash(size_t capacity);
190
193 void reserve(size_t count);
194
196 void clear() noexcept;
197
199 void swap(HashMap& hashmap) noexcept;
200 template <typename UKey, typename UValue, typename UHash, typename UEqual, typename UAllocator>
201 friend void swap(HashMap<UKey, UValue, UHash, UEqual, UAllocator>& hashmap1, HashMap<UKey, UValue, UHash, UEqual, UAllocator>& hashmap2) noexcept;
202
203private:
204 THash _hash; // Hash map key hasher
205 TEqual _equal; // Hash map key comparator
206 TKey _blank; // Hash map blank key
207 size_t _size; // Hash map size
208 std::vector<value_type, TAllocator> _buckets; // Hash map buckets
209
210 template <typename... Args>
211 std::pair<iterator, bool> emplace_internal(const TKey& key, Args&&... args);
212 void erase_internal(size_t index);
213 size_t key_to_index(const TKey& key) const noexcept;
214 size_t next_index(size_t index) const noexcept;
215 size_t diff(size_t index1, size_t index2) const noexcept;
216};
217
219
222template <class TContainer, typename TKey, typename TValue>
224{
226 friend TContainer;
227
228public:
229 // Standard iterator type definitions
230 typedef std::pair<TKey, TValue> value_type;
234 typedef const value_type* const_pointer;
235 typedef ptrdiff_t difference_type;
236 typedef size_t size_type;
237 typedef std::bidirectional_iterator_tag iterator_category;
238
239 HashMapIterator() noexcept : _container(nullptr), _index(0) {}
240 explicit HashMapIterator(TContainer* container) noexcept;
241 explicit HashMapIterator(TContainer* container, size_t index) noexcept : _container(container), _index(index) {}
242 HashMapIterator(const HashMapIterator& it) noexcept = default;
243 HashMapIterator(HashMapIterator&& it) noexcept = default;
244 ~HashMapIterator() noexcept = default;
245
246 HashMapIterator& operator=(const HashMapIterator& it) noexcept = default;
247 HashMapIterator& operator=(HashMapIterator&& it) noexcept = default;
248
249 friend bool operator==(const HashMapIterator& it1, const HashMapIterator& it2) noexcept
250 { return (it1._container == it2._container) && (it1._index == it2._index); }
251 friend bool operator!=(const HashMapIterator& it1, const HashMapIterator& it2) noexcept
252 { return (it1._container != it2._container) || (it1._index != it2._index); }
253
254 HashMapIterator& operator++() noexcept;
255 HashMapIterator operator++(int) noexcept;
256
257 reference operator*() noexcept;
258 pointer operator->() noexcept;
259
261 explicit operator bool() const noexcept { return _container != nullptr; }
262
264 void swap(HashMapIterator& it) noexcept;
265 template <class UContainer, typename UKey, typename UValue>
267
268private:
269 TContainer* _container;
270 size_t _index;
271};
272
274
277template <class TContainer, typename TKey, typename TValue>
279{
280 friend TContainer;
281
282public:
283 // Standard iterator type definitions
284 typedef std::pair<TKey, TValue> value_type;
288 typedef const value_type* const_pointer;
289 typedef ptrdiff_t difference_type;
290 typedef size_t size_type;
291 typedef std::bidirectional_iterator_tag iterator_category;
292
293 HashMapConstIterator() noexcept : _container(nullptr), _index(0) {}
294 explicit HashMapConstIterator(const TContainer* container) noexcept;
295 explicit HashMapConstIterator(const TContainer* container, size_t index) noexcept : _container(container), _index(index) {}
296 HashMapConstIterator(const HashMapIterator<TContainer, TKey, TValue>& it) noexcept : _container(it._container), _index(it._index) {}
297 HashMapConstIterator(const HashMapConstIterator& it) noexcept = default;
299 ~HashMapConstIterator() noexcept = default;
300
301 HashMapConstIterator& operator=(const HashMapIterator<TContainer, TKey, TValue>& it) noexcept
302 { _container = it._container; _index = it._index; return *this; }
305
306 friend bool operator==(const HashMapConstIterator& it1, const HashMapConstIterator& it2) noexcept
307 { return (it1._container == it2._container) && (it1._index == it2._index); }
308 friend bool operator!=(const HashMapConstIterator& it1, const HashMapConstIterator& it2) noexcept
309 { return (it1._container != it2._container) || (it1._index != it2._index); }
310
311 HashMapConstIterator& operator++() noexcept;
312 HashMapConstIterator operator++(int) noexcept;
313
314 const_reference operator*() const noexcept;
315 const_pointer operator->() const noexcept;
316
318 explicit operator bool() const noexcept { return _container != nullptr; }
319
321 void swap(HashMapConstIterator& it) noexcept;
322 template <class UContainer, typename UKey, typename UValue>
324
325private:
326 const TContainer* _container;
327 size_t _index;
328};
329
331
334template <class TContainer, typename TKey, typename TValue>
336{
338 friend TContainer;
339
340public:
341 // Standard iterator type definitions
342 typedef std::pair<TKey, TValue> value_type;
346 typedef const value_type* const_pointer;
347 typedef ptrdiff_t difference_type;
348 typedef size_t size_type;
349 typedef std::bidirectional_iterator_tag iterator_category;
350
351 HashMapReverseIterator() noexcept : _container(nullptr), _index(0) {}
352 explicit HashMapReverseIterator(TContainer* container) noexcept;
353 explicit HashMapReverseIterator(TContainer* container, size_t index) noexcept : _container(container), _index(index) {}
354 HashMapReverseIterator(const HashMapReverseIterator& it) noexcept = default;
356 ~HashMapReverseIterator() noexcept = default;
357
358 HashMapReverseIterator& operator=(const HashMapReverseIterator& it) noexcept = default;
359 HashMapReverseIterator& operator=(HashMapReverseIterator&& it) noexcept = default;
360
361 friend bool operator==(const HashMapReverseIterator& it1, const HashMapReverseIterator& it2) noexcept
362 { return (it1._container == it2._container) && (it1._index == it2._index); }
363 friend bool operator!=(const HashMapReverseIterator& it1, const HashMapReverseIterator& it2) noexcept
364 { return (it1._container != it2._container) || (it1._index != it2._index); }
365
366 HashMapReverseIterator& operator++() noexcept;
367 HashMapReverseIterator operator++(int) noexcept;
368
369 reference operator*() noexcept;
370 pointer operator->() noexcept;
371
373 explicit operator bool() const noexcept { return _container != nullptr; }
374
376 void swap(HashMapReverseIterator& it) noexcept;
377 template <class UContainer, typename UKey, typename UValue>
379
380private:
381 TContainer* _container;
382 size_t _index;
383};
384
386
389template <class TContainer, typename TKey, typename TValue>
391{
392 friend TContainer;
393
394public:
395 // Standard iterator type definitions
396 typedef std::pair<TKey, TValue> value_type;
400 typedef const value_type* const_pointer;
401 typedef ptrdiff_t difference_type;
402 typedef size_t size_type;
403 typedef std::bidirectional_iterator_tag iterator_category;
404
405 HashMapConstReverseIterator() noexcept : _container(nullptr), _index(0) {}
406 explicit HashMapConstReverseIterator(const TContainer* container) noexcept;
407 explicit HashMapConstReverseIterator(const TContainer* container, size_t index) noexcept : _container(container), _index(index) {}
408 HashMapConstReverseIterator(const HashMapReverseIterator<TContainer, TKey, TValue>& it) noexcept : _container(it._container), _index(it._index) {}
411 ~HashMapConstReverseIterator() noexcept = default;
412
413 HashMapConstReverseIterator& operator=(const HashMapReverseIterator<TContainer, TKey, TValue>& it) noexcept
414 { _container = it._container; _index = it._index; return *this; }
417
418 friend bool operator==(const HashMapConstReverseIterator& it1, const HashMapConstReverseIterator& it2) noexcept
419 { return (it1._container == it2._container) && (it1._index == it2._index); }
420 friend bool operator!=(const HashMapConstReverseIterator& it1, const HashMapConstReverseIterator& it2) noexcept
421 { return (it1._container != it2._container) || (it1._index != it2._index); }
422
423 HashMapConstReverseIterator& operator++() noexcept;
424 HashMapConstReverseIterator operator++(int) noexcept;
425
426 const_reference operator*() const noexcept;
427 const_pointer operator->() const noexcept;
428
430 explicit operator bool() const noexcept { return _container != nullptr; }
431
433 void swap(HashMapConstReverseIterator& it) noexcept;
434 template <class UContainer, typename UKey, typename UValue>
436
437private:
438 const TContainer* _container;
439 size_t _index;
440};
441
444} // namespace CppCommon
445
446#include "hashmap.inl"
447
448#endif // CPPCOMMON_CONTAINERS_HASHMAP_H
Hash map constant iterator.
Definition hashmap.h:279
HashMapConstIterator(HashMapConstIterator &&it) noexcept=default
HashMapConstIterator(const HashMapConstIterator &it) noexcept=default
friend void swap(HashMapConstIterator< UContainer, UKey, UValue > &it1, HashMapConstIterator< UContainer, UKey, UValue > &it2) noexcept
HashMapConstIterator & operator=(const HashMapConstIterator &it) noexcept=default
HashMapConstIterator(const HashMapIterator< TContainer, TKey, TValue > &it) noexcept
Definition hashmap.h:296
HashMapConstIterator & operator=(HashMapConstIterator &&it) noexcept=default
std::pair< TKey, TValue > value_type
Definition hashmap.h:284
friend bool operator==(const HashMapConstIterator &it1, const HashMapConstIterator &it2) noexcept
Definition hashmap.h:306
const value_type * const_pointer
Definition hashmap.h:288
friend bool operator!=(const HashMapConstIterator &it1, const HashMapConstIterator &it2) noexcept
Definition hashmap.h:308
std::bidirectional_iterator_tag iterator_category
Definition hashmap.h:291
HashMapConstIterator(const TContainer *container, size_t index) noexcept
Definition hashmap.h:295
~HashMapConstIterator() noexcept=default
const value_type & const_reference
Definition hashmap.h:286
Hash map constant reverse iterator.
Definition hashmap.h:391
HashMapConstReverseIterator(HashMapConstReverseIterator &&it) noexcept=default
friend void swap(HashMapConstReverseIterator< UContainer, UKey, UValue > &it1, HashMapConstReverseIterator< UContainer, UKey, UValue > &it2) noexcept
~HashMapConstReverseIterator() noexcept=default
friend bool operator!=(const HashMapConstReverseIterator &it1, const HashMapConstReverseIterator &it2) noexcept
Definition hashmap.h:420
HashMapConstReverseIterator & operator=(const HashMapConstReverseIterator &it) noexcept=default
HashMapConstReverseIterator(const TContainer *container, size_t index) noexcept
Definition hashmap.h:407
HashMapConstReverseIterator(const HashMapConstReverseIterator &it) noexcept=default
std::bidirectional_iterator_tag iterator_category
Definition hashmap.h:403
HashMapConstReverseIterator(const HashMapReverseIterator< TContainer, TKey, TValue > &it) noexcept
Definition hashmap.h:408
std::pair< TKey, TValue > value_type
Definition hashmap.h:396
friend bool operator==(const HashMapConstReverseIterator &it1, const HashMapConstReverseIterator &it2) noexcept
Definition hashmap.h:418
HashMapConstReverseIterator & operator=(HashMapConstReverseIterator &&it) noexcept=default
Hash map container.
Definition hashmap.h:45
iterator find(const TKey &key) noexcept
Find the iterator which points to the first item with the given key in the hash map or return end ite...
Definition hashmap.inl:129
HashMapReverseIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > reverse_iterator
Definition hashmap.h:64
HashMapConstReverseIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > const_reverse_iterator
Definition hashmap.h:65
const value_type * const_pointer
Definition hashmap.h:59
reverse_iterator rbegin() noexcept
Get the reverse begin hash map iterator.
Definition hashmap.inl:93
ptrdiff_t difference_type
Definition hashmap.h:60
value_type & reference
Definition hashmap.h:56
std::pair< iterator, bool > insert(const value_type &item)
Insert a new item into the hash map.
Definition hashmap.inl:189
TValue mapped_type
Definition hashmap.h:54
void clear() noexcept
Clear the hash map.
Definition hashmap.inl:306
mapped_type & at(const TKey &key) noexcept
Access to the item with the given key or throw std::out_of_range exception.
Definition hashmap.inl:169
const_iterator cend() const noexcept
Definition hashmap.inl:87
const_iterator cbegin() const noexcept
Definition hashmap.inl:69
void rehash(size_t capacity)
Rehash the hash map to the given capacity or more.
Definition hashmap.inl:291
size_t count(const TKey &key) const noexcept
Find the count of items with the given key.
Definition hashmap.h:136
HashMapConstIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > const_iterator
Definition hashmap.h:63
std::pair< iterator, bool > emplace(Args &&... args)
Emplace a new item into the hash map.
const_reverse_iterator crend() const noexcept
Definition hashmap.inl:123
const_reverse_iterator crbegin() const noexcept
Definition hashmap.inl:105
void reserve(size_t count)
Reserve the hash map capacity to fit the given count of items.
Definition hashmap.inl:299
value_type * pointer
Definition hashmap.h:58
iterator end() noexcept
Get the end hash map iterator.
Definition hashmap.inl:75
bool key_equal(const TKey &key1, const TKey &key2) const noexcept
Compare two keys: if the first key equals to the second one?
Definition hashmap.h:107
size_t max_size() const noexcept
Get the hash map maximum size.
Definition hashmap.h:98
std::pair< TKey, TValue > value_type
Definition hashmap.h:55
HashMap & operator=(const HashMap &hashmap)
Definition hashmap.inl:47
bool empty() const noexcept
Is the hash map empty?
Definition hashmap.h:93
HashMap(HashMap &&)=default
const value_type & const_reference
Definition hashmap.h:57
friend void swap(HashMap< UKey, UValue, UHash, UEqual, UAllocator > &hashmap1, HashMap< UKey, UValue, UHash, UEqual, UAllocator > &hashmap2) noexcept
size_t size() const noexcept
Get the hash map size.
Definition hashmap.h:96
reverse_iterator rend() noexcept
Get the reverse end hash map iterator.
Definition hashmap.inl:111
size_t erase(const TKey &key)
Erase the item with the given key from the hash map.
Definition hashmap.inl:208
size_t key_hash(const TKey &key) const noexcept
Calculate hash of the given key.
Definition hashmap.h:105
HashMapIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > iterator
Definition hashmap.h:62
mapped_type & operator[](const TKey &key)
Access to the item with the given key or insert a new one.
Definition hashmap.h:90
size_t max_bucket_count() const noexcept
Get the hash map maximum bucket count.
Definition hashmap.h:102
std::pair< iterator, iterator > equal_range(const TKey &key) noexcept
Find the bounds of a range that includes all the elements in the hash map with the given key.
Definition hashmap.inl:157
iterator begin() noexcept
Get the begin hash map iterator.
Definition hashmap.inl:57
size_t bucket_count() const noexcept
Get the hash map bucket count.
Definition hashmap.h:100
HashMap & operator=(HashMap &&)=default
Hash map iterator.
Definition hashmap.h:224
friend void swap(HashMapIterator< UContainer, UKey, UValue > &it1, HashMapIterator< UContainer, UKey, UValue > &it2) noexcept
~HashMapIterator() noexcept=default
HashMapIterator(HashMapIterator &&it) noexcept=default
std::pair< TKey, TValue > value_type
Definition hashmap.h:230
const value_type & const_reference
Definition hashmap.h:232
HashMapIterator(const HashMapIterator &it) noexcept=default
friend bool operator!=(const HashMapIterator &it1, const HashMapIterator &it2) noexcept
Definition hashmap.h:251
std::bidirectional_iterator_tag iterator_category
Definition hashmap.h:237
HashMapIterator(TContainer *container, size_t index) noexcept
Definition hashmap.h:241
const value_type * const_pointer
Definition hashmap.h:234
Hash map reverse iterator.
Definition hashmap.h:336
~HashMapReverseIterator() noexcept=default
const value_type * const_pointer
Definition hashmap.h:346
std::pair< TKey, TValue > value_type
Definition hashmap.h:342
HashMapReverseIterator(const HashMapReverseIterator &it) noexcept=default
const value_type & const_reference
Definition hashmap.h:344
std::bidirectional_iterator_tag iterator_category
Definition hashmap.h:349
HashMapReverseIterator(TContainer *container, size_t index) noexcept
Definition hashmap.h:353
friend bool operator!=(const HashMapReverseIterator &it1, const HashMapReverseIterator &it2) noexcept
Definition hashmap.h:363
friend void swap(HashMapReverseIterator< UContainer, UKey, UValue > &it1, HashMapReverseIterator< UContainer, UKey, UValue > &it2) noexcept
HashMapReverseIterator(HashMapReverseIterator &&it) noexcept=default
Hash map container inline implementation.
C++ Common project definitions.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition filecache.inl:23