source: trunk/source/visualization/XXX/include/tree/iterator.cc@ 979

Last change on this file since 979 was 834, checked in by garnier, 17 years ago

import all except CVS

File size: 8.6 KB
Line 
1/*
2Copyright (c) 2003-2006, Troy Aaron Johnson
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 * Neither the name of Troy Aaron Johnson nor the names of any
15 contributors may be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28POSSIBILITY OF SUCH DAMAGE.
29*/
30
31template<class N>
32void tree<N>::iterator::clear(void)
33{
34 /* this line necessary for g++ 3.4 onward */
35 tree_node<N>*& current = this->current;
36
37 assert(current != NULL);
38
39 for (sibling_iterator i(beginChildren());
40 i != endChildren(); )
41 {
42 i.clear();
43 ++i;
44 (i - 1).destroy();
45 }
46
47 current->first_child = NULL;
48 current->last_child = NULL;
49}
50
51template<class N>
52typename tree<N>::iterator tree<N>::iterator::erase(void)
53{
54 tree_node<N>*& current = this->current;
55
56 assert(current != NULL);
57
58 /* remove all children and grandchildren */
59 clear();
60
61 /* make copies because there is an ordering
62 problem updating the previous and next links */
63 tree_node<N>* old_prev = current->prev_sibling;
64 tree_node<N>* old_next = current->next_sibling;
65
66 if (old_prev != NULL)
67 old_prev->next_sibling = old_next;
68
69 if (old_next != NULL)
70 old_next->prev_sibling = old_prev;
71
72 if (current->parent->first_child == current)
73 current->parent->first_child = old_next;
74
75 if (current->parent->last_child == current)
76 current->parent->last_child = old_prev;
77
78 /* destroy has no parameters, so gcc complains that it
79 can't find the method unless this is made explicit */
80 super::destroy();
81
82 return iterator(old_next);
83}
84
85template<class N>
86typename tree<N>::iterator tree<N>::iterator::insert(const N& data)
87{
88 tree_node<N>*& current = this->current;
89
90 assert(current != NULL);
91
92 tree_node<N>* p = new tree_node<N>(data);
93 p->parent = current->parent;
94 p->first_child = p->last_child = NULL;
95
96 p->prev_sibling = current->prev_sibling;
97 p->next_sibling = current;
98
99 if (current->prev_sibling != NULL)
100 current->prev_sibling->next_sibling = p;
101 else
102 current->parent->first_child = p;
103
104 current->prev_sibling = p;
105
106 return p;
107}
108
109template<class N>
110typename tree<N>::iterator tree<N>::iterator::insert(const tree<N>& t)
111{
112 assert(this->current != NULL);
113
114 return absorb_before(new tree<N>(t));
115}
116
117template<class N>
118typename tree<N>::iterator tree<N>::iterator::insert_after(const N& data)
119{
120 /* this line necessary for g++ 3.4 onward */
121 tree_node<N>*& current = this->current;
122
123 assert(current != NULL);
124
125 tree_node<N>* p = new tree_node<N>(data);
126 p->parent = current->parent;
127 p->first_child = p->last_child = NULL;
128
129 p->prev_sibling = current;
130 p->next_sibling = current->next_sibling;
131
132 if (current->next_sibling != NULL)
133 current->next_sibling->prev_sibling = p;
134 else
135 current->parent->last_child = p;
136
137 current->next_sibling = p;
138
139 return p;
140}
141
142template<class N>
143typename tree<N>::iterator tree<N>::iterator::insert_after(const tree<N>& t)
144{
145 assert(this->current != NULL);
146
147 return absorb_after(new tree<N>(t));
148}
149
150template<class N>
151void tree<N>::iterator::pop_back(void)
152{
153 /* this line necessary for g++ 3.4 onward */
154 tree_node<N>*& current = this->current;
155
156 assert(current != NULL);
157 assert(current->last_child != NULL);
158 assert(current->last_child->next_sibling == NULL);
159
160 tree_node<N>* p = current->last_child;
161 current->last_child = p->prev_sibling;
162
163 if (p->prev_sibling != NULL)
164 p->prev_sibling->next_sibling = NULL;
165 else
166 current->first_child = NULL;
167
168 delete p;
169}
170
171template<class N>
172void tree<N>::iterator::pop_front(void)
173{
174 /* this line necessary for g++ 3.4 onward */
175 tree_node<N>*& current = this->current;
176
177 assert(current != NULL);
178 assert(current->first_child != NULL);
179 assert(current->first_child->prev_sibling == NULL);
180
181 tree_node<N>* p = current->first_child;
182 current->first_child = p->next_sibling;
183
184 if (p->next_sibling != NULL)
185 p->next_sibling->prev_sibling = NULL;
186 else
187 current->last_child = NULL;
188
189 delete p;
190}
191
192template<class N>
193typename tree<N>::iterator tree<N>::iterator::push_back(const N& data)
194{
195 /* this line necessary for g++ 3.4 onward */
196 tree_node<N>*& current = this->current;
197
198 assert(current != NULL);
199
200 tree_node<N>* p = new tree_node<N>(data);
201 p->parent = current;
202 p->first_child = p->last_child = NULL;
203
204 if (current->last_child == NULL)
205 {
206 current->first_child = current->last_child = p;
207 p->prev_sibling = p->next_sibling = NULL;
208 }
209 else
210 {
211 p->prev_sibling = current->last_child;
212 p->next_sibling = NULL;
213 current->last_child->next_sibling = p;
214 current->last_child = p;
215 }
216
217 return iterator(p);
218}
219
220template<class N>
221typename tree<N>::iterator tree<N>::iterator::push_back(const tree<N>& t)
222{
223 assert(this->current != NULL);
224
225 return absorb_back(new tree<N>(t));
226}
227
228template<class N>
229typename tree<N>::iterator tree<N>::iterator::push_front(const N& data)
230{
231 /* this line necessary for g++ 3.4 onward */
232 tree_node<N>*& current = this->current;
233
234 assert(current != NULL);
235
236 tree_node<N>* p = new tree_node<N>(data);
237 p->parent = current;
238 p->first_child = p->last_child = NULL;
239
240 if (current->first_child == NULL)
241 {
242 current->first_child = current->last_child = p;
243 p->prev_sibling = p->next_sibling = NULL;
244 }
245 else
246 {
247 p->prev_sibling = NULL;
248 p->next_sibling = current->first_child;
249 current->first_child->prev_sibling = p;
250 current->first_child = p;
251 }
252
253 return iterator(p);
254}
255
256template<class N>
257typename tree<N>::iterator tree<N>::iterator::push_front(const tree<N>& t)
258{
259 assert(this->current != NULL);
260
261 return absorb_front(new tree<N>(t));
262}
263
264template<class N>
265N tree<N>::iterator::replace(const N& data)
266{
267 N ret(this->current->data);
268 this->current->data = data;
269 return ret;
270}
271
272template<class N>
273size_t tree<N>::iterator::size(void) const
274{
275 assert(this->current != NULL);
276
277 size_t s = 1;
278
279 for (typename tree<N>::sibling_iterator i(beginChildren());
280 i != endChildren(); ++i)
281 {
282 s += i.size();
283 }
284
285 return s;
286}
287
288template<class N>
289typename tree<N>::iterator tree<N>::iterator::splice_after(tree<N>& t)
290{
291 /* this line necessary for g++ 3.4 onward */
292 tree_node<N>*& current = this->current;
293
294 assert(current != NULL);
295
296 tree_node<N>* p = t.master->next_sibling;
297 t.master->next_sibling = t.master;
298 t.master->prev_sibling = t.master;
299
300 p->parent = current->parent;
301
302 p->prev_sibling = current;
303 p->next_sibling = current->next_sibling;
304
305 if (current->next_sibling != NULL)
306 current->next_sibling->prev_sibling = p;
307 else
308 current->parent->last_child = p;
309
310 current->next_sibling = p;
311
312 return p;
313}
314
315template<class N>
316typename tree<N>::iterator tree<N>::iterator::splice_back(tree<N>& t)
317{
318 /* this line necessary for g++ 3.4 onward */
319 tree_node<N>*& current = this->current;
320
321 assert(current != NULL);
322 assert(!t.empty());
323
324 tree_node<N>* p = t.master->next_sibling;
325 t.master->next_sibling = t.master;
326 t.master->prev_sibling = t.master;
327
328 p->parent = current;
329
330 if (current->last_child == NULL)
331 {
332 current->first_child = current->last_child = p;
333 p->prev_sibling = p->next_sibling = NULL;
334 }
335 else
336 {
337 p->prev_sibling = current->last_child;
338 p->next_sibling = NULL;
339 current->last_child->next_sibling = p;
340 current->last_child = p;
341 }
342
343 return p;
344}
345
346template<class N>
347typename tree<N>::iterator tree<N>::iterator::splice_before(tree<N>& t)
348{
349 /* TODO */
350 assert(false);
351 return NULL;
352}
353
354template<class N>
355typename tree<N>::iterator tree<N>::iterator::splice_front(tree<N>& t)
356{
357 /* TODO */
358 assert(false);
359 return NULL;
360}
361
Note: See TracBrowser for help on using the repository browser.