aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
AVLTree.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 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-2025 *
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
49
50#ifndef GUM_AVL_TREE_H
51#define GUM_AVL_TREE_H
52
53#include <algorithm>
54#include <string>
55
56#include <agrum/agrum.h>
57
60
61#include <initializer_list>
62
63namespace gum {
64
65#ifndef DOXYGEN_SHOULD_SKIP_THIS
66
67 template < typename Val, typename Cmp >
68 class AVLTreeIterator;
69 template < typename Val, typename Cmp >
71
72 template < typename Val, typename Cmp >
74 template < typename Val, typename Cmp >
76
78 template < typename Val >
79 struct AVLTreeNode {
80 // the neighbors in our AVL tree
81 AVLTreeNode* parent{nullptr};
82 AVLTreeNode* left_child{nullptr};
83 AVLTreeNode* right_child{nullptr};
84
85 // the height of the node in the AVL tree
86 int height{1};
87
88 // the element to be stored into the node
89 Val value;
90
91 // a class to enabling emplacing values in AVLNodes
92 enum class Emplace { EMPLACE };
93
94 explicit AVLTreeNode(const Val& val) : value(val) { GUM_CONSTRUCTOR(AVLTreeNode); };
95
96 explicit AVLTreeNode(Val&& val) noexcept : value(std::move(val)) {
97 GUM_CONSTRUCTOR(AVLTreeNode);
98 };
99
100 template < typename... Args >
101 explicit AVLTreeNode(const Emplace& emplace, Args&&... args) :
102 value(std::forward< Args >(args)...) {
103 GUM_CONSTRUCTOR(AVLTreeNode);
104 }
105
106 AVLTreeNode(const AVLTreeNode< Val >& from) :
107 parent(from.parent), left_child(from.left_child), right_child(from.right_child),
108 height(from.height), value(from.value) {
109 GUM_CONS_CPY(AVLTreeNode);
110 }
111
112 AVLTreeNode(AVLTreeNode< Val >&& from) :
113 parent(from.parent), left_child(from.left_child), right_child(from.right_child),
114 height(from.height), value(std::move(from.value)) {
115 GUM_CONS_MOV(AVLTreeNode);
116 }
117
118 ~AVLTreeNode() { GUM_DESTRUCTOR(AVLTreeNode); }
119
120 // two nodes are equal if and only if they contain the same value
121 bool operator==(const AVLTreeNode< Val >& from) const { return value == from.value; }
122 };
123
125 template < typename Val >
126 std::ostream& operator<<(std::ostream& stream, const AVLTreeNode< Val >& node) {
127 return stream << '<' << node.value << '>';
128 }
129
131 template < typename Val >
132 class HashFunc< AVLTreeNode< Val > >: public HashFunc< Val > {
133 public:
139 static Size castToSize(const AVLTreeNode< Val >& key) {
140 return HashFunc< Val >::castToSize(key.value);
141 }
142
144
145 private: // best attempt to get rid of overloaded virtual warnings
146 using HashFunc< Val >::operator();
147
148 public:
149 INLINE Size operator()(const AVLTreeNode< Val >& key) const {
150 return HashFunc< Val >::operator()(key.value);
151 }
152 };
153
154#endif // DOXYGEN_SHOULD_SKIP_THIS
155
156
167 template < typename Val, typename Cmp = std::less< Val > >
168 class AVLTree {
169 public:
172 using value_type = Val;
173 using reference = Val&;
174 using const_reference = const Val&;
175 using pointer = Val*;
176 using const_pointer = const Val*;
181 using AVLNode = AVLTreeNode< Val >;
183
184 // ============================================================================
186 // ============================================================================
188
196 explicit AVLTree(const Cmp& compare = Cmp());
197
205 explicit AVLTree(std::initializer_list< Val > list);
206
212
217 AVLTree(AVLTree< Val, Cmp >&& from) noexcept;
218
223
225
226 // ============================================================================
228 // ============================================================================
230
239
247
249
250
251 // ============================================================================
253 // ============================================================================
255
260 Size size() const noexcept;
261
266 bool empty() const noexcept;
267
273 bool contains(const value_type& val) const;
274
280 bool exists(const value_type& val) const;
281
283
284 const value_type& highestValue() const;
285
287
288 const value_type& lowestValue() const;
289
291 const value_type& insert(const value_type& val);
292
295
297 template < typename... Args >
298 const value_type& emplace(Args&&... args);
299
301
306 void erase(const value_type& val);
307
309
315 void erase(iterator_safe& iter);
316
318
325
327 void clear();
328
332 std::string toString() const;
333
335
336 // ============================================================================
338 // ============================================================================
340
343
345 constexpr const iterator& end() const;
346
349
351 constexpr const reverse_iterator& rend() const;
352
355
357 constexpr const iterator_safe& endSafe() const;
358
361
363 constexpr const reverse_iterator_safe& rendSafe() const;
364
366
367 protected:
370
373
376
379
381 bool owns_nodes_{true};
382
385
387 std::vector< iterator_safe* > safe_iterators_;
388
389
391 AVLNode* lowestNode_() const noexcept;
392
394 AVLNode* highestNode_() const noexcept;
395
398
401
404
406
415
417 void erase_(AVLNode* node);
418
421
424
427
429
434 static AVLNode* copySubtree_(const AVLNode* from_node, AVLNode* new_parent);
435
437 static void deleteSubtree_(AVLNode* subtree_root_node);
438
444 };
445
456 template < typename Val, typename Cmp = std::less< Val > >
458 public:
461 using iterator_category = std::bidirectional_iterator_tag;
462 using value_type = Val;
466 using const_pointer = const value_type*;
468
469
470 // ============================================================================
472 // ============================================================================
474
481 explicit AVLTreeIterator(const AVLTree< Val, Cmp >& tree, const bool begin = true) noexcept;
482
483#ifndef DOXYGEN_SHOULD_SKIP_THIS
484 // constructor for the static end iterator
485 // only AVLTree.cpp should use this constructor
486 explicit consteval AVLTreeIterator(StaticInitializer init) noexcept {}
487#endif // DOXYGEN_SHOULD_SKIP_THIS
488
491
494
497
499
500
501 // ============================================================================
503 // ============================================================================
505
507 AVLTreeIterator< Val, Cmp >& operator=(const AVLTreeIterator< Val, Cmp >& from) noexcept;
508
510 AVLTreeIterator< Val, Cmp >& operator=(AVLTreeIterator< Val, Cmp >&& from) noexcept;
511
513 bool operator==(const AVLTreeIterator< Val, Cmp >& from) const;
514
516 bool operator!=(const AVLTreeIterator< Val, Cmp >& from) const;
517
519
521 AVLTreeIterator< Val, Cmp >& operator++() noexcept;
522
524
526 AVLTreeIterator< Val, Cmp >& operator+=(const Size k) noexcept;
527
529
531 AVLTreeIterator< Val, Cmp >& operator--() noexcept;
532
534
536 AVLTreeIterator< Val, Cmp >& operator-=(const Size k) noexcept;
537
544 const_reference operator*() const;
545
547
548
549 protected:
551 using AVLNode = AVLTreeNode< Val >;
552
554 AVLTree< Val, Cmp >* tree_{nullptr};
555
557 AVLNode* node_{nullptr};
558
561
564
565
567 AVLNode* nextNode_(AVLNode* node) const noexcept;
568
570 AVLNode* precedingNode_(AVLNode* node) const noexcept;
571
573 void unregisterTree_() noexcept;
574
576 void pointToEndRend_() noexcept;
577
578
581 };
582
593 template < typename Val, typename Cmp = std::less< Val > >
594 class AVLTreeIteratorSafe: protected AVLTreeIterator< Val, Cmp > {
595 public:
598 using iterator_category = std::bidirectional_iterator_tag;
599 using value_type = Val;
603 using const_pointer = const value_type*;
605
606
607 // ============================================================================
609 // ============================================================================
611
618 explicit AVLTreeIteratorSafe(AVLTree< Val, Cmp >& tree, const bool begin = true);
619
620#ifndef DOXYGEN_SHOULD_SKIP_THIS
621 // constructor for the static endSafe iterator
622 // only AVLTree.cpp should use this constructor
623 explicit consteval AVLTreeIteratorSafe(StaticInitializer init) noexcept :
625#endif // DOXYGEN_SHOULD_SKIP_THIS
626
629
632
635
637
638 // ============================================================================
640 // ============================================================================
642
644 AVLTreeIteratorSafe< Val, Cmp >& operator=(const AVLTreeIteratorSafe< Val, Cmp >& from);
645
647 AVLTreeIteratorSafe< Val, Cmp >& operator=(AVLTreeIteratorSafe< Val, Cmp >&& from);
648
650 bool operator==(const AVLTreeIteratorSafe< Val, Cmp >& from) const;
651
653 bool operator!=(const AVLTreeIteratorSafe< Val, Cmp >& from) const;
654
656
658 AVLTreeIteratorSafe< Val, Cmp >& operator++() noexcept;
659
661
663 AVLTreeIteratorSafe< Val, Cmp >& operator+=(const Size k) noexcept;
664
666
668 AVLTreeIteratorSafe< Val, Cmp >& operator--() noexcept;
669
671
673 AVLTreeIteratorSafe< Val, Cmp >& operator-=(const Size k) noexcept;
674
681 using AVLTreeIterator< Val, Cmp >::operator*;
682
684
685
686 protected:
689 };
690
701 template < typename Val, typename Cmp = std::less< Val > >
702 class AVLTreeReverseIterator: protected AVLTreeIterator< Val, Cmp > {
703 public:
706 using iterator_category = std::bidirectional_iterator_tag;
707 using value_type = Val;
711 using const_pointer = const value_type*;
713
714
715 // ============================================================================
717 // ============================================================================
719
727 const bool rbegin = true) noexcept;
728
729#ifndef DOXYGEN_SHOULD_SKIP_THIS
730 // constructor for the static rend iterator
731 // only AVLTree.cpp should use this constructor
732 explicit consteval AVLTreeReverseIterator(StaticInitializer init) noexcept :
734#endif // DOXYGEN_SHOULD_SKIP_THIS
735
738
741
744
746
747 // ============================================================================
749 // ============================================================================
751
754 operator=(const AVLTreeReverseIterator< Val, Cmp >& from) noexcept;
755
758 operator=(AVLTreeReverseIterator< Val, Cmp >&& from) noexcept;
759
761 bool operator==(const AVLTreeReverseIterator< Val, Cmp >& from) const;
762
764 bool operator!=(const AVLTreeReverseIterator< Val, Cmp >& from) const;
765
767
769 AVLTreeReverseIterator< Val, Cmp >& operator++() noexcept;
770
772
774 AVLTreeReverseIterator< Val, Cmp >& operator+=(const Size k) noexcept;
775
777
779 AVLTreeReverseIterator< Val, Cmp >& operator--() noexcept;
780
782
784 AVLTreeReverseIterator< Val, Cmp >& operator-=(const Size k) noexcept;
785
792 using AVLTreeIterator< Val, Cmp >::operator*;
793
795
796
797 protected:
800 };
801
812 template < typename Val, typename Cmp = std::less< Val > >
814 public:
817 using iterator_category = std::bidirectional_iterator_tag;
818 using value_type = Val;
822 using const_pointer = const value_type*;
824
825
826 // ============================================================================
828 // ============================================================================
830
837 explicit AVLTreeReverseIteratorSafe(AVLTree< Val, Cmp >& tree, const bool rbegin = true);
838
839#ifndef DOXYGEN_SHOULD_SKIP_THIS
840 // constructor for the static rendSafe iterator
841 // only AVLTree.cpp should use this constructor
842 explicit consteval AVLTreeReverseIteratorSafe(StaticInitializer init) noexcept :
844#endif // DOXYGEN_SHOULD_SKIP_THIS
845
848
851
854
856
857 // ============================================================================
859 // ============================================================================
861
864 operator=(const AVLTreeReverseIteratorSafe< Val, Cmp >& from);
865
868 operator=(AVLTreeReverseIteratorSafe< Val, Cmp >&& from);
869
871 bool operator==(const AVLTreeReverseIteratorSafe< Val, Cmp >& from) const;
872
874 bool operator!=(const AVLTreeReverseIteratorSafe< Val, Cmp >& from) const;
875
877
879 AVLTreeReverseIteratorSafe< Val, Cmp >& operator++() noexcept;
880
882
884 AVLTreeReverseIteratorSafe< Val, Cmp >& operator+=(const Size k) noexcept;
885
887
889 AVLTreeReverseIteratorSafe< Val, Cmp >& operator--() noexcept;
890
892
894 AVLTreeReverseIteratorSafe< Val, Cmp >& operator-=(const Size k) noexcept;
895
902 using AVLTreeIteratorSafe< Val, Cmp >::operator*;
903
905
906 protected:
909 };
910
912 template < typename Val, typename Cmp >
913 std::ostream& operator<<(std::ostream& stream, const AVLTree< Val, Cmp >& tree) {
914 return stream << tree.toString();
915 }
916
917
918#ifndef DOXYGEN_SHOULD_SKIP_THIS
919 // _static_AVLTree_end_ is a 'constant' iterator initialized at compile time
920 // that represents the end iterators for all AVL trees (whatever their
921 // type). This global variable avoids creating the same iterators within every
922 // AVL tree instance (this would be quite inefficient as end is precisely
923 // identical for all AVL trees). The same hold for reverse and safe end iterators.
924 // The type of _AVLTree_end_ is a pointer to void because C++ allows
925 // pointers to void to be cast into pointers to other types (and conversely).
926 // This avoids the painful strict-aliasing rule warning
927 extern const AVLTreeIterator< int, std::less< int > > _static_AVLTree_end_;
928 extern const AVLTreeReverseIterator< int, std::less< int > > _static_AVLTree_rend_;
929 extern const AVLTreeIteratorSafe< int, std::less< int > > _static_AVLTree_end_safe_;
930 extern const AVLTreeReverseIteratorSafe< int, std::less< int > > _static_AVLTree_rend_safe_;
931
932 inline constexpr void* const _AVLTree_end_ = (void* const)&_static_AVLTree_end_;
933 inline constexpr void* const _AVLTree_rend_ = (void* const)&_static_AVLTree_rend_;
934 inline constexpr void* const _AVLTree_end_safe_ = (void* const)&_static_AVLTree_end_safe_;
935 inline constexpr void* const _AVLTree_rend_safe_ = (void* const)&_static_AVLTree_rend_safe_;
936#endif // DOXYGEN_SHOULD_SKIP_THIS
937
938
939} // namespace gum
940
941// always include the implementation of the templates
943
944#endif // GUM_AVL_TREE_H
AVL binary search tree safe (w.r.t.
Definition AVLTree.h:594
AVLTreeIteratorSafe(AVLTree< Val, Cmp > &tree, const bool begin=true)
constructor for begin safe iterators
AVLTreeIteratorSafe(const AVLTreeIteratorSafe< Val, Cmp > &from)
copy constructor
const value_type & const_reference
Definition AVLTree.h:601
const value_type * const_pointer
Definition AVLTree.h:603
AVLTreeIteratorSafe(AVLTreeIteratorSafe< Val, Cmp > &&from)
move constructor
std::bidirectional_iterator_tag iterator_category
Definition AVLTree.h:598
~AVLTreeIteratorSafe() noexcept
destructor
AVL binary search tree iterator.
Definition AVLTree.h:457
AVLTreeNode< Val > AVLNode
Definition AVLTree.h:551
AVLTree< Val, Cmp > * tree_
Definition AVLTree.h:554
AVLNode * precedingNode_(AVLNode *node) const noexcept
computes the node to go to when applying operator--
const value_type & const_reference
Definition AVLTree.h:464
AVLTreeIterator(AVLTreeIterator< Val, Cmp > &&from) noexcept
move constructor
void unregisterTree_() noexcept
make the iterator point to nothing
~AVLTreeIterator() noexcept
destructor
AVLTreeIterator(const AVLTree< Val, Cmp > &tree, const bool begin=true) noexcept
constructor for begin iterators
const value_type * const_pointer
Definition AVLTree.h:466
AVLTreeIterator(const AVLTreeIterator< Val, Cmp > &from) noexcept
copy constructor
AVLNode * nextNode_(AVLNode *node) const noexcept
computes the node to go to when applying operator++
std::bidirectional_iterator_tag iterator_category
Definition AVLTree.h:461
AVL binary search tree safe (w.r.t.
Definition AVLTree.h:813
AVLTreeReverseIteratorSafe(AVLTreeReverseIteratorSafe< Val, Cmp > &&from)
move constructor
AVLTreeReverseIteratorSafe(AVLTree< Val, Cmp > &tree, const bool rbegin=true)
constructor for rbegin safe iterators
~AVLTreeReverseIteratorSafe() noexcept
destructor
AVLTreeReverseIteratorSafe(const AVLTreeReverseIteratorSafe< Val, Cmp > &from)
copy constructor
std::bidirectional_iterator_tag iterator_category
Definition AVLTree.h:817
AVL binary search tree reverse iterator.
Definition AVLTree.h:702
AVLTreeReverseIterator(AVLTreeReverseIterator< Val, Cmp > &&from) noexcept
move constructor
AVLTreeReverseIterator(const AVLTreeReverseIterator< Val, Cmp > &from) noexcept
copy constructor
std::bidirectional_iterator_tag iterator_category
Definition AVLTree.h:706
~AVLTreeReverseIterator() noexcept
destructor
AVLTreeReverseIterator(const AVLTree< Val, Cmp > &tree, const bool rbegin=true) noexcept
constructor for rbegin iterators
AVL binary search tree.
Definition AVLTree.h:168
AVLNode * leftRotation_(AVLNode *node_p)
rotate the subtree rooted at p to the left
AVLTreeIteratorSafe< Val, Cmp > iterator_safe
Types for STL compliance.
Definition AVLTree.h:178
AVLTreeReverseIteratorSafe< Val, Cmp > reverse_iterator_safe
Types for STL compliance.
Definition AVLTree.h:180
AVLTree(AVLTree< Val, Cmp > &&from) noexcept
Move constructor.
AVLTreeIterator< Val, Cmp > iterator
Types for STL compliance.
Definition AVLTree.h:177
AVLTree(const Cmp &compare=Cmp())
Basic constructor.
const value_type & insert_(AVLNode *node)
insert a node into the tree
std::vector< iterator_safe * > safe_iterators_
The list of safe iterators and reverse iterators used by the AVL tree.
Definition AVLTree.h:387
void clear()
remove all the elements in the tree
~AVLTree()
Class destructor.
AVLNode * rightRotation_(AVLNode *node_q)
rotate the subtree rooted at q to the right
AVLTree(std::initializer_list< Val > list)
Initializer list constructor.
void erase_(AVLNode *node)
remove a node from the tree and free memory
void removeFromSafeList_(iterator_safe *iter)
unregister a safe iterator
bool contains(const value_type &val) const
Indicates whether the tree contains a given value.
AVLNode * highest_node_
the node containing the highest element
Definition AVLTree.h:375
Val value_type
Types for STL compliance.
Definition AVLTree.h:172
AVLNode * removeNodeFromTree_(AVLNode *node)
remove a node from the tree and returns the node that was actually removed
const value_type & highestValue() const
returns the max element (w.r.t. Cmp) in the tree
AVLNode * lowestNode_() const noexcept
returns the node containing the lowest element of the tree
AVLTreeNode< Val > AVLNode
Types for STL compliance.
Definition AVLTree.h:181
const Val * const_pointer
Types for STL compliance.
Definition AVLTree.h:176
bool empty() const noexcept
Indicates whether the tree is empty.
AVLTree< Val, Cmp > & operator=(AVLTree< Val, Cmp > &&from) noexcept
Move operator.
AVLNode * highestNode_() const noexcept
returns the node containing the highest element of the tree
AVLTreeReverseIterator< Val, Cmp > reverse_iterator
Types for STL compliance.
Definition AVLTree.h:179
const value_type & emplace(Args &&... args)
emplace a new element into the tree
iterator begin() const
returns a new iterator pointing to the minimal element of the tree
static AVLNode * copySubtree_(const AVLNode *from_node, AVLNode *new_parent)
copies recursively a subtree of the AVL tree
Val & reference
Types for STL compliance.
Definition AVLTree.h:173
AVLTree< Val, Cmp > & operator=(const AVLTree< Val, Cmp > &from)
Copy operator.
void erase(const value_type &val)
remove an element from the tree
bool exists(const value_type &val) const
Alias of contains: indicates whether the tree contains a given value.
bool owns_nodes_
indicates whether the tree owns its nodes. If not, it won't delete them
Definition AVLTree.h:381
AVLNode * root_node_
the root of the AVL tree
Definition AVLTree.h:369
constexpr const iterator_safe & endSafe() const
returns a safe iterator pointing just after the maximal element
Size size() const noexcept
Returns the number of elements in the tree.
iterator_safe beginSafe()
returns a new safe iterator pointing to the minimal element of the tree
void rebalanceTree_(AVLNode *node)
rebalance the tree moving up recursively from a given node
AVLTree(const AVLTree< Val, Cmp > &from)
Copy constructor.
constexpr const reverse_iterator & rend() const
returns an iterator pointing just before the minimal element
std::string toString() const
returns a string with the content of the tree, order from the lowest to the highest element
const value_type & insert(const value_type &val)
adds (by copy) a new element into the tree
static void deleteSubtree_(AVLNode *subtree_root_node)
deletes recursively a subtree of the AVL tree
void insertIntoSafeList_(iterator_safe *iter)
register a new safe iterator
Val * pointer
Types for STL compliance.
Definition AVLTree.h:175
reverse_iterator_safe rbeginSafe()
returns a safe iterator pointing to the maximal element of the tree
const value_type & lowestValue() const
returns the min element (w.r.t. Cmp) in the tree
constexpr const reverse_iterator_safe & rendSafe() const
returns a safe iterator pointing just before the minimal element
reverse_iterator rbegin() const
returns a new iterator pointing to the maximal element of the tree
const Val & const_reference
Types for STL compliance.
Definition AVLTree.h:174
AVLNode * lowest_node_
the node containing the lowest element
Definition AVLTree.h:372
Cmp cmp_
the comparison function
Definition AVLTree.h:384
constexpr const iterator & end() const
returns an iterator pointing just after the maximal element
Size nb_elements_
the number of elements in the tree
Definition AVLTree.h:378
This class should be useless as only its specializations should be used.
Definition hashFunc.h:487
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Classes providing basic hash functions for hash tables.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree
Definition AVLTree.h:913
STL namespace.
Data types to enable creating static variables at compile time.
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition tinystr.h:243