Fix several warnings that appear in gcc 4.3.2.
[wvstreams.git] / uniconf / unihashtree.cc
blob4b7f25516af27049fe99ff08300f982e8876386e
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * UniConf low-level tree storage abstraction.
6 */
7 #include "unihashtree.h"
8 #include "assert.h"
11 UniHashTreeBase::UniHashTreeBase(UniHashTreeBase *parent,
12 const UniConfKey &key) :
13 xkey(key)
15 xparent = parent;
16 xchildren = NULL;
18 if (xparent)
19 xparent->link(this);
23 UniHashTreeBase::~UniHashTreeBase()
25 if (xchildren)
27 Container *oldchildren = xchildren;
28 xchildren = NULL;
30 delete oldchildren;
33 // This happens only after the children are deleted by our
34 // subclass. This ensures that we do not confuse them
35 // about their parentage as their destructors are invoked
36 // The xchildren vector is destroyed by the subclass!
37 if (xparent)
38 xparent->unlink(this);
42 void UniHashTreeBase::_setparent(UniHashTreeBase *parent)
44 if (xparent == parent)
45 return;
46 if (xparent)
47 xparent->unlink(this);
48 xparent = parent;
49 if (xparent)
50 xparent->link(this);
54 UniHashTreeBase *UniHashTreeBase::_root() const
56 const UniHashTreeBase *node = this;
57 while (node->xparent)
58 node = node->xparent;
59 return const_cast<UniHashTreeBase*>(node);
63 UniConfKey UniHashTreeBase::_fullkey(const UniHashTreeBase *ancestor) const
65 UniConfKey result;
66 if (ancestor)
68 const UniHashTreeBase *node = this;
69 while (node != ancestor)
71 result.prepend(node->key());
72 node = node->xparent;
73 assert(node != NULL ||
74 ! "ancestor was not a node in the tree");
77 else
79 const UniHashTreeBase *node = this;
80 while (node->xparent)
82 result.prepend(node->key());
83 node = node->xparent;
86 return result;
90 UniHashTreeBase *UniHashTreeBase::_find(const UniConfKey &key) const
92 const UniHashTreeBase *node = this;
93 UniConfKey::Iter it(key);
94 it.rewind();
95 while (it.next())
97 node = node->_findchild(it());
98 if (!node)
99 break;
101 return const_cast<UniHashTreeBase*>(node);
105 UniHashTreeBase *UniHashTreeBase::_findchild(const UniConfKey &key) const
107 if (key.isempty())
108 return const_cast<UniHashTreeBase*>(this);
110 return xchildren ? (*xchildren)[key] : NULL;
114 bool UniHashTreeBase::haschildren() const
116 return xchildren && !xchildren->isempty();
120 void UniHashTreeBase::link(UniHashTreeBase *node)
122 if (!xchildren)
123 xchildren = new Container();
125 xchildren->add(node);
129 void UniHashTreeBase::unlink(UniHashTreeBase *node)
131 if (!xchildren)
132 return;
134 xchildren->remove(node);
135 if (xchildren->count() == 0)
137 delete xchildren;
138 xchildren = NULL;
143 static int keysorter(const UniHashTreeBase *a, const UniHashTreeBase *b)
145 return a->key().compareto(b->key());
148 void UniHashTreeBase::_recursive_unsorted_visit(
149 const UniHashTreeBase *a,
150 const UniHashTreeBaseVisitor &visitor, void *userdata,
151 bool preorder, bool postorder)
153 if (preorder)
154 visitor(a, userdata);
155 Container::Iter i(*const_cast<Container*>(a->xchildren));
156 for (i.rewind(); i.next();)
157 _recursive_unsorted_visit(i.ptr(), visitor, userdata,
158 preorder, postorder);
159 if (postorder)
160 visitor(a, userdata);
163 bool UniHashTreeBase::_recursivecompare(
164 const UniHashTreeBase *a, const UniHashTreeBase *b,
165 const UniHashTreeBaseComparator &comparator)
167 bool equal = true;
169 // don't bother comparing subtree if this returns false
170 // apenwarr 2004/04/26: some people seem to call recursivecompare and
171 // have their comparator function get called for *all* keys, because
172 // it has side effects. Gross, but whatever. If that's the case, then
173 // short-circuiting here is a bad idea.
174 if (!comparator(a, b))
175 equal = false;
177 // begin iteration sequence
178 Container::Sorter *ait = NULL, *bit = NULL;
179 if (a != NULL)
181 ait = new Container::Sorter(*const_cast<Container*>(a->xchildren),
182 keysorter);
183 ait->rewind();
184 a = ait->next() ? ait->ptr() : NULL;
186 if (b != NULL)
188 bit = new Container::Sorter(*const_cast<Container*>(b->xchildren),
189 keysorter);
190 bit->rewind();
191 b = bit->next() ? bit->ptr() : NULL;
194 // compare each key
195 while (a != NULL && b != NULL)
197 int order = a->key().compareto(b->key());
198 if (order < 0)
200 equal = false;
201 _recursivecompare(a, NULL, comparator);
202 a = ait->next() ? ait->ptr() : NULL;
204 else if (order > 0)
206 equal = false;
207 _recursivecompare(NULL, b, comparator);
208 b = bit->next() ? bit->ptr() : NULL;
210 else // keys are equal
212 if (!_recursivecompare(a, b, comparator))
213 equal = false;
214 a = ait->next() ? ait->ptr() : NULL;
215 b = bit->next() ? bit->ptr() : NULL;
219 // finish up if one side is bigger than the other
220 while (a != NULL)
222 equal = false;
223 _recursivecompare(a, NULL, comparator);
224 a = ait->next() ? ait->ptr() : NULL;
226 while (b != NULL)
228 equal = false;
229 _recursivecompare(NULL, b, comparator);
230 b = bit->next() ? bit->ptr() : NULL;
233 delete ait;
234 delete bit;
236 return equal;