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
StackHashMap.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2026 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
31
32#pragma once
33
35
36#include <array>
37#include <cstddef>
38#include <functional>
39#include <initializer_list>
40#include <memory>
41#include <optional>
42#include <utility>
43
44namespace nfx::containers
45{
46 //=====================================================================
47 // StackHashMap class
48 //=====================================================================
49
64 template <typename TKey,
65 typename TValue,
66 size_t N = 8,
67 typename KeyEqual = std::equal_to<>>
68 class StackHashMap final
69 {
70 public:
71 //----------------------------------------------
72 // STL-compatible type aliases
73 //----------------------------------------------
74
76 using key_type = TKey;
77
79 using mapped_type = TValue;
80
82 using value_type = std::pair<const TKey, TValue>;
83
85 using size_type = size_t;
86
88 using difference_type = std::ptrdiff_t;
89
91 using key_equal = KeyEqual;
92
93 //----------------------------------------------
94 // Construction
95 //----------------------------------------------
96
100 inline StackHashMap();
101
106 inline StackHashMap( std::initializer_list<std::pair<TKey, TValue>> init );
107
114 template <typename InputIt>
115 inline StackHashMap( InputIt first, InputIt last );
116
117 //----------------------------------------------
118 // Capacity
119 //----------------------------------------------
120
126 [[nodiscard]] inline bool isEmpty() const noexcept;
127
133 [[nodiscard]] inline size_t size() const noexcept;
134
140 [[nodiscard]] static constexpr size_t stackCapacity() noexcept { return N; }
141
142 //----------------------------------------------
143 // Element access
144 //----------------------------------------------
145
152 inline TValue& at( const TKey& key );
153
160 inline const TValue& at( const TKey& key ) const;
161
171 inline TValue& operator[]( const TKey& key );
172
182 inline TValue& operator[]( TKey&& key );
183
184 //----------------------------------------------
185 // Modifiers
186 //----------------------------------------------
187
196 inline std::pair<value_type*, bool> insert( const std::pair<TKey, TValue>& value );
197
206 inline std::pair<value_type*, bool> insert( std::pair<TKey, TValue>&& value );
207
214 template <typename... Args>
215 inline std::pair<value_type*, bool> emplace( Args&&... args );
216
224 inline void insertOrAssign( const TKey& key, const TValue& value );
225
233 inline void insertOrAssign( const TKey& key, TValue&& value );
234
242 inline void insertOrAssign( TKey&& key, TValue&& value );
243
249 inline size_t erase( const TKey& key );
250
255 inline void clear() noexcept;
256
265 [[nodiscard]] inline std::optional<std::pair<TKey, TValue>> extract( const TKey& key );
266
274 inline void merge( StackHashMap& other );
275
281 inline void merge( StackHashMap&& other );
282
283 //----------------------------------------------
284 // Lookup
285 //----------------------------------------------
286
293 [[nodiscard]] inline TValue* find( const TKey& key ) noexcept;
294
301 [[nodiscard]] inline const TValue* find( const TKey& key ) const noexcept;
302
309 [[nodiscard]] inline size_t count( const TKey& key ) const;
310
317 [[nodiscard]] inline bool contains( const TKey& key ) const;
318
327 template <typename K>
328 [[nodiscard]] inline bool contains( const K& key ) const
329 requires requires( KeyEqual eq, const K& k, const TKey& t ) { eq( k, t ); };
330
331 //----------------------------------------------
332 // Iteration
333 //----------------------------------------------
334
343 template <typename Func>
344 inline void forEach( Func&& func );
345
354 template <typename Func>
355 inline void forEach( Func&& func ) const;
356
357 private:
358 //----------------------------------------------
359 // Internal storage
360 //----------------------------------------------
361
365 struct StackEntry
366 {
367 std::optional<std::pair<TKey, TValue>> data;
368 };
369
373 std::array<StackEntry, N> m_stack;
374
378 size_t m_stackSize;
379
383 std::unique_ptr<FastHashMap<TKey, TValue>> m_heap;
384
389 [[nodiscard]] inline bool isOnStack() const noexcept;
390
395 inline void transitionToHeap();
396 };
397} // namespace nfx::containers
398
399#include "nfx/detail/containers/StackHashMap.inl"
Hash map with Robin Hood hashing and heterogeneous lookup.
std::pair< value_type *, bool > insert(const std::pair< TKey, TValue > &value)
Insert a key-value pair (copy semantics).
TValue & operator[](const TKey &key)
STL-compatible subscript operator (insert-if-missing).
std::optional< std::pair< TKey, TValue > > extract(const TKey &key)
Extract a key-value pair from the map without destroying it.
bool contains(const TKey &key) const
Check if a key exists in the map.
StackHashMap(InputIt first, InputIt last)
Construct map from iterator range.
TValue * find(const TKey &key) noexcept
Find a value by key.
bool isEmpty() const noexcept
Check if the map is empty.
void insertOrAssign(const TKey &key, TValue &&value)
Insert or assign a key-value pair (move value).
const TValue & at(const TKey &key) const
Checked const element access with bounds checking.
std::pair< const TKey, TValue > value_type
Type alias for key-value pair type.
void insertOrAssign(TKey &&key, TValue &&value)
Insert or assign a key-value pair (move key and value).
std::pair< value_type *, bool > emplace(Args &&... args)
Emplace a key-value pair with in-place construction.
void merge(StackHashMap &other)
Merge another StackHashMap into this one.
void forEach(Func &&func) const
Apply a function to each key-value pair (const version).
size_t size_type
Type alias for size type.
size_t erase(const TKey &key)
Erase element by key.
TValue mapped_type
Type alias for mapped value type.
KeyEqual key_equal
Type alias for key equality comparator.
void forEach(Func &&func)
Apply a function to each key-value pair.
std::ptrdiff_t difference_type
Type alias for difference type.
void insertOrAssign(const TKey &key, const TValue &value)
Insert or assign a key-value pair (copy value).
TValue & at(const TKey &key)
Checked element access with bounds checking.
size_t size() const noexcept
Get the number of elements in the map.
size_t count(const TKey &key) const
Count occurrences of key in map.
TValue & operator[](TKey &&key)
STL-compatible subscript operator with move semantics.
StackHashMap()
Default constructor with empty stack storage.
void clear() noexcept
Clear all elements from the map.
static constexpr size_t stackCapacity() noexcept
Get the maximum stack capacity before heap allocation.
std::pair< value_type *, bool > insert(std::pair< TKey, TValue > &&value)
Insert a key-value pair (move semantics).
TKey key_type
Type alias for key type.
StackHashMap(std::initializer_list< std::pair< TKey, TValue > > init)
Construct map from initializer_list.