1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
3
<title>LibOFX: tree.hh Source File</title>
4
<link href="doxygen.css" rel="stylesheet" type="text/css">
6
<!-- Generated by Doxygen 1.3.9.1 -->
7
<div class="qindex"><a class="qindex" href="main.html">Main Page</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a></div>
9
<a class="el" href="dir_000003.html">libofx-0.8.0</a> / <a class="el" href="dir_000004.html">lib</a></div>
10
<h1>fx-0.8.0/lib/tree.hh</h1><div class="fragment"><pre class="fragment">00001 <span class="comment">/* </span>
11
00002 <span class="comment"></span>
12
00003 <span class="comment"> $Id: tree.hh,v 1.3 2004/04/09 06:51:45 benoitg Exp $</span>
13
00004 <span class="comment"></span>
14
00005 <span class="comment"> STL-like templated tree class.</span>
15
00006 <span class="comment"> Copyright (C) 2001 Kasper Peeters <k.peeters@damtp.cam.ac.uk></span>
16
00007 <span class="comment"></span>
17
00008 <span class="comment"> See </span>
18
00009 <span class="comment"> </span>
19
00010 <span class="comment"> http://www.damtp.cam.ac.uk/user/kp229/tree/</span>
20
00011 <span class="comment"></span>
21
00012 <span class="comment"> for more information and documentation. See the Changelog file for</span>
22
00013 <span class="comment"> other credits.</span>
23
00014 <span class="comment"></span>
24
00015 <span class="comment"> This program is free software; you can redistribute it and/or modify</span>
25
00016 <span class="comment"> it under the terms of the GNU General Public License as published by</span>
26
00017 <span class="comment"> the Free Software Foundation; version 2.</span>
27
00018 <span class="comment"> </span>
28
00019 <span class="comment"> This program is distributed in the hope that it will be useful,</span>
29
00020 <span class="comment"> but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
30
00021 <span class="comment"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
31
00022 <span class="comment"> GNU General Public License for more details.</span>
32
00023 <span class="comment"> </span>
33
00024 <span class="comment"> You should have received a copy of the GNU General Public License</span>
34
00025 <span class="comment"> along with this program; if not, write to the Free Software</span>
35
00026 <span class="comment"> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</span>
36
00027 <span class="comment"> </span>
37
00028 <span class="comment"> TODO: - 'Move' members are long overdue; will hopefully be incorporated in the</span>
38
00029 <span class="comment"> next release.</span>
39
00030 <span class="comment"> - Fixed depth iterators do not iterate over the entire range if there</span>
40
00031 <span class="comment"> are 'holes' in the tree.</span>
41
00032 <span class="comment"> - If a range uses const iter_base& as end iterator, things will</span>
42
00033 <span class="comment"> inevitably go wrong, because upcast from iter_base to a non-sibling_iter</span>
43
00034 <span class="comment"> is incorrect. This upcast should be removed (and then all illegal uses</span>
44
00035 <span class="comment"> as previously in 'equal' will be flagged by the compiler). This requires</span>
45
00036 <span class="comment"> new copy constructors though.</span>
46
00037 <span class="comment"> - There's a bug in replace(sibling_iterator, ...) when the ranges</span>
47
00038 <span class="comment"> sit next to each other. Turned up in append_child(iter,iter)</span>
48
00039 <span class="comment"> but has been avoided now.</span>
49
00040 <span class="comment"> - "std::operator<" does not work correctly on our iterators, and for some</span>
50
00041 <span class="comment"> reason a globally defined template operator< did not get picked up. </span>
51
00042 <span class="comment"> Using a comparison class now, but this should be investigated.</span>
52
00043 <span class="comment">*/</span>
54
00045 <span class="preprocessor">#ifndef tree_hh_</span>
55
00046 <span class="preprocessor"></span><span class="preprocessor">#define tree_hh_</span>
56
00047 <span class="preprocessor"></span>
57
00048 <span class="preprocessor">#include <cassert></span>
58
00049 <span class="preprocessor">#include <memory></span>
59
00050 <span class="preprocessor">#include <stdexcept></span>
60
00051 <span class="preprocessor">#include <iterator></span>
61
00052 <span class="preprocessor">#include <set></span>
63
00054 <span class="comment">// HP-style construct/destroy have gone from the standard,</span>
64
00055 <span class="comment">// so here is a copy.</span>
66
00057 <span class="keyword">namespace </span>kp {
68
00059 <span class="keyword">template</span> <<span class="keyword">class</span> T1, <span class="keyword">class</span> T2>
69
00060 <span class="keyword">inline</span> <span class="keywordtype">void</span> constructor(T1* p, T2& val)
71
00062 <span class="keyword">new</span> ((<span class="keywordtype">void</span> *) p) T1(val);
74
00065 <span class="keyword">template</span> <<span class="keyword">class</span> T1>
75
00066 <span class="keyword">inline</span> <span class="keywordtype">void</span> constructor(T1* p)
77
00068 <span class="keyword">new</span> ((<span class="keywordtype">void</span> *) p) T1;
80
00071 <span class="keyword">template</span> <<span class="keyword">class</span> T1>
81
00072 <span class="keyword">inline</span> <span class="keywordtype">void</span> kp::destructor(T1* p)
88
00079 <span class="keyword">template</span><<span class="keyword">class</span> T>
89
00080 <span class="keyword">class </span>tree_node_ { <span class="comment">// size: 5*4=20 bytes (on 32 bit arch), can be reduced by 8.</span>
90
00081 <span class="keyword">public</span>:
91
00082 tree_node_<T> *parent;
92
00083 tree_node_<T> *first_child, *last_child;
93
00084 tree_node_<T> *prev_sibling, *next_sibling;
97
00088 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator = std::allocator<tree_node_<T> > >
98
00089 <span class="keyword">class </span>tree {
99
00090 <span class="keyword">protected</span>:
100
00091 <span class="keyword">typedef</span> tree_node_<T> tree_node;
101
00092 <span class="keyword">public</span>:
102
00093 <span class="keyword">typedef</span> T value_type;
104
00095 <span class="keyword">class </span>iterator_base;
105
00096 <span class="keyword">class </span>pre_order_iterator;
106
00097 <span class="keyword">class </span>post_order_iterator;
107
00098 <span class="keyword">class </span>sibling_iterator;
110
00101 tree(<span class="keyword">const</span> T&);
111
00102 tree(<span class="keyword">const</span> iterator_base&);
112
00103 tree(<span class="keyword">const</span> tree<T, tree_node_allocator>&);
114
00105 <span class="keywordtype">void</span> operator=(<span class="keyword">const</span> tree<T, tree_node_allocator>&);
116
00107 <span class="preprocessor">#ifdef __SGI_STL_PORT</span>
117
00108 <span class="preprocessor"></span> <span class="keyword">class </span>iterator_base : <span class="keyword">public</span> stlport::bidirectional_iterator<T, ptrdiff_t> {
118
00109 <span class="preprocessor">#else</span>
119
00110 <span class="preprocessor"></span> <span class="keyword">class </span>iterator_base {
120
00111 <span class="preprocessor">#endif</span>
121
00112 <span class="preprocessor"></span> <span class="keyword">public</span>:
122
00113 <span class="keyword">typedef</span> T value_type;
123
00114 <span class="keyword">typedef</span> T* pointer;
124
00115 <span class="keyword">typedef</span> T& reference;
125
00116 <span class="keyword">typedef</span> size_t size_type;
126
00117 <span class="keyword">typedef</span> ptrdiff_t difference_type;
127
00118 <span class="keyword">typedef</span> std::bidirectional_iterator_tag iterator_category;
129
00120 iterator_base();
130
00121 iterator_base(tree_node *);
132
00123 T& operator*() <span class="keyword">const</span>;
133
00124 T* operator->() <span class="keyword">const</span>;
135
00126 <span class="keywordtype">void</span> skip_children(); <span class="comment">// do not iterate over children of this node</span>
136
00127 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> number_of_children() <span class="keyword">const</span>;
138
00129 sibling_iterator begin() <span class="keyword">const</span>;
139
00130 sibling_iterator end() <span class="keyword">const</span>;
141
00132 tree_node *node;
142
00133 <span class="keyword">protected</span>:
143
00134 <span class="keywordtype">bool</span> skip_current_children_;
146
00137 <span class="keyword">class </span>pre_order_iterator : <span class="keyword">public</span> iterator_base {
147
00138 <span class="keyword">public</span>:
148
00139 pre_order_iterator();
149
00140 pre_order_iterator(tree_node *);
150
00141 pre_order_iterator(<span class="keyword">const</span> iterator_base&);
151
00142 pre_order_iterator(<span class="keyword">const</span> sibling_iterator&);
153
00144 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> pre_order_iterator&) <span class="keyword">const</span>;
154
00145 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> pre_order_iterator&) <span class="keyword">const</span>;
155
00146 pre_order_iterator& operator++();
156
00147 pre_order_iterator& operator--();
157
00148 pre_order_iterator operator++(<span class="keywordtype">int</span>);
158
00149 pre_order_iterator operator--(<span class="keywordtype">int</span>);
159
00150 pre_order_iterator& operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
160
00151 pre_order_iterator& operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
163
00154 <span class="keyword">class </span>post_order_iterator : <span class="keyword">public</span> iterator_base {
164
00155 <span class="keyword">public</span>:
165
00156 post_order_iterator();
166
00157 post_order_iterator(tree_node *);
167
00158 post_order_iterator(<span class="keyword">const</span> iterator_base&);
168
00159 post_order_iterator(<span class="keyword">const</span> sibling_iterator&);
170
00161 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> post_order_iterator&) <span class="keyword">const</span>;
171
00162 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> post_order_iterator&) <span class="keyword">const</span>;
172
00163 post_order_iterator& operator++();
173
00164 post_order_iterator& operator--();
174
00165 post_order_iterator operator++(<span class="keywordtype">int</span>);
175
00166 post_order_iterator operator--(<span class="keywordtype">int</span>);
176
00167 post_order_iterator& operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
177
00168 post_order_iterator& operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
179
00170 <span class="keywordtype">void</span> descend_all();
182
00173 <span class="keyword">typedef</span> pre_order_iterator iterator;
184
00175 <span class="keyword">class </span>fixed_depth_iterator : <span class="keyword">public</span> iterator_base {
185
00176 <span class="keyword">public</span>:
186
00177 fixed_depth_iterator();
187
00178 fixed_depth_iterator(tree_node *);
188
00179 fixed_depth_iterator(<span class="keyword">const</span> iterator_base&);
189
00180 fixed_depth_iterator(<span class="keyword">const</span> sibling_iterator&);
190
00181 fixed_depth_iterator(<span class="keyword">const</span> fixed_depth_iterator&);
192
00183 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> fixed_depth_iterator&) <span class="keyword">const</span>;
193
00184 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> fixed_depth_iterator&) <span class="keyword">const</span>;
194
00185 fixed_depth_iterator& operator++();
195
00186 fixed_depth_iterator& operator--();
196
00187 fixed_depth_iterator operator++(<span class="keywordtype">int</span>);
197
00188 fixed_depth_iterator operator--(<span class="keywordtype">int</span>);
198
00189 fixed_depth_iterator& operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
199
00190 fixed_depth_iterator& operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
201
00192 tree_node *first_parent_;
202
00193 <span class="keyword">private</span>:
203
00194 <span class="keywordtype">void</span> set_first_parent_();
204
00195 <span class="keywordtype">void</span> find_leftmost_parent_();
207
00198 <span class="keyword">class </span>sibling_iterator : <span class="keyword">public</span> iterator_base {
208
00199 <span class="keyword">public</span>:
209
00200 sibling_iterator();
210
00201 sibling_iterator(tree_node *);
211
00202 sibling_iterator(<span class="keyword">const</span> sibling_iterator&);
212
00203 sibling_iterator(<span class="keyword">const</span> iterator_base&);
214
00205 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> sibling_iterator&) <span class="keyword">const</span>;
215
00206 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> sibling_iterator&) <span class="keyword">const</span>;
216
00207 sibling_iterator& operator++();
217
00208 sibling_iterator& operator--();
218
00209 sibling_iterator operator++(<span class="keywordtype">int</span>);
219
00210 sibling_iterator operator--(<span class="keywordtype">int</span>);
220
00211 sibling_iterator& operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
221
00212 sibling_iterator& operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>);
223
00214 tree_node *range_first() <span class="keyword">const</span>;
224
00215 tree_node *range_last() <span class="keyword">const</span>;
225
00216 tree_node *parent_;
226
00217 <span class="keyword">private</span>:
227
00218 <span class="keywordtype">void</span> set_parent_();
230
00221 <span class="comment">// begin/end of tree</span>
231
00222 pre_order_iterator begin() <span class="keyword">const</span>;
232
00223 pre_order_iterator end() <span class="keyword">const</span>;
233
00224 post_order_iterator begin_post() <span class="keyword">const</span>;
234
00225 post_order_iterator end_post() <span class="keyword">const</span>;
235
00226 fixed_depth_iterator begin_fixed(<span class="keyword">const</span> iterator_base&, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) <span class="keyword">const</span>;
236
00227 fixed_depth_iterator end_fixed(<span class="keyword">const</span> iterator_base&, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) <span class="keyword">const</span>;
237
00228 <span class="comment">// begin/end of children of node</span>
238
00229 sibling_iterator begin(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
239
00230 sibling_iterator end(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
241
00232 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter parent(iter) <span class="keyword">const</span>;
242
00233 sibling_iterator previous_sibling(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
243
00234 sibling_iterator next_sibling(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
245
00236 <span class="keywordtype">void</span> clear();
246
00237 <span class="comment">// erase element at position pointed to by iterator, increment iterator</span>
247
00238 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter erase(iter);
248
00239 <span class="comment">// erase all children of the node pointed to by iterator</span>
249
00240 <span class="keywordtype">void</span> erase_children(<span class="keyword">const</span> iterator_base&);
251
00242 <span class="comment">// insert node as last child of node pointed to by position (first one inserts empty node)</span>
252
00243 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter append_child(iter position);
253
00244 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter append_child(iter position, <span class="keyword">const</span> T& x);
254
00245 <span class="comment">// the following two append nodes plus their children</span>
255
00246 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter append_child(iter position, iter other_position);
256
00247 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter append_children(iter position, sibling_iterator from, sibling_iterator to);
258
00249 <span class="comment">// short-hand to insert topmost node in otherwise empty tree</span>
259
00250 pre_order_iterator set_head(<span class="keyword">const</span> T& x);
260
00251 <span class="comment">// insert node as previous sibling of node pointed to by position</span>
261
00252 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter insert(iter position, <span class="keyword">const</span> T& x);
262
00253 <span class="comment">// specialisation: insert node as previous sibling of node pointed to by position</span>
263
00254 <span class="comment">//pre_order_iterator insert(sibling_iterator position, const T& x);</span>
264
00255 sibling_iterator insert(sibling_iterator position, <span class="keyword">const</span> T& x);
265
00256 <span class="comment">// insert node (with children) pointed to by subtree as previous sibling of node pointed to by position</span>
266
00257 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter insert_subtree(iter position, <span class="keyword">const</span> iterator_base& subtree);
267
00258 <span class="comment">// insert node as next sibling of node pointed to by position</span>
268
00259 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter insert_after(iter position, <span class="keyword">const</span> T& x);
270
00261 <span class="comment">// replace node at 'position' with other node (keeping same children); 'position' becomes invalid.</span>
271
00262 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter replace(iter position, <span class="keyword">const</span> T& x);
272
00263 <span class="comment">// replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from'); see above.</span>
273
00264 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter replace(iter position, <span class="keyword">const</span> iterator_base& from);
274
00265 <span class="comment">// replace string of siblings (plus their children) with copy of a new string (with children); see above</span>
275
00266 sibling_iterator replace(sibling_iterator orig_begin, sibling_iterator orig_end,
276
00267 sibling_iterator new_begin, sibling_iterator new_end);
278
00269 <span class="comment">// move all children of node at 'position' to be siblings, returns position</span>
279
00270 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter flatten(iter position);
280
00271 <span class="comment">// move nodes in range to be children of 'position'</span>
281
00272 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter reparent(iter position, sibling_iterator begin, sibling_iterator end);
282
00273 <span class="comment">// ditto, the range being all children of the 'from' node</span>
283
00274 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter reparent(iter position, iter from);
285
00276 <span class="comment">// new style move members, moving nodes plus children to a different </span>
286
00277 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter move_after(iter target, iter source);
287
00278 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter move_before(iter target, iter source);
288
00279 <span class="keyword">template</span><<span class="keyword">typename</span> iter> iter move_below(iter target, iter source);
290
00281 <span class="comment">// merge with other tree, creating new branches and leaves only if they are not already present</span>
291
00282 <span class="keywordtype">void</span> merge(sibling_iterator, sibling_iterator, sibling_iterator, sibling_iterator,
292
00283 <span class="keywordtype">bool</span> duplicate_leaves=<span class="keyword">false</span>);
293
00284 <span class="comment">// sort (std::sort only moves values of nodes, this one moves children as well)</span>
294
00285 <span class="keywordtype">void</span> sort(sibling_iterator from, sibling_iterator to, <span class="keywordtype">bool</span> deep=<span class="keyword">false</span>);
295
00286 <span class="keyword">template</span><<span class="keyword">class</span> StrictWeakOrdering>
296
00287 <span class="keywordtype">void</span> sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, <span class="keywordtype">bool</span> deep=<span class="keyword">false</span>);
297
00288 <span class="comment">// compare two ranges of nodes (compares nodes as well as tree structure)</span>
298
00289 <span class="keyword">template</span><<span class="keyword">typename</span> iter>
299
00290 <span class="keywordtype">bool</span> equal(<span class="keyword">const</span> iter& one, <span class="keyword">const</span> iter& two, <span class="keyword">const</span> iter& three) <span class="keyword">const</span>;
300
00291 <span class="keyword">template</span><<span class="keyword">typename</span> iter, <span class="keyword">class</span> BinaryPredicate>
301
00292 <span class="keywordtype">bool</span> equal(<span class="keyword">const</span> iter& one, <span class="keyword">const</span> iter& two, <span class="keyword">const</span> iter& three, BinaryPredicate) <span class="keyword">const</span>;
302
00293 <span class="keyword">template</span><<span class="keyword">typename</span> iter>
303
00294 <span class="keywordtype">bool</span> equal_subtree(<span class="keyword">const</span> iter& one, <span class="keyword">const</span> iter& two) <span class="keyword">const</span>;
304
00295 <span class="keyword">template</span><<span class="keyword">typename</span> iter, <span class="keyword">class</span> BinaryPredicate>
305
00296 <span class="keywordtype">bool</span> equal_subtree(<span class="keyword">const</span> iter& one, <span class="keyword">const</span> iter& two, BinaryPredicate) <span class="keyword">const</span>;
306
00297 <span class="comment">// extract a new tree formed by the range of siblings plus all their children</span>
307
00298 tree subtree(sibling_iterator from, sibling_iterator to) <span class="keyword">const</span>;
308
00299 <span class="keywordtype">void</span> subtree(tree&, sibling_iterator from, sibling_iterator to) <span class="keyword">const</span>;
309
00300 <span class="comment">// exchange the node (plus subtree) with its sibling node (do nothing if no sibling present)</span>
310
00301 <span class="keywordtype">void</span> swap(sibling_iterator it);
311
00302 <span class="comment">// find a subtree</span>
312
00303 <span class="comment">// template<class BinaryPredicate></span>
313
00304 <span class="comment">// iterator find_subtree(sibling_iterator, sibling_iterator, iterator from, iterator to, BinaryPredicate) const;</span>
315
00306 <span class="comment">// count the total number of nodes</span>
316
00307 <span class="keywordtype">int</span> size() <span class="keyword">const</span>;
317
00308 <span class="comment">// check if tree is empty</span>
318
00309 <span class="keywordtype">bool</span> empty() <span class="keyword">const</span>;
319
00310 <span class="comment">// compute the depth to the root</span>
320
00311 <span class="keywordtype">int</span> depth(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
321
00312 <span class="comment">// count the number of children of node at position</span>
322
00313 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> number_of_children(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
323
00314 <span class="comment">// count the number of 'next' siblings of node at iterator</span>
324
00315 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> number_of_siblings(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
325
00316 <span class="comment">// determine whether node at position is in the subtrees with root in the range</span>
326
00317 <span class="keywordtype">bool</span> is_in_subtree(<span class="keyword">const</span> iterator_base& position, <span class="keyword">const</span> iterator_base& begin,
327
00318 <span class="keyword">const</span> iterator_base& end) <span class="keyword">const</span>;
328
00319 <span class="comment">// determine whether the iterator is an 'end' iterator and thus not actually</span>
329
00320 <span class="comment">// pointing to a node</span>
330
00321 <span class="keywordtype">bool</span> is_valid(<span class="keyword">const</span> iterator_base&) <span class="keyword">const</span>;
332
00323 <span class="comment">// determine the index of a node in the range of siblings to which it belongs.</span>
333
00324 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> index(sibling_iterator it) <span class="keyword">const</span>;
334
00325 <span class="comment">// inverse of 'index': return the n-th child of the node at position</span>
335
00326 sibling_iterator child(<span class="keyword">const</span> iterator_base& position, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) <span class="keyword">const</span>;
337
00328 <span class="keyword">class </span>iterator_base_less {
338
00329 <span class="keyword">public</span>:
339
00330 <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> <span class="keyword">typename</span> tree<T, tree_node_allocator>::iterator_base& one,
340
00331 <span class="keyword">const</span> <span class="keyword">typename</span> tree<T, tree_node_allocator>::iterator_base& two)<span class="keyword"> const</span>
341
00332 <span class="keyword"> </span>{
342
00333 <span class="keywordflow">return</span> one.node < two.node;
345
00336 tree_node *head, *feet; <span class="comment">// head/feet are always dummy; if an iterator points to them it is invalid</span>
346
00337 <span class="keyword">private</span>:
347
00338 tree_node_allocator alloc_;
348
00339 <span class="keywordtype">void</span> head_initialise_();
349
00340 <span class="keywordtype">void</span> copy_(<span class="keyword">const</span> tree<T, tree_node_allocator>& other);
350
00341 <span class="keyword">template</span><<span class="keyword">class</span> StrictWeakOrdering>
351
00342 <span class="keyword">class </span>compare_nodes {
352
00343 <span class="keyword">public</span>:
353
00344 <span class="keywordtype">bool</span> operator()(<span class="keyword">const</span> tree_node*, <span class="keyword">const</span> tree_node *);
357
00348 <span class="comment">//template <class T, class tree_node_allocator></span>
358
00349 <span class="comment">//class iterator_base_less {</span>
359
00350 <span class="comment">// public:</span>
360
00351 <span class="comment">// bool operator()(const typename tree<T, tree_node_allocator>::iterator_base& one,</span>
361
00352 <span class="comment">// const typename tree<T, tree_node_allocator>::iterator_base& two) const</span>
362
00353 <span class="comment">// {</span>
363
00354 <span class="comment">// txtout << "operatorclass<" << one.node < two.node << std::endl;</span>
364
00355 <span class="comment">// return one.node < two.node;</span>
365
00356 <span class="comment">// }</span>
366
00357 <span class="comment">//};</span>
368
00359 <span class="comment">//template <class T, class tree_node_allocator></span>
369
00360 <span class="comment">//bool operator<(const typename tree<T, tree_node_allocator>::iterator& one,</span>
370
00361 <span class="comment">// const typename tree<T, tree_node_allocator>::iterator& two)</span>
371
00362 <span class="comment">// {</span>
372
00363 <span class="comment">// txtout << "operator< " << one.node < two.node << std::endl;</span>
373
00364 <span class="comment">// if(one.node < two.node) return true;</span>
374
00365 <span class="comment">// return false;</span>
375
00366 <span class="comment">// }</span>
377
00368 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
378
00369 <span class="keywordtype">bool</span> operator>(<span class="keyword">const</span> <span class="keyword">typename</span> tree<T, tree_node_allocator>::iterator_base& one,
379
00370 <span class="keyword">const</span> <span class="keyword">typename</span> tree<T, tree_node_allocator>::iterator_base& two)
381
00372 <span class="keywordflow">if</span>(one.node > two.node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
382
00373 <span class="keywordflow">return</span> <span class="keyword">false</span>;
387
00378 <span class="comment">// Tree</span>
389
00380 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
390
00381 tree<T, tree_node_allocator>::tree()
392
00383 head_initialise_();
395
00386 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
396
00387 tree<T, tree_node_allocator>::tree(<span class="keyword">const</span> T& x)
398
00389 head_initialise_();
402
00393 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
403
00394 tree<T, tree_node_allocator>::tree(<span class="keyword">const</span> iterator_base& other)
405
00396 head_initialise_();
406
00397 set_head((*other));
407
00398 replace(begin(), other);
410
00401 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
411
00402 tree<T, tree_node_allocator>::~tree()
414
00405 alloc_.deallocate(head,1);
415
00406 alloc_.deallocate(feet,1);
418
00409 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
419
00410 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::head_initialise_()
421
00412 head = alloc_.allocate(1,0); <span class="comment">// MSVC does not have default second argument </span>
422
00413 feet = alloc_.allocate(1,0);
424
00415 head->parent=0;
425
00416 head->first_child=0;
426
00417 head->last_child=0;
427
00418 head->prev_sibling=0; <span class="comment">//head;</span>
428
00419 head->next_sibling=feet; <span class="comment">//head;</span>
430
00421 feet->parent=0;
431
00422 feet->first_child=0;
432
00423 feet->last_child=0;
433
00424 feet->prev_sibling=head;
434
00425 feet->next_sibling=0;
437
00428 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
438
00429 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::operator=(<span class="keyword">const</span> tree<T, tree_node_allocator>& other)
443
00434 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
444
00435 tree<T, tree_node_allocator>::tree(<span class="keyword">const</span> tree<T, tree_node_allocator>& other)
446
00437 head_initialise_();
450
00441 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
451
00442 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::copy_(<span class="keyword">const</span> tree<T, tree_node_allocator>& other)
454
00445 pre_order_iterator it=other.begin(), to=begin();
455
00446 <span class="keywordflow">while</span>(it!=other.end()) {
456
00447 to=insert(to, (*it));
457
00448 it.skip_children();
461
00452 it=other.begin();
462
00453 <span class="keywordflow">while</span>(it!=other.end()) {
463
00454 to=replace(to, it);
464
00455 to.skip_children();
465
00456 it.skip_children();
471
00462 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
472
00463 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::clear()
474
00465 <span class="keywordflow">if</span>(head)
475
00466 <span class="keywordflow">while</span>(head->next_sibling!=feet)
476
00467 erase(pre_order_iterator(head->next_sibling));
479
00470 <span class="keyword">template</span><<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
480
00471 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::erase_children(<span class="keyword">const</span> iterator_base& it)
482
00473 tree_node *cur=it.node->first_child;
483
00474 tree_node *prev=0;
485
00476 <span class="keywordflow">while</span>(cur!=0) {
487
00478 cur=cur->next_sibling;
488
00479 erase_children(pre_order_iterator(prev));
489
00480 kp::destructor(&prev->data);
490
00481 alloc_.deallocate(prev,1);
492
00483 it.node->first_child=0;
493
00484 it.node->last_child=0;
496
00487 <span class="keyword">template</span><<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
497
00488 <span class="keyword">template</span><<span class="keyword">class</span> iter>
498
00489 iter tree<T, tree_node_allocator>::erase(iter it)
500
00491 tree_node *cur=it.node;
501
00492 assert(cur!=head);
503
00494 ret.skip_children();
505
00496 erase_children(it);
506
00497 <span class="keywordflow">if</span>(cur->prev_sibling==0) {
507
00498 cur->parent->first_child=cur->next_sibling;
509
00500 <span class="keywordflow">else</span> {
510
00501 cur->prev_sibling->next_sibling=cur->next_sibling;
512
00503 <span class="keywordflow">if</span>(cur->next_sibling==0) {
513
00504 cur->parent->last_child=cur->prev_sibling;
515
00506 <span class="keywordflow">else</span> {
516
00507 cur->next_sibling->prev_sibling=cur->prev_sibling;
519
00510 kp::destructor(&cur->data);
520
00511 alloc_.deallocate(cur,1);
521
00512 <span class="keywordflow">return</span> ret;
524
00515 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
525
00516 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::begin()<span class="keyword"> const</span>
526
00517 <span class="keyword"> </span>{
527
00518 <span class="keywordflow">return</span> pre_order_iterator(head->next_sibling);
530
00521 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
531
00522 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::end()<span class="keyword"> const</span>
532
00523 <span class="keyword"> </span>{
533
00524 <span class="keywordflow">return</span> pre_order_iterator(feet);
536
00527 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
537
00528 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::begin_post()<span class="keyword"> const</span>
538
00529 <span class="keyword"> </span>{
539
00530 tree_node *tmp=head->next_sibling;
540
00531 <span class="keywordflow">if</span>(tmp!=feet) {
541
00532 <span class="keywordflow">while</span>(tmp->first_child)
542
00533 tmp=tmp->first_child;
544
00535 <span class="keywordflow">return</span> post_order_iterator(tmp);
547
00538 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
548
00539 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::end_post()<span class="keyword"> const</span>
549
00540 <span class="keyword"> </span>{
550
00541 <span class="keywordflow">return</span> post_order_iterator(feet);
553
00544 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
554
00545 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::begin_fixed(<span class="keyword">const</span> iterator_base& pos, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> dp)<span class="keyword"> const</span>
555
00546 <span class="keyword"> </span>{
556
00547 tree_node *tmp=pos.node;
557
00548 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> curdepth=0;
558
00549 <span class="keywordflow">while</span>(curdepth<dp) { <span class="comment">// go down one level</span>
559
00550 <span class="keywordflow">while</span>(tmp->first_child==0) {
560
00551 tmp=tmp->next_sibling;
561
00552 <span class="keywordflow">if</span>(tmp==0)
562
00553 <span class="keywordflow">throw</span> std::range_error(<span class="stringliteral">"tree: begin_fixed out of range"</span>);
564
00555 tmp=tmp->first_child;
567
00558 <span class="keywordflow">return</span> tmp;
570
00561 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
571
00562 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::end_fixed(<span class="keyword">const</span> iterator_base& pos, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> dp)<span class="keyword"> const</span>
572
00563 <span class="keyword"> </span>{
573
00564 assert(1==0); <span class="comment">// FIXME: not correct yet</span>
574
00565 tree_node *tmp=pos.node;
575
00566 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> curdepth=1;
576
00567 <span class="keywordflow">while</span>(curdepth<dp) { <span class="comment">// go down one level</span>
577
00568 <span class="keywordflow">while</span>(tmp->first_child==0) {
578
00569 tmp=tmp->next_sibling;
579
00570 <span class="keywordflow">if</span>(tmp==0)
580
00571 <span class="keywordflow">throw</span> std::range_error(<span class="stringliteral">"tree: end_fixed out of range"</span>);
582
00573 tmp=tmp->first_child;
585
00576 <span class="keywordflow">return</span> tmp;
588
00579 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
589
00580 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::begin(<span class="keyword">const</span> iterator_base& pos)<span class="keyword"> const</span>
590
00581 <span class="keyword"> </span>{
591
00582 <span class="keywordflow">if</span>(pos.node->first_child==0) {
592
00583 <span class="keywordflow">return</span> end(pos);
594
00585 <span class="keywordflow">return</span> pos.node->first_child;
597
00588 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
598
00589 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::end(<span class="keyword">const</span> iterator_base& pos)<span class="keyword"> const</span>
599
00590 <span class="keyword"> </span>{
600
00591 sibling_iterator ret(0);
601
00592 ret.parent_=pos.node;
602
00593 <span class="keywordflow">return</span> ret;
605
00596 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
606
00597 <span class="keyword">template</span> <<span class="keyword">typename</span> iter>
607
00598 iter tree<T, tree_node_allocator>::parent(iter position)<span class="keyword"> const</span>
608
00599 <span class="keyword"> </span>{
609
00600 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=0);
610
00601 <span class="keywordflow">return</span> iter(<a class="code" href="messages_8cpp.html#a1">position</a>.node->parent);
613
00604 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
614
00605 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::previous_sibling(<span class="keyword">const</span> iterator_base& position)<span class="keyword"> const</span>
615
00606 <span class="keyword"> </span>{
616
00607 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=0);
617
00608 <span class="keywordflow">return</span> sibling_iterator(<a class="code" href="messages_8cpp.html#a1">position</a>.node->prev_sibling);
620
00611 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
621
00612 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::next_sibling(<span class="keyword">const</span> iterator_base& position)<span class="keyword"> const</span>
622
00613 <span class="keyword"> </span>{
623
00614 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=0);
624
00615 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling==0)
625
00616 <span class="keywordflow">return</span> end(pre_order_iterator(<a class="code" href="messages_8cpp.html#a1">position</a>.node->parent));
626
00617 <span class="keywordflow">else</span>
627
00618 <span class="keywordflow">return</span> sibling_iterator(<a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling);
630
00621 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
631
00622 <span class="keyword">template</span> <<span class="keyword">typename</span> iter>
632
00623 iter tree<T, tree_node_allocator>::append_child(iter position)
634
00625 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=head);
636
00627 tree_node* tmp = alloc_.allocate(1,0);
637
00628 kp::constructor(&tmp->data);
638
00629 tmp->first_child=0;
639
00630 tmp->last_child=0;
641
00632 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
642
00633 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child!=0) {
643
00634 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child->next_sibling=tmp;
645
00636 <span class="keywordflow">else</span> {
646
00637 <a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child=tmp;
648
00639 tmp->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child;
649
00640 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child=tmp;
650
00641 tmp->next_sibling=0;
651
00642 <span class="keywordflow">return</span> tmp;
654
00645 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
655
00646 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
656
00647 iter tree<T, tree_node_allocator>::append_child(iter position, <span class="keyword">const</span> T& x)
658
00649 <span class="comment">// If your program fails here you probably used 'append_child' to add the top</span>
659
00650 <span class="comment">// node to an empty tree. From version 1.45 the top element should be added</span>
660
00651 <span class="comment">// using 'insert'. See the documentation for further information, and sorry about</span>
661
00652 <span class="comment">// the API change.</span>
662
00653 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=head);
664
00655 tree_node* tmp = alloc_.allocate(1,0);
665
00656 kp::constructor(&tmp->data, x);
666
00657 tmp->first_child=0;
667
00658 tmp->last_child=0;
669
00660 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
670
00661 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child!=0) {
671
00662 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child->next_sibling=tmp;
673
00664 <span class="keywordflow">else</span> {
674
00665 <a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child=tmp;
676
00667 tmp->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child;
677
00668 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child=tmp;
678
00669 tmp->next_sibling=0;
679
00670 <span class="keywordflow">return</span> tmp;
682
00673 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
683
00674 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
684
00675 iter tree<T, tree_node_allocator>::append_child(iter position, iter other)
686
00677 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=head);
688
00679 sibling_iterator aargh=append_child(position, value_type());
689
00680 <span class="keywordflow">return</span> replace(aargh, other);
692
00683 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
693
00684 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
694
00685 iter tree<T, tree_node_allocator>::append_children(iter position, sibling_iterator from, sibling_iterator to)
698
00689 <span class="keywordflow">while</span>(from!=to) {
699
00690 insert_subtree(<a class="code" href="messages_8cpp.html#a1">position</a>.end(), from);
702
00693 <span class="keywordflow">return</span> ret;
705
00696 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
706
00697 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::set_head(<span class="keyword">const</span> T& x)
708
00699 assert(head->next_sibling==feet);
709
00700 <span class="keywordflow">return</span> insert(iterator(feet), x);
712
00703 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
713
00704 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
714
00705 iter tree<T, tree_node_allocator>::insert(iter position, <span class="keyword">const</span> T& x)
716
00707 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node==0) {
717
00708 <a class="code" href="messages_8cpp.html#a1">position</a>.node=feet; <span class="comment">// Backward compatibility: when calling insert on a null node,</span>
718
00709 <span class="comment">// insert before the feet.</span>
720
00711 tree_node* tmp = alloc_.allocate(1,0);
721
00712 kp::constructor(&tmp->data, x);
722
00713 tmp->first_child=0;
723
00714 tmp->last_child=0;
725
00716 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node->parent;
726
00717 tmp->next_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
727
00718 tmp->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->prev_sibling;
728
00719 <a class="code" href="messages_8cpp.html#a1">position</a>.node->prev_sibling=tmp;
730
00721 <span class="keywordflow">if</span>(tmp->prev_sibling==0)
731
00722 tmp->parent->first_child=tmp;
732
00723 <span class="keywordflow">else</span>
733
00724 tmp->prev_sibling->next_sibling=tmp;
734
00725 <span class="keywordflow">return</span> tmp;
737
00728 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
738
00729 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::insert(sibling_iterator position, <span class="keyword">const</span> T& x)
740
00731 tree_node* tmp = alloc_.allocate(1,0);
741
00732 kp::constructor(&tmp->data, x);
742
00733 tmp->first_child=0;
743
00734 tmp->last_child=0;
745
00736 tmp->next_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
746
00737 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node==0) { <span class="comment">// iterator points to end of a subtree</span>
747
00738 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.parent_;
748
00739 tmp->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.range_last();
749
00740 tmp->parent->last_child=tmp;
751
00742 <span class="keywordflow">else</span> {
752
00743 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node->parent;
753
00744 tmp->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->prev_sibling;
754
00745 <a class="code" href="messages_8cpp.html#a1">position</a>.node->prev_sibling=tmp;
757
00748 <span class="keywordflow">if</span>(tmp->prev_sibling==0)
758
00749 tmp->parent->first_child=tmp;
759
00750 <span class="keywordflow">else</span>
760
00751 tmp->prev_sibling->next_sibling=tmp;
761
00752 <span class="keywordflow">return</span> tmp;
764
00755 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
765
00756 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
766
00757 iter tree<T, tree_node_allocator>::insert_after(iter position, <span class="keyword">const</span> T& x)
768
00759 tree_node* tmp = alloc_.allocate(1,0);
769
00760 kp::constructor(&tmp->data, x);
770
00761 tmp->first_child=0;
771
00762 tmp->last_child=0;
773
00764 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node->parent;
774
00765 tmp->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
775
00766 tmp->next_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling;
776
00767 <a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling=tmp;
778
00769 <span class="keywordflow">if</span>(tmp->next_sibling==0) {
779
00770 <span class="keywordflow">if</span>(tmp->parent) <span class="comment">// when adding nodes at the head, there is no parent</span>
780
00771 tmp->parent->last_child=tmp;
782
00773 <span class="keywordflow">else</span> {
783
00774 tmp->next_sibling->prev_sibling=tmp;
785
00776 <span class="keywordflow">return</span> tmp;
788
00779 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
789
00780 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
790
00781 iter tree<T, tree_node_allocator>::insert_subtree(iter position, <span class="keyword">const</span> iterator_base& subtree)
792
00783 <span class="comment">// insert dummy</span>
793
00784 iter it=insert(position, value_type());
794
00785 <span class="comment">// replace dummy with subtree</span>
795
00786 <span class="keywordflow">return</span> replace(it, subtree);
798
00789 <span class="comment">// template <class T, class tree_node_allocator></span>
799
00790 <span class="comment">// template <class iter></span>
800
00791 <span class="comment">// iter tree<T, tree_node_allocator>::insert_subtree(sibling_iterator position, iter subtree)</span>
801
00792 <span class="comment">// {</span>
802
00793 <span class="comment">// // insert dummy</span>
803
00794 <span class="comment">// iter it(insert(position, value_type()));</span>
804
00795 <span class="comment">// // replace dummy with subtree</span>
805
00796 <span class="comment">// return replace(it, subtree);</span>
806
00797 <span class="comment">// }</span>
808
00799 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
809
00800 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
810
00801 iter tree<T, tree_node_allocator>::replace(iter position, <span class="keyword">const</span> T& x)
812
00803 kp::destructor(&<a class="code" href="messages_8cpp.html#a1">position</a>.node->data);
813
00804 kp::constructor(&<a class="code" href="messages_8cpp.html#a1">position</a>.node->data, x);
814
00805 <span class="keywordflow">return</span> position;
817
00808 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
818
00809 <span class="keyword">template</span> <<span class="keyword">class</span> iter>
819
00810 iter tree<T, tree_node_allocator>::replace(iter position, <span class="keyword">const</span> iterator_base& from)
821
00812 assert(<a class="code" href="messages_8cpp.html#a1">position</a>.node!=head);
822
00813 tree_node *current_from=from.node;
823
00814 tree_node *start_from=from.node;
824
00815 tree_node *current_to =<a class="code" href="messages_8cpp.html#a1">position</a>.node;
826
00817 <span class="comment">// replace the node at position with head of the replacement tree at from</span>
827
00818 erase_children(position);
828
00819 tree_node* tmp = alloc_.allocate(1,0);
829
00820 kp::constructor(&tmp->data, (*from));
830
00821 tmp->first_child=0;
831
00822 tmp->last_child=0;
832
00823 <span class="keywordflow">if</span>(current_to->prev_sibling==0) {
833
00824 current_to->parent->first_child=tmp;
835
00826 <span class="keywordflow">else</span> {
836
00827 current_to->prev_sibling->next_sibling=tmp;
838
00829 tmp->prev_sibling=current_to->prev_sibling;
839
00830 <span class="keywordflow">if</span>(current_to->next_sibling==0) {
840
00831 current_to->parent->last_child=tmp;
842
00833 <span class="keywordflow">else</span> {
843
00834 current_to->next_sibling->prev_sibling=tmp;
845
00836 tmp->next_sibling=current_to->next_sibling;
846
00837 tmp->parent=current_to->parent;
847
00838 kp::destructor(&current_to->data);
848
00839 alloc_.deallocate(current_to,1);
849
00840 current_to=tmp;
851
00842 <span class="comment">// only at this stage can we fix 'last'</span>
852
00843 tree_node *last=from.node->next_sibling;
854
00845 pre_order_iterator toit=tmp;
855
00846 <span class="comment">// copy all children</span>
856
00847 <span class="keywordflow">do</span> {
857
00848 assert(current_from!=0);
858
00849 <span class="keywordflow">if</span>(current_from->first_child != 0) {
859
00850 current_from=current_from->first_child;
860
00851 toit=append_child(toit, current_from->data);
862
00853 <span class="keywordflow">else</span> {
863
00854 <span class="keywordflow">while</span>(current_from->next_sibling==0 && current_from!=start_from) {
864
00855 current_from=current_from->parent;
865
00856 toit=parent(toit);
866
00857 assert(current_from!=0);
868
00859 current_from=current_from->next_sibling;
869
00860 <span class="keywordflow">if</span>(current_from!=last) {
870
00861 toit=append_child(parent(toit), current_from->data);
873
00864 } <span class="keywordflow">while</span>(current_from!=last);
875
00866 <span class="keywordflow">return</span> current_to;
878
00869 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
879
00870 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::replace(
880
00871 sibling_iterator orig_begin,
881
00872 sibling_iterator orig_end,
882
00873 sibling_iterator new_begin,
883
00874 sibling_iterator new_end)
885
00876 tree_node *orig_first=orig_begin.node;
886
00877 tree_node *new_first=new_begin.node;
887
00878 tree_node *orig_last=orig_first;
888
00879 <span class="keywordflow">while</span>((++orig_begin)!=orig_end)
889
00880 orig_last=orig_last->next_sibling;
890
00881 tree_node *new_last=new_first;
891
00882 <span class="keywordflow">while</span>((++new_begin)!=new_end)
892
00883 new_last=new_last->next_sibling;
894
00885 <span class="comment">// insert all siblings in new_first..new_last before orig_first</span>
895
00886 <span class="keywordtype">bool</span> first=<span class="keyword">true</span>;
896
00887 pre_order_iterator ret;
897
00888 <span class="keywordflow">while</span>(1==1) {
898
00889 pre_order_iterator tt=insert_subtree(pre_order_iterator(orig_first), pre_order_iterator(new_first));
899
00890 <span class="keywordflow">if</span>(first) {
901
00892 first=<span class="keyword">false</span>;
903
00894 <span class="keywordflow">if</span>(new_first==new_last)
904
00895 <span class="keywordflow">break</span>;
905
00896 new_first=new_first->next_sibling;
908
00899 <span class="comment">// erase old range of siblings</span>
909
00900 <span class="keywordtype">bool</span> last=<span class="keyword">false</span>;
910
00901 tree_node *next=orig_first;
911
00902 <span class="keywordflow">while</span>(1==1) {
912
00903 <span class="keywordflow">if</span>(next==orig_last)
913
00904 last=<span class="keyword">true</span>;
914
00905 next=next->next_sibling;
915
00906 erase((pre_order_iterator)orig_first);
916
00907 <span class="keywordflow">if</span>(last)
917
00908 <span class="keywordflow">break</span>;
918
00909 orig_first=next;
920
00911 <span class="keywordflow">return</span> ret;
923
00914 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
924
00915 <span class="keyword">template</span> <<span class="keyword">typename</span> iter>
925
00916 iter tree<T, tree_node_allocator>::flatten(iter position)
927
00918 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child==0)
928
00919 <span class="keywordflow">return</span> position;
930
00921 tree_node *tmp=<a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child;
931
00922 <span class="keywordflow">while</span>(tmp) {
932
00923 tmp->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node->parent;
933
00924 tmp=tmp->next_sibling;
935
00926 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling) {
936
00927 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child->next_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling;
937
00928 <a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child;
939
00930 <span class="keywordflow">else</span> {
940
00931 <a class="code" href="messages_8cpp.html#a1">position</a>.node->parent->last_child=<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child;
942
00933 <a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child;
943
00934 <a class="code" href="messages_8cpp.html#a1">position</a>.node->next_sibling->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
944
00935 <a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child=0;
945
00936 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child=0;
947
00938 <span class="keywordflow">return</span> position;
951
00942 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
952
00943 <span class="keyword">template</span> <<span class="keyword">typename</span> iter>
953
00944 iter tree<T, tree_node_allocator>::reparent(iter position, sibling_iterator begin, sibling_iterator end)
955
00946 tree_node *first=begin.node;
956
00947 tree_node *last=first;
957
00948 <span class="keywordflow">if</span>(begin==end) <span class="keywordflow">return</span> begin;
958
00949 <span class="comment">// determine last node</span>
959
00950 <span class="keywordflow">while</span>((++begin)!=end) {
960
00951 last=last->next_sibling;
962
00953 <span class="comment">// move subtree</span>
963
00954 <span class="keywordflow">if</span>(first->prev_sibling==0) {
964
00955 first->parent->first_child=last->next_sibling;
966
00957 <span class="keywordflow">else</span> {
967
00958 first->prev_sibling->next_sibling=last->next_sibling;
969
00960 <span class="keywordflow">if</span>(last->next_sibling==0) {
970
00961 last->parent->last_child=first->prev_sibling;
972
00963 <span class="keywordflow">else</span> {
973
00964 last->next_sibling->prev_sibling=first->prev_sibling;
975
00966 <span class="keywordflow">if</span>(<a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child==0) {
976
00967 <a class="code" href="messages_8cpp.html#a1">position</a>.node->first_child=first;
977
00968 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child=last;
978
00969 first->prev_sibling=0;
980
00971 <span class="keywordflow">else</span> {
981
00972 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child->next_sibling=first;
982
00973 first->prev_sibling=<a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child;
983
00974 <a class="code" href="messages_8cpp.html#a1">position</a>.node->last_child=last;
985
00976 last->next_sibling=0;
987
00978 tree_node *pos=first;
988
00979 <span class="keywordflow">while</span>(1==1) {
989
00980 pos->parent=<a class="code" href="messages_8cpp.html#a1">position</a>.node;
990
00981 <span class="keywordflow">if</span>(pos==last) <span class="keywordflow">break</span>;
991
00982 pos=pos->next_sibling;
994
00985 <span class="keywordflow">return</span> first;
997
00988 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
998
00989 <span class="keyword">template</span> <<span class="keyword">typename</span> iter> iter tree<T, tree_node_allocator>::reparent(iter position, iter from)
1000
00991 <span class="keywordflow">if</span>(from.node->first_child==0) <span class="keywordflow">return</span> position;
1001
00992 <span class="keywordflow">return</span> reparent(position, from.node->first_child, end(from));
1004
00995 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1005
00996 <span class="keyword">template</span> <<span class="keyword">typename</span> iter> iter tree<T, tree_node_allocator>::move_before(iter target, iter source)
1007
00998 tree_node *dst=target.node;
1008
00999 tree_node *src=source.node;
1012
01003 <span class="keywordflow">if</span>(dst==src) <span class="keywordflow">return</span> source;
1014
01005 <span class="comment">// take src out of the tree</span>
1015
01006 <span class="keywordflow">if</span>(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling;
1016
01007 <span class="keywordflow">else</span> src->parent->first_child=src->next_sibling;
1017
01008 <span class="keywordflow">if</span>(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling;
1018
01009 <span class="keywordflow">else</span> src->parent->last_child=src->prev_sibling;
1020
01011 <span class="comment">// connect it to the new point</span>
1021
01012 <span class="keywordflow">if</span>(dst->prev_sibling!=0) dst->prev_sibling->next_sibling=src;
1022
01013 <span class="keywordflow">else</span> dst->parent->first_child=src;
1023
01014 src->prev_sibling=dst->prev_sibling;
1024
01015 dst->prev_sibling=src;
1025
01016 src->next_sibling=dst;
1026
01017 src->parent=dst->parent;
1027
01018 <span class="keywordflow">return</span> src;
1030
01021 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1031
01022 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::merge(sibling_iterator to1, sibling_iterator to2,
1032
01023 sibling_iterator from1, sibling_iterator from2,
1033
01024 <span class="keywordtype">bool</span> duplicate_leaves)
1035
01026 sibling_iterator fnd;
1036
01027 <span class="keywordflow">while</span>(from1!=from2) {
1037
01028 <span class="keywordflow">if</span>((fnd=std::find(to1, to2, (*from1))) != to2) { <span class="comment">// element found</span>
1038
01029 <span class="keywordflow">if</span>(from1.begin()==from1.end()) { <span class="comment">// full depth reached</span>
1039
01030 <span class="keywordflow">if</span>(duplicate_leaves)
1040
01031 append_child(parent(to1), (*from1));
1042
01033 <span class="keywordflow">else</span> { <span class="comment">// descend further</span>
1043
01034 merge(fnd.begin(), fnd.end(), from1.begin(), from1.end(), duplicate_leaves);
1046
01037 <span class="keywordflow">else</span> { <span class="comment">// element missing</span>
1047
01038 insert_subtree(to2, from1);
1053
01044 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1054
01045 <span class="keyword">template</span> <<span class="keyword">class</span> StrictWeakOrdering>
1055
01046 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::compare_nodes<StrictWeakOrdering>::operator()(<span class="keyword">const</span> tree_node *a,
1056
01047 <span class="keyword">const</span> tree_node *b)
1058
01049 <span class="keyword">static</span> StrictWeakOrdering comp;
1060
01051 <span class="keywordflow">return</span> comp(a->data, b->data);
1063
01054 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1064
01055 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, <span class="keywordtype">bool</span> deep)
1066
01057 std::less<T> comp;
1067
01058 sort(from, to, comp, deep);
1070
01061 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1071
01062 <span class="keyword">template</span> <<span class="keyword">class</span> StrictWeakOrdering>
1072
01063 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to,
1073
01064 StrictWeakOrdering comp, <span class="keywordtype">bool</span> deep)
1075
01066 <span class="keywordflow">if</span>(from==to) <span class="keywordflow">return</span>;
1076
01067 <span class="comment">// make list of sorted nodes</span>
1077
01068 <span class="comment">// CHECK: if multiset stores equivalent nodes in the order in which they</span>
1078
01069 <span class="comment">// are inserted, then this routine should be called 'stable_sort'.</span>
1079
01070 std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> > nodes;
1080
01071 sibling_iterator it=from, it2=to;
1081
01072 <span class="keywordflow">while</span>(it != to) {
1082
01073 nodes.insert(it.node);
1085
01076 <span class="comment">// reassemble</span>
1088
01079 <span class="comment">// prev and next are the nodes before and after the sorted range</span>
1089
01080 tree_node *prev=from.node->prev_sibling;
1090
01081 tree_node *next=it2.node->next_sibling;
1091
01082 <span class="keyword">typename</span> std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> >::iterator nit=nodes.begin(), eit=nodes.end();
1092
01083 <span class="keywordflow">if</span>(prev==0) {
1093
01084 <span class="keywordflow">if</span>((*nit)->parent!=0) <span class="comment">// to catch "sorting the head" situations, when there is no parent</span>
1094
01085 (*nit)->parent->first_child=(*nit);
1096
01087 <span class="keywordflow">else</span> prev->next_sibling=(*nit);
1099
01090 <span class="keywordflow">while</span>(nit!=eit) {
1100
01091 (*nit)->prev_sibling=prev;
1101
01092 <span class="keywordflow">if</span>(prev)
1102
01093 prev->next_sibling=(*nit);
1106
01097 <span class="comment">// prev now points to the last-but-one node in the sorted range</span>
1107
01098 <span class="keywordflow">if</span>(prev)
1108
01099 prev->next_sibling=(*eit);
1110
01101 <span class="comment">// eit points to the last node in the sorted range.</span>
1111
01102 (*eit)->next_sibling=next;
1112
01103 (*eit)->prev_sibling=prev; <span class="comment">// missed in the loop above</span>
1113
01104 <span class="keywordflow">if</span>(next==0) {
1114
01105 <span class="keywordflow">if</span>((*eit)->parent!=0) <span class="comment">// to catch "sorting the head" situations, when there is no parent</span>
1115
01106 (*eit)->parent->last_child=(*eit);
1117
01108 <span class="keywordflow">else</span> next->prev_sibling=(*eit);
1119
01110 <span class="keywordflow">if</span>(deep) { <span class="comment">// sort the children of each node too</span>
1120
01111 sibling_iterator bcs(*nodes.begin());
1121
01112 sibling_iterator ecs(*eit);
1123
01114 <span class="keywordflow">while</span>(bcs!=ecs) {
1124
01115 sort(begin(bcs), end(bcs), comp, deep);
1130
01121 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1131
01122 <span class="keyword">template</span> <<span class="keyword">typename</span> iter>
1132
01123 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::equal(<span class="keyword">const</span> iter& one_, <span class="keyword">const</span> iter& two, <span class="keyword">const</span> iter& three_)<span class="keyword"> const</span>
1133
01124 <span class="keyword"> </span>{
1134
01125 std::equal_to<T> comp;
1135
01126 <span class="keywordflow">return</span> equal(one_, two, three_, comp);
1138
01129 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1139
01130 <span class="keyword">template</span> <<span class="keyword">typename</span> iter>
1140
01131 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::equal_subtree(<span class="keyword">const</span> iter& one_, <span class="keyword">const</span> iter& two_)<span class="keyword"> const</span>
1141
01132 <span class="keyword"> </span>{
1142
01133 std::equal_to<T> comp;
1143
01134 <span class="keywordflow">return</span> equal_subtree(one_, two_, comp);
1146
01137 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1147
01138 <span class="keyword">template</span> <<span class="keyword">typename</span> iter, <span class="keyword">class</span> BinaryPredicate>
1148
01139 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::equal(<span class="keyword">const</span> iter& one_, <span class="keyword">const</span> iter& two, <span class="keyword">const</span> iter& three_, BinaryPredicate fun)<span class="keyword"> const</span>
1149
01140 <span class="keyword"> </span>{
1150
01141 pre_order_iterator one(one_), three(three_);
1152
01143 <span class="comment">// if(one==two && is_valid(three) && three.number_of_children()!=0)</span>
1153
01144 <span class="comment">// return false;</span>
1154
01145 <span class="keywordflow">while</span>(one!=two && is_valid(three)) {
1155
01146 <span class="keywordflow">if</span>(!fun(*one,*three))
1156
01147 <span class="keywordflow">return</span> <span class="keyword">false</span>;
1157
01148 <span class="keywordflow">if</span>(one.number_of_children()!=three.number_of_children())
1158
01149 <span class="keywordflow">return</span> <span class="keyword">false</span>;
1162
01153 <span class="keywordflow">return</span> <span class="keyword">true</span>;
1165
01156 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1166
01157 <span class="keyword">template</span> <<span class="keyword">typename</span> iter, <span class="keyword">class</span> BinaryPredicate>
1167
01158 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::equal_subtree(<span class="keyword">const</span> iter& one_, <span class="keyword">const</span> iter& two_, BinaryPredicate fun)<span class="keyword"> const</span>
1168
01159 <span class="keyword"> </span>{
1169
01160 pre_order_iterator one(one_), two(two_);
1171
01162 <span class="keywordflow">if</span>(!fun(*one,*two)) <span class="keywordflow">return</span> <span class="keyword">false</span>;
1172
01163 <span class="keywordflow">if</span>(number_of_children(one)!=number_of_children(two)) <span class="keywordflow">return</span> <span class="keyword">false</span>;
1173
01164 <span class="keywordflow">return</span> equal(begin(one),end(one),begin(two),fun);
1176
01167 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1177
01168 tree<T, tree_node_allocator> tree<T, tree_node_allocator>::subtree(sibling_iterator from, sibling_iterator to)<span class="keyword"> const</span>
1178
01169 <span class="keyword"> </span>{
1180
01171 tmp.set_head(value_type());
1181
01172 tmp.replace(tmp.begin(), tmp.end(), from, to);
1182
01173 <span class="keywordflow">return</span> tmp;
1185
01176 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1186
01177 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::subtree(tree& tmp, sibling_iterator from, sibling_iterator to)<span class="keyword"> const</span>
1187
01178 <span class="keyword"> </span>{
1188
01179 tmp.set_head(value_type());
1189
01180 tmp.replace(tmp.begin(), tmp.end(), from, to);
1192
01183 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1193
01184 <span class="keywordtype">int</span> tree<T, tree_node_allocator>::size()<span class="keyword"> const</span>
1194
01185 <span class="keyword"> </span>{
1195
01186 <span class="keywordtype">int</span> i=0;
1196
01187 pre_order_iterator it=begin(), eit=end();
1197
01188 <span class="keywordflow">while</span>(it!=eit) {
1201
01192 <span class="keywordflow">return</span> i;
1204
01195 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1205
01196 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::empty()<span class="keyword"> const</span>
1206
01197 <span class="keyword"> </span>{
1207
01198 pre_order_iterator it=begin(), eit=end();
1208
01199 <span class="keywordflow">return</span> (it==eit);
1211
01202 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1212
01203 <span class="keywordtype">int</span> tree<T, tree_node_allocator>::depth(<span class="keyword">const</span> iterator_base& it)<span class="keyword"> const</span>
1213
01204 <span class="keyword"> </span>{
1214
01205 tree_node* pos=it.node;
1215
01206 assert(pos!=0);
1216
01207 <span class="keywordtype">int</span> ret=0;
1217
01208 <span class="keywordflow">while</span>(pos->parent!=0) {
1218
01209 pos=pos->parent;
1221
01212 <span class="keywordflow">return</span> ret;
1224
01215 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1225
01216 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tree<T, tree_node_allocator>::number_of_children(<span class="keyword">const</span> iterator_base& it)<span class="keyword"> const</span>
1226
01217 <span class="keyword"> </span>{
1227
01218 tree_node *pos=it.node->first_child;
1228
01219 <span class="keywordflow">if</span>(pos==0) <span class="keywordflow">return</span> 0;
1230
01221 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ret=1;
1231
01222 <span class="comment">// while(pos!=it.node->last_child) {</span>
1232
01223 <span class="comment">// ++ret;</span>
1233
01224 <span class="comment">// pos=pos->next_sibling;</span>
1234
01225 <span class="comment">// }</span>
1235
01226 <span class="keywordflow">while</span>((pos=pos->next_sibling))
1237
01228 <span class="keywordflow">return</span> ret;
1240
01231 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1241
01232 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tree<T, tree_node_allocator>::number_of_siblings(<span class="keyword">const</span> iterator_base& it)<span class="keyword"> const</span>
1242
01233 <span class="keyword"> </span>{
1243
01234 tree_node *pos=it.node;
1244
01235 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ret=1;
1245
01236 <span class="keywordflow">while</span>(pos->next_sibling && pos->next_sibling!=head) {
1247
01238 pos=pos->next_sibling;
1249
01240 <span class="keywordflow">return</span> ret;
1252
01243 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1253
01244 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::swap(sibling_iterator it)
1255
01246 tree_node *nxt=it.node->next_sibling;
1256
01247 <span class="keywordflow">if</span>(nxt) {
1257
01248 <span class="keywordflow">if</span>(it.node->prev_sibling)
1258
01249 it.node->prev_sibling->next_sibling=nxt;
1259
01250 <span class="keywordflow">else</span>
1260
01251 it.node->parent->first_child=nxt;
1261
01252 nxt->prev_sibling=it.node->prev_sibling;
1262
01253 tree_node *nxtnxt=nxt->next_sibling;
1263
01254 <span class="keywordflow">if</span>(nxtnxt)
1264
01255 nxtnxt->prev_sibling=it.node;
1265
01256 <span class="keywordflow">else</span>
1266
01257 it.node->parent->last_child=it.node;
1267
01258 nxt->next_sibling=it.node;
1268
01259 it.node->prev_sibling=nxt;
1269
01260 it.node->next_sibling=nxtnxt;
1273
01264 <span class="comment">// template <class BinaryPredicate></span>
1274
01265 <span class="comment">// tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::find_subtree(</span>
1275
01266 <span class="comment">// sibling_iterator subfrom, sibling_iterator subto, iterator from, iterator to, </span>
1276
01267 <span class="comment">// BinaryPredicate fun) const</span>
1277
01268 <span class="comment">// {</span>
1278
01269 <span class="comment">// assert(1==0); // this routine is not finished yet.</span>
1279
01270 <span class="comment">// while(from!=to) {</span>
1280
01271 <span class="comment">// if(fun(*subfrom, *from)) {</span>
1281
01272 <span class="comment">// </span>
1282
01273 <span class="comment">// }</span>
1283
01274 <span class="comment">// }</span>
1284
01275 <span class="comment">// return to;</span>
1285
01276 <span class="comment">// }</span>
1287
01278 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1288
01279 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::is_in_subtree(<span class="keyword">const</span> iterator_base& it, <span class="keyword">const</span> iterator_base& begin,
1289
01280 <span class="keyword">const</span> iterator_base& end)<span class="keyword"> const</span>
1290
01281 <span class="keyword"> </span>{
1291
01282 <span class="comment">// FIXME: this should be optimised.</span>
1292
01283 pre_order_iterator tmp=begin;
1293
01284 <span class="keywordflow">while</span>(tmp!=end) {
1294
01285 <span class="keywordflow">if</span>(tmp==it) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1297
01288 <span class="keywordflow">return</span> <span class="keyword">false</span>;
1300
01291 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1301
01292 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::is_valid(<span class="keyword">const</span> iterator_base& it)<span class="keyword"> const</span>
1302
01293 <span class="keyword"> </span>{
1303
01294 <span class="keywordflow">if</span>(it.node==0 || it.node==feet) <span class="keywordflow">return</span> <span class="keyword">false</span>;
1304
01295 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">true</span>;
1307
01298 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1308
01299 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tree<T, tree_node_allocator>::index(sibling_iterator it)<span class="keyword"> const</span>
1309
01300 <span class="keyword"> </span>{
1310
01301 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ind=0;
1311
01302 <span class="keywordflow">if</span>(it.node->parent==0) {
1312
01303 <span class="keywordflow">while</span>(it.node->prev_sibling!=head) {
1313
01304 it.node=it.node->prev_sibling;
1317
01308 <span class="keywordflow">else</span> {
1318
01309 <span class="keywordflow">while</span>(it.node->prev_sibling!=0) {
1319
01310 it.node=it.node->prev_sibling;
1323
01314 <span class="keywordflow">return</span> ind;
1327
01318 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1328
01319 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::child(<span class="keyword">const</span> iterator_base& it, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)<span class="keyword"> const</span>
1329
01320 <span class="keyword"> </span>{
1330
01321 tree_node *tmp=it.node->first_child;
1331
01322 <span class="keywordflow">while</span>(num--) {
1332
01323 assert(tmp!=0);
1333
01324 tmp=tmp->next_sibling;
1335
01326 <span class="keywordflow">return</span> tmp;
1341
01332 <span class="comment">// Iterator base</span>
1343
01334 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1344
01335 tree<T, tree_node_allocator>::iterator_base::iterator_base()
1345
01336 : node(0), skip_current_children_(false)
1349
01340 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1350
01341 tree<T, tree_node_allocator>::iterator_base::iterator_base(tree_node *tn)
1351
01342 : node(tn), skip_current_children_(false)
1355
01346 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1356
01347 T& tree<T, tree_node_allocator>::iterator_base::operator*()<span class="keyword"> const</span>
1357
01348 <span class="keyword"> </span>{
1358
01349 <span class="keywordflow">return</span> node->data;
1361
01352 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1362
01353 T* tree<T, tree_node_allocator>::iterator_base::operator->()<span class="keyword"> const</span>
1363
01354 <span class="keyword"> </span>{
1364
01355 <span class="keywordflow">return</span> &(node->data);
1367
01358 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1368
01359 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::post_order_iterator::operator!=(<span class="keyword">const</span> post_order_iterator& other)<span class="keyword"> const</span>
1369
01360 <span class="keyword"> </span>{
1370
01361 <span class="keywordflow">if</span>(other.node!=this->node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1371
01362 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;
1374
01365 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1375
01366 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::post_order_iterator::operator==(<span class="keyword">const</span> post_order_iterator& other)<span class="keyword"> const</span>
1376
01367 <span class="keyword"> </span>{
1377
01368 <span class="keywordflow">if</span>(other.node==this->node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1378
01369 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;
1381
01372 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1382
01373 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::pre_order_iterator::operator!=(<span class="keyword">const</span> pre_order_iterator& other)<span class="keyword"> const</span>
1383
01374 <span class="keyword"> </span>{
1384
01375 <span class="keywordflow">if</span>(other.node!=this->node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1385
01376 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;
1388
01379 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1389
01380 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::pre_order_iterator::operator==(<span class="keyword">const</span> pre_order_iterator& other)<span class="keyword"> const</span>
1390
01381 <span class="keyword"> </span>{
1391
01382 <span class="keywordflow">if</span>(other.node==this->node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1392
01383 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;
1395
01386 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1396
01387 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::sibling_iterator::operator!=(<span class="keyword">const</span> sibling_iterator& other)<span class="keyword"> const</span>
1397
01388 <span class="keyword"> </span>{
1398
01389 <span class="keywordflow">if</span>(other.node!=this->node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1399
01390 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;
1402
01393 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1403
01394 <span class="keywordtype">bool</span> tree<T, tree_node_allocator>::sibling_iterator::operator==(<span class="keyword">const</span> sibling_iterator& other)<span class="keyword"> const</span>
1404
01395 <span class="keyword"> </span>{
1405
01396 <span class="keywordflow">if</span>(other.node==this->node) <span class="keywordflow">return</span> <span class="keyword">true</span>;
1406
01397 <span class="keywordflow">else</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;
1409
01400 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1410
01401 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::iterator_base::begin()<span class="keyword"> const</span>
1411
01402 <span class="keyword"> </span>{
1412
01403 sibling_iterator ret(node->first_child);
1413
01404 ret.parent_=this->node;
1414
01405 <span class="keywordflow">return</span> ret;
1417
01408 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1418
01409 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::iterator_base::end()<span class="keyword"> const</span>
1419
01410 <span class="keyword"> </span>{
1420
01411 sibling_iterator ret(0);
1421
01412 ret.parent_=node;
1422
01413 <span class="keywordflow">return</span> ret;
1425
01416 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1426
01417 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::iterator_base::skip_children()
1428
01419 skip_current_children_=<span class="keyword">true</span>;
1431
01422 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1432
01423 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tree<T, tree_node_allocator>::iterator_base::number_of_children()<span class="keyword"> const</span>
1433
01424 <span class="keyword"> </span>{
1434
01425 tree_node *pos=node->first_child;
1435
01426 <span class="keywordflow">if</span>(pos==0) <span class="keywordflow">return</span> 0;
1437
01428 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ret=1;
1438
01429 <span class="keywordflow">while</span>(pos!=node->last_child) {
1440
01431 pos=pos->next_sibling;
1442
01433 <span class="keywordflow">return</span> ret;
1447
01438 <span class="comment">// Pre-order iterator</span>
1449
01440 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1450
01441 tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator()
1451
01442 : iterator_base(0)
1455
01446 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1456
01447 tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(tree_node *tn)
1457
01448 : iterator_base(tn)
1461
01452 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1462
01453 tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(<span class="keyword">const</span> iterator_base &other)
1463
01454 : iterator_base(other.node)
1467
01458 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1468
01459 tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(<span class="keyword">const</span> sibling_iterator& other)
1469
01460 : iterator_base(other.node)
1471
01462 <span class="keywordflow">if</span>(this->node==0) {
1472
01463 <span class="keywordflow">if</span>(other.range_last()!=0)
1473
01464 this->node=other.range_last();
1474
01465 <span class="keywordflow">else</span>
1475
01466 this->node=other.parent_;
1476
01467 this->skip_children();
1481
01472 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1482
01473 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator++()
1484
01475 assert(this->node!=0);
1485
01476 <span class="keywordflow">if</span>(!this->skip_current_children_ && this->node->first_child != 0) {
1486
01477 this->node=this->node->first_child;
1488
01479 <span class="keywordflow">else</span> {
1489
01480 this->skip_current_children_=<span class="keyword">false</span>;
1490
01481 <span class="keywordflow">while</span>(this->node->next_sibling==0) {
1491
01482 this->node=this->node->parent;
1492
01483 <span class="keywordflow">if</span>(this->node==0)
1493
01484 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1495
01486 this->node=this->node->next_sibling;
1497
01488 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1500
01491 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1501
01492 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator--()
1503
01494 assert(this->node!=0);
1504
01495 <span class="keywordflow">if</span>(this->node->prev_sibling) {
1505
01496 this->node=this->node->prev_sibling;
1506
01497 <span class="keywordflow">while</span>(this->node->last_child)
1507
01498 this->node=this->node->last_child;
1509
01500 <span class="keywordflow">else</span> {
1510
01501 this->node=this->node->parent;
1511
01502 <span class="keywordflow">if</span>(this->node==0)
1512
01503 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1514
01505 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1517
01508 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1518
01509 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::pre_order_iterator::operator++(<span class="keywordtype">int</span> n)
1520
01511 pre_order_iterator copy = *<span class="keyword">this</span>;
1522
01513 <span class="keywordflow">return</span> copy;
1525
01516 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1526
01517 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::pre_order_iterator::operator--(<span class="keywordtype">int</span> n)
1528
01519 pre_order_iterator copy = *<span class="keyword">this</span>;
1530
01521 <span class="keywordflow">return</span> copy;
1533
01524 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1534
01525 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1536
01527 <span class="keywordflow">while</span>(num>0) {
1540
01531 <span class="keywordflow">return</span> (*this);
1543
01534 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1544
01535 <span class="keyword">typename</span> tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1546
01537 <span class="keywordflow">while</span>(num>0) {
1550
01541 <span class="keywordflow">return</span> (*this);
1555
01546 <span class="comment">// Post-order iterator</span>
1557
01548 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1558
01549 tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator()
1559
01550 : iterator_base(0)
1563
01554 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1564
01555 tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator(tree_node *tn)
1565
01556 : iterator_base(tn)
1569
01560 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1570
01561 tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator(<span class="keyword">const</span> iterator_base &other)
1571
01562 : iterator_base(other.node)
1575
01566 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1576
01567 tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator(<span class="keyword">const</span> sibling_iterator& other)
1577
01568 : iterator_base(other.node)
1579
01570 <span class="keywordflow">if</span>(this->node==0) {
1580
01571 <span class="keywordflow">if</span>(other.range_last()!=0)
1581
01572 this->node=other.range_last();
1582
01573 <span class="keywordflow">else</span>
1583
01574 this->node=other.parent_;
1584
01575 this->skip_children();
1589
01580 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1590
01581 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator++()
1592
01583 assert(this->node!=0);
1593
01584 <span class="keywordflow">if</span>(this->node->next_sibling==0)
1594
01585 this->node=this->node->parent;
1595
01586 <span class="keywordflow">else</span> {
1596
01587 this->node=this->node->next_sibling;
1597
01588 <span class="keywordflow">if</span>(this->skip_current_children_) {
1598
01589 this->skip_current_children_=<span class="keyword">false</span>;
1600
01591 <span class="keywordflow">else</span> {
1601
01592 <span class="keywordflow">while</span>(this->node->first_child)
1602
01593 this->node=this->node->first_child;
1605
01596 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1608
01599 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1609
01600 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator--()
1611
01602 assert(this->node!=0);
1612
01603 <span class="keywordflow">if</span>(this->skip_current_children_ || this->node->last_child==0) {
1613
01604 this->skip_current_children_=<span class="keyword">false</span>;
1614
01605 <span class="keywordflow">while</span>(this->node->prev_sibling==0)
1615
01606 this->node=this->node->parent;
1616
01607 this->node=this->node->prev_sibling;
1618
01609 <span class="keywordflow">else</span> {
1619
01610 this->node=this->node->last_child;
1621
01612 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1624
01615 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1625
01616 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::post_order_iterator::operator++(<span class="keywordtype">int</span>)
1627
01618 post_order_iterator copy = *<span class="keyword">this</span>;
1629
01620 <span class="keywordflow">return</span> copy;
1632
01623 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1633
01624 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::post_order_iterator::operator--(<span class="keywordtype">int</span>)
1635
01626 post_order_iterator copy = *<span class="keyword">this</span>;
1637
01628 <span class="keywordflow">return</span> copy;
1641
01632 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1642
01633 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1644
01635 <span class="keywordflow">while</span>(num>0) {
1648
01639 <span class="keywordflow">return</span> (*this);
1651
01642 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1652
01643 <span class="keyword">typename</span> tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1654
01645 <span class="keywordflow">while</span>(num>0) {
1658
01649 <span class="keywordflow">return</span> (*this);
1661
01652 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1662
01653 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::post_order_iterator::descend_all()
1664
01655 assert(this->node!=0);
1665
01656 <span class="keywordflow">while</span>(this->node->first_child)
1666
01657 this->node=this->node->first_child;
1670
01661 <span class="comment">// Fixed depth iterator</span>
1672
01663 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1673
01664 tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator()
1674
01665 : iterator_base()
1676
01667 set_first_parent_();
1679
01670 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1680
01671 tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(tree_node *tn)
1681
01672 : iterator_base(tn)
1683
01674 set_first_parent_();
1686
01677 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1687
01678 tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(<span class="keyword">const</span> iterator_base& other)
1688
01679 : iterator_base(other.node)
1690
01681 set_first_parent_();
1693
01684 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1694
01685 tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(<span class="keyword">const</span> sibling_iterator& other)
1695
01686 : iterator_base(other.node), first_parent_(other.parent_)
1697
01688 find_leftmost_parent_();
1700
01691 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1701
01692 tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(<span class="keyword">const</span> fixed_depth_iterator& other)
1702
01693 : iterator_base(other.node), first_parent_(other.first_parent_)
1706
01697 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1707
01698 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::fixed_depth_iterator::set_first_parent_()
1709
01700 <span class="keywordflow">return</span>; <span class="comment">// FIXME: we do not use first_parent_ yet, and it actually needs some serious reworking if</span>
1710
01701 <span class="comment">// it is ever to work at the 'head' level.</span>
1711
01702 first_parent_=0;
1712
01703 <span class="keywordflow">if</span>(this->node==0) <span class="keywordflow">return</span>;
1713
01704 <span class="keywordflow">if</span>(this->node->parent!=0)
1714
01705 first_parent_=this->node->parent;
1715
01706 <span class="keywordflow">if</span>(first_parent_)
1716
01707 find_leftmost_parent_();
1719
01710 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1720
01711 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::fixed_depth_iterator::find_leftmost_parent_()
1722
01713 <span class="keywordflow">return</span>; <span class="comment">// FIXME: see 'set_first_parent()'</span>
1723
01714 tree_node *tmppar=first_parent_;
1724
01715 <span class="keywordflow">while</span>(tmppar->prev_sibling) {
1725
01716 tmppar=tmppar->prev_sibling;
1726
01717 <span class="keywordflow">if</span>(tmppar->first_child)
1727
01718 first_parent_=tmppar;
1731
01722 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1732
01723 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator++()
1734
01725 assert(this->node!=0);
1735
01726 <span class="keywordflow">if</span>(this->node->next_sibling!=0) {
1736
01727 this->node=this->node->next_sibling;
1737
01728 assert(this->node!=0);
1738
01729 <span class="keywordflow">if</span>(this->node->parent==0 && this->node->next_sibling==0) <span class="comment">// feet element</span>
1739
01730 this->node=0;
1741
01732 <span class="keywordflow">else</span> {
1742
01733 tree_node *par=this->node->parent;
1743
01734 <span class="keywordflow">do</span> {
1744
01735 par=par->next_sibling;
1745
01736 <span class="keywordflow">if</span>(par==0) { <span class="comment">// FIXME: need to keep track of this!</span>
1746
01737 this->node=0;
1747
01738 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1749
01740 } <span class="keywordflow">while</span>(par->first_child==0);
1750
01741 this->node=par->first_child;
1752
01743 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1755
01746 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1756
01747 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator--()
1758
01749 assert(this->node!=0);
1759
01750 <span class="keywordflow">if</span>(this->node->prev_sibling!=0) {
1760
01751 this->node=this->node->prev_sibling;
1761
01752 assert(this->node!=0);
1762
01753 <span class="keywordflow">if</span>(this->node->parent==0 && this->node->prev_sibling==0) <span class="comment">// head element</span>
1763
01754 this->node=0;
1765
01756 <span class="keywordflow">else</span> {
1766
01757 tree_node *par=this->node->parent;
1767
01758 <span class="keywordflow">do</span> {
1768
01759 par=par->prev_sibling;
1769
01760 <span class="keywordflow">if</span>(par==0) { <span class="comment">// FIXME: need to keep track of this!</span>
1770
01761 this->node=0;
1771
01762 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1773
01764 } <span class="keywordflow">while</span>(par->last_child==0);
1774
01765 this->node=par->last_child;
1776
01767 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1779
01770 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1780
01771 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::fixed_depth_iterator::operator++(<span class="keywordtype">int</span>)
1782
01773 fixed_depth_iterator copy = *<span class="keyword">this</span>;
1784
01775 <span class="keywordflow">return</span> copy;
1787
01778 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1788
01779 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::fixed_depth_iterator::operator--(<span class="keywordtype">int</span>)
1790
01781 fixed_depth_iterator copy = *<span class="keyword">this</span>;
1792
01783 <span class="keywordflow">return</span> copy;
1795
01786 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1796
01787 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1798
01789 <span class="keywordflow">while</span>(num>0) {
1802
01793 <span class="keywordflow">return</span> (*this);
1805
01796 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1806
01797 <span class="keyword">typename</span> tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1808
01799 <span class="keywordflow">while</span>(num>0) {
1812
01803 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1815
01806 <span class="comment">// FIXME: add the other members of fixed_depth_iterator.</span>
1818
01809 <span class="comment">// Sibling iterator</span>
1820
01811 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1821
01812 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator()
1822
01813 : iterator_base()
1824
01815 set_parent_();
1827
01818 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1828
01819 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(tree_node *tn)
1829
01820 : iterator_base(tn)
1831
01822 set_parent_();
1834
01825 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1835
01826 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(<span class="keyword">const</span> iterator_base& other)
1836
01827 : iterator_base(other.node)
1838
01829 set_parent_();
1841
01832 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1842
01833 tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(<span class="keyword">const</span> sibling_iterator& other)
1843
01834 : iterator_base(other), parent_(other.parent_)
1847
01838 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1848
01839 <span class="keywordtype">void</span> tree<T, tree_node_allocator>::sibling_iterator::set_parent_()
1851
01842 <span class="keywordflow">if</span>(this->node==0) <span class="keywordflow">return</span>;
1852
01843 <span class="keywordflow">if</span>(this->node->parent!=0)
1853
01844 parent_=this->node->parent;
1856
01847 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1857
01848 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator++()
1859
01850 <span class="keywordflow">if</span>(this->node)
1860
01851 this->node=this->node->next_sibling;
1861
01852 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1864
01855 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1865
01856 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator--()
1867
01858 <span class="keywordflow">if</span>(this->node) this->node=this->node->prev_sibling;
1868
01859 <span class="keywordflow">else</span> {
1869
01860 assert(parent_);
1870
01861 this->node=parent_->last_child;
1872
01863 <span class="keywordflow">return</span> *<span class="keyword">this</span>;
1875
01866 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1876
01867 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::sibling_iterator::operator++(<span class="keywordtype">int</span>)
1878
01869 sibling_iterator copy = *<span class="keyword">this</span>;
1880
01871 <span class="keywordflow">return</span> copy;
1883
01874 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1884
01875 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::sibling_iterator::operator--(<span class="keywordtype">int</span>)
1886
01877 sibling_iterator copy = *<span class="keyword">this</span>;
1888
01879 <span class="keywordflow">return</span> copy;
1891
01882 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1892
01883 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator+=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1894
01885 <span class="keywordflow">while</span>(num>0) {
1898
01889 <span class="keywordflow">return</span> (*this);
1901
01892 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1902
01893 <span class="keyword">typename</span> tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator-=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num)
1904
01895 <span class="keywordflow">while</span>(num>0) {
1908
01899 <span class="keywordflow">return</span> (*this);
1911
01902 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1912
01903 <span class="keyword">typename</span> tree<T, tree_node_allocator>::tree_node *tree<T, tree_node_allocator>::sibling_iterator::range_first()<span class="keyword"> const</span>
1913
01904 <span class="keyword"> </span>{
1914
01905 tree_node *tmp=parent_->first_child;
1915
01906 <span class="keywordflow">return</span> tmp;
1918
01909 <span class="keyword">template</span> <<span class="keyword">class</span> T, <span class="keyword">class</span> tree_node_allocator>
1919
01910 <span class="keyword">typename</span> tree<T, tree_node_allocator>::tree_node *tree<T, tree_node_allocator>::sibling_iterator::range_last()<span class="keyword"> const</span>
1920
01911 <span class="keyword"> </span>{
1921
01912 <span class="keywordflow">return</span> parent_->last_child;
1925
01916 <span class="preprocessor">#endif</span>
1926
01917 <span class="preprocessor"></span>
1927
01918 <span class="comment">// Local variables:</span>
1928
01919 <span class="comment">// default-tab-width: 3</span>
1929
01920 <span class="comment">// End:</span>
1930
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Jul 31 15:38:35 2005 for LibOFX by
1931
<a href="http://www.doxygen.org/index.html">
1932
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.3.9.1 </small></address>