aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
sharedAVLTree_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
44#include <functional>
45#include <sstream>
46#include <utility>
47
50
51#include <type_traits>
52
53#ifndef DOXYGEN_SHOULD_SKIP_THIS
54
55namespace gum {
56
58 template < typename Val, typename Cmp >
59 SharedAVLTree< Val, Cmp >::SharedAVLTree(const Cmp& compare) : AVLTree< Val, Cmp >(compare) {
60 this->owns_nodes_ = false;
61
62 // for debugging purposes
63 GUM_CONSTRUCTOR(SharedAVLTree);
64 }
65
67 template < typename Val, typename Cmp >
68 SharedAVLTree< Val, Cmp >::SharedAVLTree(SharedAVLTree< Val, Cmp >&& from) noexcept :
69 AVLTree< Val, Cmp >(std::move(from)) {
70 // for debugging purposes
71 GUM_CONS_MOV(SharedAVLTree);
72 }
73
75 template < typename Val, typename Cmp >
76 SharedAVLTree< Val, Cmp >::~SharedAVLTree() {
77 // for debugging purposes
78 GUM_DESTRUCTOR(SharedAVLTree);
79 }
80
82 template < typename Val, typename Cmp >
83 SharedAVLTree< Val, Cmp >&
84 SharedAVLTree< Val, Cmp >::operator=(SharedAVLTree< Val, Cmp >&& from) {
85 operator=(std::move(from));
86 return *this;
87 }
88
90 template < typename Val, typename Cmp >
91 typename SharedAVLTree< Val, Cmp >::AVLNode*
92 SharedAVLTree< Val, Cmp >::highestNode() const noexcept {
93 return this->highest_node_;
94 }
95
97 template < typename Val, typename Cmp >
98 typename SharedAVLTree< Val, Cmp >::AVLNode*
99 SharedAVLTree< Val, Cmp >::lowestNode() const noexcept {
100 return this->lowest_node_;
101 }
102
104 template < typename Val, typename Cmp >
105 void SharedAVLTree< Val, Cmp >::insert(AVLNode* node) {
106 // the insert_ method will update the parent of node, but we should also
107 // guarantee that the children are null pointers before the insertion (as the
108 // node will be added to the
109 node->left_child = nullptr;
110 node->right_child = nullptr;
111 this->insert_(node);
112 }
113
115 template < typename Val, typename Cmp >
116 void SharedAVLTree< Val, Cmp >::erase(AVLNode* node) {
117 this->removeNodeFromTree_(node);
118 }
119
121 template < typename Val, typename Cmp >
122 void SharedAVLTree< Val, Cmp >::erase(iterator_safe& iter) {
123 this->removeNodeFromTree_(iter.node_);
124 }
125
127 template < typename Val, typename Cmp >
128 void SharedAVLTree< Val, Cmp >::erase(reverse_iterator_safe& iter) {
129 this->removeNodeFromTree_(iter.node_);
130 }
131
133 template < typename Val, typename Cmp >
134 typename SharedAVLTree< Val, Cmp >::iterator SharedAVLTree< Val, Cmp >::begin() const {
135 return SharedAVLTreeIterator(*this);
136 }
137
139 template < typename Val, typename Cmp >
140 constexpr const typename SharedAVLTree< Val, Cmp >::iterator&
141 SharedAVLTree< Val, Cmp >::end() const {
142 return *(reinterpret_cast< const iterator* >(_SharedAVLTree_end_));
143 }
144
146 template < typename Val, typename Cmp >
147 typename SharedAVLTree< Val, Cmp >::reverse_iterator SharedAVLTree< Val, Cmp >::rbegin() const {
148 return SharedAVLTreeReverseIterator(*this, true);
149 }
150
152 template < typename Val, typename Cmp >
153 constexpr const typename SharedAVLTree< Val, Cmp >::reverse_iterator&
154 SharedAVLTree< Val, Cmp >::rend() const {
155 return *(reinterpret_cast< const reverse_iterator* >(_SharedAVLTree_rend_));
156 }
157
159 template < typename Val, typename Cmp >
160 typename SharedAVLTree< Val, Cmp >::iterator_safe SharedAVLTree< Val, Cmp >::beginSafe() {
161 return SharedAVLTreeIteratorSafe(*this);
162 }
163
165 template < typename Val, typename Cmp >
166 constexpr const typename SharedAVLTree< Val, Cmp >::iterator_safe&
167 SharedAVLTree< Val, Cmp >::endSafe() const {
168 return *(reinterpret_cast< const iterator_safe* >(_SharedAVLTree_end_safe_));
169 }
170
172 template < typename Val, typename Cmp >
173 typename SharedAVLTree< Val, Cmp >::reverse_iterator_safe
174 SharedAVLTree< Val, Cmp >::rbeginSafe() {
175 return SharedAVLTreeReverseIteratorSafe(*this, true);
176 }
177
179 template < typename Val, typename Cmp >
180 constexpr const typename SharedAVLTree< Val, Cmp >::reverse_iterator_safe&
181 SharedAVLTree< Val, Cmp >::rendSafe() const {
182 return *(reinterpret_cast< const reverse_iterator_safe* >(_SharedAVLTree_rend_safe_));
183 }
184
186
188 template < typename Val, typename Cmp >
189 SharedAVLTreeIterator< Val, Cmp >::SharedAVLTreeIterator(const SharedAVLTree< Val, Cmp >& tree,
190 const bool begin) noexcept :
191 AVLTreeIterator< Val, Cmp >(tree, begin) {
192 GUM_CONSTRUCTOR(SharedAVLTreeIterator)
193 }
194
196 template < typename Val, typename Cmp >
197 SharedAVLTreeIterator< Val, Cmp >::SharedAVLTreeIterator(
198 const SharedAVLTreeIterator< Val, Cmp >& from) noexcept : AVLTreeIterator< Val, Cmp >(from) {
199 GUM_CONS_CPY(SharedAVLTreeIterator)
200 }
201
203 template < typename Val, typename Cmp >
204 SharedAVLTreeIterator< Val, Cmp >::SharedAVLTreeIterator(
205 SharedAVLTreeIterator< Val, Cmp >&& from) noexcept :
206 AVLTreeIterator< Val, Cmp >(std::move(from)) {
207 GUM_CONS_MOV(SharedAVLTreeIterator)
208 }
209
211 template < typename Val, typename Cmp >
212 SharedAVLTreeIterator< Val, Cmp >::~SharedAVLTreeIterator() noexcept {
213 GUM_DESTRUCTOR(SharedAVLTreeIterator)
214 }
215
217 template < typename Val, typename Cmp >
218 SharedAVLTreeIterator< Val, Cmp >& SharedAVLTreeIterator< Val, Cmp >::operator=(
219 const SharedAVLTreeIterator< Val, Cmp >& from) noexcept {
220 AVLTreeIterator< Val, Cmp >::operator=(from);
221 return *this;
222 }
223
225 template < typename Val, typename Cmp >
226 SharedAVLTreeIterator< Val, Cmp >& SharedAVLTreeIterator< Val, Cmp >::operator=(
227 SharedAVLTreeIterator< Val, Cmp >&& from) noexcept {
228 AVLTreeIterator< Val, Cmp >::operator=(std::move(from));
229 return *this;
230 }
231
233 template < typename Val, typename Cmp >
234 bool SharedAVLTreeIterator< Val, Cmp >::operator==(
235 const SharedAVLTreeIterator< Val, Cmp >& from) const {
236 return AVLTreeIterator< Val, Cmp >::operator==(from);
237 }
238
240 template < typename Val, typename Cmp >
241 bool SharedAVLTreeIterator< Val, Cmp >::operator!=(
242 const SharedAVLTreeIterator< Val, Cmp >& from) const {
243 return !SharedAVLTreeIterator< Val, Cmp >::operator==(from);
244 }
245
247 template < typename Val, typename Cmp >
248 SharedAVLTreeIterator< Val, Cmp >& SharedAVLTreeIterator< Val, Cmp >::operator++() noexcept {
249 AVLTreeIterator< Val, Cmp >::operator++();
250 return *this;
251 }
252
254 template < typename Val, typename Cmp >
255 SharedAVLTreeIterator< Val, Cmp >&
256 SharedAVLTreeIterator< Val, Cmp >::operator+=(const Size k) noexcept {
257 AVLTreeIterator< Val, Cmp >::operator+=(k);
258 return *this;
259 }
260
262 template < typename Val, typename Cmp >
263 SharedAVLTreeIterator< Val, Cmp >& SharedAVLTreeIterator< Val, Cmp >::operator--() noexcept {
264 AVLTreeIterator< Val, Cmp >::operator--();
265 return *this;
266 }
267
269 template < typename Val, typename Cmp >
270 SharedAVLTreeIterator< Val, Cmp >&
271 SharedAVLTreeIterator< Val, Cmp >::operator-=(const Size k) noexcept {
272 AVLTreeIterator< Val, Cmp >::operator-=(k);
273 return *this;
274 }
275
277 template < typename Val, typename Cmp >
278 typename SharedAVLTreeIterator< Val, Cmp >::const_reference
279 SharedAVLTreeIterator< Val, Cmp >::operator*() const {
280 if (this->node_ != nullptr) return *(this->node_);
281 else {
282 if ((this->next_node_ == nullptr) || (this->preceding_node_ == nullptr)) {
283 GUM_ERROR(NotFound, "an end SharedAVLTree iterator does not contain any value")
284 } else {
285 GUM_ERROR(NotFound, "the SharedAVLTree iterator points to an erased value")
286 }
287 }
288 }
289
291 template < typename Val, typename Cmp >
292 typename SharedAVLTreeIterator< Val, Cmp >::const_pointer
293 SharedAVLTreeIterator< Val, Cmp >::operator->() const {
294 return this->node_;
295 }
296
298
300 template < typename Val, typename Cmp >
301 SharedAVLTreeIteratorSafe< Val, Cmp >::SharedAVLTreeIteratorSafe(SharedAVLTree< Val, Cmp >& tree,
302 const bool rbegin) :
303 AVLTreeIteratorSafe< Val, Cmp >(tree, rbegin) {
304 GUM_CONSTRUCTOR(SharedAVLTreeIteratorSafe)
305 }
306
308 template < typename Val, typename Cmp >
309 SharedAVLTreeIteratorSafe< Val, Cmp >::SharedAVLTreeIteratorSafe(
310 const SharedAVLTreeIteratorSafe< Val, Cmp >& from) : AVLTreeIteratorSafe< Val, Cmp >(from) {
311 GUM_CONS_CPY(SharedAVLTreeIteratorSafe)
312 }
313
315 template < typename Val, typename Cmp >
316 SharedAVLTreeIteratorSafe< Val, Cmp >::SharedAVLTreeIteratorSafe(
317 SharedAVLTreeIteratorSafe< Val, Cmp >&& from) :
318 AVLTreeIteratorSafe< Val, Cmp >(std::move(from)) {
319 GUM_CONS_CPY(SharedAVLTreeIteratorSafe)
320 }
321
323 template < typename Val, typename Cmp >
324 SharedAVLTreeIteratorSafe< Val, Cmp >::~SharedAVLTreeIteratorSafe() noexcept {
325 GUM_DESTRUCTOR(SharedAVLTreeIteratorSafe)
326 }
327
329 template < typename Val, typename Cmp >
330 SharedAVLTreeIteratorSafe< Val, Cmp >& SharedAVLTreeIteratorSafe< Val, Cmp >::operator=(
331 const SharedAVLTreeIteratorSafe< Val, Cmp >& from) {
332 AVLTreeIteratorSafe< Val, Cmp >::operator=(from);
333 return *this;
334 }
335
337 template < typename Val, typename Cmp >
338 SharedAVLTreeIteratorSafe< Val, Cmp >& SharedAVLTreeIteratorSafe< Val, Cmp >::operator=(
339 SharedAVLTreeIteratorSafe< Val, Cmp >&& from) {
340 AVLTreeIteratorSafe< Val, Cmp >::operator=(std::move(from));
341 return *this;
342 }
343
345 template < typename Val, typename Cmp >
346 bool SharedAVLTreeIteratorSafe< Val, Cmp >::operator==(
347 const SharedAVLTreeIteratorSafe< Val, Cmp >& from) const {
348 return AVLTreeIteratorSafe< Val, Cmp >::operator==(from);
349 }
350
352 template < typename Val, typename Cmp >
353 bool SharedAVLTreeIteratorSafe< Val, Cmp >::operator!=(
354 const SharedAVLTreeIteratorSafe< Val, Cmp >& from) const {
355 return !SharedAVLTreeIteratorSafe< Val, Cmp >::operator==(from);
356 }
357
359 template < typename Val, typename Cmp >
360 SharedAVLTreeIteratorSafe< Val, Cmp >&
361 SharedAVLTreeIteratorSafe< Val, Cmp >::operator++() noexcept {
362 AVLTreeIteratorSafe< Val, Cmp >::operator++();
363 return *this;
364 }
365
367 template < typename Val, typename Cmp >
368 SharedAVLTreeIteratorSafe< Val, Cmp >&
369 SharedAVLTreeIteratorSafe< Val, Cmp >::operator+=(const Size k) noexcept {
370 AVLTreeIteratorSafe< Val, Cmp >::operator+=(k);
371 return *this;
372 }
373
375 template < typename Val, typename Cmp >
376 SharedAVLTreeIteratorSafe< Val, Cmp >&
377 SharedAVLTreeIteratorSafe< Val, Cmp >::operator--() noexcept {
378 AVLTreeIteratorSafe< Val, Cmp >::operator--();
379 return *this;
380 }
381
383 template < typename Val, typename Cmp >
384 SharedAVLTreeIteratorSafe< Val, Cmp >&
385 SharedAVLTreeIteratorSafe< Val, Cmp >::operator-=(const Size k) noexcept {
386 AVLTreeIteratorSafe< Val, Cmp >::operator-=(k);
387 return *this;
388 }
389
391 template < typename Val, typename Cmp >
392 typename SharedAVLTreeIteratorSafe< Val, Cmp >::const_reference
393 SharedAVLTreeIteratorSafe< Val, Cmp >::operator*() const {
394 if (this->node_ != nullptr) return *(this->node_);
395 else {
396 if ((this->next_node_ == nullptr) || (this->preceding_node_ == nullptr)) {
397 GUM_ERROR(NotFound, "an end SharedAVLTree iterator does not contain any value")
398 } else {
399 GUM_ERROR(NotFound, "the SharedAVLTree iterator points to an erased value")
400 }
401 }
402 }
403
405 template < typename Val, typename Cmp >
406 typename SharedAVLTreeIteratorSafe< Val, Cmp >::const_pointer
407 SharedAVLTreeIteratorSafe< Val, Cmp >::operator->() const {
408 return this->node_;
409 }
410
412
414 template < typename Val, typename Cmp >
415 SharedAVLTreeReverseIterator< Val, Cmp >::SharedAVLTreeReverseIterator(
416 const SharedAVLTree< Val, Cmp >& tree,
417 const bool rbegin) noexcept : SharedAVLTreeIterator< Val, Cmp >(tree, !rbegin) {
418 GUM_CONSTRUCTOR(SharedAVLTreeReverseIterator)
419 }
420
422 template < typename Val, typename Cmp >
423 SharedAVLTreeReverseIterator< Val, Cmp >::SharedAVLTreeReverseIterator(
424 const SharedAVLTreeReverseIterator< Val, Cmp >& from) noexcept :
425 SharedAVLTreeIterator< Val, Cmp >(from) {
426 GUM_CONS_CPY(SharedAVLTreeReverseIterator)
427 }
428
430 template < typename Val, typename Cmp >
431 SharedAVLTreeReverseIterator< Val, Cmp >::SharedAVLTreeReverseIterator(
432 SharedAVLTreeReverseIterator< Val, Cmp >&& from) noexcept :
433 SharedAVLTreeIterator< Val, Cmp >(std::move(from)) {
434 GUM_CONS_CPY(SharedAVLTreeReverseIterator)
435 }
436
438 template < typename Val, typename Cmp >
439 SharedAVLTreeReverseIterator< Val, Cmp >::~SharedAVLTreeReverseIterator() noexcept {
440 GUM_DESTRUCTOR(SharedAVLTreeReverseIterator)
441 }
442
444 template < typename Val, typename Cmp >
445 SharedAVLTreeReverseIterator< Val, Cmp >& SharedAVLTreeReverseIterator< Val, Cmp >::operator=(
446 const SharedAVLTreeReverseIterator< Val, Cmp >& from) noexcept {
447 SharedAVLTreeIterator< Val, Cmp >::operator=(from);
448 return *this;
449 }
450
452 template < typename Val, typename Cmp >
453 SharedAVLTreeReverseIterator< Val, Cmp >& SharedAVLTreeReverseIterator< Val, Cmp >::operator=(
454 SharedAVLTreeReverseIterator< Val, Cmp >&& from) noexcept {
455 SharedAVLTreeIterator< Val, Cmp >::operator=(std::move(from));
456 return *this;
457 }
458
460 template < typename Val, typename Cmp >
461 bool SharedAVLTreeReverseIterator< Val, Cmp >::operator==(
462 const SharedAVLTreeReverseIterator< Val, Cmp >& from) const {
463 // when node_ is different from nullptr, testing whether "this" is equal to from
464 // simply amounts to comparing their node_ fields. However, due to erasures in
465 // the tree, it may happen that two iterators pointing to different nodes have
466 // a nullptr node_ field. In this case, they will be equal if and only if their
467 // preceding_node_ fields are equal. Here, it is important to use the preceding_node_
468 // rather than their next_node_ field because the rend iterator has nullptr
469 // as the value of its next_node_ while a reverse iterator moving by ++ operators
470 // up to the end will not have this value for its next_node_. However, it
471 // will have a preceding_node_ equal to nullptr, exactly as the end iterator.
472 return (this->node_ == from.node_) && (this->preceding_node_ == from.preceding_node_);
473 }
474
476 template < typename Val, typename Cmp >
477 bool SharedAVLTreeReverseIterator< Val, Cmp >::operator!=(
478 const SharedAVLTreeReverseIterator< Val, Cmp >& from) const {
479 return !SharedAVLTreeReverseIterator< Val, Cmp >::operator==(from);
480 }
481
483 template < typename Val, typename Cmp >
484 SharedAVLTreeReverseIterator< Val, Cmp >&
485 SharedAVLTreeReverseIterator< Val, Cmp >::operator++() noexcept {
486 SharedAVLTreeIterator< Val, Cmp >::operator--();
487 return *this;
488 }
489
491 template < typename Val, typename Cmp >
492 SharedAVLTreeReverseIterator< Val, Cmp >&
493 SharedAVLTreeReverseIterator< Val, Cmp >::operator+=(const Size k) noexcept {
494 SharedAVLTreeIterator< Val, Cmp >::operator-=(k);
495 return *this;
496 }
497
499 template < typename Val, typename Cmp >
500 SharedAVLTreeReverseIterator< Val, Cmp >&
501 SharedAVLTreeReverseIterator< Val, Cmp >::operator--() noexcept {
502 SharedAVLTreeIterator< Val, Cmp >::operator++();
503 return *this;
504 }
505
507 template < typename Val, typename Cmp >
508 SharedAVLTreeReverseIterator< Val, Cmp >&
509 SharedAVLTreeReverseIterator< Val, Cmp >::operator-=(const Size k) noexcept {
510 SharedAVLTreeIterator< Val, Cmp >::operator+=(k);
511 return *this;
512 }
513
515
517 template < typename Val, typename Cmp >
518 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::SharedAVLTreeReverseIteratorSafe(
519 SharedAVLTree< Val, Cmp >& tree,
520 const bool rbegin) : SharedAVLTreeIteratorSafe< Val, Cmp >(tree, !rbegin) {
521 GUM_CONSTRUCTOR(SharedAVLTreeReverseIteratorSafe)
522 }
523
525 template < typename Val, typename Cmp >
526 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::SharedAVLTreeReverseIteratorSafe(
527 const SharedAVLTreeReverseIteratorSafe< Val, Cmp >& from) :
528 SharedAVLTreeIteratorSafe< Val, Cmp >(from) {
529 GUM_CONS_CPY(SharedAVLTreeReverseIteratorSafe)
530 }
531
533 template < typename Val, typename Cmp >
534 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::SharedAVLTreeReverseIteratorSafe(
535 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&& from) :
536 SharedAVLTreeIteratorSafe< Val, Cmp >(std::move(from)) {
537 GUM_CONS_MOV(SharedAVLTreeReverseIteratorSafe)
538 }
539
541 template < typename Val, typename Cmp >
542 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::~SharedAVLTreeReverseIteratorSafe() noexcept {
543 GUM_DESTRUCTOR(SharedAVLTreeReverseIteratorSafe)
544 }
545
547 template < typename Val, typename Cmp >
548 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&
549 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator=(
550 const SharedAVLTreeReverseIteratorSafe< Val, Cmp >& from) {
551 SharedAVLTreeIteratorSafe< Val, Cmp >::operator=(from);
552 return *this;
553 }
554
556 template < typename Val, typename Cmp >
557 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&
558 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator=(
559 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&& from) {
560 SharedAVLTreeIteratorSafe< Val, Cmp >::operator=(std::move(from));
561 return *this;
562 }
563
565 template < typename Val, typename Cmp >
566 bool SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator==(
567 const SharedAVLTreeReverseIteratorSafe< Val, Cmp >& from) const {
568 // when node_ is different from nullptr, testing whether "this" is equal to from
569 // simply amounts to comparing their node_ fields. However, due to erasures in
570 // the tree, it may happen that two iterators pointing to different nodes have
571 // a nullptr node_ field. In this case, they will be equal if and only if their
572 // preceding_node_ fields are equal. Here, it is important to use the preceding_node_
573 // rather than their next_node_ field because the rend iterator has nullptr
574 // as the value of its next_node_ while a reverse iterator moving by ++ operators
575 // up to the end will not have this value for its next_node_. However, it
576 // will have a preceding_node_ equal to nullptr, exactly as the end iterator.
577 return (this->node_ == from.node_) && (this->preceding_node_ == from.preceding_node_);
578 }
579
581 template < typename Val, typename Cmp >
582 bool SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator!=(
583 const SharedAVLTreeReverseIteratorSafe< Val, Cmp >& from) const {
584 return !SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator==(from);
585 }
586
588 template < typename Val, typename Cmp >
589 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&
590 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator++() noexcept {
591 SharedAVLTreeIteratorSafe< Val, Cmp >::operator--();
592 return *this;
593 }
594
596 template < typename Val, typename Cmp >
597 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&
598 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator+=(const Size k) noexcept {
599 SharedAVLTreeIteratorSafe< Val, Cmp >::operator-=(k);
600 return *this;
601 }
602
604 template < typename Val, typename Cmp >
605 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&
606 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator--() noexcept {
607 SharedAVLTreeIteratorSafe< Val, Cmp >::operator++();
608 return *this;
609 }
610
612 template < typename Val, typename Cmp >
613 SharedAVLTreeReverseIteratorSafe< Val, Cmp >&
614 SharedAVLTreeReverseIteratorSafe< Val, Cmp >::operator-=(const Size k) noexcept {
615 SharedAVLTreeIteratorSafe< Val, Cmp >::operator+=(k);
616 return *this;
617 }
618
620 template < typename Val, typename Cmp >
621 std::ostream& operator<<(std::ostream& stream, const SharedAVLTree< Val, Cmp >& tree) {
622 return stream << tree.toString();
623 }
624
625
626} // namespace gum
627
628#endif // DOXYGEN_SHOULD_SKIP_THIS
AVL binary search tree.
Definition AVLTree.h:149
Exception : the element we looked for cannot be found.
aGrUM's exceptions
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
STL namespace.
AVL binary search trees that do not possess their own nodes.
std::ostream & operator<<(std::ostream &out, const TiXmlNode &base)
Definition tinyxml.cpp:1516