FastLED 3.9.15
Loading...
Searching...
No Matches
rbtree.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/assert.h"
4#include "fl/comparators.h"
5#include "fl/namespace.h"
6#include "fl/pair.h"
7#include "fl/type_traits.h"
8#include "fl/type_traits.h"
9#include "fl/algorithm.h"
10#include "fl/allocator.h"
11
12namespace fl {
13
14// Generic Red-Black Tree implementation
15// This is a self-balancing binary search tree with O(log n) operations
16// T is the value type stored in the tree
17// Compare is a comparator that can compare T values
18template <typename T, typename Compare = less<T>, typename Allocator = allocator_slab<char>>
20public:
21 class iterator;
22 class const_iterator;
23 using value_type = T;
24 using size_type = fl::size;
26 using compare_type = Compare;
30 using const_pointer = const value_type*;
31 using allocator_type = Allocator;
32
33 // Red-Black Tree colors
34 enum Color { RED, BLACK };
35
36private:
37 struct Node {
43
44 Node(const value_type& val, Color c = RED, Node* p = nullptr)
45 : data(val), color(c), left(nullptr), right(nullptr), parent(p) {}
46
47 template<typename... Args>
48 Node(Color c, Node* p, Args&&... args)
49 : data(fl::forward<Args>(args)...), color(c), left(nullptr), right(nullptr), parent(p) {}
50 };
51
52 using NodeAllocator = typename Allocator::template rebind<Node>::other;
53
54 Node* root_;
55 fl::size size_;
56 Compare comp_;
58
59 // Helper methods
60 void rotateLeft(Node* x) {
61 Node* y = x->right;
62 x->right = y->left;
63 if (y->left != nullptr) {
64 y->left->parent = x;
65 }
66 y->parent = x->parent;
67 if (x->parent == nullptr) {
68 root_ = y;
69 } else if (x == x->parent->left) {
70 x->parent->left = y;
71 } else {
72 x->parent->right = y;
73 }
74 y->left = x;
75 x->parent = y;
76 }
77
78 void rotateRight(Node* x) {
79 Node* y = x->left;
80 x->left = y->right;
81 if (y->right != nullptr) {
82 y->right->parent = x;
83 }
84 y->parent = x->parent;
85 if (x->parent == nullptr) {
86 root_ = y;
87 } else if (x == x->parent->right) {
88 x->parent->right = y;
89 } else {
90 x->parent->left = y;
91 }
92 y->right = x;
93 x->parent = y;
94 }
95
96 void insertFixup(Node* z) {
97 while (z->parent != nullptr && z->parent->parent != nullptr && z->parent->color == RED) {
98 if (z->parent == z->parent->parent->left) {
99 Node* y = z->parent->parent->right;
100 if (y != nullptr && y->color == RED) {
101 z->parent->color = BLACK;
102 y->color = BLACK;
103 z->parent->parent->color = RED;
104 z = z->parent->parent;
105 } else {
106 if (z == z->parent->right) {
107 z = z->parent;
108 rotateLeft(z);
109 }
110 z->parent->color = BLACK;
111 z->parent->parent->color = RED;
112 rotateRight(z->parent->parent);
113 }
114 } else {
115 Node* y = z->parent->parent->left;
116 if (y != nullptr && y->color == RED) {
117 z->parent->color = BLACK;
118 y->color = BLACK;
119 z->parent->parent->color = RED;
120 z = z->parent->parent;
121 } else {
122 if (z == z->parent->left) {
123 z = z->parent;
124 rotateRight(z);
125 }
126 z->parent->color = BLACK;
127 z->parent->parent->color = RED;
128 rotateLeft(z->parent->parent);
129 }
130 }
131 }
132 root_->color = BLACK;
133 }
134
135 void transplant(Node* u, Node* v) {
136 if (u->parent == nullptr) {
137 root_ = v;
138 } else if (u == u->parent->left) {
139 u->parent->left = v;
140 } else {
141 u->parent->right = v;
142 }
143 if (v != nullptr) {
144 v->parent = u->parent;
145 }
146 }
147
148 Node* minimum(Node* x) const {
149 while (x->left != nullptr) {
150 x = x->left;
151 }
152 return x;
153 }
154
155 Node* maximum(Node* x) const {
156 while (x->right != nullptr) {
157 x = x->right;
158 }
159 return x;
160 }
161
162 // Fixed to properly use xParent when x is nullptr; removes unused parameter warning and centralizes erase fixup
163 void deleteFixup(Node* x, Node* xParent) {
164 while ((x != root_) && (x == nullptr || x->color == BLACK)) {
165 if (x == (xParent ? xParent->left : nullptr)) {
166 Node* w = xParent ? xParent->right : nullptr;
167 if (w && w->color == RED) {
168 w->color = BLACK;
169 if (xParent) { xParent->color = RED; rotateLeft(xParent); }
170 w = xParent ? xParent->right : nullptr;
171 }
172 bool wLeftBlack = (!w || !w->left || w->left->color == BLACK);
173 bool wRightBlack = (!w || !w->right || w->right->color == BLACK);
174 if (wLeftBlack && wRightBlack) {
175 if (w) w->color = RED;
176 x = xParent;
177 xParent = xParent ? xParent->parent : nullptr;
178 } else {
179 if (!w || (w->right == nullptr || w->right->color == BLACK)) {
180 if (w && w->left) w->left->color = BLACK;
181 if (w) { w->color = RED; rotateRight(w); }
182 w = xParent ? xParent->right : nullptr;
183 }
184 if (w) w->color = xParent ? xParent->color : BLACK;
185 if (xParent) xParent->color = BLACK;
186 if (w && w->right) w->right->color = BLACK;
187 if (xParent) rotateLeft(xParent);
188 x = root_;
189 }
190 } else {
191 Node* w = xParent ? xParent->left : nullptr;
192 if (w && w->color == RED) {
193 w->color = BLACK;
194 if (xParent) { xParent->color = RED; rotateRight(xParent); }
195 w = xParent ? xParent->left : nullptr;
196 }
197 bool wRightBlack = (!w || !w->right || w->right->color == BLACK);
198 bool wLeftBlack = (!w || !w->left || w->left->color == BLACK);
199 if (wRightBlack && wLeftBlack) {
200 if (w) w->color = RED;
201 x = xParent;
202 xParent = xParent ? xParent->parent : nullptr;
203 } else {
204 if (!w || (w->left == nullptr || w->left->color == BLACK)) {
205 if (w && w->right) w->right->color = BLACK;
206 if (w) { w->color = RED; rotateLeft(w); }
207 w = xParent ? xParent->left : nullptr;
208 }
209 if (w) w->color = xParent ? xParent->color : BLACK;
210 if (xParent) xParent->color = BLACK;
211 if (w && w->left) w->left->color = BLACK;
212 if (xParent) rotateRight(xParent);
213 x = root_;
214 }
215 }
216 }
217 if (x) x->color = BLACK;
218 }
219
220 Node* findNode(const value_type& value) const {
221 Node* current = root_;
222 while (current != nullptr) {
223 if (comp_(value, current->data)) {
224 current = current->left;
225 } else if (comp_(current->data, value)) {
226 current = current->right;
227 } else {
228 return current;
229 }
230 }
231 return nullptr;
232 }
233
234 void destroyTree(Node* node) {
235 if (node != nullptr) {
236 destroyTree(node->left);
237 destroyTree(node->right);
238 alloc_.destroy(node);
239 alloc_.deallocate(node, 1);
240 }
241 }
242
243 Node* copyTree(Node* node, Node* parent = nullptr) {
244 if (node == nullptr) return nullptr;
245
246 Node* newNode = alloc_.allocate(1);
247 if (newNode == nullptr) {
248 return nullptr;
249 }
250
251 alloc_.construct(newNode, node->data, node->color, parent);
252 newNode->left = copyTree(node->left, newNode);
253 newNode->right = copyTree(node->right, newNode);
254 return newNode;
255 }
256
257 // Shared insert implementation to reduce duplication
258 template <typename U>
260 Node* parent = nullptr;
261 Node* current = root_;
262
263 while (current != nullptr) {
264 parent = current;
265 if (comp_(value, current->data)) {
266 current = current->left;
267 } else if (comp_(current->data, value)) {
268 current = current->right;
269 } else {
270 return fl::pair<iterator, bool>(iterator(current, this), false);
271 }
272 }
273
274 Node* newNode = alloc_.allocate(1);
275 if (newNode == nullptr) {
276 return fl::pair<iterator, bool>(end(), false);
277 }
278
279 alloc_.construct(newNode, fl::forward<U>(value), RED, parent);
280
281 if (parent == nullptr) {
282 root_ = newNode;
283 } else if (comp_(newNode->data, parent->data)) {
284 parent->left = newNode;
285 } else {
286 parent->right = newNode;
287 }
288
289 insertFixup(newNode);
290 ++size_;
291
292 return fl::pair<iterator, bool>(iterator(newNode, this), true);
293 }
294
295 // Bound helpers to avoid duplication between const/non-const
296 Node* lowerBoundNode(const value_type& value) const {
297 Node* current = root_;
298 Node* result = nullptr;
299 while (current != nullptr) {
300 if (!comp_(current->data, value)) {
301 result = current;
302 current = current->left;
303 } else {
304 current = current->right;
305 }
306 }
307 return result;
308 }
309
310 Node* upperBoundNode(const value_type& value) const {
311 Node* current = root_;
312 Node* result = nullptr;
313 while (current != nullptr) {
314 if (comp_(value, current->data)) {
315 result = current;
316 current = current->left;
317 } else {
318 current = current->right;
319 }
320 }
321 return result;
322 }
323
324public:
325 // Iterator implementation
326 class iterator {
327 friend class RedBlackTree;
328 friend class const_iterator;
329 public:
330 using value_type = T;
331 private:
334
335 Node* successor(Node* x) const {
336 if (x == nullptr) return nullptr;
337 if (x->right != nullptr) {
338 return mTree->minimum(x->right);
339 }
340 Node* y = x->parent;
341 while (y != nullptr && x == y->right) {
342 x = y;
343 y = y->parent;
344 }
345 return y;
346 }
347
349 if (x == nullptr) return nullptr;
350 if (x->left != nullptr) {
351 return mTree->maximum(x->left);
352 }
353 Node* y = x->parent;
354 while (y != nullptr && x == y->left) {
355 x = y;
356 y = y->parent;
357 }
358 return y;
359 }
360
361 public:
362 iterator() : node_(nullptr), mTree(nullptr) {}
363 iterator(Node* n, const RedBlackTree* t) : node_(n), mTree(t) {}
364
366 FASTLED_ASSERT(node_ != nullptr, "RedBlackTree::iterator: dereferencing end iterator");
367 return node_->data;
368 }
370 FASTLED_ASSERT(node_ != nullptr, "RedBlackTree::iterator: dereferencing end iterator");
371 return &(node_->data);
372 }
373
375 if (node_) {
377 }
378 return *this;
379 }
380
382 iterator temp = *this;
383 ++(*this);
384 return temp;
385 }
386
388 if (node_) {
390 } else if (mTree && mTree->root_) {
391 node_ = mTree->maximum(mTree->root_);
392 }
393 return *this;
394 }
395
397 iterator temp = *this;
398 --(*this);
399 return temp;
400 }
401
402 bool operator==(const iterator& other) const {
403 return node_ == other.node_;
404 }
405
406 bool operator!=(const iterator& other) const {
407 return node_ != other.node_;
408 }
409 };
410
412 friend class RedBlackTree;
413 friend class iterator;
414 private:
415 const Node* node_;
417
418 const Node* successor(const Node* x) const {
419 if (x == nullptr) return nullptr;
420 if (x->right != nullptr) {
421 return mTree->minimum(x->right);
422 }
423 const Node* y = x->parent;
424 while (y != nullptr && x == y->right) {
425 x = y;
426 y = y->parent;
427 }
428 return y;
429 }
430
431 const Node* predecessor(const Node* x) const {
432 if (x == nullptr) return nullptr;
433 if (x->left != nullptr) {
434 return mTree->maximum(x->left);
435 }
436 const Node* y = x->parent;
437 while (y != nullptr && x == y->left) {
438 x = y;
439 y = y->parent;
440 }
441 return y;
442 }
443
444 public:
445 const_iterator() : node_(nullptr), mTree(nullptr) {}
446 const_iterator(const Node* n, const RedBlackTree* t) : node_(n), mTree(t) {}
447 const_iterator(const iterator& it) : node_(it.node_), mTree(it.mTree) {}
448
449 const value_type& operator*() const {
450 FASTLED_ASSERT(node_ != nullptr, "RedBlackTree::iterator: dereferencing end iterator");
451 return node_->data;
452 }
453 const value_type* operator->() const {
454 FASTLED_ASSERT(node_ != nullptr, "RedBlackTree::iterator: dereferencing end iterator");
455 return &(node_->data);
456 }
457
459 if (node_) {
461 }
462 return *this;
463 }
464
466 const_iterator temp = *this;
467 ++(*this);
468 return temp;
469 }
470
472 if (node_) {
474 } else if (mTree && mTree->root_) {
475 // Decrementing from end() should give us the maximum element
476 node_ = mTree->maximum(mTree->root_);
477 }
478 return *this;
479 }
480
482 const_iterator temp = *this;
483 --(*this);
484 return temp;
485 }
486
487 bool operator==(const const_iterator& other) const {
488 return node_ == other.node_;
489 }
490
491 bool operator!=(const const_iterator& other) const {
492 return node_ != other.node_;
493 }
494 };
495
496 // Constructors and destructor
497 RedBlackTree(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
498 : root_(nullptr), size_(0), comp_(comp), alloc_(alloc) {}
499
501 : root_(nullptr), size_(other.size_), comp_(other.comp_), alloc_(other.alloc_) {
502 if (other.root_) {
503 root_ = copyTree(other.root_);
504 }
505 }
506
508 if (this != &other) {
509 clear();
510 size_ = other.size_;
511 comp_ = other.comp_;
512 alloc_ = other.alloc_;
513 if (other.root_) {
514 root_ = copyTree(other.root_);
515 }
516 }
517 return *this;
518 }
519
521 clear();
522 }
523
524 // Iterators
525 iterator begin() {
526 if (root_ == nullptr) return end();
527 return iterator(minimum(root_), this);
528 }
529
530 const_iterator begin() const {
531 if (root_ == nullptr) return end();
532 return const_iterator(minimum(root_), this);
533 }
534
535 const_iterator cbegin() const {
536 return begin();
537 }
538
539 iterator end() {
540 return iterator(nullptr, this);
541 }
542
543 const_iterator end() const {
544 return const_iterator(nullptr, this);
545 }
546
547 const_iterator cend() const {
548 return end();
549 }
550
551 // Capacity
552 bool empty() const { return size_ == 0; }
553 fl::size size() const { return size_; }
554 fl::size max_size() const { return fl::size(-1); }
555
556 // Modifiers
557 void clear() {
559 root_ = nullptr;
560 size_ = 0;
561 }
562
564 return insertImpl(value);
565 }
566
568 return insertImpl(fl::move(value));
569 }
570
571 template<typename... Args>
574 return insert(fl::move(value));
575 }
576
577 iterator erase(const_iterator pos) {
578 if (pos.node_ == nullptr) return end();
579
580 Node* nodeToDelete = const_cast<Node*>(pos.node_);
581 Node* successor = nullptr;
582
583 if (nodeToDelete->right != nullptr) {
584 successor = minimum(nodeToDelete->right);
585 } else {
586 Node* current = nodeToDelete;
587 Node* parent = current->parent;
588 while (parent != nullptr && current == parent->right) {
589 current = parent;
590 parent = parent->parent;
591 }
592 successor = parent;
593 }
594
595 Node* y = nodeToDelete;
596 Node* x = nullptr;
597 Node* xParent = nullptr;
598 Color originalColor = y->color;
599
600 if (nodeToDelete->left == nullptr) {
601 x = nodeToDelete->right;
602 xParent = nodeToDelete->parent;
603 transplant(nodeToDelete, nodeToDelete->right);
604 } else if (nodeToDelete->right == nullptr) {
605 x = nodeToDelete->left;
606 xParent = nodeToDelete->parent;
607 transplant(nodeToDelete, nodeToDelete->left);
608 } else {
609 y = minimum(nodeToDelete->right);
610 originalColor = y->color;
611 x = y->right;
612 if (y->parent == nodeToDelete) {
613 xParent = y;
614 if (x) x->parent = y;
615 } else {
616 xParent = y->parent;
617 transplant(y, y->right);
618 y->right = nodeToDelete->right;
619 y->right->parent = y;
620 }
621
622 transplant(nodeToDelete, y);
623 y->left = nodeToDelete->left;
624 y->left->parent = y;
625 y->color = nodeToDelete->color;
626 }
627
628 alloc_.destroy(nodeToDelete);
629 alloc_.deallocate(nodeToDelete, 1);
630 --size_;
631
632 if (originalColor == BLACK) {
633 deleteFixup(x, xParent);
634 }
635
636 return iterator(successor, this);
637 }
638
639 fl::size erase(const value_type& value) {
640 Node* node = findNode(value);
641 if (node == nullptr) return 0;
642
643 erase(const_iterator(node, this));
644 return 1;
645 }
646
647 void swap(RedBlackTree& other) {
648 fl::swap(root_, other.root_);
649 fl::swap(size_, other.size_);
650 fl::swap(comp_, other.comp_);
651 fl::swap(alloc_, other.alloc_);
652 }
653
654 // Lookup
655 fl::size count(const value_type& value) const {
656 return findNode(value) != nullptr ? 1 : 0;
657 }
658
659 iterator find(const value_type& value) {
660 Node* node = findNode(value);
661 return node ? iterator(node, this) : end();
662 }
663
664 const_iterator find(const value_type& value) const {
665 Node* node = findNode(value);
666 return node ? const_iterator(node, this) : end();
667 }
668
669 bool contains(const value_type& value) const {
670 return findNode(value) != nullptr;
671 }
672
674 iterator lower = lower_bound(value);
675 iterator upper = upper_bound(value);
676 return fl::pair<iterator, iterator>(lower, upper);
677 }
678
680 const_iterator lower = lower_bound(value);
681 const_iterator upper = upper_bound(value);
682 return fl::pair<const_iterator, const_iterator>(lower, upper);
683 }
684
685 iterator lower_bound(const value_type& value) {
686 Node* n = lowerBoundNode(value);
687 return n ? iterator(n, this) : end();
688 }
689
690 const_iterator lower_bound(const value_type& value) const {
691 Node* n = lowerBoundNode(value);
692 return n ? const_iterator(n, this) : end();
693 }
694
695 iterator upper_bound(const value_type& value) {
696 Node* n = upperBoundNode(value);
697 return n ? iterator(n, this) : end();
698 }
699
700 const_iterator upper_bound(const value_type& value) const {
701 Node* n = upperBoundNode(value);
702 return n ? const_iterator(n, this) : end();
703 }
704
705 // Observers
707 return comp_;
708 }
709
710 // Comparison operators
711 bool operator==(const RedBlackTree& other) const {
712 if (size_ != other.size_) return false;
713
714 const_iterator it1 = begin();
715 const_iterator it2 = other.begin();
716
717 while (it1 != end() && it2 != other.end()) {
718 // Two values are equal if neither is less than the other
719 if (comp_(*it1, *it2) || comp_(*it2, *it1)) {
720 return false;
721 }
722 ++it1;
723 ++it2;
724 }
725
726 return it1 == end() && it2 == other.end();
727 }
728
729 bool operator!=(const RedBlackTree& other) const {
730 return !(*this == other);
731 }
732};
733
734// Specialized Red-Black Tree for key-value pairs (maps)
735template <typename Key, typename Value, typename Compare = less<Key>, typename Allocator = allocator_slab<char>>
737public:
738 using key_type = Key;
739 using mapped_type = Value;
741 using size_type = fl::size;
743 using key_compare = Compare;
747 using const_pointer = const value_type*;
748 using allocator_type = Allocator;
749
750private:
751 // Comparator for pairs that compares only the key
752 struct PairCompare {
753 Compare comp_;
754
755 PairCompare(const Compare& comp = Compare()) : comp_(comp) {}
756
757 bool operator()(const value_type& a, const value_type& b) const {
758 return comp_(a.first, b.first);
759 }
760 };
761
764
765public:
766 using iterator = typename TreeType::iterator;
768
769 // Constructors and destructor
770 MapRedBlackTree(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
771 : mTree(PairCompare(comp), alloc) {}
772
773 MapRedBlackTree(const MapRedBlackTree& other) = default;
774 MapRedBlackTree& operator=(const MapRedBlackTree& other) = default;
775 ~MapRedBlackTree() = default;
776
777 // Iterators
778 iterator begin() { return mTree.begin(); }
779 const_iterator begin() const { return mTree.begin(); }
780 const_iterator cbegin() const { return mTree.cbegin(); }
781 iterator end() { return mTree.end(); }
782 const_iterator end() const { return mTree.end(); }
783 const_iterator cend() const { return mTree.cend(); }
784
785 // Capacity
786 bool empty() const { return mTree.empty(); }
787 fl::size size() const { return mTree.size(); }
788 fl::size max_size() const { return mTree.max_size(); }
789
790 // Element access
791 Value& operator[](const Key& key) {
792 auto result = mTree.insert(value_type(key, Value()));
793 return result.first->second;
794 }
795
796 Value& at(const Key& key) {
797 auto it = mTree.find(value_type(key, Value()));
798 FASTLED_ASSERT(it != mTree.end(), "MapRedBlackTree::at: key not found");
799 return it->second;
800 }
801
802 const Value& at(const Key& key) const {
803 auto it = mTree.find(value_type(key, Value()));
804 FASTLED_ASSERT(it != mTree.end(), "MapRedBlackTree::at: key not found");
805 return it->second;
806 }
807
808 // Modifiers
809 void clear() { mTree.clear(); }
810
812 return mTree.insert(value);
813 }
814
816 return mTree.insert(fl::move(value));
817 }
818
819 template<typename... Args>
821 return mTree.emplace(fl::forward<Args>(args)...);
822 }
823
825 return mTree.erase(pos);
826 }
827
828 fl::size erase(const Key& key) {
829 return mTree.erase(value_type(key, Value()));
830 }
831
832 void swap(MapRedBlackTree& other) {
833 mTree.swap(other.mTree);
834 }
835
836 // Lookup
837 fl::size count(const Key& key) const {
838 return mTree.count(value_type(key, Value()));
839 }
840
841 iterator find(const Key& key) {
842 return mTree.find(value_type(key, Value()));
843 }
844
845 const_iterator find(const Key& key) const {
846 return mTree.find(value_type(key, Value()));
847 }
848
849 bool contains(const Key& key) const {
850 return mTree.contains(value_type(key, Value()));
851 }
852
854 return mTree.equal_range(value_type(key, Value()));
855 }
856
858 return mTree.equal_range(value_type(key, Value()));
859 }
860
862 return mTree.lower_bound(value_type(key, Value()));
863 }
864
865 const_iterator lower_bound(const Key& key) const {
866 return mTree.lower_bound(value_type(key, Value()));
867 }
868
870 return mTree.upper_bound(value_type(key, Value()));
871 }
872
873 const_iterator upper_bound(const Key& key) const {
874 return mTree.upper_bound(value_type(key, Value()));
875 }
876
877 // Observers
879 return mTree.value_comp().comp_;
880 }
881
882 // Comparison operators
883 bool operator==(const MapRedBlackTree& other) const {
884 if (mTree.size() != other.mTree.size()) return false;
885
886 auto it1 = mTree.begin();
887 auto it2 = other.mTree.begin();
888
889 while (it1 != mTree.end() && it2 != other.mTree.end()) {
890 // Compare both key and value
891 if (it1->first != it2->first || it1->second != it2->second) {
892 return false;
893 }
894 ++it1;
895 ++it2;
896 }
897
898 return it1 == mTree.end() && it2 == other.mTree.end();
899 }
900
901 bool operator!=(const MapRedBlackTree& other) const {
902 return !(*this == other);
903 }
904};
905
906// Specialized Red-Black Tree for sets (just keys, no values)
907template <typename Key, typename Compare = less<Key>, typename Allocator = allocator_slab<char>>
909public:
910 using key_type = Key;
912 using size_type = fl::size;
914 using key_compare = Compare;
915 using reference = const value_type&;
917 using pointer = const value_type*;
918 using const_pointer = const value_type*;
919 using allocator_type = Allocator;
920
921private:
924
925public:
926 using iterator = typename TreeType::const_iterator; // Set iterators are always const
927 using const_iterator = typename TreeType::const_iterator;
928
929 // Constructors and destructor
930 SetRedBlackTree(const Compare& comp = Compare(), const Allocator& alloc = Allocator())
931 : mTree(comp, alloc) {}
932
933 SetRedBlackTree(const SetRedBlackTree& other) = default;
934 SetRedBlackTree& operator=(const SetRedBlackTree& other) = default;
935 ~SetRedBlackTree() = default;
936
937 // Iterators
938 const_iterator begin() const { return mTree.begin(); }
939 const_iterator cbegin() const { return mTree.cbegin(); }
940 const_iterator end() const { return mTree.end(); }
941 const_iterator cend() const { return mTree.cend(); }
942
943 // Capacity
944 bool empty() const { return mTree.empty(); }
945 fl::size size() const { return mTree.size(); }
946 fl::size max_size() const { return mTree.max_size(); }
947
948 // Modifiers
949 void clear() { mTree.clear(); }
950
952 auto result = mTree.insert(value);
953 return fl::pair<const_iterator, bool>(result.first, result.second);
954 }
955
957 auto result = mTree.insert(fl::move(value));
958 return fl::pair<const_iterator, bool>(result.first, result.second);
959 }
960
961 template<typename... Args>
963 auto result = mTree.emplace(fl::forward<Args>(args)...);
964 return fl::pair<const_iterator, bool>(result.first, result.second);
965 }
966
968 return mTree.erase(pos);
969 }
970
971 fl::size erase(const Key& key) {
972 return mTree.erase(key);
973 }
974
975 void swap(SetRedBlackTree& other) {
976 mTree.swap(other.mTree);
977 }
978
979 // Lookup
980 fl::size count(const Key& key) const {
981 return mTree.count(key);
982 }
983
984 const_iterator find(const Key& key) const {
985 return mTree.find(key);
986 }
987
988 bool contains(const Key& key) const {
989 return mTree.contains(key);
990 }
991
993 return mTree.equal_range(key);
994 }
995
996 const_iterator lower_bound(const Key& key) const {
997 return mTree.lower_bound(key);
998 }
999
1000 const_iterator upper_bound(const Key& key) const {
1001 return mTree.upper_bound(key);
1002 }
1003
1004 // Observers
1006 return mTree.value_comp();
1007 }
1008
1009 // Comparison operators
1010 bool operator==(const SetRedBlackTree& other) const {
1011 return mTree == other.mTree;
1012 }
1013
1014 bool operator!=(const SetRedBlackTree& other) const {
1015 return mTree != other.mTree;
1016 }
1017};
1018
1019} // namespace fl
int y
Definition simple.h:93
int x
Definition simple.h:92
uint8_t pos
Definition Blur.ino:11
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:94
const_iterator upper_bound(const Key &key) const
Definition rbtree.h:873
MapRedBlackTree(const MapRedBlackTree &other)=default
iterator end()
Definition rbtree.h:781
MapRedBlackTree & operator=(const MapRedBlackTree &other)=default
fl::size size() const
Definition rbtree.h:787
const_iterator begin() const
Definition rbtree.h:779
const_iterator cbegin() const
Definition rbtree.h:780
const Value & at(const Key &key) const
Definition rbtree.h:802
bool operator!=(const MapRedBlackTree &other) const
Definition rbtree.h:901
RedBlackTree< value_type, PairCompare, fl::allocator_slab< char > > TreeType
Definition rbtree.h:762
iterator erase(const_iterator pos)
Definition rbtree.h:824
const_iterator end() const
Definition rbtree.h:782
bool empty() const
Definition rbtree.h:786
Value & operator[](const Key &key)
Definition rbtree.h:791
iterator find(const Key &key)
Definition rbtree.h:841
fl::pair< iterator, iterator > equal_range(const Key &key)
Definition rbtree.h:853
key_compare key_comp() const
Definition rbtree.h:878
fl::pair< iterator, bool > emplace(Args &&... args)
Definition rbtree.h:820
const_iterator lower_bound(const Key &key) const
Definition rbtree.h:865
iterator lower_bound(const Key &key)
Definition rbtree.h:861
MapRedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
Definition rbtree.h:770
iterator begin()
Definition rbtree.h:778
bool contains(const Key &key) const
Definition rbtree.h:849
fl::size erase(const Key &key)
Definition rbtree.h:828
bool operator==(const MapRedBlackTree &other) const
Definition rbtree.h:883
void swap(MapRedBlackTree &other)
Definition rbtree.h:832
fl::pair< const_iterator, const_iterator > equal_range(const Key &key) const
Definition rbtree.h:857
fl::pair< iterator, bool > insert(value_type &&value)
Definition rbtree.h:815
const_iterator find(const Key &key) const
Definition rbtree.h:845
fl::pair< iterator, bool > insert(const value_type &value)
Definition rbtree.h:811
fl::size max_size() const
Definition rbtree.h:788
Value & at(const Key &key)
Definition rbtree.h:796
~MapRedBlackTree()=default
const_iterator cend() const
Definition rbtree.h:783
iterator upper_bound(const Key &key)
Definition rbtree.h:869
fl::size count(const Key &key) const
Definition rbtree.h:837
const Node * predecessor(const Node *x) const
Definition rbtree.h:431
const_iterator & operator--()
Definition rbtree.h:471
const value_type & operator*() const
Definition rbtree.h:449
bool operator==(const const_iterator &other) const
Definition rbtree.h:487
const RedBlackTree * mTree
Definition rbtree.h:416
const value_type * operator->() const
Definition rbtree.h:453
const_iterator operator++(int)
Definition rbtree.h:465
const_iterator & operator++()
Definition rbtree.h:458
const_iterator operator--(int)
Definition rbtree.h:481
const Node * successor(const Node *x) const
Definition rbtree.h:418
const_iterator(const Node *n, const RedBlackTree *t)
Definition rbtree.h:446
const_iterator(const iterator &it)
Definition rbtree.h:447
bool operator!=(const const_iterator &other) const
Definition rbtree.h:491
Node * predecessor(Node *x) const
Definition rbtree.h:348
friend class RedBlackTree
Definition rbtree.h:327
iterator & operator--()
Definition rbtree.h:387
Node * successor(Node *x) const
Definition rbtree.h:335
bool operator==(const iterator &other) const
Definition rbtree.h:402
value_type & operator*() const
Definition rbtree.h:365
value_type * operator->() const
Definition rbtree.h:369
iterator operator++(int)
Definition rbtree.h:381
const RedBlackTree * mTree
Definition rbtree.h:333
iterator(Node *n, const RedBlackTree *t)
Definition rbtree.h:363
iterator & operator++()
Definition rbtree.h:374
iterator operator--(int)
Definition rbtree.h:396
friend class const_iterator
Definition rbtree.h:328
bool operator!=(const iterator &other) const
Definition rbtree.h:406
Allocator allocator_type
Definition rbtree.h:31
fl::size erase(const value_type &value)
Definition rbtree.h:639
iterator upper_bound(const value_type &value)
Definition rbtree.h:695
RedBlackTree & operator=(const RedBlackTree &other)
Definition rbtree.h:507
Compare compare_type
Definition rbtree.h:26
RedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
Definition rbtree.h:497
fl::pair< iterator, iterator > equal_range(const value_type &value)
Definition rbtree.h:673
Node * findNode(const value_type &value) const
Definition rbtree.h:220
fl::pair< iterator, bool > emplace(Args &&... args)
Definition rbtree.h:572
bool empty() const
Definition rbtree.h:552
const_iterator upper_bound(const value_type &value) const
Definition rbtree.h:700
compare_type value_comp() const
Definition rbtree.h:706
fl::size size_type
Definition rbtree.h:24
void deleteFixup(Node *x, Node *xParent)
Definition rbtree.h:163
bool operator!=(const RedBlackTree &other) const
Definition rbtree.h:729
void destroyTree(Node *node)
Definition rbtree.h:234
Node * maximum(Node *x) const
Definition rbtree.h:155
fl::size size() const
Definition rbtree.h:553
iterator end()
Definition rbtree.h:539
RedBlackTree(const RedBlackTree &other)
Definition rbtree.h:500
iterator erase(const_iterator pos)
Definition rbtree.h:577
iterator begin()
Definition rbtree.h:525
void swap(RedBlackTree &other)
Definition rbtree.h:647
fl::size count(const value_type &value) const
Definition rbtree.h:655
fl::size max_size() const
Definition rbtree.h:554
const_iterator end() const
Definition rbtree.h:543
Node * lowerBoundNode(const value_type &value) const
Definition rbtree.h:296
bool operator==(const RedBlackTree &other) const
Definition rbtree.h:711
void insertFixup(Node *z)
Definition rbtree.h:96
const value_type & const_reference
Definition rbtree.h:28
const_iterator begin() const
Definition rbtree.h:530
void rotateRight(Node *x)
Definition rbtree.h:78
fl::pair< iterator, bool > insertImpl(U &&value)
Definition rbtree.h:259
iterator find(const value_type &value)
Definition rbtree.h:659
bool contains(const value_type &value) const
Definition rbtree.h:669
const_iterator cbegin() const
Definition rbtree.h:535
iterator lower_bound(const value_type &value)
Definition rbtree.h:685
Node * copyTree(Node *node, Node *parent=nullptr)
Definition rbtree.h:243
const_iterator find(const value_type &value) const
Definition rbtree.h:664
Node * upperBoundNode(const value_type &value) const
Definition rbtree.h:310
typename Allocator::template rebind< Node >::other NodeAllocator
Definition rbtree.h:52
Node * minimum(Node *x) const
Definition rbtree.h:148
void transplant(Node *u, Node *v)
Definition rbtree.h:135
const_iterator cend() const
Definition rbtree.h:547
const_iterator lower_bound(const value_type &value) const
Definition rbtree.h:690
fl::pair< iterator, bool > insert(const value_type &value)
Definition rbtree.h:563
value_type & reference
Definition rbtree.h:27
ptrdiff_t difference_type
Definition rbtree.h:25
const value_type * const_pointer
Definition rbtree.h:30
fl::pair< const_iterator, const_iterator > equal_range(const value_type &value) const
Definition rbtree.h:679
fl::pair< iterator, bool > insert(value_type &&value)
Definition rbtree.h:567
value_type * pointer
Definition rbtree.h:29
void rotateLeft(Node *x)
Definition rbtree.h:60
fl::size erase(const Key &key)
Definition rbtree.h:971
Compare key_compare
Definition rbtree.h:914
const value_type * pointer
Definition rbtree.h:917
const_iterator cbegin() const
Definition rbtree.h:939
fl::size size_type
Definition rbtree.h:912
bool contains(const Key &key) const
Definition rbtree.h:988
void swap(SetRedBlackTree &other)
Definition rbtree.h:975
fl::pair< const_iterator, bool > insert(value_type &&value)
Definition rbtree.h:956
fl::size size() const
Definition rbtree.h:945
const_iterator lower_bound(const Key &key) const
Definition rbtree.h:996
key_compare key_comp() const
Definition rbtree.h:1005
~SetRedBlackTree()=default
fl::pair< const_iterator, const_iterator > equal_range(const Key &key) const
Definition rbtree.h:992
const_iterator begin() const
Definition rbtree.h:938
fl::pair< const_iterator, bool > emplace(Args &&... args)
Definition rbtree.h:962
ptrdiff_t difference_type
Definition rbtree.h:913
const_iterator erase(const_iterator pos)
Definition rbtree.h:967
fl::pair< const_iterator, bool > insert(const value_type &value)
Definition rbtree.h:951
const value_type & reference
Definition rbtree.h:915
typename TreeType::const_iterator iterator
Definition rbtree.h:926
Allocator allocator_type
Definition rbtree.h:919
const_iterator upper_bound(const Key &key) const
Definition rbtree.h:1000
SetRedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
Definition rbtree.h:930
RedBlackTree< Key, Compare, Allocator > TreeType
Definition rbtree.h:922
typename TreeType::const_iterator const_iterator
Definition rbtree.h:927
bool operator!=(const SetRedBlackTree &other) const
Definition rbtree.h:1014
const_iterator find(const Key &key) const
Definition rbtree.h:984
const value_type * const_pointer
Definition rbtree.h:918
fl::size max_size() const
Definition rbtree.h:946
bool empty() const
Definition rbtree.h:944
SetRedBlackTree(const SetRedBlackTree &other)=default
fl::size count(const Key &key) const
Definition rbtree.h:980
const_iterator end() const
Definition rbtree.h:940
bool operator==(const SetRedBlackTree &other) const
Definition rbtree.h:1010
const value_type & const_reference
Definition rbtree.h:916
const_iterator cend() const
Definition rbtree.h:941
SetRedBlackTree & operator=(const SetRedBlackTree &other)=default
Result type for promise operations.
static uint32_t t
Definition Luminova.h:54
Implements the FastLED namespace macros.
constexpr remove_reference< T >::type && move(T &&t) noexcept
Definition move.h:27
void swap(array< T, N > &lhs, array< T, N > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition array.h:156
__PTRDIFF_TYPE__ ptrdiff_t
Definition cstddef.h:22
constexpr T && forward(typename remove_reference< T >::type &t) noexcept
IMPORTANT!
Definition crgb.h:20
corkscrew_args args
Definition old.h:150
Definition Keyboard.h:22
PairCompare(const Compare &comp=Compare())
Definition rbtree.h:755
bool operator()(const value_type &a, const value_type &b) const
Definition rbtree.h:757
value_type data
Definition rbtree.h:38
Node(const value_type &val, Color c=RED, Node *p=nullptr)
Definition rbtree.h:44
Node(Color c, Node *p, Args &&... args)
Definition rbtree.h:48
T1 first
Definition pair.h:14
Definition pair.h:9