MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
rb_tree.hpp
1#ifndef MSTL_CORE_CONTAINER_RB_TREE_HPP__
2#define MSTL_CORE_CONTAINER_RB_TREE_HPP__
8#include "../utility/pair.hpp"
10
11MSTL_INLINE17 constexpr bool RB_TREE_RED = false;
12MSTL_INLINE17 constexpr bool RB_TREE_BLACK = true;
13
15struct __rb_tree_node_base;
16struct __rb_tree_base_iterator;
18
19template <bool IsConst, typename RB_TREE>
20struct rb_tree_iterator;
21template <typename Key, typename Value, typename KeyOfValue, typename Compare, typename Alloc>
22class rb_tree;
23
25
26MSTL_API void rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root) noexcept;
27MSTL_API void rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) noexcept;
28MSTL_API void rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) noexcept;
29MSTL_API __rb_tree_node_base* rb_tree_rebalance_for_erase(
30 __rb_tree_node_base* z, __rb_tree_node_base*& root,
31 __rb_tree_node_base*& leftmost, __rb_tree_node_base*& rightmost
32 ) noexcept;
33
34
35struct MSTL_API __rb_tree_node_base {
36public:
37 using color_type = bool;
38
39protected:
40 using base_ptr = __rb_tree_node_base*;
41
42 color_type color_ = RB_TREE_RED;
43 base_ptr parent_ = nullptr;
44 base_ptr left_ = nullptr;
45 base_ptr right_ = nullptr;
46
47 friend _INNER __rb_tree_base_iterator;
48 template <bool, typename> friend struct _MSTL rb_tree_iterator;
49 template <typename, typename, typename, typename, typename> friend class _MSTL rb_tree;
50 friend MSTL_API void _INNER rb_tree_rotate_left(__rb_tree_node_base*, __rb_tree_node_base*&) noexcept;
51 friend MSTL_API void _INNER rb_tree_rotate_right(__rb_tree_node_base*, __rb_tree_node_base*&) noexcept;
52 friend MSTL_API void _INNER rb_tree_rebalance(__rb_tree_node_base*, __rb_tree_node_base*&) noexcept;
53 friend MSTL_API _INNER __rb_tree_node_base* _INNER rb_tree_rebalance_for_erase(
54 _INNER __rb_tree_node_base*, _INNER __rb_tree_node_base*&,
55 _INNER __rb_tree_node_base*&, _INNER __rb_tree_node_base*&) noexcept;
56
57 static base_ptr minimum(base_ptr x) noexcept {
58 while (x->left_ != nullptr) x = x->left_;
59 return x;
60 }
61 static base_ptr maximum(base_ptr x) noexcept {
62 while (x->right_ != nullptr) x = x->right_;
63 return x;
64 }
65};
66
68
69
70template <typename T>
71struct rb_tree_node : _INNER __rb_tree_node_base {
72private:
73 T data_{};
74
75 template <typename, typename, typename, typename, typename> friend class rb_tree;
76 template <bool, typename> friend struct rb_tree_iterator;
77
78public:
79 rb_tree_node() = default;
80 ~rb_tree_node() = default;
81};
82
83
85struct MSTL_API __rb_tree_base_iterator {
86public:
87 using iterator_category = bidirectional_iterator_tag;
88
89protected:
90 using base_ptr = __rb_tree_node_base::base_ptr;
91 base_ptr node_ = nullptr;
92
93 void increment() noexcept;
94 void decrement() noexcept;
95
96public:
97 MSTL_NODISCARD bool operator ==(const __rb_tree_base_iterator& rhs) const noexcept {
98 return node_ == rhs.node_;
99 }
100 MSTL_NODISCARD bool operator !=(const __rb_tree_base_iterator& rhs) const noexcept {
101 return node_ != rhs.node_;
102 }
103};
105
106
107template <bool IsConst, typename RB_TREE>
108struct rb_tree_iterator : _INNER __rb_tree_base_iterator {
109private:
110 using container_type = RB_TREE;
111 using iterator = rb_tree_iterator<false, container_type>;
112 using const_iterator = rb_tree_iterator<true, container_type>;
113
114public:
115 using value_type = typename container_type::value_type;
118 using difference_type = typename container_type::difference_type;
119 using size_type = typename container_type::size_type;
120
121private:
122 using link_type = rb_tree_node<value_type>*;
123
124 const container_type* tree_ = nullptr;
125
126 template <typename, typename, typename, typename, typename> friend class rb_tree;
127 template <bool, typename> friend struct rb_tree_iterator;
128
129public:
130 rb_tree_iterator() = default;
131 rb_tree_iterator(link_type x, const container_type* cont)
132 : tree_(cont) {
133 node_ = x;
134 }
135
136 rb_tree_iterator(const iterator& it) {
137 node_ = it.node_;
138 tree_ = it.tree_;
139 }
140 rb_tree_iterator& operator =(const iterator& it) {
141 if(_MSTL addressof(it) == this) return *this;
142 node_ = it.node_;
143 tree_ = it.tree_;
144 return *this;
145 }
146
147 rb_tree_iterator(iterator&& it) noexcept {
148 node_ = it.node_;
149 tree_ = it.tree_;
150 it.node_ = nullptr;
151 it.tree_ = nullptr;
152 }
153 rb_tree_iterator& operator =(iterator&& it) {
154 if(_MSTL addressof(it) == this) return *this;
155 node_ = it.node_;
156 tree_ = it.tree_;
157 it.node_ = nullptr;
158 it.tree_ = nullptr;
159 return *this;
160 }
161
162 rb_tree_iterator(const const_iterator& it) {
163 node_ = it.node_;
164 tree_ = it.tree_;
165 }
166 rb_tree_iterator& operator =(const const_iterator& it) {
167 if(_MSTL addressof(it) == this) return *this;
168 node_ = it.node_;
169 tree_ = it.tree_;
170 return *this;
171 }
172
173 rb_tree_iterator(const_iterator&& it) {
174 node_ = it.node_;
175 tree_ = it.tree_;
176 it.node_ = nullptr;
177 it.tree_ = nullptr;
178 }
179 rb_tree_iterator& operator =(const_iterator&& it) {
180 if(_MSTL addressof(it) == this) return *this;
181 node_ = it.node_;
182 tree_ = it.tree_;
183 it.node_ = nullptr;
184 it.tree_ = nullptr;
185 return *this;
186 }
187
188 ~rb_tree_iterator() = default;
189
190 MSTL_NODISCARD reference operator *() const noexcept {
191 MSTL_DEBUG_VERIFY(node_ && tree_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(rb_tree_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
192 link_type link = link_type(node_);
193 MSTL_DEBUG_VERIFY(node_ != tree_->header_ && node_->parent_ != nullptr,
194 __MSTL_DEBUG_MESG_OUT_OF_RANGE(rb_tree_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
195 return link->data_;
196 }
197 MSTL_NODISCARD pointer operator ->() const noexcept {
198 return &operator*();
199 }
200
201 rb_tree_iterator& operator ++() noexcept {
202 MSTL_DEBUG_VERIFY(node_ && tree_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(rb_tree_iterator, __MSTL_DEBUG_TAG_INCREMENT));
203 MSTL_DEBUG_VERIFY(link_type(node_) != tree_->header_,
204 __MSTL_DEBUG_MESG_OUT_OF_RANGE(rb_tree_iterator, __MSTL_DEBUG_TAG_INCREMENT));
205 increment();
206 return *this;
207 }
208 rb_tree_iterator operator ++(int) noexcept {
209 rb_tree_iterator tmp = *this;
210 ++*this;
211 return tmp;
212 }
213 rb_tree_iterator& operator --() noexcept {
214 MSTL_DEBUG_VERIFY(node_ && tree_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(rb_tree_iterator, __MSTL_DEBUG_TAG_DECREMENT));
215 MSTL_DEBUG_VERIFY(node_ != tree_->header_,
216 __MSTL_DEBUG_MESG_OUT_OF_RANGE(rb_tree_iterator, __MSTL_DEBUG_TAG_DECREMENT));
217 decrement();
218 return *this;
219 }
220 rb_tree_iterator operator --(int) noexcept {
221 rb_tree_iterator tmp = *this;
222 --*this;
223 return tmp;
224 }
225
226 MSTL_NODISCARD bool operator ==(const rb_tree_iterator& rhs) const noexcept {
227 MSTL_DEBUG_VERIFY(node_ && tree_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(rb_tree_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
228 MSTL_DEBUG_VERIFY(tree_ == rhs.tree_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(rb_tree_iterator));
229 return __rb_tree_base_iterator::operator ==(rhs);
230 }
231 MSTL_NODISCARD bool operator !=(const rb_tree_iterator& rhs) const noexcept {
232 MSTL_DEBUG_VERIFY(node_ && tree_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(rb_tree_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
233 MSTL_DEBUG_VERIFY(tree_ == rhs.tree_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(rb_tree_iterator));
234 return __rb_tree_base_iterator::operator !=(rhs);
235 }
236
237 MSTL_NODISCARD constexpr pointer base() const noexcept {
238 return node_;
239 }
240};
241
242
243template <typename Key, typename Value, typename KeyOfValue, typename Compare,
244 typename Alloc = allocator<rb_tree_node<Value>>>
245class rb_tree : icollector<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>> {
246#ifdef MSTL_STANDARD_20__
247 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
248#endif
249 static_assert(is_same_v<rb_tree_node<Value>, typename Alloc::value_type>, "allocator type mismatch.");
250 static_assert(is_object_v<Value>, "list only contains object types.");
251
252 using base_node = _INNER __rb_tree_node_base;
253 using link_node = rb_tree_node<Value>;
254 using base_ptr = base_node*;
255 using link_type = link_node*;
256
257public:
258 using key_type = Key;
259 using color_type = bool;
260
262
263 using iterator = rb_tree_iterator<false, rb_tree>;
264 using const_iterator = rb_tree_iterator<true, rb_tree>;
265 using reverse_iterator = _MSTL reverse_iterator<iterator>;
266 using const_reverse_iterator = _MSTL reverse_iterator<const_iterator>;
267
268 using allocator_type = Alloc;
269
270private:
271 link_type header_ = nullptr;
272 Compare key_compare_{};
273 KeyOfValue extracter_{};
274 compressed_pair<allocator_type, size_t> size_pair_{ default_construct_tag{}, 0 }; // size
275
276 template <bool, typename> friend struct rb_tree_iterator;
277
278private:
279 template <typename... Args>
280 link_type create_node(Args... args) {
281 link_type tmp = size_pair_.get_base().allocate();
282 try {
283 _MSTL construct(&tmp->data_, _MSTL forward<Args>(args)...);
284 } catch (...) {
285 destroy_node(tmp);
286 throw_exception(memory_exception("rb tree construct node failed."));
287 }
288 return tmp;
289 }
290 link_type copy_node(link_type x) {
291 link_type tmp = (create_node)(x->data_);
292 tmp->color_ = x->color_;
293 tmp->left_ = nullptr;
294 tmp->right_ = nullptr;
295 return tmp;
296 }
297 void destroy_node(link_type p) noexcept {
298 if (p == nullptr) return;
299 _MSTL destroy(&p->data_);
300 size_pair_.get_base().deallocate(p);
301 }
302
303 link_type& root() const noexcept { return reinterpret_cast<link_type&>(header_->parent_); }
304 link_type& leftmost() const noexcept { return reinterpret_cast<link_type&>(header_->left_); }
305 link_type& rightmost() const noexcept { return reinterpret_cast<link_type&>(header_->right_); }
306
307 static link_type& left(link_type x) noexcept { return reinterpret_cast<link_type&>(x->left_); }
308 static link_type& right(link_type x) noexcept { return reinterpret_cast<link_type&>(x->right_); }
309 static link_type& parent(link_type x) noexcept { return reinterpret_cast<link_type&>(x->parent_); }
310 static const Key& key(link_type x) noexcept { return KeyOfValue()(x->data_); }
311 static const Key& key(const base_ptr x) noexcept { return rb_tree::key(reinterpret_cast<link_type>(x)); }
312
313 static link_type minimum(link_type x) noexcept {
314 return static_cast<link_type>(base_node::minimum(x));
315 }
316 static link_type maximum(link_type x) noexcept {
317 return static_cast<link_type>(base_node::maximum(x));
318 }
319
320 iterator insert_node_into(base_ptr bx, base_ptr by, link_type p) {
321 auto x = static_cast<link_type>(bx);
322 auto y = static_cast<link_type>(by);
323 if (y == header_ || x != nullptr || key_compare_(key(p), key(y))) {
324 left(y) = p;
325 if (y == header_) {
326 root() = p;
327 leftmost() = p;
328 rightmost() = p;
329 }
330 else if (y == leftmost()) leftmost() = p;
331 }
332 else {
333 right(y) = p;
334 if (y == rightmost()) rightmost() = p;
335 }
336 parent(p) = y;
337 left(p) = nullptr;
338 right(p) = nullptr;
339 _INNER rb_tree_rebalance(p, header_->parent_);
340 ++size_pair_.value;
341 return iterator(p, this);
342 }
343
344 link_type copy_under_node(link_type x, link_type parent) {
345 link_type top = copy_node(x);
346 top->parent_ = parent;
347 try{
348 if (x->right_ != nullptr)
349 top->right_ = copy_under_node(right(x), top);
350 parent = top;
351 x = left(x);
352 while (x != nullptr) {
353 link_type y = copy_node(x);
354 parent->left_ = y;
355 y->parent_ = parent;
356 if (x->right_ != nullptr)
357 y->right_ = copy_under_node(right(x), y);
358 parent = y;
359 x = left(x);
360 }
361 if (root() != nullptr) {
362 leftmost() = minimum(root());
363 rightmost() = maximum(root());
364 } else {
365 leftmost() = header_;
366 rightmost() = header_;
367 }
368 } catch (...) {
369 this->erase_under_node(top);
370 throw;
371 }
372 return top;
373 }
374
375 void erase_under_node(link_type x) noexcept {
376 if (x == nullptr) return;
377 this->erase_under_node(this->right(x));
378 this->erase_under_node(this->left(x));
379 this->destroy_node(x);
380 }
381
382 void header_init() {
383 header_ = size_pair_.get_base().allocate();
384 header_->color_ = RB_TREE_RED;
385 root() = nullptr;
386 leftmost() = header_;
387 rightmost() = header_;
388 }
389
390 void copy_from(const rb_tree& x) {
391 if (x.root() == nullptr) {
392 root() = nullptr;
393 leftmost() = header_;
394 rightmost() = header_;
395 }
396 else {
397 try {
398 root() = copy_under_node(x.root(), header_);
399 }
400 catch (...) {
401 size_pair_.get_base().deallocate(header_);
402 throw;
403 }
404 leftmost() = minimum(root());
405 rightmost() = maximum(root());
406 }
407 size_pair_.value = x.size_pair_.value;
408 }
409
410 pair<iterator, bool> insert_unique_node(link_type p) {
411 link_type y = header_;
412 link_type x = root();
413 bool comp = true;
414 while (x != nullptr) {
415 y = x;
416 comp = key_compare_(key(p), key(x));
417 x = comp ? left(x) : right(x);
418 }
419 iterator j(y, this);
420 if (comp) {
421 if (j == begin())
422 return pair<iterator, bool>(insert_node_into(x, y, p), true);
423 --j;
424 }
425 if (key_compare_(key(link_type(j.node_)), key(p)))
426 return pair<iterator, bool>(insert_node_into(x, y, p), true);
427 destroy_node(p);
428 return pair<iterator, bool>(j, false);
429 }
430
431 iterator insert_equal_node(link_type p) {
432 link_type y = header_;
433 link_type x = root();
434 while (x != nullptr) {
435 y = x;
436 x = key_compare_(key(p), key(x)) ? left(x) : right(x);
437 }
438 return insert_node_into(x, y, p);
439 }
440
441public:
442 rb_tree() {
443 header_init();
444 }
445
446 explicit rb_tree(const Compare& comp) : key_compare_(comp) {
447 header_init();
448 }
449
450 rb_tree(const rb_tree& x) :
451 key_compare_(x.key_compare_),
452 extracter_(x.extracter_), size_pair_(x.size_pair_) {
453 header_init();
454 copy_from(x);
455 }
456 rb_tree& operator =(const rb_tree& x) {
457 if (_MSTL addressof(x) == this) return *this;
458 clear();
459 copy_from(x);
460 return *this;
461 }
462
463 rb_tree(rb_tree&& x) noexcept :
464 header_(_MSTL move(x.header_)), key_compare_(_MSTL move(x.key_compare_)),
465 extracter_(_MSTL move(x.extracter_)), size_pair_(_MSTL move(x.size_pair_)) {
466 x.header_ = nullptr;
467 x.size_pair_.value = 0;
468 }
469
470 rb_tree& operator =(rb_tree&& x) noexcept {
471 if (_MSTL addressof(x) == this) return *this;
472 clear();
473 size_pair_.get_base().deallocate(header_);
474 header_ = x.header_;
475 key_compare_ = _MSTL move(x.key_compare_);
476 size_pair_ = _MSTL move(x.size_pair_);
477 x.header_ = nullptr;
478 x.size_pair_.value = 0;
479 return *this;
480 }
481
482 ~rb_tree() {
483 clear();
484 if (header_) {
485 size_pair_.get_base().deallocate(header_);
486 }
487 }
488
489 MSTL_NODISCARD iterator begin() noexcept { return {leftmost(), this}; }
490 MSTL_NODISCARD iterator end() noexcept { return {header_, this}; }
491 MSTL_NODISCARD const_iterator begin() const noexcept { return cbegin(); }
492 MSTL_NODISCARD const_iterator end() const noexcept { return cend(); }
493 MSTL_NODISCARD const_iterator cbegin() const noexcept { return {leftmost(), this}; }
494 MSTL_NODISCARD const_iterator cend() const noexcept { return {header_, this}; }
495 MSTL_NODISCARD reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
496 MSTL_NODISCARD reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
497 MSTL_NODISCARD const_reverse_iterator rbegin() const noexcept { return crbegin(); }
498 MSTL_NODISCARD const_reverse_iterator rend() const noexcept { return crend(); }
499 MSTL_NODISCARD const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
500 MSTL_NODISCARD const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
501
502 MSTL_NODISCARD size_type size() const noexcept { return size_pair_.value; }
503 MSTL_NODISCARD size_type max_size() const noexcept { return static_cast<size_type>(-1); }
504 MSTL_NODISCARD bool empty() const noexcept { return size_pair_.value == 0; }
505
506 MSTL_NODISCARD allocator_type get_allocator() const noexcept { return allocator_type(); }
507
508 MSTL_NODISCARD Compare key_comp() const noexcept(is_nothrow_copy_constructible_v<Compare>) {
509 return key_compare_;
510 }
511
512 template <typename... Args>
513 pair<iterator, bool> emplace_unique(Args&&... args) {
514 const link_type tmp = (create_node)(_MSTL forward<Args>(args)...);
515 return (insert_unique_node)(tmp);
516 }
517 pair<iterator, bool> insert_unique(const value_type& v) {
518 return (emplace_unique)(v);
519 }
520 pair<iterator, bool> insert_unique(value_type&& v) {
521 return (emplace_unique)(_MSTL move(v));
522 }
523 template <typename... Args>
524 iterator emplace_unique_hint(iterator position, Args&&... args) {
525 link_type tmp = (create_node)(_MSTL forward<Args>(args)...);
526 if (position.node_ == header_->left_) {
527 if (size() > 0 && key_compare_(key(tmp), key(position.node_)))
528 return insert_node_into(position.node_, position.node_, tmp);
529 return insert_unique_node(tmp).first;
530 }
531 if (position.node_ == header_) {
532 if (key_compare_(key(rightmost()), key(tmp)))
533 return insert_node_into(nullptr, rightmost(), tmp);
534 return insert_unique_node(tmp).first;
535 }
536 iterator before = position;
537 --before;
538 if (key_compare_(key(before.node_), key(tmp)) &&
539 key_compare_(key(tmp), key(position.node_))) {
540 if (right(link_type(before.node_)) == nullptr)
541 return insert_node_into(nullptr, before.node_, tmp);
542 return insert_node_into(position.node_, position.node_, tmp);
543 }
544 return insert_unique_node(tmp).first;
545 }
546 iterator insert_unique(iterator position, const value_type& v) {
547 return (emplace_unique_hint)(position, v);
548 }
549 iterator insert_unique(iterator position, value_type&& v) {
550 return (emplace_unique_hint)(position, _MSTL move(v));
551 }
552 template <typename Iterator, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
553 void insert_unique(Iterator first, Iterator last) {
554 for (; first != last; ++first) insert_unique(*first);
555 }
556
557 template <typename... Args>
558 iterator emplace_equal(Args&&... args) {
559 const link_type tmp = (create_node)(_MSTL forward<Args>(args)...);
560 return (insert_equal_node)(tmp);
561 }
562 iterator insert_equal(const value_type& v) {
563 return (emplace_equal)(v);
564 }
565 iterator insert_equal(value_type&& v) {
566 return (emplace_equal)(_MSTL move(v));
567 }
568 template <typename... Args>
569 iterator emplace_equal_hint(iterator position, Args&&... args) {
570 link_type tmp = (create_node)(_MSTL forward<Args>(args)...);
571 if (position.node_ == header_->left_) {
572 if (size() > 0 && key_compare_(key(tmp), key(position.node_)))
573 return insert_node_into(position.node_, position.node_, tmp);
574 return insert_equal_node(tmp);
575 }
576 if (position.node_ == header_) {
577 if (!key_compare_(key(tmp), key(rightmost())))
578 return insert_node_into(nullptr, rightmost(), tmp);
579 return insert_equal_node(tmp);
580 }
581 iterator before = position;
582 --before;
583 if (!key_compare_(key(tmp), key(before.node_)) &&
584 !key_compare_(key(position.node_), key(tmp))) {
585 if (right(link_type(before.node_)) == nullptr)
586 return insert_node_into(nullptr, before.node_, tmp);
587 return insert_node_into(position.node_, position.node_, tmp);
588 }
589 return insert_equal_node(tmp);
590 }
591 iterator insert_equal(iterator position, const value_type& v) {
592 return (emplace_equal_hint)(position, v);
593 }
594 iterator insert_equal(iterator position, value_type&& v) {
595 return (emplace_equal_hint)(position, _MSTL move(v));
596 }
597 template <typename Iterator, enable_if_t<is_ranges_input_iter_v<Iterator>, int> = 0>
598 void insert_equal(Iterator first, Iterator last) {
599 for (; first != last; ++first) insert_equal(*first);
600 }
601
602 size_type erase(const key_type& k) noexcept {
603 pair<iterator, iterator> p = equal_range(k);
604 const size_type n = _MSTL distance(p.first, p.second);
605 erase(p.first, p.second);
606 return n;
607 }
608 void erase(iterator position) noexcept {
609 auto y = reinterpret_cast<link_type>(rb_tree_rebalance_for_erase(
610 position.node_, header_->parent_, header_->left_, header_->right_));
611 destroy_node(y);
612 --size_pair_.value;
613 }
614 void erase(iterator first, iterator last) noexcept {
615 if (first == begin() && last == end())
616 clear();
617 else
618 while (first != last) erase(first++);
619 }
620
621 void clear() noexcept {
622 if (size_pair_.value == 0) return;
623 this->erase_under_node(root());
624 leftmost() = header_;
625 root() = nullptr;
626 rightmost() = header_;
627 size_pair_.value = 0;
628 }
629
630 MSTL_NODISCARD iterator find(const key_type& k) {
631 link_type y = header_;
632 link_type x = root();
633 while (x != nullptr) {
634 if (!key_compare_(key(x), k)) {
635 y = x;
636 x = left(x);
637 }
638 else x = right(x);
639 }
640 iterator j(y, this);
641 if (j == end())
642 return end();
643 return key_compare_(k, key(y)) ? end() : j;
644 }
645 MSTL_NODISCARD const_iterator find(const key_type& k) const {
646 link_type y = header_;
647 link_type x = root();
648 while (x != nullptr) {
649 if (!key_compare_(key(x), k)) {
650 y = x;
651 x = left(x);
652 }
653 else x = right(x);
654 }
655 const_iterator j(y, this);
656 if (j == cend())
657 return cend();
658 return key_compare_(k, key(y)) ? cend() : j;
659 }
660
661 MSTL_NODISCARD size_type count(const key_type& k) const {
662 pair<const_iterator, const_iterator> p = equal_range(k);
663 const size_type n = _MSTL distance(p.first, p.second);
664 return n;
665 }
666
667 MSTL_NODISCARD iterator lower_bound(const key_type& k) {
668 link_type y = header_;
669 link_type x = root();
670 while (x != nullptr) {
671 if (!key_compare_(key(x), k)) {
672 y = x;
673 x = left(x);
674 }
675 else x = right(x);
676 }
677 return iterator(y, this);
678 }
679 MSTL_NODISCARD const_iterator lower_bound(const key_type& k) const {
680 link_type y = header_;
681 link_type x = root();
682 while (x != nullptr) {
683 if (!key_compare_(key(x), k)) {
684 y = x;
685 x = left(x);
686 }
687 else x = right(x);
688 }
689 return const_iterator(y, this);
690 }
691
692 MSTL_NODISCARD iterator upper_bound(const key_type& k) {
693 link_type y = header_;
694 link_type x = root();
695 while (x != nullptr) {
696 if (key_compare_(k, key(x))) {
697 y = x;
698 x = left(x);
699 }
700 else x = right(x);
701 }
702 return iterator(y, this);
703 }
704 MSTL_NODISCARD const_iterator upper_bound(const key_type& k) const {
705 link_type y = header_;
706 link_type x = root();
707 while (x != nullptr) {
708 if (key_compare_(k, key(x))) {
709 y = x;
710 x = left(x);
711 }
712 else x = right(x);
713 }
714 return const_iterator(y, this);
715 }
716
717 MSTL_NODISCARD pair<iterator, iterator> equal_range(const key_type& k) {
718 return pair<iterator, iterator>(this->lower_bound(k), this->upper_bound(k));
719 }
720 MSTL_NODISCARD pair<const_iterator, const_iterator> equal_range(const key_type& k) const {
721 return pair<const_iterator, const_iterator>(this->lower_bound(k), this->upper_bound(k));
722 }
723
724 void swap(rb_tree& x)
725 noexcept(is_nothrow_swappable_v<Compare> &&
726 is_nothrow_swappable_v<KeyOfValue> &&
727 noexcept(size_pair_.swap(x.size_pair_))) {
728 _MSTL swap(header_, x.header_);
729 _MSTL swap(size_pair_, x.size_pair_);
730 _MSTL swap(key_compare_, x.key_compare_);
731 _MSTL swap(extracter_, x.extracter_);
732 }
733
734 MSTL_NODISCARD bool operator ==(const rb_tree& rhs) const
735 noexcept(noexcept(this->size() == rhs.size() && _MSTL equal(this->cbegin(), this->cend(), rhs.cbegin()))) {
736 return this->size() == rhs.size() && _MSTL equal(this->cbegin(), this->cend(), rhs.cbegin());
737 }
738 MSTL_NODISCARD bool operator <(const rb_tree& rhs) const
739 noexcept(noexcept(_MSTL lexicographical_compare(this->cbegin(), this->cend(), rhs.cbegin(), rhs.cend()))) {
740 return _MSTL lexicographical_compare(this->cbegin(), this->cend(), rhs.cbegin(), rhs.cend());
741 }
742};
743
745#endif // MSTL_CORE_CONTAINER_RB_TREE_HPP__
MSTL比较算法
MSTL压缩对实现
MSTL内存构造和销毁函数
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个不小于指定值的元素位置
constexpr Iterator upper_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个大于指定值的元素位置
MSTL_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
MSTL_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))
字典序比较两个范围
constexpr pair< Iterator, Iterator > equal_range(Iterator first, Iterator last, const T &value, Compare comp)
查找值的相等范围
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr duration< _INNER __common_rep_t< Rep1, Rep2 >, Period > operator*(const duration< Rep1, Period > &value, const Rep2 &scalar)
乘法运算符(持续时间 * 标量)
MSTL_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T &value)
查找范围内第一个等于指定值的元素
bool operator!=(const function< Res(Args...)> &f, nullptr_t null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
MSTL_CONSTEXPR20 enable_if_t< is_constructible_v< T, Args... >, void * > construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
MSTL_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
标准分配器别名
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
MSTL_NODISCARD constexpr bool operator<(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于比较运算符
#define MSTL_BUILD_TYPE_ALIAS(TYPE)
快速构建标准类型别名
constexpr size_t erase(Container &cont, const U &value)
从容器中删除所有等于指定值的元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr bool empty(const Container &cont) noexcept(noexcept(cont.empty()))
检查容器是否为空
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) rend(Container &cont) noexcept(noexcept(cont.rend()))
获取const容器的反向起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) cend(const Container &cont) noexcept(noexcept(cont.cend()))
获取const容器的const结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) begin(Container &cont) noexcept(noexcept(cont.begin()))
获取容器的起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) crbegin(const Container &cont) noexcept(noexcept(cont.crbegin()))
获取const容器的const反向起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) cbegin(const Container &cont) noexcept(noexcept(cont.cbegin()))
获取const容器的const起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) rbegin(Container &cont) noexcept(noexcept(cont.rbegin()))
获取容器的反向起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) crend(const Container &cont) noexcept(noexcept(cont.crend()))
获取const容器的const反向结束迭代器
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
MSTL集合器接口
MSTL键值对
MSTL标准分配器
constexpr void swap(compressed_pair &rhs) noexcept(is_nothrow_swappable_v< T >)
交换两个压缩对
constexpr compressed_pair & get_base() noexcept
获取基类引用
集合器接口模板
T2 second
第二个元素
T1 first
第一个元素