FastLED 3.9.15
Loading...
Searching...
No Matches
set.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/vector.h"
5#include "fl/stl/allocator.h"
6#include "fl/stl/pair.h"
7#include "fl/stl/cstddef.h"
8#include "fl/stl/move.h"
9#include "fl/stl/strstream.h"
10#include "fl/stl/type_traits.h"
11#include "fl/stl/utility.h"
12#include "fl/stl/algorithm.h"
13#include "fl/stl/int.h"
14#include "fl/stl/noexcept.h"
15
16namespace fl {
17
18template <typename Key, typename Allocator> class set; // IWYU pragma: keep
19
20// VectorSet stores values in order of insertion.
21template <typename Key, size N> class VectorSetFixed;
22template <typename Key> class VectorSet; // IWYU pragma: keep
23
24template <typename Key, size N>
25using FixedSet = VectorSetFixed<Key, N>; // Backwards compatibility
26
27// A simple unordered set implementation with a fixed size.
28// The user is responsible for making sure that the inserts
29// do not exceed the capacity of the set, otherwise they will
30// fail. Because of this limitation, this set is not a drop in
31// replacement for std::set.
32template <typename Key, size N> class VectorSetFixed {
33 public:
37
38 // Constructor
39 constexpr VectorSetFixed() FL_NOEXCEPT = default;
40
41 iterator begin() { return data.begin(); }
42 iterator end() { return data.end(); }
43 const_iterator begin() const { return data.begin(); }
44 const_iterator end() const { return data.end(); }
45
46 iterator find(const Key &key) {
47 for (auto it = begin(); it != end(); ++it) {
48 if (*it == key) {
49 return it;
50 }
51 }
52 return end();
53 }
54
55 const_iterator find(const Key &key) const {
56 for (auto it = begin(); it != end(); ++it) {
57 if (*it == key) {
58 return it;
59 }
60 }
61 return end();
62 }
63
64 bool insert(const Key &key) {
65 if (data.size() < N) {
66 auto it = find(key);
67 if (it == end()) {
68 data.push_back(key);
69 return true;
70 }
71 }
72 return false;
73 }
74
75 // Move version of insert
76 bool insert(Key &&key) {
77 if (data.size() < N) {
78 auto it = find(key);
79 if (it == end()) {
80 data.push_back(fl::move(key));
81 return true;
82 }
83 }
84 return false;
85 }
86
87 // Emplace - construct in place with perfect forwarding
88 template<typename... Args>
89 bool emplace(Args&&... args) {
90 if (data.size() < N) {
91 // Create a temporary to check if it already exists
92 Key temp_key(fl::forward<Args>(args)...);
93 auto it = find(temp_key);
94 if (it == end()) {
95 data.push_back(fl::move(temp_key));
96 return true;
97 }
98 }
99 return false;
100 }
101
102 bool erase(const Key &key) {
103 auto it = find(key);
104 if (it != end()) {
105 data.erase(it);
106 return true;
107 }
108 return false;
109 }
110
112 if (pos != end()) {
113 data.erase(pos);
114 return true;
115 }
116 return false;
117 }
118
119 bool next(const Key &key, Key *next_key,
120 bool allow_rollover = false) const {
121 const_iterator it = find(key);
122 if (it != end()) {
123 ++it;
124 if (it != end()) {
125 *next_key = *it;
126 return true;
127 } else if (allow_rollover && !empty()) {
128 *next_key = *begin();
129 return true;
130 }
131 }
132 return false;
133 }
134
135 bool prev(const Key &key, Key *prev_key,
136 bool allow_rollover = false) const {
137 const_iterator it = find(key);
138 if (it != end()) {
139 if (it != begin()) {
140 --it;
141 *prev_key = *it;
142 return true;
143 } else if (allow_rollover && !empty()) {
144 *prev_key = data[data.size() - 1];
145 return true;
146 }
147 }
148 return false;
149 }
150
151 // Get the current size of the set
152 constexpr fl::size size() const { return data.size(); }
153
154 constexpr bool empty() const { return data.empty(); }
155
156 // Get the capacity of the set
157 constexpr fl::size capacity() const { return N; }
158
159 // Clear the set
160 void clear() { data.clear(); }
161
162 bool has(const Key &key) const { return find(key) != end(); }
163
164 // Return the first element of the set
165 const Key &front() const { return data.front(); }
166
167 // Return the last element of the set
168 const Key &back() const { return data.back(); }
169
171 bool operator==(const VectorSetFixed& other) const {
172 return data == other.data;
173 }
174
176 bool operator!=(const VectorSetFixed& other) const {
177 return data != other.data;
178 }
179
181 bool operator<(const VectorSetFixed& other) const {
182 return data < other.data;
183 }
184
186 bool operator<=(const VectorSetFixed& other) const {
187 return data <= other.data;
188 }
189
191 bool operator>(const VectorSetFixed& other) const {
192 return data > other.data;
193 }
194
196 bool operator>=(const VectorSetFixed& other) const {
197 return data >= other.data;
198 }
199
200 private:
202};
203
204template <typename Key> class VectorSet {
205 public:
209 typedef typename VectorType::reverse_iterator reverse_iterator;
210
211 // Constructor
212 constexpr VectorSet() FL_NOEXCEPT = default;
213
214 // Copy constructor
215 VectorSet(const VectorSet &other) : data(other.data) {}
216
217 // Move constructor
219 : data(fl::move(other.data)) {}
220
221 // Copy assignment operator
223 if (this != &other) {
224 data = other.data;
225 }
226 return *this;
227 }
228
229 // Move assignment operator
231 if (this != &other) {
232 data = fl::move(other.data);
233 }
234 return *this;
235 }
236
237 iterator begin() { return data.begin(); }
238 iterator end() { return data.end(); }
239 const_iterator begin() const { return data.begin(); }
240 const_iterator end() const { return data.end(); }
241
242 reverse_iterator rbegin() { return data.rbegin(); }
243 reverse_iterator rend() { return data.rend(); }
244
245 iterator find(const Key &key) {
246 for (auto it = begin(); it != end(); ++it) {
247 if (*it == key) {
248 return it;
249 }
250 }
251 return end();
252 }
253
254 const_iterator find(const Key &key) const {
255 for (auto it = begin(); it != end(); ++it) {
256 if (*it == key) {
257 return it;
258 }
259 }
260 return end();
261 }
262
263 bool insert(const Key &key) {
264 auto it = find(key);
265 if (it == end()) {
266 data.push_back(key);
267 return true;
268 }
269 return false;
270 }
271
272 // Move version of insert
273 bool insert(Key &&key) {
274 auto it = find(key);
275 if (it == end()) {
276 data.push_back(fl::move(key));
277 return true;
278 }
279 return false;
280 }
281
282 // Emplace - construct in place with perfect forwarding
283 template<typename... Args>
284 bool emplace(Args&&... args) {
285 // Create a temporary to check if it already exists
286 Key temp_key(fl::forward<Args>(args)...);
287 auto it = find(temp_key);
288 if (it == end()) {
289 data.push_back(fl::move(temp_key));
290 return true;
291 }
292 return false;
293 }
294
295 bool erase(const Key &key) {
296 auto it = find(key);
297 if (it != end()) {
298 data.erase(it);
299 return true;
300 }
301 return false;
302 }
303
305 if (pos != end()) {
306 data.erase(pos);
307 return true;
308 }
309 return false;
310 }
311
312 // Get the current size of the set
313 constexpr fl::size size() const { return data.size(); }
314
315 constexpr bool empty() const { return data.empty(); }
316
317 // Get the capacity of the set
318 constexpr fl::size capacity() const { return data.capacity(); }
319
320 // Clear the set
321 void clear() { data.clear(); }
322
323 bool has(const Key &key) const { return find(key) != end(); }
324
325 // Return the first element of the set
326 const Key &front() const { return data.front(); }
327
328 // Return the last element of the set
329 const Key &back() const { return data.back(); }
330
332 bool operator==(const VectorSet& other) const {
333 return data == other.data;
334 }
335
337 bool operator!=(const VectorSet& other) const {
338 return data != other.data;
339 }
340
342 bool operator<(const VectorSet& other) const {
343 return data < other.data;
344 }
345
347 bool operator<=(const VectorSet& other) const {
348 return data <= other.data;
349 }
350
352 bool operator>(const VectorSet& other) const {
353 return data > other.data;
354 }
355
357 bool operator>=(const VectorSet& other) const {
358 return data >= other.data;
359 }
360
361 private:
363};
364
365// fl::set<T, Allocator> - Ordered set implementation using SetRedBlackTree
366// This is an ordered set that keeps elements sorted, similar to std::set
367template <typename Key, typename Allocator = fl::allocator_slab<Key>> class set {
368 private:
371
372 public:
373 // Standard set typedefs
374 using key_type = Key;
376 using size_type = fl::size;
378 using reference = const Key&;
379 using const_reference = const Key&;
380 using pointer = const Key*;
381 using const_pointer = const Key*;
382
383 // Iterator types - we only provide const iterators since set elements are immutable
385 using iterator = const_iterator; // set only provides const iterators
387 using reverse_iterator = const_reverse_iterator; // set only provides const reverse iterators
388 using allocator_type = Allocator;
389
390 // Constructors
391 set() FL_NOEXCEPT = default;
392 explicit set(const Allocator& alloc) : mTree(fl::less<Key>(), alloc) {}
393 set(const set& other) FL_NOEXCEPT = default;
394 set(set&& other) FL_NOEXCEPT = default;
395 set& operator=(const set& other) FL_NOEXCEPT = default;
396 set& operator=(set&& other) FL_NOEXCEPT = default;
397
398 // Initializer list constructor
399 set(fl::initializer_list<Key> init) {
400 for (const auto& elem : init) {
401 insert(elem);
402 }
403 }
404
405 // Initializer list assignment
406 set& operator=(fl::initializer_list<Key> init) FL_NOEXCEPT {
407 clear();
408 for (const auto& elem : init) {
409 insert(elem);
410 }
411 return *this;
412 }
413
414 // Iterators
415 const_iterator begin() const { return mTree.begin(); }
416 const_iterator end() const { return mTree.end(); }
417 const_iterator cbegin() const { return mTree.cbegin(); }
418 const_iterator cend() const { return mTree.cend(); }
419
420 // Reverse iterators
421 const_reverse_iterator rbegin() const { return mTree.rbegin(); }
422 const_reverse_iterator rend() const { return mTree.rend(); }
423
424 // Capacity
425 bool empty() const { return mTree.empty(); }
426 size_type size() const { return mTree.size(); }
427 size_type max_size() const { return mTree.max_size(); }
428 allocator_type get_allocator() const { return mTree.get_allocator(); }
429
430 // Modifiers
431 void clear() { mTree.clear(); }
432
434 return mTree.insert(key);
435 }
436
438 return mTree.insert(fl::move(key));
439 }
440
441 template<typename... Args>
443 return mTree.emplace(fl::forward<Args>(args)...);
444 }
445
447 return mTree.erase(pos);
448 }
449
450 size_type erase(const Key& key) {
451 return mTree.erase(key);
452 }
453
454 void swap(set& other) {
455 mTree.swap(other.mTree);
456 }
457
458 // Lookup
459 size_type count(const Key& key) const {
460 return mTree.count(key);
461 }
462
463 const_iterator find(const Key& key) const {
464 return mTree.find(key);
465 }
466
467 bool contains(const Key& key) const {
468 return mTree.contains(key);
469 }
470
471 bool has(const Key& key) const {
472 return contains(key);
473 }
474
476 return mTree.equal_range(key);
477 }
478
479 const_iterator lower_bound(const Key& key) const {
480 return mTree.lower_bound(key);
481 }
482
483 const_iterator upper_bound(const Key& key) const {
484 return mTree.upper_bound(key);
485 }
486
488 bool operator==(const set& other) const {
489 if (size() != other.size()) return false;
490 return fl::equal(begin(), end(), other.begin());
491 }
492
494 bool operator!=(const set& other) const {
495 return !(*this == other);
496 }
497
499 bool operator<(const set& other) const {
500 return fl::lexicographical_compare(begin(), end(), other.begin(), other.end());
501 }
502
504 bool operator<=(const set& other) const {
505 return *this < other || *this == other;
506 }
507
509 bool operator>(const set& other) const {
510 return other < *this;
511 }
512
514 bool operator>=(const set& other) const {
515 return other <= *this;
516 }
517};
518
519// fl::set_inlined<T, N> - Inlined set implementation using proper allocator
520// This is a using declaration that sets the proper allocator for fl::set
521template <typename T, fl::size N>
523
524} // namespace fl
uint8_t pos
Definition Blur.ino:11
const Key * const_iterator
Definition vector.h:97
typename TreeType::const_reverse_iterator const_reverse_iterator
Definition rbtree.h:1461
typename TreeType::const_iterator const_iterator
Definition rbtree.h:1459
VectorSet(VectorSet &&other) FL_NOEXCEPT
Definition set.h:218
const_iterator begin() const
Definition set.h:239
bool has(const Key &key) const
Definition set.h:323
VectorType::iterator iterator
Definition set.h:207
bool insert(const Key &key)
Definition set.h:263
const Key & front() const
Definition set.h:326
bool erase(const Key &key)
Definition set.h:295
constexpr fl::size capacity() const
Definition set.h:318
bool operator==(const VectorSet &other) const
Equality comparison.
Definition set.h:332
VectorType data
Definition set.h:362
VectorSet & operator=(VectorSet &&other) FL_NOEXCEPT
Definition set.h:230
VectorType::reverse_iterator reverse_iterator
Definition set.h:209
const Key & back() const
Definition set.h:329
fl::vector< Key > VectorType
Definition set.h:206
bool operator>=(const VectorSet &other) const
Greater-than-or-equal comparison.
Definition set.h:357
bool operator<=(const VectorSet &other) const
Less-than-or-equal comparison.
Definition set.h:347
void clear()
Definition set.h:321
bool operator<(const VectorSet &other) const
Lexicographic comparison.
Definition set.h:342
iterator find(const Key &key)
Definition set.h:245
bool insert(Key &&key)
Definition set.h:273
const_iterator find(const Key &key) const
Definition set.h:254
bool emplace(Args &&... args)
Definition set.h:284
constexpr fl::size size() const
Definition set.h:313
reverse_iterator rbegin()
Definition set.h:242
iterator begin()
Definition set.h:237
constexpr bool empty() const
Definition set.h:315
constexpr VectorSet() FL_NOEXCEPT=default
bool operator!=(const VectorSet &other) const
Inequality comparison.
Definition set.h:337
iterator end()
Definition set.h:238
const_iterator end() const
Definition set.h:240
VectorType::const_iterator const_iterator
Definition set.h:208
bool operator>(const VectorSet &other) const
Greater-than comparison.
Definition set.h:352
VectorSet & operator=(const VectorSet &other) FL_NOEXCEPT
Definition set.h:222
reverse_iterator rend()
Definition set.h:243
bool erase(iterator pos)
Definition set.h:304
constexpr fl::size capacity() const
Definition set.h:157
bool insert(Key &&key)
Definition set.h:76
bool operator>=(const VectorSetFixed &other) const
Greater-than-or-equal comparison.
Definition set.h:196
VectorType::iterator iterator
Definition set.h:35
bool operator!=(const VectorSetFixed &other) const
Inequality comparison.
Definition set.h:176
void clear()
Definition set.h:160
iterator end()
Definition set.h:42
const_iterator find(const Key &key) const
Definition set.h:55
bool erase(const Key &key)
Definition set.h:102
bool operator==(const VectorSetFixed &other) const
Equality comparison.
Definition set.h:171
constexpr fl::size size() const
Definition set.h:152
constexpr bool empty() const
Definition set.h:154
bool operator>(const VectorSetFixed &other) const
Greater-than comparison.
Definition set.h:191
VectorType data
Definition set.h:201
VectorType::const_iterator const_iterator
Definition set.h:36
bool next(const Key &key, Key *next_key, bool allow_rollover=false) const
Definition set.h:119
bool operator<(const VectorSetFixed &other) const
Lexicographic comparison.
Definition set.h:181
constexpr VectorSetFixed() FL_NOEXCEPT=default
iterator begin()
Definition set.h:41
FixedVector< Key, N > VectorType
Definition set.h:34
const_iterator begin() const
Definition set.h:43
bool erase(iterator pos)
Definition set.h:111
bool prev(const Key &key, Key *prev_key, bool allow_rollover=false) const
Definition set.h:135
const Key & back() const
Definition set.h:168
bool emplace(Args &&... args)
Definition set.h:89
const_iterator end() const
Definition set.h:44
bool insert(const Key &key)
Definition set.h:64
const Key & front() const
Definition set.h:165
bool has(const Key &key) const
Definition set.h:162
iterator find(const Key &key)
Definition set.h:46
bool operator<=(const VectorSetFixed &other) const
Less-than-or-equal comparison.
Definition set.h:186
void clear()
Definition set.h:431
bool empty() const
Definition set.h:425
bool operator>=(const set &other) const
Greater-than-or-equal comparison.
Definition set.h:514
set & operator=(set &&other) FL_NOEXCEPT=default
const_reverse_iterator rbegin() const
Definition set.h:421
size_type max_size() const
Definition set.h:427
const_reverse_iterator rend() const
Definition set.h:422
ptrdiff_t difference_type
Definition set.h:377
bool operator!=(const set &other) const
Inequality comparison.
Definition set.h:494
set & operator=(fl::initializer_list< Key > init) FL_NOEXCEPT
Definition set.h:406
set(fl::initializer_list< Key > init)
Definition set.h:399
const_reverse_iterator reverse_iterator
Definition set.h:387
void swap(set &other)
Definition set.h:454
fl::pair< const_iterator, bool > insert(Key &&key)
Definition set.h:437
const_iterator begin() const
Definition set.h:415
bool has(const Key &key) const
Definition set.h:471
size_type size() const
Definition set.h:426
fl::pair< const_iterator, bool > insert(const Key &key)
Definition set.h:433
const Key & const_reference
Definition set.h:379
const Key * pointer
Definition set.h:380
bool contains(const Key &key) const
Definition set.h:467
typename TreeType::const_reverse_iterator const_reverse_iterator
Definition set.h:386
const_iterator cbegin() const
Definition set.h:417
set & operator=(const set &other) FL_NOEXCEPT=default
fl::pair< const_iterator, bool > emplace(Args &&... args)
Definition set.h:442
typename TreeType::const_iterator const_iterator
Definition set.h:384
fl::pair< const_iterator, const_iterator > equal_range(const Key &key) const
Definition set.h:475
const_iterator find(const Key &key) const
Definition set.h:463
size_type count(const Key &key) const
Definition set.h:459
const_iterator lower_bound(const Key &key) const
Definition set.h:479
bool operator<(const set &other) const
Lexicographic comparison.
Definition set.h:499
const_iterator erase(const_iterator pos)
Definition set.h:446
const Key & reference
Definition set.h:378
bool operator<=(const set &other) const
Less-than-or-equal comparison.
Definition set.h:504
set() FL_NOEXCEPT=default
const Key * const_pointer
Definition set.h:381
const_iterator cend() const
Definition set.h:418
const_iterator end() const
Definition set.h:416
set(const set &other) FL_NOEXCEPT=default
Allocator allocator_type
Definition set.h:388
bool operator>(const set &other) const
Greater-than comparison.
Definition set.h:509
Key value_type
Definition set.h:375
const_iterator upper_bound(const Key &key) const
Definition set.h:483
fl::SetRedBlackTree< Key, fl::less< Key >, Allocator > TreeType
Definition set.h:369
bool operator==(const set &other) const
Equality comparison.
Definition set.h:488
set(set &&other) FL_NOEXCEPT=default
Key key_type
Definition set.h:374
size_type erase(const Key &key)
Definition set.h:450
const_iterator iterator
Definition set.h:385
allocator_type get_allocator() const
Definition set.h:428
fl::size size_type
Definition set.h:376
Definition set.h:367
const Key * const_iterator
Definition vector.h:453
constexpr T && forward(typename remove_reference< T >::type &t) FL_NOEXCEPT
Definition s16x16x4.h:234
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
void init(Context &ctx, int w, int h)
Definition engine.h:133
fl::set< T, fl::allocator_inlined_slab< T, N > > set_inlined
Definition set.h:522
VectorSetFixed< Key, N > FixedSet
Definition set.h:25
bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) FL_NOEXCEPT
Definition algorithm.h:146
bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2) FL_NOEXCEPT
Definition algorithm.h:96
fl::ptrdiff ptrdiff_t
Definition s16x16x4.h:226
Base definition for an LED controller.
Definition crgb.hpp:179
corkscrew_args args
Definition old.h:149
#define FL_NOEXCEPT
Definition Keyboard.h:22
Binary function object that returns whether the first argument is less than the second.
Definition utility.h:15