CPP-TOOLBOX
Loading...
Searching...
No Matches
reactive_unordered_map.hpp
Go to the documentation of this file.
1#ifndef UNORDERED_MAP_WRAPPER_HPP
2#define UNORDERED_MAP_WRAPPER_HPP
3
4#include <unordered_map>
5#include <optional>
6#include <utility>
7#include <stdexcept>
8
10
11//
12// Signals for UnorderedMap modification events
13//
14template <typename Key, typename Value> struct MapSignals {
15 // Fired when a new key-value pair is inserted
16 struct Inserted {
17 const Key &key;
18 const Value &value;
19 };
20
21 // Fired when an existing key's value changes
22 struct Updated {
23 const Key &key;
24 const Value &old_value;
25 const Value &new_value;
26 };
27
28 // Fired when an element is erased
29 struct Erased {
30 const Key &key;
31 const Value &old_value;
32 };
33
34 // Fired when the entire map is cleared
35 struct Cleared {};
36
37 // Optional: fired when internal bucket structure changes
38 struct Rehashed {
39 std::size_t old_bucket_count;
40 std::size_t new_bucket_count;
41 };
42
43 // Optional: fired when reserve() changes capacity
44 struct Reserved {
45 std::size_t new_capacity;
46 };
47};
48
81template <typename Key, typename Value, typename Hash = std::hash<Key>, typename KeyEq = std::equal_to<Key>>
83 public:
84 using key_type = Key;
85 using mapped_type = Value;
86 using value_type = std::pair<const Key, Value>;
87 using size_type = std::size_t;
88 using map_type = std::unordered_map<Key, Value, Hash, KeyEq>;
89 using iterator = typename map_type::iterator;
90 using const_iterator = typename map_type::const_iterator;
91
92 // startfold specific signals
96 // endfold
97
99
101
102 // ---------- Observers ----------
103 bool empty() const noexcept { return map_.empty(); }
104 size_type size() const noexcept { return map_.size(); }
105 void reserve(size_type n) { map_.reserve(n); }
106
107 iterator begin() noexcept { return map_.begin(); }
108 iterator end() noexcept { return map_.end(); }
109 const_iterator begin() const noexcept { return map_.begin(); }
110 const_iterator end() const noexcept { return map_.end(); }
111
112 // ---------- Lookup ----------
113 iterator find(const Key &k) { return map_.find(k); }
114 const_iterator find(const Key &k) const { return map_.find(k); }
115 bool contains(const Key &k) const { return map_.find(k) != map_.end(); }
116
117 Value &at(const Key &k) { return map_.at(k); }
118 const Value &at(const Key &k) const { return map_.at(k); }
119
120 // ---------- Modifiers ----------
121 std::pair<iterator, bool> insert_or_assign(const Key &key, Value &&value) {
122 return map_.insert_or_assign(key, std::move(value));
123 }
124
125 template <typename... Args> std::pair<iterator, bool> try_emplace(const Key &key, Args &&...args) {
126 return map_.try_emplace(key, std::forward<Args>(args)...);
127 }
128
132 template <class... Args> std::pair<iterator, bool> emplace(Args &&...args) {
133 auto [it, inserted] = map_.emplace(std::forward<Args>(args)...);
134 if (inserted)
135 signal_emitter.emit(typename map_signals::Inserted(it->first, it->second));
136 return {it, inserted};
137 }
138
139 Value &operator[](const Key &key) { return map_[key]; }
140
144 size_type erase(const Key &key) {
145
146 auto it = map_.find(key);
147 if (it == map_.end())
148 return 0;
149
150 Value old_value = it->second; // capture before erasing
151 size_type num_elts_erased = map_.erase(key);
152
153 if (num_elts_erased == 1)
154 signal_emitter.emit(typename map_signals::Erased{key, old_value});
155
156 return num_elts_erased;
157 }
158
159 iterator erase(iterator pos) { return map_.erase(pos); }
160
161 void clear() noexcept { map_.clear(); }
162
163 bool update_if_exists(const Key &key, Value &&new_value) {
164 auto it = map_.find(key);
165 if (it == map_.end())
166 return false;
167 it->second = std::move(new_value);
168 return true;
169 }
170
171 private:
172 map_type map_;
173};
174
175#endif // UNORDERED_MAP_WRAPPER_HPP
Definition input_state.hpp:168
size_type erase(const Key &key)
runs the internal call and emits an erased signal if succeeded
Definition reactive_unordered_map.hpp:144
iterator end() noexcept
Definition reactive_unordered_map.hpp:108
std::pair< iterator, bool > insert_or_assign(const Key &key, Value &&value)
Definition reactive_unordered_map.hpp:121
const Value & at(const Key &k) const
Definition reactive_unordered_map.hpp:118
typename map_type::iterator iterator
Definition reactive_unordered_map.hpp:89
bool update_if_exists(const Key &key, Value &&new_value)
Definition reactive_unordered_map.hpp:163
std::pair< iterator, bool > try_emplace(const Key &key, Args &&...args)
Definition reactive_unordered_map.hpp:125
map_signals::Erased erased_signal
Definition reactive_unordered_map.hpp:95
std::unordered_map< Key, Value, Hash, KeyEq > map_type
Definition reactive_unordered_map.hpp:88
ReactiveUnorderedMap()=default
iterator find(const Key &k)
Definition reactive_unordered_map.hpp:113
MapSignals< Key, Value > map_signals
Definition reactive_unordered_map.hpp:93
bool empty() const noexcept
Definition reactive_unordered_map.hpp:103
const_iterator end() const noexcept
Definition reactive_unordered_map.hpp:110
SignalEmitter signal_emitter
Definition reactive_unordered_map.hpp:100
Value & at(const Key &k)
Definition reactive_unordered_map.hpp:117
Value & operator[](const Key &key)
Definition reactive_unordered_map.hpp:139
iterator erase(iterator pos)
Definition reactive_unordered_map.hpp:159
const_iterator begin() const noexcept
Definition reactive_unordered_map.hpp:109
Value mapped_type
Definition reactive_unordered_map.hpp:85
iterator begin() noexcept
Definition reactive_unordered_map.hpp:107
const_iterator find(const Key &k) const
Definition reactive_unordered_map.hpp:114
typename map_type::const_iterator const_iterator
Definition reactive_unordered_map.hpp:90
void clear() noexcept
Definition reactive_unordered_map.hpp:161
bool contains(const Key &k) const
Definition reactive_unordered_map.hpp:115
std::size_t size_type
Definition reactive_unordered_map.hpp:87
map_signals::Inserted inserted_signal
Definition reactive_unordered_map.hpp:94
std::pair< const Key, Value > value_type
Definition reactive_unordered_map.hpp:86
size_type size() const noexcept
Definition reactive_unordered_map.hpp:104
std::pair< iterator, bool > emplace(Args &&...args)
runs the internal call and emits an inserted signal if succeeded
Definition reactive_unordered_map.hpp:132
Key key_type
Definition reactive_unordered_map.hpp:84
void reserve(size_type n)
Definition reactive_unordered_map.hpp:105
A type-safe signal emitter that allows different signal types (represented as structs).
Definition signal_emitter.hpp:43
@ n
Definition input_state.hpp:40
@ k
Definition input_state.hpp:37
Definition reactive_unordered_map.hpp:35
Definition reactive_unordered_map.hpp:29
const Key & key
Definition reactive_unordered_map.hpp:30
const Value & old_value
Definition reactive_unordered_map.hpp:31
Definition reactive_unordered_map.hpp:16
const Value & value
Definition reactive_unordered_map.hpp:18
const Key & key
Definition reactive_unordered_map.hpp:17
Definition reactive_unordered_map.hpp:38
std::size_t new_bucket_count
Definition reactive_unordered_map.hpp:40
std::size_t old_bucket_count
Definition reactive_unordered_map.hpp:39
Definition reactive_unordered_map.hpp:44
std::size_t new_capacity
Definition reactive_unordered_map.hpp:45
Definition reactive_unordered_map.hpp:22
const Value & old_value
Definition reactive_unordered_map.hpp:24
const Key & key
Definition reactive_unordered_map.hpp:23
const Value & new_value
Definition reactive_unordered_map.hpp:25
Definition reactive_unordered_map.hpp:14