FastLED 3.9.7
Loading...
Searching...
No Matches
map.h
1#pragma once
2
3#include <stdint.h>
4#include <stddef.h>
5
6#include "fl/namespace.h"
7#include "fl/vector.h"
8#include "fl/template_magic.h"
9#include "fl/insert_result.h"
10#include "fl/pair.h"
11
12namespace fl {
13
14// A simple unordered map implementation with a fixed size.
15// The user is responsible for making sure that the inserts
16// do not exceed the capacity of the set, otherwise they will
17// fail. Because of this limitation, this set is not a drop in
18// replacement for std::map.
19template<typename Key, typename Value, size_t N>
20class FixedMap {
21public:
23
25 typedef typename VectorType::iterator iterator;
26 typedef typename VectorType::const_iterator const_iterator;
27
28
29 // Constructor
30 constexpr FixedMap() = default;
31
32 iterator begin() {
33 return data.begin();
34 }
35 iterator end() {
36 return data.end();
37 }
38 const_iterator begin() const {
39 return data.begin();
40 }
41 const_iterator end() const {
42 return data.end();
43 }
44
45 iterator find(const Key& key) {
46 for (auto it = begin(); it != end(); ++it) {
47 if (it->first == key) {
48 return it;
49 }
50 }
51 return end();
52 }
53
54 const_iterator find(const Key& key) const {
55 for (auto it = begin(); it != end(); ++it) {
56 if (it->first == key) {
57 return it;
58 }
59 }
60 return end();
61 }
62
63 template<typename Less>
64 iterator lowest(Less less_than = Less()) {
65 iterator lowest = end();
66 for (iterator it = begin(); it != end(); ++it) {
67 if (lowest == end() || less_than(it->first, lowest->first)) {
68 lowest = it;
69 }
70 }
71 return lowest;
72 }
73
74 template<typename Less>
75 const_iterator lowest(Less less_than = Less()) const {
76 const_iterator lowest = end();
77 for (const_iterator it = begin(); it != end(); ++it) {
78 if (lowest == end() || less_than(it->first, lowest->first)) {
79 lowest = it;
80 }
81 }
82 return lowest;
83 }
84
85 template<typename Less>
86 iterator highest(Less less_than = Less()) {
87 iterator highest = end();
88 for (iterator it = begin(); it != end(); ++it) {
89 if (highest == end() || less_than(highest->first, it->first)) {
90 highest = it;
91 }
92 }
93 return highest;
94 }
95
96 template<typename Less>
97 const_iterator highest(Less less_than = Less()) const {
98 const_iterator highest = end();
99 for (const_iterator it = begin(); it != end(); ++it) {
100 if (highest == end() || less_than(highest->first, it->first)) {
101 highest = it;
102 }
103 }
104 return highest;
105 }
106
107 // We differ from the std standard here so that we don't allow
108 // dereferencing the end iterator.
109 bool get(const Key& key, Value* value) const {
110 const_iterator it = find(key);
111 if (it != end()) {
112 *value = it->second;
113 return true;
114 }
115 return false;
116 }
117
118 Value get(const Key& key, bool* has=nullptr) const {
119 const_iterator it = find(key);
120 if (it != end()) {
121 if (has) {
122 *has = true;
123 }
124 return it->second;
125 }
126 if (has) {
127 *has = false;
128 }
129 return Value();
130 }
131
132 Pair<bool, iterator> insert(const Key& key, const Value& value, InsertResult* result = nullptr) {
133 iterator it = find(key);
134 if (it != end()) {
135 if (result) {
136 *result = InsertResult::kExists;
137 }
138 // return false;
139 return {false, it};
140 }
141 if (data.size() < N) {
142 data.push_back(PairKV(key, value));
143 if (result) {
144 *result = InsertResult::kInserted;
145 }
146 // return true;
147 return {true, data.end() - 1};
148 }
149 if (result) {
150 *result = InsertResult::kMaxSize;
151 }
152 //return false;
153 return {false, end()};
154 }
155
156 bool update(const Key& key, const Value& value, bool insert_if_missing = true) {
157 iterator it = find(key);
158 if (it != end()) {
159 it->second = value;
160 return true;
161 } else if (insert_if_missing) {
162 return insert(key, value).first;
163 }
164 return false;
165 }
166
167 Value& operator[](const Key& key) {
168 iterator it = find(key);
169 if (it != end()) {
170 return it->second;
171 }
172 data.push_back(PairKV(key, Value()));
173 return data.back().second;
174 }
175
176 const Value& operator[](const Key& key) const {
177 const_iterator it = find(key);
178 if (it != end()) {
179 return it->second;
180 }
181 static Value default_value;
182 return default_value;
183 }
184
185 bool next(const Key& key, Key* next_key, bool allow_rollover = false) const {
186 const_iterator it = find(key);
187 if (it != end()) {
188 ++it;
189 if (it != end()) {
190 *next_key = it->first;
191 return true;
192 } else if (allow_rollover && !empty()) {
193 *next_key = begin()->first;
194 return true;
195 }
196 }
197 return false;
198 }
199
200 bool prev(const Key& key, Key* prev_key, bool allow_rollover = false) const {
201 const_iterator it = find(key);
202 if (it != end()) {
203 if (it != begin()) {
204 --it;
205 *prev_key = it->first;
206 return true;
207 } else if (allow_rollover && !empty()) {
208 *prev_key = data[data.size() - 1].first;
209 return true;
210 }
211 }
212 return false;
213 }
214
215
216 // Get the current size of the vector
217 constexpr size_t size() const {
218 return data.size();
219 }
220
221 constexpr bool empty() const {
222 return data.empty();
223 }
224
225 // Get the capacity of the vector
226 constexpr size_t capacity() const {
227 return N;
228 }
229
230 // Clear the vector
231 void clear() {
232 data.clear();
233 }
234
235 bool has(const Key& it) const {
236 return find(it) != end();
237 }
238private:
239 VectorType data;
240};
241
242template <typename Key, typename Value, typename Less>
244private:
245 struct Pair {
246 Key first;
247 Value second;
248
249 Pair(const Key& k = Key(), const Value& v = Value())
250 : first(k), second(v) {}
251 };
252
253 struct PairLess {
254 Less less;
255 bool operator()(const Pair& a, const Pair& b) const {
256 return less(a.first, b.first);
257 }
258 };
259
261
262public:
263
266
267 SortedHeapMap(Less less = Less())
268 : data(PairLess{less}) {
269 }
270
271 void setMaxSize(size_t n) {
272 data.setMaxSize(n);
273 }
274
275 void reserve(size_t n) {
276 data.reserve(n);
277 }
278
279 bool insert(const Key& key, const Value& value, InsertResult* result = nullptr) {
280 return data.insert(Pair(key, value), result);
281 }
282
283 bool has(const Key& key) const {
284 return data.has(Pair(key));
285 }
286
287 size_t size() const { return data.size(); }
288 bool empty() const { return data.empty(); }
289 bool full() const { return data.full(); }
290 size_t capacity() const { return data.capacity(); }
291 void clear() { data.clear(); }
292
293 // begin, dend
294 iterator begin() { return data.begin(); }
295 iterator end() { return data.end(); }
296 const_iterator begin() const { return data.begin(); }
297 const_iterator end() const { return data.end(); }
298
299 iterator find(const Key& key) {
300 return data.find(Pair(key));
301 }
302 const_iterator find(const Key& key) const {
303 return data.find(Pair(key));
304 }
305
306 bool erase(const Key& key) {
307 return data.erase(Pair(key));
308 }
309 bool erase(iterator it) {
310 return data.erase(it);
311 }
312
313 iterator lower_bound(const Key& key) {
314 return data.lower_bound(Pair(key));
315 }
316
317 const_iterator lower_bound(const Key& key) const {
318 return data.lower_bound(Pair(key));
319 }
320
321 iterator upper_bound(const Key& key) {
322 iterator it = lower_bound(key);
323 if (it != end() && it->first == key) {
324 ++it;
325 }
326 return it;
327 }
328
329 const_iterator upper_bound(const Key& key) const {
330 const_iterator it = lower_bound(key);
331 if (it != end() && it->first == key) {
332 ++it;
333 }
334 return it;
335 }
336
337 Pair& front() { return data.front(); }
338 const Pair& front() const { return data.front(); }
339 Pair& back() { return data.back(); }
340 const Pair& back() const { return data.back(); }
341
342
343};
344
345} // namespace fl
Implements the FastLED namespace macros.
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
Definition Keyboard.h:22
Definition pair.h:6