53#ifndef DOXYGEN_SHOULD_SKIP_THIS
61 template <
typename Val >
62 AVLTreeNode< Val >::AVLTreeNode(
const Val& val) : value(val) {}
64 template <
typename Val >
65 AVLTreeNode< Val >::AVLTreeNode(Val&& val) noexcept : value(std::move(val)) {}
67 template <
typename Val >
68 template <
typename... Args >
69 AVLTreeNode< Val >::AVLTreeNode(
const Emplace& emplace, Args&&... args) :
70 value(
std::forward< Args >(args)...) {}
72 template <
typename Val >
73 AVLTreeNode< Val >::AVLTreeNode(
const AVLTreeNode< Val >& from) :
74 parent(from.parent), left_child(from.left_child), right_child(from.right_child),
75 height(from.height), value(from.value) {}
77 template <
typename Val >
78 AVLTreeNode< Val >::AVLTreeNode(AVLTreeNode< Val >&& from) noexcept :
79 parent(from.parent), left_child(from.left_child), right_child(from.right_child),
80 height(from.height), value(std::move(from.value)) {}
82 template <
typename Val >
83 AVLTreeNode< Val >::~AVLTreeNode() {
84 GUM_DESTRUCTOR(AVLTreeNode);
87 template <
typename Val >
88 bool AVLTreeNode< Val >::operator==(
const AVLTreeNode< Val >& from)
const {
89 return value == from.value;
92 template <
typename Val >
93 std::ostream&
operator<<(std::ostream& stream,
const AVLTreeNode< Val >& node) {
94 return stream <<
'<' << node.value <<
'>';
98 template <
typename Val,
typename Cmp >
99 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::copySubtree_(
const AVLNode* from_node,
100 AVLNode* new_parent) {
101 if (from_node ==
nullptr)
return nullptr;
103 AVLNode* new_node =
nullptr;
104 AVLNode* new_left_child =
nullptr;
105 AVLNode* new_right_child;
107 new_node =
new AVLNode(from_node->value);
109 new_left_child = copySubtree_(from_node->left_child, new_node);
110 new_right_child = copySubtree_(from_node->right_child, new_node);
112 new_node->parent = new_parent;
113 new_node->left_child = new_left_child;
114 new_node->right_child = new_right_child;
115 new_node->height = from_node->height;
119 if (new_node !=
nullptr)
delete new_node;
120 if (new_left_child !=
nullptr) deleteSubtree_(new_left_child);
128 template <
typename Val,
typename Cmp >
129 void AVLTree< Val, Cmp >::deleteSubtree_(AVLNode* subtree_root_node) {
130 if (subtree_root_node ==
nullptr)
return;
132 deleteSubtree_(subtree_root_node->left_child);
133 deleteSubtree_(subtree_root_node->right_child);
134 delete subtree_root_node;
138 template <
typename Val,
typename Cmp >
139 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::lowestNode_() const noexcept {
140 if (root_node_ ==
nullptr)
return nullptr;
142 AVLNode* node = root_node_;
143 while (node->left_child !=
nullptr)
144 node = node->left_child;
150 template <
typename Val,
typename Cmp >
151 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::highestNode_() const noexcept {
152 if (root_node_ ==
nullptr)
return nullptr;
154 AVLNode* node = root_node_;
155 while (node->right_child !=
nullptr)
156 node = node->right_child;
162 template <
typename Val,
typename Cmp >
163 AVLTree< Val, Cmp >::AVLTree(
const Cmp& compare) : cmp_(compare) {
165 GUM_CONSTRUCTOR(AVLTree);
169 template <
typename Val,
typename Cmp >
170 AVLTree< Val, Cmp >::AVLTree(std::initializer_list< Val > list) {
172 for (
const auto& val: list)
176 deleteSubtree_(root_node_);
178 root_node_ =
nullptr;
179 lowest_node_ =
nullptr;
180 highest_node_ =
nullptr;
181 nb_elements_ = Size(0);
187 GUM_CONSTRUCTOR(AVLTree);
191 template <
typename Val,
typename Cmp >
192 AVLTree< Val, Cmp >::AVLTree(
const AVLTree< Val, Cmp >& from) :
193 nb_elements_(from.nb_elements_), cmp_(from.cmp_) {
194 root_node_ = copySubtree_(from.root_node_,
nullptr);
195 lowest_node_ = lowestNode_();
196 highest_node_ = highestNode_();
199 GUM_CONS_CPY(AVLTree);
203 template <
typename Val,
typename Cmp >
204 AVLTree< Val, Cmp >::AVLTree(AVLTree< Val, Cmp >&& from) noexcept :
205 root_node_(from.root_node_), lowest_node_(from.lowest_node_),
206 highest_node_(from.highest_node_), nb_elements_(from.nb_elements_),
207 owns_nodes_(from.owns_nodes_), cmp_(std::move(from.cmp_)),
208 safe_iterators_(std::move(from.safe_iterators_)) {
209 from.root_node_ =
nullptr;
210 from.lowest_node_ =
nullptr;
211 from.highest_node_ =
nullptr;
214 for (
auto iter: safe_iterators_) {
219 GUM_CONS_CPY(AVLTree);
223 template <
typename Val,
typename Cmp >
224 AVLTree< Val, Cmp >::~AVLTree() {
225 if (owns_nodes_) deleteSubtree_(root_node_);
228 for (
auto iter: safe_iterators_) {
229 iter->unregisterTree_();
233 GUM_DESTRUCTOR(AVLTree);
237 template <
typename Val,
typename Cmp >
238 AVLTree< Val, Cmp >& AVLTree< Val, Cmp >::operator=(
const AVLTree< Val, Cmp >& from) {
242 "It is forbidden to copy an AVLTree into a tree that does not own its nodes")
245 if (owns_nodes_) deleteSubtree_(root_node_);
248 for (
auto iter: safe_iterators_) {
249 iter->pointToEndRend_();
253 root_node_ = copySubtree_(from.root_node_,
nullptr);
254 lowest_node_ = lowestNode_();
255 highest_node_ = highestNode_();
256 nb_elements_ = from.nb_elements_;
259 root_node_ =
nullptr;
260 lowest_node_ =
nullptr;
261 highest_node_ =
nullptr;
262 nb_elements_ = Size(0);
272 template <
typename Val,
typename Cmp >
273 AVLTree< Val, Cmp >& AVLTree< Val, Cmp >::operator=(AVLTree< Val, Cmp >&& from) {
277 "It is forbidden to move an AVLTree into a tree that does not own its nodes")
280 if (owns_nodes_) deleteSubtree_(root_node_);
283 for (
auto iter: safe_iterators_) {
284 iter->pointToEndRend_();
287 root_node_ = from.root_node_;
288 lowest_node_ = from.lowest_node_;
289 highest_node_ = from.highest_node_;
290 nb_elements_ = from.nb_elements_;
291 cmp_ = std::move(from.cmp_);
294 if (safe_iterators_.empty()) {
295 safe_iterators_ = std::move(from.safe_iterators_);
296 for (
auto iter: safe_iterators_) {
300 for (
auto from_iter: from.safe_iterators_) {
301 safe_iterators_.push_back(from_iter);
302 safe_iterators_.back()->tree_ =
this;
303 from.safe_iterators_.clear();
307 from.root_node_ =
nullptr;
308 from.lowest_node_ =
nullptr;
309 from.highest_node_ =
nullptr;
314 template <
typename Val,
typename Cmp >
315 Size AVLTree< Val, Cmp >::size() const noexcept {
320 template <
typename Val,
typename Cmp >
321 bool AVLTree< Val, Cmp >::empty() const noexcept {
322 return nb_elements_ == Size(0);
326 template <
typename Val,
typename Cmp >
327 bool AVLTree< Val, Cmp >::contains(
const value_type& val)
const {
328 AVLNode* node = root_node_;
329 while (node !=
nullptr) {
330 if (node->value == val)
return true;
331 node = cmp_(val, node->value) ? node->left_child : node->right_child;
337 template <
typename Val,
typename Cmp >
338 bool AVLTree< Val, Cmp >::exists(
const value_type& val)
const {
343 template <
typename Val,
typename Cmp >
344 const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::highestValue()
const {
345 if (highest_node_ ==
nullptr) {
348 return highest_node_->value;
352 template <
typename Val,
typename Cmp >
353 const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::lowestValue()
const {
354 if (lowest_node_ ==
nullptr) {
GUM_ERROR(
NotFound,
"an empty AVL tree has no lowest element"); }
355 return lowest_node_->value;
371 template <
typename Val,
typename Cmp >
372 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::rightRotation_(AVLNode* node_q) {
373 AVLNode* node_p = node_q->left_child;
374 AVLNode* parent_q = node_q->parent;
375 AVLNode* subtree_u = node_p->left_child;
376 AVLNode* subtree_v = node_p->right_child;
377 AVLNode* subtree_w = node_q->right_child;
380 node_p->right_child = node_q;
381 node_q->parent = node_p;
383 node_p->parent = parent_q;
384 if (parent_q !=
nullptr) {
385 if (parent_q->left_child == node_q) parent_q->left_child = node_p;
386 else parent_q->right_child = node_p;
388 node_q->left_child = subtree_v;
389 if (subtree_v !=
nullptr) subtree_v->parent = node_q;
392 const int height_u = subtree_u !=
nullptr ? subtree_u->height : 0;
393 const int height_v = subtree_v !=
nullptr ? subtree_v->height : 0;
394 const int height_w = subtree_w !=
nullptr ? subtree_w->height : 0;
395 node_q->height = std::max(height_v, height_w) + 1;
396 node_p->height = std::max(node_q->height, height_u) + 1;
415 template <
typename Val,
typename Cmp >
416 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::leftRotation_(AVLNode* node_p) {
417 AVLNode* node_q = node_p->right_child;
418 AVLNode* parent_p = node_p->parent;
419 AVLNode* subtree_u = node_p->left_child;
420 AVLNode* subtree_v = node_q->left_child;
421 AVLNode* subtree_w = node_q->right_child;
424 node_q->left_child = node_p;
425 node_p->parent = node_q;
427 node_q->parent = parent_p;
428 if (parent_p !=
nullptr) {
429 if (parent_p->left_child == node_p) parent_p->left_child = node_q;
430 else parent_p->right_child = node_q;
433 node_p->right_child = subtree_v;
434 if (subtree_v !=
nullptr) subtree_v->parent = node_p;
437 const int height_u = subtree_u !=
nullptr ? subtree_u->height : 0;
438 const int height_v = subtree_v !=
nullptr ? subtree_v->height : 0;
439 const int height_w = subtree_w !=
nullptr ? subtree_w->height : 0;
440 node_p->height = std::max(height_u, height_v) + 1;
441 node_q->height = std::max(node_p->height, height_w) + 1;
448 template <
typename Val,
typename Cmp >
449 void AVLTree< Val, Cmp >::rebalanceTree_(AVLNode* node) {
450 AVLNode* top_node =
nullptr;
451 while (node !=
nullptr) {
452 const int left_height = node->left_child !=
nullptr ? node->left_child->height : 0;
453 const int right_height = node->right_child !=
nullptr ? node->right_child->height : 0;
454 node->height = 1 + std::max(left_height, right_height);
457 if (left_height > right_height + 1) {
459 AVLNode* left_child = node->left_child;
460 const int left_left_height
461 = left_child->left_child !=
nullptr ? left_child->left_child->height : 0;
462 const int left_right_height
463 = left_child->right_child !=
nullptr ? left_child->right_child->height : 0;
464 if (left_left_height < left_right_height) {
468 leftRotation_(left_child);
470 top_node = rightRotation_(node);
471 }
else if (right_height > left_height + 1) {
473 AVLNode* right_child = node->right_child;
474 const int right_left_height
475 = right_child->left_child !=
nullptr ? right_child->left_child->height : 0;
476 const int right_right_height
477 = right_child->right_child !=
nullptr ? right_child->right_child->height : 0;
478 if (right_left_height > right_right_height) {
482 rightRotation_(right_child);
484 top_node = leftRotation_(node);
490 node = top_node->parent;
495 root_node_ = top_node;
499 template <
typename Val,
typename Cmp >
500 const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::insert_(AVLNode* new_node) {
502 if (root_node_ ==
nullptr) {
503 new_node->parent =
nullptr;
504 root_node_ = new_node;
505 lowest_node_ = root_node_;
506 highest_node_ = root_node_;
508 return new_node->value;
513 const Val& value = new_node->value;
514 AVLNode* node = root_node_;
515 AVLNode* parent_node =
nullptr;
516 while (node !=
nullptr) {
518 node = cmp_(value, node->value) ? node->left_child : node->right_child;
522 new_node->parent = parent_node;
523 if (cmp_(new_node->value, parent_node->value)) {
524 parent_node->left_child = new_node;
525 if (lowest_node_ == parent_node) lowest_node_ = new_node;
527 parent_node->right_child = new_node;
528 if (highest_node_ == parent_node) highest_node_ = new_node;
533 rebalanceTree_(parent_node);
534 return new_node->value;
538 template <
typename Val,
typename Cmp >
539 const typename AVLTree< Val, Cmp >::value_type&
540 AVLTree< Val, Cmp >::insert(
typename AVLTree< Val, Cmp >::value_type&& value) {
541 return insert_(
new AVLNode(std::move(value)));
545 template <
typename Val,
typename Cmp >
546 const typename AVLTree< Val, Cmp >::value_type&
547 AVLTree< Val, Cmp >::insert(
const typename AVLTree< Val, Cmp >::value_type& val) {
548 return insert_(
new AVLNode(val));
552 template <
typename Val,
typename Cmp >
553 template <
typename... Args >
554 const typename AVLTree< Val, Cmp >::value_type& AVLTree< Val, Cmp >::emplace(Args&&... args) {
555 return insert_(
new AVLNode(AVLNode::Emplace::EMPLACE, std::forward< Args >(args)...));
559 template <
typename Val,
typename Cmp >
560 typename AVLTree< Val, Cmp >::AVLNode* AVLTree< Val, Cmp >::removeNodeFromTree_(AVLNode* node) {
562 if (node ==
nullptr)
return nullptr;
565 AVLNode* parent_node = node->parent;
570 if ((node->left_child !=
nullptr) && (node->right_child !=
nullptr)) {
572 AVLNode* successor = node->right_child;
573 while (successor->left_child !=
nullptr)
574 successor = successor->left_child;
578 AVLNode* successor_parent = successor->parent;
579 if (successor_parent->left_child == successor) {
581 successor_parent->left_child = successor->right_child;
584 successor_parent->right_child = successor->right_child;
586 if (successor->right_child !=
nullptr) successor->right_child->parent = successor_parent;
589 AVLNode *removed_node, *kept_node;
592 std::swap(node->value, successor->value);
595 removed_node = successor;
599 successor->parent = node->parent;
600 if (node->parent !=
nullptr) {
601 if (node->parent->right_child == node) node->parent->right_child = successor;
602 else node->parent->left_child = successor;
604 successor->right_child = node->right_child;
605 if (node->right_child !=
nullptr) node->right_child->parent = successor;
606 successor->left_child = node->left_child;
607 if (node->left_child !=
nullptr) node->left_child->parent = successor;
611 kept_node = successor;
621 rebalanceTree_(successor_parent != node ? successor_parent : kept_node);
628 if (highest_node_ == successor) { highest_node_ = kept_node; }
639 if (!safe_iterators_.empty()) {
640 AVLNode *new_predecessor =
nullptr, *new_successor =
nullptr;
641 for (
auto iter: safe_iterators_) {
642 if (iter->node_ == node) {
644 if (new_successor ==
nullptr) { new_successor = iter->nextNode_(kept_node); }
645 iter->node_ =
nullptr;
646 iter->next_node_ = new_successor;
647 }
else if (iter->node_ == successor) {
649 if (new_predecessor ==
nullptr) { new_predecessor = iter->precedingNode_(kept_node); }
650 iter->node_ = kept_node;
651 iter->preceding_node_ = new_predecessor;
652 }
else if (iter->next_node_ == node) {
653 iter->next_node_ = kept_node;
654 }
else if (iter->preceding_node_ == successor) {
655 iter->preceding_node_ = kept_node;
664 AVLNode* child = node->left_child ==
nullptr ? node->right_child : node->left_child;
672 if (!safe_iterators_.empty()) {
673 AVLNode *new_predecessor =
nullptr, *new_successor =
nullptr;
674 for (
auto iter: safe_iterators_) {
675 if (iter->node_ == node) {
676 iter->node_ =
nullptr;
677 }
else if (iter->preceding_node_ == node) {
678 if (new_predecessor ==
nullptr) { new_predecessor = iter->precedingNode_(node); }
679 iter->preceding_node_ = new_predecessor;
680 }
else if (iter->next_node_ == node) {
681 if (new_successor ==
nullptr) { new_successor = iter->nextNode_(node); }
682 iter->next_node_ = new_successor;
687 if (child ==
nullptr) {
689 if (parent_node !=
nullptr) {
690 if (parent_node->left_child == node) {
691 parent_node->left_child =
nullptr;
692 if (node == lowest_node_) lowest_node_ = parent_node;
694 parent_node->right_child =
nullptr;
695 if (node == highest_node_) highest_node_ = parent_node;
701 root_node_ =
nullptr;
702 lowest_node_ =
nullptr;
703 highest_node_ =
nullptr;
712 if (parent_node !=
nullptr) {
713 if (parent_node->left_child == node) {
714 parent_node->left_child = child;
715 child->parent = parent_node;
716 if (node == lowest_node_) {
722 lowest_node_ = child;
725 parent_node->right_child = child;
726 child->parent = parent_node;
727 if (node == highest_node_) highest_node_ = child;
733 child->parent =
nullptr;
735 if (node == lowest_node_) {
738 lowest_node_ = child;
739 while (lowest_node_->left_child !=
nullptr)
740 lowest_node_ = lowest_node_->left_child;
742 if (node == highest_node_) {
743 highest_node_ = child;
744 while (highest_node_->right_child !=
nullptr)
745 highest_node_ = highest_node_->right_child;
753 rebalanceTree_(parent_node);
758 template <
typename Val,
typename Cmp >
759 void AVLTree< Val, Cmp >::erase_(AVLNode* node) {
760 AVLNode* removed_node = removeNodeFromTree_(node);
761 if (removed_node !=
nullptr)
delete removed_node;
765 template <
typename Val,
typename Cmp >
766 void AVLTree< Val, Cmp >::erase(
const value_type& val) {
768 AVLNode* node = root_node_;
769 while (node !=
nullptr) {
770 if (node->value == val)
break;
771 node = cmp_(val, node->value) ? node->left_child : node->right_child;
777 template <
typename Val,
typename Cmp >
778 void AVLTree< Val, Cmp >::erase(
typename AVLTree< Val, Cmp >::iterator_safe& iter) {
783 template <
typename Val,
typename Cmp >
784 void AVLTree< Val, Cmp >::erase(
typename AVLTree< Val, Cmp >::reverse_iterator_safe& iter) {
789 template <
typename Val,
typename Cmp >
790 void AVLTree< Val, Cmp >::clear() {
792 if (owns_nodes_) deleteSubtree_(root_node_);
793 root_node_ =
nullptr;
794 lowest_node_ =
nullptr;
795 highest_node_ =
nullptr;
796 nb_elements_ = Size(0);
799 for (
auto iter: safe_iterators_) {
800 iter->pointToEndRend_();
805 template <
typename Val,
typename Cmp >
806 typename AVLTree< Val, Cmp >::iterator AVLTree< Val, Cmp >::begin()
const {
807 return AVLTreeIterator(*
this);
811 template <
typename Val,
typename Cmp >
812 constexpr const typename AVLTree< Val, Cmp >::iterator& AVLTree< Val, Cmp >::end()
const {
813 return *(
reinterpret_cast< const iterator*
>(_AVLTree_end_));
817 template <
typename Val,
typename Cmp >
818 typename AVLTree< Val, Cmp >::reverse_iterator AVLTree< Val, Cmp >::rbegin()
const {
819 return AVLTreeReverseIterator(*
this,
true);
823 template <
typename Val,
typename Cmp >
824 constexpr const typename AVLTree< Val, Cmp >::reverse_iterator&
825 AVLTree< Val, Cmp >::rend()
const {
826 return *(
reinterpret_cast< const reverse_iterator*
>(_AVLTree_rend_));
830 template <
typename Val,
typename Cmp >
831 typename AVLTree< Val, Cmp >::iterator_safe AVLTree< Val, Cmp >::beginSafe() {
832 return AVLTreeIteratorSafe(*
this);
836 template <
typename Val,
typename Cmp >
837 constexpr const typename AVLTree< Val, Cmp >::iterator_safe&
838 AVLTree< Val, Cmp >::endSafe()
const {
839 return *(
reinterpret_cast< const iterator_safe*
>(_AVLTree_end_safe_));
843 template <
typename Val,
typename Cmp >
844 typename AVLTree< Val, Cmp >::reverse_iterator_safe AVLTree< Val, Cmp >::rbeginSafe() {
845 return AVLTreeReverseIteratorSafe(*
this,
true);
849 template <
typename Val,
typename Cmp >
850 constexpr const typename AVLTree< Val, Cmp >::reverse_iterator_safe&
851 AVLTree< Val, Cmp >::rendSafe()
const {
852 return *(
reinterpret_cast< const reverse_iterator_safe*
>(_AVLTree_rend_safe_));
856 template <
typename Val,
typename Cmp >
857 void AVLTree< Val, Cmp >::insertIntoSafeList_(
typename AVLTree< Val, Cmp >::iterator_safe* iter) {
858 safe_iterators_.push_back(iter);
862 template <
typename Val,
typename Cmp >
863 void AVLTree< Val, Cmp >::removeFromSafeList_(
typename AVLTree< Val, Cmp >::iterator_safe* iter) {
864 const Size len = safe_iterators_.size();
865 for (Size i = Size(0); i < len; ++i) {
866 if (safe_iterators_[i] == iter) {
867 safe_iterators_[i] = safe_iterators_[len - 1];
868 safe_iterators_.pop_back();
875 template <
typename Val,
typename Cmp >
876 std::string AVLTree< Val, Cmp >::toString()
const {
877 std::stringstream str;
880 for (
const auto& val: *
this) {
881 if (!first) str <<
" , ";
892 template <
typename Val,
typename Cmp >
893 typename AVLTreeIterator< Val, Cmp >::AVLNode*
894 AVLTreeIterator< Val, Cmp >::nextNode_(AVLNode* node)
const noexcept {
895 if (node !=
nullptr) {
898 if (node->right_child !=
nullptr) {
901 AVLNode* next_node = node->right_child;
902 while (next_node->left_child !=
nullptr)
903 next_node = next_node->left_child;
908 if (node == tree_->highest_node_) {
return nullptr; }
912 AVLNode* current_node = node;
913 AVLNode* next_node = node->parent;
915 while (next_node->right_child == current_node) {
916 current_node = next_node;
917 next_node = next_node->parent;
928 template <
typename Val,
typename Cmp >
929 typename AVLTreeIterator< Val, Cmp >::AVLNode*
930 AVLTreeIterator< Val, Cmp >::precedingNode_(AVLNode* node)
const noexcept {
931 if (node !=
nullptr) {
934 if (node->left_child !=
nullptr) {
937 AVLNode* next_node = node->left_child;
938 while (next_node->right_child !=
nullptr)
939 next_node = next_node->right_child;
944 if (node == tree_->lowest_node_) {
return nullptr; }
948 AVLNode* current_node = node;
949 AVLNode* next_node = node->parent;
951 while (next_node->left_child == current_node) {
952 current_node = next_node;
953 next_node = next_node->parent;
964 template <
typename Val,
typename Cmp >
965 AVLTreeIterator< Val, Cmp >::AVLTreeIterator(
const AVLTree< Val, Cmp >& tree,
966 const bool begin) noexcept :
967 tree_(
const_cast< AVLTree< Val, Cmp >*
>(&tree)),
968 node_(begin ? tree.lowest_node_ : tree.highest_node_) {
969 next_node_ = nextNode_(node_);
970 preceding_node_ = precedingNode_(node_);
972 GUM_CONSTRUCTOR(AVLTreeIterator)
976 template <
typename Val,
typename Cmp >
977 AVLTreeIterator< Val, Cmp >::AVLTreeIterator(
const AVLTreeIterator< Val, Cmp >& from) noexcept :
978 tree_(from.tree_), node_(from.node_), next_node_(from.next_node_),
979 preceding_node_(from.preceding_node_) {
980 GUM_CONS_CPY(AVLTreeIterator)
984 template <
typename Val,
typename Cmp >
985 AVLTreeIterator< Val, Cmp >::AVLTreeIterator(AVLTreeIterator< Val, Cmp >&& from) noexcept :
986 tree_(from.tree_), node_(from.node_), next_node_(from.next_node_),
987 preceding_node_(from.preceding_node_) {
988 GUM_CONS_MOV(AVLTreeIterator)
992 template <
typename Val,
typename Cmp >
993 AVLTreeIterator< Val, Cmp >::~AVLTreeIterator() noexcept {
994 GUM_DESTRUCTOR(AVLTreeIterator);
998 template <
typename Val,
typename Cmp >
999 AVLTreeIterator< Val, Cmp >&
1000 AVLTreeIterator< Val, Cmp >::operator=(
const AVLTreeIterator< Val, Cmp >& from)
noexcept
1004 template <
typename Val,
typename Cmp >
1005 AVLTreeIterator< Val, Cmp >&
1006 AVLTreeIterator< Val, Cmp >::operator=(AVLTreeIterator< Val, Cmp >&& from)
noexcept {
1009 next_node_ = from.next_node_;
1010 preceding_node_ = from.preceding_node_;
1015 template <
typename Val,
typename Cmp >
1016 bool AVLTreeIterator< Val, Cmp >::operator==(
const AVLTreeIterator< Val, Cmp >& from)
const {
1026 return (node_ == from.node_) && (next_node_ == from.next_node_);
1030 template <
typename Val,
typename Cmp >
1031 bool AVLTreeIterator< Val, Cmp >::operator!=(
const AVLTreeIterator< Val, Cmp >& from)
const {
1033 return (node_ != from.node_) || (next_node_ != from.next_node_);
1037 template <
typename Val,
typename Cmp >
1038 AVLTreeIterator< Val, Cmp >& AVLTreeIterator< Val, Cmp >::operator++() noexcept {
1039 preceding_node_ = node_;
1041 next_node_ = nextNode_(node_);
1046 template <
typename Val,
typename Cmp >
1047 AVLTreeIterator< Val, Cmp >& AVLTreeIterator< Val, Cmp >::operator+=(
const Size k)
noexcept {
1048 for (Size i = 0; i < k; ++i) {
1049 AVLTreeIterator< Val, Cmp >::operator++();
1055 template <
typename Val,
typename Cmp >
1056 AVLTreeIterator< Val, Cmp >& AVLTreeIterator< Val, Cmp >::operator--() noexcept {
1058 node_ = preceding_node_;
1059 preceding_node_ = precedingNode_(node_);
1064 template <
typename Val,
typename Cmp >
1065 AVLTreeIterator< Val, Cmp >& AVLTreeIterator< Val, Cmp >::operator-=(
const Size k)
noexcept {
1066 for (Size i = 0; i < k; ++i) {
1067 AVLTreeIterator< Val, Cmp >::operator--();
1073 template <
typename Val,
typename Cmp >
1074 void AVLTreeIterator< Val, Cmp >::unregisterTree_() noexcept {
1077 preceding_node_ =
nullptr;
1078 next_node_ =
nullptr;
1082 template <
typename Val,
typename Cmp >
1083 void AVLTreeIterator< Val, Cmp >::pointToEndRend_() noexcept {
1085 preceding_node_ =
nullptr;
1086 next_node_ =
nullptr;
1090 template <
typename Val,
typename Cmp >
1091 typename AVLTreeIterator< Val, Cmp >::const_reference
1092 AVLTreeIterator< Val, Cmp >::operator*()
const {
1093 if (node_ !=
nullptr)
return node_->value;
1095 if ((next_node_ ==
nullptr) || (preceding_node_ ==
nullptr)) {
1106 template <
typename Val,
typename Cmp >
1107 AVLTreeIteratorSafe< Val, Cmp >::AVLTreeIteratorSafe(AVLTree< Val, Cmp >& tree,
1108 const bool rbegin) :
1109 AVLTreeIterator< Val,
Cmp >(tree, rbegin) {
1110 tree.insertIntoSafeList_(
this);
1111 GUM_CONSTRUCTOR(AVLTreeIteratorSafe)
1115 template <
typename Val,
typename Cmp >
1116 AVLTreeIteratorSafe< Val, Cmp >::AVLTreeIteratorSafe(
1117 const AVLTreeIteratorSafe< Val, Cmp >& from) : AVLTreeIterator< Val,
Cmp >(from) {
1118 if (this->tree_ !=
nullptr) this->tree_->insertIntoSafeList_(
this);
1119 GUM_CONS_CPY(AVLTreeIteratorSafe)
1123 template <
typename Val,
typename Cmp >
1124 AVLTreeIteratorSafe< Val, Cmp >::AVLTreeIteratorSafe(AVLTreeIteratorSafe< Val, Cmp >&& from) :
1125 AVLTreeIterator< Val,
Cmp >(
std::move(from)) {
1126 if (this->tree_ !=
nullptr) {
1127 this->tree_->insertIntoSafeList_(
this);
1128 this->tree_->removeFromSafeList_(&from);
1130 GUM_CONS_MOV(AVLTreeIteratorSafe)
1134 template <
typename Val,
typename Cmp >
1135 AVLTreeIteratorSafe< Val, Cmp >::~AVLTreeIteratorSafe() noexcept {
1136 if (this->tree_ !=
nullptr) { this->tree_->removeFromSafeList_(
this); }
1137 GUM_DESTRUCTOR(AVLTreeIteratorSafe)
1141 template <
typename Val,
typename Cmp >
1142 AVLTreeIteratorSafe< Val, Cmp >&
1143 AVLTreeIteratorSafe< Val, Cmp >::operator=(
const AVLTreeIteratorSafe< Val, Cmp >& from) {
1144 if (
this != &from) {
1145 if (from.tree_ != this->tree_) {
1146 if (this->tree_ !=
nullptr) { this->tree_->removeFromSafeList_(
this); }
1147 if (from.tree_ !=
nullptr) { from.tree_->insertIntoSafeList_(
this); }
1149 AVLTreeIterator< Val, Cmp >::operator=(from);
1155 template <
typename Val,
typename Cmp >
1156 AVLTreeIteratorSafe< Val, Cmp >&
1157 AVLTreeIteratorSafe< Val, Cmp >::operator=(AVLTreeIteratorSafe< Val, Cmp >&& from) {
1158 if (
this != &from) {
1159 if (from.tree_ != this->tree_) {
1160 if (this->tree_ !=
nullptr) { this->tree_->removeFromSafeList_(
this); }
1161 if (from.tree_ !=
nullptr) { from.tree_->insertIntoSafeList_(
this); }
1163 AVLTreeIterator< Val, Cmp >::operator=(std::move(from));
1169 template <
typename Val,
typename Cmp >
1170 bool AVLTreeIteratorSafe< Val, Cmp >::operator==(
1171 const AVLTreeIteratorSafe< Val, Cmp >& from)
const {
1172 return AVLTreeIterator< Val, Cmp >::operator==(from);
1176 template <
typename Val,
typename Cmp >
1177 bool AVLTreeIteratorSafe< Val, Cmp >::operator!=(
1178 const AVLTreeIteratorSafe< Val, Cmp >& from)
const {
1179 return AVLTreeIterator< Val, Cmp >::operator!=(from);
1183 template <
typename Val,
typename Cmp >
1184 AVLTreeIteratorSafe< Val, Cmp >& AVLTreeIteratorSafe< Val, Cmp >::operator++() noexcept {
1185 AVLTreeIterator< Val, Cmp >::operator++();
1190 template <
typename Val,
typename Cmp >
1191 AVLTreeIteratorSafe< Val, Cmp >&
1192 AVLTreeIteratorSafe< Val, Cmp >::operator+=(
const Size k)
noexcept {
1193 AVLTreeIterator< Val, Cmp >::operator+=(k);
1198 template <
typename Val,
typename Cmp >
1199 AVLTreeIteratorSafe< Val, Cmp >& AVLTreeIteratorSafe< Val, Cmp >::operator--() noexcept {
1200 AVLTreeIterator< Val, Cmp >::operator--();
1205 template <
typename Val,
typename Cmp >
1206 AVLTreeIteratorSafe< Val, Cmp >&
1207 AVLTreeIteratorSafe< Val, Cmp >::operator-=(
const Size k)
noexcept {
1208 AVLTreeIterator< Val, Cmp >::operator-=(k);
1215 template <
typename Val,
typename Cmp >
1216 AVLTreeReverseIterator< Val, Cmp >::AVLTreeReverseIterator(
const AVLTree< Val, Cmp >& tree,
1217 const bool rbegin) noexcept :
1218 AVLTreeIterator< Val, Cmp >(tree, !rbegin) {
1219 GUM_CONSTRUCTOR(AVLTreeReverseIterator)
1223 template <
typename Val,
typename Cmp >
1224 AVLTreeReverseIterator< Val, Cmp >::AVLTreeReverseIterator(
1225 const AVLTreeReverseIterator< Val, Cmp >& from) noexcept : AVLTreeIterator< Val, Cmp >(from) {
1226 GUM_CONS_CPY(AVLTreeReverseIterator)
1230 template <
typename Val,
typename Cmp >
1231 AVLTreeReverseIterator< Val, Cmp >::AVLTreeReverseIterator(
1232 AVLTreeReverseIterator< Val, Cmp >&& from) noexcept :
1233 AVLTreeIterator< Val, Cmp >(std::move(from)) {
1234 GUM_CONS_MOV(AVLTreeReverseIterator)
1238 template <
typename Val,
typename Cmp >
1239 AVLTreeReverseIterator< Val, Cmp >::~AVLTreeReverseIterator() noexcept {
1240 GUM_DESTRUCTOR(AVLTreeReverseIterator)
1244 template <
typename Val,
typename Cmp >
1245 AVLTreeReverseIterator< Val, Cmp >& AVLTreeReverseIterator< Val, Cmp >::operator=(
1246 const AVLTreeReverseIterator< Val, Cmp >& from)
noexcept {
1247 AVLTreeIterator< Val, Cmp >::operator=(from);
1252 template <
typename Val,
typename Cmp >
1253 AVLTreeReverseIterator< Val, Cmp >& AVLTreeReverseIterator< Val, Cmp >::operator=(
1254 AVLTreeReverseIterator< Val, Cmp >&& from)
noexcept {
1255 AVLTreeIterator< Val, Cmp >::operator=(std::move(from));
1260 template <
typename Val,
typename Cmp >
1261 bool AVLTreeReverseIterator< Val, Cmp >::operator==(
1262 const AVLTreeReverseIterator< Val, Cmp >& from)
const {
1272 return (this->node_ == from.node_) && (this->preceding_node_ == from.preceding_node_);
1276 template <
typename Val,
typename Cmp >
1277 bool AVLTreeReverseIterator< Val, Cmp >::operator!=(
1278 const AVLTreeReverseIterator< Val, Cmp >& from)
const {
1280 return (this->node_ != from.node_) || (this->preceding_node_ != from.preceding_node_);
1284 template <
typename Val,
typename Cmp >
1285 AVLTreeReverseIterator< Val, Cmp >& AVLTreeReverseIterator< Val, Cmp >::operator++() noexcept {
1286 AVLTreeIterator< Val, Cmp >::operator--();
1291 template <
typename Val,
typename Cmp >
1292 AVLTreeReverseIterator< Val, Cmp >&
1293 AVLTreeReverseIterator< Val, Cmp >::operator+=(
const Size k)
noexcept {
1294 for (Size i = 0; i < k; ++i) {
1295 AVLTreeReverseIterator< Val, Cmp >::operator++();
1301 template <
typename Val,
typename Cmp >
1302 AVLTreeReverseIterator< Val, Cmp >& AVLTreeReverseIterator< Val, Cmp >::operator--() noexcept {
1303 AVLTreeIterator< Val, Cmp >::operator++();
1308 template <
typename Val,
typename Cmp >
1309 AVLTreeReverseIterator< Val, Cmp >&
1310 AVLTreeReverseIterator< Val, Cmp >::operator-=(
const Size k)
noexcept {
1311 for (Size i = 0; i < k; ++i) {
1312 AVLTreeReverseIterator< Val, Cmp >::operator--();
1320 template <
typename Val,
typename Cmp >
1321 AVLTreeReverseIteratorSafe< Val, Cmp >::AVLTreeReverseIteratorSafe(AVLTree< Val, Cmp >& tree,
1322 const bool rbegin) :
1323 AVLTreeIteratorSafe< Val,
Cmp >(tree, !rbegin) {
1324 GUM_CONSTRUCTOR(AVLTreeReverseIteratorSafe)
1328 template <
typename Val,
typename Cmp >
1329 AVLTreeReverseIteratorSafe< Val, Cmp >::AVLTreeReverseIteratorSafe(
1330 const AVLTreeReverseIteratorSafe< Val, Cmp >& from) : AVLTreeIteratorSafe< Val,
Cmp >(from) {
1331 GUM_CONS_CPY(AVLTreeReverseIteratorSafe)
1335 template <
typename Val,
typename Cmp >
1336 AVLTreeReverseIteratorSafe< Val, Cmp >::AVLTreeReverseIteratorSafe(
1337 AVLTreeReverseIteratorSafe< Val, Cmp >&& from) :
1338 AVLTreeIteratorSafe< Val,
Cmp >(
std::move(from)) {
1339 GUM_CONS_MOV(AVLTreeReverseIteratorSafe)
1343 template <
typename Val,
typename Cmp >
1344 AVLTreeReverseIteratorSafe< Val, Cmp >::~AVLTreeReverseIteratorSafe() noexcept {
1345 GUM_DESTRUCTOR(AVLTreeReverseIteratorSafe)
1349 template <
typename Val,
typename Cmp >
1350 AVLTreeReverseIteratorSafe< Val, Cmp >& AVLTreeReverseIteratorSafe< Val, Cmp >::operator=(
1351 const AVLTreeReverseIteratorSafe< Val, Cmp >& from) {
1352 AVLTreeIteratorSafe< Val, Cmp >::operator=(from);
1357 template <
typename Val,
typename Cmp >
1358 AVLTreeReverseIteratorSafe< Val, Cmp >& AVLTreeReverseIteratorSafe< Val, Cmp >::operator=(
1359 AVLTreeReverseIteratorSafe< Val, Cmp >&& from) {
1360 AVLTreeIteratorSafe< Val, Cmp >::operator=(std::move(from));
1365 template <
typename Val,
typename Cmp >
1366 bool AVLTreeReverseIteratorSafe< Val, Cmp >::operator==(
1367 const AVLTreeReverseIteratorSafe< Val, Cmp >& from)
const {
1377 return (this->node_ == from.node_) && (this->preceding_node_ == from.preceding_node_);
1381 template <
typename Val,
typename Cmp >
1382 bool AVLTreeReverseIteratorSafe< Val, Cmp >::operator!=(
1383 const AVLTreeReverseIteratorSafe< Val, Cmp >& from)
const {
1385 return (this->node_ != from.node_) || (this->preceding_node_ != from.preceding_node_);
1389 template <
typename Val,
typename Cmp >
1390 AVLTreeReverseIteratorSafe< Val, Cmp >&
1391 AVLTreeReverseIteratorSafe< Val, Cmp >::operator++() noexcept {
1392 AVLTreeIteratorSafe< Val, Cmp >::operator--();
1397 template <
typename Val,
typename Cmp >
1398 AVLTreeReverseIteratorSafe< Val, Cmp >&
1399 AVLTreeReverseIteratorSafe< Val, Cmp >::operator+=(
const Size k)
noexcept {
1400 for (Size i = 0; i < k; ++i) {
1401 AVLTreeReverseIteratorSafe< Val, Cmp >::operator++();
1407 template <
typename Val,
typename Cmp >
1408 AVLTreeReverseIteratorSafe< Val, Cmp >&
1409 AVLTreeReverseIteratorSafe< Val, Cmp >::operator--() noexcept {
1410 AVLTreeIteratorSafe< Val, Cmp >::operator++();
1415 template <
typename Val,
typename Cmp >
1416 AVLTreeReverseIteratorSafe< Val, Cmp >&
1417 AVLTreeReverseIteratorSafe< Val, Cmp >::operator-=(
const Size k)
noexcept {
1418 for (Size i = 0; i < k; ++i) {
1419 AVLTreeReverseIteratorSafe< Val, Cmp >::operator--();
1424 template <
typename Val,
typename Cmp >
1425 std::ostream&
operator<<(std::ostream& stream,
const AVLTree< Val, Cmp >& tree) {
1426 return stream << tree.toString();
1430 template <
typename Val >
1431 Size HashFunc< AVLTreeNode< Val > >::operator()(
const AVLTreeNode< Val >& key)
const {
1432 return HashFunc< Val >::operator()(key.value);
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
#define GUM_ERROR(type, msg)
bool contains(std::string_view s, std::string_view needle)
true if needle in s
gum is the global namespace for all aGrUM entities
std::ostream & operator<<(std::ostream &out, const TiXmlNode &base)