1#ifndef NEFORCE_CORE_CONTAINER_RB_TREE_HPP__
2#define NEFORCE_CORE_CONTAINER_RB_TREE_HPP__
20NEFORCE_BEGIN_NAMESPACE__
104 if (root ==
nullptr) {
107 while (root->left_ !=
nullptr) {
119 if (root ==
nullptr) {
122 while (root->right_ !=
nullptr) {
140 if (y->
left_ !=
nullptr) {
148 }
else if (axis == axis->parent_->left_) {
149 axis->parent_->left_ = y;
151 axis->parent_->right_ = y;
168 if (y->
right_ !=
nullptr) {
175 }
else if (axis == axis->parent_->right_) {
176 axis->parent_->right_ = y;
178 axis->parent_->left_ = y;
196 while (insert != root && insert->parent_->color_ ==
RB_TREE_RED) {
197 if (insert->parent_ == insert->parent_->parent_->left_) {
204 insert = insert->parent_->parent_;
206 if (insert == insert->parent_->right_) {
207 insert = insert->parent_;
220 insert = insert->parent_->parent_;
222 if (insert == insert->parent_->left_) {
223 insert = insert->parent_;
253 if (y->
left_ ==
nullptr) {
256 if (y->
right_ ==
nullptr) {
260 while (y->
left_ !=
nullptr) {
268 erase->left_->parent_ = y;
271 if (y !=
erase->right_) {
279 erase->right_->parent_ = y;
287 erase->parent_->left_ = y;
289 erase->parent_->right_ = y;
305 erase->parent_->left_ = x;
307 erase->parent_->right_ = x;
311 if (leftmost ==
erase) {
312 if (
erase->right_ ==
nullptr) {
313 leftmost =
erase->parent_;
319 if (rightmost ==
erase) {
320 if (
erase->left_ ==
nullptr) {
321 rightmost =
erase->parent_;
330 if (x == x_parent->
left_) {
332 NEFORCE_DEBUG_VERIFY(w !=
nullptr,
"RB-tree structure corrupted: right sibling is null");
353 if (w->
left_ !=
nullptr) {
362 if (w->
right_ !=
nullptr) {
370 NEFORCE_DEBUG_VERIFY(w !=
nullptr,
"RB-tree structure corrupted: left sibling is null");
391 if (w->
right_ !=
nullptr) {
401 if (w->
left_ !=
nullptr) {
457 if (
node_->right_ !=
nullptr) {
459 while (
node_->left_ !=
nullptr) {
468 if (
node_->right_ != y) {
480 }
else if (
node_->left_ !=
nullptr) {
482 while (y->
right_ !=
nullptr) {
509template <
bool IsConst,
typename RbTree>
518 typename container_type::reference>;
520 typename container_type::pointer>;
525 using link_type = node_type*;
529 template <
typename,
typename,
typename,
typename,
typename>
530 friend class rb_tree;
533 rb_tree_iterator() noexcept = default;
534 ~rb_tree_iterator() = default;
536 rb_tree_iterator(const rb_tree_iterator&) noexcept = default;
537 rb_tree_iterator& operator=(const rb_tree_iterator&) noexcept = default;
538 rb_tree_iterator(rb_tree_iterator&&) noexcept = default;
539 rb_tree_iterator& operator=(rb_tree_iterator&&) noexcept = default;
556 NEFORCE_DEBUG_VERIFY(
node_ && container_,
"Attempting to dereference on a null pointer");
557 link_type link = link_type(
node_);
558 NEFORCE_DEBUG_VERIFY(
node_ != container_->header_ &&
node_->parent_ !=
nullptr,
559 "Attempting to dereference out of boundary");
567 NEFORCE_DEBUG_VERIFY(
node_ && container_,
"Attempting to increment a null pointer");
568 NEFORCE_DEBUG_VERIFY(link_type(
node_) != container_->header_,
"Attempting to increment out of boundary");
576 NEFORCE_DEBUG_VERIFY(
node_ && container_,
"Attempting to decrement a null pointer");
577 NEFORCE_DEBUG_VERIFY(!container_->empty() ||
node_ != container_->header_,
578 "Attempting to decrement on empty container");
587 NEFORCE_NODISCARD
bool equal_to(
const rb_tree_iterator& rhs)
const noexcept {
588 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_,
"Attempting to equal to a different container");
589 return node_ == rhs.node_;
617template <
typename Key,
typename Value,
typename KeyOfValue,
typename Compare,
644 using base_ptr = base_node*;
645 using link_type = link_node*;
647 link_type header_ =
nullptr;
648 Compare key_compare_{};
649 KeyOfValue extracter_{};
650 compressed_pair<allocator_type, size_t> size_pair_{default_construct_tag{}, 0};
652 template <
bool,
typename>
653 friend struct rb_tree_iterator;
660 bool released_ =
false;
663 node_guard(
rb_tree* t, link_type n) noexcept :
669 tree_->destroy_node(node_);
673 link_type release() noexcept {
683 link_type& root() const noexcept {
return reinterpret_cast<link_type&
>(header_->parent_); }
689 link_type& leftmost() const noexcept {
return reinterpret_cast<link_type&
>(header_->left_); }
695 link_type& rightmost() const noexcept {
return reinterpret_cast<link_type&
>(header_->right_); }
702 static link_type& left(link_type ptr)
noexcept {
return reinterpret_cast<link_type&
>(ptr->left_); }
709 static link_type& right(link_type ptr)
noexcept {
return reinterpret_cast<link_type&
>(ptr->right_); }
716 static link_type& parent(link_type ptr)
noexcept {
return reinterpret_cast<link_type&
>(ptr->parent_); }
723 static const Key& key(link_type ptr)
noexcept {
return KeyOfValue()(ptr->data); }
730 static const Key& key(base_ptr ptr)
noexcept {
return rb_tree::key(
reinterpret_cast<link_type
>(ptr)); }
737 static link_type minimum(link_type ptr)
noexcept {
return static_cast<link_type
>(
base_node::minimum(ptr)); }
744 static link_type maximum(link_type ptr)
noexcept {
return static_cast<link_type
>(
base_node::maximum(ptr)); }
752 template <
typename... Args>
753 link_type create_node(Args&&... args) {
754 link_type tmp = size_pair_.get_base().allocate();
758 rb_tree::destroy_node(tmp);
769 link_type copy_node(link_type ptr) {
770 link_type tmp = rb_tree::create_node(ptr->data);
771 tmp->color_ = ptr->color_;
772 tmp->left_ =
nullptr;
773 tmp->right_ =
nullptr;
782 if (ptr ==
nullptr) {
786 size_pair_.get_base().deallocate(ptr);
796 iterator insert_into(base_ptr child, base_ptr parent, link_type ptr) {
797 auto x =
static_cast<link_type
>(child);
798 auto y =
static_cast<link_type
>(parent);
799 if (y == header_ || x !=
nullptr || key_compare_(rb_tree::key(ptr), rb_tree::key(y))) {
800 rb_tree::left(y) = ptr;
805 }
else if (y == leftmost()) {
809 rb_tree::right(y) = ptr;
810 if (y == rightmost()) {
814 rb_tree::parent(ptr) = y;
815 rb_tree::left(ptr) =
nullptr;
816 rb_tree::right(ptr) =
nullptr;
828 link_type copy_under(link_type src_root, link_type parent) {
829 link_type top = rb_tree::copy_node(src_root);
830 top->parent_ = parent;
832 if (src_root->right_ !=
nullptr) {
833 top->right_ = rb_tree::copy_under(rb_tree::right(src_root), top);
836 src_root = rb_tree::left(src_root);
837 while (src_root !=
nullptr) {
838 link_type y = rb_tree::copy_node(src_root);
841 if (src_root->right_ !=
nullptr) {
842 y->right_ = rb_tree::copy_under(rb_tree::right(src_root), y);
845 src_root = rb_tree::left(src_root);
848 rb_tree::erase_under(top);
859 if (root ==
nullptr) {
862 rb_tree::erase_under(rb_tree::right(root));
863 rb_tree::erase_under(rb_tree::left(root));
864 rb_tree::destroy_node(root);
871 header_ = size_pair_.get_base().allocate(1);
874 leftmost() = header_;
875 rightmost() = header_;
882 void copy_from(
const rb_tree& other) {
883 if (other.root() ==
nullptr) {
885 leftmost() = header_;
886 rightmost() = header_;
889 root() = rb_tree::copy_under(other.root(), header_);
891 size_pair_.get_base().deallocate(header_);
895 leftmost() = rb_tree::minimum(root());
896 rightmost() = rb_tree::maximum(root());
898 size_pair_.value = other.size_pair_.
value;
906 pair<iterator, bool> insert_unique(link_type node) {
907 link_type y = header_;
908 link_type x = root();
910 while (x !=
nullptr) {
912 comp = key_compare_(rb_tree::key(node), rb_tree::key(x));
913 x = comp ? rb_tree::left(x) :
rb_tree::right(x);
919 return pair<iterator, bool>(rb_tree::insert_into(x, y, node),
true);
924 if (key_compare_(rb_tree::key(link_type(j.node_)), rb_tree::key(node))) {
925 return pair<iterator, bool>(rb_tree::insert_into(x, y, node),
true);
927 rb_tree::destroy_node(node);
928 return pair<iterator, bool>(j,
false);
936 iterator insert_equal(link_type node) {
937 link_type y = header_;
938 link_type x = root();
939 while (x !=
nullptr) {
941 x = key_compare_(rb_tree::key(node), rb_tree::key(x)) ? rb_tree::left(x) :
rb_tree::right(x);
943 return rb_tree::insert_into(x, y, node);
966 key_compare_(other.key_compare_),
967 extracter_(other.extracter_),
968 size_pair_(other.size_pair_) {
970 rb_tree::copy_from(other);
994 header_(_NEFORCE
move(other.header_)),
995 key_compare_(_NEFORCE
move(other.key_compare_)),
996 extracter_(_NEFORCE
move(other.extracter_)),
997 size_pair_(_NEFORCE
move(other.size_pair_)) {
998 other.header_ =
nullptr;
999 other.size_pair_.
value = 0;
1008 if (_NEFORCE
addressof(other) ==
this) {
1022 size_pair_.get_base().deallocate(header_);
1114 NEFORCE_NODISCARD
bool empty() const noexcept {
return size_pair_.value == 0; }
1121 return key_compare_;
1130 template <
typename... Args>
1132 const link_type tmp = rb_tree::create_node(_NEFORCE
forward<Args>(args)...);
1133 return rb_tree::insert_unique(tmp);
1157 template <
typename... Args>
1159 link_type tmp = rb_tree::create_node(_NEFORCE
forward<Args>(args)...);
1160 node_guard guard(
this, tmp);
1163 if (
size() > 0 && key_compare_(rb_tree::key(tmp), rb_tree::key(position.
node_))) {
1165 return rb_tree::insert_into(position.
node_, position.
node_, tmp);
1168 return rb_tree::insert_unique(tmp).first;
1171 if (position.
node_ == header_) {
1172 if (key_compare_(rb_tree::key(rightmost()), rb_tree::key(tmp))) {
1174 return rb_tree::insert_into(
nullptr, rightmost(), tmp);
1177 return rb_tree::insert_unique(tmp).first;
1183 if (key_compare_(rb_tree::key(before.
node_), rb_tree::key(tmp)) &&
1184 key_compare_(rb_tree::key(tmp), rb_tree::key(position.
node_))) {
1185 if (rb_tree::right(link_type(before.
node_)) ==
nullptr) {
1187 return rb_tree::insert_into(
nullptr, before.
node_, tmp);
1189 if (rb_tree::left(link_type(position.
node_)) ==
nullptr) {
1191 return rb_tree::insert_into(position.
node_, position.
node_, tmp);
1196 return rb_tree::insert_unique(tmp).first;
1225 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
1227 for (; first != last; ++first) {
1228 rb_tree::insert_unique(*first);
1238 template <
typename... Args>
1240 const link_type tmp = rb_tree::create_node(_NEFORCE
forward<Args>(args)...);
1241 return rb_tree::insert_equal(tmp);
1265 template <
typename... Args>
1267 link_type tmp = rb_tree::create_node(_NEFORCE
forward<Args>(args)...);
1268 node_guard guard(
this, tmp);
1271 if (
size() > 0 && key_compare_(rb_tree::key(tmp), rb_tree::key(position.
node_))) {
1273 return rb_tree::insert_into(position.
node_, position.
node_, tmp);
1276 return rb_tree::insert_equal(tmp);
1279 if (position.
node_ == header_) {
1280 if (!key_compare_(rb_tree::key(tmp), rb_tree::key(rightmost()))) {
1282 return rb_tree::insert_into(
nullptr, rightmost(), tmp);
1285 return rb_tree::insert_equal(tmp);
1291 if (!key_compare_(rb_tree::key(tmp), rb_tree::key(before.
node_)) &&
1292 !key_compare_(rb_tree::key(position.
node_), rb_tree::key(tmp))) {
1293 if (rb_tree::right(link_type(before.
node_)) ==
nullptr) {
1295 return rb_tree::insert_into(
nullptr, before.
node_, tmp);
1298 return rb_tree::insert_into(position.
node_, position.
node_, tmp);
1302 return rb_tree::insert_equal(tmp);
1331 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
1333 for (; first != last; ++first) {
1334 rb_tree::insert_equal(*first);
1355 auto y =
reinterpret_cast<link_type
>(
1357 rb_tree::destroy_node(y);
1367 if (first ==
begin() && last ==
end()) {
1370 while (first != last) {
1380 if (header_ ==
nullptr) {
1383 if (size_pair_.value == 0) {
1386 rb_tree::erase_under(root());
1387 leftmost() = header_;
1389 rightmost() = header_;
1390 size_pair_.value = 0;
1399 link_type y = header_;
1400 link_type x = root();
1402 while (x !=
nullptr) {
1403 if (!key_compare_(rb_tree::key(x), key)) {
1405 x = rb_tree::left(x);
1407 x = rb_tree::right(x);
1415 return key_compare_(key, rb_tree::key(y)) ?
end() : j;
1424 link_type y = header_;
1425 link_type x = root();
1427 while (x !=
nullptr) {
1428 if (!key_compare_(rb_tree::key(x), key)) {
1430 x = rb_tree::left(x);
1432 x = rb_tree::right(x);
1440 return key_compare_(key, rb_tree::key(y)) ?
cend() : j;
1460 link_type y = header_;
1461 link_type x = root();
1463 while (x !=
nullptr) {
1464 if (!key_compare_(rb_tree::key(x), key)) {
1466 x = rb_tree::left(x);
1468 x = rb_tree::right(x);
1481 link_type y = header_;
1482 link_type x = root();
1484 while (x !=
nullptr) {
1485 if (!key_compare_(rb_tree::key(x), key)) {
1487 x = rb_tree::left(x);
1489 x = rb_tree::right(x);
1502 link_type y = header_;
1503 link_type x = root();
1505 while (x !=
nullptr) {
1506 if (key_compare_(key, rb_tree::key(x))) {
1508 x = rb_tree::left(x);
1510 x = rb_tree::right(x);
1523 link_type y = header_;
1524 link_type x = root();
1526 while (x !=
nullptr) {
1527 if (key_compare_(key, rb_tree::key(x))) {
1529 x = rb_tree::left(x);
1531 x = rb_tree::right(x);
1562 _NEFORCE
swap(header_, other.header_);
1563 _NEFORCE
swap(size_pair_, other.size_pair_);
1564 _NEFORCE
swap(key_compare_, other.key_compare_);
1565 _NEFORCE
swap(extracter_, other.extracter_);
1591NEFORCE_END_NAMESPACE__
const_iterator lower_bound(const key_type &key) const
获取第一个不小于指定键的元素位置(常量版本)
void erase(iterator first, iterator last) noexcept(is_nothrow_destructible_v< link_node >)
删除指定范围内的元素
reverse_iterator rend() noexcept
获取反向结束迭代器
iterator emplace_equal(Args &&... args)
在树中构造元素(允许重复键版本)
iterator upper_bound(const key_type &key)
获取第一个大于指定键的元素位置
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
iterator insert_equal(value_type &&value)
移动插入元素(允许重复键版本)
iterator insert_unique(iterator position, const value_type &value)
在提示位置附近插入元素(唯一键版本)
rb_tree(rb_tree &&other) noexcept(is_nothrow_move_constructible_v< Compare > &&is_nothrow_move_constructible_v< KeyOfValue > &&is_nothrow_move_constructible_v< allocator_type >)
移动构造函数
const_iterator begin() const noexcept
获取常量起始迭代器
const pair< const Key, T > & const_reference
iterator insert_equal(iterator position, const value_type &value)
在提示位置附近插入元素(允许重复键版本)
iterator insert_equal(iterator position, value_type &&value)
在提示位置附近移动插入元素(允许重复键版本)
_NEFORCE reverse_iterator< iterator > reverse_iterator
void insert_equal(Iterator first, Iterator last)
范围插入元素(允许重复键版本)
size_type max_size() const noexcept
获取最大可能大小
iterator emplace_unique_hint(iterator position, Args &&... args)
在提示位置附近构造元素(唯一键版本)
const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
bool equal_to(const rb_tree &rhs) const noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin())))
相等比较操作符
iterator end() noexcept
获取结束迭代器
pair< const_iterator, const_iterator > equal_range(const key_type &key) const
获取等于指定键的元素范围(常量版本)
pair< const Key, T > value_type
const_iterator upper_bound(const key_type &key) const
获取第一个大于指定键的元素位置(常量版本)
rb_tree_iterator< true, rb_tree > const_iterator
reverse_iterator rbegin() noexcept
获取反向起始迭代器
ptrdiff_t difference_type
size_type size() const noexcept
获取元素数量
pair< iterator, bool > insert_unique(const value_type &value)
插入元素(唯一键版本)
iterator insert_equal(const value_type &value)
插入元素(允许重复键版本)
pair< iterator, bool > emplace_unique(Args &&... args)
在树中构造元素(唯一键版本)
size_type erase(const key_type &key) noexcept(is_nothrow_destructible_v< link_node >)
删除所有具有指定键的元素
const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
void erase(iterator position) noexcept(is_nothrow_destructible_v< link_node >)
删除指定位置的元素
const_iterator find(const key_type &key) const
查找具有指定键的元素(常量版本)
pair< iterator, iterator > equal_range(const key_type &key)
获取等于指定键的元素范围
iterator lower_bound(const key_type &key)
获取第一个不小于指定键的元素位置
iterator emplace_equal_hint(iterator position, Args &&... args)
在提示位置附近构造元素(允许重复键版本)
const_iterator end() const noexcept
获取常量结束迭代器
rb_tree & operator=(rb_tree &&other) noexcept(is_nothrow_move_constructible_v< rb_tree >)
移动赋值运算符
void insert_unique(Iterator first, Iterator last)
范围插入元素(唯一键版本)
rb_tree_iterator< false, rb_tree > iterator
void clear() noexcept(is_nothrow_destructible_v< link_node >)
清空树
bool less_than(const rb_tree &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
Compare key_compare() const noexcept(is_nothrow_copy_constructible_v< Compare >)
获取键比较函数对象
rb_tree(const rb_tree &other)
拷贝构造函数
const_iterator cend() const noexcept
获取常量结束迭代器
const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
pair< iterator, bool > insert_unique(value_type &&value)
移动插入元素(唯一键版本)
const pair< const Key, T > * const_pointer
pair< const Key, T > & reference
size_type count(const key_type &key) const
统计具有指定键的元素数量
iterator begin() noexcept
获取起始迭代器
void swap(rb_tree &other) noexcept(is_nothrow_swappable_v< Compare > &&is_nothrow_swappable_v< KeyOfValue > &&is_nothrow_swappable_v< allocator_type >)
交换两个红黑树的内容
iterator find(const key_type &key)
查找具有指定键的元素
pair< const Key, T > * pointer
bool empty() const noexcept
检查是否为空
rb_tree & operator=(const rb_tree &other)
拷贝赋值运算符
const_iterator cbegin() const noexcept
获取常量起始迭代器
iterator insert_unique(iterator position, value_type &&value)
在提示位置附近移动插入元素(唯一键版本)
rb_tree(const Compare &comp)
构造函数,指定比较函数
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr bool is_object_v
is_object的便捷变量模板
constexpr bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(comp(*first1, *first2)) &&noexcept(first1==last1 &&first2 !=last2))
字典序比较两个范围
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
standard_allocator< T > allocator
标准分配器别名
void rb_tree_insert_rebalance(rb_tree_node_base *insert, rb_tree_node_base *&root) noexcept
插入节点后重新平衡红黑树
constexpr bool RB_TREE_RED
红黑树节点颜色常量:红色
rb_tree_node_base * rb_tree_erase_rebalance(rb_tree_node_base *erase, rb_tree_node_base *&root, rb_tree_node_base *&leftmost, rb_tree_node_base *&rightmost) noexcept
删除节点后重新平衡红黑树
void rb_tree_rotate_right(rb_tree_node_base *axis, rb_tree_node_base *&root) noexcept
红黑树右旋转
void rb_tree_rotate_left(rb_tree_node_base *axis, rb_tree_node_base *&root) noexcept
红黑树左旋转
constexpr bool RB_TREE_BLACK
红黑树节点颜色常量:黑色
constexpr size_t erase(Container &cont, const U &value)
从容器中删除所有等于指定值的元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
constexpr bool is_allocator_v
is_allocator的便捷变量模板
constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
constexpr bool is_nothrow_default_constructible_v
is_nothrow_default_constructible的便捷变量模板
constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
void increment() noexcept
递增操作(移动到中序遍历的后继节点)
rb_tree_node_base::base_ptr base_ptr
基类指针类型
void decrement() noexcept
递减操作(移动到中序遍历的前驱节点)
bidirectional_iterator_tag iterator_category
双向迭代器
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
reference dereference() const noexcept
解引用操作
typename container_type::size_type size_type
大小类型
typename container_type::difference_type difference_type
差值类型
RbTree container_type
容器类型
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
constexpr void increment() noexcept
递增操作
constexpr void decrement() noexcept
递减操作
rb_tree_base_iterator::iterator_category iterator_category
迭代器类别(双向)
typename container_type::value_type value_type
值类型
const container_type * container() const noexcept
获取关联容器
pointer base() const noexcept
获取底层指针
bool equal_to(const rb_tree_iterator &rhs) const noexcept
相等比较
static base_ptr maximum(base_ptr root) noexcept
获取子树中的最大节点
static base_ptr minimum(base_ptr root) noexcept
获取子树中的最小节点
color_type color_
节点颜色,默认为红色
rb_tree_node_base * base_ptr
基类指针类型
rb_tree_node() noexcept(is_nothrow_default_constructible_v< T >)
默认构造函数