7 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>,
8 * Carsten Weinhold <weinhold@os.inf.tu-dresden.de>
9 * economic rights: Technische Universität Dresden (Germany)
11 * This file is part of TUD:OS and distributed under the terms of the
12 * GNU General Public License 2.
13 * Please see the COPYING-GPL-2 file for details.
15 * As a special exception, you may use this file as part of a free software
16 * library without restriction. Specifically, if other files instantiate
17 * templates or use macros or inline functions from this file, or you compile
18 * this file and link it with other files to produce an executable, this
19 * file does not by itself cause the resulting executable to be covered by
20 * the GNU General Public License. This exception does not however
21 * invalidate any other reasons why the executable file might be covered by
22 * the GNU General Public License.
29 namespace cxx { namespace Bits {
34 * \brief Generic iterator for the AVL-tree based set.
35 * \param Cmp the type of the comparison functor.
36 * \param Node the type of a node.
37 * \param Node_op the type used to determine the direction of the iterator.
39 template< typename Node, typename Node_op >
43 typedef Direction Dir;
44 Node const *_n; ///< Current node
45 Node const *_r; ///< Root node of current subtree
47 /// Create an invalid iterator, used as end marker.
48 __Bst_iter_b() : _n(0), _r(0) {}
51 * \brief Create an iterator for the given AVL tree.
52 * \param t the root node of the tree to iterate.
53 * \param cmp the comparison functor for tree elements.
55 __Bst_iter_b(Node const *t)
59 __Bst_iter_b(Node const *t, Node const *r)
63 /// traverse the subtree down to the leftmost/rightmost leave.
64 inline void _downmost();
66 /// Increment to the next element.
70 /// Check two iterators for equality.
71 bool operator == (__Bst_iter_b const &o) const { return _n == o._n; }
72 /// Check two iterators for non equality.
73 bool operator != (__Bst_iter_b const &o) const { return _n != o._n; }
79 * \brief Generic iterator for the AVL-tree based set.
80 * \param Node the type of a node.
81 * \param Node_type the type of the node to return stored in a node.
82 * \param Node_op the type used to determine the direction of the iterator.
84 template< typename Node, typename Node_type, typename Node_op >
85 class __Bst_iter : public __Bst_iter_b<Node, Node_op>
89 typedef __Bst_iter_b<Node, Node_op> Base;
96 /// Create an invalid iterator (end marker)
100 * \brief Create an iterator for the given tree.
101 * \param t the root node of the tree to iterate.
102 * \param cmp the conmparison functor for tree elements.
104 __Bst_iter(Node const *t) : Base(t) {}
105 __Bst_iter(Node const *t, Node const *r) : Base(t, r) {}
107 // template<typename Key2>
108 __Bst_iter(Base const &o) : Base(o) {}
111 * \brief Dereference the iterator and get the item out of the tree.
112 * \return A reference to the data stored in the AVL tree.
114 Node_type &operator * () const { return *const_cast<Node *>(_n); }
116 * \brief Member access to the item the iterator points to.
117 * \return A pointer to the item in the node.
119 Node_type *operator -> () const { return const_cast<Node *>(_n); }
121 * \brief Set the iterator to the next element (pre increment).
123 __Bst_iter &operator ++ () { inc(); return *this; }
125 * \brief Set the iterator to the next element (post increment).
127 __Bst_iter &operator ++ (int)
128 { __Bst_iter tmp = *this; inc(); return tmp; }
132 //----------------------------------------------------------------------------
133 /* IMPLEMENTATION: __Bst_iter_b */
135 template< typename Node, typename Node_op>
137 void __Bst_iter_b<Node, Node_op>::_downmost()
141 Node *n = Node_op::child(_n, Dir::L);
149 template< typename Node, typename Node_op>
150 void __Bst_iter_b<Node, Node_op>::inc()
157 _r = _n = Node_op::child(_r, Dir::R);
162 if (Node_op::child(_n, Dir::R))
164 _n = Node_op::child(_n, Dir::R);
173 if (Node_op::cmp(_n, q))
176 q = Node_op::child(q, Dir::L);
178 else if (_n == q || Node_op::child(q, Dir::R) == _n)
184 q = Node_op::child(q, Dir::R);