18template <
typename T,
typename Compare = less<T>,
typename Allocator = allocator_slab<
char>>
47 template<
typename... Args>
63 if (
y->left !=
nullptr) {
66 y->parent =
x->parent;
67 if (
x->parent ==
nullptr) {
69 }
else if (
x ==
x->parent->left) {
81 if (
y->right !=
nullptr) {
84 y->parent =
x->parent;
85 if (
x->parent ==
nullptr) {
87 }
else if (
x ==
x->parent->right) {
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) {
103 z->parent->parent->color =
RED;
104 z =
z->parent->parent;
106 if (
z ==
z->parent->right) {
111 z->parent->parent->color =
RED;
115 Node*
y =
z->parent->parent->left;
116 if (
y !=
nullptr &&
y->color ==
RED) {
119 z->parent->parent->color =
RED;
120 z =
z->parent->parent;
122 if (
z ==
z->parent->left) {
127 z->parent->parent->color =
RED;
136 if (u->parent ==
nullptr) {
138 }
else if (u == u->parent->
left) {
141 u->parent->
right = v;
144 v->parent = u->parent;
149 while (
x->left !=
nullptr) {
156 while (
x->right !=
nullptr) {
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) {
170 w = xParent ? xParent->right :
nullptr;
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;
177 xParent = xParent ? xParent->parent :
nullptr;
179 if (!w || (w->right ==
nullptr || w->right->
color ==
BLACK)) {
182 w = xParent ? xParent->right :
nullptr;
184 if (w) w->color = xParent ? xParent->color :
BLACK;
185 if (xParent) xParent->color =
BLACK;
191 Node* w = xParent ? xParent->left :
nullptr;
192 if (w && w->color ==
RED) {
195 w = xParent ? xParent->left :
nullptr;
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;
202 xParent = xParent ? xParent->parent :
nullptr;
204 if (!w || (w->left ==
nullptr || w->left->
color ==
BLACK)) {
207 w = xParent ? xParent->left :
nullptr;
209 if (w) w->color = xParent ? xParent->color :
BLACK;
210 if (xParent) xParent->color =
BLACK;
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;
235 if (node !=
nullptr) {
239 alloc_.deallocate(node, 1);
243 Node*
copyTree(Node* node, Node* parent =
nullptr) {
244 if (node ==
nullptr)
return nullptr;
246 Node* newNode =
alloc_.allocate(1);
247 if (newNode ==
nullptr) {
251 alloc_.construct(newNode, node->data, node->color, parent);
252 newNode->left =
copyTree(node->left, newNode);
253 newNode->right =
copyTree(node->right, newNode);
258 template <
typename U>
260 Node* parent =
nullptr;
261 Node* current =
root_;
263 while (current !=
nullptr) {
265 if (
comp_(value, current->data)) {
266 current = current->left;
267 }
else if (
comp_(current->data, value)) {
268 current = current->right;
274 Node* newNode =
alloc_.allocate(1);
275 if (newNode ==
nullptr) {
281 if (parent ==
nullptr) {
283 }
else if (
comp_(newNode->data, parent->data)) {
284 parent->left = newNode;
286 parent->right = newNode;
297 Node* current =
root_;
299 while (current !=
nullptr) {
300 if (!
comp_(current->data, value)) {
302 current = current->left;
304 current = current->right;
311 Node* current =
root_;
313 while (current !=
nullptr) {
314 if (
comp_(value, current->data)) {
316 current = current->left;
318 current = current->right;
336 if (
x ==
nullptr)
return nullptr;
337 if (
x->right !=
nullptr) {
338 return mTree->minimum(
x->right);
341 while (
y !=
nullptr &&
x ==
y->right) {
349 if (
x ==
nullptr)
return nullptr;
350 if (
x->left !=
nullptr) {
351 return mTree->maximum(
x->left);
354 while (
y !=
nullptr &&
x ==
y->left) {
366 FASTLED_ASSERT(
node_ !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
370 FASTLED_ASSERT(
node_ !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
371 return &(
node_->data);
419 if (
x ==
nullptr)
return nullptr;
420 if (
x->right !=
nullptr) {
421 return mTree->minimum(
x->right);
423 const Node*
y =
x->parent;
424 while (
y !=
nullptr &&
x ==
y->right) {
432 if (
x ==
nullptr)
return nullptr;
433 if (
x->left !=
nullptr) {
434 return mTree->maximum(
x->left);
436 const Node*
y =
x->parent;
437 while (
y !=
nullptr &&
x ==
y->left) {
450 FASTLED_ASSERT(
node_ !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
454 FASTLED_ASSERT(
node_ !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
455 return &(
node_->data);
497 RedBlackTree(
const Compare& comp = Compare(),
const Allocator& alloc = Allocator())
503 root_ = copyTree(other.root_);
508 if (
this != &other) {
540 return iterator(
nullptr,
this);
543 const_iterator
end()
const {
544 return const_iterator(
nullptr,
this);
571 template<
typename... Args>
578 if (
pos.node_ ==
nullptr)
return end();
580 Node* nodeToDelete =
const_cast<Node*
>(
pos.node_);
581 Node* successor =
nullptr;
583 if (nodeToDelete->right !=
nullptr) {
584 successor =
minimum(nodeToDelete->right);
586 Node* current = nodeToDelete;
587 Node* parent = current->parent;
588 while (parent !=
nullptr && current == parent->right) {
590 parent = parent->parent;
595 Node*
y = nodeToDelete;
597 Node* xParent =
nullptr;
598 Color originalColor =
y->color;
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;
610 originalColor =
y->color;
612 if (
y->parent == nodeToDelete) {
614 if (
x)
x->parent =
y;
618 y->right = nodeToDelete->right;
619 y->right->parent =
y;
623 y->left = nodeToDelete->left;
625 y->color = nodeToDelete->color;
628 alloc_.destroy(nodeToDelete);
629 alloc_.deallocate(nodeToDelete, 1);
632 if (originalColor ==
BLACK) {
636 return iterator(successor,
this);
641 if (node ==
nullptr)
return 0;
643 erase(const_iterator(node,
this));
656 return findNode(value) !=
nullptr ? 1 : 0;
661 return node ? iterator(node,
this) :
end();
666 return node ? const_iterator(node,
this) :
end();
687 return n ? iterator(n,
this) :
end();
692 return n ? const_iterator(n,
this) :
end();
697 return n ? iterator(n,
this) :
end();
702 return n ? const_iterator(n,
this) :
end();
714 const_iterator it1 =
begin();
715 const_iterator it2 = other.
begin();
717 while (it1 !=
end() && it2 != other.
end()) {
726 return it1 ==
end() && it2 == other.
end();
730 return !(*
this == other);
735template <
typename Key,
typename Value,
typename Compare = less<Key>,
typename Allocator = allocator_slab<
char>>
770 MapRedBlackTree(
const Compare& comp = Compare(),
const Allocator& alloc = Allocator())
771 :
mTree(PairCompare(comp), alloc) {}
793 return result.first->second;
798 FASTLED_ASSERT(it !=
mTree.end(),
"MapRedBlackTree::at: key not found");
802 const Value&
at(
const Key& key)
const {
804 FASTLED_ASSERT(it !=
mTree.end(),
"MapRedBlackTree::at: key not found");
812 return mTree.insert(value);
819 template<
typename... Args>
879 return mTree.value_comp().comp_;
886 auto it1 =
mTree.begin();
891 if (it1->first != it2->first || it1->second != it2->second) {
902 return !(*
this == other);
907template <
typename Key,
typename Compare = less<Key>,
typename Allocator = allocator_slab<
char>>
926 using iterator =
typename TreeType::const_iterator;
930 SetRedBlackTree(
const Compare& comp = Compare(),
const Allocator& alloc = Allocator())
931 :
mTree(comp, alloc) {}
961 template<
typename... Args>
972 return mTree.erase(key);
981 return mTree.count(key);
985 return mTree.find(key);
989 return mTree.contains(key);
993 return mTree.equal_range(key);
997 return mTree.lower_bound(key);
1001 return mTree.upper_bound(key);
1006 return mTree.value_comp();
const_iterator upper_bound(const Key &key) const
MapRedBlackTree(const MapRedBlackTree &other)=default
const value_type * const_pointer
ptrdiff_t difference_type
MapRedBlackTree & operator=(const MapRedBlackTree &other)=default
const_iterator begin() const
const_iterator cbegin() const
const Value & at(const Key &key) const
bool operator!=(const MapRedBlackTree &other) const
typename TreeType::iterator iterator
RedBlackTree< value_type, PairCompare, fl::allocator_slab< char > > TreeType
iterator erase(const_iterator pos)
const_iterator end() const
Value & operator[](const Key &key)
iterator find(const Key &key)
fl::pair< iterator, iterator > equal_range(const Key &key)
key_compare key_comp() const
typename TreeType::const_iterator const_iterator
fl::pair< iterator, bool > emplace(Args &&... args)
const_iterator lower_bound(const Key &key) const
fl::pair< Key, T > value_type
iterator lower_bound(const Key &key)
MapRedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
bool contains(const Key &key) const
fl::size erase(const Key &key)
bool operator==(const MapRedBlackTree &other) const
void swap(MapRedBlackTree &other)
fl::pair< const_iterator, const_iterator > equal_range(const Key &key) const
fl::pair< iterator, bool > insert(value_type &&value)
const_iterator find(const Key &key) const
fl::pair< iterator, bool > insert(const value_type &value)
fl::size max_size() const
Value & at(const Key &key)
~MapRedBlackTree()=default
const_iterator cend() const
iterator upper_bound(const Key &key)
fl::size count(const Key &key) const
fl::allocator_slab< char > allocator_type
const value_type & const_reference
const Node * predecessor(const Node *x) const
const_iterator & operator--()
friend class RedBlackTree
const value_type & operator*() const
bool operator==(const const_iterator &other) const
const RedBlackTree * mTree
const value_type * operator->() const
const_iterator operator++(int)
const_iterator & operator++()
const_iterator operator--(int)
const Node * successor(const Node *x) const
const_iterator(const Node *n, const RedBlackTree *t)
const_iterator(const iterator &it)
bool operator!=(const const_iterator &other) const
Node * predecessor(Node *x) const
friend class RedBlackTree
Node * successor(Node *x) const
bool operator==(const iterator &other) const
value_type & operator*() const
value_type * operator->() const
const RedBlackTree * mTree
iterator(Node *n, const RedBlackTree *t)
friend class const_iterator
bool operator!=(const iterator &other) const
fl::size erase(const value_type &value)
iterator upper_bound(const value_type &value)
RedBlackTree & operator=(const RedBlackTree &other)
RedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
fl::pair< iterator, iterator > equal_range(const value_type &value)
Node * findNode(const value_type &value) const
fl::pair< iterator, bool > emplace(Args &&... args)
const_iterator upper_bound(const value_type &value) const
compare_type value_comp() const
void deleteFixup(Node *x, Node *xParent)
bool operator!=(const RedBlackTree &other) const
void destroyTree(Node *node)
Node * maximum(Node *x) const
RedBlackTree(const RedBlackTree &other)
iterator erase(const_iterator pos)
void swap(RedBlackTree &other)
fl::size count(const value_type &value) const
fl::size max_size() const
const_iterator end() const
Node * lowerBoundNode(const value_type &value) const
bool operator==(const RedBlackTree &other) const
void insertFixup(Node *z)
const value_type & const_reference
const_iterator begin() const
void rotateRight(Node *x)
fl::pair< iterator, bool > insertImpl(U &&value)
iterator find(const value_type &value)
bool contains(const value_type &value) const
const_iterator cbegin() const
iterator lower_bound(const value_type &value)
Node * copyTree(Node *node, Node *parent=nullptr)
const_iterator find(const value_type &value) const
Node * upperBoundNode(const value_type &value) const
typename Allocator::template rebind< Node >::other NodeAllocator
Node * minimum(Node *x) const
void transplant(Node *u, Node *v)
const_iterator cend() const
const_iterator lower_bound(const value_type &value) const
fl::pair< iterator, bool > insert(const value_type &value)
ptrdiff_t difference_type
const value_type * const_pointer
fl::pair< const_iterator, const_iterator > equal_range(const value_type &value) const
fl::pair< iterator, bool > insert(value_type &&value)
fl::size erase(const Key &key)
const value_type * pointer
const_iterator cbegin() const
bool contains(const Key &key) const
void swap(SetRedBlackTree &other)
fl::pair< const_iterator, bool > insert(value_type &&value)
const_iterator lower_bound(const Key &key) const
key_compare key_comp() const
~SetRedBlackTree()=default
fl::pair< const_iterator, const_iterator > equal_range(const Key &key) const
const_iterator begin() const
fl::pair< const_iterator, bool > emplace(Args &&... args)
ptrdiff_t difference_type
const_iterator erase(const_iterator pos)
fl::pair< const_iterator, bool > insert(const value_type &value)
const value_type & reference
typename TreeType::const_iterator iterator
const_iterator upper_bound(const Key &key) const
SetRedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
RedBlackTree< Key, Compare, Allocator > TreeType
typename TreeType::const_iterator const_iterator
bool operator!=(const SetRedBlackTree &other) const
const_iterator find(const Key &key) const
const value_type * const_pointer
fl::size max_size() const
SetRedBlackTree(const SetRedBlackTree &other)=default
fl::size count(const Key &key) const
const_iterator end() const
bool operator==(const SetRedBlackTree &other) const
const value_type & const_reference
const_iterator cend() const
SetRedBlackTree & operator=(const SetRedBlackTree &other)=default
Result type for promise operations.
Implements the FastLED namespace macros.
constexpr remove_reference< T >::type && move(T &&t) noexcept
void swap(array< T, N > &lhs, array< T, N > &rhs) noexcept(noexcept(lhs.swap(rhs)))
__PTRDIFF_TYPE__ ptrdiff_t
constexpr T && forward(typename remove_reference< T >::type &t) noexcept
PairCompare(const Compare &comp=Compare())
bool operator()(const value_type &a, const value_type &b) const
Node(const value_type &val, Color c=RED, Node *p=nullptr)
Node(Color c, Node *p, Args &&... args)