52#ifndef DOXYGEN_SHOULD_SKIP_THIS
57 template <
typename Val,
typename Cmp >
59 AVLNode* new_parent) {
60 if (from_node ==
nullptr)
return nullptr;
62 AVLNode* new_node =
nullptr;
63 AVLNode* new_left_child =
nullptr;
64 AVLNode* new_right_child;
66 new_node =
new AVLNode(from_node->value);
68 new_left_child = copySubtree_(from_node->left_child, new_node);
69 new_right_child = copySubtree_(from_node->right_child, new_node);
71 new_node->parent = new_parent;
72 new_node->left_child = new_left_child;
73 new_node->right_child = new_right_child;
74 new_node->height = from_node->height;
78 if (new_node !=
nullptr)
delete new_node;
79 if (new_left_child !=
nullptr) deleteSubtree_(new_left_child);
87 template <
typename Val,
typename Cmp >
89 if (subtree_root_node ==
nullptr)
return;
91 deleteSubtree_(subtree_root_node->left_child);
92 deleteSubtree_(subtree_root_node->right_child);
93 delete subtree_root_node;
97 template <
typename Val,
typename Cmp >
99 if (root_node_ ==
nullptr)
return nullptr;
101 AVLNode* node = root_node_;
102 while (node->left_child !=
nullptr)
103 node = node->left_child;
109 template <
typename Val,
typename Cmp >
111 if (root_node_ ==
nullptr)
return nullptr;
113 AVLNode* node = root_node_;
114 while (node->right_child !=
nullptr)
115 node = node->right_child;
121 template <
typename Val,
typename Cmp >
124 GUM_CONSTRUCTOR(AVLTree);
128 template <
typename Val,
typename Cmp >
129 INLINE AVLTree< Val, Cmp >::AVLTree(std::initializer_list< Val > list) {
131 for (
const auto& val: list)
135 deleteSubtree_(root_node_);
137 root_node_ =
nullptr;
138 lowest_node_ =
nullptr;
139 highest_node_ =
nullptr;
140 nb_elements_ = Size(0);
146 GUM_CONSTRUCTOR(AVLTree);
150 template <
typename Val,
typename Cmp >
151 INLINE AVLTree< Val, Cmp >::AVLTree(
const AVLTree< Val, Cmp >& from) :
152 nb_elements_(from.nb_elements_), cmp_(from.cmp_) {
153 root_node_ = copySubtree_(from.root_node_,
nullptr);
154 lowest_node_ = lowestNode_();
155 highest_node_ = highestNode_();
158 GUM_CONS_CPY(AVLTree);
162 template <
typename Val,
typename Cmp >
163 INLINE AVLTree< Val, Cmp >::AVLTree(AVLTree< Val, Cmp >&& from) noexcept :
164 root_node_(from.root_node_), lowest_node_(from.lowest_node_),
165 highest_node_(from.highest_node_), nb_elements_(from.nb_elements_),
166 owns_nodes_(from.owns_nodes_), cmp_(std::move(from.cmp_)),
167 safe_iterators_(std::move(from.safe_iterators_)) {
168 from.root_node_ =
nullptr;
169 from.lowest_node_ =
nullptr;
170 from.highest_node_ =
nullptr;
173 for (
auto iter: safe_iterators_) {
178 GUM_CONS_CPY(AVLTree);
182 template <
typename Val,
typename Cmp >
183 INLINE AVLTree< Val, Cmp >::~AVLTree() {
184 if (owns_nodes_) deleteSubtree_(root_node_);
187 for (
auto iter: safe_iterators_) {
188 iter->unregisterTree_();
192 GUM_DESTRUCTOR(AVLTree);
196 template <
typename Val,
typename Cmp >
197 AVLTree< Val, Cmp >& AVLTree< Val, Cmp >::operator=(
const AVLTree< Val, Cmp >& from) {
201 "It is forbidden to copy an AVLTree into a tree that does not own its nodes")
204 if (owns_nodes_) deleteSubtree_(root_node_);
207 for (
auto iter: safe_iterators_) {
208 iter->pointToEndRend_();
212 root_node_ = copySubtree_(from.root_node_,
nullptr);
213 lowest_node_ = lowestNode_();
214 highest_node_ = highestNode_();
215 nb_elements_ = from.nb_elements_;
218 root_node_ =
nullptr;
219 lowest_node_ =
nullptr;
220 highest_node_ =
nullptr;
221 nb_elements_ = Size(0);
231 template <
typename Val,
typename Cmp >
232 AVLTree< Val, Cmp >& AVLTree< Val, Cmp >::operator=(AVLTree< Val, Cmp >&& from)
noexcept {
236 "It is forbidden to move an AVLTree into a tree that does not own its nodes")
239 if (owns_nodes_) deleteSubtree_(root_node_);
242 for (
auto iter: safe_iterators_) {
243 iter->pointToEndRend_();
246 root_node_ = from.root_node_;
247 lowest_node_ = from.lowest_node_;
248 highest_node_ = from.highest_node_;
249 nb_elements_ = from.nb_elements_;
250 cmp_ = std::move(from.cmp_);
253 if (safe_iterators_.empty()) {
254 safe_iterators_ = std::move(from.safe_iterators_);
255 for (
auto iter: safe_iterators_) {
259 for (
auto from_iter: from.safe_iterators_) {
260 safe_iterators_.push_back(from_iter);
261 safe_iterators_.back()->tree_ =
this;
262 from.safe_iterators_.clear();
266 from.root_node_ =
nullptr;
267 from.lowest_node_ =
nullptr;
268 from.highest_node_ =
nullptr;
273 template <
typename Val,
typename Cmp >
274 INLINE Size AVLTree< Val, Cmp >::size() const noexcept {
279 template <
typename Val,
typename Cmp >
280 INLINE
bool AVLTree< Val, Cmp >::empty() const noexcept {
281 return nb_elements_ == Size(0);
285 template <
typename Val,
typename Cmp >
286 bool AVLTree< Val, Cmp >::contains(
const value_type& val)
const {
287 AVLNode* node = root_node_;
288 while (node !=
nullptr) {
289 if (node->value == val)
return true;
290 node = cmp_(val, node->value) ? node->left_child : node->right_child;
296 template <
typename Val,
typename Cmp >
297 INLINE
bool AVLTree< Val, Cmp >::exists(
const value_type& val)
const {
298 return contains(val);
302 template <
typename Val,
typename Cmp >
303 INLINE
const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::highestValue()
const {
304 if (highest_node_ ==
nullptr) {
307 return highest_node_->value;
311 template <
typename Val,
typename Cmp >
312 INLINE
const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::lowestValue()
const {
313 if (lowest_node_ ==
nullptr) {
GUM_ERROR(
NotFound,
"an empty AVL tree has no lowest element"); }
314 return lowest_node_->value;
330 template <
typename Val,
typename Cmp >
331 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::rightRotation_(AVLNode* node_q) {
332 AVLNode* node_p = node_q->left_child;
333 AVLNode* parent_q = node_q->parent;
334 AVLNode* subtree_u = node_p->left_child;
335 AVLNode* subtree_v = node_p->right_child;
336 AVLNode* subtree_w = node_q->right_child;
339 node_p->right_child = node_q;
340 node_q->parent = node_p;
342 node_p->parent = parent_q;
343 if (parent_q !=
nullptr) {
344 if (parent_q->left_child == node_q) parent_q->left_child = node_p;
345 else parent_q->right_child = node_p;
347 node_q->left_child = subtree_v;
348 if (subtree_v !=
nullptr) subtree_v->parent = node_q;
351 const int height_u = subtree_u !=
nullptr ? subtree_u->height : 0;
352 const int height_v = subtree_v !=
nullptr ? subtree_v->height : 0;
353 const int height_w = subtree_w !=
nullptr ? subtree_w->height : 0;
354 node_q->height = std::max(height_v, height_w) + 1;
355 node_p->height = std::max(node_q->height, height_u) + 1;
374 template <
typename Val,
typename Cmp >
375 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::leftRotation_(AVLNode* node_p) {
376 AVLNode* node_q = node_p->right_child;
377 AVLNode* parent_p = node_p->parent;
378 AVLNode* subtree_u = node_p->left_child;
379 AVLNode* subtree_v = node_q->left_child;
380 AVLNode* subtree_w = node_q->right_child;
383 node_q->left_child = node_p;
384 node_p->parent = node_q;
386 node_q->parent = parent_p;
387 if (parent_p !=
nullptr) {
388 if (parent_p->left_child == node_p) parent_p->left_child = node_q;
389 else parent_p->right_child = node_q;
392 node_p->right_child = subtree_v;
393 if (subtree_v !=
nullptr) subtree_v->parent = node_p;
396 const int height_u = subtree_u !=
nullptr ? subtree_u->height : 0;
397 const int height_v = subtree_v !=
nullptr ? subtree_v->height : 0;
398 const int height_w = subtree_w !=
nullptr ? subtree_w->height : 0;
399 node_p->height = std::max(height_u, height_v) + 1;
400 node_q->height = std::max(node_p->height, height_w) + 1;
407 template <
typename Val,
typename Cmp >
408 void AVLTree< Val, Cmp >::rebalanceTree_(AVLNode* node) {
409 AVLNode* top_node =
nullptr;
410 while (node !=
nullptr) {
411 const int left_height = node->left_child !=
nullptr ? node->left_child->height : 0;
412 const int right_height = node->right_child !=
nullptr ? node->right_child->height : 0;
413 node->height = 1 + std::max(left_height, right_height);
416 if (left_height > right_height + 1) {
418 AVLNode* left_child = node->left_child;
419 const int left_left_height
420 = left_child->left_child !=
nullptr ? left_child->left_child->height : 0;
421 const int left_right_height
422 = left_child->right_child !=
nullptr ? left_child->right_child->height : 0;
423 if (left_left_height < left_right_height) {
427 leftRotation_(left_child);
429 top_node = rightRotation_(node);
430 }
else if (right_height > left_height + 1) {
432 AVLNode* right_child = node->right_child;
433 const int right_left_height
434 = right_child->left_child !=
nullptr ? right_child->left_child->height : 0;
435 const int right_right_height
436 = right_child->right_child !=
nullptr ? right_child->right_child->height : 0;
437 if (right_left_height > right_right_height) {
441 rightRotation_(right_child);
443 top_node = leftRotation_(node);
449 node = top_node->parent;
454 root_node_ = top_node;
458 template <
typename Val,
typename Cmp >
459 const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::insert_(AVLNode* new_node) {
461 if (root_node_ ==
nullptr) {
462 new_node->parent =
nullptr;
463 root_node_ = new_node;
464 lowest_node_ = root_node_;
465 highest_node_ = root_node_;
467 return new_node->value;
472 const Val& value = new_node->value;
473 AVLNode* node = root_node_;
474 AVLNode* parent_node =
nullptr;
475 while (node !=
nullptr) {
477 node = cmp_(value, node->value) ? node->left_child : node->right_child;
481 new_node->parent = parent_node;
482 if (cmp_(new_node->value, parent_node->value)) {
483 parent_node->left_child = new_node;
484 if (lowest_node_ == parent_node) lowest_node_ = new_node;
486 parent_node->right_child = new_node;
487 if (highest_node_ == parent_node) highest_node_ = new_node;
492 rebalanceTree_(parent_node);
493 return new_node->value;
497 template <
typename Val,
typename Cmp >
498 INLINE
const typename AVLTree< Val, Cmp >::value_type&
499 AVLTree< Val, Cmp >::insert(
typename AVLTree< Val, Cmp >::value_type&& value) {
500 return insert_(
new AVLNode(std::move(value)));
504 template <
typename Val,
typename Cmp >
505 INLINE
const typename AVLTree< Val, Cmp >::value_type&
506 AVLTree< Val, Cmp >::insert(
const typename AVLTree< Val, Cmp >::value_type& val) {
507 return insert_(
new AVLNode(val));
511 template <
typename Val,
typename Cmp >
512 template <
typename... Args >
513 INLINE
const typename AVLTree< Val, Cmp >::value_type&
514 AVLTree< Val, Cmp >::emplace(Args&&... args) {
515 return insert_(
new AVLNode(AVLNode::Emplace::EMPLACE, std::forward< Args >(args)...));
519 template <
typename Val,
typename Cmp >
520 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::removeNodeFromTree_(AVLNode* node) {
522 if (node ==
nullptr)
return nullptr;
525 AVLNode* parent_node = node->parent;
530 if ((node->left_child !=
nullptr) && (node->right_child !=
nullptr)) {
532 AVLNode* successor = node->right_child;
533 while (successor->left_child !=
nullptr)
534 successor = successor->left_child;
538 AVLNode* successor_parent = successor->parent;
539 if (successor_parent->left_child == successor) {
541 successor_parent->left_child = successor->right_child;
544 successor_parent->right_child = successor->right_child;
546 if (successor->right_child !=
nullptr) successor->right_child->parent = successor_parent;
549 AVLNode *removed_node, *kept_node;
552 std::swap(node->value, successor->value);
555 removed_node = successor;
559 successor->parent = node->parent;
560 if (node->parent !=
nullptr) {
561 if (node->parent->right_child == node) node->parent->right_child = successor;
562 else node->parent->left_child = successor;
564 successor->right_child = node->right_child;
565 if (node->right_child !=
nullptr) node->right_child->parent = successor;
566 successor->left_child = node->left_child;
567 if (node->left_child !=
nullptr) node->left_child->parent = successor;
571 kept_node = successor;
581 rebalanceTree_(successor_parent != node ? successor_parent : kept_node);
588 if (highest_node_ == successor) { highest_node_ = kept_node; }
599 if (!safe_iterators_.empty()) {
600 AVLNode *new_predecessor =
nullptr, *new_successor =
nullptr;
601 for (
auto iter: safe_iterators_) {
602 if (iter->node_ == node) {
604 if (new_successor ==
nullptr) { new_successor = iter->nextNode_(kept_node); }
605 iter->node_ =
nullptr;
606 iter->next_node_ = new_successor;
607 }
else if (iter->node_ == successor) {
609 if (new_predecessor ==
nullptr) { new_predecessor = iter->precedingNode_(kept_node); }
610 iter->node_ = kept_node;
611 iter->preceding_node_ = new_predecessor;
612 }
else if (iter->next_node_ == node) {
613 iter->next_node_ = kept_node;
614 }
else if (iter->preceding_node_ == successor) {
615 iter->preceding_node_ = kept_node;
624 AVLNode* child = node->left_child ==
nullptr ? node->right_child : node->left_child;
632 if (!safe_iterators_.empty()) {
633 AVLNode *new_predecessor =
nullptr, *new_successor =
nullptr;
634 for (
auto iter: safe_iterators_) {
635 if (iter->node_ == node) {
636 iter->node_ =
nullptr;
637 }
else if (iter->preceding_node_ == node) {
638 if (new_predecessor ==
nullptr) { new_predecessor = iter->precedingNode_(node); }
639 iter->preceding_node_ = new_predecessor;
640 }
else if (iter->next_node_ == node) {
641 if (new_successor ==
nullptr) { new_successor = iter->nextNode_(node); }
642 iter->next_node_ = new_successor;
647 if (child ==
nullptr) {
649 if (parent_node !=
nullptr) {
650 if (parent_node->left_child == node) {
651 parent_node->left_child =
nullptr;
652 if (node == lowest_node_) lowest_node_ = parent_node;
654 parent_node->right_child =
nullptr;
655 if (node == highest_node_) highest_node_ = parent_node;
661 root_node_ =
nullptr;
662 lowest_node_ =
nullptr;
663 highest_node_ =
nullptr;
672 if (parent_node !=
nullptr) {
673 if (parent_node->left_child == node) {
674 parent_node->left_child = child;
675 child->parent = parent_node;
676 if (node == lowest_node_) {
682 lowest_node_ = child;
685 parent_node->right_child = child;
686 child->parent = parent_node;
687 if (node == highest_node_) highest_node_ = child;
693 child->parent =
nullptr;
695 if (node == lowest_node_) {
698 lowest_node_ = child;
699 while (lowest_node_->left_child !=
nullptr)
700 lowest_node_ = lowest_node_->left_child;
702 if (node == highest_node_) {
703 highest_node_ = child;
704 while (highest_node_->right_child !=
nullptr)
705 highest_node_ = highest_node_->right_child;
713 rebalanceTree_(parent_node);
718 template <
typename Val,
typename Cmp >
719 INLINE
void AVLTree< Val, Cmp >::erase_(AVLNode* node) {
720 AVLNode* removed_node = removeNodeFromTree_(node);
721 if (removed_node !=
nullptr)
delete removed_node;
725 template <
typename Val,
typename Cmp >
726 void AVLTree< Val, Cmp >::erase(
const value_type& val) {
728 AVLNode* node = root_node_;
729 while (node !=
nullptr) {
730 if (node->value == val)
break;
731 node = cmp_(val, node->value) ? node->left_child : node->right_child;
737 template <
typename Val,
typename Cmp >
738 INLINE
void AVLTree< Val, Cmp >::erase(
typename AVLTree< Val, Cmp >::iterator_safe& iter) {
743 template <
typename Val,
typename Cmp >
745 AVLTree< Val, Cmp >::erase(
typename AVLTree< Val, Cmp >::reverse_iterator_safe& iter) {
750 template <
typename Val,
typename Cmp >
751 void AVLTree< Val, Cmp >::clear() {
753 if (owns_nodes_) deleteSubtree_(root_node_);
754 root_node_ =
nullptr;
755 lowest_node_ =
nullptr;
756 highest_node_ =
nullptr;
757 nb_elements_ = Size(0);
760 for (
auto iter: safe_iterators_) {
761 iter->pointToEndRend_();
766 template <
typename Val,
typename Cmp >
767 INLINE
typename AVLTree< Val, Cmp >::iterator AVLTree< Val, Cmp >::begin()
const {
768 return AVLTreeIterator(*
this);
772 template <
typename Val,
typename Cmp >
773 constexpr const typename AVLTree< Val, Cmp >::iterator& AVLTree< Val, Cmp >::end()
const {
774 return *(
reinterpret_cast< const iterator*
>(_AVLTree_end_));
778 template <
typename Val,
typename Cmp >
779 INLINE
typename AVLTree< Val, Cmp >::reverse_iterator AVLTree< Val, Cmp >::rbegin()
const {
780 return AVLTreeReverseIterator(*
this,
true);
784 template <
typename Val,
typename Cmp >
785 constexpr const typename AVLTree< Val, Cmp >::reverse_iterator&
786 AVLTree< Val, Cmp >::rend()
const {
787 return *(
reinterpret_cast< const reverse_iterator*
>(_AVLTree_rend_));
791 template <
typename Val,
typename Cmp >
792 INLINE
typename AVLTree< Val, Cmp >::iterator_safe AVLTree< Val, Cmp >::beginSafe() {
793 return AVLTreeIteratorSafe(*
this);
797 template <
typename Val,
typename Cmp >
798 constexpr const typename AVLTree< Val, Cmp >::iterator_safe&
799 AVLTree< Val, Cmp >::endSafe()
const {
800 return *(
reinterpret_cast< const iterator_safe*
>(_AVLTree_end_safe_));
804 template <
typename Val,
typename Cmp >
805 INLINE
typename AVLTree< Val, Cmp >::reverse_iterator_safe AVLTree< Val, Cmp >::rbeginSafe() {
806 return AVLTreeReverseIteratorSafe(*
this,
true);
810 template <
typename Val,
typename Cmp >
811 constexpr const typename AVLTree< Val, Cmp >::reverse_iterator_safe&
812 AVLTree< Val, Cmp >::rendSafe()
const {
813 return *(
reinterpret_cast< const reverse_iterator_safe*
>(_AVLTree_rend_safe_));
817 template <
typename Val,
typename Cmp >
819 AVLTree< Val, Cmp >::insertIntoSafeList_(
typename AVLTree< Val, Cmp >::iterator_safe* iter) {
820 safe_iterators_.push_back(iter);
824 template <
typename Val,
typename Cmp >
826 AVLTree< Val, Cmp >::removeFromSafeList_(
typename AVLTree< Val, Cmp >::iterator_safe* iter) {
827 const Size len = safe_iterators_.size();
828 for (Size i = Size(0); i < len; ++i) {
829 if (safe_iterators_[i] == iter) {
830 safe_iterators_[i] = safe_iterators_[len - 1];
831 safe_iterators_.pop_back();
838 template <
typename Val,
typename Cmp >
839 std::string AVLTree< Val, Cmp >::toString()
const {
840 std::stringstream str;
843 for (
const auto& val: *
this) {
844 if (!first) str <<
" , ";
855 template <
typename Val,
typename Cmp >
856 typename AVLTreeIterator< Val, Cmp >::AVLNode*
857 AVLTreeIterator< Val, Cmp >::nextNode_(AVLNode* node)
const noexcept {
858 if (node !=
nullptr) {
861 if (node->right_child !=
nullptr) {
864 AVLNode* next_node = node->right_child;
865 while (next_node->left_child !=
nullptr)
866 next_node = next_node->left_child;
871 if (node == tree_->highest_node_) {
return nullptr; }
875 AVLNode* current_node = node;
876 AVLNode* next_node = node->parent;
878 while (next_node->right_child == current_node) {
879 current_node = next_node;
880 next_node = next_node->parent;
891 template <
typename Val,
typename Cmp >
892 typename AVLTreeIterator< Val, Cmp >::AVLNode*
893 AVLTreeIterator< Val, Cmp >::precedingNode_(AVLNode* node)
const noexcept {
894 if (node !=
nullptr) {
897 if (node->left_child !=
nullptr) {
900 AVLNode* next_node = node->left_child;
901 while (next_node->right_child !=
nullptr)
902 next_node = next_node->right_child;
907 if (node == tree_->lowest_node_) {
return nullptr; }
911 AVLNode* current_node = node;
912 AVLNode* next_node = node->parent;
914 while (next_node->left_child == current_node) {
915 current_node = next_node;
916 next_node = next_node->parent;
927 template <
typename Val,
typename Cmp >
928 INLINE AVLTreeIterator< Val, Cmp >::AVLTreeIterator(
const AVLTree< Val, Cmp >& tree,
929 const bool begin) noexcept :
930 tree_(
const_cast< AVLTree< Val, Cmp >*
>(&tree)),
931 node_(begin ? tree.lowest_node_ : tree.highest_node_) {
932 next_node_ = nextNode_(node_);
933 preceding_node_ = precedingNode_(node_);
935 GUM_CONSTRUCTOR(AVLTreeIterator)
939 template <
typename Val,
typename Cmp >
941 AVLTreeIterator< Val, Cmp >::AVLTreeIterator(
const AVLTreeIterator< Val, Cmp >& from) noexcept
943 tree_(from.tree_), node_(from.node_), next_node_(from.next_node_),
944 preceding_node_(from.preceding_node_) {
945 GUM_CONS_CPY(AVLTreeIterator)
949 template <
typename Val,
typename Cmp >
950 INLINE AVLTreeIterator< Val, Cmp >::AVLTreeIterator(AVLTreeIterator< Val, Cmp >&& from) noexcept :
951 tree_(from.tree_), node_(from.node_), next_node_(from.next_node_),
952 preceding_node_(from.preceding_node_) {
953 GUM_CONS_MOV(AVLTreeIterator)
957 template <
typename Val,
typename Cmp >
958 INLINE AVLTreeIterator< Val, Cmp >::~AVLTreeIterator() noexcept {
959 GUM_DESTRUCTOR(AVLTreeIterator);
963 template <
typename Val,
typename Cmp >
964 INLINE AVLTreeIterator< Val, Cmp >&
965 AVLTreeIterator< Val, Cmp >::operator=(
const AVLTreeIterator< Val, Cmp >& from)
noexcept {
968 next_node_ = from.next_node_;
969 preceding_node_ = from.preceding_node_;
974 template <
typename Val,
typename Cmp >
975 INLINE AVLTreeIterator< Val, Cmp >&
976 AVLTreeIterator< Val, Cmp >::operator=(AVLTreeIterator< Val, Cmp >&& from)
noexcept {
979 next_node_ = from.next_node_;
980 preceding_node_ = from.preceding_node_;
985 template <
typename Val,
typename Cmp >
987 AVLTreeIterator< Val, Cmp >::operator==(
const AVLTreeIterator< Val, Cmp >& from)
const {
997 return (node_ == from.node_) && (next_node_ == from.next_node_);
1001 template <
typename Val,
typename Cmp >
1003 AVLTreeIterator< Val, Cmp >::operator!=(
const AVLTreeIterator< Val, Cmp >& from)
const {
1005 return (node_ != from.node_) || (next_node_ != from.next_node_);
1009 template <
typename Val,
typename Cmp >
1010 INLINE AVLTreeIterator< Val, Cmp >& AVLTreeIterator< Val, Cmp >::operator++() noexcept {
1011 preceding_node_ = node_;
1013 next_node_ = nextNode_(node_);
1018 template <
typename Val,
typename Cmp >
1019 INLINE AVLTreeIterator< Val, Cmp >&
1020 AVLTreeIterator< Val, Cmp >::operator+=(
const Size k)
noexcept {
1021 for (Size i = 0; i < k; ++i) {
1022 AVLTreeIterator< Val, Cmp >::operator++();
1028 template <
typename Val,
typename Cmp >
1029 INLINE AVLTreeIterator< Val, Cmp >& AVLTreeIterator< Val, Cmp >::operator--() noexcept {
1031 node_ = preceding_node_;
1032 preceding_node_ = precedingNode_(node_);
1037 template <
typename Val,
typename Cmp >
1038 INLINE AVLTreeIterator< Val, Cmp >&
1039 AVLTreeIterator< Val, Cmp >::operator-=(
const Size k)
noexcept {
1040 for (Size i = 0; i < k; ++i) {
1041 AVLTreeIterator< Val, Cmp >::operator--();
1047 template <
typename Val,
typename Cmp >
1048 INLINE
void AVLTreeIterator< Val, Cmp >::unregisterTree_() noexcept {
1051 preceding_node_ =
nullptr;
1052 next_node_ =
nullptr;
1056 template <
typename Val,
typename Cmp >
1057 INLINE
void AVLTreeIterator< Val, Cmp >::pointToEndRend_() noexcept {
1059 preceding_node_ =
nullptr;
1060 next_node_ =
nullptr;
1064 template <
typename Val,
typename Cmp >
1065 INLINE
typename AVLTreeIterator< Val, Cmp >::const_reference
1066 AVLTreeIterator< Val, Cmp >::operator*()
const {
1067 if (node_ !=
nullptr)
return node_->value;
1069 if ((next_node_ ==
nullptr) || (preceding_node_ ==
nullptr)) {
1080 template <
typename Val,
typename Cmp >
1081 INLINE AVLTreeIteratorSafe< Val, Cmp >::AVLTreeIteratorSafe(AVLTree< Val, Cmp >& tree,
1082 const bool rbegin) :
1083 AVLTreeIterator< Val,
Cmp >(tree, rbegin) {
1084 tree.insertIntoSafeList_(
this);
1085 GUM_CONSTRUCTOR(AVLTreeIteratorSafe)
1089 template <
typename Val,
typename Cmp >
1090 INLINE AVLTreeIteratorSafe< Val, Cmp >::AVLTreeIteratorSafe(
1091 const AVLTreeIteratorSafe< Val, Cmp >& from) : AVLTreeIterator< Val,
Cmp >(from) {
1092 if (this->tree_ !=
nullptr) this->tree_->insertIntoSafeList_(
this);
1093 GUM_CONS_CPY(AVLTreeIteratorSafe)
1097 template <
typename Val,
typename Cmp >
1099 AVLTreeIteratorSafe< Val, Cmp >::AVLTreeIteratorSafe(AVLTreeIteratorSafe< Val, Cmp >&& from) :
1100 AVLTreeIterator< Val,
Cmp >(
std::move(from)) {
1101 if (this->tree_ !=
nullptr) {
1102 this->tree_->insertIntoSafeList_(
this);
1103 this->tree_->removeFromSafeList_(&from);
1105 GUM_CONS_MOV(AVLTreeIteratorSafe)
1109 template <
typename Val,
typename Cmp >
1110 INLINE AVLTreeIteratorSafe< Val, Cmp >::~AVLTreeIteratorSafe() noexcept {
1111 if (this->tree_ !=
nullptr) { this->tree_->removeFromSafeList_(
this); }
1112 GUM_DESTRUCTOR(AVLTreeIteratorSafe)
1116 template <
typename Val,
typename Cmp >
1117 INLINE AVLTreeIteratorSafe< Val, Cmp >&
1118 AVLTreeIteratorSafe< Val, Cmp >::operator=(
const AVLTreeIteratorSafe< Val, Cmp >& from) {
1119 if (
this != &from) {
1120 if (from.tree_ != this->tree_) {
1121 if (this->tree_ !=
nullptr) { this->tree_->removeFromSafeList_(
this); }
1122 if (from.tree_ !=
nullptr) { from.tree_->insertIntoSafeList_(
this); }
1124 AVLTreeIterator< Val, Cmp >::operator=(from);
1130 template <
typename Val,
typename Cmp >
1131 INLINE AVLTreeIteratorSafe< Val, Cmp >&
1132 AVLTreeIteratorSafe< Val, Cmp >::operator=(AVLTreeIteratorSafe< Val, Cmp >&& from) {
1133 if (
this != &from) {
1134 if (from.tree_ != this->tree_) {
1135 if (this->tree_ !=
nullptr) { this->tree_->removeFromSafeList_(
this); }
1136 if (from.tree_ !=
nullptr) { from.tree_->insertIntoSafeList_(
this); }
1138 AVLTreeIterator< Val, Cmp >::operator=(std::move(from));
1144 template <
typename Val,
typename Cmp >
1145 INLINE
bool AVLTreeIteratorSafe< Val, Cmp >::operator==(
1146 const AVLTreeIteratorSafe< Val, Cmp >& from)
const {
1147 return AVLTreeIterator< Val, Cmp >::operator==(from);
1151 template <
typename Val,
typename Cmp >
1152 INLINE
bool AVLTreeIteratorSafe< Val, Cmp >::operator!=(
1153 const AVLTreeIteratorSafe< Val, Cmp >& from)
const {
1154 return AVLTreeIterator< Val, Cmp >::operator!=(from);
1158 template <
typename Val,
typename Cmp >
1159 INLINE AVLTreeIteratorSafe< Val, Cmp >& AVLTreeIteratorSafe< Val, Cmp >::operator++() noexcept {
1160 AVLTreeIterator< Val, Cmp >::operator++();
1165 template <
typename Val,
typename Cmp >
1166 INLINE AVLTreeIteratorSafe< Val, Cmp >&
1167 AVLTreeIteratorSafe< Val, Cmp >::operator+=(
const Size k)
noexcept {
1168 AVLTreeIterator< Val, Cmp >::operator+=(k);
1173 template <
typename Val,
typename Cmp >
1174 INLINE AVLTreeIteratorSafe< Val, Cmp >& AVLTreeIteratorSafe< Val, Cmp >::operator--() noexcept {
1175 AVLTreeIterator< Val, Cmp >::operator--();
1180 template <
typename Val,
typename Cmp >
1181 INLINE AVLTreeIteratorSafe< Val, Cmp >&
1182 AVLTreeIteratorSafe< Val, Cmp >::operator-=(
const Size k)
noexcept {
1183 AVLTreeIterator< Val, Cmp >::operator-=(k);
1190 template <
typename Val,
typename Cmp >
1191 INLINE AVLTreeReverseIterator< Val, Cmp >::AVLTreeReverseIterator(
const AVLTree< Val, Cmp >& tree,
1192 const bool rbegin) noexcept :
1193 AVLTreeIterator< Val, Cmp >(tree, !rbegin) {
1194 GUM_CONSTRUCTOR(AVLTreeReverseIterator)
1198 template <
typename Val,
typename Cmp >
1199 INLINE AVLTreeReverseIterator< Val, Cmp >::AVLTreeReverseIterator(
1200 const AVLTreeReverseIterator< Val, Cmp >& from) noexcept : AVLTreeIterator< Val, Cmp >(from) {
1201 GUM_CONS_CPY(AVLTreeReverseIterator)
1205 template <
typename Val,
typename Cmp >
1206 INLINE AVLTreeReverseIterator< Val, Cmp >::AVLTreeReverseIterator(
1207 AVLTreeReverseIterator< Val, Cmp >&& from) noexcept :
1208 AVLTreeIterator< Val, Cmp >(std::move(from)) {
1209 GUM_CONS_MOV(AVLTreeReverseIterator)
1213 template <
typename Val,
typename Cmp >
1214 INLINE AVLTreeReverseIterator< Val, Cmp >::~AVLTreeReverseIterator() noexcept {
1215 GUM_DESTRUCTOR(AVLTreeReverseIterator)
1219 template <
typename Val,
typename Cmp >
1220 INLINE AVLTreeReverseIterator< Val, Cmp >& AVLTreeReverseIterator< Val, Cmp >::operator=(
1221 const AVLTreeReverseIterator< Val, Cmp >& from)
noexcept {
1222 AVLTreeIterator< Val, Cmp >::operator=(from);
1227 template <
typename Val,
typename Cmp >
1228 INLINE AVLTreeReverseIterator< Val, Cmp >& AVLTreeReverseIterator< Val, Cmp >::operator=(
1229 AVLTreeReverseIterator< Val, Cmp >&& from)
noexcept {
1230 AVLTreeIterator< Val, Cmp >::operator=(std::move(from));
1235 template <
typename Val,
typename Cmp >
1236 INLINE
bool AVLTreeReverseIterator< Val, Cmp >::operator==(
1237 const AVLTreeReverseIterator< Val, Cmp >& from)
const {
1247 return (this->node_ == from.node_) && (this->preceding_node_ == from.preceding_node_);
1251 template <
typename Val,
typename Cmp >
1252 INLINE
bool AVLTreeReverseIterator< Val, Cmp >::operator!=(
1253 const AVLTreeReverseIterator< Val, Cmp >& from)
const {
1255 return (this->node_ != from.node_) || (this->preceding_node_ != from.preceding_node_);
1259 template <
typename Val,
typename Cmp >
1260 INLINE AVLTreeReverseIterator< Val, Cmp >&
1261 AVLTreeReverseIterator< Val, Cmp >::operator++() noexcept {
1262 AVLTreeIterator< Val, Cmp >::operator--();
1267 template <
typename Val,
typename Cmp >
1268 INLINE AVLTreeReverseIterator< Val, Cmp >&
1269 AVLTreeReverseIterator< Val, Cmp >::operator+=(
const Size k)
noexcept {
1270 for (Size i = 0; i < k; ++i) {
1271 AVLTreeReverseIterator< Val, Cmp >::operator++();
1277 template <
typename Val,
typename Cmp >
1278 INLINE AVLTreeReverseIterator< Val, Cmp >&
1279 AVLTreeReverseIterator< Val, Cmp >::operator--() noexcept {
1280 AVLTreeIterator< Val, Cmp >::operator++();
1285 template <
typename Val,
typename Cmp >
1286 INLINE AVLTreeReverseIterator< Val, Cmp >&
1287 AVLTreeReverseIterator< Val, Cmp >::operator-=(
const Size k)
noexcept {
1288 for (Size i = 0; i < k; ++i) {
1289 AVLTreeReverseIterator< Val, Cmp >::operator--();
1297 template <
typename Val,
typename Cmp >
1299 AVLTreeReverseIteratorSafe< Val, Cmp >::AVLTreeReverseIteratorSafe(AVLTree< Val, Cmp >& tree,
1300 const bool rbegin) :
1301 AVLTreeIteratorSafe< Val,
Cmp >(tree, !rbegin) {
1302 GUM_CONSTRUCTOR(AVLTreeReverseIteratorSafe)
1306 template <
typename Val,
typename Cmp >
1307 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >::AVLTreeReverseIteratorSafe(
1308 const AVLTreeReverseIteratorSafe< Val, Cmp >& from) : AVLTreeIteratorSafe< Val,
Cmp >(from) {
1309 GUM_CONS_CPY(AVLTreeReverseIteratorSafe)
1313 template <
typename Val,
typename Cmp >
1314 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >::AVLTreeReverseIteratorSafe(
1315 AVLTreeReverseIteratorSafe< Val, Cmp >&& from) :
1316 AVLTreeIteratorSafe< Val,
Cmp >(
std::move(from)) {
1317 GUM_CONS_MOV(AVLTreeReverseIteratorSafe)
1321 template <
typename Val,
typename Cmp >
1322 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >::~AVLTreeReverseIteratorSafe() noexcept {
1323 GUM_DESTRUCTOR(AVLTreeReverseIteratorSafe)
1327 template <
typename Val,
typename Cmp >
1328 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >& AVLTreeReverseIteratorSafe< Val, Cmp >::operator=(
1329 const AVLTreeReverseIteratorSafe< Val, Cmp >& from) {
1330 AVLTreeIteratorSafe< Val, Cmp >::operator=(from);
1335 template <
typename Val,
typename Cmp >
1336 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >& AVLTreeReverseIteratorSafe< Val, Cmp >::operator=(
1337 AVLTreeReverseIteratorSafe< Val, Cmp >&& from) {
1338 AVLTreeIteratorSafe< Val, Cmp >::operator=(std::move(from));
1343 template <
typename Val,
typename Cmp >
1344 INLINE
bool AVLTreeReverseIteratorSafe< Val, Cmp >::operator==(
1345 const AVLTreeReverseIteratorSafe< Val, Cmp >& from)
const {
1355 return (this->node_ == from.node_) && (this->preceding_node_ == from.preceding_node_);
1359 template <
typename Val,
typename Cmp >
1360 INLINE
bool AVLTreeReverseIteratorSafe< Val, Cmp >::operator!=(
1361 const AVLTreeReverseIteratorSafe< Val, Cmp >& from)
const {
1363 return (this->node_ != from.node_) || (this->preceding_node_ != from.preceding_node_);
1367 template <
typename Val,
typename Cmp >
1368 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >&
1369 AVLTreeReverseIteratorSafe< Val, Cmp >::operator++() noexcept {
1370 AVLTreeIteratorSafe< Val, Cmp >::operator--();
1375 template <
typename Val,
typename Cmp >
1376 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >&
1377 AVLTreeReverseIteratorSafe< Val, Cmp >::operator+=(
const Size k)
noexcept {
1378 for (Size i = 0; i < k; ++i) {
1379 AVLTreeReverseIteratorSafe< Val, Cmp >::operator++();
1385 template <
typename Val,
typename Cmp >
1386 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >&
1387 AVLTreeReverseIteratorSafe< Val, Cmp >::operator--() noexcept {
1388 AVLTreeIteratorSafe< Val, Cmp >::operator++();
1393 template <
typename Val,
typename Cmp >
1394 INLINE AVLTreeReverseIteratorSafe< Val, Cmp >&
1395 AVLTreeReverseIteratorSafe< Val, Cmp >::operator-=(
const Size k)
noexcept {
1396 for (Size i = 0; i < k; ++i) {
1397 AVLTreeReverseIteratorSafe< Val, Cmp >::operator--();
AVLTree(const Cmp &compare=Cmp())
Basic constructor.
AVLNode * lowestNode_() const noexcept
returns the node containing the lowest element of the tree
AVLTreeNode< Val > AVLNode
Types for STL compliance.
AVLNode * highestNode_() const noexcept
returns the node containing the highest element of the tree
static AVLNode * copySubtree_(const AVLNode *from_node, AVLNode *new_parent)
copies recursively a subtree of the AVL tree
static void deleteSubtree_(AVLNode *subtree_root_node)
deletes recursively a subtree of the AVL tree
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
#define GUM_ERROR(type, msg)
gum is the global namespace for all aGrUM entities