9 #ifndef CPPCOMMON_CONTAINERS_HASHMAP_H
10 #define CPPCOMMON_CONTAINERS_HASHMAP_H
23 template <
class TContainer,
typename TKey,
typename TValue>
25 template <
class TContainer,
typename TKey,
typename TValue>
27 template <
class TContainer,
typename TKey,
typename TValue>
29 template <
class TContainer,
typename TKey,
typename TValue>
43 template <
typename TKey,
typename TValue,
typename THash = std::hash<TKey>,
typename TEqual = std::equal_to<TKey>,
typename TAllocator = std::allocator<std::pair<TKey, TValue>>>
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());
87 explicit operator bool() const noexcept {
return !
empty(); }
93 bool empty() const noexcept {
return _size == 0; }
96 size_t size() const noexcept {
return _size; }
98 size_t max_size() const noexcept {
return std::numeric_limits<size_type>::max(); }
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); }
136 size_t count(const TKey& key) const noexcept {
return (
find(key) ==
end()) ? 0 : 1; }
169 template <
typename... Args>
170 std::pair<iterator, bool>
emplace(Args&&... args);
177 size_t erase(
const TKey& key);
188 void rehash(
size_t capacity);
196 void clear() 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;
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;
222 template <class TContainer, typename TKey, typename TValue>
241 explicit HashMapIterator(TContainer* container,
size_t index) noexcept : _container(container), _index(index) {}
250 {
return (it1._container == it2._container) && (it1._index == it2._index); }
252 {
return (it1._container != it2._container) || (it1._index != it2._index); }
261 explicit operator
bool() const noexcept {
return _container !=
nullptr; }
265 template <
class UContainer,
typename UKey,
typename UValue>
269 TContainer* _container;
277 template <
class TContainer,
typename TKey,
typename TValue>
295 explicit HashMapConstIterator(
const TContainer* container,
size_t index) noexcept : _container(container), _index(index) {}
302 { _container = it._container; _index = it._index;
return *
this; }
307 {
return (it1._container == it2._container) && (it1._index == it2._index); }
309 {
return (it1._container != it2._container) || (it1._index != it2._index); }
318 explicit operator
bool() const noexcept {
return _container !=
nullptr; }
322 template <
class UContainer,
typename UKey,
typename UValue>
326 const TContainer* _container;
334 template <
class TContainer,
typename TKey,
typename TValue>
362 {
return (it1._container == it2._container) && (it1._index == it2._index); }
364 {
return (it1._container != it2._container) || (it1._index != it2._index); }
373 explicit operator
bool() const noexcept {
return _container !=
nullptr; }
377 template <
class UContainer,
typename UKey,
typename UValue>
381 TContainer* _container;
389 template <
class TContainer,
typename TKey,
typename TValue>
414 { _container = it._container; _index = it._index;
return *
this; }
419 {
return (it1._container == it2._container) && (it1._index == it2._index); }
421 {
return (it1._container != it2._container) || (it1._index != it2._index); }
430 explicit operator
bool() const noexcept {
return _container !=
nullptr; }
434 template <
class UContainer,
typename UKey,
typename UValue>
438 const TContainer* _container;
Hash map constant iterator.
HashMapConstIterator(HashMapConstIterator &&it) noexcept=default
HashMapConstIterator() noexcept
HashMapConstIterator(const HashMapConstIterator &it) noexcept=default
friend void swap(HashMapConstIterator< UContainer, UKey, UValue > &it1, HashMapConstIterator< UContainer, UKey, UValue > &it2) noexcept
HashMapConstIterator & operator=(HashMapConstIterator &&it) noexcept=default
HashMapConstIterator(const HashMapIterator< TContainer, TKey, TValue > &it) noexcept
std::pair< TKey, TValue > value_type
ptrdiff_t difference_type
friend bool operator==(const HashMapConstIterator &it1, const HashMapConstIterator &it2) noexcept
const value_type * const_pointer
friend bool operator!=(const HashMapConstIterator &it1, const HashMapConstIterator &it2) noexcept
std::bidirectional_iterator_tag iterator_category
HashMapConstIterator(const TContainer *container, size_t index) noexcept
HashMapConstIterator & operator=(const HashMapConstIterator &it) noexcept=default
~HashMapConstIterator() noexcept=default
const value_type & const_reference
Hash map constant reverse iterator.
HashMapConstReverseIterator(HashMapConstReverseIterator &&it) noexcept=default
friend void swap(HashMapConstReverseIterator< UContainer, UKey, UValue > &it1, HashMapConstReverseIterator< UContainer, UKey, UValue > &it2) noexcept
~HashMapConstReverseIterator() noexcept=default
HashMapConstReverseIterator & operator=(const HashMapConstReverseIterator &it) noexcept=default
HashMapConstReverseIterator() noexcept
friend bool operator!=(const HashMapConstReverseIterator &it1, const HashMapConstReverseIterator &it2) noexcept
ptrdiff_t difference_type
HashMapConstReverseIterator(const TContainer *container, size_t index) noexcept
const value_type & const_reference
HashMapConstReverseIterator & operator=(HashMapConstReverseIterator &&it) noexcept=default
HashMapConstReverseIterator(const HashMapConstReverseIterator &it) noexcept=default
std::bidirectional_iterator_tag iterator_category
const value_type * const_pointer
HashMapConstReverseIterator(const HashMapReverseIterator< TContainer, TKey, TValue > &it) noexcept
std::pair< TKey, TValue > value_type
friend bool operator==(const HashMapConstReverseIterator &it1, const HashMapConstReverseIterator &it2) noexcept
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...
HashMapReverseIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > reverse_iterator
HashMapConstReverseIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > const_reverse_iterator
const value_type * const_pointer
reverse_iterator rbegin() noexcept
Get the reverse begin hash map iterator.
ptrdiff_t difference_type
std::pair< iterator, bool > insert(const value_type &item)
Insert a new item into the hash map.
HashMap & operator=(HashMap &&)=default
void clear() noexcept
Clear the hash map.
mapped_type & at(const TKey &key) noexcept
Access to the item with the given key or throw std::out_of_range exception.
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
void rehash(size_t capacity)
Rehash the hash map to the given capacity or more.
size_t count(const TKey &key) const noexcept
Find the count of items with the given key.
HashMapConstIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > const_iterator
std::pair< iterator, bool > emplace(Args &&... args)
Emplace a new item into the hash map.
const_reverse_iterator crend() const noexcept
const_reverse_iterator crbegin() const noexcept
void reserve(size_t count)
Reserve the hash map capacity to fit the given count of items.
iterator end() noexcept
Get the end hash map iterator.
bool key_equal(const TKey &key1, const TKey &key2) const noexcept
Compare two keys: if the first key equals to the second one?
HashMap(size_t capacity=128, const TKey &blank=TKey(), const THash &hash=THash(), const TEqual &equal=TEqual(), const TAllocator &allocator=TAllocator())
Initialize the hash map with a given capacity and blank key value.
size_t max_size() const noexcept
Get the hash map maximum size.
std::pair< TKey, TValue > value_type
HashMap & operator=(const HashMap &hashmap)
bool empty() const noexcept
Is the hash map empty?
HashMap(HashMap &&)=default
const value_type & const_reference
mapped_type & operator[](const TKey &key)
Access to the item with the given key or insert a new one.
size_t size() const noexcept
Get the hash map size.
reverse_iterator rend() noexcept
Get the reverse end hash map iterator.
void swap(HashMap &hashmap) noexcept
Swap two instances.
size_t erase(const TKey &key)
Erase the item with the given key from the hash map.
size_t key_hash(const TKey &key) const noexcept
Calculate hash of the given key.
HashMapIterator< HashMap< TKey, TValue, THash, TEqual, TAllocator >, TKey, TValue > iterator
size_t max_bucket_count() const noexcept
Get the hash map maximum bucket count.
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.
iterator begin() noexcept
Get the begin hash map iterator.
size_t bucket_count() const noexcept
Get the hash map bucket count.
HashMapIterator() noexcept
friend void swap(HashMapIterator< UContainer, UKey, UValue > &it1, HashMapIterator< UContainer, UKey, UValue > &it2) noexcept
ptrdiff_t difference_type
~HashMapIterator() noexcept=default
HashMapIterator(HashMapIterator &&it) noexcept=default
std::pair< TKey, TValue > value_type
const value_type & const_reference
HashMapIterator(const HashMapIterator &it) noexcept=default
friend bool operator!=(const HashMapIterator &it1, const HashMapIterator &it2) noexcept
std::bidirectional_iterator_tag iterator_category
HashMapIterator(TContainer *container, size_t index) noexcept
const value_type * const_pointer
Hash map reverse iterator.
~HashMapReverseIterator() noexcept=default
ptrdiff_t difference_type
const value_type * const_pointer
std::pair< TKey, TValue > value_type
HashMapReverseIterator(const HashMapReverseIterator &it) noexcept=default
const value_type & const_reference
std::bidirectional_iterator_tag iterator_category
HashMapReverseIterator() noexcept
HashMapReverseIterator(TContainer *container, size_t index) noexcept
friend bool operator!=(const HashMapReverseIterator &it1, const HashMapReverseIterator &it2) noexcept
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.