2 // STL-like templated tree class.
4 // Copyright (C) 2001-2014 Kasper Peeters <kasper@phi-sci.com>
5 // Distributed under the GNU General Public License version 3.
7 // Special permission to use tree.hh under the conditions of a
8 // different license can be requested from the author.
11 \author Kasper Peeters
14 \see http://tree.phi-sci.com/
15 \see http://tree.phi-sci.com/ChangeLog
17 The tree.hh library for C++ provides an STL-like container class
18 for n-ary trees, templated over the data stored at the
19 nodes. Various types of iterators are provided (post-order,
20 pre-order, and others). Where possible the access methods are
21 compatible with the STL or alternative algorithms are
39 /// A node in the tree, combining links to other nodes as well as the actual data.
41 class tree_node_
{ // size: 5*4=20 bytes (on 32 bit arch), can be reduced by 8.
46 tree_node_
<T
> *parent
;
47 tree_node_
<T
> *first_child
, *last_child
;
48 tree_node_
<T
> *prev_sibling
, *next_sibling
;
50 }; // __attribute__((packed));
53 tree_node_
<T
>::tree_node_()
54 : parent(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0)
59 tree_node_
<T
>::tree_node_(const T
& val
)
60 : parent(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0), data(val
)
64 template <class T
, class tree_node_allocator
= std::allocator
<tree_node_
<T
> > >
67 typedef tree_node_
<T
> tree_node
;
69 /// Value of the data stored at a node.
73 class pre_order_iterator
;
74 class post_order_iterator
;
75 class sibling_iterator
;
78 tree(); // empty constructor
79 tree(const T
&); // constructor setting given element as head
80 tree(const iterator_base
&);
81 tree(const tree
<T
, tree_node_allocator
>&); // copy constructor
82 tree(tree
<T
, tree_node_allocator
>&&); // move constructor
84 tree
<T
,tree_node_allocator
>& operator=(const tree
<T
, tree_node_allocator
>&); // copy assignment
85 tree
<T
,tree_node_allocator
>& operator=(tree
<T
, tree_node_allocator
>&&); // move assignment
87 /// Base class for iterators, only pointers stored, no traversal logic.
89 class iterator_base
: public stlport::bidirectional_iterator
<T
, ptrdiff_t> {
97 typedef size_t size_type
;
98 typedef ptrdiff_t difference_type
;
99 typedef std::bidirectional_iterator_tag iterator_category
;
102 iterator_base(tree_node
*);
104 T
& operator*() const;
105 T
* operator->() const;
107 /// When called, the next increment/decrement skips children of this node.
108 void skip_children();
109 void skip_children(bool skip
);
110 /// Number of children of the node pointed to by the iterator.
111 unsigned int number_of_children() const;
113 sibling_iterator
begin() const;
114 sibling_iterator
end() const;
118 bool skip_current_children_
;
121 /// Depth-first iterator, first accessing the node, then its children.
122 class pre_order_iterator
: public iterator_base
{
124 pre_order_iterator();
125 pre_order_iterator(tree_node
*);
126 pre_order_iterator(const iterator_base
&);
127 pre_order_iterator(const sibling_iterator
&);
129 bool operator==(const pre_order_iterator
&) const;
130 bool operator!=(const pre_order_iterator
&) const;
131 pre_order_iterator
& operator++();
132 pre_order_iterator
& operator--();
133 pre_order_iterator
operator++(int);
134 pre_order_iterator
operator--(int);
135 pre_order_iterator
& operator+=(unsigned int);
136 pre_order_iterator
& operator-=(unsigned int);
138 pre_order_iterator
& next_skip_children();
141 /// Depth-first iterator, first accessing the children, then the node itself.
142 class post_order_iterator
: public iterator_base
{
144 post_order_iterator();
145 post_order_iterator(tree_node
*);
146 post_order_iterator(const iterator_base
&);
147 post_order_iterator(const sibling_iterator
&);
149 bool operator==(const post_order_iterator
&) const;
150 bool operator!=(const post_order_iterator
&) const;
151 post_order_iterator
& operator++();
152 post_order_iterator
& operator--();
153 post_order_iterator
operator++(int);
154 post_order_iterator
operator--(int);
155 post_order_iterator
& operator+=(unsigned int);
156 post_order_iterator
& operator-=(unsigned int);
158 /// Set iterator to the first child as deep as possible down the tree.
162 /// Breadth-first iterator, using a queue
163 class breadth_first_queued_iterator
: public iterator_base
{
165 breadth_first_queued_iterator();
166 breadth_first_queued_iterator(tree_node
*);
167 breadth_first_queued_iterator(const iterator_base
&);
169 bool operator==(const breadth_first_queued_iterator
&) const;
170 bool operator!=(const breadth_first_queued_iterator
&) const;
171 breadth_first_queued_iterator
& operator++();
172 breadth_first_queued_iterator
operator++(int);
173 breadth_first_queued_iterator
& operator+=(unsigned int);
176 std::queue
<tree_node
*> traversal_queue
;
179 /// The default iterator types throughout the tree class.
180 typedef pre_order_iterator iterator
;
181 typedef breadth_first_queued_iterator breadth_first_iterator
;
183 /// Iterator which traverses only the nodes at a given depth from the root.
184 class fixed_depth_iterator
: public iterator_base
{
186 fixed_depth_iterator();
187 fixed_depth_iterator(tree_node
*);
188 fixed_depth_iterator(const iterator_base
&);
189 fixed_depth_iterator(const sibling_iterator
&);
190 fixed_depth_iterator(const fixed_depth_iterator
&);
192 bool operator==(const fixed_depth_iterator
&) const;
193 bool operator!=(const fixed_depth_iterator
&) const;
194 fixed_depth_iterator
& operator++();
195 fixed_depth_iterator
& operator--();
196 fixed_depth_iterator
operator++(int);
197 fixed_depth_iterator
operator--(int);
198 fixed_depth_iterator
& operator+=(unsigned int);
199 fixed_depth_iterator
& operator-=(unsigned int);
204 /// Iterator which traverses only the nodes which are siblings of each other.
205 class sibling_iterator
: public iterator_base
{
208 sibling_iterator(tree_node
*);
209 sibling_iterator(const sibling_iterator
&);
210 sibling_iterator(const iterator_base
&);
212 bool operator==(const sibling_iterator
&) const;
213 bool operator!=(const sibling_iterator
&) const;
214 sibling_iterator
& operator++();
215 sibling_iterator
& operator--();
216 sibling_iterator
operator++(int);
217 sibling_iterator
operator--(int);
218 sibling_iterator
& operator+=(unsigned int);
219 sibling_iterator
& operator-=(unsigned int);
221 tree_node
*range_first() const;
222 tree_node
*range_last() const;
228 /// Iterator which traverses only the leaves.
229 class leaf_iterator
: public iterator_base
{
232 leaf_iterator(tree_node
*, tree_node
*top
=0);
233 leaf_iterator(const sibling_iterator
&);
234 leaf_iterator(const iterator_base
&);
236 bool operator==(const leaf_iterator
&) const;
237 bool operator!=(const leaf_iterator
&) const;
238 leaf_iterator
& operator++();
239 leaf_iterator
& operator--();
240 leaf_iterator
operator++(int);
241 leaf_iterator
operator--(int);
242 leaf_iterator
& operator+=(unsigned int);
243 leaf_iterator
& operator-=(unsigned int);
248 /// Return iterator to the beginning of the tree.
249 inline pre_order_iterator
begin() const;
250 /// Return iterator to the end of the tree.
251 inline pre_order_iterator
end() const;
252 /// Return post-order iterator to the beginning of the tree.
253 post_order_iterator
begin_post() const;
254 /// Return post-order end iterator of the tree.
255 post_order_iterator
end_post() const;
256 /// Return fixed-depth iterator to the first node at a given depth from the given iterator.
257 fixed_depth_iterator
begin_fixed(const iterator_base
&, unsigned int) const;
258 /// Return fixed-depth end iterator.
259 fixed_depth_iterator
end_fixed(const iterator_base
&, unsigned int) const;
260 /// Return breadth-first iterator to the first node at a given depth.
261 breadth_first_queued_iterator
begin_breadth_first() const;
262 /// Return breadth-first end iterator.
263 breadth_first_queued_iterator
end_breadth_first() const;
264 /// Return sibling iterator to the first child of given node.
265 sibling_iterator
begin(const iterator_base
&) const;
266 /// Return sibling end iterator for children of given node.
267 sibling_iterator
end(const iterator_base
&) const;
268 /// Return leaf iterator to the first leaf of the tree.
269 leaf_iterator
begin_leaf() const;
270 /// Return leaf end iterator for entire tree.
271 leaf_iterator
end_leaf() const;
272 /// Return leaf iterator to the first leaf of the subtree at the given node.
273 leaf_iterator
begin_leaf(const iterator_base
& top
) const;
274 /// Return leaf end iterator for the subtree at the given node.
275 leaf_iterator
end_leaf(const iterator_base
& top
) const;
277 /// Return iterator to the parent of a node.
278 template<typename iter
> static iter
parent(iter
);
279 /// Return iterator to the previous sibling of a node.
280 template<typename iter
> static iter
previous_sibling(iter
);
281 /// Return iterator to the next sibling of a node.
282 template<typename iter
> static iter
next_sibling(iter
);
283 /// Return iterator to the next node at a given depth.
284 template<typename iter
> iter
next_at_same_depth(iter
) const;
286 /// Erase all nodes of the tree.
288 /// Erase element at position pointed to by iterator, return incremented iterator.
289 template<typename iter
> iter
erase(iter
);
290 /// Erase all children of the node pointed to by iterator.
291 void erase_children(const iterator_base
&);
293 /// Insert empty node as last/first child of node pointed to by position.
294 template<typename iter
> iter
append_child(iter position
);
295 template<typename iter
> iter
prepend_child(iter position
);
296 /// Insert node as last/first child of node pointed to by position.
297 template<typename iter
> iter
append_child(iter position
, const T
& x
);
298 template<typename iter
> iter
prepend_child(iter position
, const T
& x
);
299 /// Append the node (plus its children) at other_position as last/first child of position.
300 template<typename iter
> iter
append_child(iter position
, iter other_position
);
301 template<typename iter
> iter
prepend_child(iter position
, iter other_position
);
302 /// Append the nodes in the from-to range (plus their children) as last/first children of position.
303 template<typename iter
> iter
append_children(iter position
, sibling_iterator from
, sibling_iterator to
);
304 template<typename iter
> iter
prepend_children(iter position
, sibling_iterator from
, sibling_iterator to
);
306 /// Short-hand to insert topmost node in otherwise empty tree.
307 pre_order_iterator
set_head(const T
& x
);
308 /// Insert node as previous sibling of node pointed to by position.
309 template<typename iter
> iter
insert(iter position
, const T
& x
);
310 /// Specialisation of previous member.
311 sibling_iterator
insert(sibling_iterator position
, const T
& x
);
312 /// Insert node (with children) pointed to by subtree as previous sibling of node pointed to by position.
313 /// Does not change the subtree itself (use move_in or move_in_below for that).
314 template<typename iter
> iter
insert_subtree(iter position
, const iterator_base
& subtree
);
315 /// Insert node as next sibling of node pointed to by position.
316 template<typename iter
> iter
insert_after(iter position
, const T
& x
);
317 /// Insert node (with children) pointed to by subtree as next sibling of node pointed to by position.
318 template<typename iter
> iter
insert_subtree_after(iter position
, const iterator_base
& subtree
);
320 /// Replace node at 'position' with other node (keeping same children); 'position' becomes invalid.
321 template<typename iter
> iter
replace(iter position
, const T
& x
);
322 /// Replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from'); see above.
323 template<typename iter
> iter
replace(iter position
, const iterator_base
& from
);
324 /// Replace string of siblings (plus their children) with copy of a new string (with children); see above
325 sibling_iterator
replace(sibling_iterator orig_begin
, sibling_iterator orig_end
,
326 sibling_iterator new_begin
, sibling_iterator new_end
);
328 /// Move all children of node at 'position' to be siblings, returns position.
329 template<typename iter
> iter
flatten(iter position
);
330 /// Move nodes in range to be children of 'position'.
331 template<typename iter
> iter
reparent(iter position
, sibling_iterator begin
, sibling_iterator end
);
332 /// Move all child nodes of 'from' to be children of 'position'.
333 template<typename iter
> iter
reparent(iter position
, iter from
);
335 /// Replace node with a new node, making the old node a child of the new node.
336 template<typename iter
> iter
wrap(iter position
, const T
& x
);
338 /// Move 'source' node (plus its children) to become the next sibling of 'target'.
339 template<typename iter
> iter
move_after(iter target
, iter source
);
340 /// Move 'source' node (plus its children) to become the previous sibling of 'target'.
341 template<typename iter
> iter
move_before(iter target
, iter source
);
342 sibling_iterator
move_before(sibling_iterator target
, sibling_iterator source
);
343 /// Move 'source' node (plus its children) to become the node at 'target' (erasing the node at 'target').
344 template<typename iter
> iter
move_ontop(iter target
, iter source
);
346 /// Extract the subtree starting at the indicated node, removing it from the original tree.
347 tree
move_out(iterator
);
348 /// Inverse of take_out: inserts the given tree as previous sibling of indicated node by a
349 /// move operation, that is, the given tree becomes empty. Returns iterator to the top node.
350 template<typename iter
> iter
move_in(iter
, tree
&);
351 /// As above, but now make the tree a child of the indicated node.
352 template<typename iter
> iter
move_in_below(iter
, tree
&);
353 /// As above, but now make the tree the nth child of the indicated node (if possible).
354 template<typename iter
> iter
move_in_as_nth_child(iter
, size_t, tree
&);
356 /// Merge with other tree, creating new branches and leaves only if they are not already present.
357 void merge(sibling_iterator
, sibling_iterator
, sibling_iterator
, sibling_iterator
,
358 bool duplicate_leaves
=false);
359 /// Sort (std::sort only moves values of nodes, this one moves children as well).
360 void sort(sibling_iterator from
, sibling_iterator to
, bool deep
=false);
361 template<class StrictWeakOrdering
>
362 void sort(sibling_iterator from
, sibling_iterator to
, StrictWeakOrdering comp
, bool deep
=false);
363 /// Compare two ranges of nodes (compares nodes as well as tree structure).
364 template<typename iter
>
365 bool equal(const iter
& one
, const iter
& two
, const iter
& three
) const;
366 template<typename iter
, class BinaryPredicate
>
367 bool equal(const iter
& one
, const iter
& two
, const iter
& three
, BinaryPredicate
) const;
368 template<typename iter
>
369 bool equal_subtree(const iter
& one
, const iter
& two
) const;
370 template<typename iter
, class BinaryPredicate
>
371 bool equal_subtree(const iter
& one
, const iter
& two
, BinaryPredicate
) const;
372 /// Extract a new tree formed by the range of siblings plus all their children.
373 tree
subtree(sibling_iterator from
, sibling_iterator to
) const;
374 void subtree(tree
&, sibling_iterator from
, sibling_iterator to
) const;
375 /// Exchange the node (plus subtree) with its sibling node (do nothing if no sibling present).
376 void swap(sibling_iterator it
);
377 /// Exchange two nodes (plus subtrees)
378 void swap(iterator
, iterator
);
380 /// Count the total number of nodes.
382 /// Count the total number of nodes below the indicated node (plus one).
383 size_t size(const iterator_base
&) const;
384 /// Check if tree is empty.
386 /// Compute the depth to the root or to a fixed other iterator.
387 static int depth(const iterator_base
&);
388 static int depth(const iterator_base
&, const iterator_base
&);
389 /// Determine the maximal depth of the tree. An empty tree has max_depth=-1.
390 int max_depth() const;
391 /// Determine the maximal depth of the tree with top node at the given position.
392 int max_depth(const iterator_base
&) const;
393 /// Count the number of children of node at position.
394 static unsigned int number_of_children(const iterator_base
&);
395 /// Count the number of siblings (left and right) of node at iterator. Total nodes at this level is +1.
396 unsigned int number_of_siblings(const iterator_base
&) const;
397 /// Determine whether node at position is in the subtrees with root in the range.
398 bool is_in_subtree(const iterator_base
& position
, const iterator_base
& begin
,
399 const iterator_base
& end
) const;
400 /// Determine whether the iterator is an 'end' iterator and thus not actually pointing to a node.
401 bool is_valid(const iterator_base
&) const;
402 /// Find the lowest common ancestor of two nodes, that is, the deepest node such that
403 /// both nodes are descendants of it.
404 iterator
lowest_common_ancestor(const iterator_base
&, const iterator_base
&) const;
406 /// Determine the index of a node in the range of siblings to which it belongs.
407 unsigned int index(sibling_iterator it
) const;
408 /// Inverse of 'index': return the n-th child of the node at position.
409 static sibling_iterator
child(const iterator_base
& position
, unsigned int);
410 /// Return iterator to the sibling indicated by index
411 sibling_iterator
sibling(const iterator_base
& position
, unsigned int);
413 /// For debugging only: verify internal consistency by inspecting all pointers in the tree
414 /// (which will also trigger a valgrind error in case something got corrupted).
415 void debug_verify_consistency() const;
417 /// Comparator class for iterators (compares pointer values; why doesn't this work automatically?)
418 class iterator_base_less
{
420 bool operator()(const typename tree
<T
, tree_node_allocator
>::iterator_base
& one
,
421 const typename tree
<T
, tree_node_allocator
>::iterator_base
& two
) const
423 return one
.node
< two
.node
;
426 tree_node
*head
, *feet
; // head/feet are always dummy; if an iterator points to them it is invalid
428 tree_node_allocator alloc_
;
429 void head_initialise_();
430 void copy_(const tree
<T
, tree_node_allocator
>& other
);
432 /// Comparator class for two nodes of a tree (used for sorting and searching).
433 template<class StrictWeakOrdering
>
434 class compare_nodes
{
436 compare_nodes(StrictWeakOrdering comp
) : comp_(comp
) {};
438 bool operator()(const tree_node
*a
, const tree_node
*b
)
440 return comp_(a
->data
, b
->data
);
443 StrictWeakOrdering comp_
;
447 //template <class T, class tree_node_allocator>
448 //class iterator_base_less {
450 // bool operator()(const typename tree<T, tree_node_allocator>::iterator_base& one,
451 // const typename tree<T, tree_node_allocator>::iterator_base& two) const
453 // txtout << "operatorclass<" << one.node < two.node << std::endl;
454 // return one.node < two.node;
458 // template <class T, class tree_node_allocator>
459 // bool operator<(const typename tree<T, tree_node_allocator>::iterator& one,
460 // const typename tree<T, tree_node_allocator>::iterator& two)
462 // txtout << "operator< " << one.node < two.node << std::endl;
463 // if(one.node < two.node) return true;
467 // template <class T, class tree_node_allocator>
468 // bool operator==(const typename tree<T, tree_node_allocator>::iterator& one,
469 // const typename tree<T, tree_node_allocator>::iterator& two)
471 // txtout << "operator== " << one.node == two.node << std::endl;
472 // if(one.node == two.node) return true;
476 // template <class T, class tree_node_allocator>
477 // bool operator>(const typename tree<T, tree_node_allocator>::iterator_base& one,
478 // const typename tree<T, tree_node_allocator>::iterator_base& two)
480 // txtout << "operator> " << one.node < two.node << std::endl;
481 // if(one.node > two.node) return true;
489 template <class T
, class tree_node_allocator
>
490 tree
<T
, tree_node_allocator
>::tree()
495 template <class T
, class tree_node_allocator
>
496 tree
<T
, tree_node_allocator
>::tree(const T
& x
)
502 template <class T
, class tree_node_allocator
>
503 tree
<T
, tree_node_allocator
>::tree(tree
<T
, tree_node_allocator
>&& x
)
506 head
->next_sibling
=x
.head
->next_sibling
;
507 feet
->prev_sibling
=x
.head
->prev_sibling
;
508 x
.head
->next_sibling
->prev_sibling
=head
;
509 x
.feet
->prev_sibling
->next_sibling
=feet
;
510 x
.head
->next_sibling
=x
.feet
;
511 x
.feet
->prev_sibling
=x
.head
;
514 template <class T
, class tree_node_allocator
>
515 tree
<T
, tree_node_allocator
>::tree(const iterator_base
& other
)
519 replace(begin(), other
);
522 template <class T
, class tree_node_allocator
>
523 tree
<T
, tree_node_allocator
>::~tree()
526 alloc_
.destroy(head
);
527 alloc_
.destroy(feet
);
528 alloc_
.deallocate(head
,1);
529 alloc_
.deallocate(feet
,1);
532 template <class T
, class tree_node_allocator
>
533 void tree
<T
, tree_node_allocator
>::head_initialise_()
535 head
= alloc_
.allocate(1,0); // MSVC does not have default second argument
536 feet
= alloc_
.allocate(1,0);
537 alloc_
.construct(head
, tree_node_
<T
>());
538 alloc_
.construct(feet
, tree_node_
<T
>());
543 head
->prev_sibling
=0; //head;
544 head
->next_sibling
=feet
; //head;
549 feet
->prev_sibling
=head
;
550 feet
->next_sibling
=0;
553 template <class T
, class tree_node_allocator
>
554 tree
<T
,tree_node_allocator
>& tree
<T
, tree_node_allocator
>::operator=(const tree
<T
, tree_node_allocator
>& other
)
561 template <class T
, class tree_node_allocator
>
562 tree
<T
,tree_node_allocator
>& tree
<T
, tree_node_allocator
>::operator=(tree
<T
, tree_node_allocator
>&& x
)
565 head
->next_sibling
=x
.head
->next_sibling
;
566 feet
->prev_sibling
=x
.head
->prev_sibling
;
567 x
.head
->next_sibling
->prev_sibling
=head
;
568 x
.feet
->prev_sibling
->next_sibling
=feet
;
569 x
.head
->next_sibling
=x
.feet
;
570 x
.feet
->prev_sibling
=x
.head
;
575 template <class T
, class tree_node_allocator
>
576 tree
<T
, tree_node_allocator
>::tree(const tree
<T
, tree_node_allocator
>& other
)
582 template <class T
, class tree_node_allocator
>
583 void tree
<T
, tree_node_allocator
>::copy_(const tree
<T
, tree_node_allocator
>& other
)
586 pre_order_iterator it
=other
.begin(), to
=begin();
587 while(it
!=other
.end()) {
588 to
=insert(to
, (*it
));
594 while(it
!=other
.end()) {
603 template <class T
, class tree_node_allocator
>
604 void tree
<T
, tree_node_allocator
>::clear()
607 while(head
->next_sibling
!=feet
)
608 erase(pre_order_iterator(head
->next_sibling
));
611 template<class T
, class tree_node_allocator
>
612 void tree
<T
, tree_node_allocator
>::erase_children(const iterator_base
& it
)
614 // std::cout << "erase_children " << it.node << std::endl;
615 if(it
.node
==0) return;
617 tree_node
*cur
=it
.node
->first_child
;
622 cur
=cur
->next_sibling
;
623 erase_children(pre_order_iterator(prev
));
624 // kp::destructor(&prev->data);
625 alloc_
.destroy(prev
);
626 alloc_
.deallocate(prev
,1);
628 it
.node
->first_child
=0;
629 it
.node
->last_child
=0;
630 // std::cout << "exit" << std::endl;
633 template<class T
, class tree_node_allocator
>
635 iter tree
<T
, tree_node_allocator
>::erase(iter it
)
637 tree_node
*cur
=it
.node
;
643 if(cur
->prev_sibling
==0) {
644 cur
->parent
->first_child
=cur
->next_sibling
;
647 cur
->prev_sibling
->next_sibling
=cur
->next_sibling
;
649 if(cur
->next_sibling
==0) {
650 cur
->parent
->last_child
=cur
->prev_sibling
;
653 cur
->next_sibling
->prev_sibling
=cur
->prev_sibling
;
656 // kp::destructor(&cur->data);
658 alloc_
.deallocate(cur
,1);
662 template <class T
, class tree_node_allocator
>
663 typename tree
<T
, tree_node_allocator
>::pre_order_iterator tree
<T
, tree_node_allocator
>::begin() const
665 return pre_order_iterator(head
->next_sibling
);
668 template <class T
, class tree_node_allocator
>
669 typename tree
<T
, tree_node_allocator
>::pre_order_iterator tree
<T
, tree_node_allocator
>::end() const
671 return pre_order_iterator(feet
);
674 template <class T
, class tree_node_allocator
>
675 typename tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator tree
<T
, tree_node_allocator
>::begin_breadth_first() const
677 return breadth_first_queued_iterator(head
->next_sibling
);
680 template <class T
, class tree_node_allocator
>
681 typename tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator tree
<T
, tree_node_allocator
>::end_breadth_first() const
683 return breadth_first_queued_iterator();
686 template <class T
, class tree_node_allocator
>
687 typename tree
<T
, tree_node_allocator
>::post_order_iterator tree
<T
, tree_node_allocator
>::begin_post() const
689 tree_node
*tmp
=head
->next_sibling
;
691 while(tmp
->first_child
)
692 tmp
=tmp
->first_child
;
694 return post_order_iterator(tmp
);
697 template <class T
, class tree_node_allocator
>
698 typename tree
<T
, tree_node_allocator
>::post_order_iterator tree
<T
, tree_node_allocator
>::end_post() const
700 return post_order_iterator(feet
);
703 template <class T
, class tree_node_allocator
>
704 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator tree
<T
, tree_node_allocator
>::begin_fixed(const iterator_base
& pos
, unsigned int dp
) const
706 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator ret
;
707 ret
.top_node
=pos
.node
;
709 tree_node
*tmp
=pos
.node
;
710 unsigned int curdepth
=0;
711 while(curdepth
<dp
) { // go down one level
712 while(tmp
->first_child
==0) {
713 if(tmp
->next_sibling
==0) {
714 // try to walk up and then right again
716 if(tmp
==ret
.top_node
)
717 throw std::range_error("tree: begin_fixed out of range");
720 throw std::range_error("tree: begin_fixed out of range");
722 } while(tmp
->next_sibling
==0);
724 tmp
=tmp
->next_sibling
;
726 tmp
=tmp
->first_child
;
734 template <class T
, class tree_node_allocator
>
735 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator tree
<T
, tree_node_allocator
>::end_fixed(const iterator_base
& pos
, unsigned int dp
) const
737 assert(1==0); // FIXME: not correct yet: use is_valid() as a temporary workaround
738 tree_node
*tmp
=pos
.node
;
739 unsigned int curdepth
=1;
740 while(curdepth
<dp
) { // go down one level
741 while(tmp
->first_child
==0) {
742 tmp
=tmp
->next_sibling
;
744 throw std::range_error("tree: end_fixed out of range");
746 tmp
=tmp
->first_child
;
752 template <class T
, class tree_node_allocator
>
753 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::begin(const iterator_base
& pos
) const
756 if(pos
.node
->first_child
==0) {
759 return pos
.node
->first_child
;
762 template <class T
, class tree_node_allocator
>
763 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::end(const iterator_base
& pos
) const
765 sibling_iterator
ret(0);
766 ret
.parent_
=pos
.node
;
770 template <class T
, class tree_node_allocator
>
771 typename tree
<T
, tree_node_allocator
>::leaf_iterator tree
<T
, tree_node_allocator
>::begin_leaf() const
773 tree_node
*tmp
=head
->next_sibling
;
775 while(tmp
->first_child
)
776 tmp
=tmp
->first_child
;
778 return leaf_iterator(tmp
);
781 template <class T
, class tree_node_allocator
>
782 typename tree
<T
, tree_node_allocator
>::leaf_iterator tree
<T
, tree_node_allocator
>::end_leaf() const
784 return leaf_iterator(feet
);
787 template <class T
, class tree_node_allocator
>
788 typename tree
<T
, tree_node_allocator
>::leaf_iterator tree
<T
, tree_node_allocator
>::begin_leaf(const iterator_base
& top
) const
790 tree_node
*tmp
=top
.node
;
791 while(tmp
->first_child
)
792 tmp
=tmp
->first_child
;
793 return leaf_iterator(tmp
, top
.node
);
796 template <class T
, class tree_node_allocator
>
797 typename tree
<T
, tree_node_allocator
>::leaf_iterator tree
<T
, tree_node_allocator
>::end_leaf(const iterator_base
& top
) const
799 return leaf_iterator(top
.node
, top
.node
);
802 template <class T
, class tree_node_allocator
>
803 template <typename iter
>
804 iter tree
<T
, tree_node_allocator
>::parent(iter position
)
806 assert(position
.node
!=0);
807 return iter(position
.node
->parent
);
810 template <class T
, class tree_node_allocator
>
811 template <typename iter
>
812 iter tree
<T
, tree_node_allocator
>::previous_sibling(iter position
)
814 assert(position
.node
!=0);
816 ret
.node
=position
.node
->prev_sibling
;
820 template <class T
, class tree_node_allocator
>
821 template <typename iter
>
822 iter tree
<T
, tree_node_allocator
>::next_sibling(iter position
)
824 assert(position
.node
!=0);
826 ret
.node
=position
.node
->next_sibling
;
830 template <class T
, class tree_node_allocator
>
831 template <typename iter
>
832 iter tree
<T
, tree_node_allocator
>::next_at_same_depth(iter position
) const
834 // We make use of a temporary fixed_depth iterator to implement this.
836 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator
tmp(position
.node
);
841 // assert(position.node!=0);
842 // iter ret(position);
844 // if(position.node->next_sibling) {
845 // ret.node=position.node->next_sibling;
848 // int relative_depth=0;
851 // ret.node=ret.node->parent;
852 // if(ret.node==0) return ret;
854 // } while(ret.node->next_sibling==0);
856 // ret.node=ret.node->next_sibling;
857 // while(ret.node->first_child==0) {
858 // if(ret.node->next_sibling==0)
860 // ret.node=ret.node->next_sibling;
861 // if(ret.node==0) return ret;
863 // while(relative_depth<0 && ret.node->first_child!=0) {
864 // ret.node=ret.node->first_child;
867 // if(relative_depth<0) {
868 // if(ret.node->next_sibling==0) goto upper;
875 template <class T
, class tree_node_allocator
>
876 template <typename iter
>
877 iter tree
<T
, tree_node_allocator
>::append_child(iter position
)
879 assert(position
.node
!=head
);
880 assert(position
.node
!=feet
);
881 assert(position
.node
);
883 tree_node
*tmp
=alloc_
.allocate(1,0);
884 alloc_
.construct(tmp
, tree_node_
<T
>());
885 // kp::constructor(&tmp->data);
889 tmp
->parent
=position
.node
;
890 if(position
.node
->last_child
!=0) {
891 position
.node
->last_child
->next_sibling
=tmp
;
894 position
.node
->first_child
=tmp
;
896 tmp
->prev_sibling
=position
.node
->last_child
;
897 position
.node
->last_child
=tmp
;
902 template <class T
, class tree_node_allocator
>
903 template <typename iter
>
904 iter tree
<T
, tree_node_allocator
>::prepend_child(iter position
)
906 assert(position
.node
!=head
);
907 assert(position
.node
!=feet
);
908 assert(position
.node
);
910 tree_node
*tmp
=alloc_
.allocate(1,0);
911 alloc_
.construct(tmp
, tree_node_
<T
>());
912 // kp::constructor(&tmp->data);
916 tmp
->parent
=position
.node
;
917 if(position
.node
->first_child
!=0) {
918 position
.node
->first_child
->prev_sibling
=tmp
;
921 position
.node
->last_child
=tmp
;
923 tmp
->next_sibling
=position
.node
->first_child
;
924 position
.node
->prev_child
=tmp
;
929 template <class T
, class tree_node_allocator
>
930 template <class iter
>
931 iter tree
<T
, tree_node_allocator
>::append_child(iter position
, const T
& x
)
933 // If your program fails here you probably used 'append_child' to add the top
934 // node to an empty tree. From version 1.45 the top element should be added
935 // using 'insert'. See the documentation for further information, and sorry about
937 assert(position
.node
!=head
);
938 assert(position
.node
!=feet
);
939 assert(position
.node
);
941 tree_node
* tmp
= alloc_
.allocate(1,0);
942 alloc_
.construct(tmp
, x
);
943 // kp::constructor(&tmp->data, x);
947 tmp
->parent
=position
.node
;
948 if(position
.node
->last_child
!=0) {
949 position
.node
->last_child
->next_sibling
=tmp
;
952 position
.node
->first_child
=tmp
;
954 tmp
->prev_sibling
=position
.node
->last_child
;
955 position
.node
->last_child
=tmp
;
960 template <class T
, class tree_node_allocator
>
961 template <class iter
>
962 iter tree
<T
, tree_node_allocator
>::prepend_child(iter position
, const T
& x
)
964 assert(position
.node
!=head
);
965 assert(position
.node
!=feet
);
966 assert(position
.node
);
968 tree_node
* tmp
= alloc_
.allocate(1,0);
969 alloc_
.construct(tmp
, x
);
970 // kp::constructor(&tmp->data, x);
974 tmp
->parent
=position
.node
;
975 if(position
.node
->first_child
!=0) {
976 position
.node
->first_child
->prev_sibling
=tmp
;
979 position
.node
->last_child
=tmp
;
981 tmp
->next_sibling
=position
.node
->first_child
;
982 position
.node
->first_child
=tmp
;
987 template <class T
, class tree_node_allocator
>
988 template <class iter
>
989 iter tree
<T
, tree_node_allocator
>::append_child(iter position
, iter other
)
991 assert(position
.node
!=head
);
992 assert(position
.node
!=feet
);
993 assert(position
.node
);
995 sibling_iterator aargh
=append_child(position
, value_type());
996 return replace(aargh
, other
);
999 template <class T
, class tree_node_allocator
>
1000 template <class iter
>
1001 iter tree
<T
, tree_node_allocator
>::prepend_child(iter position
, iter other
)
1003 assert(position
.node
!=head
);
1004 assert(position
.node
!=feet
);
1005 assert(position
.node
);
1007 sibling_iterator aargh
=prepend_child(position
, value_type());
1008 return replace(aargh
, other
);
1011 template <class T
, class tree_node_allocator
>
1012 template <class iter
>
1013 iter tree
<T
, tree_node_allocator
>::append_children(iter position
, sibling_iterator from
, sibling_iterator to
)
1015 assert(position
.node
!=head
);
1016 assert(position
.node
!=feet
);
1017 assert(position
.node
);
1022 insert_subtree(position
.end(), from
);
1028 template <class T
, class tree_node_allocator
>
1029 template <class iter
>
1030 iter tree
<T
, tree_node_allocator
>::prepend_children(iter position
, sibling_iterator from
, sibling_iterator to
)
1032 assert(position
.node
!=head
);
1033 assert(position
.node
!=feet
);
1034 assert(position
.node
);
1039 insert_subtree(position
.begin(), from
);
1045 template <class T
, class tree_node_allocator
>
1046 typename tree
<T
, tree_node_allocator
>::pre_order_iterator tree
<T
, tree_node_allocator
>::set_head(const T
& x
)
1048 assert(head
->next_sibling
==feet
);
1049 return insert(iterator(feet
), x
);
1052 template <class T
, class tree_node_allocator
>
1053 template <class iter
>
1054 iter tree
<T
, tree_node_allocator
>::insert(iter position
, const T
& x
)
1056 if(position
.node
==0) {
1057 position
.node
=feet
; // Backward compatibility: when calling insert on a null node,
1058 // insert before the feet.
1060 tree_node
* tmp
= alloc_
.allocate(1,0);
1061 alloc_
.construct(tmp
, x
);
1062 // kp::constructor(&tmp->data, x);
1066 tmp
->parent
=position
.node
->parent
;
1067 tmp
->next_sibling
=position
.node
;
1068 tmp
->prev_sibling
=position
.node
->prev_sibling
;
1069 position
.node
->prev_sibling
=tmp
;
1071 if(tmp
->prev_sibling
==0) {
1072 if(tmp
->parent
) // when inserting nodes at the head, there is no parent
1073 tmp
->parent
->first_child
=tmp
;
1076 tmp
->prev_sibling
->next_sibling
=tmp
;
1080 template <class T
, class tree_node_allocator
>
1081 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::insert(sibling_iterator position
, const T
& x
)
1083 tree_node
* tmp
= alloc_
.allocate(1,0);
1084 alloc_
.construct(tmp
, x
);
1085 // kp::constructor(&tmp->data, x);
1089 tmp
->next_sibling
=position
.node
;
1090 if(position
.node
==0) { // iterator points to end of a subtree
1091 tmp
->parent
=position
.parent_
;
1092 tmp
->prev_sibling
=position
.range_last();
1093 tmp
->parent
->last_child
=tmp
;
1096 tmp
->parent
=position
.node
->parent
;
1097 tmp
->prev_sibling
=position
.node
->prev_sibling
;
1098 position
.node
->prev_sibling
=tmp
;
1101 if(tmp
->prev_sibling
==0) {
1102 if(tmp
->parent
) // when inserting nodes at the head, there is no parent
1103 tmp
->parent
->first_child
=tmp
;
1106 tmp
->prev_sibling
->next_sibling
=tmp
;
1110 template <class T
, class tree_node_allocator
>
1111 template <class iter
>
1112 iter tree
<T
, tree_node_allocator
>::insert_after(iter position
, const T
& x
)
1114 tree_node
* tmp
= alloc_
.allocate(1,0);
1115 alloc_
.construct(tmp
, x
);
1116 // kp::constructor(&tmp->data, x);
1120 tmp
->parent
=position
.node
->parent
;
1121 tmp
->prev_sibling
=position
.node
;
1122 tmp
->next_sibling
=position
.node
->next_sibling
;
1123 position
.node
->next_sibling
=tmp
;
1125 if(tmp
->next_sibling
==0) {
1126 if(tmp
->parent
) // when inserting nodes at the head, there is no parent
1127 tmp
->parent
->last_child
=tmp
;
1130 tmp
->next_sibling
->prev_sibling
=tmp
;
1135 template <class T
, class tree_node_allocator
>
1136 template <class iter
>
1137 iter tree
<T
, tree_node_allocator
>::insert_subtree(iter position
, const iterator_base
& subtree
)
1140 iter it
=insert(position
, value_type());
1141 // replace dummy with subtree
1142 return replace(it
, subtree
);
1145 template <class T
, class tree_node_allocator
>
1146 template <class iter
>
1147 iter tree
<T
, tree_node_allocator
>::insert_subtree_after(iter position
, const iterator_base
& subtree
)
1150 iter it
=insert_after(position
, value_type());
1151 // replace dummy with subtree
1152 return replace(it
, subtree
);
1155 // template <class T, class tree_node_allocator>
1156 // template <class iter>
1157 // iter tree<T, tree_node_allocator>::insert_subtree(sibling_iterator position, iter subtree)
1160 // iter it(insert(position, value_type()));
1161 // // replace dummy with subtree
1162 // return replace(it, subtree);
1165 template <class T
, class tree_node_allocator
>
1166 template <class iter
>
1167 iter tree
<T
, tree_node_allocator
>::replace(iter position
, const T
& x
)
1169 // kp::destructor(&position.node->data);
1170 // kp::constructor(&position.node->data, x);
1171 position
.node
->data
=x
;
1172 // alloc_.destroy(position.node);
1173 // alloc_.construct(position.node, x);
1177 template <class T
, class tree_node_allocator
>
1178 template <class iter
>
1179 iter tree
<T
, tree_node_allocator
>::replace(iter position
, const iterator_base
& from
)
1181 assert(position
.node
!=head
);
1182 tree_node
*current_from
=from
.node
;
1183 tree_node
*start_from
=from
.node
;
1184 tree_node
*current_to
=position
.node
;
1186 // replace the node at position with head of the replacement tree at from
1187 // std::cout << "warning!" << position.node << std::endl;
1188 erase_children(position
);
1189 // std::cout << "no warning!" << std::endl;
1190 tree_node
* tmp
= alloc_
.allocate(1,0);
1191 alloc_
.construct(tmp
, (*from
));
1192 // kp::constructor(&tmp->data, (*from));
1195 if(current_to
->prev_sibling
==0) {
1196 if(current_to
->parent
!=0)
1197 current_to
->parent
->first_child
=tmp
;
1200 current_to
->prev_sibling
->next_sibling
=tmp
;
1202 tmp
->prev_sibling
=current_to
->prev_sibling
;
1203 if(current_to
->next_sibling
==0) {
1204 if(current_to
->parent
!=0)
1205 current_to
->parent
->last_child
=tmp
;
1208 current_to
->next_sibling
->prev_sibling
=tmp
;
1210 tmp
->next_sibling
=current_to
->next_sibling
;
1211 tmp
->parent
=current_to
->parent
;
1212 // kp::destructor(¤t_to->data);
1213 alloc_
.destroy(current_to
);
1214 alloc_
.deallocate(current_to
,1);
1217 // only at this stage can we fix 'last'
1218 tree_node
*last
=from
.node
->next_sibling
;
1220 pre_order_iterator toit
=tmp
;
1221 // copy all children
1223 assert(current_from
!=0);
1224 if(current_from
->first_child
!= 0) {
1225 current_from
=current_from
->first_child
;
1226 toit
=append_child(toit
, current_from
->data
);
1229 while(current_from
->next_sibling
==0 && current_from
!=start_from
) {
1230 current_from
=current_from
->parent
;
1232 assert(current_from
!=0);
1234 current_from
=current_from
->next_sibling
;
1235 if(current_from
!=last
) {
1236 toit
=append_child(parent(toit
), current_from
->data
);
1239 } while(current_from
!=last
);
1244 template <class T
, class tree_node_allocator
>
1245 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::replace(
1246 sibling_iterator orig_begin
,
1247 sibling_iterator orig_end
,
1248 sibling_iterator new_begin
,
1249 sibling_iterator new_end
)
1251 tree_node
*orig_first
=orig_begin
.node
;
1252 tree_node
*new_first
=new_begin
.node
;
1253 tree_node
*orig_last
=orig_first
;
1254 while((++orig_begin
)!=orig_end
)
1255 orig_last
=orig_last
->next_sibling
;
1256 tree_node
*new_last
=new_first
;
1257 while((++new_begin
)!=new_end
)
1258 new_last
=new_last
->next_sibling
;
1260 // insert all siblings in new_first..new_last before orig_first
1262 pre_order_iterator ret
;
1264 pre_order_iterator tt
=insert_subtree(pre_order_iterator(orig_first
), pre_order_iterator(new_first
));
1269 if(new_first
==new_last
)
1271 new_first
=new_first
->next_sibling
;
1274 // erase old range of siblings
1276 tree_node
*next
=orig_first
;
1280 next
=next
->next_sibling
;
1281 erase((pre_order_iterator
)orig_first
);
1289 template <class T
, class tree_node_allocator
>
1290 template <typename iter
>
1291 iter tree
<T
, tree_node_allocator
>::flatten(iter position
)
1293 if(position
.node
->first_child
==0)
1296 tree_node
*tmp
=position
.node
->first_child
;
1298 tmp
->parent
=position
.node
->parent
;
1299 tmp
=tmp
->next_sibling
;
1301 if(position
.node
->next_sibling
) {
1302 position
.node
->last_child
->next_sibling
=position
.node
->next_sibling
;
1303 position
.node
->next_sibling
->prev_sibling
=position
.node
->last_child
;
1306 position
.node
->parent
->last_child
=position
.node
->last_child
;
1308 position
.node
->next_sibling
=position
.node
->first_child
;
1309 position
.node
->next_sibling
->prev_sibling
=position
.node
;
1310 position
.node
->first_child
=0;
1311 position
.node
->last_child
=0;
1317 template <class T
, class tree_node_allocator
>
1318 template <typename iter
>
1319 iter tree
<T
, tree_node_allocator
>::reparent(iter position
, sibling_iterator begin
, sibling_iterator end
)
1321 tree_node
*first
=begin
.node
;
1322 tree_node
*last
=first
;
1324 assert(first
!=position
.node
);
1326 if(begin
==end
) return begin
;
1327 // determine last node
1328 while((++begin
)!=end
) {
1329 last
=last
->next_sibling
;
1332 if(first
->prev_sibling
==0) {
1333 first
->parent
->first_child
=last
->next_sibling
;
1336 first
->prev_sibling
->next_sibling
=last
->next_sibling
;
1338 if(last
->next_sibling
==0) {
1339 last
->parent
->last_child
=first
->prev_sibling
;
1342 last
->next_sibling
->prev_sibling
=first
->prev_sibling
;
1344 if(position
.node
->first_child
==0) {
1345 position
.node
->first_child
=first
;
1346 position
.node
->last_child
=last
;
1347 first
->prev_sibling
=0;
1350 position
.node
->last_child
->next_sibling
=first
;
1351 first
->prev_sibling
=position
.node
->last_child
;
1352 position
.node
->last_child
=last
;
1354 last
->next_sibling
=0;
1356 tree_node
*pos
=first
;
1358 pos
->parent
=position
.node
;
1359 if(pos
==last
) break;
1360 pos
=pos
->next_sibling
;
1366 template <class T
, class tree_node_allocator
>
1367 template <typename iter
> iter tree
<T
, tree_node_allocator
>::reparent(iter position
, iter from
)
1369 if(from
.node
->first_child
==0) return position
;
1370 return reparent(position
, from
.node
->first_child
, end(from
));
1373 template <class T
, class tree_node_allocator
>
1374 template <typename iter
> iter tree
<T
, tree_node_allocator
>::wrap(iter position
, const T
& x
)
1376 assert(position
.node
!=0);
1377 sibling_iterator fr
=position
, to
=position
;
1379 iter ret
= insert(position
, x
);
1380 reparent(ret
, fr
, to
);
1384 template <class T
, class tree_node_allocator
>
1385 template <typename iter
> iter tree
<T
, tree_node_allocator
>::move_after(iter target
, iter source
)
1387 tree_node
*dst
=target
.node
;
1388 tree_node
*src
=source
.node
;
1392 if(dst
==src
) return source
;
1393 if(dst
->next_sibling
)
1394 if(dst
->next_sibling
==src
) // already in the right spot
1397 // take src out of the tree
1398 if(src
->prev_sibling
!=0) src
->prev_sibling
->next_sibling
=src
->next_sibling
;
1399 else src
->parent
->first_child
=src
->next_sibling
;
1400 if(src
->next_sibling
!=0) src
->next_sibling
->prev_sibling
=src
->prev_sibling
;
1401 else src
->parent
->last_child
=src
->prev_sibling
;
1403 // connect it to the new point
1404 if(dst
->next_sibling
!=0) dst
->next_sibling
->prev_sibling
=src
;
1405 else dst
->parent
->last_child
=src
;
1406 src
->next_sibling
=dst
->next_sibling
;
1407 dst
->next_sibling
=src
;
1408 src
->prev_sibling
=dst
;
1409 src
->parent
=dst
->parent
;
1413 template <class T
, class tree_node_allocator
>
1414 template <typename iter
> iter tree
<T
, tree_node_allocator
>::move_before(iter target
, iter source
)
1416 tree_node
*dst
=target
.node
;
1417 tree_node
*src
=source
.node
;
1421 if(dst
==src
) return source
;
1422 if(dst
->prev_sibling
)
1423 if(dst
->prev_sibling
==src
) // already in the right spot
1426 // take src out of the tree
1427 if(src
->prev_sibling
!=0) src
->prev_sibling
->next_sibling
=src
->next_sibling
;
1428 else src
->parent
->first_child
=src
->next_sibling
;
1429 if(src
->next_sibling
!=0) src
->next_sibling
->prev_sibling
=src
->prev_sibling
;
1430 else src
->parent
->last_child
=src
->prev_sibling
;
1432 // connect it to the new point
1433 if(dst
->prev_sibling
!=0) dst
->prev_sibling
->next_sibling
=src
;
1434 else dst
->parent
->first_child
=src
;
1435 src
->prev_sibling
=dst
->prev_sibling
;
1436 dst
->prev_sibling
=src
;
1437 src
->next_sibling
=dst
;
1438 src
->parent
=dst
->parent
;
1442 // specialisation for sibling_iterators
1443 template <class T
, class tree_node_allocator
>
1444 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::move_before(sibling_iterator target
,
1445 sibling_iterator source
)
1447 tree_node
*dst
=target
.node
;
1448 tree_node
*src
=source
.node
;
1449 tree_node
*dst_prev_sibling
;
1450 if(dst
==0) { // must then be an end iterator
1451 dst_prev_sibling
=target
.parent_
->last_child
;
1452 assert(dst_prev_sibling
);
1454 else dst_prev_sibling
=dst
->prev_sibling
;
1457 if(dst
==src
) return source
;
1458 if(dst_prev_sibling
)
1459 if(dst_prev_sibling
==src
) // already in the right spot
1462 // take src out of the tree
1463 if(src
->prev_sibling
!=0) src
->prev_sibling
->next_sibling
=src
->next_sibling
;
1464 else src
->parent
->first_child
=src
->next_sibling
;
1465 if(src
->next_sibling
!=0) src
->next_sibling
->prev_sibling
=src
->prev_sibling
;
1466 else src
->parent
->last_child
=src
->prev_sibling
;
1468 // connect it to the new point
1469 if(dst_prev_sibling
!=0) dst_prev_sibling
->next_sibling
=src
;
1470 else target
.parent_
->first_child
=src
;
1471 src
->prev_sibling
=dst_prev_sibling
;
1473 dst
->prev_sibling
=src
;
1474 src
->parent
=dst
->parent
;
1476 src
->next_sibling
=dst
;
1480 template <class T
, class tree_node_allocator
>
1481 template <typename iter
> iter tree
<T
, tree_node_allocator
>::move_ontop(iter target
, iter source
)
1483 tree_node
*dst
=target
.node
;
1484 tree_node
*src
=source
.node
;
1488 if(dst
==src
) return source
;
1490 // if(dst==src->prev_sibling) {
1494 // remember connection points
1495 tree_node
*b_prev_sibling
=dst
->prev_sibling
;
1496 tree_node
*b_next_sibling
=dst
->next_sibling
;
1497 tree_node
*b_parent
=dst
->parent
;
1502 // take src out of the tree
1503 if(src
->prev_sibling
!=0) src
->prev_sibling
->next_sibling
=src
->next_sibling
;
1504 else src
->parent
->first_child
=src
->next_sibling
;
1505 if(src
->next_sibling
!=0) src
->next_sibling
->prev_sibling
=src
->prev_sibling
;
1506 else src
->parent
->last_child
=src
->prev_sibling
;
1508 // connect it to the new point
1509 if(b_prev_sibling
!=0) b_prev_sibling
->next_sibling
=src
;
1510 else b_parent
->first_child
=src
;
1511 if(b_next_sibling
!=0) b_next_sibling
->prev_sibling
=src
;
1512 else b_parent
->last_child
=src
;
1513 src
->prev_sibling
=b_prev_sibling
;
1514 src
->next_sibling
=b_next_sibling
;
1515 src
->parent
=b_parent
;
1520 template <class T
, class tree_node_allocator
>
1521 tree
<T
, tree_node_allocator
> tree
<T
, tree_node_allocator
>::move_out(iterator source
)
1525 // Move source node into the 'ret' tree.
1526 ret
.head
->next_sibling
= source
.node
;
1527 ret
.feet
->prev_sibling
= source
.node
;
1528 source
.node
->parent
=0;
1530 // Close the links in the current tree.
1531 if(source
.node
->prev_sibling
!=0)
1532 source
.node
->prev_sibling
->next_sibling
= source
.node
->next_sibling
;
1534 if(source
.node
->next_sibling
!=0)
1535 source
.node
->next_sibling
->prev_sibling
= source
.node
->prev_sibling
;
1537 // Fix source prev/next links.
1538 source
.node
->prev_sibling
= ret
.head
;
1539 source
.node
->next_sibling
= ret
.feet
;
1541 return ret
; // A good compiler will move this, not copy.
1544 template <class T
, class tree_node_allocator
>
1545 template<typename iter
> iter tree
<T
, tree_node_allocator
>::move_in(iter loc
, tree
& other
)
1547 if(other
.head
->next_sibling
==other
.feet
) return loc
; // other tree is empty
1549 tree_node
*other_first_head
= other
.head
->next_sibling
;
1550 tree_node
*other_last_head
= other
.feet
->prev_sibling
;
1552 sibling_iterator
prev(loc
);
1555 prev
.node
->next_sibling
= other_first_head
;
1556 loc
.node
->prev_sibling
= other_last_head
;
1557 other_first_head
->prev_sibling
= prev
.node
;
1558 other_last_head
->next_sibling
= loc
.node
;
1560 // Adjust parent pointers.
1561 tree_node
*walk
=other_first_head
;
1563 walk
->parent
=loc
.node
->parent
;
1564 if(walk
==other_last_head
)
1566 walk
=walk
->next_sibling
;
1569 // Close other tree.
1570 other
.head
->next_sibling
=other
.feet
;
1571 other
.feet
->prev_sibling
=other
.head
;
1573 return other_first_head
;
1576 template <class T
, class tree_node_allocator
>
1577 template<typename iter
> iter tree
<T
, tree_node_allocator
>::move_in_as_nth_child(iter loc
, size_t n
, tree
& other
)
1579 if(other
.head
->next_sibling
==other
.feet
) return loc
; // other tree is empty
1581 tree_node
*other_first_head
= other
.head
->next_sibling
;
1582 tree_node
*other_last_head
= other
.feet
->prev_sibling
;
1585 if(loc
.node
->first_child
==0) {
1586 loc
.node
->first_child
=other_first_head
;
1587 loc
.node
->last_child
=other_last_head
;
1588 other_last_head
->next_sibling
=0;
1589 other_first_head
->prev_sibling
=0;
1592 loc
.node
->first_child
->prev_sibling
=other_last_head
;
1593 other_last_head
->next_sibling
=loc
.node
->first_child
;
1594 loc
.node
->first_child
=other_first_head
;
1595 other_first_head
->prev_sibling
=0;
1600 tree_node
*walk
= loc
.node
->first_child
;
1603 throw std::range_error("tree: move_in_as_nth_child position "
1604 +std::to_string(n
+1)
1605 +" out of range; only "
1606 +std::to_string(number_of_children(loc
))
1607 +" child nodes present");
1611 walk
= walk
->next_sibling
;
1613 if(walk
->next_sibling
==0)
1614 loc
.node
->last_child
=other_last_head
;
1616 walk
->next_sibling
->prev_sibling
=other_last_head
;
1617 other_last_head
->next_sibling
=walk
->next_sibling
;
1618 walk
->next_sibling
=other_first_head
;
1619 other_first_head
->prev_sibling
=walk
;
1622 // Adjust parent pointers.
1623 tree_node
*walk
=other_first_head
;
1625 walk
->parent
=loc
.node
;
1626 if(walk
==other_last_head
)
1628 walk
=walk
->next_sibling
;
1631 // Close other tree.
1632 other
.head
->next_sibling
=other
.feet
;
1633 other
.feet
->prev_sibling
=other
.head
;
1635 return other_first_head
;
1639 template <class T
, class tree_node_allocator
>
1640 void tree
<T
, tree_node_allocator
>::merge(sibling_iterator to1
, sibling_iterator to2
,
1641 sibling_iterator from1
, sibling_iterator from2
,
1642 bool duplicate_leaves
)
1644 sibling_iterator fnd
;
1645 while(from1
!=from2
) {
1646 if((fnd
=std::find(to1
, to2
, (*from1
))) != to2
) { // element found
1647 if(from1
.begin()==from1
.end()) { // full depth reached
1648 if(duplicate_leaves
)
1649 append_child(parent(to1
), (*from1
));
1651 else { // descend further
1652 merge(fnd
.begin(), fnd
.end(), from1
.begin(), from1
.end(), duplicate_leaves
);
1655 else { // element missing
1656 insert_subtree(to2
, from1
);
1663 template <class T
, class tree_node_allocator
>
1664 void tree
<T
, tree_node_allocator
>::sort(sibling_iterator from
, sibling_iterator to
, bool deep
)
1667 sort(from
, to
, comp
, deep
);
1670 template <class T
, class tree_node_allocator
>
1671 template <class StrictWeakOrdering
>
1672 void tree
<T
, tree_node_allocator
>::sort(sibling_iterator from
, sibling_iterator to
,
1673 StrictWeakOrdering comp
, bool deep
)
1675 if(from
==to
) return;
1676 // make list of sorted nodes
1677 // CHECK: if multiset stores equivalent nodes in the order in which they
1678 // are inserted, then this routine should be called 'stable_sort'.
1679 std::multiset
<tree_node
*, compare_nodes
<StrictWeakOrdering
> > nodes(comp
);
1680 sibling_iterator it
=from
, it2
=to
;
1682 nodes
.insert(it
.node
);
1688 // prev and next are the nodes before and after the sorted range
1689 tree_node
*prev
=from
.node
->prev_sibling
;
1690 tree_node
*next
=it2
.node
->next_sibling
;
1691 typename
std::multiset
<tree_node
*, compare_nodes
<StrictWeakOrdering
> >::iterator nit
=nodes
.begin(), eit
=nodes
.end();
1693 if((*nit
)->parent
!=0) // to catch "sorting the head" situations, when there is no parent
1694 (*nit
)->parent
->first_child
=(*nit
);
1696 else prev
->next_sibling
=(*nit
);
1700 (*nit
)->prev_sibling
=prev
;
1702 prev
->next_sibling
=(*nit
);
1706 // prev now points to the last-but-one node in the sorted range
1708 prev
->next_sibling
=(*eit
);
1710 // eit points to the last node in the sorted range.
1711 (*eit
)->next_sibling
=next
;
1712 (*eit
)->prev_sibling
=prev
; // missed in the loop above
1714 if((*eit
)->parent
!=0) // to catch "sorting the head" situations, when there is no parent
1715 (*eit
)->parent
->last_child
=(*eit
);
1717 else next
->prev_sibling
=(*eit
);
1719 if(deep
) { // sort the children of each node too
1720 sibling_iterator
bcs(*nodes
.begin());
1721 sibling_iterator
ecs(*eit
);
1724 sort(begin(bcs
), end(bcs
), comp
, deep
);
1730 template <class T
, class tree_node_allocator
>
1731 template <typename iter
>
1732 bool tree
<T
, tree_node_allocator
>::equal(const iter
& one_
, const iter
& two
, const iter
& three_
) const
1734 std::equal_to
<T
> comp
;
1735 return equal(one_
, two
, three_
, comp
);
1738 template <class T
, class tree_node_allocator
>
1739 template <typename iter
>
1740 bool tree
<T
, tree_node_allocator
>::equal_subtree(const iter
& one_
, const iter
& two_
) const
1742 std::equal_to
<T
> comp
;
1743 return equal_subtree(one_
, two_
, comp
);
1746 template <class T
, class tree_node_allocator
>
1747 template <typename iter
, class BinaryPredicate
>
1748 bool tree
<T
, tree_node_allocator
>::equal(const iter
& one_
, const iter
& two
, const iter
& three_
, BinaryPredicate fun
) const
1750 pre_order_iterator
one(one_
), three(three_
);
1752 // if(one==two && is_valid(three) && three.number_of_children()!=0)
1754 while(one
!=two
&& is_valid(three
)) {
1755 if(!fun(*one
,*three
))
1757 if(one
.number_of_children()!=three
.number_of_children())
1765 template <class T
, class tree_node_allocator
>
1766 template <typename iter
, class BinaryPredicate
>
1767 bool tree
<T
, tree_node_allocator
>::equal_subtree(const iter
& one_
, const iter
& two_
, BinaryPredicate fun
) const
1769 pre_order_iterator
one(one_
), two(two_
);
1771 if(!fun(*one
,*two
)) return false;
1772 if(number_of_children(one
)!=number_of_children(two
)) return false;
1773 return equal(begin(one
),end(one
),begin(two
),fun
);
1776 template <class T
, class tree_node_allocator
>
1777 tree
<T
, tree_node_allocator
> tree
<T
, tree_node_allocator
>::subtree(sibling_iterator from
, sibling_iterator to
) const
1779 assert(from
!=to
); // if from==to, the range is empty, hence no tree to return.
1782 tmp
.set_head(value_type());
1783 tmp
.replace(tmp
.begin(), tmp
.end(), from
, to
);
1787 template <class T
, class tree_node_allocator
>
1788 void tree
<T
, tree_node_allocator
>::subtree(tree
& tmp
, sibling_iterator from
, sibling_iterator to
) const
1790 assert(from
!=to
); // if from==to, the range is empty, hence no tree to return.
1792 tmp
.set_head(value_type());
1793 tmp
.replace(tmp
.begin(), tmp
.end(), from
, to
);
1796 template <class T
, class tree_node_allocator
>
1797 size_t tree
<T
, tree_node_allocator
>::size() const
1800 pre_order_iterator it
=begin(), eit
=end();
1808 template <class T
, class tree_node_allocator
>
1809 size_t tree
<T
, tree_node_allocator
>::size(const iterator_base
& top
) const
1812 pre_order_iterator it
=top
, eit
=top
;
1813 eit
.skip_children();
1822 template <class T
, class tree_node_allocator
>
1823 bool tree
<T
, tree_node_allocator
>::empty() const
1825 pre_order_iterator it
=begin(), eit
=end();
1829 template <class T
, class tree_node_allocator
>
1830 int tree
<T
, tree_node_allocator
>::depth(const iterator_base
& it
)
1832 tree_node
* pos
=it
.node
;
1835 while(pos
->parent
!=0) {
1842 template <class T
, class tree_node_allocator
>
1843 int tree
<T
, tree_node_allocator
>::depth(const iterator_base
& it
, const iterator_base
& root
)
1845 tree_node
* pos
=it
.node
;
1848 while(pos
->parent
!=0 && pos
!=root
.node
) {
1855 template <class T
, class tree_node_allocator
>
1856 int tree
<T
, tree_node_allocator
>::max_depth() const
1859 for(tree_node
*it
= head
->next_sibling
; it
!=feet
; it
=it
->next_sibling
)
1860 maxd
=std::max(maxd
, max_depth(it
));
1866 template <class T
, class tree_node_allocator
>
1867 int tree
<T
, tree_node_allocator
>::max_depth(const iterator_base
& pos
) const
1869 tree_node
*tmp
=pos
.node
;
1871 if(tmp
==0 || tmp
==head
|| tmp
==feet
) return -1;
1873 int curdepth
=0, maxdepth
=0;
1874 while(true) { // try to walk the bottom of the tree
1875 while(tmp
->first_child
==0) {
1876 if(tmp
==pos
.node
) return maxdepth
;
1877 if(tmp
->next_sibling
==0) {
1878 // try to walk up and then right again
1881 if(tmp
==0) return maxdepth
;
1883 } while(tmp
->next_sibling
==0);
1885 if(tmp
==pos
.node
) return maxdepth
;
1886 tmp
=tmp
->next_sibling
;
1888 tmp
=tmp
->first_child
;
1890 maxdepth
=std::max(curdepth
, maxdepth
);
1894 template <class T
, class tree_node_allocator
>
1895 unsigned int tree
<T
, tree_node_allocator
>::number_of_children(const iterator_base
& it
)
1897 tree_node
*pos
=it
.node
->first_child
;
1898 if(pos
==0) return 0;
1901 // while(pos!=it.node->last_child) {
1903 // pos=pos->next_sibling;
1905 while((pos
=pos
->next_sibling
))
1910 template <class T
, class tree_node_allocator
>
1911 unsigned int tree
<T
, tree_node_allocator
>::number_of_siblings(const iterator_base
& it
) const
1913 tree_node
*pos
=it
.node
;
1916 while(pos
->next_sibling
&&
1917 pos
->next_sibling
!=head
&&
1918 pos
->next_sibling
!=feet
) {
1920 pos
=pos
->next_sibling
;
1924 while(pos
->prev_sibling
&&
1925 pos
->prev_sibling
!=head
&&
1926 pos
->prev_sibling
!=feet
) {
1928 pos
=pos
->prev_sibling
;
1934 template <class T
, class tree_node_allocator
>
1935 void tree
<T
, tree_node_allocator
>::swap(sibling_iterator it
)
1937 tree_node
*nxt
=it
.node
->next_sibling
;
1939 if(it
.node
->prev_sibling
)
1940 it
.node
->prev_sibling
->next_sibling
=nxt
;
1942 it
.node
->parent
->first_child
=nxt
;
1943 nxt
->prev_sibling
=it
.node
->prev_sibling
;
1944 tree_node
*nxtnxt
=nxt
->next_sibling
;
1946 nxtnxt
->prev_sibling
=it
.node
;
1948 it
.node
->parent
->last_child
=it
.node
;
1949 nxt
->next_sibling
=it
.node
;
1950 it
.node
->prev_sibling
=nxt
;
1951 it
.node
->next_sibling
=nxtnxt
;
1955 template <class T
, class tree_node_allocator
>
1956 void tree
<T
, tree_node_allocator
>::swap(iterator one
, iterator two
)
1958 // if one and two are adjacent siblings, use the sibling swap
1959 if(one
.node
->next_sibling
==two
.node
) swap(one
);
1960 else if(two
.node
->next_sibling
==one
.node
) swap(two
);
1962 tree_node
*nxt1
=one
.node
->next_sibling
;
1963 tree_node
*nxt2
=two
.node
->next_sibling
;
1964 tree_node
*pre1
=one
.node
->prev_sibling
;
1965 tree_node
*pre2
=two
.node
->prev_sibling
;
1966 tree_node
*par1
=one
.node
->parent
;
1967 tree_node
*par2
=two
.node
->parent
;
1970 one
.node
->parent
=par2
;
1971 one
.node
->next_sibling
=nxt2
;
1972 if(nxt2
) nxt2
->prev_sibling
=one
.node
;
1973 else par2
->last_child
=one
.node
;
1974 one
.node
->prev_sibling
=pre2
;
1975 if(pre2
) pre2
->next_sibling
=one
.node
;
1976 else par2
->first_child
=one
.node
;
1978 two
.node
->parent
=par1
;
1979 two
.node
->next_sibling
=nxt1
;
1980 if(nxt1
) nxt1
->prev_sibling
=two
.node
;
1981 else par1
->last_child
=two
.node
;
1982 two
.node
->prev_sibling
=pre1
;
1983 if(pre1
) pre1
->next_sibling
=two
.node
;
1984 else par1
->first_child
=two
.node
;
1988 // template <class BinaryPredicate>
1989 // tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::find_subtree(
1990 // sibling_iterator subfrom, sibling_iterator subto, iterator from, iterator to,
1991 // BinaryPredicate fun) const
1993 // assert(1==0); // this routine is not finished yet.
1994 // while(from!=to) {
1995 // if(fun(*subfrom, *from)) {
2002 template <class T
, class tree_node_allocator
>
2003 bool tree
<T
, tree_node_allocator
>::is_in_subtree(const iterator_base
& it
, const iterator_base
& begin
,
2004 const iterator_base
& end
) const
2006 // FIXME: this should be optimised.
2007 pre_order_iterator tmp
=begin
;
2009 if(tmp
==it
) return true;
2015 template <class T
, class tree_node_allocator
>
2016 bool tree
<T
, tree_node_allocator
>::is_valid(const iterator_base
& it
) const
2018 if(it
.node
==0 || it
.node
==feet
|| it
.node
==head
) return false;
2022 template <class T
, class tree_node_allocator
>
2023 typename tree
<T
, tree_node_allocator
>::iterator tree
<T
, tree_node_allocator
>::lowest_common_ancestor(
2024 const iterator_base
& one
, const iterator_base
& two
) const
2026 std::set
<iterator
, iterator_base_less
> parents
;
2028 // Walk up from 'one' storing all parents.
2032 parents
.insert(walk
);
2033 } while( is_valid(parent(walk
)) );
2035 // Walk up from 'two' until we encounter a node in parents.
2039 if(parents
.find(walk
) != parents
.end()) break;
2040 } while( is_valid(parent(walk
)) );
2045 template <class T
, class tree_node_allocator
>
2046 unsigned int tree
<T
, tree_node_allocator
>::index(sibling_iterator it
) const
2049 if(it
.node
->parent
==0) {
2050 while(it
.node
->prev_sibling
!=head
) {
2051 it
.node
=it
.node
->prev_sibling
;
2056 while(it
.node
->prev_sibling
!=0) {
2057 it
.node
=it
.node
->prev_sibling
;
2064 template <class T
, class tree_node_allocator
>
2065 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::sibling(const iterator_base
& it
, unsigned int num
)
2068 if(it
.node
->parent
==0) {
2069 tmp
=head
->next_sibling
;
2071 tmp
= tmp
->next_sibling
;
2076 tmp
=it
.node
->parent
->first_child
;
2079 tmp
= tmp
->next_sibling
;
2086 template <class T
, class tree_node_allocator
>
2087 void tree
<T
, tree_node_allocator
>::debug_verify_consistency() const
2089 iterator it
=begin();
2091 if(it
.node
->parent
!=0) {
2092 if(it
.node
->prev_sibling
==0)
2093 assert(it
.node
->parent
->first_child
==it
.node
);
2095 assert(it
.node
->prev_sibling
->next_sibling
==it
.node
);
2096 if(it
.node
->next_sibling
==0)
2097 assert(it
.node
->parent
->last_child
==it
.node
);
2099 assert(it
.node
->next_sibling
->prev_sibling
==it
.node
);
2105 template <class T
, class tree_node_allocator
>
2106 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::child(const iterator_base
& it
, unsigned int num
)
2108 tree_node
*tmp
=it
.node
->first_child
;
2111 tmp
=tmp
->next_sibling
;
2121 template <class T
, class tree_node_allocator
>
2122 tree
<T
, tree_node_allocator
>::iterator_base::iterator_base()
2123 : node(0), skip_current_children_(false)
2127 template <class T
, class tree_node_allocator
>
2128 tree
<T
, tree_node_allocator
>::iterator_base::iterator_base(tree_node
*tn
)
2129 : node(tn
), skip_current_children_(false)
2133 template <class T
, class tree_node_allocator
>
2134 T
& tree
<T
, tree_node_allocator
>::iterator_base::operator*() const
2139 template <class T
, class tree_node_allocator
>
2140 T
* tree
<T
, tree_node_allocator
>::iterator_base::operator->() const
2142 return &(node
->data
);
2145 template <class T
, class tree_node_allocator
>
2146 bool tree
<T
, tree_node_allocator
>::post_order_iterator::operator!=(const post_order_iterator
& other
) const
2148 if(other
.node
!=this->node
) return true;
2152 template <class T
, class tree_node_allocator
>
2153 bool tree
<T
, tree_node_allocator
>::post_order_iterator::operator==(const post_order_iterator
& other
) const
2155 if(other
.node
==this->node
) return true;
2159 template <class T
, class tree_node_allocator
>
2160 bool tree
<T
, tree_node_allocator
>::pre_order_iterator::operator!=(const pre_order_iterator
& other
) const
2162 if(other
.node
!=this->node
) return true;
2166 template <class T
, class tree_node_allocator
>
2167 bool tree
<T
, tree_node_allocator
>::pre_order_iterator::operator==(const pre_order_iterator
& other
) const
2169 if(other
.node
==this->node
) return true;
2173 template <class T
, class tree_node_allocator
>
2174 bool tree
<T
, tree_node_allocator
>::sibling_iterator::operator!=(const sibling_iterator
& other
) const
2176 if(other
.node
!=this->node
) return true;
2180 template <class T
, class tree_node_allocator
>
2181 bool tree
<T
, tree_node_allocator
>::sibling_iterator::operator==(const sibling_iterator
& other
) const
2183 if(other
.node
==this->node
) return true;
2187 template <class T
, class tree_node_allocator
>
2188 bool tree
<T
, tree_node_allocator
>::leaf_iterator::operator!=(const leaf_iterator
& other
) const
2190 if(other
.node
!=this->node
) return true;
2194 template <class T
, class tree_node_allocator
>
2195 bool tree
<T
, tree_node_allocator
>::leaf_iterator::operator==(const leaf_iterator
& other
) const
2197 if(other
.node
==this->node
&& other
.top_node
==this->top_node
) return true;
2201 template <class T
, class tree_node_allocator
>
2202 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::iterator_base::begin() const
2204 if(node
->first_child
==0)
2207 sibling_iterator
ret(node
->first_child
);
2208 ret
.parent_
=this->node
;
2212 template <class T
, class tree_node_allocator
>
2213 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::iterator_base::end() const
2215 sibling_iterator
ret(0);
2220 template <class T
, class tree_node_allocator
>
2221 void tree
<T
, tree_node_allocator
>::iterator_base::skip_children()
2223 skip_current_children_
=true;
2226 template <class T
, class tree_node_allocator
>
2227 void tree
<T
, tree_node_allocator
>::iterator_base::skip_children(bool skip
)
2229 skip_current_children_
=skip
;
2232 template <class T
, class tree_node_allocator
>
2233 unsigned int tree
<T
, tree_node_allocator
>::iterator_base::number_of_children() const
2235 tree_node
*pos
=node
->first_child
;
2236 if(pos
==0) return 0;
2239 while(pos
!=node
->last_child
) {
2241 pos
=pos
->next_sibling
;
2248 // Pre-order iterator
2250 template <class T
, class tree_node_allocator
>
2251 tree
<T
, tree_node_allocator
>::pre_order_iterator::pre_order_iterator()
2256 template <class T
, class tree_node_allocator
>
2257 tree
<T
, tree_node_allocator
>::pre_order_iterator::pre_order_iterator(tree_node
*tn
)
2262 template <class T
, class tree_node_allocator
>
2263 tree
<T
, tree_node_allocator
>::pre_order_iterator::pre_order_iterator(const iterator_base
&other
)
2264 : iterator_base(other
.node
)
2268 template <class T
, class tree_node_allocator
>
2269 tree
<T
, tree_node_allocator
>::pre_order_iterator::pre_order_iterator(const sibling_iterator
& other
)
2270 : iterator_base(other
.node
)
2273 if(other
.range_last()!=0)
2274 this->node
=other
.range_last();
2276 this->node
=other
.parent_
;
2277 this->skip_children();
2282 template <class T
, class tree_node_allocator
>
2283 typename tree
<T
, tree_node_allocator
>::pre_order_iterator
& tree
<T
, tree_node_allocator
>::pre_order_iterator::operator++()
2285 assert(this->node
!=0);
2286 if(!this->skip_current_children_
&& this->node
->first_child
!= 0) {
2287 this->node
=this->node
->first_child
;
2290 this->skip_current_children_
=false;
2291 while(this->node
->next_sibling
==0) {
2292 this->node
=this->node
->parent
;
2296 this->node
=this->node
->next_sibling
;
2301 template <class T
, class tree_node_allocator
>
2302 typename tree
<T
, tree_node_allocator
>::pre_order_iterator
& tree
<T
, tree_node_allocator
>::pre_order_iterator::operator--()
2304 assert(this->node
!=0);
2305 if(this->node
->prev_sibling
) {
2306 this->node
=this->node
->prev_sibling
;
2307 while(this->node
->last_child
)
2308 this->node
=this->node
->last_child
;
2311 this->node
=this->node
->parent
;
2318 template <class T
, class tree_node_allocator
>
2319 typename tree
<T
, tree_node_allocator
>::pre_order_iterator tree
<T
, tree_node_allocator
>::pre_order_iterator::operator++(int)
2321 pre_order_iterator copy
= *this;
2326 template <class T
, class tree_node_allocator
>
2327 typename tree
<T
, tree_node_allocator
>::pre_order_iterator
& tree
<T
, tree_node_allocator
>::pre_order_iterator::next_skip_children()
2329 (*this).skip_children();
2334 template <class T
, class tree_node_allocator
>
2335 typename tree
<T
, tree_node_allocator
>::pre_order_iterator tree
<T
, tree_node_allocator
>::pre_order_iterator::operator--(int)
2337 pre_order_iterator copy
= *this;
2342 template <class T
, class tree_node_allocator
>
2343 typename tree
<T
, tree_node_allocator
>::pre_order_iterator
& tree
<T
, tree_node_allocator
>::pre_order_iterator::operator+=(unsigned int num
)
2352 template <class T
, class tree_node_allocator
>
2353 typename tree
<T
, tree_node_allocator
>::pre_order_iterator
& tree
<T
, tree_node_allocator
>::pre_order_iterator::operator-=(unsigned int num
)
2364 // Post-order iterator
2366 template <class T
, class tree_node_allocator
>
2367 tree
<T
, tree_node_allocator
>::post_order_iterator::post_order_iterator()
2372 template <class T
, class tree_node_allocator
>
2373 tree
<T
, tree_node_allocator
>::post_order_iterator::post_order_iterator(tree_node
*tn
)
2378 template <class T
, class tree_node_allocator
>
2379 tree
<T
, tree_node_allocator
>::post_order_iterator::post_order_iterator(const iterator_base
&other
)
2380 : iterator_base(other
.node
)
2384 template <class T
, class tree_node_allocator
>
2385 tree
<T
, tree_node_allocator
>::post_order_iterator::post_order_iterator(const sibling_iterator
& other
)
2386 : iterator_base(other
.node
)
2389 if(other
.range_last()!=0)
2390 this->node
=other
.range_last();
2392 this->node
=other
.parent_
;
2393 this->skip_children();
2398 template <class T
, class tree_node_allocator
>
2399 typename tree
<T
, tree_node_allocator
>::post_order_iterator
& tree
<T
, tree_node_allocator
>::post_order_iterator::operator++()
2401 assert(this->node
!=0);
2402 if(this->node
->next_sibling
==0) {
2403 this->node
=this->node
->parent
;
2404 this->skip_current_children_
=false;
2407 this->node
=this->node
->next_sibling
;
2408 if(this->skip_current_children_
) {
2409 this->skip_current_children_
=false;
2412 while(this->node
->first_child
)
2413 this->node
=this->node
->first_child
;
2419 template <class T
, class tree_node_allocator
>
2420 typename tree
<T
, tree_node_allocator
>::post_order_iterator
& tree
<T
, tree_node_allocator
>::post_order_iterator::operator--()
2422 assert(this->node
!=0);
2423 if(this->skip_current_children_
|| this->node
->last_child
==0) {
2424 this->skip_current_children_
=false;
2425 while(this->node
->prev_sibling
==0)
2426 this->node
=this->node
->parent
;
2427 this->node
=this->node
->prev_sibling
;
2430 this->node
=this->node
->last_child
;
2435 template <class T
, class tree_node_allocator
>
2436 typename tree
<T
, tree_node_allocator
>::post_order_iterator tree
<T
, tree_node_allocator
>::post_order_iterator::operator++(int)
2438 post_order_iterator copy
= *this;
2443 template <class T
, class tree_node_allocator
>
2444 typename tree
<T
, tree_node_allocator
>::post_order_iterator tree
<T
, tree_node_allocator
>::post_order_iterator::operator--(int)
2446 post_order_iterator copy
= *this;
2452 template <class T
, class tree_node_allocator
>
2453 typename tree
<T
, tree_node_allocator
>::post_order_iterator
& tree
<T
, tree_node_allocator
>::post_order_iterator::operator+=(unsigned int num
)
2462 template <class T
, class tree_node_allocator
>
2463 typename tree
<T
, tree_node_allocator
>::post_order_iterator
& tree
<T
, tree_node_allocator
>::post_order_iterator::operator-=(unsigned int num
)
2472 template <class T
, class tree_node_allocator
>
2473 void tree
<T
, tree_node_allocator
>::post_order_iterator::descend_all()
2475 assert(this->node
!=0);
2476 while(this->node
->first_child
)
2477 this->node
=this->node
->first_child
;
2481 // Breadth-first iterator
2483 template <class T
, class tree_node_allocator
>
2484 tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::breadth_first_queued_iterator()
2489 template <class T
, class tree_node_allocator
>
2490 tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::breadth_first_queued_iterator(tree_node
*tn
)
2493 traversal_queue
.push(tn
);
2496 template <class T
, class tree_node_allocator
>
2497 tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::breadth_first_queued_iterator(const iterator_base
& other
)
2498 : iterator_base(other
.node
)
2500 traversal_queue
.push(other
.node
);
2503 template <class T
, class tree_node_allocator
>
2504 bool tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::operator!=(const breadth_first_queued_iterator
& other
) const
2506 if(other
.node
!=this->node
) return true;
2510 template <class T
, class tree_node_allocator
>
2511 bool tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::operator==(const breadth_first_queued_iterator
& other
) const
2513 if(other
.node
==this->node
) return true;
2517 template <class T
, class tree_node_allocator
>
2518 typename tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator
& tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::operator++()
2520 assert(this->node
!=0);
2522 // Add child nodes and pop current node
2523 sibling_iterator sib
=this->begin();
2524 while(sib
!=this->end()) {
2525 traversal_queue
.push(sib
.node
);
2528 traversal_queue
.pop();
2529 if(traversal_queue
.size()>0)
2530 this->node
=traversal_queue
.front();
2536 template <class T
, class tree_node_allocator
>
2537 typename tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::operator++(int)
2539 breadth_first_queued_iterator copy
= *this;
2544 template <class T
, class tree_node_allocator
>
2545 typename tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator
& tree
<T
, tree_node_allocator
>::breadth_first_queued_iterator::operator+=(unsigned int num
)
2556 // Fixed depth iterator
2558 template <class T
, class tree_node_allocator
>
2559 tree
<T
, tree_node_allocator
>::fixed_depth_iterator::fixed_depth_iterator()
2564 template <class T
, class tree_node_allocator
>
2565 tree
<T
, tree_node_allocator
>::fixed_depth_iterator::fixed_depth_iterator(tree_node
*tn
)
2566 : iterator_base(tn
), top_node(0)
2570 template <class T
, class tree_node_allocator
>
2571 tree
<T
, tree_node_allocator
>::fixed_depth_iterator::fixed_depth_iterator(const iterator_base
& other
)
2572 : iterator_base(other
.node
), top_node(0)
2576 template <class T
, class tree_node_allocator
>
2577 tree
<T
, tree_node_allocator
>::fixed_depth_iterator::fixed_depth_iterator(const sibling_iterator
& other
)
2578 : iterator_base(other
.node
), top_node(0)
2582 template <class T
, class tree_node_allocator
>
2583 tree
<T
, tree_node_allocator
>::fixed_depth_iterator::fixed_depth_iterator(const fixed_depth_iterator
& other
)
2584 : iterator_base(other
.node
), top_node(other
.top_node
)
2588 template <class T
, class tree_node_allocator
>
2589 bool tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator==(const fixed_depth_iterator
& other
) const
2591 if(other
.node
==this->node
&& other
.top_node
==top_node
) return true;
2595 template <class T
, class tree_node_allocator
>
2596 bool tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator!=(const fixed_depth_iterator
& other
) const
2598 if(other
.node
!=this->node
|| other
.top_node
!=top_node
) return true;
2602 template <class T
, class tree_node_allocator
>
2603 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator
& tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator++()
2605 assert(this->node
!=0);
2607 if(this->node
->next_sibling
) {
2608 this->node
=this->node
->next_sibling
;
2611 int relative_depth
=0;
2614 if(this->node
==this->top_node
) {
2615 this->node
=0; // FIXME: return a proper fixed_depth end iterator once implemented
2618 this->node
=this->node
->parent
;
2619 if(this->node
==0) return *this;
2621 } while(this->node
->next_sibling
==0);
2623 this->node
=this->node
->next_sibling
;
2624 while(this->node
->first_child
==0) {
2625 if(this->node
->next_sibling
==0)
2627 this->node
=this->node
->next_sibling
;
2628 if(this->node
==0) return *this;
2630 while(relative_depth
<0 && this->node
->first_child
!=0) {
2631 this->node
=this->node
->first_child
;
2634 if(relative_depth
<0) {
2635 if(this->node
->next_sibling
==0) goto upper
;
2642 template <class T
, class tree_node_allocator
>
2643 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator
& tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator--()
2645 assert(this->node
!=0);
2647 if(this->node
->prev_sibling
) {
2648 this->node
=this->node
->prev_sibling
;
2651 int relative_depth
=0;
2654 if(this->node
==this->top_node
) {
2658 this->node
=this->node
->parent
;
2659 if(this->node
==0) return *this;
2661 } while(this->node
->prev_sibling
==0);
2663 this->node
=this->node
->prev_sibling
;
2664 while(this->node
->last_child
==0) {
2665 if(this->node
->prev_sibling
==0)
2667 this->node
=this->node
->prev_sibling
;
2668 if(this->node
==0) return *this;
2670 while(relative_depth
<0 && this->node
->last_child
!=0) {
2671 this->node
=this->node
->last_child
;
2674 if(relative_depth
<0) {
2675 if(this->node
->prev_sibling
==0) goto upper
;
2683 // assert(this->node!=0);
2684 // if(this->node->prev_sibling!=0) {
2685 // this->node=this->node->prev_sibling;
2686 // assert(this->node!=0);
2687 // if(this->node->parent==0 && this->node->prev_sibling==0) // head element
2691 // tree_node *par=this->node->parent;
2693 // par=par->prev_sibling;
2694 // if(par==0) { // FIXME: need to keep track of this!
2698 // } while(par->last_child==0);
2699 // this->node=par->last_child;
2704 template <class T
, class tree_node_allocator
>
2705 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator++(int)
2707 fixed_depth_iterator copy
= *this;
2712 template <class T
, class tree_node_allocator
>
2713 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator--(int)
2715 fixed_depth_iterator copy
= *this;
2720 template <class T
, class tree_node_allocator
>
2721 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator
& tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator-=(unsigned int num
)
2730 template <class T
, class tree_node_allocator
>
2731 typename tree
<T
, tree_node_allocator
>::fixed_depth_iterator
& tree
<T
, tree_node_allocator
>::fixed_depth_iterator::operator+=(unsigned int num
)
2743 template <class T
, class tree_node_allocator
>
2744 tree
<T
, tree_node_allocator
>::sibling_iterator::sibling_iterator()
2750 template <class T
, class tree_node_allocator
>
2751 tree
<T
, tree_node_allocator
>::sibling_iterator::sibling_iterator(tree_node
*tn
)
2757 template <class T
, class tree_node_allocator
>
2758 tree
<T
, tree_node_allocator
>::sibling_iterator::sibling_iterator(const iterator_base
& other
)
2759 : iterator_base(other
.node
)
2764 template <class T
, class tree_node_allocator
>
2765 tree
<T
, tree_node_allocator
>::sibling_iterator::sibling_iterator(const sibling_iterator
& other
)
2766 : iterator_base(other
), parent_(other
.parent_
)
2770 template <class T
, class tree_node_allocator
>
2771 void tree
<T
, tree_node_allocator
>::sibling_iterator::set_parent_()
2774 if(this->node
==0) return;
2775 if(this->node
->parent
!=0)
2776 parent_
=this->node
->parent
;
2779 template <class T
, class tree_node_allocator
>
2780 typename tree
<T
, tree_node_allocator
>::sibling_iterator
& tree
<T
, tree_node_allocator
>::sibling_iterator::operator++()
2783 this->node
=this->node
->next_sibling
;
2787 template <class T
, class tree_node_allocator
>
2788 typename tree
<T
, tree_node_allocator
>::sibling_iterator
& tree
<T
, tree_node_allocator
>::sibling_iterator::operator--()
2790 if(this->node
) this->node
=this->node
->prev_sibling
;
2793 this->node
=parent_
->last_child
;
2798 template <class T
, class tree_node_allocator
>
2799 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::sibling_iterator::operator++(int)
2801 sibling_iterator copy
= *this;
2806 template <class T
, class tree_node_allocator
>
2807 typename tree
<T
, tree_node_allocator
>::sibling_iterator tree
<T
, tree_node_allocator
>::sibling_iterator::operator--(int)
2809 sibling_iterator copy
= *this;
2814 template <class T
, class tree_node_allocator
>
2815 typename tree
<T
, tree_node_allocator
>::sibling_iterator
& tree
<T
, tree_node_allocator
>::sibling_iterator::operator+=(unsigned int num
)
2824 template <class T
, class tree_node_allocator
>
2825 typename tree
<T
, tree_node_allocator
>::sibling_iterator
& tree
<T
, tree_node_allocator
>::sibling_iterator::operator-=(unsigned int num
)
2834 template <class T
, class tree_node_allocator
>
2835 typename tree
<T
, tree_node_allocator
>::tree_node
*tree
<T
, tree_node_allocator
>::sibling_iterator::range_first() const
2837 tree_node
*tmp
=parent_
->first_child
;
2841 template <class T
, class tree_node_allocator
>
2842 typename tree
<T
, tree_node_allocator
>::tree_node
*tree
<T
, tree_node_allocator
>::sibling_iterator::range_last() const
2844 return parent_
->last_child
;
2849 template <class T
, class tree_node_allocator
>
2850 tree
<T
, tree_node_allocator
>::leaf_iterator::leaf_iterator()
2851 : iterator_base(0), top_node(0)
2855 template <class T
, class tree_node_allocator
>
2856 tree
<T
, tree_node_allocator
>::leaf_iterator::leaf_iterator(tree_node
*tn
, tree_node
*top
)
2857 : iterator_base(tn
), top_node(top
)
2861 template <class T
, class tree_node_allocator
>
2862 tree
<T
, tree_node_allocator
>::leaf_iterator::leaf_iterator(const iterator_base
&other
)
2863 : iterator_base(other
.node
), top_node(0)
2867 template <class T
, class tree_node_allocator
>
2868 tree
<T
, tree_node_allocator
>::leaf_iterator::leaf_iterator(const sibling_iterator
& other
)
2869 : iterator_base(other
.node
), top_node(0)
2872 if(other
.range_last()!=0)
2873 this->node
=other
.range_last();
2875 this->node
=other
.parent_
;
2880 template <class T
, class tree_node_allocator
>
2881 typename tree
<T
, tree_node_allocator
>::leaf_iterator
& tree
<T
, tree_node_allocator
>::leaf_iterator::operator++()
2883 assert(this->node
!=0);
2884 if(this->node
->first_child
!=0) { // current node is no longer leaf (children got added)
2885 while(this->node
->first_child
)
2886 this->node
=this->node
->first_child
;
2889 while(this->node
->next_sibling
==0) {
2890 if (this->node
->parent
==0) return *this;
2891 this->node
=this->node
->parent
;
2892 if (top_node
!= 0 && this->node
==top_node
) return *this;
2894 this->node
=this->node
->next_sibling
;
2895 while(this->node
->first_child
)
2896 this->node
=this->node
->first_child
;
2901 template <class T
, class tree_node_allocator
>
2902 typename tree
<T
, tree_node_allocator
>::leaf_iterator
& tree
<T
, tree_node_allocator
>::leaf_iterator::operator--()
2904 assert(this->node
!=0);
2905 while (this->node
->prev_sibling
==0) {
2906 if (this->node
->parent
==0) return *this;
2907 this->node
=this->node
->parent
;
2908 if (top_node
!=0 && this->node
==top_node
) return *this;
2910 this->node
=this->node
->prev_sibling
;
2911 while(this->node
->last_child
)
2912 this->node
=this->node
->last_child
;
2916 template <class T
, class tree_node_allocator
>
2917 typename tree
<T
, tree_node_allocator
>::leaf_iterator tree
<T
, tree_node_allocator
>::leaf_iterator::operator++(int)
2919 leaf_iterator copy
= *this;
2924 template <class T
, class tree_node_allocator
>
2925 typename tree
<T
, tree_node_allocator
>::leaf_iterator tree
<T
, tree_node_allocator
>::leaf_iterator::operator--(int)
2927 leaf_iterator copy
= *this;
2933 template <class T
, class tree_node_allocator
>
2934 typename tree
<T
, tree_node_allocator
>::leaf_iterator
& tree
<T
, tree_node_allocator
>::leaf_iterator::operator+=(unsigned int num
)
2943 template <class T
, class tree_node_allocator
>
2944 typename tree
<T
, tree_node_allocator
>::leaf_iterator
& tree
<T
, tree_node_allocator
>::leaf_iterator::operator-=(unsigned int num
)
2956 // default-tab-width: 3