nfx-containers 0.6.0
Modern C++20 header-only library providing high-performance hash containers with Robin Hood and perfect hashing
Loading...
Searching...
No Matches
PerfectHashMap.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 nfx
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
34
35#pragma once
36
37#include <nfx/Hashing.h>
38
39#include <cstdint>
40#include <cstddef>
41#include <functional>
42#include <iterator>
43#include <optional>
44#include <string>
45#include <string_view>
46#include <type_traits>
47#include <vector>
48
49namespace nfx::containers
50{
51 //=====================================================================
52 // PerfectHashMap class
53 //=====================================================================
54
79 template <typename TKey,
80 typename TValue,
81 hashing::Hash32or64 HashType = uint32_t,
82 HashType Seed = ( sizeof( HashType ) == 4 ? hashing::constants::FNV_OFFSET_BASIS_32 : hashing::constants::FNV_OFFSET_BASIS_64 ),
83 typename Hasher = hashing::Hasher<HashType, Seed>,
84 typename KeyEqual = std::equal_to<>>
85 class PerfectHashMap final
86 {
87 public:
88 //----------------------------------------------
89 // Forward declarations for iterator support
90 //----------------------------------------------
91
92 class Iterator;
93
94 //----------------------------------------------
95 // Type aliases
96 //----------------------------------------------
97
99 using key_type = TKey;
100
102 using mapped_type = TValue;
103
105 using value_type = std::pair<TKey, TValue>;
106
108 using hasher = Hasher;
109
111 using key_equal = KeyEqual;
112
114 using hash_type = HashType;
115
117 using seed_type = std::make_signed_t<hash_type>;
118
120 using size_type = size_t;
121
123 using difference_type = std::ptrdiff_t;
124
127
130
133
134 //----------------------------------------------
135 // Construction
136 //----------------------------------------------
137
145 inline explicit PerfectHashMap( std::vector<std::pair<TKey, TValue>>&& items );
146
152 PerfectHashMap() = default;
153
157 PerfectHashMap( const PerfectHashMap& ) = default;
158
162 PerfectHashMap( PerfectHashMap&& ) noexcept = default;
163
164 //----------------------------------------------
165 // Destruction
166 //----------------------------------------------
167
171 ~PerfectHashMap() = default;
172
173 //----------------------------------------------
174 // Assignment
175 //----------------------------------------------
176
181 PerfectHashMap& operator=( const PerfectHashMap& ) = default;
182
187 PerfectHashMap& operator=( PerfectHashMap&& ) noexcept = default;
188
189 //----------------------------------------------
190 // Comparison
191 //----------------------------------------------
192
198 [[nodiscard]] inline bool operator==( const PerfectHashMap& other ) const noexcept;
199
205 [[nodiscard]] inline bool operator!=( const PerfectHashMap& other ) const noexcept;
206
207 //----------------------------------------------
208 // Element access
209 //----------------------------------------------
210
220 template <typename K>
221 inline const TValue& at( const K& key ) const;
222
223 //----------------------------------------------
224 // Lookup
225 //----------------------------------------------
226
236 template <typename K>
237 [[nodiscard]] inline bool contains( const K& key ) const noexcept;
238
246 template <typename K>
247 [[nodiscard]] inline const TValue* find( const K& key ) const noexcept;
248
249 //----------------------------------------------
250 // Capacity
251 //----------------------------------------------
252
258 [[nodiscard]] inline size_type size() const noexcept;
259
265 [[nodiscard]] inline size_type count() const noexcept;
266
272 [[nodiscard]] inline bool isEmpty() const noexcept;
273
274 //----------------------------------------------
275 // Iterators
276 //----------------------------------------------
277
283 [[nodiscard]] inline Iterator begin() const noexcept;
284
290 [[nodiscard]] inline Iterator end() const noexcept;
291
297 [[nodiscard]] inline ConstIterator cbegin() const noexcept;
298
304 [[nodiscard]] inline ConstIterator cend() const noexcept;
305
306 //----------------------------------------------
307 // Hash policy
308 //----------------------------------------------
309
314 inline hasher hash_function() const;
315
320 inline key_equal key_eq() const;
321
322 //----------------------------------------------
323 // PerfectHashMap::Iterator class
324 //----------------------------------------------
325
331 class Iterator final
332 {
333 public:
335 using iterator_category = std::forward_iterator_tag;
336
338 using value_type = std::pair<TKey, TValue>;
339
341 using difference_type = std::ptrdiff_t;
342
344 using pointer = const value_type*;
345
347 using reference = const value_type&;
348
349 //---------------------------
350 // Construction
351 //---------------------------
352
358 inline Iterator( const std::vector<std::optional<std::pair<TKey, TValue>>>* table, size_t index );
359
360 //---------------------------
361 // Operations
362 //---------------------------
363
368 inline reference operator*() const;
369
374 inline pointer operator->() const;
375
381
386 inline Iterator operator++( int );
387
388 //---------------------------
389 // Comparison
390 //---------------------------
391
397 inline bool operator==( const Iterator& other ) const;
398
404 inline bool operator!=( const Iterator& other ) const;
405
406 private:
407 //---------------------------
408 // Private methods
409 //---------------------------
410
415 inline void skipEmpty();
416
417 //---------------------------
418 // Private members
419 //---------------------------
420
421 const std::vector<std::optional<std::pair<TKey, TValue>>>* m_table;
422 size_t m_index;
423 };
424
425 private:
426 size_t m_itemCount = 0;
427 std::vector<std::optional<std::pair<TKey, TValue>>> m_table;
428 std::vector<seed_type> m_seeds;
429 hasher m_hasher;
430 KeyEqual m_keyEqual;
431 };
432} // namespace nfx::containers
433
434#include "nfx/detail/containers/PerfectHashMap.inl"
hasher hash_function() const
Get the hash function object.
const TValue * find(const K &key) const noexcept
Fast lookup with heterogeneous key types (C++ idiom: pointer return).
std::make_signed_t< hash_type > seed_type
Type alias for signed seed type (used internally for displacement seeds).
ConstIterator cbegin() const noexcept
Get const iterator to beginning of occupied slots (explicit const).
key_equal key_eq() const
Get the key equality comparison function object.
PerfectHashMap()=default
Default constructor creates an empty map.
size_type count() const noexcept
Get the number of elements in the map.
bool contains(const K &key) const noexcept
Check if a key exists in the map.
Iterator ConstIterator
Alias for const iterator.
Iterator end() const noexcept
Get iterator to end (past last occupied slot).
HashType hash_type
Type alias for hash type (uint32_t or uint64_t).
PerfectHashMap(std::vector< std::pair< TKey, TValue > > &&items)
Constructs a perfect hash map from a vector of key-value pairs.
Hasher hasher
Type alias for hasher type.
Iterator iterator
Primary iterator class.
KeyEqual key_equal
Type alias for key equality comparator.
size_t size_type
Type alias for size type.
std::pair< TKey, TValue > value_type
Type alias for key-value pair type.
PerfectHashMap(PerfectHashMap &&) noexcept=default
Move constructor.
TValue mapped_type
Type alias for mapped value type.
TKey key_type
Type alias for key type.
bool isEmpty() const noexcept
Check if the map is empty.
size_type size() const noexcept
Get the total size of the hash table.
PerfectHashMap(const PerfectHashMap &)=default
Copy constructor.
std::ptrdiff_t difference_type
Type alias for difference type.
ConstIterator cend() const noexcept
Get const iterator to end (explicit const).
const TValue & at(const K &key) const
Access element with bounds checking.
Iterator begin() const noexcept
Get iterator to beginning of occupied slots.
Iterator const_iterator
Type alias for const iterator (same as iterator since map is immutable).
Const forward iterator for PerfectHashMap.
pointer operator->() const
Arrow operator to access key-value pair members.
Iterator & operator++()
Pre-increment operator to advance to next occupied slot.
std::pair< TKey, TValue > value_type
STL iterator value type (key-value pair).
Iterator(const std::vector< std::optional< std::pair< TKey, TValue > > > *table, size_t index)
Construct iterator from table pointers and index.
bool operator==(const Iterator &other) const
Equality comparison operator.
bool operator!=(const Iterator &other) const
Inequality comparison operator.
Iterator operator++(int)
Post-increment operator to advance to next occupied slot.
std::forward_iterator_tag iterator_category
STL iterator category (forward iterator).
const value_type * pointer
STL iterator pointer type (const).
std::ptrdiff_t difference_type
STL iterator difference type.
const value_type & reference
STL iterator reference type (const).
reference operator*() const
Dereference operator to access key-value pair.