NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
rb_tree.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_CONTAINER_RB_TREE_HPP__
2#define NEFORCE_CORE_CONTAINER_RB_TREE_HPP__
3
12
20NEFORCE_BEGIN_NAMESPACE__
21
74
76NEFORCE_INLINE17 constexpr bool RB_TREE_RED = false;
77
79NEFORCE_INLINE17 constexpr bool RB_TREE_BLACK = true;
80
81
90 using color_type = bool;
92
94 base_ptr parent_ = nullptr;
95 base_ptr left_ = nullptr;
96 base_ptr right_ = nullptr;
97
103 static base_ptr minimum(base_ptr root) noexcept {
104 while (root->left_ != nullptr) {
105 root = root->left_;
106 }
107 return root;
108 }
109
115 static base_ptr maximum(base_ptr root) noexcept {
116 while (root->right_ != nullptr) {
117 root = root->right_;
118 }
119 return root;
120 }
121};
122
123
131NEFORCE_ALWAYS_INLINE_INLINE void rb_tree_rotate_left(rb_tree_node_base* axis, rb_tree_node_base*& root) noexcept {
132 rb_tree_node_base* y = axis->right_;
133 axis->right_ = y->left_;
134 if (y->left_ != nullptr) {
135 y->left_->parent_ = axis;
136 }
137
138 y->parent_ = axis->parent_;
139
140 if (axis == root) {
141 root = y;
142 } else if (axis == axis->parent_->left_) {
143 axis->parent_->left_ = y;
144 } else {
145 axis->parent_->right_ = y;
146 }
147
148 y->left_ = axis;
149 axis->parent_ = y;
150}
151
159NEFORCE_ALWAYS_INLINE_INLINE void rb_tree_rotate_right(rb_tree_node_base* axis, rb_tree_node_base*& root) noexcept {
160 rb_tree_node_base* y = axis->left_;
161 axis->left_ = y->right_;
162 if (y->right_ != nullptr) {
163 y->right_->parent_ = axis;
164 }
165 y->parent_ = axis->parent_;
166
167 if (axis == root) {
168 root = y;
169 } else if (axis == axis->parent_->right_) {
170 axis->parent_->right_ = y;
171 } else {
172 axis->parent_->left_ = y;
173 }
174
175 y->right_ = axis;
176 axis->parent_ = y;
177}
178
186NEFORCE_ALWAYS_INLINE_INLINE void rb_tree_insert_rebalance(rb_tree_node_base* insert,
187 rb_tree_node_base*& root) noexcept {
188 insert->color_ = RB_TREE_RED;
189
190 while (insert != root && insert->parent_->color_ == RB_TREE_RED) {
191 if (insert->parent_ == insert->parent_->parent_->left_) {
193
194 if (y != nullptr && y->color_ == RB_TREE_RED) {
195 insert->parent_->color_ = RB_TREE_BLACK;
197 insert->parent_->parent_->color_ = RB_TREE_RED;
198 insert = insert->parent_->parent_;
199 } else {
200 if (insert == insert->parent_->right_) {
201 insert = insert->parent_;
202 _NEFORCE rb_tree_rotate_left(insert, root);
203 }
204 insert->parent_->color_ = RB_TREE_BLACK;
205 insert->parent_->parent_->color_ = RB_TREE_RED;
206 _NEFORCE rb_tree_rotate_right(insert->parent_->parent_, root);
207 }
208 } else {
209 rb_tree_node_base* y = insert->parent_->parent_->left_;
210 if (y != nullptr && y->color_ == RB_TREE_RED) {
211 insert->parent_->color_ = RB_TREE_BLACK;
213 insert->parent_->parent_->color_ = RB_TREE_RED;
214 insert = insert->parent_->parent_;
215 } else {
216 if (insert == insert->parent_->left_) {
217 insert = insert->parent_;
218 _NEFORCE rb_tree_rotate_right(insert, root);
219 }
220 insert->parent_->color_ = RB_TREE_BLACK;
221 insert->parent_->parent_->color_ = RB_TREE_RED;
222 _NEFORCE rb_tree_rotate_left(insert->parent_->parent_, root);
223 }
224 }
225 }
226 root->color_ = RB_TREE_BLACK;
227}
228
240 rb_tree_node_base*& root,
241 rb_tree_node_base*& leftmost,
242 rb_tree_node_base*& rightmost) noexcept {
245 rb_tree_node_base* x_parent;
246
247 if (y->left_ == nullptr) {
248 x = y->right_;
249 } else {
250 if (y->right_ == nullptr) {
251 x = y->left_;
252 } else {
253 y = y->right_;
254 while (y->left_ != nullptr) {
255 y = y->left_;
256 }
257 x = y->right_;
258 }
259 }
260
261 if (y != erase) {
262 erase->left_->parent_ = y;
263 y->left_ = erase->left_;
264
265 if (y != erase->right_) {
266 x_parent = y->parent_;
267 if (x != nullptr) {
268 x->parent_ = y->parent_;
269 }
270
271 y->parent_->left_ = x;
272 y->right_ = erase->right_;
273 erase->right_->parent_ = y;
274 } else {
275 x_parent = y;
276 }
277
278 if (root == erase) {
279 root = y;
280 } else if (erase->parent_->left_ == erase) {
281 erase->parent_->left_ = y;
282 } else {
283 erase->parent_->right_ = y;
284 }
285
286 y->parent_ = erase->parent_;
287 _NEFORCE swap(y->color_, erase->color_);
288 y = erase;
289 } else {
290 x_parent = y->parent_;
291 if (x != nullptr) {
292 x->parent_ = y->parent_;
293 }
294
295 if (root == erase) {
296 root = x;
297 } else {
298 if (erase->parent_->left_ == erase) {
299 erase->parent_->left_ = x;
300 } else {
301 erase->parent_->right_ = x;
302 }
303 }
304
305 if (leftmost == erase) {
306 if (erase->right_ == nullptr) {
307 leftmost = erase->parent_;
308 } else {
309 leftmost = rb_tree_node_base::minimum(x);
310 }
311 }
312
313 if (rightmost == erase) {
314 if (erase->left_ == nullptr) {
315 rightmost = erase->parent_;
316 } else {
317 rightmost = rb_tree_node_base::maximum(x);
318 }
319 }
320 }
321
322 if (y->color_ != RB_TREE_RED) {
323 while (x != root && (x == nullptr || x->color_ == RB_TREE_BLACK)) {
324 if (x == x_parent->left_) {
325 rb_tree_node_base* w = x_parent->right_;
326 NEFORCE_DEBUG_VERIFY(w != nullptr, "RB-tree structure corrupted: right sibling is null");
327 if (w == nullptr) {
328 x = x_parent;
329 x_parent = x_parent->parent_;
330 continue;
331 }
332
333 if (w->color_ == RB_TREE_RED) {
335 x_parent->color_ = RB_TREE_RED;
336 _NEFORCE rb_tree_rotate_left(x_parent, root);
337 w = x_parent->right_;
338 }
339
340 if ((w->left_ == nullptr || w->left_->color_ == RB_TREE_BLACK) &&
341 (w->right_ == nullptr || w->right_->color_ == RB_TREE_BLACK)) {
342 w->color_ = RB_TREE_RED;
343 x = x_parent;
344 x_parent = x_parent->parent_;
345 } else {
346 if (w->right_ == nullptr || w->right_->color_ == RB_TREE_BLACK) {
347 if (w->left_ != nullptr) {
349 }
350 w->color_ = RB_TREE_RED;
351 _NEFORCE rb_tree_rotate_right(w, root);
352 w = x_parent->right_;
353 }
354 w->color_ = x_parent->color_;
355 x_parent->color_ = RB_TREE_BLACK;
356 if (w->right_ != nullptr) {
358 }
359 _NEFORCE rb_tree_rotate_left(x_parent, root);
360 break;
361 }
362 } else {
363 rb_tree_node_base* w = x_parent->left_;
364 NEFORCE_DEBUG_VERIFY(w != nullptr, "RB-tree structure corrupted: left sibling is null");
365 if (w == nullptr) {
366 x = x_parent;
367 x_parent = x_parent->parent_;
368 continue;
369 }
370
371 if (w->color_ == RB_TREE_RED) {
373 x_parent->color_ = RB_TREE_RED;
374 _NEFORCE rb_tree_rotate_right(x_parent, root);
375 w = x_parent->left_;
376 }
377
378 if ((w->right_ == nullptr || w->right_->color_ == RB_TREE_BLACK) &&
379 (w->left_ == nullptr || w->left_->color_ == RB_TREE_BLACK)) {
380 w->color_ = RB_TREE_RED;
381 x = x_parent;
382 x_parent = x_parent->parent_;
383 } else {
384 if (w->left_ == nullptr || w->left_->color_ == RB_TREE_BLACK) {
385 if (w->right_ != nullptr) {
387 }
388
389 w->color_ = RB_TREE_RED;
390 _NEFORCE rb_tree_rotate_left(w, root);
391 w = x_parent->left_;
392 }
393 w->color_ = x_parent->color_;
394 x_parent->color_ = RB_TREE_BLACK;
395 if (w->left_ != nullptr) {
397 }
398
399 _NEFORCE rb_tree_rotate_right(x_parent, root);
400 break;
401 }
402 }
403 }
404
405 if (x != nullptr) {
407 }
408 }
409 return y;
410}
411
412
420template <typename T>
430
431
439public:
441
442protected:
444
445 base_ptr node_ = nullptr;
446
450 void increment() noexcept {
451 if (node_->right_ != nullptr) {
452 node_ = node_->right_;
453 while (node_->left_ != nullptr) {
454 node_ = node_->left_;
455 }
456 } else {
457 base_ptr y = node_->parent_;
458 while (node_ == y->right_) {
459 node_ = y;
460 y = y->parent_;
461 }
462 if (node_->right_ != y) {
463 node_ = y;
464 }
465 }
466 }
467
471 void decrement() noexcept {
472 if (node_->color_ == RB_TREE_RED && node_->parent_ != nullptr && node_->parent_->parent_ == node_) {
473 node_ = node_->right_;
474 } else if (node_->left_ != nullptr) {
475 base_ptr y = node_->left_;
476 while (y->right_ != nullptr) {
477 y = y->right_;
478 }
479 node_ = y;
480 } else {
481 base_ptr y = node_->parent_;
482 while (node_ == y->left_) {
483 node_ = y;
484 y = y->parent_;
485 }
486 node_ = y;
487 }
488 }
489};
490
491
500template <bool IsConst, typename RbTree>
501struct rb_tree_iterator : rb_tree_base_iterator, iiterator<rb_tree_iterator<IsConst, RbTree>> {
502public:
503 using container_type = RbTree;
504 using value_type = typename container_type::value_type;
505 using size_type = typename container_type::size_type;
506 using difference_type = typename container_type::difference_type;
508 using reference = conditional_t<IsConst, typename container_type::const_reference,
509 typename container_type::reference>;
510 using pointer = conditional_t<IsConst, typename container_type::const_pointer,
511 typename container_type::pointer>;
512
513private:
514 using base_type = rb_tree_base_iterator;
515 using node_type = rb_tree_node<value_type>;
516 using link_type = node_type*;
517
518 const container_type* container_ = nullptr;
519
520 template <typename, typename, typename, typename, typename>
521 friend class rb_tree;
522
523public:
524 rb_tree_iterator() noexcept = default;
525 ~rb_tree_iterator() = default;
526
527 rb_tree_iterator(const rb_tree_iterator&) noexcept = default;
528 rb_tree_iterator& operator=(const rb_tree_iterator&) noexcept = default;
529 rb_tree_iterator(rb_tree_iterator&&) noexcept = default;
530 rb_tree_iterator& operator=(rb_tree_iterator&&) noexcept = default;
531
537 rb_tree_iterator(node_type* ptr, const container_type* tree) noexcept :
538 container_(tree) {
539 node_ = ptr;
540 }
541
546 NEFORCE_NODISCARD reference dereference() const noexcept {
547 NEFORCE_DEBUG_VERIFY(node_ && container_, "Attempting to dereference on a null pointer");
548 link_type link = link_type(node_);
549 NEFORCE_DEBUG_VERIFY(node_ != container_->header_ && node_->parent_ != nullptr,
550 "Attempting to dereference out of boundary");
551 return link->data;
552 }
553
557 NEFORCE_CONSTEXPR20 void increment() noexcept {
558 NEFORCE_DEBUG_VERIFY(node_ && container_, "Attempting to increment a null pointer");
559 NEFORCE_DEBUG_VERIFY(link_type(node_) != container_->header_, "Attempting to increment out of boundary");
561 }
562
566 NEFORCE_CONSTEXPR20 void decrement() noexcept {
567 NEFORCE_DEBUG_VERIFY(node_ && container_, "Attempting to decrement a null pointer");
568 NEFORCE_DEBUG_VERIFY(node_ != container_->header_, "Attempting to decrement out of boundary");
570 }
571
577 NEFORCE_NODISCARD bool equal(const rb_tree_iterator& rhs) const noexcept {
578 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to equal to a different container");
579 return node_ == rhs.node_;
580 }
581
586 NEFORCE_NODISCARD pointer base() const noexcept { return node_; }
587
592 NEFORCE_NODISCARD const container_type* container() const noexcept { return container_; }
593};
594
595
607template <typename Key, typename Value, typename KeyOfValue, typename Compare,
608 typename Alloc = allocator<rb_tree_node<Value>>>
609class rb_tree : icollector<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>> {
610 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
611 static_assert(is_same_v<rb_tree_node<Value>, typename Alloc::value_type>, "allocator type mismatch.");
612 static_assert(is_object_v<Value>, "list only contains object types.");
613
614public:
615 using key_type = Key;
616 using color_type = bool;
617
618 using value_type = Value;
619 using pointer = Value*;
620 using reference = Value&;
621 using const_pointer = const Value*;
622 using const_reference = const Value&;
625 using iterator = rb_tree_iterator<false, rb_tree>;
626 using const_iterator = rb_tree_iterator<true, rb_tree>;
629 using allocator_type = Alloc;
630
631private:
632 using base_node = rb_tree_node_base;
633 using link_node = rb_tree_node<Value>;
634 using base_ptr = base_node*;
635 using link_type = link_node*;
636
637 link_type header_ = nullptr;
638 Compare key_compare_{};
639 KeyOfValue extracter_{};
640 compressed_pair<allocator_type, size_t> size_pair_{default_construct_tag{}, 0};
641
642 template <bool, typename>
643 friend struct rb_tree_iterator;
644
645private:
646 struct node_guard {
647 private:
648 rb_tree* tree_;
649 link_type node_;
650 bool released_ = false;
651
652 public:
653 node_guard(rb_tree* t, link_type n) noexcept :
654 tree_(t),
655 node_(n) {}
656
657 ~node_guard() {
658 if (!released_) {
659 tree_->destroy_node(node_);
660 }
661 }
662
663 link_type release() noexcept {
664 released_ = true;
665 return node_;
666 }
667 };
668
673 link_type& root() const noexcept { return reinterpret_cast<link_type&>(header_->parent_); }
674
679 link_type& leftmost() const noexcept { return reinterpret_cast<link_type&>(header_->left_); }
680
685 link_type& rightmost() const noexcept { return reinterpret_cast<link_type&>(header_->right_); }
686
692 static link_type& left(link_type ptr) noexcept { return reinterpret_cast<link_type&>(ptr->left_); }
693
699 static link_type& right(link_type ptr) noexcept { return reinterpret_cast<link_type&>(ptr->right_); }
700
706 static link_type& parent(link_type ptr) noexcept { return reinterpret_cast<link_type&>(ptr->parent_); }
707
713 static const Key& key(link_type ptr) noexcept { return KeyOfValue()(ptr->data); }
714
720 static const Key& key(base_ptr ptr) noexcept { return rb_tree::key(reinterpret_cast<link_type>(ptr)); }
721
727 static link_type minimum(link_type ptr) noexcept { return static_cast<link_type>(base_node::minimum(ptr)); }
728
734 static link_type maximum(link_type ptr) noexcept { return static_cast<link_type>(base_node::maximum(ptr)); }
735
742 template <typename... Args>
743 link_type create_node(Args&&... args) {
744 link_type tmp = size_pair_.get_base().allocate();
745 try {
746 _NEFORCE construct(&tmp->data, _NEFORCE forward<Args>(args)...);
747 } catch (...) {
748 rb_tree::destroy_node(tmp);
749 throw;
750 }
751 return tmp;
752 }
753
759 link_type copy_node(link_type ptr) {
760 link_type tmp = rb_tree::create_node(ptr->data);
761 tmp->color_ = ptr->color_;
762 tmp->left_ = nullptr;
763 tmp->right_ = nullptr;
764 return tmp;
765 }
766
771 void destroy_node(link_type ptr) noexcept(is_nothrow_destructible_v<link_node>) {
772 if (ptr == nullptr) {
773 return;
774 }
775 _NEFORCE destroy(&ptr->data);
776 size_pair_.get_base().deallocate(ptr);
777 }
778
786 iterator insert_into(base_ptr child, base_ptr parent, link_type ptr) {
787 auto x = static_cast<link_type>(child);
788 auto y = static_cast<link_type>(parent);
789 if (y == header_ || x != nullptr || key_compare_(rb_tree::key(ptr), rb_tree::key(y))) {
790 rb_tree::left(y) = ptr;
791 if (y == header_) {
792 root() = ptr;
793 leftmost() = ptr;
794 rightmost() = ptr;
795 } else if (y == leftmost()) {
796 leftmost() = ptr;
797 }
798 } else {
799 rb_tree::right(y) = ptr;
800 if (y == rightmost()) {
801 rightmost() = ptr;
802 }
803 }
804 rb_tree::parent(ptr) = y;
805 rb_tree::left(ptr) = nullptr;
806 rb_tree::right(ptr) = nullptr;
807 _NEFORCE rb_tree_insert_rebalance(ptr, header_->parent_);
808 ++size_pair_.value;
809 return iterator(ptr, this);
810 }
811
818 link_type copy_under(link_type src_root, link_type parent) {
819 link_type top = rb_tree::copy_node(src_root);
820 top->parent_ = parent;
821 try {
822 if (src_root->right_ != nullptr) {
823 top->right_ = rb_tree::copy_under(rb_tree::right(src_root), top);
824 }
825 parent = top;
826 src_root = rb_tree::left(src_root);
827 while (src_root != nullptr) {
828 link_type y = rb_tree::copy_node(src_root);
829 parent->left_ = y;
830 y->parent_ = parent;
831 if (src_root->right_ != nullptr) {
832 y->right_ = rb_tree::copy_under(rb_tree::right(src_root), y);
833 }
834 parent = y;
835 src_root = rb_tree::left(src_root);
836 }
837 } catch (...) {
838 rb_tree::erase_under(top);
839 throw;
840 }
841 return top;
842 }
843
848 void erase_under(link_type root) noexcept(is_nothrow_destructible_v<link_node>) {
849 if (root == nullptr) {
850 return;
851 }
852 rb_tree::erase_under(rb_tree::right(root));
853 rb_tree::erase_under(rb_tree::left(root));
854 rb_tree::destroy_node(root);
855 }
856
860 void header_init() {
861 header_ = size_pair_.get_base().allocate(1);
862 header_->color_ = RB_TREE_RED;
863 root() = nullptr;
864 leftmost() = header_;
865 rightmost() = header_;
866 }
867
872 void copy_from(const rb_tree& other) {
873 if (other.root() == nullptr) {
874 root() = nullptr;
875 leftmost() = header_;
876 rightmost() = header_;
877 } else {
878 try {
879 root() = rb_tree::copy_under(other.root(), header_);
880 } catch (...) {
881 size_pair_.get_base().deallocate(header_);
882 header_ = nullptr;
883 throw;
884 }
885 leftmost() = rb_tree::minimum(root());
886 rightmost() = rb_tree::maximum(root());
887 }
888 size_pair_.value = other.size_pair_.value;
889 }
890
896 pair<iterator, bool> insert_unique(link_type node) {
897 link_type y = header_;
898 link_type x = root();
899 bool comp = true;
900 while (x != nullptr) {
901 y = x;
902 comp = key_compare_(rb_tree::key(node), rb_tree::key(x));
903 x = comp ? rb_tree::left(x) : rb_tree::right(x);
904 }
905
906 iterator j(y, this);
907 if (comp) {
908 if (j == begin()) {
909 return pair<iterator, bool>(rb_tree::insert_into(x, y, node), true);
910 }
911 --j;
912 }
913
914 if (key_compare_(rb_tree::key(link_type(j.node_)), rb_tree::key(node))) {
915 return pair<iterator, bool>(rb_tree::insert_into(x, y, node), true);
916 }
917 rb_tree::destroy_node(node);
918 return pair<iterator, bool>(j, false);
919 }
920
926 iterator insert_equal(link_type node) {
927 link_type y = header_;
928 link_type x = root();
929 while (x != nullptr) {
930 y = x;
931 x = key_compare_(rb_tree::key(node), rb_tree::key(x)) ? rb_tree::left(x) : rb_tree::right(x);
932 }
933 return rb_tree::insert_into(x, y, node);
934 }
935
936public:
940 rb_tree() { header_init(); }
941
946 explicit rb_tree(const Compare& comp) :
947 key_compare_(comp) {
948 header_init();
949 }
950
955 rb_tree(const rb_tree& other) :
956 key_compare_(other.key_compare_),
957 extracter_(other.extracter_),
958 size_pair_(other.size_pair_) {
959 header_init();
960 rb_tree::copy_from(other);
961 }
962
968 rb_tree& operator=(const rb_tree& other) {
969 if (_NEFORCE addressof(other) == this) {
970 return *this;
971 }
972 rb_tree tmp(other);
973 rb_tree::swap(tmp);
974 return *this;
975 }
976
984 header_(_NEFORCE move(other.header_)),
985 key_compare_(_NEFORCE move(other.key_compare_)),
986 extracter_(_NEFORCE move(other.extracter_)),
987 size_pair_(_NEFORCE move(other.size_pair_)) {
988 other.header_ = nullptr;
989 other.size_pair_.value = 0;
990 }
991
998 if (_NEFORCE addressof(other) == this) {
999 return *this;
1000 }
1001 rb_tree tmp(_NEFORCE move(other));
1002 rb_tree::swap(tmp);
1003 return *this;
1004 }
1005
1010 clear();
1011 if (header_) {
1012 size_pair_.get_base().deallocate(header_);
1013 }
1014 }
1015
1020 NEFORCE_NODISCARD iterator begin() noexcept { return {leftmost(), this}; }
1021
1026 NEFORCE_NODISCARD iterator end() noexcept { return {header_, this}; }
1027
1032 NEFORCE_NODISCARD const_iterator begin() const noexcept { return cbegin(); }
1033
1038 NEFORCE_NODISCARD const_iterator end() const noexcept { return cend(); }
1039
1044 NEFORCE_NODISCARD const_iterator cbegin() const noexcept { return {leftmost(), this}; }
1045
1050 NEFORCE_NODISCARD const_iterator cend() const noexcept { return {header_, this}; }
1051
1056 NEFORCE_NODISCARD reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
1057
1062 NEFORCE_NODISCARD reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
1063
1068 NEFORCE_NODISCARD const_reverse_iterator rbegin() const noexcept { return crbegin(); }
1069
1074 NEFORCE_NODISCARD const_reverse_iterator rend() const noexcept { return crend(); }
1075
1080 NEFORCE_NODISCARD const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
1081
1086 NEFORCE_NODISCARD const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
1087
1092 NEFORCE_NODISCARD size_type size() const noexcept { return size_pair_.value; }
1093
1098 NEFORCE_NODISCARD size_type max_size() const noexcept { return static_cast<size_type>(-1); }
1099
1104 NEFORCE_NODISCARD bool empty() const noexcept { return size_pair_.value == 0; }
1105
1110 NEFORCE_NODISCARD Compare key_compare() const noexcept(is_nothrow_copy_constructible_v<Compare>) {
1111 return key_compare_;
1112 }
1113
1120 template <typename... Args>
1122 const link_type tmp = rb_tree::create_node(_NEFORCE forward<Args>(args)...);
1123 return rb_tree::insert_unique(tmp);
1124 }
1125
1132
1139
1147 template <typename... Args>
1148 iterator emplace_unique_hint(iterator position, Args&&... args) {
1149 link_type tmp = rb_tree::create_node(_NEFORCE forward<Args>(args)...);
1150 node_guard guard(this, tmp);
1151
1152 if (position.node_ == header_->left_) {
1153 if (size() > 0 && key_compare_(rb_tree::key(tmp), rb_tree::key(position.node_))) {
1154 guard.release();
1155 return rb_tree::insert_into(position.node_, position.node_, tmp);
1156 }
1157 guard.release();
1158 return rb_tree::insert_unique(tmp).first;
1159 }
1160
1161 if (position.node_ == header_) {
1162 if (key_compare_(rb_tree::key(rightmost()), rb_tree::key(tmp))) {
1163 guard.release();
1164 return rb_tree::insert_into(nullptr, rightmost(), tmp);
1165 }
1166 guard.release();
1167 return rb_tree::insert_unique(tmp).first;
1168 }
1169
1170 iterator before = position;
1171 --before;
1172
1173 if (key_compare_(rb_tree::key(before.node_), rb_tree::key(tmp)) &&
1174 key_compare_(rb_tree::key(tmp), rb_tree::key(position.node_))) {
1175 if (rb_tree::right(link_type(before.node_)) == nullptr) {
1176 guard.release();
1177 return rb_tree::insert_into(nullptr, before.node_, tmp);
1178 }
1179 if (rb_tree::left(link_type(position.node_)) == nullptr) {
1180 guard.release();
1181 return rb_tree::insert_into(position.node_, position.node_, tmp);
1182 }
1183 }
1184
1185 guard.release();
1186 return rb_tree::insert_unique(tmp).first;
1187 }
1188
1195 iterator insert_unique(iterator position, const value_type& value) {
1196 return rb_tree::emplace_unique_hint(position, value);
1197 }
1198
1206 return rb_tree::emplace_unique_hint(position, _NEFORCE move(value));
1207 }
1208
1215 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1216 void insert_unique(Iterator first, Iterator last) {
1217 for (; first != last; ++first) {
1218 rb_tree::insert_unique(*first);
1219 }
1220 }
1221
1228 template <typename... Args>
1229 iterator emplace_equal(Args&&... args) {
1230 const link_type tmp = rb_tree::create_node(_NEFORCE forward<Args>(args)...);
1231 return rb_tree::insert_equal(tmp);
1232 }
1233
1240
1246 iterator insert_equal(value_type&& value) { return rb_tree::emplace_equal(_NEFORCE move(value)); }
1247
1255 template <typename... Args>
1256 iterator emplace_equal_hint(iterator position, Args&&... args) {
1257 link_type tmp = rb_tree::create_node(_NEFORCE forward<Args>(args)...);
1258 node_guard guard(this, tmp);
1259
1260 if (position.node_ == header_->left_) {
1261 if (size() > 0 && key_compare_(rb_tree::key(tmp), rb_tree::key(position.node_))) {
1262 guard.release();
1263 return rb_tree::insert_into(position.node_, position.node_, tmp);
1264 }
1265 guard.release();
1266 return rb_tree::insert_equal(tmp);
1267 }
1268
1269 if (position.node_ == header_) {
1270 if (!key_compare_(rb_tree::key(tmp), rb_tree::key(rightmost()))) {
1271 guard.release();
1272 return rb_tree::insert_into(nullptr, rightmost(), tmp);
1273 }
1274 guard.release();
1275 return rb_tree::insert_equal(tmp);
1276 }
1277
1278 iterator before = position;
1279 --before;
1280
1281 if (!key_compare_(rb_tree::key(tmp), rb_tree::key(before.node_)) &&
1282 !key_compare_(rb_tree::key(position.node_), rb_tree::key(tmp))) {
1283 if (rb_tree::right(link_type(before.node_)) == nullptr) {
1284 guard.release();
1285 return rb_tree::insert_into(nullptr, before.node_, tmp);
1286 }
1287 guard.release();
1288 return rb_tree::insert_into(position.node_, position.node_, tmp);
1289 }
1290
1291 guard.release();
1292 return rb_tree::insert_equal(tmp);
1293 }
1294
1301 iterator insert_equal(iterator position, const value_type& value) {
1302 return rb_tree::emplace_equal_hint(position, value);
1303 }
1304
1312 return rb_tree::emplace_equal_hint(position, _NEFORCE move(value));
1313 }
1314
1321 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1322 void insert_equal(Iterator first, Iterator last) {
1323 for (; first != last; ++first) {
1324 rb_tree::insert_equal(*first);
1325 }
1326 }
1327
1335 const size_type n = _NEFORCE distance(p.first, p.second);
1337 return n;
1338 }
1339
1345 auto y = reinterpret_cast<link_type>(
1346 _NEFORCE rb_tree_erase_rebalance(position.node_, header_->parent_, header_->left_, header_->right_));
1347 rb_tree::destroy_node(y);
1348 --size_pair_.value;
1349 }
1350
1357 if (first == begin() && last == end()) {
1358 clear();
1359 } else {
1360 while (first != last) {
1361 rb_tree::erase(first++);
1362 }
1363 }
1364 }
1365
1369 void clear() noexcept(is_nothrow_destructible_v<link_node>) {
1370 if (header_ == nullptr) {
1371 return;
1372 }
1373 if (size_pair_.value == 0) {
1374 return;
1375 }
1376 rb_tree::erase_under(root());
1377 leftmost() = header_;
1378 root() = nullptr;
1379 rightmost() = header_;
1380 size_pair_.value = 0;
1381 }
1382
1388 NEFORCE_NODISCARD iterator find(const key_type& key) {
1389 link_type y = header_;
1390 link_type x = root();
1391
1392 while (x != nullptr) {
1393 if (!key_compare_(rb_tree::key(x), key)) {
1394 y = x;
1395 x = rb_tree::left(x);
1396 } else {
1397 x = rb_tree::right(x);
1398 }
1399 }
1400
1401 iterator j(y, this);
1402 if (j == end()) {
1403 return end();
1404 }
1405 return key_compare_(key, rb_tree::key(y)) ? end() : j;
1406 }
1407
1413 NEFORCE_NODISCARD const_iterator find(const key_type& key) const {
1414 link_type y = header_;
1415 link_type x = root();
1416
1417 while (x != nullptr) {
1418 if (!key_compare_(rb_tree::key(x), key)) {
1419 y = x;
1420 x = rb_tree::left(x);
1421 } else {
1422 x = rb_tree::right(x);
1423 }
1424 }
1425
1426 const_iterator j(y, this);
1427 if (j == cend()) {
1428 return cend();
1429 }
1430 return key_compare_(key, rb_tree::key(y)) ? cend() : j;
1431 }
1432
1438 NEFORCE_NODISCARD size_type count(const key_type& key) const {
1440 const size_type n = _NEFORCE distance(p.first, p.second);
1441 return n;
1442 }
1443
1449 NEFORCE_NODISCARD iterator lower_bound(const key_type& key) {
1450 link_type y = header_;
1451 link_type x = root();
1452
1453 while (x != nullptr) {
1454 if (!key_compare_(rb_tree::key(x), key)) {
1455 y = x;
1456 x = rb_tree::left(x);
1457 } else {
1458 x = rb_tree::right(x);
1459 }
1460 }
1461
1462 return iterator(y, this);
1463 }
1464
1470 NEFORCE_NODISCARD const_iterator lower_bound(const key_type& key) const {
1471 link_type y = header_;
1472 link_type x = root();
1473
1474 while (x != nullptr) {
1475 if (!key_compare_(rb_tree::key(x), key)) {
1476 y = x;
1477 x = rb_tree::left(x);
1478 } else {
1479 x = rb_tree::right(x);
1480 }
1481 }
1482
1483 return const_iterator(y, this);
1484 }
1485
1491 NEFORCE_NODISCARD iterator upper_bound(const key_type& key) {
1492 link_type y = header_;
1493 link_type x = root();
1494
1495 while (x != nullptr) {
1496 if (key_compare_(key, rb_tree::key(x))) {
1497 y = x;
1498 x = rb_tree::left(x);
1499 } else {
1500 x = rb_tree::right(x);
1501 }
1502 }
1503
1504 return iterator(y, this);
1505 }
1506
1512 NEFORCE_NODISCARD const_iterator upper_bound(const key_type& key) const {
1513 link_type y = header_;
1514 link_type x = root();
1515
1516 while (x != nullptr) {
1517 if (key_compare_(key, rb_tree::key(x))) {
1518 y = x;
1519 x = rb_tree::left(x);
1520 } else {
1521 x = rb_tree::right(x);
1522 }
1523 }
1524
1525 return const_iterator(y, this);
1526 }
1527
1536
1545
1552 _NEFORCE swap(header_, other.header_);
1553 _NEFORCE swap(size_pair_, other.size_pair_);
1554 _NEFORCE swap(key_compare_, other.key_compare_);
1555 _NEFORCE swap(extracter_, other.extracter_);
1556 }
1557
1563 NEFORCE_NODISCARD bool operator==(const rb_tree& rhs) const
1564 noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin()))) {
1565 return size() == rhs.size() && _NEFORCE equal(cbegin(), cend(), rhs.cbegin());
1566 }
1567
1573 NEFORCE_NODISCARD bool operator<(const rb_tree& rhs) const
1574 noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend()))) {
1575 return _NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend());
1576 }
1577};
1578 // RBTree
1580
1581NEFORCE_END_NAMESPACE__
1582#endif // NEFORCE_CORE_CONTAINER_RB_TREE_HPP__
NEFORCE_NODISCARD bool empty() const noexcept
检查是否为空
void erase(iterator first, iterator last) noexcept(is_nothrow_destructible_v< link_node >)
删除指定范围内的元素
NEFORCE_NODISCARD iterator upper_bound(const key_type &key)
获取第一个大于指定键的元素位置
iterator emplace_equal(Args &&... args)
在树中构造元素(允许重复键版本)
NEFORCE_NODISCARD bool operator==(const rb_tree &rhs) const noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin())))
相等比较操作符
NEFORCE_NODISCARD pair< iterator, iterator > equal_range(const key_type &key)
获取等于指定键的元素范围
NEFORCE_NODISCARD const_iterator end() const noexcept
获取常量结束迭代器
NEFORCE_NODISCARD iterator lower_bound(const key_type &key)
获取第一个不小于指定键的元素位置
NEFORCE_NODISCARD const_iterator find(const key_type &key) const
查找具有指定键的元素(常量版本)
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 >)
移动构造函数
NEFORCE_NODISCARD size_type size() const noexcept
获取元素数量
iterator insert_equal(iterator position, const value_type &value)
在提示位置附近插入元素(允许重复键版本)
NEFORCE_NODISCARD size_type count(const key_type &key) const
统计具有指定键的元素数量
iterator insert_equal(iterator position, value_type &&value)
在提示位置附近移动插入元素(允许重复键版本)
void insert_equal(Iterator first, Iterator last)
范围插入元素(允许重复键版本)
iterator emplace_unique_hint(iterator position, Args &&... args)
在提示位置附近构造元素(唯一键版本)
NEFORCE_NODISCARD const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
NEFORCE_NODISCARD iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD reverse_iterator rbegin() noexcept
获取反向起始迭代器
NEFORCE_NODISCARD const_iterator cbegin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD iterator find(const key_type &key)
查找具有指定键的元素
NEFORCE_NODISCARD iterator end() noexcept
获取结束迭代器
pair< iterator, bool > insert_unique(const value_type &value)
插入元素(唯一键版本)
iterator insert_equal(const value_type &value)
插入元素(允许重复键版本)
NEFORCE_NODISCARD const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
pair< iterator, bool > emplace_unique(Args &&... args)
在树中构造元素(唯一键版本)
size_type erase(const key_type &key) noexcept(is_nothrow_destructible_v< link_node >)
删除所有具有指定键的元素
NEFORCE_NODISCARD reverse_iterator rend() noexcept
获取反向结束迭代器
void erase(iterator position) noexcept(is_nothrow_destructible_v< link_node >)
删除指定位置的元素
NEFORCE_NODISCARD Compare key_compare() const noexcept(is_nothrow_copy_constructible_v< Compare >)
获取键比较函数对象
NEFORCE_NODISCARD const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
iterator emplace_equal_hint(iterator position, Args &&... args)
在提示位置附近构造元素(允许重复键版本)
rb_tree & operator=(rb_tree &&other) noexcept(is_nothrow_move_constructible_v< rb_tree >)
移动赋值运算符
void insert_unique(Iterator first, Iterator last)
范围插入元素(唯一键版本)
NEFORCE_NODISCARD const_iterator begin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD const_iterator lower_bound(const key_type &key) const
获取第一个不小于指定键的元素位置(常量版本)
void clear() noexcept(is_nothrow_destructible_v< link_node >)
清空树
rb_tree(const rb_tree &other)
拷贝构造函数
pair< iterator, bool > insert_unique(value_type &&value)
移动插入元素(唯一键版本)
NEFORCE_NODISCARD const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
NEFORCE_NODISCARD const_iterator cend() const noexcept
获取常量结束迭代器
NEFORCE_NODISCARD pair< const_iterator, const_iterator > equal_range(const key_type &key) const
获取等于指定键的元素范围(常量版本)
void swap(rb_tree &other) noexcept(is_nothrow_swappable_v< Compare > &&is_nothrow_swappable_v< KeyOfValue > &&is_nothrow_swappable_v< allocator_type >)
交换两个红黑树的内容
rb_tree()
默认构造函数
rb_tree & operator=(const rb_tree &other)
拷贝赋值运算符
NEFORCE_NODISCARD size_type max_size() const noexcept
获取最大可能大小
~rb_tree()
析构函数
iterator insert_unique(iterator position, value_type &&value)
在提示位置附近移动插入元素(唯一键版本)
NEFORCE_NODISCARD const_iterator upper_bound(const key_type &key) const
获取第一个大于指定键的元素位置(常量版本)
NEFORCE_NODISCARD bool operator<(const rb_tree &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
rb_tree(const Compare &comp)
构造函数,指定比较函数
比较算法
压缩对实现
内存构造和销毁函数
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
NEFORCE_NODISCARD 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))
字典序比较两个范围
#define NEFORCE_DEBUG_VERIFY(CON, MESG)
调试模式断言
NEFORCE_CONSTEXPR20 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
NEFORCE_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
standard_allocator< T > allocator
标准分配器别名
uint64_t size_t
无符号大小类型
int64_t ptrdiff_t
指针差类型
NEFORCE_INLINE17 constexpr bool RB_TREE_RED
红黑树节点颜色常量:红色
NEFORCE_ALWAYS_INLINE_INLINE 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
删除节点后重新平衡红黑树
NEFORCE_ALWAYS_INLINE_INLINE void rb_tree_rotate_right(rb_tree_node_base *axis, rb_tree_node_base *&root) noexcept
红黑树右旋转
NEFORCE_ALWAYS_INLINE_INLINE void rb_tree_insert_rebalance(rb_tree_node_base *insert, rb_tree_node_base *&root) noexcept
插入节点后重新平衡红黑树
NEFORCE_INLINE17 constexpr bool RB_TREE_BLACK
红黑树节点颜色常量:黑色
NEFORCE_ALWAYS_INLINE_INLINE void rb_tree_rotate_left(rb_tree_node_base *axis, rb_tree_node_base *&root) noexcept
红黑树左旋转
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重载
NEFORCE_INLINE17 constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_allocator_v
is_allocator的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_default_constructible_v
is_nothrow_default_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
集合器接口
迭代器接口
键值对
标准分配器
双向迭代器标签
集合器接口模板
迭代器接口模板
存储两个值的元组对
T2 second
第二个元素
T1 first
第一个元素
红黑树迭代器基类
void increment() noexcept
递增操作(移动到中序遍历的后继节点)
rb_tree_node_base::base_ptr base_ptr
基类指针类型
void decrement() noexcept
递减操作(移动到中序遍历的前驱节点)
bidirectional_iterator_tag iterator_category
双向迭代器
base_ptr node_
当前节点指针
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
NEFORCE_CONSTEXPR20 void increment() noexcept
递增操作
NEFORCE_CONSTEXPR20 void decrement() noexcept
递减操作
typename container_type::size_type size_type
大小类型
typename container_type::difference_type difference_type
差值类型
RbTree container_type
容器类型
NEFORCE_NODISCARD pointer base() const noexcept
获取底层指针
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
NEFORCE_NODISCARD bool equal(const rb_tree_iterator &rhs) const noexcept
相等比较
rb_tree_base_iterator::iterator_category iterator_category
迭代器类别(双向)
NEFORCE_NODISCARD reference dereference() const noexcept
解引用操作
NEFORCE_NODISCARD const container_type * container() const noexcept
获取关联容器
typename container_type::value_type value_type
值类型
红黑树节点基类
static base_ptr maximum(base_ptr root) noexcept
获取子树中的最大节点
base_ptr parent_
父节点指针
base_ptr left_
左子节点指针
base_ptr right_
右子节点指针
static base_ptr minimum(base_ptr root) noexcept
获取子树中的最小节点
color_type color_
节点颜色,默认为红色
rb_tree_node_base * base_ptr
基类指针类型
bool color_type
颜色类型
红黑树数据节点
rb_tree_node() noexcept(is_nothrow_default_constructible_v< T >)
默认构造函数