23template <
typename T,
typename Compare = less<T>,
typename Allocator = allocator_slab<
char>>
54 template<
typename... Args>
59 using NodeAllocator =
typename Allocator::template rebind<RBNode>::other;
70 if (
y->left !=
nullptr) {
73 y->parent =
x->parent;
74 if (
x->parent ==
nullptr) {
76 }
else if (
x ==
x->parent->left) {
88 if (
y->right !=
nullptr) {
91 y->parent =
x->parent;
92 if (
x->parent ==
nullptr) {
94 }
else if (
x ==
x->parent->right) {
104 while (
z->parent !=
nullptr &&
z->parent->parent !=
nullptr &&
z->parent->color ==
Color::kRed) {
105 if (
z->parent ==
z->parent->parent->left) {
106 RBNode*
y =
z->parent->parent->right;
111 z =
z->parent->parent;
113 if (
z ==
z->parent->right) {
122 RBNode*
y =
z->parent->parent->left;
127 z =
z->parent->parent;
129 if (
z ==
z->parent->left) {
143 if (u->parent ==
nullptr) {
145 }
else if (u == u->parent->
left) {
148 u->parent->
right = v;
151 v->parent = u->parent;
156 while (
x->left !=
nullptr) {
163 while (
x->right !=
nullptr) {
172 if (
x == (xParent ? xParent->left :
nullptr)) {
173 RBNode* w = xParent ? xParent->right :
nullptr;
177 w = xParent ? xParent->right :
nullptr;
181 if (wLeftBlack && wRightBlack) {
184 xParent = xParent ? xParent->parent :
nullptr;
189 w = xParent ? xParent->right :
nullptr;
198 RBNode* w = xParent ? xParent->left :
nullptr;
202 w = xParent ? xParent->left :
nullptr;
206 if (wRightBlack && wLeftBlack) {
209 xParent = xParent ? xParent->parent :
nullptr;
214 w = xParent ? xParent->left :
nullptr;
228 RBNode* current =
mRoot;
229 while (current !=
nullptr) {
231 current = current->left;
233 current = current->right;
242 if (node !=
nullptr) {
246 mAlloc.deallocate(node, 1);
250 RBNode*
copyTree(RBNode* node, RBNode* parent =
nullptr) {
251 if (node ==
nullptr)
return nullptr;
253 RBNode* newNode =
mAlloc.allocate(1);
254 if (newNode ==
nullptr) {
258 mAlloc.construct(newNode, node->color, parent, node->data);
259 newNode->left =
copyTree(node->left, newNode);
260 newNode->right =
copyTree(node->right, newNode);
265 template <
typename U>
267 RBNode* parent =
nullptr;
268 RBNode* current =
mRoot;
270 while (current !=
nullptr) {
273 current = current->left;
275 current = current->right;
281 RBNode* newNode =
mAlloc.allocate(1);
282 if (newNode ==
nullptr) {
288 if (parent ==
nullptr) {
290 }
else if (
mComp(newNode->data, parent->data)) {
291 parent->left = newNode;
293 parent->right = newNode;
304 RBNode* current =
mRoot;
306 while (current !=
nullptr) {
309 current = current->left;
311 current = current->right;
318 RBNode* current =
mRoot;
320 while (current !=
nullptr) {
323 current = current->left;
325 current = current->right;
344 if (
x ==
nullptr)
return nullptr;
345 if (
x->right !=
nullptr) {
346 return mTree->minimum(
x->right);
349 while (
y !=
nullptr &&
x ==
y->right) {
357 if (
x ==
nullptr)
return nullptr;
358 if (
x->left !=
nullptr) {
359 return mTree->maximum(
x->left);
362 while (
y !=
nullptr &&
x ==
y->left) {
374 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
378 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
379 return &(
mNode->data);
427 if (
x ==
nullptr)
return nullptr;
428 if (
x->right !=
nullptr) {
429 return mTree->minimum(
x->right);
432 while (
y !=
nullptr &&
x ==
y->right) {
440 if (
x ==
nullptr)
return nullptr;
441 if (
x->left !=
nullptr) {
442 return mTree->maximum(
x->left);
445 while (
y !=
nullptr &&
x ==
y->left) {
461 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
465 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::iterator: dereferencing end iterator");
466 return &(
mNode->data);
534 if (
x ==
nullptr)
return nullptr;
535 if (
x->right !=
nullptr) {
536 return mTree->minimum(
x->right);
539 while (
y !=
nullptr &&
x ==
y->right) {
547 if (
x ==
nullptr)
return nullptr;
548 if (
x->left !=
nullptr) {
549 return mTree->maximum(
x->left);
552 while (
y !=
nullptr &&
x ==
y->left) {
567 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::reverse_iterator: dereferencing end iterator");
571 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::reverse_iterator: dereferencing end iterator");
572 return &(
mNode->data);
623 if (
x ==
nullptr)
return nullptr;
624 if (
x->right !=
nullptr) {
625 return mTree->minimum(
x->right);
628 while (
y !=
nullptr &&
x ==
y->right) {
636 if (
x ==
nullptr)
return nullptr;
637 if (
x->left !=
nullptr) {
638 return mTree->maximum(
x->left);
641 while (
y !=
nullptr &&
x ==
y->left) {
657 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::const_reverse_iterator: dereferencing end iterator");
661 FASTLED_ASSERT(
mNode !=
nullptr,
"RedBlackTree::const_reverse_iterator: dereferencing end iterator");
662 return &(
mNode->data);
706 RedBlackTree(
const Compare& comp = Compare(),
const Allocator& alloc = Allocator())
717 if (
this != &other) {
732 other.mRoot =
nullptr;
738 if (
this != &other) {
744 other.mRoot =
nullptr;
756 if (
mRoot ==
nullptr)
return iterator(
nullptr,
this);
761 if (
mRoot ==
nullptr)
return const_iterator(
nullptr,
this);
770 return iterator(
nullptr,
this);
773 const_iterator
end()
const {
774 return const_iterator(
nullptr,
this);
783 if (
mRoot ==
nullptr)
return reverse_iterator(
nullptr,
this);
788 return reverse_iterator(
nullptr,
this);
792 if (
mRoot ==
nullptr)
return const_reverse_iterator(
nullptr,
this);
796 const_reverse_iterator
rend()
const {
797 return const_reverse_iterator(
nullptr,
this);
804 const_reverse_iterator
crend()
const {
828 template<
typename... Args>
835 if (
pos.mNode ==
nullptr)
return end();
837 RBNode* nodeToDelete =
const_cast<RBNode*
>(
pos.mNode);
838 RBNode* successor =
nullptr;
840 if (nodeToDelete->right !=
nullptr) {
841 successor =
minimum(nodeToDelete->right);
843 RBNode* current = nodeToDelete;
844 RBNode* parent = current->parent;
845 while (parent !=
nullptr && current == parent->right) {
847 parent = parent->parent;
852 RBNode*
y = nodeToDelete;
854 RBNode* xParent =
nullptr;
855 Color originalColor =
y->color;
857 if (nodeToDelete->left ==
nullptr) {
858 x = nodeToDelete->right;
859 xParent = nodeToDelete->parent;
860 transplant(nodeToDelete, nodeToDelete->right);
861 }
else if (nodeToDelete->right ==
nullptr) {
862 x = nodeToDelete->left;
863 xParent = nodeToDelete->parent;
867 originalColor =
y->color;
869 if (
y->parent == nodeToDelete) {
871 if (
x)
x->parent =
y;
875 y->right = nodeToDelete->right;
876 y->right->parent =
y;
880 y->left = nodeToDelete->left;
882 y->color = nodeToDelete->color;
885 mAlloc.destroy(nodeToDelete);
886 mAlloc.deallocate(nodeToDelete, 1);
893 return iterator(successor,
this);
898 if (node ==
nullptr)
return 0;
900 erase(const_iterator(node,
this));
918 return node ? iterator(node,
this) :
end();
923 return node ? const_iterator(node,
this) :
end();
944 return n ? iterator(n,
this) :
end();
949 return n ? const_iterator(n,
this) :
end();
954 return n ? iterator(n,
this) :
end();
959 return n ? const_iterator(n,
this) :
end();
976 const_iterator it1 =
begin();
977 const_iterator it2 = other.
begin();
979 while (it1 !=
end() && it2 != other.
end()) {
988 return it1 ==
end() && it2 == other.
end();
992 return !(*
this == other);
997template <
typename Key,
typename Value,
typename Compare = less<Key>,
typename Allocator = allocator_slab<
char>>
1035 return mComp(
x.first,
y.first);
1049 :
mTree(PairCompare(comp), alloc) {}
1064 for (
const auto&
value : ilist) {
1073 template <
typename InputIt>
1075 const Compare& comp = Compare(),
1076 const Allocator& alloc = Allocator())
1077 :
mTree(PairCompare(comp), alloc) {
1079 for (InputIt it = first; it != last; ++it) {
1088 const Compare& comp = Compare(),
1089 const Allocator& alloc = Allocator())
1090 :
mTree(PairCompare(comp), alloc) {
1123 return result.first->second;
1128 FASTLED_ASSERT(it !=
mTree.end(),
"MapRedBlackTree::at: key not found");
1134 FASTLED_ASSERT(it !=
mTree.end(),
"MapRedBlackTree::at: key not found");
1149 template<
typename... Args>
1156 template <
typename InputIt>
1158 for (InputIt it = first; it != last; ++it) {
1165 void insert(fl::initializer_list<value_type> ilist) {
1166 for (
const auto&
value : ilist) {
1189 template<
typename... Args>
1198 template <
typename M>
1201 if (it !=
mTree.end()) {
1211 template <
typename M>
1214 if (it !=
mTree.end()) {
1225 template <
typename M>
1232 template <
typename M>
1250 template <
typename... Args>
1256 if (it !=
mTree.end() && it->first == key) {
1265 template <
typename... Args>
1271 if (it !=
mTree.end() && it->first == key) {
1281 template <
typename... Args>
1288 template <
typename... Args>
1307 if (first == last) {
1310 if (first ==
mTree.cend()) {
1324 while (current != last) {
1325 current =
mTree.erase(current);
1379 return mTree.value_comp().mComp;
1388 return mTree.get_allocator();
1395 auto it1 =
mTree.begin();
1400 if (it1->first != it2->first || it1->second != it2->second) {
1411 return !(*
this == other);
1424 return !(other < *
this);
1429 return other < *
this;
1434 return !(*
this < other);
1439template <
typename Key,
typename Compare = less<Key>,
typename Allocator = allocator_slab<
char>>
1465 :
mTree(comp, alloc) {}
1504 template<
typename... Args>
1515 return mTree.erase(key);
1524 return mTree.count(key);
1528 return mTree.find(key);
1532 return mTree.contains(key);
1536 return mTree.equal_range(key);
1540 return mTree.lower_bound(key);
1544 return mTree.upper_bound(key);
1549 return mTree.value_comp();
bool operator()(const value_type &x, const value_type &y) const
friend class MapRedBlackTree
const_iterator upper_bound(const Key &key) const
MapRedBlackTree(const MapRedBlackTree &other) FL_NOEXCEPT=default
MapRedBlackTree(MapRedBlackTree &&other) FL_NOEXCEPT=default
value_compare value_comp() const
bool operator<=(const MapRedBlackTree &other) const
typename TreeType::const_reverse_iterator const_reverse_iterator
iterator insert(const_iterator hint, value_type &&value)
const value_type * const_pointer
MapRedBlackTree(InputIt first, InputIt last, const Compare &comp=Compare(), const fl::allocator_slab< char > &alloc=fl::allocator_slab< char >())
MapRedBlackTree & operator=(fl::initializer_list< value_type > ilist) FL_NOEXCEPT
ptrdiff_t difference_type
MapRedBlackTree & operator=(MapRedBlackTree &&other) FL_NOEXCEPT=default
const_reverse_iterator crbegin() const
MapRedBlackTree & operator=(const MapRedBlackTree &other) FL_NOEXCEPT=default
fl::pair< iterator, bool > insert_or_assign(const Key &key, M &&obj)
iterator insert_or_assign(const_iterator hint, const Key &key, M &&obj)
void insert(InputIt first, InputIt last)
const_reverse_iterator crend() const
iterator erase(const_iterator first, const_iterator last)
const_iterator begin() const
const_iterator cbegin() const
const T & at(const Key &key) const
bool operator!=(const MapRedBlackTree &other) const
typename TreeType::iterator iterator
fl::pair< iterator, bool > try_emplace(Key &&key, Args &&... args)
RedBlackTree< value_type, PairCompare, Allocator > TreeType
iterator erase(const_iterator pos)
const_iterator end() const
T & operator[](const Key &key)
iterator find(const Key &key)
fl::pair< iterator, iterator > equal_range(const Key &key)
iterator try_emplace(const_iterator hint, const Key &key, Args &&... args)
key_compare key_comp() const
typename TreeType::const_iterator const_iterator
bool operator<(const MapRedBlackTree &other) const
fl::pair< iterator, bool > emplace(Args &&... args)
const_iterator lower_bound(const Key &key) const
reverse_iterator rbegin()
iterator try_emplace(const_iterator hint, Key &&key, Args &&... args)
iterator insert(const_iterator hint, const value_type &value)
const_reverse_iterator rbegin() const
fl::pair< Key, Value > value_type
fl::pair< iterator, bool > try_emplace(const Key &key, Args &&... args)
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
iterator insert_or_assign(const_iterator hint, Key &&key, M &&obj)
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
bool operator>=(const MapRedBlackTree &other) const
bool operator>(const MapRedBlackTree &other) const
void insert(fl::initializer_list< value_type > ilist)
const_iterator cend() const
iterator emplace_hint(const_iterator hint, Args &&... args)
MapRedBlackTree(fl::initializer_list< value_type > init, const Compare &comp=Compare(), const fl::allocator_slab< char > &alloc=fl::allocator_slab< char >())
iterator upper_bound(const Key &key)
fl::size count(const Key &key) const
typename TreeType::reverse_iterator reverse_iterator
const_reverse_iterator rend() const
const value_type & const_reference
~MapRedBlackTree() FL_NOEXCEPT=default
fl::pair< iterator, bool > insert_or_assign(Key &&key, M &&obj)
allocator_type get_allocator() const
const RBNode * predecessor(const RBNode *x) const
const_iterator() FL_NOEXCEPT
friend bool operator==(const iterator &lhs, const const_iterator &rhs)
const RBNode * successor(const RBNode *x) const
const_iterator & operator--()
friend class RedBlackTree
const value_type & operator*() const
bool operator!=(const iterator &other) const
bool operator==(const const_iterator &other) const
const RedBlackTree * mTree
const value_type * operator->() const
fl::bidirectional_iterator_tag iterator_category
const_iterator operator++(int)
const_iterator & operator++()
const_iterator operator--(int)
bool operator==(const iterator &other) const
friend bool operator!=(const iterator &lhs, const const_iterator &rhs)
const_iterator(const iterator &it)
bool operator!=(const const_iterator &other) const
const_iterator(const RBNode *n, const RedBlackTree *t)
friend class RedBlackTree
const RBNode * predecessor(const RBNode *x) const
const_reverse_iterator & operator++()
const_reverse_iterator operator--(int)
bool operator==(const const_reverse_iterator &other) const
const_reverse_iterator & operator--()
const_reverse_iterator(const RBNode *n, const RedBlackTree *t)
const value_type * operator->() const
fl::bidirectional_iterator_tag iterator_category
const_reverse_iterator() FL_NOEXCEPT
const_reverse_iterator operator++(int)
const RBNode * successor(const RBNode *x) const
bool operator!=(const const_reverse_iterator &other) const
const RedBlackTree * mTree
const_reverse_iterator(const reverse_iterator &it)
const value_type & operator*() const
friend class reverse_iterator
friend class RedBlackTree
bool operator==(const iterator &other) const
value_type & operator*() const
value_type * operator->() const
const RedBlackTree * mTree
fl::bidirectional_iterator_tag iterator_category
friend class const_iterator
RBNode * predecessor(RBNode *x) const
RBNode * successor(RBNode *x) const
bool operator!=(const iterator &other) const
iterator(RBNode *n, const RedBlackTree *t)
reverse_iterator() FL_NOEXCEPT
reverse_iterator operator++(int)
friend class RedBlackTree
reverse_iterator(RBNode *n, const RedBlackTree *t)
RBNode * successor(RBNode *x) const
const RedBlackTree * mTree
value_type & operator*() const
value_type * operator->() const
reverse_iterator & operator++()
friend class const_reverse_iterator
bool operator!=(const reverse_iterator &other) const
RBNode * predecessor(RBNode *x) const
bool operator==(const reverse_iterator &other) const
fl::bidirectional_iterator_tag iterator_category
reverse_iterator & operator--()
reverse_iterator operator--(int)
RedBlackTree & operator=(RedBlackTree &&other) FL_NOEXCEPT
fl::size erase(const value_type &value)
iterator upper_bound(const value_type &value)
RBNode * minimum(RBNode *x) const
RedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
fl::pair< iterator, iterator > equal_range(const value_type &value)
fl::pair< iterator, bool > emplace(Args &&... args)
const_iterator upper_bound(const value_type &value) const
compare_type value_comp() const
RBNode * upperBoundNode(const value_type &value) const
bool operator!=(const RedBlackTree &other) const
iterator erase(const_iterator pos)
void swap(RedBlackTree &other)
fl::size count(const value_type &value) const
fl::size max_size() const
void rotateRight(RBNode *x)
const_iterator end() const
reverse_iterator rbegin()
RedBlackTree(RedBlackTree &&other) FL_NOEXCEPT
bool operator==(const RedBlackTree &other) const
allocator_type get_allocator() const
const value_type & const_reference
RedBlackTree & operator=(const RedBlackTree &other) FL_NOEXCEPT
const_iterator begin() const
void transplant(RBNode *u, RBNode *v)
RedBlackTree(const RedBlackTree &other) FL_NOEXCEPT
fl::pair< iterator, bool > insertImpl(U &&value)
RBNode * maximum(RBNode *x) const
void rotateLeft(RBNode *x)
~RedBlackTree() FL_NOEXCEPT
iterator find(const value_type &value)
bool contains(const value_type &value) const
const_reverse_iterator rbegin() const
const_iterator cbegin() const
const_reverse_iterator rend() const
iterator lower_bound(const value_type &value)
void insertFixup(RBNode *z)
const_iterator find(const value_type &value) const
const_iterator cend() const
const_iterator lower_bound(const value_type &value) const
RBNode * copyTree(RBNode *node, RBNode *parent=nullptr)
fl::pair< iterator, bool > insert(const value_type &value)
void destroyTree(RBNode *node)
const_reverse_iterator crend() const
ptrdiff_t difference_type
const value_type * const_pointer
const_reverse_iterator crbegin() const
fl::pair< const_iterator, const_iterator > equal_range(const value_type &value) const
fl::pair< iterator, bool > insert(value_type &&value)
RBNode * lowerBoundNode(const value_type &value) const
typename Allocator::template rebind< RBNode >::other NodeAllocator
RBNode * findNode(const value_type &value) const
void deleteFixup(RBNode *x, RBNode *xParent)
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
fl::pair< const_iterator, const_iterator > equal_range(const Key &key) const
const_iterator begin() const
allocator_type get_allocator() const
fl::pair< const_iterator, bool > emplace(Args &&... args)
ptrdiff_t difference_type
const_iterator erase(const_iterator pos)
const_reverse_iterator rbegin() const
typename TreeType::const_reverse_iterator const_reverse_iterator
fl::pair< const_iterator, bool > insert(const value_type &value)
const value_type & reference
typename TreeType::const_iterator iterator
typename TreeType::const_reverse_iterator reverse_iterator
const_iterator upper_bound(const Key &key) const
SetRedBlackTree(const Compare &comp=Compare(), const Allocator &alloc=Allocator())
RedBlackTree< Key, Compare, Allocator > TreeType
SetRedBlackTree & operator=(const SetRedBlackTree &other) FL_NOEXCEPT=default
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 & operator=(SetRedBlackTree &&other) FL_NOEXCEPT=default
const_reverse_iterator rend() const
fl::size count(const Key &key) const
const_iterator end() const
bool operator==(const SetRedBlackTree &other) const
const value_type & const_reference
SetRedBlackTree(const SetRedBlackTree &other) FL_NOEXCEPT=default
SetRedBlackTree(SetRedBlackTree &&other) FL_NOEXCEPT=default
const_iterator cend() const
~SetRedBlackTree() FL_NOEXCEPT=default
constexpr T && forward(typename remove_reference< T >::type &t) FL_NOEXCEPT
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
void swap(T &a, T &b) FL_NOEXCEPT
constexpr int type_rank< T >::value
void init(Context &ctx, int w, int h)
bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) FL_NOEXCEPT
expected< T, E > result
Alias for expected (Rust-style naming)
constexpr T && forward(typename remove_reference< T >::type &t) FL_NOEXCEPT
Base definition for an LED controller.
PairCompare(const Compare &comp=Compare())
bool operator()(const value_type &a, const value_type &b) const
RBNode(const value_type &val, Color c=Color::kRed, RBNode *p=nullptr)
RBNode(Color c, RBNode *p, Args &&... args)