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

Last change on this file since 1202 was 834, checked in by garnier, 16 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.