FastLED 3.9.15
Loading...
Searching...
No Matches
map.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/stdint.h"
4
5#include "fl/stl/assert.h" // IWYU pragma: keep
6#include "fl/stl/comparators.h" // IWYU pragma: keep
7#include "fl/stl/pair.h"
8#include "fl/stl/type_traits.h" // IWYU pragma: keep
9#include "fl/stl/type_traits.h" // IWYU pragma: keep
10#include "fl/stl/vector.h"
12#include "fl/stl/allocator.h"
13#include "fl/stl/noexcept.h"
14
15namespace fl {
16
17// A simple unordered map implementation with a fixed size.
18// The user is responsible for making sure that the inserts
19// do not exceed the capacity of the set, otherwise they will
20// fail. Because of this limitation, this set is not a drop in
21// replacement for std::map.
22template <typename Key, typename Value, fl::size N> class unsorted_map_fixed {
23 public:
24 enum insert_result { inserted = 0, exists = 1, at_capacity = 2 };
25
27
31
32 // Constructor
33 constexpr unsorted_map_fixed() FL_NOEXCEPT = default;
34
35 iterator begin() { return data.begin(); }
36 iterator end() { return data.end(); }
37 const_iterator begin() const { return data.begin(); }
38 const_iterator end() const { return data.end(); }
39
40 iterator find(const Key &key) {
41 for (auto it = begin(); it != end(); ++it) {
42 if (it->first == key) {
43 return it;
44 }
45 }
46 return end();
47 }
48
49 const_iterator find(const Key &key) const {
50 for (auto it = begin(); it != end(); ++it) {
51 if (it->first == key) {
52 return it;
53 }
54 }
55 return end();
56 }
57
58 template <typename Less> iterator lowest(Less less_than = Less()) {
60 for (iterator it = begin(); it != end(); ++it) {
61 if (lowest == end() || less_than(it->first, lowest->first)) {
62 lowest = it;
63 }
64 }
65 return lowest;
66 }
67
68 template <typename Less>
69 const_iterator lowest(Less less_than = Less()) const {
71 for (const_iterator it = begin(); it != end(); ++it) {
72 if (lowest == end() || less_than(it->first, lowest->first)) {
73 lowest = it;
74 }
75 }
76 return lowest;
77 }
78
79 template <typename Less> iterator highest(Less less_than = Less()) {
81 for (iterator it = begin(); it != end(); ++it) {
82 if (highest == end() || less_than(highest->first, it->first)) {
83 highest = it;
84 }
85 }
86 return highest;
87 }
88
89 template <typename Less>
90 const_iterator highest(Less less_than = Less()) const {
92 for (const_iterator it = begin(); it != end(); ++it) {
93 if (highest == end() || less_than(highest->first, it->first)) {
94 highest = it;
95 }
96 }
97 return highest;
98 }
99
100 // We differ from the std standard here so that we don't allow
101 // dereferencing the end iterator.
102 bool get(const Key &key, Value *value) const {
103 const_iterator it = find(key);
104 if (it != end()) {
105 *value = it->second;
106 return true;
107 }
108 return false;
109 }
110
111 Value get(const Key &key, bool *has = nullptr) const {
112 const_iterator it = find(key);
113 if (it != end()) {
114 if (has) {
115 *has = true;
116 }
117 return it->second;
118 }
119 if (has) {
120 *has = false;
121 }
122 return Value();
123 }
124
125 pair<bool, iterator> insert(const Key &key, const Value &value,
126 insert_result *result = nullptr) {
127 iterator it = find(key);
128 if (it != end()) {
129 if (result) {
130 *result = exists;
131 }
132 return {false, it};
133 }
134 if (data.size() < N) {
135 data.push_back(PairKV(key, value));
136 if (result) {
137 *result = inserted;
138 }
139 return {true, data.end() - 1};
140 }
141 if (result) {
143 }
144 return {false, end()};
145 }
146
148 insert_result *result = nullptr) {
149 iterator it = find(key);
150 if (it != end()) {
151 if (result) {
152 *result = exists;
153 }
154 return {false, it};
155 }
156 if (data.size() < N) {
157 data.push_back(PairKV(fl::move(key), fl::move(value)));
158 if (result) {
159 *result = inserted;
160 }
161 return {true, data.end() - 1};
162 }
163 if (result) {
165 }
166 return {false, end()};
167 }
168
169 bool update(const Key &key, const Value &value,
170 bool insert_if_missing = true) {
171 iterator it = find(key);
172 if (it != end()) {
173 it->second = value;
174 return true;
175 } else if (insert_if_missing) {
176 return insert(key, value).first;
177 }
178 return false;
179 }
180
181 // Move version of update
182 bool update(const Key &key, Value &&value,
183 bool insert_if_missing = true) {
184 iterator it = find(key);
185 if (it != end()) {
186 it->second = fl::move(value);
187 return true;
188 } else if (insert_if_missing) {
189 return insert(key, fl::move(value)).first;
190 }
191 return false;
192 }
193
194 Value &operator[](const Key &key) {
195 iterator it = find(key);
196 if (it != end()) {
197 return it->second;
198 }
199 data.push_back(PairKV(key, Value()));
200 return data.back().second;
201 }
202
203 const Value &operator[](const Key &key) const {
204 const_iterator it = find(key);
205 if (it != end()) {
206 return it->second;
207 }
208 static Value default_value;
209 return default_value;
210 }
211
212 bool next(const Key &key, Key *next_key,
213 bool allow_rollover = false) const {
214 const_iterator it = find(key);
215 if (it != end()) {
216 ++it;
217 if (it != end()) {
218 *next_key = it->first;
219 return true;
220 } else if (allow_rollover && !empty()) {
221 *next_key = begin()->first;
222 return true;
223 }
224 }
225 return false;
226 }
227
228 bool prev(const Key &key, Key *prev_key,
229 bool allow_rollover = false) const {
230 const_iterator it = find(key);
231 if (it != end()) {
232 if (it != begin()) {
233 --it;
234 *prev_key = it->first;
235 return true;
236 } else if (allow_rollover && !empty()) {
237 *prev_key = data[data.size() - 1].first;
238 return true;
239 }
240 }
241 return false;
242 }
243
244 // Get the current size of the vector
245 constexpr fl::size size() const { return data.size(); }
246
247 constexpr bool empty() const { return data.empty(); }
248
249 // Get the capacity of the vector
250 constexpr fl::size capacity() const { return N; }
251
252 // Clear the vector
253 void clear() { data.clear(); }
254
255 bool has(const Key &it) const { return find(it) != end(); }
256
257 bool contains(const Key &key) const { return has(key); }
258
259 // Erase element by key
260 fl::size erase(const Key &key) {
261 iterator it = find(key);
262 if (it != end()) {
263 data.erase(it);
264 return 1;
265 }
266 return 0;
267 }
268
269 private:
271};
272
273
274} // namespace fl
275
276// Drop-in replacement for std::map
277namespace fl {
278
279// Default map uses slab allocator for better performance
280// In fl:: namespace, "map" refers to the container (map data structure)
281// The Arduino map() function exists only in global namespace (not in fl::)
282template <typename Key, typename T, typename Compare = fl::less<Key>>
284
285// Legacy alias for backward compatibility
286template <typename Key, typename T, typename Compare = fl::less<Key>>
288
289} // namespace fl
const PairKV * const_iterator
Definition vector.h:97
FixedVector< PairKV, N > VectorType
Definition map.h:28
constexpr fl::size size() const
Definition map.h:245
bool update(const Key &key, Value &&value, bool insert_if_missing=true)
Definition map.h:182
const_iterator begin() const
Definition map.h:37
bool update(const Key &key, const Value &value, bool insert_if_missing=true)
Definition map.h:169
fl::pair< Key, Value > PairKV
Definition map.h:26
fl::size erase(const Key &key)
Definition map.h:260
const_iterator lowest(Less less_than=Less()) const
Definition map.h:69
bool prev(const Key &key, Key *prev_key, bool allow_rollover=false) const
Definition map.h:228
VectorType::iterator iterator
Definition map.h:29
iterator lowest(Less less_than=Less())
Definition map.h:58
Value & operator[](const Key &key)
Definition map.h:194
Value get(const Key &key, bool *has=nullptr) const
Definition map.h:111
pair< bool, iterator > insert(const Key &key, const Value &value, insert_result *result=nullptr)
Definition map.h:125
constexpr fl::size capacity() const
Definition map.h:250
iterator highest(Less less_than=Less())
Definition map.h:79
VectorType::const_iterator const_iterator
Definition map.h:30
VectorType data
Definition map.h:270
const_iterator find(const Key &key) const
Definition map.h:49
pair< bool, iterator > insert(Key &&key, Value &&value, insert_result *result=nullptr)
Definition map.h:147
bool contains(const Key &key) const
Definition map.h:257
constexpr bool empty() const
Definition map.h:247
const_iterator end() const
Definition map.h:38
iterator end()
Definition map.h:36
constexpr unsorted_map_fixed() FL_NOEXCEPT=default
bool has(const Key &it) const
Definition map.h:255
iterator find(const Key &key)
Definition map.h:40
bool get(const Key &key, Value *value) const
Definition map.h:102
iterator begin()
Definition map.h:35
const_iterator highest(Less less_than=Less()) const
Definition map.h:90
const Value & operator[](const Key &key) const
Definition map.h:203
bool next(const Key &key, Key *next_key, bool allow_rollover=false) const
Definition map.h:212
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
constexpr int type_rank< T >::value
MapRedBlackTree< Key, T, Compare, fl::allocator_slab< char > > map
Definition map.h:283
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
map< Key, T, Compare > fl_map
Definition map.h:287
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
Definition Keyboard.h:22